Win32 printing with js-ctypes fails with ERROR_INVALID_HANDLE

385 Views Asked by At

I am converting a binary component to js-ctypes and StartPagePrinter is giving me ERROR_INVALID_HANDLE. I'm printing using the standard Windows techniques. (Search for "MSDN WritePrinter" to see the basic steps.) I think I'm either using the wrong type or not doing some kind of cast.

Instead of using ctypes.uintptr_t for jobHandle, I've tried ctypes.intptr_t, ctypes.voidptr_t, and ctypes.int32_t. They all fail with the same error.

I must confess that this the first Win32 programming I've done in my 30 year career, so please bear with me.

Here's the code snippet:

Components.utils.import('resource://gre/modules/ctypes.jsm');
var winspoolLib = ctypes.open('winspool.drv');
var spoolssLib = ctypes.open('spoolss');
const docNameLength = 32;
const printer = "My Printer"; // A valid, configured printer
var jobHandle = new ctypes.uintptr_t(0);
var openPrinter = winspoolLib.declare(
    "OpenPrinterW", ctypes.winapi_abi, ctypes.bool, ctypes.jschar.ptr,
    ctypes.uintptr_t.ptr, ctypes.voidptr_t
);
if (openPrinter(printer, jobHandle.address(), null)) {
    const docInfo1 = new ctypes.StructType(
        "docInfo1",
        [
            {pDocName: ctypes.jschar.ptr},
            {pOutputFile: ctypes.voidptr_t},
            {pDataType: ctypes.voidptr_t}
        ]
    );
    var startDocPrinter = winspoolLib.declare(
        "StartDocPrinterW", ctypes.winapi_abi, ctypes.int32_t,
        ctypes.uintptr_t, ctypes.int32_t, docInfo1.ptr
    );
    var docInfo = new docInfo1(
        ctypes.jschar.array(docNameLength)('MYJOB'), null, null
    );
    var job = startDocPrinter(jobHandle, 1, docInfo.address());
    if (job != 0) {
        var startPagePrinter = spoolssLib.declare(
            "StartPagePrinter", ctypes.winapi_abi, ctypes.bool,
            ctypes.uintptr_t
        );
        if (! startPagePrinter(jobHandle))
            // Always fails with ERROR_INVALID_HANDLE (6)
            alert('There was an error: ' + ctypes.winLastError);
    }
} 
1

There are 1 best solutions below

4
On

I got it working! Ignore the MSDN documentation and don't use spoolss.dll. Use all of the functions in winspool.dll. That is the answer.

Don't need to use the RAW setting. Null works fine.

Finally, voidptr_t is the proper type.