Sample Code

Windows Driver Samples/ Print Driver USB Monitor and Bidi Sample/ C++/ USBMon-Bidi-Extension.js/

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
// File Name:
//
//    USBMon-Bidi-Extension.js
//
// Abstract:
//
//    Sample USBMON Javascript extension file for v4 printer drivers.

// Add a reference that provides intellisense information for Windows 8 APIs.
/// <reference path="v4PrintDriver-Intellisense.js" />

function getSchemas(scriptContext, printerStream, schemaRequests, printerBidiSchemaResponses) {
    /// <summary>
    ///    Get the requested Schema(s).
    ///
    ///    The script can use the 'schemaRequests' object to iterate through the Query Keys requested by the user. Based on the query keys,
    ///    the script should use the 'printerStream' object to communicate with the USB print device and determine the values of one or more Bidi
    ///    Schema elements. For each Bidi Schema element the new value can be returned to the caller by using functions of the 'printerBidiSchemaResponses'
    ///    object. Once all query keys have been processed and all values added to the 'printerBidiSchemaResponses' object the script can return.
    ///
    ///    It is possible the attached device is not ready to return some of the requested data. In this case the function can return a value of 1 to indicate the call
    ///    should be retried after a wait.
    /// </summary>
    /// <param name="scriptContext" type="IPrinterScriptContext">
    ///     Script context object.
    /// </param>
    /// <param name="printerStream" type="IPrinterScriptableSequentialStream">
    ///    Allows the script to Write/Read data from the attached USB device.
    /// </param>
    /// <param name="schemaRequests" type="Array">
    ///    Array of strings that contains all the requested Query Keys.
    /// </param>
    /// <param name="printerBidiSchemaResponses" type="IPrinterBidiSchemaResponses">
    ///    Object the script will use to store all responses to query keys.
    /// </param>
    /// <returns type="Number" integer="true">
    ///     Integer value indicating function completion status.
    ///         1 - The attached device was not ready to provide some requested information. Call the function again using any Requery Keys added during processing.
    ///         0 - The script completed successfuly.
    /// </returns>

    var retVal = 0;

    // Loop through all the QueryKeys provided in the schemaRequests object.
    for (var index = 0; index < schemaRequests.length; index++) {
        var key = schemaRequests[index];

        // Process the "Configuration" Query key.
        if (key === "Configuration") {

            // Write command data to the device and read the response.
            // This command checks if the duplexing unit is installed.
            var duplexInstalled = false;
            var writeDataConfig = [0x0D, 0x0D, 0x02, 0xCA, 0xFE];
            var bytesWrittenConfig = printerStream.write(writeDataConfig);
            if (bytesWrittenConfig === 5) {
                // Correct number of bytes were written. Now read the response from the device.
                var readBufferConfig = printerStream.read(64);
                if (readBufferConfig.length === 1) {
                    // A value of 1 indicates the duplexing unit is installed.
                    var data = readBufferConfig.shift();
                    if (data === 1) {
                        duplexInstalled = true;
                    } else if (data === 2) {
                        // Tell USBMon to call this function again after a timeout period.
                        // Retry the "Configuration"  query key.
                        retVal = 1;
                        printerBidiSchemaResponses.addRequeryKey("Configuration");
                    }
                }
            }
            // If the device was able to process the request for Duplex status correctly,
            // add the response to the 'printerBidiSchemaResponses' object for processing by USBMon upon function completion.
            if (retVal === 0) {
                printerBidiSchemaResponses.addBool("\\Printer.Configuration.DuplexUnit:Installed", duplexInstalled);
            }

            // Write command data to the device and read the response.
            // This command requests the current memory size.
            var memSize = 0;
            var writeDataMem = [0x0D, 0x0D, 0x02, 0xAB, 0xCD];
            var bytesWrittenMem = printerStream.write(writeDataMem);
            if (bytesWrittenMem === 5) {
                // Correct number of bytes were written. Now read the response from the device.
                // Convert the incoming bytes to a string then convert the string to a number.
                var readBufferMem = printerStream.read(64);
                var bytesReadMem = readBufferMem.length;
                for (var i = 0; i < bytesReadMem; i++) {
                    // Read a byte at a time from the stream and convert to an integer.
                    memSize *= 256;
                    memSize += readBufferMem.shift();
                }
            }
            // Add the response to the 'printerBidiSchemaResponses' object for processing by USBMon upon function completion.
            printerBidiSchemaResponses.addInt32("\\Printer.Configuration.Memory:Size", memSize);

            // Read a property from the Queue Property Bag and add it to the 'printerBidiSchemaResponses' object for processing by USBMon upon function completion.
            var bag = scriptContext.QueueProperties;
            var queueProperty = bag.GetString("QueuePropName");
            printerBidiSchemaResponses.addString("\\Printer.DeviceInfo:QueueProperty", queueProperty);

        } else if (key === "IntKey") {
            // Process the "IntKey" Query key.
            // Write data to the device.
            var writeDataIntKey = [0x0D, 0x0D, 0x04, 0xDE, 0xAD, 0xBE, 0xEF];
            var bytesWrittenIntKey = printerStream.write(writeDataIntKey);
            // Add the response to the 'printerBidiSchemaResponses' object for processing by USBMon upon function completion.
            var intResult = printerBidiSchemaResponses.addInt32("\\Printer.Extension:IntegerValue", bytesWrittenIntKey);

        } else if (key === "\\Printer.Extension:StringValue") {
            // Process the "\\Printer.Extension:StringValue" Query key.
            // Write command data to the device and read the response.
            // This command retrieves a string from the device.
            var readString = "";
            var writeDataString = [0x0D, 0x0D, 0x01, 0xAA];
            var bytesWrittenString = printerStream.write(writeDataString);
            if (bytesWrittenString === 4) {
                // Correct number of bytes were written. Now read the response from the device.
                // Convert the incoming bytes to a string and store the value in the 'printerBidiSchemaResponses' object.
                var readBufferString = printerStream.read(64);
                var bytesReadString = readBufferString.length;
                for (i = 0; i < bytesReadString; i++) {
                    readString += String.fromCharCode(readBufferString.shift());
                }
            }
            // Add the response to the 'printerBidiSchemaResponses' object for processing by USBMon upon function completion.
            printerBidiSchemaResponses.addString("\\Printer.Extension:StringValue", readString);
        }
    }
    return retVal;
}

