summaryrefslogtreecommitdiff
path: root/usb/kmdf_enumswitches/sys
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /usb/kmdf_enumswitches/sys
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'usb/kmdf_enumswitches/sys')
-rw-r--r--usb/kmdf_enumswitches/sys/Device.c384
-rw-r--r--usb/kmdf_enumswitches/sys/driver.c188
-rw-r--r--usb/kmdf_enumswitches/sys/interrupt.c195
-rw-r--r--usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx112
-rw-r--r--usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj229
-rw-r--r--usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters43
-rw-r--r--usb/kmdf_enumswitches/sys/osrusbfx2.h227
-rw-r--r--usb/kmdf_enumswitches/sys/rawpdo.c330
-rw-r--r--usb/kmdf_enumswitches/sys/rawpdo.h60
-rw-r--r--usb/kmdf_enumswitches/sys/trace.h115
10 files changed, 1883 insertions, 0 deletions
diff --git a/usb/kmdf_enumswitches/sys/Device.c b/usb/kmdf_enumswitches/sys/Device.c
new file mode 100644
index 00000000..0d61fe99
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/Device.c
@@ -0,0 +1,384 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ Device.c
+
+Abstract:
+
+ USB device driver for OSR USB-FX2 Learning Kit
+
+Environment:
+
+ Kernel mode only
+
+--*/
+
+#include <osrusbfx2.h>
+#include "rawpdo.h"
+
+#include "device.tmh"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, OsrFxEvtDeviceAdd)
+#pragma alloc_text(PAGE, OsrFxEvtDevicePrepareHardware)
+#pragma alloc_text(PAGE, OsrFxEvtDeviceD0Exit)
+#endif
+
+
+NTSTATUS
+OsrFxEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a device object to
+ represent a new instance of the device. All the software resources
+ should be allocated in this callback.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ NTSTATUS status;
+ WDFDEVICE device;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ PAGED_CODE();
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> OsrFxEvtDeviceAdd routine\n");
+
+ //
+ // Initialize the pnpPowerCallbacks structure. Callback events for PNP
+ // and Power are specified here. If you don't supply any callbacks,
+ // the Framework will take appropriate default actions based on whether
+ // DeviceInit is initialized to be an FDO, a PDO or a filter device
+ // object.
+ //
+
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
+ //
+ // For usb devices, PrepareHardware callback is the to place select the
+ // interface and configure the device.
+ //
+ pnpPowerCallbacks.EvtDevicePrepareHardware = OsrFxEvtDevicePrepareHardware;
+
+ //
+ // These two callbacks start and stop the WDFUSBPIPE continuous reader
+ // as we go in and out of the D0-working state.
+ //
+
+ pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry;
+ pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit;
+
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
+
+ OsrFxInitChildList(DeviceInit);
+
+ //
+ // Now specify the size of device extension where we track per device
+ // context.DeviceInit is completely initialized. So call the framework
+ // to create the device and attach it to the lower stack.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
+
+ status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ "WdfDeviceCreate failed with Status code %!STATUS!\n", status);
+ return status;
+ }
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "OsrFxEvtDeviceAdd - ends\n");
+
+ return status;
+}
+
+NTSTATUS
+OsrFxEvtDevicePrepareHardware(
+ 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 descriptors and selecting interfaces.
+
+Arguments:
+
+ Device - handle to a device
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status, tempStatus;
+ PDEVICE_CONTEXT pDeviceContext;
+ WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
+
+ UNREFERENCED_PARAMETER(ResourceList);
+ UNREFERENCED_PARAMETER(ResourceListTranslated);
+
+ PAGED_CODE();
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> EvtDevicePrepareHardware\n");
+
+ pDeviceContext = GetDeviceContext(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 device the first
+ // the 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) {
+ WDF_USB_DEVICE_CREATE_CONFIG config;
+
+ WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config,
+ USBD_CLIENT_CONTRACT_VERSION_602);
+
+ status = WdfUsbTargetDeviceCreateWithParameters(Device,
+ &config,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &pDeviceContext->UsbDevice);
+
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ "WdfUsbTargetDeviceCreateWithParameters failed with Status code %!STATUS!\n", status);
+ return status;
+ }
+ }
+
+ WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);
+
+ status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &configParams);
+ if(!NT_SUCCESS(status)) {
+ WDF_USB_DEVICE_INFORMATION deviceInfo;
+
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
+ status);
+ //
+ // detect if we are connected to a 1.1 USB port
+ //
+ WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);
+ tempStatus = WdfUsbTargetDeviceRetrieveInformation(pDeviceContext->UsbDevice, &deviceInfo);
+
+ if (NT_SUCCESS(tempStatus)) {
+ //
+ // Since the Osr USB fx2 device is capable of working at high speed, the only reason
+ // the device would not be working at high speed is if the port doesn't
+ // support it. If the port doesn't support high speed it is a 1.1 port
+ //
+ if ((deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ " On a 1.1 USB port on Windows Vista"
+ " this is expected as the OSR USB Fx2 board's Interrupt EndPoint descriptor"
+ " doesn't conform to the USB specification. Windows Vista detects this and"
+ " returns an error. \n"
+ );
+ }
+ }
+
+ return status;
+ }
+
+ pDeviceContext->UsbInterface =
+ configParams.Types.SingleInterface.ConfiguredUsbInterface;
+
+ status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n");
+
+ return status;
+}
+
+
+NTSTATUS
+OsrFxEvtDeviceD0Entry(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE PreviousState
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceD0Entry event callback must perform any operations that are
+ necessary before the specified device is used. It will be called every
+ time the hardware needs to be (re-)initialized.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+ This function runs at PASSIVE_LEVEL, even though it is not paged. A
+ driver can optionally make this function pageable if DO_POWER_PAGABLE
+ is set. Even if DO_POWER_PAGABLE isn't set, this function still runs
+ at PASSIVE_LEVEL. In this case, though, the function absolutely must
+ not do anything that will cause a page fault.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ PreviousState - Device power state which the device was in most recently.
+ If the device is being newly started, this will be
+ PowerDeviceUnspecified.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ PDEVICE_CONTEXT pDeviceContext;
+ NTSTATUS status;
+
+ pDeviceContext = GetDeviceContext(Device);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
+ "-->OsrFxEvtEvtDeviceD0Entry - coming from %s\n",
+ DbgDevicePowerString(PreviousState));
+
+ status = WdfIoTargetStart(WdfUsbTargetDeviceGetIoTarget(pDeviceContext->UsbDevice));
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtEvtDeviceD0Entry\n");
+
+ return status;
+}
+
+
+NTSTATUS
+OsrFxEvtDeviceD0Exit(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE TargetState
+ )
+/*++
+
+Routine Description:
+
+ This routine undoes anything done in EvtDeviceD0Entry. It is called
+ whenever the device leaves the D0 state, which happens when the device is
+ stopped, when it is removed, and when it is powered off.
+
+ The device is still in D0 when this callback is invoked, which means that
+ the driver can still touch hardware in this routine.
+
+
+ EvtDeviceD0Exit event callback must perform any operations that are
+ necessary before the specified device is moved out of the D0 state. If the
+ driver needs to save hardware state before the device is powered down, then
+ that should be done here.
+
+ This function runs at PASSIVE_LEVEL, though it is generally not paged. A
+ driver can optionally make this function pageable if DO_POWER_PAGABLE is set.
+
+ Even if DO_POWER_PAGABLE isn't set, this function still runs at
+ PASSIVE_LEVEL. In this case, though, the function absolutely must not do
+ anything that will cause a page fault.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ TargetState - Device power state which the device will be put in once this
+ callback is complete.
+
+Return Value:
+
+ Success implies that the device can be used. Failure will result in the
+ device stack being torn down.
+
+--*/
+{
+ PDEVICE_CONTEXT pDeviceContext;
+
+ PAGED_CODE();
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,
+ "-->OsrFxEvtDeviceD0Exit - moving to %s\n",
+ DbgDevicePowerString(TargetState));
+
+ pDeviceContext = GetDeviceContext(Device);
+
+ WdfIoTargetStop(WdfUsbTargetDeviceGetIoTarget(pDeviceContext->UsbDevice),
+ WdfIoTargetCancelSentIo);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtDeviceD0Exit\n");
+
+ return STATUS_SUCCESS;
+}
+
+
+_IRQL_requires_(PASSIVE_LEVEL)
+PCHAR
+DbgDevicePowerString(
+ _In_ WDF_POWER_DEVICE_STATE Type
+ )
+/*++
+
+Updated Routine Description:
+ DbgDevicePowerString does not change in this stage of the function driver.
+
+--*/
+{
+ switch (Type)
+ {
+ case WdfPowerDeviceInvalid:
+ return "WdfPowerDeviceInvalid";
+ case WdfPowerDeviceD0:
+ return "WdfPowerDeviceD0";
+ case WdfPowerDeviceD1:
+ return "WdfPowerDeviceD1";
+ case WdfPowerDeviceD2:
+ return "WdfPowerDeviceD2";
+ case WdfPowerDeviceD3:
+ return "WdfPowerDeviceD3";
+ case WdfPowerDeviceD3Final:
+ return "WdfPowerDeviceD3Final";
+ case WdfPowerDevicePrepareForHibernation:
+ return "WdfPowerDevicePrepareForHibernation";
+ case WdfPowerDeviceMaximum:
+ return "WdfPowerDeviceMaximum";
+ default:
+ return "UnKnown Device Power State";
+ }
+}
+
+
diff --git a/usb/kmdf_enumswitches/sys/driver.c b/usb/kmdf_enumswitches/sys/driver.c
new file mode 100644
index 00000000..10586be3
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/driver.c
@@ -0,0 +1,188 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ Driver.c
+
+Abstract:
+
+ Main module.
+
+ This driver is for Open System Resources USB-FX2 Learning Kit designed
+ and built by OSR specifically for use in teaching software developers how to write
+ drivers for USB devices.
+
+ The board supports a single configuration. The board automatically
+ detects the speed of the host controller, and supplies either the
+ high or full speed configuration based on the host controller's speed.
+
+ The firmware supports 3 endpoints:
+
+ Endpoint number 1 is used to indicate the state of the 8-switch
+ switch-pack on the OSR USB-FX2 board. A single byte representing
+ the switch state is sent (a) when the board is first stated,
+ (b) when the board resumes after selective-suspend,
+ (c) whenever the state of the switches is changed.
+
+ Endpoints 6 and 8 perform an internal loop-back function.
+ Data that is sent to the board at EP6 is returned to the host on EP8.
+
+ For further information on the endpoints, please refer to the spec
+ http://www.osronline.com/hardware/OSRFX2_32.pdf.
+
+ Vendor ID of the device is 0x4705 and Product ID is 0x210.
+
+Environment:
+
+ Kernel mode only
+
+--*/
+
+#include <osrusbfx2.h>
+#include "trace.h"
+
+//
+// The trace message header (.tmh) file must be included in a source file
+// before any WPP macro calls and after defining a WPP_CONTROL_GUIDS
+// macro (defined in toaster.h). During the compilation, WPP scans the source
+// files for DoTraceMessage() calls and builds a .tmh file which stores a unique
+// data GUID for each message, the text resource string for each message,
+// and the data types of the variables passed in for each message. This file
+// is automatically generated and used during post-processing.
+//
+#include "driver.tmh"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, OsrFxEvtDriverContextCleanup)
+#endif
+
+NTSTATUS
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded.
+
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverEntry must initialize members of DriverObject before it
+ returns to the caller. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ WDF_DRIVER_CONFIG config;
+ NTSTATUS status;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ //
+ // Initialize WPP Tracing
+ //
+ WPP_INIT_TRACING(DriverObject, RegistryPath);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
+ "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n");
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
+ "Built %s %s\n", __DATE__, __TIME__);
+
+ //
+ // Initiialize driver config to control the attributes that
+ // are global to the driver. Note that framework by default
+ // provides a driver unload routine. If you create any resources
+ // in the DriverEntry and want to be cleaned in driver unload,
+ // you can override that by manually setting the EvtDriverUnload in the
+ // config structure. In general xxx_CONFIG_INIT macros are provided to
+ // initialize most commonly used members.
+ //
+
+ WDF_DRIVER_CONFIG_INIT(
+ &config,
+ OsrFxEvtDeviceAdd
+ );
+
+ //
+ // Register a cleanup callback so that we can call WPP_CLEANUP when
+ // the framework driver object is deleted during driver unload.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.EvtCleanupCallback = OsrFxEvtDriverContextCleanup;
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+ status = WdfDriverCreate(
+ DriverObject,
+ RegistryPath,
+ &attributes, // Driver Attributes
+ &config, // Driver Config Info
+ WDF_NO_HANDLE // hDriver
+ );
+
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,
+ "WdfDriverCreate failed with status 0x%x\n", status);
+ //
+ // Cleanup tracing here because DriverContextCleanup will not be called
+ // as we have failed to create WDFDRIVER object itself.
+ // Please note that if your return failure from DriverEntry after the
+ // WDFDRIVER object is created successfully, you don't have to
+ // call WPP cleanup because in those cases DriverContextCleanup
+ // will be executed when the framework deletes the DriverObject.
+ //
+ WPP_CLEANUP(DriverObject);
+ }
+
+ return status;
+}
+
+VOID
+OsrFxEvtDriverContextCleanup(
+ IN WDFOBJECT Driver
+ )
+/*++
+Routine Description:
+
+ Free resources allocated in DriverEntry that are not
+ automatically cleaned up framework.
+
+Arguments:
+
+ Driver - handle to a WDF Driver object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+ PAGED_CODE ();
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,"<-- OsrFxEvtDriverContextCleanup\n");
+
+ WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)Driver ));
+}
+
diff --git a/usb/kmdf_enumswitches/sys/interrupt.c b/usb/kmdf_enumswitches/sys/interrupt.c
new file mode 100644
index 00000000..bb84af8b
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/interrupt.c
@@ -0,0 +1,195 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ Interrupt.c
+
+Abstract:
+
+ This modules has routines configure a continuous reader on an
+ interrupt pipe to asynchronously read toggle switch states.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <osrusbfx2.h>
+
+#include "interrupt.tmh"
+
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+OsrFxConfigContReaderForInterruptEndPoint(
+ _In_ PDEVICE_CONTEXT DeviceContext
+ )
+/*++
+
+Routine Description:
+
+ This routine configures a continuous reader on the
+ interrupt endpoint. It's called from the PrepareHarware event.
+
+Arguments:
+
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ WDF_USB_CONTINUOUS_READER_CONFIG contReaderConfig;
+ NTSTATUS status;
+ WDFUSBPIPE pipe;
+
+ pipe = WdfUsbInterfaceGetConfiguredPipe(DeviceContext->UsbInterface,
+ INTERRUPT_IN_ENDPOINT_INDEX, // PipeIndex,
+ NULL); // pipeInfo
+ //
+ // Tell the framework that it's okay to read less than
+ // MaximumPacketSize
+ //
+ WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);
+
+ WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&contReaderConfig,
+ OsrFxEvtUsbInterruptPipeReadComplete,
+ DeviceContext, // Context
+ sizeof(UCHAR)); // TransferLength
+
+ contReaderConfig.EvtUsbTargetPipeReadersFailed =
+ OsrFxEvtUsbInterruptReadersFailed;
+
+ //
+ // Reader requests are not posted to the target automatically.
+ // Driver must explictly call WdfIoTargetStart to kick start the
+ // reader. In this sample, it's done in D0Entry.
+ // By defaut, framework queues two requests to the target
+ // endpoint. Driver can configure up to 10 requests with CONFIG macro.
+ //
+ status = WdfUsbTargetPipeConfigContinuousReader(pipe, &contReaderConfig);
+ if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ "OsrFxConfigContReaderForInterruptEndPoint failed %x\n",
+ status);
+ return status;
+ }
+
+ return status;
+}
+
+VOID
+OsrFxEvtUsbInterruptPipeReadComplete(
+ WDFUSBPIPE Pipe,
+ WDFMEMORY Buffer,
+ size_t NumBytesTransferred,
+ WDFCONTEXT Context
+ )
+/*++
+
+Routine Description:
+
+ This the completion routine of the continour reader. This can
+ called concurrently on multiprocessor system if there are
+ more than one readers configured. So make sure to protect
+ access to global resources.
+
+Arguments:
+
+ Buffer - This buffer is freed when this call returns.
+ If the driver wants to delay processing of the buffer, it
+ can take an additional referrence.
+
+ Context - Provided in the WDF_USB_CONTINUOUS_READER_CONFIG_INIT macro
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ PUCHAR switchState = NULL;
+ WDFDEVICE device;
+ PDEVICE_CONTEXT pDeviceContext = Context;
+
+ UNREFERENCED_PARAMETER(Pipe);
+
+ device = WdfObjectContextGetObject(pDeviceContext);
+
+ //
+ // Make sure that there is data in the read packet. Depending on the device
+ // specification, it is possible for it to return a 0 length read in
+ // certain conditions.
+ //
+
+ if (NumBytesTransferred == 0) {
+ TraceEvents(TRACE_LEVEL_WARNING, DBG_INIT,
+ "OsrFxEvtUsbInterruptPipeReadComplete Zero length read "
+ "occured on the Interrupt Pipe's Continuous Reader\n"
+ );
+ return;
+ }
+
+ NT_ASSERT(NumBytesTransferred == sizeof(UCHAR));
+
+ switchState = WdfMemoryGetBuffer(Buffer, NULL);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
+ "OsrFxEvtUsbInterruptPipeReadComplete SwitchState %x\n",
+ *switchState);
+
+ pDeviceContext->CurrentSwitchState = *switchState;
+
+ OsrFxEnumerateChildren(device);
+}
+
+BOOLEAN
+OsrFxEvtUsbInterruptReadersFailed(
+ WDFUSBPIPE Pipe,
+ NTSTATUS Status,
+ USBD_STATUS UsbdStatus
+ )
+/*++
+
+Routine Description:
+
+ EvtUsbTargetPipeReadersFailed is called to inform the driver that a
+ continuous reader has reported an error while processing a read request.
+
+Arguments:
+
+ Pipe - handle to a framework pipe object.
+ Status - NTSTATUS value that the pipe's I/O target returned.
+ UsbdStatus - USBD_STATUS-typed status value that the pipe's I/O target returned.
+
+Return Value:
+
+ If TRUE, causes the framework to reset the USB pipe and then
+ restart the continuous reader.
+ If FASLE, the framework does not reset the device or restart
+ the continuous reader.
+
+ If this event is not registered, framework default action is to reset
+ the pipe and restart the reader.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Pipe);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,
+ "OsrFxEvtUsbInterruptReadersFailed NTSTATUS 0x%x, UsbdStatus 0x%x\n",
+ Status, UsbdStatus);
+
+ return TRUE;
+}
+
+
diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx
new file mode 100644
index 00000000..adab710e
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx
@@ -0,0 +1,112 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+; 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.
+;
+;Module Name:
+;
+; OSRUSBFX2.INF
+;
+;Abstract:
+; Installation inf for OSR USB-FX2 Learning Kit
+;
+;--*/
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=Sample
+ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171}
+Provider=%MSFT%
+DriverVer=03/20/2003,5.00.3788
+CatalogFile=KmdfSamples.cat
+
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=SampleClassReg
+
+[SampleClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,-5
+
+
+; ================= Device section =====================
+
+[Manufacturer]
+%MfgName%=Microsoft,NT$ARCH$
+
+[Microsoft.NT$ARCH$]
+%USB\VID_045E&PID_930A.DeviceDesc%=kmdf_enumswitches.Dev, USB\VID_0547&PID_1002
+%Switch.DeviceDesc%=Switch.Dev, {6FDE7521-1B65-48ae-B628-80BE62016026}\OsrUsbFxRawPdo
+
+
+[kmdf_enumswitches.Dev.NT]
+CopyFiles=kmdf_enumswitches.Files.Ext
+
+[Switch.Dev.NT]
+;dummy section
+
+[Switch.Dev.NT.Services]
+AddService = , %SPSVCINST_ASSOCSERVICE%,
+
+[kmdf_enumswitches.Dev.NT.Services]
+AddService = kmdf_enumswitches, %SPSVCINST_ASSOCSERVICE%, kmdf_enumswitches.AddService
+
+[kmdf_enumswitches.AddService]
+DisplayName = %kmdf_enumswitches.SvcDesc%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %10%\System32\Drivers\kmdf_enumswitches.sys
+
+[kmdf_enumswitches.Files.Ext]
+kmdf_enumswitches.sys
+
+[SourceDisksNames]
+1=%Disk_Description%,,,
+
+[SourceDisksFiles]
+kmdf_enumswitches.sys = 1
+
+[DestinationDirs]
+DefaultDestDir = 12
+
+;-------------- WDF Coinstaller installation
+
+[DestinationDirs]
+CoInstaller_CopyFiles = 11
+
+[kmdf_enumswitches.Dev.NT.CoInstallers]
+AddReg=CoInstaller_AddReg
+CopyFiles=CoInstaller_CopyFiles
+
+[CoInstaller_CopyFiles]
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
+
+[SourceDisksFiles]
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
+
+[CoInstaller_AddReg]
+HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
+
+[kmdf_enumswitches.Dev.NT.Wdf]
+KmdfService = kmdf_enumswitches, kmdf_enumswitches_wdfsect
+[kmdf_enumswitches_wdfsect]
+KmdfLibraryVersion = $KMDFVERSION$
+
+;---------------------------------------------------------------;
+
+[Strings]
+MSFT="Microsoft"
+MfgName="OSR"
+Disk_Description="OSRUSBFX2 Installation Disk"
+USB\VID_045E&PID_930A.DeviceDesc="WDF Sample Bus Driver for OSR USB-FX2 Learning Kit"
+kmdf_enumswitches.SvcDesc="WDF Sample Bus Driver for OSR USB-FX2 Learning Kit"
+ClassName = "Sample Device"
+Switch.DeviceDesc = "OsrUsbFX2 RawPdo For Switch"
+SPSVCINST_ASSOCSERVICE= 0x00000002
diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj
new file mode 100644
index 00000000..a8bde5c4
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{6A32E70D-E961-4940-A1E8-AB1A7CED390D}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{5F18CAB2-2FE2-4E6B-BA36-C0EFF928BB0E}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <ClCompile Include="Driver.c; device.c; interrupt.c; rawpdo.c">
+ <WppEnabled>true</WppEnabled>
+ <WppKernelMode>true</WppKernelMode>
+ <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction>
+ <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile>
+ </ClCompile>
+ <Inf Include="kmdf_enumswitches.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\kmdf_enumswitches.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>kmdf_enumswitches</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>kmdf_enumswitches</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>kmdf_enumswitches</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>kmdf_enumswitches</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions>
+ </Midl>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters
new file mode 100644
index 00000000..f230f871
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{8CFB48AC-E2E0-495E-B587-5D803D866819}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{D29CD043-B947-42D0-8741-B8510E442021}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{5A199DB9-BFEF-42C9-A546-9AA11B9322FE}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{634C8B4D-FD4D-4D9D-9A2A-9A4C2E388164}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="device.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Driver.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="interrupt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="rawpdo.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\kmdf_enumswitches.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include="kmdf_enumswitches.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/usb/kmdf_enumswitches/sys/osrusbfx2.h b/usb/kmdf_enumswitches/sys/osrusbfx2.h
new file mode 100644
index 00000000..968069c7
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/osrusbfx2.h
@@ -0,0 +1,227 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ private.h
+
+Abstract:
+
+ Contains structure definitions and function prototypes private to
+ the driver.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <initguid.h>
+#include <ntddk.h>
+#include "usbdi.h"
+#include "usbdlib.h"
+#include "public.h"
+#include "driverspecs.h"
+#include <wdf.h>
+#include <wdfusb.h>
+#define NTSTRSAFE_LIB
+#include <ntstrsafe.h>
+
+#include "trace.h"
+
+#ifndef _PRIVATE_H
+#define _PRIVATE_H
+
+#define POOL_TAG (ULONG) 'FRSO'
+#define _DRIVER_NAME_ "OSRUSBFX2"
+
+#define TEST_BOARD_TRANSFER_BUFFER_SIZE (64*1024)
+#define DEVICE_DESC_LENGTH 256
+
+extern const __declspec(selectany) LONGLONG DEFAULT_CONTROL_TRANSFER_TIMEOUT = 5 * -1 * WDF_TIMEOUT_TO_SEC;
+
+//
+// Define the vendor commands supported by our device
+//
+#define USBFX2LK_READ_7SEGMENT_DISPLAY 0xD4
+#define USBFX2LK_READ_SWITCHES 0xD6
+#define USBFX2LK_READ_BARGRAPH_DISPLAY 0xD7
+#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8
+#define USBFX2LK_IS_HIGH_SPEED 0xD9
+#define USBFX2LK_REENUMERATE 0xDA
+#define USBFX2LK_SET_7SEGMENT_DISPLAY 0xDB
+
+//
+// Define the features that we can clear
+// and set on our device
+//
+#define USBFX2LK_FEATURE_EPSTALL 0x00
+#define USBFX2LK_FEATURE_WAKE 0x01
+
+//
+// Order of endpoints in the interface descriptor
+//
+#define INTERRUPT_IN_ENDPOINT_INDEX 0
+#define BULK_OUT_ENDPOINT_INDEX 1
+#define BULK_IN_ENDPOINT_INDEX 2
+
+//
+// A structure representing the instance information associated with
+// this particular device.
+//
+
+typedef struct _DEVICE_CONTEXT {
+
+ WDFUSBDEVICE UsbDevice;
+
+ WDFUSBINTERFACE UsbInterface;
+
+ UCHAR CurrentSwitchState;
+
+} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)
+
+extern ULONG DebugLevel;
+
+
+DRIVER_INITIALIZE DriverEntry;
+
+EVT_WDF_OBJECT_CONTEXT_CLEANUP OsrFxEvtDriverContextCleanup;
+
+EVT_WDF_DRIVER_DEVICE_ADD OsrFxEvtDeviceAdd;
+
+EVT_WDF_DEVICE_PREPARE_HARDWARE OsrFxEvtDevicePrepareHardware;
+
+EVT_WDF_IO_QUEUE_IO_READ OsrFxEvtIoRead;
+
+EVT_WDF_IO_QUEUE_IO_WRITE OsrFxEvtIoWrite;
+
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL OsrFxEvtIoDeviceControl;
+
+EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestReadCompletionRoutine;
+
+EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestWriteCompletionRoutine;
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+ResetPipe(
+ _In_ WDFUSBPIPE Pipe
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+ResetDevice(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+SelectInterfaces(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+AbortPipes(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+ReenumerateDevice(
+ _In_ PDEVICE_CONTEXT DevContext
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+GetBarGraphState(
+ _In_ PDEVICE_CONTEXT DevContext,
+ _Out_ PBAR_GRAPH_STATE BarGraphState
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+SetBarGraphState(
+ _In_ PDEVICE_CONTEXT DevContext,
+ _In_ PBAR_GRAPH_STATE BarGraphState
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+GetSevenSegmentState(
+ _In_ PDEVICE_CONTEXT DevContext,
+ _Out_ PUCHAR SevenSegment
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+SetSevenSegmentState(
+ _In_ PDEVICE_CONTEXT DevContext,
+ _In_ PUCHAR SevenSegment
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+GetSwitchState(
+ _In_ PDEVICE_CONTEXT DevContext,
+ _In_ PSWITCH_STATE SwitchState
+ );
+
+_IRQL_requires_(DISPATCH_LEVEL)
+VOID
+OsrUsbIoctlGetInterruptMessage(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+OsrFxSetPowerPolicy(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+OsrFxConfigContReaderForInterruptEndPoint(
+ _In_ PDEVICE_CONTEXT DeviceContext
+ );
+
+EVT_WDF_USB_READER_COMPLETION_ROUTINE OsrFxEvtUsbInterruptPipeReadComplete;
+
+EVT_WDF_USB_READERS_FAILED OsrFxEvtUsbInterruptReadersFailed;
+
+EVT_WDF_IO_QUEUE_IO_STOP OsrFxEvtIoStop;
+
+EVT_WDF_DEVICE_D0_ENTRY OsrFxEvtDeviceD0Entry;
+
+EVT_WDF_DEVICE_D0_EXIT OsrFxEvtDeviceD0Exit;
+
+_IRQL_requires_(PASSIVE_LEVEL)
+BOOLEAN
+OsrFxReadFdoRegistryKeyValue(
+ _In_ PWDFDEVICE_INIT DeviceInit,
+ _In_ PWCHAR Name,
+ _Out_ PULONG Value
+ );
+
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
+OsrFxEnumerateChildren(
+ _In_ WDFDEVICE Device
+ );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+PCHAR
+DbgDevicePowerString(
+ _In_ WDF_POWER_DEVICE_STATE Type
+ );
+
+#endif
+
+
diff --git a/usb/kmdf_enumswitches/sys/rawpdo.c b/usb/kmdf_enumswitches/sys/rawpdo.c
new file mode 100644
index 00000000..2feb04e5
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/rawpdo.c
@@ -0,0 +1,330 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ Rawpdo.c
+
+Abstract:
+
+ This modules has routines to enumerate dip switches on the board
+ as child devices. We use dynamic enumeration interfaces to manage
+ child devices.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <osrusbfx2.h>
+#include "rawpdo.h"
+
+#include "rawpdo.tmh"
+
+VOID
+OsrFxInitChildList(
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+
+Routine Description:
+
+ This routine is called from the EvtDeviceAdd routine to initialize
+ the default child list.
+
+Arguments:
+
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ WDF_CHILD_LIST_CONFIG config;
+
+ //
+ // Init the default child list so that we can enumerate a raw PDO
+ //
+ WDF_CHILD_LIST_CONFIG_INIT(&config,
+ sizeof(PDO_IDENTIFICATION_DESCRIPTION),
+ OsrEvtDeviceListCreatePdo // callback to create a child device.
+ );
+ //
+ // Tell the framework to use the built-in devicelist to track the state
+ // of the device based on the configuration we just created.
+ //
+ WdfFdoInitSetDefaultChildListConfig(DeviceInit,
+ &config,
+ WDF_NO_OBJECT_ATTRIBUTES);
+
+ return;
+
+}
+
+
+NTSTATUS
+OsrEvtDeviceListCreatePdo(
+ WDFCHILDLIST DeviceList,
+ PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
+ PWDFDEVICE_INIT ChildInit
+ )
+/*++
+
+Routine Description:
+
+ Called by the framework in response to Query-Device relation when
+ a new PDO for a child device needs to be created.
+
+Arguments:
+
+ DeviceList - Handle to the default WDFCHILDLIST created by the
+ framework as part of FDO.
+
+ IdentificationDescription - Decription of the new child device.
+
+ ChildInit - It's a opaque structure used in collecting device settings
+ and passed in as a parameter to CreateDevice.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+{
+ NTSTATUS status;
+ WDFDEVICE hChild = NULL;
+ PPDO_IDENTIFICATION_DESCRIPTION pDesc;
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;
+ DECLARE_CONST_UNICODE_STRING(deviceId, OSRUSBFX2_SWITCH_DEVICE_ID );
+ DECLARE_CONST_UNICODE_STRING(hardwareId, OSRUSBFX2_SWITCH_DEVICE_ID );
+ DECLARE_CONST_UNICODE_STRING(deviceLocation, L"OSR USB-FX2 Learning Kit" );
+ DECLARE_UNICODE_STRING_SIZE(buffer, DEVICE_DESC_LENGTH);
+
+ UNREFERENCED_PARAMETER(DeviceList);
+
+ pDesc = CONTAINING_RECORD(IdentificationDescription,
+ PDO_IDENTIFICATION_DESCRIPTION,
+ Header);
+
+ //
+ // Mark the device RAW so that the child device can be started
+ // and accessed without requiring a function driver. Since we are
+ // creating a RAW PDO, we must provide a class guid.
+ //
+ status = WdfPdoInitAssignRawDevice(ChildInit, &GUID_DEVCLASS_OSRUSBFX2);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ //
+ // Since our devices for switches can trigger nuclear explosion,
+ // we must protect them from random users sending I/Os.
+ //
+ status = WdfDeviceInitAssignSDDLString(ChildInit,
+ &SDDL_DEVOBJ_SYS_ALL_ADM_ALL);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ status = WdfPdoInitAssignDeviceID(ChildInit, &deviceId);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ //
+ // On XP and later, there is no need to provide following IDs for raw pdos.
+ // BusQueryHardwareIDs but on On Win2K, we must provide a HWID and a NULL
+ // section in the INF to get the device installed without any problem.
+ //
+ status = WdfPdoInitAddHardwareID(ChildInit, &hardwareId);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ //
+ // Since we are enumerating more than one children, we must
+ // provide a BusQueryInstanceID. If we don't, system will throw
+ // CA bugcheck.
+ //
+ status = RtlUnicodeStringPrintf(&buffer, L"%02d", pDesc->SwitchNumber);
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ //
+ // Provide a description about the device. This text is usually read from
+ // the device. In the case of USB device, this text comes from the string
+ // descriptor. This text is displayed momentarily by the PnP manager while
+ // it's looking for a matching INF. If it finds one, it uses the Device
+ // Description from the INF file to display in the device manager.
+ // Since our device is raw device and we don't provide any hardware ID
+ // to match with an INF, this text will be displayed in the device manager.
+ //
+ status = RtlUnicodeStringPrintf(&buffer,
+ L"OsrUsbFX2 RawPdo For Switch %02d",
+ pDesc->SwitchNumber);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ //
+ // You can call WdfPdoInitAddDeviceText multiple times, adding device
+ // text for multiple locales. When the system displays the text, it
+ // chooses the text that matches the current locale, if available.
+ // Otherwise it will use the string for the default locale.
+ // The driver can specify the driver's default locale by calling
+ // WdfPdoInitSetDefaultLocale.
+ //
+ status = WdfPdoInitAddDeviceText(ChildInit,
+ &buffer,
+ &deviceLocation,
+ 0x409);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+ }
+
+ WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
+
+ status = WdfDeviceCreate(&ChildInit, WDF_NO_OBJECT_ATTRIBUTES, &hChild);
+ if (!NT_SUCCESS(status)) {
+ goto Cleanup;
+
+ }
+
+ //
+ // Set idle-time out on the child device. This is required to allow
+ // the parent device to idle-out when there are no active I/O.
+ //
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCannotWakeFromS0);
+ idleSettings.IdleTimeout = 1000; // 1-sec
+
+ status = WdfDeviceAssignS0IdleSettings(hChild, &idleSettings);
+ if ( !NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
+ "WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status);
+ return status;
+ }
+
+ return status;
+
+Cleanup:
+
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,"CreatePdo failed %x\n", status);
+
+ //
+ // On error, framework will cleanup all the resources when it deletes
+ // the device. So there is nothing to do.
+ //
+
+ return status;
+}
+
+_IRQL_requires_max_(DISPATCH_LEVEL)
+VOID
+OsrFxEnumerateChildren(
+ _In_ WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ This routine configures a continuous reader on the
+ interrupt endpoint.
+
+Arguments:
+
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ WDFCHILDLIST list;
+ UCHAR i;
+ NTSTATUS status;
+ PDEVICE_CONTEXT pDeviceContext;
+
+ pDeviceContext = GetDeviceContext(Device);
+
+ list = WdfFdoGetDefaultChildList(Device);
+
+ WdfChildListBeginScan(list);
+
+ //
+ // A call to WdfChildListBeginScan indicates to the framework that the
+ // driver is about to scan for dynamic children. If the driver doesn't
+ // call either WdfChildListUpdateChildDescriptionAsPresent or
+ // WdfChildListMarkAllChildDescriptionsPresent before WdfChildListEndScan is,
+ // called, all the previously reported children will be reported as missing
+ // to the PnP subsystem.
+ //
+ for(i=0; i< RTL_BITS_OF(UCHAR); i++) {
+
+ //
+ // Report every set bit in the switchstate as a child device.
+ //
+ if(pDeviceContext->CurrentSwitchState & (1<<i)) {
+
+ PDO_IDENTIFICATION_DESCRIPTION description;
+
+ //
+ // Initialize the description with the information about the newly
+ // plugged in device.
+ //
+ WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(
+ &description.Header,
+ sizeof(description)
+ );
+
+ //
+ // Since switches are marked in the wrong order on the board,
+ // we will fix it here so that the DM display matches with the
+ // board.
+ //
+ description.SwitchNumber = RTL_BITS_OF(UCHAR)-i;
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
+ "Switch %d is ON\n", description.SwitchNumber);
+
+ //
+ // Call the framework to add this child to the devicelist. This call
+ // will internaly call our DescriptionCompare callback to check
+ // whether this device is a new device or existing device. If
+ // it's a new device, the framework will call DescriptionDuplicate to create
+ // a copy of this description in nonpaged pool.
+ // The actual creation of the child device will happen when the framework
+ // receives QUERY_DEVICE_RELATION request from the PNP manager in
+ // response to InvalidateDevice relation call made as part of adding
+ // a new child.
+ //
+ status = WdfChildListAddOrUpdateChildDescriptionAsPresent(
+ list,
+ &description.Header,
+ NULL); // AddressDescription
+
+ if (status == STATUS_OBJECT_NAME_EXISTS) {
+ }
+
+ }
+ }
+
+
+ WdfChildListEndScan(list);
+
+ return;
+}
+
diff --git a/usb/kmdf_enumswitches/sys/rawpdo.h b/usb/kmdf_enumswitches/sys/rawpdo.h
new file mode 100644
index 00000000..66eab3e1
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/rawpdo.h
@@ -0,0 +1,60 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ Rawpdo.h
+
+Abstract:
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#ifndef _RAWPDO_H
+#define _RAWPDO_H
+
+#ifndef RTL_BITS_OF
+// This macro is not defined in Win2k ntdef.h
+#define RTL_BITS_OF(sizeOfArg) (sizeof(sizeOfArg) * 8)
+#endif
+
+//
+// Used to identify kbfilter bus. This guid is used as the enumeration string
+// for the device id.
+DEFINE_GUID(GUID_BUS_OSRUSBFX2_RAWPDO,
+0x556cf9d3, 0xe853, 0x4dfb, 0xa2, 0x16, 0x5d, 0x75, 0x6d, 0xf2, 0xc1, 0x7a);
+// {556CF9D3-E853-4dfb-A216-5D756DF2C17A}
+
+
+DEFINE_GUID(GUID_DEVCLASS_OSRUSBFX2,
+0x6fde7521, 0x1b65, 0x48ae, 0xb6, 0x28, 0x80, 0xbe, 0x62, 0x1, 0x60, 0x26);
+// {6FDE7521-1B65-48ae-B628-80BE62016026}
+
+// \0 in the end is for double termination - required for MULTI_SZ string
+#define OSRUSBFX2_SWITCH_DEVICE_ID L"{6FDE7521-1B65-48ae-B628-80BE62016026}\\OsrUsbFxRawPdo\0"
+
+typedef struct _PDO_IDENTIFICATION_DESCRIPTION
+{
+ WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Header; // should contain this header
+
+ ULONG SwitchNumber;
+
+} PDO_IDENTIFICATION_DESCRIPTION, *PPDO_IDENTIFICATION_DESCRIPTION;
+
+VOID
+OsrFxInitChildList(
+ IN PWDFDEVICE_INIT DeviceInit
+ );
+
+EVT_WDF_CHILD_LIST_CREATE_DEVICE OsrEvtDeviceListCreatePdo;
+
+#endif
diff --git a/usb/kmdf_enumswitches/sys/trace.h b/usb/kmdf_enumswitches/sys/trace.h
new file mode 100644
index 00000000..518ff5f1
--- /dev/null
+++ b/usb/kmdf_enumswitches/sys/trace.h
@@ -0,0 +1,115 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ 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.
+
+Module Name:
+
+ TRACE.h
+
+Abstract:
+
+ Header file for the debug tracing related function defintions and macros.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include <evntrace.h> // For TRACE_LEVEL definitions
+
+#if !defined(EVENT_TRACING)
+
+//
+// TODO: These defines are missing in evntrace.h
+// in some DDK build environments (XP).
+//
+#if !defined(TRACE_LEVEL_NONE)
+ #define TRACE_LEVEL_NONE 0
+ #define TRACE_LEVEL_CRITICAL 1
+ #define TRACE_LEVEL_FATAL 1
+ #define TRACE_LEVEL_ERROR 2
+ #define TRACE_LEVEL_WARNING 3
+ #define TRACE_LEVEL_INFORMATION 4
+ #define TRACE_LEVEL_VERBOSE 5
+ #define TRACE_LEVEL_RESERVED6 6
+ #define TRACE_LEVEL_RESERVED7 7
+ #define TRACE_LEVEL_RESERVED8 8
+ #define TRACE_LEVEL_RESERVED9 9
+#endif
+
+
+//
+// Define Debug Flags
+//
+#define DBG_INIT 0x00000001
+#define DBG_PNP 0x00000002
+#define DBG_POWER 0x00000004
+#define DBG_WMI 0x00000008
+#define DBG_CREATE_CLOSE 0x00000010
+#define DBG_IOCTL 0x00000020
+#define DBG_WRITE 0x00000040
+#define DBG_READ 0x00000080
+
+
+VOID
+TraceEvents (
+ _In_ ULONG DebugPrintLevel,
+ _In_ ULONG DebugPrintFlag,
+ _Printf_format_string_
+ _In_ PCSTR DebugMessage,
+ ...
+ );
+
+#define WPP_INIT_TRACING(DriverObject, RegistryPath)
+#define WPP_CLEANUP(DriverObject)
+
+#else
+//
+// If software tracing is defined in the sources file..
+// WPP_DEFINE_CONTROL_GUID specifies the GUID used for this driver.
+// *** REPLACE THE GUID WITH YOUR OWN UNIQUE ID ***
+// WPP_DEFINE_BIT allows setting debug bit masks to selectively print.
+// The names defined in the WPP_DEFINE_BIT call define the actual names
+// that are used to control the level of tracing for the control guid
+// specified.
+//
+// NOTE: If you are adopting this sample for your driver, please generate
+// a new guid, using tools\other\i386\guidgen.exe present in the
+// DDK.
+//
+// Name of the logger is OSRUSBFX2 and the guid is
+// {D23A0C5A-D307-4f0e-AE8E-E2A355AD5DAB}
+// (0xd23a0c5a, 0xd307, 0x4f0e, 0xae, 0x8e, 0xe2, 0xa3, 0x55, 0xad, 0x5d, 0xab);
+//
+
+#define WPP_CHECK_FOR_NULL_STRING //to prevent exceptions due to NULL strings
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID(OsrUsbFxTraceGuid,(d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
+ WPP_DEFINE_BIT(DBG_INIT) /* bit 0 = 0x00000001 */ \
+ WPP_DEFINE_BIT(DBG_PNP) /* bit 1 = 0x00000002 */ \
+ WPP_DEFINE_BIT(DBG_POWER) /* bit 2 = 0x00000004 */ \
+ WPP_DEFINE_BIT(DBG_WMI) /* bit 3 = 0x00000008 */ \
+ WPP_DEFINE_BIT(DBG_CREATE_CLOSE) /* bit 4 = 0x00000010 */ \
+ WPP_DEFINE_BIT(DBG_IOCTL) /* bit 5 = 0x00000020 */ \
+ WPP_DEFINE_BIT(DBG_WRITE) /* bit 6 = 0x00000040 */ \
+ WPP_DEFINE_BIT(DBG_READ) /* bit 7 = 0x00000080 */ \
+ /* You can have up to 32 defines. If you want more than that,\
+ you have to provide another trace control GUID */\
+ )
+
+
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
+
+
+#endif
+
+
+