How do I convert CALLBACK routines to js-ctypes?

72 Views Asked by At

I'm working on using ReadFileEx from WINAPI in js-ctypes. I need to setup a callback for LPOVERLAPPED_COMPLETION_ROUTINE

BOOL WINAPI WriteFileEx(
  _In_     HANDLE                          hFile,
  _In_opt_ LPCVOID                         lpBuffer,
  _In_     DWORD                           nNumberOfBytesToWrite,
  _Inout_  LPOVERLAPPED                    lpOverlapped,
  _In_     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

VOID CALLBACK FileIOCompletionRoutine(
  _In_    DWORD        dwErrorCode,
  _In_    DWORD        dwNumberOfBytesTransfered,
  _Inout_ LPOVERLAPPED lpOverlapped
);

typedef VOID (WINAPI *LPOVERLAPPED_COMPLETION_ROUTINE)(
    _In_    DWORD        dwErrorCode,
    _In_    DWORD        dwNumberOfBytesTransfered,
    _Inout_ LPOVERLAPPED lpOverlapped
);

My ReadFileEx declaration currently looks like this

const readFileEx = kernel32.declare(
  "ReadFileEx",
  ctypes.winapi_abi,
  ctypes.int32_t,       // BOOL
  ctypes.voidptr_t,     // _In_      HANDLE                          hFile,
  ctypes.char.array(),  // _Out_opt_ LPVOID                          lpBuffer,
  ctypes.uint32_t,      // _In_      DWORD                           nNumberOfBytesToRead,
  ctypes.voidptr_t,     // _Inout_   LPOVERLAPPED                    lpOverlapped,
  ctypes.voidptr_t      // _In_      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Update. deleted...

Update 2. This seems to work, but the callback is not triggered until Firefox is closed, then it gets called (with the right number of nNumberOfBytesToWrite). Currently not using ChromeWorker.

const s_offset = new ctypes.StructType("s_offset",
  [ {"Offset":        ctypes.uint32_t},
    {"OffsetHigh":    ctypes.uint32_t} ]);

const s_overlapped = new ctypes.StructType("s_overlapped",
  [ {"Internal":      ctypes.uint64_t.ptr},
    {"InternalHigh":  ctypes.uint64_t.ptr},
    {"Pointer":       s_offset.ptr},          //  union { struct { DWORD Offset; DWORD OffsetHigh; }; PVOID Pointer; };
    {"hEvent":        ctypes.voidptr_t} ]);

//https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks
var OverlappedCompletionRoutine = ctypes.FunctionType(
  ctypes.default_abi,
  ctypes.void_t,           // returns VOID
  [ ctypes.uint32_t,       // _In_    DWORD        dwErrorCode,
    ctypes.uint32_t,       // _In_    DWORD        dwNumberOfBytesTransfered,
    s_overlapped.ptr ]     // _Inout_ LPOVERLAPPED lpOverlapped
);
const readFileEx = kernel32.declare(
  "ReadFileEx",
  ctypes.winapi_abi,
  ctypes.int32_t,       // BOOL
  ctypes.voidptr_t,     // _In_      HANDLE                          hFile,
  ctypes.char.array(),  // _Out_opt_ LPVOID                          lpBuffer,
  ctypes.uint32_t,      // _In_      DWORD                           nNumberOfBytesToRead,
  s_overlapped.ptr,     // _Inout_   LPOVERLAPPED                    lpOverlapped,
  OverlappedCompletionRoutine.ptr      // _In_      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Elsewhere

this.overlapped = new s_overlapped;
this.cReadCallback = OverlappedCompletionRoutine.ptr(this.readCallback);

and

  readCallback: function(errorCodes, numberOfBytesTransfered, pOverlapped) {
    console.log("readCallback:")
    console.log("  errorCodes " + errorCodes);
    console.log("  numberOfBytesTransfered " + numberOfBytesTransfered);
    console.log("  pOverlapped " + pOverlapped);

    // get the data etc.

    return undefined;
  },

finally

readFileEx(this.pipeHandle, pBuffer, MAXLEN, this.overlapped.address(), this.cReadCallback);
0

There are 0 best solutions below