/*++ Module Name: device.c - Device handling events for example driver. Abstract: This file contains the device entry points and callbacks. Environment: Kernel-mode Driver Framework --*/ #include "driver.h" #include "device.tmh" #ifdef ALLOC_PRAGMA #pragma alloc_text (PAGE, $formatteddrivername$CreateDevice) #pragma alloc_text (PAGE, $formatteddrivername$EvtDevicePrepareHardware) #endif NTSTATUS $formatteddrivername$CreateDevice( _Inout_ PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Worker routine called to create a device and its software resources. Arguments: DeviceInit - Pointer to an opaque init structure. Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds. So don't access the structure after that point. Return Value: NTSTATUS --*/ { WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES deviceAttributes; PDEVICE_CONTEXT deviceContext; WDFDEVICE device; NTSTATUS status; PAGED_CODE(); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = $formatteddrivername$EvtDevicePrepareHardware; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (NT_SUCCESS(status)) { // // Get a pointer to the device context structure that we just associated // with the device object. We define this structure in the device.h // header file. DeviceGetContext is an inline function generated by // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h. // This function will do the type checking and return the device context. // If you pass a wrong object handle it will return NULL and assert if // run under framework verifier mode. // deviceContext = DeviceGetContext(device); // // Initialize the context. // deviceContext->PrivateDeviceData = 0; // // Create a device interface so that applications can find and talk // to us. // status = WdfDeviceCreateDeviceInterface( device, &GUID_DEVINTERFACE_$formatteddrivername$, NULL // ReferenceString ); if (NT_SUCCESS(status)) { // // Initialize the I/O Package and any Queues // status = $formatteddrivername$QueueInitialize(device); } } return status; } NTSTATUS $formatteddrivername$EvtDevicePrepareHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourceList, _In_ WDFCMRESLIST ResourceListTranslated ) /*++ Routine Description: In this callback, the driver does whatever is necessary to make the hardware ready to use. In the case of a USB device, this involves reading and selecting descriptors. Arguments: Device - handle to a device Return Value: NT status value --*/ { NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; WDF_USB_DEVICE_CREATE_CONFIG createParams; WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; UNREFERENCED_PARAMETER(ResourceList); UNREFERENCED_PARAMETER(ResourceListTranslated); PAGED_CODE(); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); status = STATUS_SUCCESS; pDeviceContext = DeviceGetContext(Device); // // Create a USB device handle so that we can communicate with the // underlying USB stack. The WDFUSBDEVICE handle is used to query, // configure, and manage all aspects of the USB device. // These aspects include device properties, bus properties, // and I/O creation and synchronization. We only create the device the first time // PrepareHardware is called. If the device is restarted by pnp manager // for resource rebalance, we will use the same device handle but then select // the interfaces again because the USB stack could reconfigure the device on // restart. // if (pDeviceContext->UsbDevice == NULL) { // // Specifying a client contract version of 602 enables us to query for // and use the new capabilities of the USB driver stack for Windows 8. // It also implies that we conform to rules mentioned in MSDN // documentation for WdfUsbTargetDeviceCreateWithParameters. // WDF_USB_DEVICE_CREATE_CONFIG_INIT(&createParams, USBD_CLIENT_CONTRACT_VERSION_602 ); status = WdfUsbTargetDeviceCreateWithParameters(Device, &createParams, WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->UsbDevice ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "WdfUsbTargetDeviceCreateWithParameters failed 0x%x", status); return status; } } // // Select the first configuration of the device, using the first alternate // setting of each interface // WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&configParams, 0, NULL ); status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "WdfUsbTargetDeviceSelectConfig failed 0x%x", status); return status; } TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); return status; }