Share via


Register and initialize the barcode scanner driver

This topic provides information about how to register and initialize your barcode scanner driver. Each barcode scanner device driver should be designed to load on top of a specific hardware ID. The hardware ID is a vendor-defined identification string that Windows uses to match a device to its associated INF file.

Tip  

The sample scanner driver INF file is configured to match a software device called Root\SampleScanner. OEMs must add their own hardware identification string to the INF file they create for their driver.

Barcode scanner interface class

Use the following interface class GUID for your scanner driver. The POSUTIL library will use this GUID to automatically create a device interface for your scanner driver. If you do not use the POSUTIL library, you must create the device interface yourself by using WdfDeviceCreateDeviceInterface during driver device initialization for the WinRT POS stack to identify your device.

DEFINE_GUID(GUID_DEVINTERFACE_POS_SCANNER,
0xC243FFBD, 0x3AFC, 0x45E9, 0xB3, 0xD3, 0x2B, 0xA1, 0x8B, 0xC7, 0xEB, 0xC5)

When you register your driver by using this GUID, the driver can be enumerated by the WinRT PointOfService stack, which uses Windows.Devices.Enumeration.DeviceInformation.FindAllAsync on the desktop and Microsoft.Embedded.Devices.Enumeration.DeviceInformation.FindAll on the phone, to find the scanner device.

Initialize the POSUTIL library

POSUTIL offloads device state management, such as claim handling, that you would otherwise need to implement in your driver.

Your driver must initialize the POSUTIL library when each devices starts up by calling POSUTILInit. Ideally, you should initialize POSUTIL from within your EVT_WDF_DRIVER_DEVICE_ADD routine for every device because POSUTIL creates a unique context that is associated with each device.

The driver should indicate the type of POS device is connected when it calls POSUTILInit. The driver must also provide callbacks to the device driver functions that handle POS property updates.

The POSUTILDrvCallback structure contains function pointers to the functions that you implement to get and set property values for your hardware, and a function that provides the health information about the device. Provide an instance of this structure to POSUTILInit when you initialize the POSUTIL library.

The following example shows how to initialize POSUTIL.

NTSTATUS
    DriverEvtDeviceAdd(
    WDFDRIVER       Driver,
    PWDFDEVICE_INIT DeviceInit
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    WDFDEVICE device;
    POSUTILDrvCallback PosUtilDrvCallback = {NULL, NULL, NULL };

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    // Create Device
    status = WdfDeviceCreate(
        &DeviceInit, 
        &deviceAttributes, 
        &device
        );

    if (NT_SUCCESS(status)) 
    {
        // Initialize function pointer for POS property callback function
        PosUtilDrvCallback.POSUTILGetProperty = DeviceGetProperty;
        PosUtilDrvCallback.POSUTILSetProperty = DeviceSetProperty;
        PosUtilDrvCallback.POSUTILCheckHealth = DeviceCheckHealth;

        // Initialize POS library, this would also initialize device interface
        status = POSUTILInit(
            device, 
            &PosUtilDrvCallback, 
            POS_BARCODE_SCANNER
            );
    }

    return status;
}

Only after your driver calls POSUTILInit, it then must call POSUTILInitDeviceInfo to notify POSUTIL of the vendor name and to provide the recommended input buffer size for passing information between the driver and POSUTIL. Provide a recommended input buffer size so that POSUTIL can ensure better performance by avoiding the need to reallocate the buffer in case the internal buffer is too small.

The following example illustrates how to call POSUTILInitDeviceInfo.

(EVT_WDF_DEVICE_PREPARE_HARDWARE)
NTSTATUS DriverPrepareHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourcesRaw,
    _In_  WDFCMRESLIST ResourcesTranslated )
{
    UNICODE_STRING vendorName;
    NTSTATUS status = STATUS_SUCCESS;
    UINT32 MaxBuffer = 64;

    RtlUnicodeStringInit(&vendorName, L"Microsoft");

    if(NT_SUCCESS(status))
    {
        POSUTILInitDeviceInfo(Device, MaxBuffer, vendorName);
    }
    return status;
}

The sample scanner driver provides an example of how to initialize the POSUTIL library in DeviceInitialize(), found in Device.c

Register a create file handler

The driver must register with the driver framework to receive a callback when an app opens a device. The driver registers a EVT_WDF_DEVICE_FILE_CREATE) callback that is called when an app requests access to the device. The driver then calls POSUTILDeviceFileCreate from its EVT_WDF_DEVICE_FILE_CREATE handler to inform the POSUTIL library when an app requests access to the device so that the POSUTIL library can keep track of each app that has requested access to the device and send status change events to all WinRT client apps. This tracking also includes apps that do not currently have a claim on the device.

In Driver.c, the DriverDeviceAdd() function provides an example of registering these callbacks. It registers DeviceFileCreate() as the EVT_WDF_DEVICE_FILE_CREATE callback, and POSUTILFileCloseas the EvtFileClosecallback.

WDF_FILEOBJECT_CONFIG_INIT(&FileObjectConfig, DeviceFileCreate, POSUTILFileClose, NULL);

This example from the sample scanner driver (device.c) illustrates notifying POSUTIL of a create file event.

VOID DeviceFileCreate(  
    WDFDEVICE Device,  
    WDFREQUEST Request,  
    WDFFILEOBJECT FileObject  
    )  
{  
    NTSTATUS status;  
  
    // Notify POSUTIL of any file creation      
    status = POSUTILDeviceFileCreate(  
        Device,  
        Request,  
        FileObject  
        );  
  
    WdfRequestComplete(Request, status);  
  
    return;  
}

Register the file close handler

Drivers must register to receive a callback when an app closes its handle to the device. The driver must notify POSUTIL which WDFFILEOBJECT is being closed. This notification is necessary for POSUTIL to ensure that the current device owner relinquishes its claim to the device if it closes its handle to the device.

Notify POSUTIL when an app closes the handle to a device by doing one of the following:

  1. Register POSUTILFileClose with the driver framework, by using the Windows Driver Framework WDF_FILEOBJECT_CONFIG_INIT method.

  2. Call POSUTILFileClose manually from your own callback function.

The sample scanner driver uses the registration approach in driver.c / DeviceDriverAdd():

WDF_FILEOBJECT_CONFIG_INIT(&FileObjectConfig, DeviceFileCreate, POSUTILFileClose, NULL);

POSUTIL_GET_PROPERTY

POSUTIL_SET_PROPERTY

POSUTIL_CHECK_HEALTH

POS interface classes

Hardware ID