b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     4  */
     6 /*
     7  * ChromeWorker Object subprocess.jsm on Windows to process stdin/stdout/stderr
     8  * on separate threads.
     9  *
    10  */
    12 // Being a ChromeWorker object, implicitly uses the following:
    13 // Components.utils.import("resource://gre/modules/ctypes.jsm");
    15 'use strict';
    17 const BufferSize = 1024;
    19 const BOOL = ctypes.bool;
    20 const HANDLE = ctypes.size_t;
    21 const DWORD = ctypes.uint32_t;
    22 const LPDWORD = DWORD.ptr;
    23 const PVOID = ctypes.voidptr_t;
    24 const LPVOID = PVOID;
    26 /*
    27 typedef struct _OVERLAPPED {
    28   ULONG_PTR Internal;
    29   ULONG_PTR InternalHigh;
    30   union {
    31     struct {
    32       DWORD Offset;
    33       DWORD OffsetHigh;
    34     };
    35     PVOID  Pointer;
    36   };
    37   HANDLE    hEvent;
    38 } OVERLAPPED, *LPOVERLAPPED;
    39 */
    40 const OVERLAPPED = new ctypes.StructType("OVERLAPPED");
    42 var ReadFileBuffer = ctypes.char.array(BufferSize);
    43 var WriteFileBuffer = ctypes.uint8_t.array(BufferSize);
    45 var kernel32dll = null;
    46 var libFunc = {};
    48 function initLib(libName) {
    49     if (ctypes.size_t.size == 8) {
    50         var WinABI = ctypes.default_abi;
    51     } else {
    52         var WinABI = ctypes.winapi_abi;
    53     }
    55     kernel32dll = ctypes.open(libName);
    57     /*
    58     BOOL WINAPI WriteFile(
    59       __in         HANDLE hFile,
    60       __in         LPCVOID lpBuffer,
    61       __in         DWORD nNumberOfBytesToWrite,
    62       __out_opt    LPDWORD lpNumberOfBytesWritten,
    63       __inout_opt  LPOVERLAPPED lpOverlapped
    64     );
    66     NOTE: lpBuffer is declared as array of unsigned int8 instead of char to avoid
    67            implicit charset conversion
    68     */
    69     libFunc.WriteFile = kernel32dll.declare("WriteFile",
    70                                         WinABI,
    71                                         BOOL,
    72                                         HANDLE,
    73                                         WriteFileBuffer,
    74                                         DWORD,
    75                                         LPDWORD,
    76                                         OVERLAPPED.ptr
    77     );
    79     /*
    80     BOOL WINAPI ReadFile(
    81       __in         HANDLE hFile,
    82       __out        LPVOID ReadFileBuffer,
    83       __in         DWORD nNumberOfBytesToRead,
    84       __out_opt    LPDWORD lpNumberOfBytesRead,
    85       __inout_opt  LPOVERLAPPED lpOverlapped
    86     );
    87     */
    88     libFunc.ReadFile = kernel32dll.declare("ReadFile",
    89                                         WinABI,
    90                                         BOOL,
    91                                         HANDLE,
    92                                         ReadFileBuffer,
    93                                         DWORD,
    94                                         LPDWORD,
    95                                         OVERLAPPED.ptr
    96     );
    98     /*
    99     BOOL WINAPI CloseHandle(
   100       __in  HANDLE hObject
   101     );
   102     */
   103     libFunc.CloseHandle = kernel32dll.declare("CloseHandle",
   104                                             WinABI,
   105                                             BOOL,
   106                                             HANDLE
   107     );
   108 }
   111 function writePipe(pipe, data) {
   112     var bytesWritten = DWORD(0);
   114     var pData = new WriteFileBuffer();
   116     var numChunks = Math.floor(data.length / BufferSize);
   117     for (var chunk = 0; chunk <= numChunks; chunk ++) {
   118         var numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize;
   119         for (var i=0; i < numBytes; i++) {
   120             pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256;
   121         }
   123       var r = libFunc.WriteFile(pipe, pData, numBytes, bytesWritten.address(), null);
   124       if (bytesWritten.value != numBytes)
   125           throw("error: wrote "+bytesWritten.value+" instead of "+numBytes+" bytes");
   126     }
   127     postMessage("wrote "+data.length+" bytes of data");
   128 }
   130 function readString(data, length, charset) {
   131     var string = '', bytes = [];
   132     for(var i = 0;i < length; i++) {
   133         if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data
   134            break;
   136         bytes.push(data[i]);
   137     }
   139     return bytes;
   140 }
   142 function readPipe(pipe, charset) {
   143     while (true) {
   144         var bytesRead = DWORD(0);
   145         var line = new ReadFileBuffer();
   146         var r = libFunc.ReadFile(pipe, line, BufferSize, bytesRead.address(), null);
   148         if (!r) {
   149             // stop if we get an error (such as EOF reached)
   150             postMessage({msg: "info", data: "ReadFile failed"});
   151             break;
   152         }
   154         if (bytesRead.value > 0) {
   155             var c = readString(line, bytesRead.value, charset);
   156             postMessage({msg: "data", data: c, count: c.length});
   157         }
   158         else {
   159             break;
   160         }
   161     }
   162     libFunc.CloseHandle(pipe);
   163     postMessage({msg: "done"});
   164     kernel32dll.close();
   165     close();
   166 }
   168 onmessage = function (event) {
   169     let pipePtr;
   170     switch (event.data.msg) {
   171     case "init":
   172         initLib(event.data.libc);
   173         break;
   174     case "write":
   175         // data contents:
   176         //   msg: 'write'
   177         //   data: the data (string) to write
   178         //   pipe: ptr to pipe
   179         pipePtr = HANDLE.ptr(event.data.pipe);
   180         writePipe(pipePtr.contents, event.data.data);
   181         postMessage("WriteOK");
   182         break;
   183     case "read":
   184         initLib(event.data.libc);
   185         pipePtr = HANDLE.ptr(event.data.pipe);
   186         readPipe(pipePtr.contents, event.data.charset);
   187         break;
   188     case "close":
   189         pipePtr = HANDLE.ptr(event.data.pipe);
   190         postMessage("closing stdin\n");
   192         if (libFunc.CloseHandle(pipePtr.contents)) {
   193             postMessage("ClosedOK");
   194         }
   195         else
   196             postMessage("Could not close stdin handle");
   197         break;
   198     case "stop":
   199         kernel32dll.close();
   200         close();
   201         break;
   202     default:
   203         throw("error: Unknown command"+event.data.msg+"\n");
   204     }
   205     return;
   206 };

mercurial