function setSchema(scriptContext, printerStream, printerBidiSchemaElement) {
    /// <summary>
    ///    Set a requested Bidi Schema Value in the device.
    ///
    ///    The script can interpret the incoming Bidi Schema value to either set data in the device or perform an action on the device.
    ///
    ///    It is possible the attached device is not ready to process the specified data. In this case the function can return a value of 1 to indicate the call
    ///    should be retried after a wait.
    /// </summary>
    ///
    /// <param name="scriptContext" type="IPrinterScriptContext">
    ///     Script context object.
    /// </param>
    /// <param name="printerStream" type="IPrinterScriptableSequentialStream">
    ///    Allows the script to Write/Read data from the attached USB device.
    /// </param>
    /// <param name="printerBidiSchemaElement" type="IPrinterBidiSchemaElement">
    ///    Contains all the data associated with the Bidi Schema Value to set.
    /// </param>
    /// <returns type="Number" integer="true">
    ///     Integer value indicating function completion status.
    ///         1 - The attached device was not ready to process/set the requested schema.  After a wait the function should be called again with the supplied printerBidiSchemaElement.
    ///         0 - The script completed successfuly.
    /// </returns>

    var retVal = 0;
    // Retrieve the Bidi Schema string to process.
    var bidiSchema = printerBidiSchemaElement.name;
    if (bidiSchema === "\\Printer.Extension:DeviceAction") {
        // Write command data to the device based on the current value of the passed in 'printerBidiSchemaElement'.
        var boolData = printerBidiSchemaElement.value;
        var writeDataBool;
        if (boolData) {
            writeDataBool = [0x65, 0x24, 0x0a];
        } else {
            writeDataBool = [0x65, 0x24, 0x0b];
        }
        var bytesWrittenBool = printerStream.write(writeDataBool);
    } else if (bidiSchema === "\\Printer.Extension:ChangeableData") {
        // Write command data to the device based on the current value of the passed in 'printerBidiSchemaElement'.
        var intData = printerBidiSchemaElement.value;
        var writeDataInt = [0x0d, 0x0a];
        writeDataInt[2] = intData;
        var bytesWrittenInt = printerStream.write(writeDataInt);
        if (bytesWrittenInt === 3) {
            // Read data from the USB device.
            var readBufferInt = printerStream.read(64);
            var bytesReadInt = readBufferInt.length;
            var data;
            // Response should be a 2 byte buffer.
            if (bytesReadInt === 2) {
                data = readBufferInt.shift();
                // Check if this is a ChangeableData value response.
                if (data === 0x1D) {
                    // Read the data byte and determine if we are done or need to try again.
                    data = readBufferInt.shift();
                    if (data === 0x01) {
                        // Tell USBMon to try again.
                        retVal = 1;
                    }
                }
            }
        }
    }
    return retVal;
}

