1

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);
    }
} 
Carey Gregory
  • 6,836
  • 2
  • 26
  • 47
John Gotts
  • 21
  • 3
  • Hmmm... You should have hit invalid handle before that point. Just a shot in the dark, but try setting pDataType in DOC_INFO_1 to "RAW" instead of null. – Carey Gregory Aug 22 '13 at 04:24
  • Oh, and trying to do stuff like this in javascript? Glutton for punishment, aren't you? ;-) – Carey Gregory Aug 22 '13 at 04:28
  • Good question. We have an app that has two components. The components must be rebuilt for every version of Firefox. All of the documentation recommends switching to js-ctypes now. I'm working on the simple component. The other one is much more complex. – John Gotts Aug 22 '13 at 16:08
  • I added ` const dataTypeLength = 32; const dataType = 'RAW'; var docInfo = new docInfo1( ctypes.jschar.array(docNameLength)(docName), null, ctypes.jschar.array(dataTypeLength)(dataType) ); ` No change. – John Gotts Aug 22 '13 at 16:39
  • It was my understanding that JS strings aren't null terminated. If not, Windows certainly won't recognize it as matching "RAW". – Carey Gregory Aug 22 '13 at 18:11
  • That's the canonical method of converting JavaScript strings to null terminated C strings. jschar because I'm using the W function. For the A function I'd use char. https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Working_with_data Scroll down to Converting JavaScript strings to C. – John Gotts Aug 22 '13 at 21:26

1 Answers1

1

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.

John Gotts
  • 21
  • 3
  • You were linking to spoolss?! Ack! The MSDN documentation isn't wrong at all, you were just reading the wrong section. Winspool is the client-side library, spoolss is the server-side. Yeah, it's a messed up architecture that has the same entry points in two incompatible libraries. – Carey Gregory Aug 23 '13 at 05:37
  • Yep, sure enough, there's `spoolssLib` right in your code. Sorry, didn't notice it. – Carey Gregory Aug 23 '13 at 05:39
  • Typo: it's winspool.drv. – Eryk Sun Aug 23 '13 at 11:03
  • The following diagrams may help: [Introduction to Spooler Components](http://msdn.microsoft.com/en-us/library/ff551781) and [Introduction to Print Providers](http://msdn.microsoft.com/en-us/library/ff551775). – Eryk Sun Aug 23 '13 at 11:03