function getStatus(scriptContext, printerStream, printerBidiSchemaResponses) {
    /// <summary>
    ///    Retrieve unsolicited Bidi Schema value updates from the USB device during printing.
    ///
    ///    This function is only called when a job is printing. A device can provide data on the read channel which this script can interpret into
    ///    Bidi Schema values and returned to USBMon.
    ///
    ///    This function will be called repeatedly during printing. It is expected the device will only return data if it is available and the script can understand it.
    ///    If the device does not support querying for unsolicited status or the script can determine that there is no need to call this function again, the script can return
    ///    a value of 2 which will tell the getStatus execution thread in USBMon to exit successfully.
    ///
    ///    If the print device does not support retrieving status during a print job this function should be left out of the driver's JavaScipt file altogether. This will inform 
    ///    USBMon to skip invocation of the function.
    /// </summary>
    /// <param name="scriptContext" type="IPrinterScriptContext">
    ///    Accessor for PropertyBags for printer driver and queue properties.
    /// </param>
    /// <param name="printerStream" type="IPrinterScriptableSequentialStream">
    ///    Allows the script to read data from the attached USB device. Calling the write function will fail. This device is opened read-only for this function.
    /// </param>
    /// <param name="printerBidiSchemaResponses" type="IPrinterBidiSchemaResponses">
    ///    Object the script will use to store all status responses.
    /// </param>
    /// <returns type="Number" integer="true">
    ///     Integer value indicating function completion status.
    ///         2 - The device no longer (if ever) supports unsolicited status so no need for USBMon to make more calls to this function.
    ///         0 - The script completed successfuly.
    /// </returns>

    var retVal = 0;

    // Read data from the USB device.
    var readBufferStatus = printerStream.read(64);
    var bytesReadStatus = readBufferStatus.length;
    var data;
    // Status Updates are 2 byte buffers.
    if (bytesReadStatus === 2) {
        data = readBufferStatus.shift();
        // Check if this is a Status value response.
        if (data === 0x1B) {
            // Read the data byte and return to USBMon for processing.
            data = readBufferStatus.shift();
            var intResult = printerBidiSchemaResponses.addInt32("\\Printer.Extension:StatusValue", data);
        } else if (data === 0x2B) {
            // This value signifies the device will not return additional status values so the thread can exit.
            retVal = 2;
        }
    }

    return retVal;
}

function requestStatus(scriptContext, printerStream, printerBidiSchemaResponses) {
    /// <summary>
    ///    Retrieve solicited Bidi Schema value updates from the USB device during printing.
    ///    This function will be called instead of getStatus if the device Printer Driver specifies an alternate BidiUSBStatusInterface to allow write/read operations
    ///    that don't conflict with the print data being sent over the primary USB Print Interface.
    ///
    ///    This function is only called when a job is printing. A device can write/read data to the Alternate interace which this script can interpret into
    ///    Bidi Schema values and returned to USBMon.
    ///
    ///    This function will be called repeatedly during printing. It is expected the device will only return data if it is available and the script can understand it.
    ///    If the device does not support querying for solicited status or the script can determine that there is no need to call this function again, the script can return
    ///    a value of 2 which will tell the requestStatus execution thread in USBMon to exit successfully.
    ///
    ///    If the print device does not support retrieving status during a print job via an alternate BidiUSBStatusInterface this function should be left out of the driver's JavaScipt 
    ///    file altogether. This will inform USBMon to skip invocation of the function.
    /// </summary>
    /// <param name="scriptContext" type="IPrinterScriptContext">
    ///    Accessor for PropertyBags for printer driver and queue properties.
    /// </param>
    /// <param name="printerStream" type="IPrinterScriptableSequentialStream">
    ///    Allows the script to write/read data from the attached USB device. 
    /// </param>
    /// <param name="printerBidiSchemaResponses" type="IPrinterBidiSchemaResponses">
    ///    Object the script will use to store all status responses.
    /// </param>
    /// <returns type="Number" integer="true">
    ///     Integer value indicating function completion status.
    ///         2 - The device no longer (if ever) supports solicited status so no need for USBMon to make more calls to this function.
    ///         0 - The script completed successfuly.
    /// </returns>

    var retVal = 0;

    // Write data to the device requesting Status data.
    var writeDataStatus = [0x0C, 0x0C];
    var bytesWrittenStatus = printerStream.write(writeDataStatus);

    if (bytesWrittenStatus === 2) {
       // Read data from the USB device.
       var readBufferStatus = printerStream.read(64);
       var bytesReadStatus = readBufferStatus.length;
       var data;
       // Status Updates are 2 byte buffers.
       if (bytesReadStatus === 2) {
           data = readBufferStatus.shift();
           // Check if this is a Status value response.
           if (data === 0x1B) {
               // Read the data byte and return to USBMon for processing.
               data = readBufferStatus.shift();
               var intResult = printerBidiSchemaResponses.addInt32("\\Printer.Extension:StatusValue", data);
           } else if (data === 0x2B) {
               // This value signifies the device will not return additional status values so the thread can exit.
               retVal = 2;
           }
       }
    }

    return retVal;
}


Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS