diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /usb | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'usb')
147 files changed, 66038 insertions, 0 deletions
diff --git a/usb/kmdf_enumswitches/ReadMe.md b/usb/kmdf_enumswitches/ReadMe.md new file mode 100644 index 00000000..2107d9b8 --- /dev/null +++ b/usb/kmdf_enumswitches/ReadMe.md @@ -0,0 +1,47 @@ +Sample KMDF Bus Driver for OSR USB-FX2 +====================================== + +The kmdf\_enumswitches sample demonstrates how to use Kernel-Mode Driver Framework (KMDF) as a bus driver using the OSR USB-FX2 device. + +This sample is written for the OSR USB-FX2 Learning Kit. The specification for the device is at <http://www.osronline.com/hardware/OSRFX2_32.pdf>. + +Testing the Device +------------------ + +To test the device, follow these steps: + +1. If you test signed your driver package, you must enable installation of test signed drivers on the target machine. To do so, either press F8 as the target machine comes up from a reboot, or specify **Bcdedit.exe -set TESTSIGNING ON** and reboot. If you use F8, the change only applies until the next reboot. +2. Plug in the OSR USB-FX-2 Learning Kit (must be version 2.00 or later). +3. In Device Manager, select **Update Driver Software**, **Browse my computer for driver software**, **Let me pick from a list of device drivers on my computer**, **Have Disk**. Navigate to the directory that contains your driver package and select the INF file. +4. After the driver installs, verify that the device appears under the **Sample Device** node in Device Manager. +5. Flip the switches on the OSR USB-FX-2 hardware board and watch the raw PDO entries appear and disappear under **Sample Device** in Device Manager. +6. Right-click a raw PDO entry, select **Properties**, and then click the **Events** tab. Under **Information**, examine the hardware ID for the PDO. It should be something like this: + + ``` {.syntax xml:space="preserve"} + 6FDE7521-1B65-48ae-B628-80BE62016026}\OsrUsbFxRawPdo\6&227995e2&0&08 + ``` + + The last digit matches the number of the switch that you toggled. + +Hardware Overview +----------------- + +Here is the overview of the device: + +- Device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681). +- Contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN). +- Firmware supports vendor commands to query or set LED Bar graph display, 7-segment LED display and query toggle switch states. +- Interrupt Endpoint: + - Sends an 8-bit value that represents the state of the switches. + - Sent on startup, resume from suspend, and whenever the switch pack setting changes. + - Firmware does not de-bounce the switch pack. + - One switch change can result in multiple bytes being sent. + - Bits are in the reverse order of the labels on the pack + + E.g. bit 0x80 is labeled 1 on the pack + +- Bulk Endpoints are configured for loopback: + - Device moves data from IN endpoint to OUT endpoint. + - Device does not change the values of the data it receives nor does it internally create any data. + - Endpoints are always double buffered. + - Maximum packet size depends on speed (64 Full speed, 512 High speed). diff --git a/usb/kmdf_enumswitches/inc/prototypes.h b/usb/kmdf_enumswitches/inc/prototypes.h new file mode 100644 index 00000000..cc99cdfe --- /dev/null +++ b/usb/kmdf_enumswitches/inc/prototypes.h @@ -0,0 +1,14 @@ +DRIVER_INITIALIZE DriverEntry; + +EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd; + +EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDriverContextCleanup; +EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; + +EVT_WDF_IO_QUEUE_IO_READ EvtIoRead; +EVT_WDF_IO_QUEUE_IO_WRITE EvtIoWrite; +EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl; + +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestReadCompletionRoutine; +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestWriteCompletionRoutine; + diff --git a/usb/kmdf_enumswitches/inc/public.h b/usb/kmdf_enumswitches/inc/public.h new file mode 100644 index 00000000..12ddf21f --- /dev/null +++ b/usb/kmdf_enumswitches/inc/public.h @@ -0,0 +1,173 @@ +/*++ + +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: + + public.h + +Abstract: + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + +#pragma warning(push) +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +#include <poppack.h> + +#pragma warning(pop) + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 0x65500 + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#endif diff --git a/usb/kmdf_enumswitches/kmdf_enumswitches.sln b/usb/kmdf_enumswitches/kmdf_enumswitches.sln new file mode 100644 index 00000000..0b3f4a9a --- /dev/null +++ b/usb/kmdf_enumswitches/kmdf_enumswitches.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kmdf_enumswitches", "sys\kmdf_enumswitches.vcxproj", "{6A32E70D-E961-4940-A1E8-AB1A7CED390D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Debug|Win32.ActiveCfg = Debug|Win32 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Debug|Win32.Build.0 = Debug|Win32 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Release|Win32.ActiveCfg = Release|Win32 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Release|Win32.Build.0 = Release|Win32 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Debug|x64.ActiveCfg = Debug|x64 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Debug|x64.Build.0 = Debug|x64 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Release|x64.ActiveCfg = Release|x64 + {6A32E70D-E961-4940-A1E8-AB1A7CED390D}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal 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 + + + diff --git a/usb/umdf2_fx2/ReadMe.md b/usb/umdf2_fx2/ReadMe.md new file mode 100644 index 00000000..74e1885e --- /dev/null +++ b/usb/umdf2_fx2/ReadMe.md @@ -0,0 +1,326 @@ +Sample UMDF Function Driver for OSR USB-FX2 (UMDF Version 1) +============================================================ + +The umdf\_fx2 sample is a User-Mode Driver Framework (UMDF) driver for the OSR USB-FX2 device. It includes a test app and sample device metadata, and supports impersonation and idle power down. + +## Universal Compliant +This sample builds a Windows Universal driver. It uses only APIs and DDIs that are included in Windows Core. + +The sample can also be used with the CustomDeviceAccess MSDK sample. The sample demonstrates how to perform bulk and interrupt data transfers to an USB device. The specification for the device is at <http://www.osronline.com/hardware/OSRFX2_32.pdf>. The driver and sample device metadata also work with the [Custom driver access](http://go.microsoft.com/fwlink/p/?LinkID=248288) sample. + +Starting in Windows 8.1, the osrusbfx2 sample has been divided into these samples: + +- [WDF Sample Driver Learning Lab for OSR USB-FX2](http://msdn.microsoft.com/en-us/library/windows/hardware/): This sample is a series of iterative drivers that demonstrate how to write a "Hello World" driver and adds additional features in each step. + +- [kmdf\_fx2](gallery_samples.123a_gallery#1): This sample is the final version of kernel-mode [wdf\_osrfx2](http://msdn.microsoft.com/en-us/library/windows/hardware/) driver. The sample demonstrates KMDF methods. + +- umdf\_fx2: This sample is the final version of the user-mode driver [wdf\_osrfx2](http://msdn.microsoft.com/en-us/library/windows/hardware/). The sample demonstrates UMDF methods. + +Overview +-------- + +Here is the overview of the device: + +- The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681). +- It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN). +- Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states. +- Interrupt Endpoint: + - Sends an 8-bit value that represents the state of the switches. + - Sent on startup, resume from suspend, and whenever the switch pack setting changes. + - Firmware does not de-bounce the switch pack. + - One switch change can result in multiple bytes being sent. + - Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack). +- Bulk Endpoints are configured for loopback: + - The device moves data from IN endpoint to OUT endpoint. + - The device does not change the values of the data it receives nor does it internally create any data. + - Endpoints are always double buffered. + - Maximum packet size depends on speed (64 full speed, 512 high speed). + +Testing the driver +------------------ + +You can use the [Custom driver access](http://go.microsoft.com/fwlink/p/?LinkID=248288) sample to test the umdf\_fx2 sample. + +This sample also includes a test application, osrusbfx2.exe, that you can use to test the device. This console application enumerates the interface registered by the driver and opens the device to send read, write, or IOCTL requests based on the command line options. + +Usage for Read/Write test: + +- -r [*n*], where *n* is number of bytes to read. +- -w [*n*], where *n* is number of bytes to write. +- -c [*n*], where *n* is number of iterations (default = 1). +- -v, shows verbose read data. +- -p, plays with Bar Display, Dip Switch, 7-Segment Display. +- -a, performs asynchronous I/O operation. +- -u, dumps USB configuration and pipe information. +- -f \<*filename*\> [*interval-seconds*], where *interval-seconds* is a delay in milliseconds, to send a text file to the seven-segment display (UMDF only) + +**Playing with the 7 segment display, toggle switches, and bar graph display** + +Use the command **osrusbfx2.exe -p** with options 1 through 9 to set and clear bar graph display, set and get 7 segment state, and read the toggle switch states. The following shows the function options: + +1. Light Bar +2. Clear Bar +3. Light entire Bar graph +4. Clear entire Bar graph +5. Get bar graph state +6. Get Switch state +7. Get Switch Interrupt Message +8. Get 7 segment state +9. Set 7 segment state +10. Reset the device +11. Re-enumerate the device + +0. Exit + +Selection: + +**Reset and re-enumerate the device** + +Use the command **osrusbfx2.exe -p** with options 10 and 11 to either reset the device or re-enumerate the device. + +**Read and write to bulk endpoints** + +The following commands send read and write requests to the device's bulk endpoint. + +- `osrusbfx2.exe -r 64` + + The preceding command reads 64 bytes to the bulk IN endpoint. + +- `osrusbfx2.exe -w 64 ` + + The preceding command writes 64 bytes to the bulk OUT endpoint. + +- `osrusbfx2.exe -r 64 -w 64 -c 100 -v` + + The preceding command first writes 64 bytes of data to bulk OUT endpoint (Pipe 1), then reads 64 bytes from bulk IN endpoint (Pipe 2), and then compares the read buffer with write buffer to see if they match. If the buffer contents match, it repeats this operation 100 times. + +- `osrusbfx2.exe -a` + + The preceding command reads and writes to the device asynchronously in an infinite loop. + +The bulk endpoints are double buffered. Depending on the operational speed (full or high), the buffer size is either 64 bytes or 512 bytes, respectively. A request to read data does not complete if the buffers are empty. If the buffers are full, a request to write data does not complete until the buffers are emptied. When you are doing a synchronous read, make sure the endpoint buffer has data (for example, when you send 512 bytes write request to the device operating in full speed mode). Because the endpoints are double buffered, the total buffer capacity is 256 bytes. The first 256 bytes fills the buffer and the write request waits in the USB stack until the buffers are emptied. If you run another instance of the application to read 512 bytes of data, both write and read requests complete successfully. + +**Displaying descriptors** + +The following command displays all the descriptors and endpoint information. + +**osrusbfx2.exe -u** + +If the device is operating in high speed mode, you get the following information: + +`===================` + +`USB_CONFIGURATION_DESCRIPTOR` + +`bLength = 0x9, decimal 9` + +`bDescriptorType = 0x2 ( USB_CONFIGURATION_DESCRIPTOR_TYPE )` + +`wTotalLength = 0x27, decimal 39` + +`bNumInterfaces = 0x1, decimal 1` + +`bConfigurationValue = 0x1, decimal 1` + +`iConfiguration = 0x4, decimal 4` + +`bmAttributes = 0xa0 ( USB_CONFIG_BUS_POWERED )` + +`MaxPower = 0x32, decimal 50` + +`-----------------------------` + +`USB_INTERFACE_DESCRIPTOR #0` + +`bLength = 0x9` + +`bDescriptorType = 0x4 ( USB_INTERFACE_DESCRIPTOR_TYPE )` + +`bInterfaceNumber = 0x0` + +`bAlternateSetting = 0x0` + +`bNumEndpoints = 0x3` + +`bInterfaceClass = 0xff` + +`bInterfaceSubClass = 0x0` + +`bInterfaceProtocol = 0x0` + +`bInterface = 0x0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe00` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x81 ( INPUT )` + +`bmAttributes= 0x3 ( USB_ENDPOINT_TYPE_INTERRUPT )` + +`wMaxPacketSize= 0x49, decimal 73` + +`bInterval = 0x1, decimal 1` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe01` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x6 ( OUTPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x200, ` + +`decimal 512 bInterval = 0x0, ` + +`decimal 0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe02` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x88 ( INPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x200, decimal 512` + +`bInterval = 0x0, decimal 0` + +If the device is operating in low speed mode, you will get the following information: + +`===================` + +`USB_CONFIGURATION_DESCRIPTOR` + +`bLength = 0x9, decimal 9` + +`bDescriptorType = 0x2 ( USB_CONFIGURATION_DESCRIPTOR_TYPE )` + +`wTotalLength = 0x27, decimal 39` + +`bNumInterfaces = 0x1, decimal 1` + +`bConfigurationValue = 0x1, decimal 1` + +`iConfiguration = 0x3, decimal 3` + +`bmAttributes = 0xa0 ( USB_CONFIG_BUS_POWERED )` + +`MaxPower = 0x32, decimal 50 ` + +`-----------------------------` + +`USB_INTERFACE_DESCRIPTOR #0` + +`bLength = 0x9` + +`bDescriptorType = 0x4 ( USB_INTERFACE_DESCRIPTOR_TYPE )` + +`bInterfaceNumber = 0x0 bAlternateSetting = 0x0` + +`bNumEndpoints = 0x3` + +`bInterfaceClass = 0xff` + +`bInterfaceSubClass = 0x0` + +`bInterfaceProtocol = 0x0` + +`bInterface = 0x0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe00` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x81 ( INPUT )` + +`bmAttributes= 0x3 ( USB_ENDPOINT_TYPE_INTERRUPT )` + +`wMaxPacketSize= 0x49, decimal 73` + +`bInterval = 0x1, decimal 1` + +`------- -----------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe01` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x6 ( OUTPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x40, decimal 64` + +`bInterval = 0x0, decimal 0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe02` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x88 ( INPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x40, decimal 64` + +`bInterval = 0x0, decimal 0 ` + +Sample Contents +--------------- + +Folder + +Description + +usb\\umdf\_fx2\\driver + +This directory contains driver code that demonstrates the following functionality: + +- Loads the driver and responds to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system. +- Registers a PnP device interface so that application can open a handle to the device. +- Implements **IPnpCallbackHardware** interface and initializes USB I/O targets in **IPnpCallbackHardware::OnPrepareHardware** method. +- Creates a sequential queue for handling IOCTL requests. +- Adds code to handle the IOCTL to set bar graph display. +- Creates a parallel queue for handling read and write requests. +- Retrieves memory from read and write requests, format the requests, and sends them to a USB target. +- Supports additional IOCTLs to get and set the 7-segment display, get bar graph display, and get config descriptor. +- Sets power policy for the device. +- Adds code to indicate that the device is ready by lighting up the period on 7-segment display. +- Calls **SetupDi** functions to determine the "BusTypeGUID" of the device, and uses impersonation to access resources that only the caller has access to. +- Shows how to implement idle and wake functionality to make the driver the power policy owner (PPO). The sample achieves this using power-managed queues and UMDF DDIs, AssignS0IdleSettings, and AssignSxWakeSettings. +- Demonstrates implementation of a continuous reader. +- Demonstrates the use of impersonation. + +usb\\umdf\_fx2\\exe + +This directory contains a test application that can be used to drive the UMDF driver and FX2 device. This is a modified version of the test application for the KMDF Fx2 driver. + +usb\\umdf\_fx2\\deviceMetadata + +This directory contains the device metadata package for the sample. You must copy the device metadata to the system before installing the device. For information on how to update and deploy device metadata, see [Custom driver access sample](http://go.microsoft.com/fwlink/p/?LinkID=248288). + diff --git a/usb/umdf2_fx2/deviceMetadata/B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms b/usb/umdf2_fx2/deviceMetadata/B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms Binary files differnew file mode 100644 index 00000000..5f8e82ee --- /dev/null +++ b/usb/umdf2_fx2/deviceMetadata/B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms diff --git a/usb/umdf2_fx2/driver/Device.c b/usb/umdf2_fx2/driver/Device.c new file mode 100644 index 00000000..0003dad7 --- /dev/null +++ b/usb/umdf2_fx2/driver/Device.c @@ -0,0 +1,911 @@ +/*++ + +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: + + User mode only + + +--*/ + +#include <osrusbfx2.h> +#include <devpkey.h> + +#if defined(EVENT_TRACING) +#include "device.tmh" +#endif + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, OsrFxEvtDeviceAdd) +#pragma alloc_text(PAGE, OsrFxEvtDevicePrepareHardware) +#pragma alloc_text(PAGE, OsrFxEvtDeviceD0Exit) +#pragma alloc_text(PAGE, SelectInterfaces) +#pragma alloc_text(PAGE, OsrFxSetPowerPolicy) +#pragma alloc_text(PAGE, OsrFxReadFdoRegistryKeyValue) +#pragma alloc_text(PAGE, GetDeviceEventLoggingNames) +#endif + + +NTSTATUS +OsrFxEvtDeviceAdd( + WDFDRIVER Driver, + 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; + WDF_DEVICE_PNP_CAPABILITIES pnpCaps; + WDF_IO_QUEUE_CONFIG ioQueueConfig; + PDEVICE_CONTEXT pDevContext; + WDFQUEUE queue; + GUID activity; + + 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 wdfusb pipe continuous reader + // as we go in and out of the D0-working state. + // + + pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry; + pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit; + pnpPowerCallbacks.EvtDeviceSelfManagedIoFlush = OsrFxEvtDeviceSelfManagedIoFlush; + + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered); + + // + // 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; + } + + // + // Setup the activity ID so that we can log events using it. + // + + activity = DeviceToActivityId(device); + + // + // Get the DeviceObject context by using accessor function specified in + // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for DEVICE_CONTEXT. + // + pDevContext = GetDeviceContext(device); + + // + // Get the device's friendly name and location so that we can use it in + // error logging. If this fails then it will setup dummy strings. + // + + GetDeviceEventLoggingNames(device); + + // + // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so + // that you don't get the popup in usermodewhen you surprise remove the device. + // + WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); + pnpCaps.SurpriseRemovalOK = WdfTrue; + + WdfDeviceSetPnpCapabilities(device, &pnpCaps); + + // + // Create a parallel default queue and register an event callback to + // receive ioctl requests. We will create separate queues for + // handling read and write requests. All other requests will be + // completed with error status automatically by the framework. + // + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, + WdfIoQueueDispatchParallel); + + ioQueueConfig.EvtIoDeviceControl = OsrFxEvtIoDeviceControl; + + // + // By default, Static Driver Verifier (SDV) displays a warning if it + // doesn't find the EvtIoStop callback on a power-managed queue. + // The 'assume' below causes SDV to suppress this warning. If the driver + // has not explicitly set PowerManaged to WdfFalse, the framework creates + // power-managed queues when the device is not a filter driver. Normally + // the EvtIoStop is required for power-managed queues, but for this driver + // it is not needed b/c the driver doesn't hold on to the requests for + // long time or forward them to other drivers. + // If the EvtIoStop callback is not implemented, the framework waits for + // all driver-owned requests to be done before moving in the Dx/sleep + // states or before removing the device, which is the correct behavior + // for this type of driver. If the requests were taking an indeterminate + // amount of time to complete, or if the driver forwarded the requests + // to a lower driver/another stack, the queue should have an + // EvtIoStop/EvtIoResume. + // + __analysis_assume(ioQueueConfig.EvtIoStop != 0); + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue);// pointer to default queue + __analysis_assume(ioQueueConfig.EvtIoStop == 0); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed %!STATUS!\n", status); + goto Error; + } + + // + // We will create a separate sequential queue and configure it + // to receive read requests. We also need to register a EvtIoStop + // handler so that we can acknowledge requests that are pending + // at the target driver. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential); + + ioQueueConfig.EvtIoRead = OsrFxEvtIoRead; + ioQueueConfig.EvtIoStop = OsrFxEvtIoStop; + + status = WdfIoQueueCreate( + device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue // queue handle + ); + + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + status = WdfDeviceConfigureRequestDispatching( + device, + queue, + WdfRequestTypeRead); + + if(!NT_SUCCESS (status)){ + assert(NT_SUCCESS(status)); + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status); + goto Error; + } + + + // + // We will create another sequential queue and configure it + // to receive write requests. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential); + + ioQueueConfig.EvtIoWrite = OsrFxEvtIoWrite; + ioQueueConfig.EvtIoStop = OsrFxEvtIoStop; + + status = WdfIoQueueCreate( + device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue // queue handle + ); + + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + status = WdfDeviceConfigureRequestDispatching( + device, + queue, + WdfRequestTypeWrite); + + if(!NT_SUCCESS (status)){ + assert(NT_SUCCESS(status)); + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status); + goto Error; + } + + // + // Register a manual I/O queue for handling Interrupt Message Read Requests. + // This queue will be used for storing Requests that need to wait for an + // interrupt to occur before they can be completed. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchManual); + + // + // This queue is used for requests that dont directly access the device. The + // requests in this queue are serviced only when the device is in a fully + // powered state and sends an interrupt. So we can use a non-power managed + // queue to park the requests since we dont care whether the device is idle + // or fully powered up. + // + ioQueueConfig.PowerManaged = WdfFalse; + + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &pDevContext->InterruptMsgQueue + ); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + // + // Register a device interface so that app can find our device and talk to it. + // + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL); // Reference String + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceCreateDeviceInterface failed %!STATUS!\n", status); + goto Error; + } + + // + // Create the lock that we use to serialize calls to ResetDevice(). As an + // alternative to using a WDFWAITLOCK to serialize the calls, a sequential + // WDFQUEUE can be created and reset IOCTLs would be forwarded to it. + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfWaitLockCreate(&attributes, &pDevContext->ResetDeviceWaitLock); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfWaitLockCreate failed %!STATUS!\n", status); + goto Error; + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- OsrFxEvtDeviceAdd\n"); + + return status; + +Error: + + // + // Log fail to add device to the event log + // + EventWriteFailAddDevice(pDevContext->DeviceName, + pDevContext->Location, + status); + + return status; +} + +NTSTATUS +OsrFxEvtDevicePrepareHardware( + WDFDEVICE Device, + WDFCMRESLIST ResourceList, + 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 + + ResourceList - handle to a resource-list object that identifies the + raw hardware resources that the PnP manager assigned + to the device + + ResourceListTranslated - handle to a resource-list object that + identifies the translated hardware resources + that the PnP manager assigned to the device + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_INFORMATION deviceInfo; + ULONG waitWakeEnable; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + waitWakeEnable = FALSE; + 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) { + status = WdfUsbTargetDeviceCreate(Device, + WDF_NO_OBJECT_ATTRIBUTES, + &pDeviceContext->UsbDevice); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfUsbTargetDeviceCreate failed with Status code %!STATUS!\n", status); + return status; + } + } + + // + // Retrieve USBD version information, port driver capabilites and device + // capabilites such as speed, power, etc. + // + WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo); + + status = WdfUsbTargetDeviceRetrieveInformation( + pDeviceContext->UsbDevice, + &deviceInfo); + if (NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "IsDeviceHighSpeed: %s\n", + (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? "TRUE" : "FALSE"); + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, + "IsDeviceSelfPowered: %s\n", + (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? "TRUE" : "FALSE"); + + waitWakeEnable = deviceInfo.Traits & + WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE; + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, + "IsDeviceRemoteWakeable: %s\n", + waitWakeEnable ? "TRUE" : "FALSE"); + // + // Save these for use later. + // + pDeviceContext->UsbDeviceTraits = deviceInfo.Traits; + } + else { + pDeviceContext->UsbDeviceTraits = 0; + } + + status = SelectInterfaces(Device); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "SelectInterfaces failed 0x%x\n", status); + return status; + } + + // + // Enable wait-wake and idle timeout if the device supports it + // + if (waitWakeEnable) { + status = OsrFxSetPowerPolicy(Device); + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "OsrFxSetPowerPolicy failed %!STATUS!\n", status); + return status; + } + } + + status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n"); + + return status; +} + + +NTSTATUS +OsrFxEvtDeviceD0Entry( + WDFDEVICE Device, + 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; + BOOLEAN isTargetStarted; + + pDeviceContext = GetDeviceContext(Device); + isTargetStarted = FALSE; + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, + "-->OsrFxEvtEvtDeviceD0Entry - coming from %s\n", + DbgDevicePowerString(PreviousState)); + + // + // Since continuous reader is configured for this interrupt-pipe, we must explicitly start + // the I/O target to get the framework to post read requests. + // + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe)); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_POWER, "Failed to start interrupt pipe %!STATUS!\n", status); + goto End; + } + + isTargetStarted = TRUE; + +End: + + if (!NT_SUCCESS(status)) { + // + // Failure in D0Entry will lead to device being removed. So let us stop the continuous + // reader in preparation for the ensuing remove. + // + if (isTargetStarted) { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); + } + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtEvtDeviceD0Entry\n"); + + return status; +} + + +NTSTATUS +OsrFxEvtDeviceD0Exit( + WDFDEVICE Device, + 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(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtDeviceD0Exit\n"); + + return STATUS_SUCCESS; +} + +VOID +OsrFxEvtDeviceSelfManagedIoFlush( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This routine handles flush activity for the device's + self-managed I/O operations. + +Arguments: + + Device - Handle to a framework device object. + +Return Value: + + None + +--*/ +{ + // Service the interrupt message queue to drain any outstanding + // requests + OsrUsbIoctlGetInterruptMessage(Device, STATUS_DEVICE_REMOVED); +} + + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +OsrFxSetPowerPolicy( + _In_ WDFDEVICE Device + ) +{ + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; + WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings; + NTSTATUS status = STATUS_SUCCESS; + + PAGED_CODE(); + + // + // Init the idle policy structure. + // + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleUsbSelectiveSuspend); + idleSettings.IdleTimeout = 10000; // 10-sec + + status = WdfDeviceAssignS0IdleSettings(Device, &idleSettings); + if ( !NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status); + return status; + } + + // + // Init wait-wake policy structure. + // + WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings); + + status = WdfDeviceAssignSxWakeSettings(Device, &wakeSettings); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceAssignSxWakeSettings failed %x\n", status); + return status; + } + + return status; +} + + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SelectInterfaces( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This helper routine selects the configuration, interface and + creates a context for every pipe (end point) in that interface. + +Arguments: + + Device - Handle to a framework device + +Return Value: + + NT status value + +--*/ +{ + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + NTSTATUS status = STATUS_SUCCESS; + PDEVICE_CONTEXT pDeviceContext; + WDFUSBPIPE pipe; + WDF_USB_PIPE_INFORMATION pipeInfo; + UCHAR index; + UCHAR numberConfiguredPipes; + WDFUSBINTERFACE usbInterface; + + PAGED_CODE(); + + pDeviceContext = GetDeviceContext(Device); + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams); + + usbInterface = + WdfUsbTargetDeviceGetInterface(pDeviceContext->UsbDevice, 0); + + if (NULL == usbInterface) { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfUsbTargetDeviceGetInterface 0 failed %!STATUS! \n", + status); + return status; + } + + configParams.Types.SingleInterface.ConfiguredUsbInterface = + usbInterface; + + configParams.Types.SingleInterface.NumberConfiguredPipes = + WdfUsbInterfaceGetNumConfiguredPipes(usbInterface); + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + + numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes; + + // + // Get pipe handles + // + for(index=0; index < numberConfiguredPipes; index++) { + + WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo); + + pipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + index, //PipeIndex, + &pipeInfo + ); + // + // Tell the framework that it's okay to read less than + // MaximumPacketSize + // + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe); + + if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "Interrupt Pipe is 0x%p\n", pipe); + pDeviceContext->InterruptPipe = pipe; + } + + if(WdfUsbPipeTypeBulk == pipeInfo.PipeType && + WdfUsbTargetPipeIsInEndpoint(pipe)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "BulkInput Pipe is 0x%p\n", pipe); + pDeviceContext->BulkReadPipe = pipe; + } + + if(WdfUsbPipeTypeBulk == pipeInfo.PipeType && + WdfUsbTargetPipeIsOutEndpoint(pipe)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "BulkOutput Pipe is 0x%p\n", pipe); + pDeviceContext->BulkWritePipe = pipe; + } + + } + + // + // If we didn't find all the 3 pipes, fail the start. + // + if(!(pDeviceContext->BulkWritePipe + && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) { + status = STATUS_INVALID_DEVICE_STATE; + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "Device is not configured properly %!STATUS!\n", + status); + + return status; + } + + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +VOID +GetDeviceEventLoggingNames( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + Retrieve the friendly name and the location string into WDFMEMORY objects + and store them in the device context. + +Arguments: + +Return Value: + + None + +--*/ +{ + PDEVICE_CONTEXT pDevContext = GetDeviceContext(Device); + + WDF_OBJECT_ATTRIBUTES objectAttributes; + + WDFMEMORY deviceNameMemory = NULL; + WDFMEMORY locationMemory = NULL; + + NTSTATUS status; + + PAGED_CODE(); + + // + // We want both memory objects to be children of the device so they will + // be deleted automatically when the device is removed. + // + + WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); + objectAttributes.ParentObject = Device; + + // + // First get the length of the string. If the FriendlyName + // is not there then get the lenght of device description. + // + + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyFriendlyName, + NonPagedPoolNx, + &objectAttributes, + &deviceNameMemory); + + if (!NT_SUCCESS(status)) + { + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyDeviceDescription, + NonPagedPoolNx, + &objectAttributes, + &deviceNameMemory); + } + + if (NT_SUCCESS(status)) + { + pDevContext->DeviceNameMemory = deviceNameMemory; + pDevContext->DeviceName = WdfMemoryGetBuffer(deviceNameMemory, NULL); + } + else + { + pDevContext->DeviceNameMemory = NULL; + pDevContext->DeviceName = L"(error retrieving name)"; + } + + // + // Retrieve the device location string. + // + + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyLocationInformation, + NonPagedPoolNx, + WDF_NO_OBJECT_ATTRIBUTES, + &locationMemory); + + if (NT_SUCCESS(status)) + { + pDevContext->LocationMemory = locationMemory; + pDevContext->Location = WdfMemoryGetBuffer(locationMemory, NULL); + } + else + { + pDevContext->LocationMemory = NULL; + pDevContext->Location = L"(error retrieving location)"; + } + + return; +} + +_IRQL_requires_(PASSIVE_LEVEL) +PCHAR +DbgDevicePowerString( + _In_ WDF_POWER_DEVICE_STATE Type + ) +{ + 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/umdf2_fx2/driver/bulkrwr.c b/usb/umdf2_fx2/driver/bulkrwr.c new file mode 100644 index 00000000..83085da4 --- /dev/null +++ b/usb/umdf2_fx2/driver/bulkrwr.c @@ -0,0 +1,430 @@ +/*++ + +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: + + bulkrwr.c + +Abstract: + + This file has routines to perform reads and writes. + The read and writes are targeted bulk to endpoints. + +Environment: + + User mode + +--*/ + +#include <osrusbfx2.h> + + +#if defined(EVENT_TRACING) +#include "bulkrwr.tmh" +#endif + +#pragma warning(disable:4267) + +VOID +OsrFxEvtIoRead( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t Length + ) +/*++ + +Routine Description: + + Called by the framework when it receives Read or Write requests. + +Arguments: + + Queue - Default queue handle + Request - Handle to the read/write request + Lenght - Length of the data buffer associated with the request. + The default property of the queue is to not dispatch + zero lenght read & write requests to the driver and + complete is with status success. So we will never get + a zero length request. + +Return Value: + + +--*/ +{ + WDFUSBPIPE pipe; + NTSTATUS status; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + + UNREFERENCED_PARAMETER(Queue); + + // + // Log read start event, using IRP activity ID if available or request + // handle otherwise. + // + + EventWriteReadStart(WdfIoQueueGetDevice(Queue), (ULONG)Length); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "-->OsrFxEvtIoRead\n"); + + // + // First validate input parameters. + // + if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Transfer exceeds %d\n", + TEST_BOARD_TRANSFER_BUFFER_SIZE); + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkReadPipe; + + status = WdfRequestRetrieveOutputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "WdfRequestRetrieveOutputMemory failed %!STATUS!\n", status); + goto Exit; + } + + // + // The format call validates to make sure that you are reading or + // writing to the right pipe type, sets the appropriate transfer flags, + // creates an URB and initializes the request. + // + status = WdfUsbTargetPipeFormatRequestForRead(pipe, + Request, + reqMemory, + NULL // Offsets + ); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "WdfUsbTargetPipeFormatRequestForRead failed 0x%x\n", status); + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestReadCompletionRoutine, + pipe); + // + // Send the request asynchronously. + // + if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) { + // + // Framework couldn't send the request for some reason. + // + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "WdfRequestSend failed\n"); + status = WdfRequestGetStatus(Request); + goto Exit; + } + + +Exit: + if (!NT_SUCCESS(status)) { + // + // log event read failed + // + EventWriteReadFail(WdfIoQueueGetDevice(Queue), status); + WdfRequestCompleteWithInformation(Request, status, 0); + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, "<-- OsrFxEvtIoRead\n"); + + return; +} + +VOID +EvtRequestReadCompletionRoutine( + _In_ WDFREQUEST Request, + _In_ WDFIOTARGET Target, + _In_ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + _In_ WDFCONTEXT Context + ) +/*++ + +Routine Description: + + This is the completion routine for reads + If the irp completes with success, we check if we + need to recirculate this irp for another stage of + transfer. + +Arguments: + + Context - Driver supplied context + Device - Device handle + Request - Request handle + Params - request completion params + +Return Value: + None + +--*/ +{ + NTSTATUS status; + size_t bytesRead = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesRead = usbCompletionParams->Parameters.PipeRead.Length; + + if (NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, + "Number of bytes read: %I64d\n", (INT64)bytesRead); + } else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "Read failed - request status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus); + + } + + // + // Log read stop event, using IRP activity ID if available or request + // handle otherwise. + // + + EventWriteReadStop(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), + bytesRead, + status, + usbCompletionParams->UsbdStatus); + + WdfRequestCompleteWithInformation(Request, status, bytesRead); + + return; +} + +VOID +OsrFxEvtIoWrite( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t Length + ) +/*++ + +Routine Description: + + Called by the framework when it receives Read or Write requests. + +Arguments: + + Queue - Default queue handle + Request - Handle to the read/write request + Lenght - Length of the data buffer associated with the request. + The default property of the queue is to not dispatch + zero lenght read & write requests to the driver and + complete is with status success. So we will never get + a zero length request. + +Return Value: + + +--*/ +{ + NTSTATUS status; + WDFUSBPIPE pipe; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + + UNREFERENCED_PARAMETER(Queue); + + + // + // Log write start event, using IRP activity ID if available or request + // handle otherwise. + // + EventWriteWriteStart(WdfIoQueueGetDevice(Queue), (ULONG)Length); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "-->OsrFxEvtIoWrite\n"); + + // + // First validate input parameters. + // + if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Transfer exceeds %d\n", + TEST_BOARD_TRANSFER_BUFFER_SIZE); + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkWritePipe; + + status = WdfRequestRetrieveInputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestRetrieveInputBuffer failed\n"); + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForWrite(pipe, + Request, + reqMemory, + NULL); // Offset + + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, + "WdfUsbTargetPipeFormatRequestForWrite failed 0x%x\n", status); + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestWriteCompletionRoutine, + pipe); + + // + // Send the request asynchronously. + // + if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) { + // + // Framework couldn't send the request for some reason. + // + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestSend failed\n"); + status = WdfRequestGetStatus(Request); + goto Exit; + } + +Exit: + + if (!NT_SUCCESS(status)) { + // + // log event write failed + // + EventWriteWriteFail(WdfIoQueueGetDevice(Queue), status); + + WdfRequestCompleteWithInformation(Request, status, 0); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- OsrFxEvtIoWrite\n"); + + return; +} + +VOID +EvtRequestWriteCompletionRoutine( + _In_ WDFREQUEST Request, + _In_ WDFIOTARGET Target, + _In_ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + _In_ WDFCONTEXT Context + ) +/*++ + +Routine Description: + + This is the completion routine for writes + If the irp completes with success, we check if we + need to recirculate this irp for another stage of + transfer. + +Arguments: + + Context - Driver supplied context + Device - Device handle + Request - Request handle + Params - request completion params + +Return Value: + None + +--*/ +{ + NTSTATUS status; + size_t bytesWritten = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + // + // For usb devices, we should look at the Usb.Completion param. + // + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length; + + if (NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, + "Number of bytes written: %I64d\n", (INT64)bytesWritten); + } else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, + "Write failed: request Status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus); + } + + // + // Log write stop event, using IRP activtiy ID if available or request + // handle otherwise + // + EventWriteWriteStop(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), + bytesWritten, + status, + usbCompletionParams->UsbdStatus); + + + WdfRequestCompleteWithInformation(Request, status, bytesWritten); + + return; +} + + +VOID +OsrFxEvtIoStop( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ ULONG ActionFlags + ) +/*++ + +Routine Description: + + This callback is invoked on every inflight request when the device + is suspended or removed. Since our inflight read and write requests + are actually pending in the target device, we will just acknowledge + its presence. Until we acknowledge, complete, or requeue the requests + framework will wait before allowing the device suspend or remove to + proceeed. When the underlying USB stack gets the request to suspend or + remove, it will fail all the pending requests. + +Arguments: + + Queue - handle to queue object that is associated with the I/O request + + Request - handle to a request object + + ActionFlags - bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS flags + +Return Value: + None + +--*/ +{ + UNREFERENCED_PARAMETER(Queue); + UNREFERENCED_PARAMETER(ActionFlags); + + if (ActionFlags & WdfRequestStopActionSuspend ) { + WdfRequestStopAcknowledge(Request, FALSE); // Don't requeue + } else if(ActionFlags & WdfRequestStopActionPurge) { + WdfRequestCancelSentRequest(Request); + } + return; +} + + diff --git a/usb/umdf2_fx2/driver/driver.c b/usb/umdf2_fx2/driver/driver.c new file mode 100644 index 00000000..10bf3d39 --- /dev/null +++ b/usb/umdf2_fx2/driver/driver.c @@ -0,0 +1,277 @@ +/*++ + +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 started, + (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: + + User mode only + +--*/ + +#include <osrusbfx2.h> + +#if defined(EVENT_TRACING) +// +// 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 trace.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" +#else +ULONG DebugLevel = TRACE_LEVEL_INFORMATION; +ULONG DebugFlag = 0xff; +#endif + +#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 or another NTSTATUS error code 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__); + + // + // Register with ETW (unified tracing) + // + EventRegisterOSRUSBFX2(); + + // + // 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 Object 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); + EventUnregisterOSRUSBFX2(); + } + + return status; +} + +VOID +OsrFxEvtDriverContextCleanup( + WDFOBJECT Driver + ) +/*++ +Routine Description: + + Free resources allocated in DriverEntry that are not automatically + cleaned up by the framework. + +Arguments: + + Driver - handle to a WDF Driver object. + +Return Value: + + VOID. + +--*/ +{ + PAGED_CODE (); + + UNREFERENCED_PARAMETER(Driver); // For the case when WPP is not being used. + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, + "--> OsrFxEvtDriverContextCleanup\n"); + + WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER) Driver)); + + EventUnregisterOSRUSBFX2(); +} + +#if !defined(EVENT_TRACING) + +VOID +TraceEvents ( + _In_ ULONG DebugPrintLevel, + _In_ ULONG DebugPrintFlag, + _Printf_format_string_ + _In_ PCSTR DebugMessage, + ... + ) +/*++ + +Routine Description: + + Debug print for the sample driver. + +Arguments: + + DebugPrintLevel - print level between 0 and 3, with 3 the most verbose + DebugPrintFlag - message mask + DebugMessage - format string of the message to print + ... - values used by the format string + +Return Value: + + None. + + --*/ + { +#if DBG +#define TEMP_BUFFER_SIZE 1024 + va_list list; + CHAR debugMessageBuffer[TEMP_BUFFER_SIZE]; + HRESULT hr; + + va_start(list, DebugMessage); + + if (DebugMessage) { + + // + // Using new safe string functions instead of _vsnprintf. + // This function takes care of NULL terminating if the message + // is longer than the buffer. + // + hr = StringCchVPrintfA(debugMessageBuffer, + sizeof(debugMessageBuffer), + DebugMessage, + list); + if(FAILED(hr)) { + DbgPrint (_DRIVER_NAME_": StringCchVPrintfA failed with HRESULT 0x%x\n", hr); + return; + } + if (DebugPrintLevel <= TRACE_LEVEL_ERROR || + (DebugPrintLevel <= DebugLevel && + ((DebugPrintFlag & DebugFlag) == DebugPrintFlag))) { + DbgPrint("%s %s", _DRIVER_NAME_, debugMessageBuffer); + } + } + va_end(list); + + return; +#else + UNREFERENCED_PARAMETER(DebugPrintLevel); + UNREFERENCED_PARAMETER(DebugPrintFlag); + UNREFERENCED_PARAMETER(DebugMessage); +#endif +} + +#endif + + + + diff --git a/usb/umdf2_fx2/driver/interrupt.c b/usb/umdf2_fx2/driver/interrupt.c new file mode 100644 index 00000000..5983d936 --- /dev/null +++ b/usb/umdf2_fx2/driver/interrupt.c @@ -0,0 +1,184 @@ +/*++ + +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: + + User mode + +--*/ + +#include <osrusbfx2.h> + +#if defined(EVENT_TRACING) +#include "interrupt.tmh" +#endif + + +_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; + + 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(DeviceContext->InterruptPipe, + &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; + } + + + assert(NumBytesTransferred == sizeof(UCHAR)); + + switchState = WdfMemoryGetBuffer(Buffer, NULL); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, + "OsrFxEvtUsbInterruptPipeReadComplete SwitchState %x\n", + *switchState); + + pDeviceContext->CurrentSwitchState = *switchState; + + // + // Handle any pending Interrupt Message IOCTLs. Note that the OSR USB device + // will generate an interrupt message when the the device resumes from a low + // power state. So if the Interrupt Message IOCTL was sent after the device + // has gone to a low power state, the pending Interrupt Message IOCTL will + // get completed in the function call below, before the user twiddles the + // dip switches on the OSR USB device. If this is not the desired behavior + // for your driver, then you could handle this condition by maintaining a + // state variable on D0Entry to track interrupt messages caused by power up. + // + OsrUsbIoctlGetInterruptMessage(device, STATUS_SUCCESS); + +} + +BOOLEAN +OsrFxEvtUsbInterruptReadersFailed( + _In_ WDFUSBPIPE Pipe, + _In_ NTSTATUS Status, + _In_ USBD_STATUS UsbdStatus + ) +{ + WDFDEVICE device = WdfIoTargetGetDevice(WdfUsbTargetPipeGetIoTarget(Pipe)); + PDEVICE_CONTEXT pDeviceContext = GetDeviceContext(device); + + UNREFERENCED_PARAMETER(UsbdStatus); + + // + // Clear the current switch state. + // + pDeviceContext->CurrentSwitchState = 0; + + // + // Service the pending interrupt switch change request + // + OsrUsbIoctlGetInterruptMessage(device, Status); + + return TRUE; +} + diff --git a/usb/umdf2_fx2/driver/ioctl.c b/usb/umdf2_fx2/driver/ioctl.c new file mode 100644 index 00000000..6312da35 --- /dev/null +++ b/usb/umdf2_fx2/driver/ioctl.c @@ -0,0 +1,1056 @@ +/*++ + +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: + + Ioctl.c + +Abstract: + + USB device driver for OSR USB-FX2 Learning Kit + +Environment: + + User mode only + +--*/ + +#include <osrusbfx2.h> + +#if defined(EVENT_TRACING) +#include "ioctl.tmh" +#endif + +#pragma alloc_text(PAGE, OsrFxEvtIoDeviceControl) +#pragma alloc_text(PAGE, ResetPipe) +#pragma alloc_text(PAGE, ResetDevice) +#pragma alloc_text(PAGE, ReenumerateDevice) +#pragma alloc_text(PAGE, GetBarGraphState) +#pragma alloc_text(PAGE, SetBarGraphState) +#pragma alloc_text(PAGE, GetSevenSegmentState) +#pragma alloc_text(PAGE, SetSevenSegmentState) +#pragma alloc_text(PAGE, GetSwitchState) + +VOID +OsrFxEvtIoDeviceControl( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode + ) +/*++ + +Routine Description: + + This event is called when the framework receives IRP_MJ_DEVICE_CONTROL + requests from the system. + +Arguments: + + Queue - Handle to the framework queue object that is associated + with the I/O request. + Request - Handle to a framework request object. + + OutputBufferLength - length of the request's output buffer, + if an output buffer is available. + InputBufferLength - length of the request's input buffer, + if an input buffer is available. + + IoControlCode - the driver-defined or system-defined I/O control code + (IOCTL) that is associated with the request. +Return Value: + + VOID + +--*/ +{ + WDFDEVICE device; + PDEVICE_CONTEXT pDevContext; + size_t bytesReturned = 0; + PBAR_GRAPH_STATE barGraphState = NULL; + PSWITCH_STATE switchState = NULL; + PUCHAR sevenSegment = NULL; + BOOLEAN requestPending = FALSE; + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + + UNREFERENCED_PARAMETER(InputBufferLength); + UNREFERENCED_PARAMETER(OutputBufferLength); + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "--> OsrFxEvtIoDeviceControl\n"); + // + // initialize variables + // + device = WdfIoQueueGetDevice(Queue); + pDevContext = GetDeviceContext(device); + + switch(IoControlCode) { + + case IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR: { + + PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL; + USHORT requiredSize = 0; + + // + // First get the size of the config descriptor + // + status = WdfUsbTargetDeviceRetrieveConfigDescriptor( + pDevContext->UsbDevice, + NULL, + &requiredSize); + + if (status != STATUS_BUFFER_TOO_SMALL) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfUsbTargetDeviceRetrieveConfigDescriptor failed 0x%x\n", status); + break; + } + + // + // Get the buffer - make sure the buffer is big enough + // + status = WdfRequestRetrieveOutputBuffer(Request, + (size_t)requiredSize, // MinimumRequired + &configurationDescriptor, + NULL); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfRequestRetrieveOutputBuffer failed 0x%x\n", status); + break; + } + + status = WdfUsbTargetDeviceRetrieveConfigDescriptor( + pDevContext->UsbDevice, + configurationDescriptor, + &requiredSize); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfUsbTargetDeviceRetrieveConfigDescriptor failed 0x%x\n", status); + break; + } + + bytesReturned = requiredSize; + + } + break; + + case IOCTL_OSRUSBFX2_RESET_DEVICE: + + status = ResetDevice(device); + break; + + case IOCTL_OSRUSBFX2_REENUMERATE_DEVICE: + + // + // Otherwise, call our function to reenumerate the + // device + // + status = ReenumerateDevice(pDevContext); + + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY: + + // + // Make sure the caller's output buffer is large enough + // to hold the state of the bar graph + // + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(BAR_GRAPH_STATE), + &barGraphState, + NULL); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"); + break; + } + // + // Call our function to get the bar graph state + // + status = GetBarGraphState(pDevContext, barGraphState); + + // + // If we succeeded return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(BAR_GRAPH_STATE); + + } else { + + bytesReturned = 0; + + } + break; + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + + status = WdfRequestRetrieveInputBuffer(Request, + sizeof(BAR_GRAPH_STATE), + &barGraphState, + NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's input buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"); + break; + } + + // + // Call our routine to set the bar graph state + // + status = SetBarGraphState(pDevContext, barGraphState); + + // + // There's no data returned for this call + // + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY: + + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(UCHAR), + &sevenSegment, + NULL); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting an UCHAR\n"); + break; + } + + // + // Call our function to get the 7 segment state + // + status = GetSevenSegmentState(pDevContext, sevenSegment); + + // + // If we succeeded return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(UCHAR); + + } else { + + bytesReturned = 0; + + } + break; + + case IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY: + + status = WdfRequestRetrieveInputBuffer(Request, + sizeof(UCHAR), + &sevenSegment, + NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's input buffer is too small for this IOCTL, expecting an UCHAR\n"); + bytesReturned = sizeof(UCHAR); + break; + } + + // + // Call our routine to set the 7 segment state + // + status = SetSevenSegmentState(pDevContext, sevenSegment); + + // + // There's no data returned for this call + // + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_READ_SWITCHES: + + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(SWITCH_STATE), + &switchState, + NULL);// BufferLength + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n"); + bytesReturned = sizeof(SWITCH_STATE); + break; + + } + + // + // Call our routine to get the state of the switches + // + status = GetSwitchState(pDevContext, switchState); + + // + // If successful, return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(SWITCH_STATE); + + } else { + // + // Don't return any data + // + bytesReturned = 0; + } + break; + + case IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE: + + // + // Forward the request to an interrupt message queue and dont complete + // the request until an interrupt from the USB device occurs. + // + status = WdfRequestForwardToIoQueue(Request, pDevContext->InterruptMsgQueue); + if (NT_SUCCESS(status)) { + requestPending = TRUE; + } + + break; + + default : + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + if (requestPending == FALSE) { + WdfRequestCompleteWithInformation(Request, status, bytesReturned); + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "<-- OsrFxEvtIoDeviceControl\n"); + + return; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ResetPipe( + _In_ WDFUSBPIPE Pipe + ) +/*++ + +Routine Description: + + This routine resets the pipe. + +Arguments: + + Pipe - framework pipe handle + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + + PAGED_CODE(); + + // + // This routine synchronously submits a URB_FUNCTION_RESET_PIPE + // request down the stack. + // + status = WdfUsbTargetPipeResetSynchronously(Pipe, + WDF_NO_HANDLE, // WDFREQUEST + NULL // PWDF_REQUEST_SEND_OPTIONS + ); + + if (NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "ResetPipe - success\n"); + status = STATUS_SUCCESS; + } + else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetPipe - failed\n"); + } + + return status; +} + +VOID +StopAllPipes( + IN PDEVICE_CONTEXT DeviceContext + ) +{ + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->InterruptPipe), + WdfIoTargetCancelSentIo); + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkReadPipe), + WdfIoTargetCancelSentIo); + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkWritePipe), + WdfIoTargetCancelSentIo); +} + +NTSTATUS +StartAllPipes( + IN PDEVICE_CONTEXT DeviceContext + ) +{ + NTSTATUS status; + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->InterruptPipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkReadPipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkWritePipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ResetDevice( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This routine calls WdfUsbTargetDeviceResetPortSynchronously to reset the device if it's still + connected. + +Arguments: + + Device - Handle to a framework device + +Return Value: + + NT status value + +--*/ +{ + PDEVICE_CONTEXT pDeviceContext; + NTSTATUS status; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "--> ResetDevice\n"); + + pDeviceContext = GetDeviceContext(Device); + + // + // A NULL timeout indicates an infinite wake + // + status = WdfWaitLockAcquire(pDeviceContext->ResetDeviceWaitLock, NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetDevice - could not acquire lock\n"); + return status; + } + + StopAllPipes(pDeviceContext); + + status = WdfUsbTargetDeviceResetPortSynchronously(pDeviceContext->UsbDevice); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetDevice failed - 0x%x\n", status); + } + + status = StartAllPipes(pDeviceContext); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "Failed to start all pipes - 0x%x\n", status); + } + + WdfWaitLockRelease(pDeviceContext->ResetDeviceWaitLock); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "<-- ResetDevice\n"); + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ReenumerateDevice( + _In_ PDEVICE_CONTEXT DevContext + ) +/*++ + +Routine Description + + This routine re-enumerates the USB device. + +Arguments: + + pDevContext - One of our device extensions + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + GUID activity; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"--> ReenumerateDevice\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_REENUMERATE, // Request + 0, // Value + 0); // Index + + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + WDF_NO_HANDLE, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + NULL, // MemoryDescriptor + NULL); // BytesTransferred + + if(!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "ReenumerateDevice: Failed to Reenumerate - 0x%x \n", status); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"<-- ReenumerateDevice\n"); + + // + // Send event to eventlog + // + + activity = DeviceToActivityId(WdfObjectContextGetObject(DevContext)); + EventWriteDeviceReenumerated(DevContext->DeviceName, + DevContext->Location, + status); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetBarGraphState( + _In_ PDEVICE_CONTEXT DevContext, + _Out_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + +Routine Description + + This routine gets the state of the bar graph on the board + +Arguments: + + DevContext - One of our device extensions + + BarGraphState - Struct that receives the bar graph's state + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetBarGraphState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + // + // Set the buffer to 0, the board will OR in everything that is set + // + BarGraphState->BarsAsUChar = 0; + + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + BarGraphState, + sizeof(BAR_GRAPH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + WDF_NO_HANDLE, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetBarGraphState: Failed to GetBarGraphState - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetBarGraphState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SetBarGraphState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + +Routine Description + + This routine sets the state of the bar graph on the board + +Arguments: + + DevContext - One of our device extensions + + BarGraphState - Struct that describes the bar graph's desired state + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetBarGraphState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + BarGraphState, + sizeof(BAR_GRAPH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "SetBarGraphState: Failed - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "SetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetBarGraphState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetSevenSegmentState( + _In_ PDEVICE_CONTEXT DevContext, + _Out_ PUCHAR SevenSegment + ) +/*++ + +Routine Description + + This routine gets the state of the 7 segment display on the board + by sending a synchronous control command. + + NOTE: It's not a good practice to send a synchronous request in the + context of the user thread because if the transfer takes long + time to complete, you end up holding the user thread. + + I'm choosing to do synchronous transfer because a) I know this one + completes immediately b) and for demonstration. + +Arguments: + + DevContext - One of our device extensions + + SevenSegment - receives the state of the 7 segment display + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Enter\n"); + + PAGED_CODE(); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_7SEGMENT_DISPLAY, // Request + 0, // Value + 0); // Index + + // + // Set the buffer to 0, the board will OR in everything that is set + // + *SevenSegment = 0; + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SevenSegment, + sizeof(UCHAR)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetSevenSegmentState: Failed to get 7 Segment state - 0x%x \n", status); + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Exit\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SetSevenSegmentState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PUCHAR SevenSegment + ) +/*++ + +Routine Description + + This routine sets the state of the 7 segment display on the board + +Arguments: + + DevContext - One of our device extensions + + SevenSegment - desired state of the 7 segment display + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetSevenSegmentState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_7SEGMENT_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SevenSegment, + sizeof(UCHAR)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "SetSevenSegmentState: Failed to set 7 Segment state - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "SetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); + + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetSevenSegmentState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetSwitchState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PSWITCH_STATE SwitchState + ) +/*++ + +Routine Description + + This routine gets the state of the switches on the board + +Arguments: + + DevContext - One of our device extensions + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetSwitchState\n"); + + PAGED_CODE(); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_SWITCHES, // Request + 0, // Value + 0); // Index + + SwitchState->SwitchesAsUChar = 0; + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SwitchState, + sizeof(SWITCH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetSwitchState: Failed to Get switches - 0x%x \n", status); + + } else { + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetSwitchState: Switch mask is 0x%x\n", SwitchState->SwitchesAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetSwitchState\n"); + + return status; + +} + + +VOID +OsrUsbIoctlGetInterruptMessage( + _In_ WDFDEVICE Device, + _In_ NTSTATUS ReaderStatus + ) +/*++ + +Routine Description + + This method handles the completion of the pended request for the IOCTL + IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE. + +Arguments: + + Device - Handle to a framework device. + +Return Value: + + None. + +--*/ +{ + NTSTATUS status; + WDFREQUEST request; + PDEVICE_CONTEXT pDevContext; + size_t bytesReturned = 0; + PSWITCH_STATE switchState = NULL; + + pDevContext = GetDeviceContext(Device); + + do { + + // + // Check if there are any pending requests in the Interrupt Message Queue. + // If a request is found then complete the pending request. + // + status = WdfIoQueueRetrieveNextRequest(pDevContext->InterruptMsgQueue, &request); + + if (NT_SUCCESS(status)) { + status = WdfRequestRetrieveOutputBuffer(request, + sizeof(SWITCH_STATE), + &switchState, + NULL);// BufferLength + + if (!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n"); + bytesReturned = sizeof(SWITCH_STATE); + + } else { + + // + // Copy the state information saved by the continuous reader. + // + if (NT_SUCCESS(ReaderStatus)) { + switchState->SwitchesAsUChar = pDevContext->CurrentSwitchState; + bytesReturned = sizeof(SWITCH_STATE); + } else { + bytesReturned = 0; + } + } + + // + // Complete the request. If we failed to get the output buffer then + // complete with that status. Otherwise complete with the status from the reader. + // + WdfRequestCompleteWithInformation(request, + NT_SUCCESS(status) ? ReaderStatus : status, + bytesReturned); + status = STATUS_SUCCESS; + + } else if (status != STATUS_NO_MORE_ENTRIES) { + KdPrint(("WdfIoQueueRetrieveNextRequest status %08x\n", status)); + } + + request = NULL; + + } while (status == STATUS_SUCCESS); + + return; + +} + + diff --git a/usb/umdf2_fx2/driver/osrusbfx2.h b/usb/umdf2_fx2/driver/osrusbfx2.h new file mode 100644 index 00000000..d59837fc --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2.h @@ -0,0 +1,312 @@ +/*++ + +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: + + User mode + +--*/ + +#include <windows.h> +#include <winioctl.h> +#pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union +#include <ntstatus.h> +#include <assert.h> +#include <strsafe.h> +#include <devpropdef.h> +#include <wudfwdm.h> +typedef struct _IO_STACK_LOCATION *PIO_STACK_LOCATION; +#include "usbdi.h" +#include <wdf.h> +#include <wdfusb.h> +#include "prototypes.h" +#include "initguid.h" +#include "public.h" +#include "driverspecs.h" + +#include "trace.h" + +// +// Include auto-generated ETW event functions (created by MC.EXE from +// osrusbfx2.man) +// +#include <evntprov.h> +#include "fx2Events.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; + + WDFUSBPIPE BulkReadPipe; + + WDFUSBPIPE BulkWritePipe; + + WDFUSBPIPE InterruptPipe; + + WDFWAITLOCK ResetDeviceWaitLock; + + UCHAR CurrentSwitchState; + + WDFQUEUE InterruptMsgQueue; + + ULONG UsbDeviceTraits; + + // + // The following fields are used during event logging to + // report the events relative to this specific instance + // of the device. + // + + WDFMEMORY DeviceNameMemory; + PCWSTR DeviceName; + + WDFMEMORY LocationMemory; + PCWSTR Location; + +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + +extern ULONG DebugLevel; + +typedef +NTSTATUS +(*PFN_IO_GET_ACTIVITY_ID_IRP) ( + _In_ PIRP Irp, + _Out_ LPGUID Guid + ); + +typedef +NTSTATUS +(*PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA) ( + _In_ PUNICODE_STRING SymbolicLinkName, + _In_ CONST DEVPROPKEY *PropertyKey, + _In_ LCID Lcid, + _In_ ULONG Flags, + _In_ DEVPROPTYPE Type, + _In_ ULONG Size, + _In_opt_ PVOID Data + ); + +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 +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 + ); + +VOID +OsrUsbIoctlGetInterruptMessage( + _In_ WDFDEVICE Device, + _In_ NTSTATUS ReaderStatus + ); + +_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; + +EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH OsrFxEvtDeviceSelfManagedIoFlush; + +_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) +VOID +GetDeviceEventLoggingNames( + _In_ WDFDEVICE Device + ); + +_IRQL_requires_(PASSIVE_LEVEL) +PCHAR +DbgDevicePowerString( + _In_ WDF_POWER_DEVICE_STATE Type + ); + +FORCEINLINE +GUID +RequestToActivityId( + _In_ WDFREQUEST Request + ) +{ + GUID activity = {0}; + + // + // Use the WDFREQUEST handle as the activity ID + // + RtlCopyMemory(&activity, &Request, sizeof(WDFREQUEST)); + + return activity; +} + +FORCEINLINE +GUID +DeviceToActivityId( + _In_ WDFDEVICE Device + ) +{ + GUID activity = {0}; + RtlCopyMemory(&activity, &Device, sizeof(WDFDEVICE)); + return activity; +} + + +#endif + + diff --git a/usb/umdf2_fx2/driver/osrusbfx2.man b/usb/umdf2_fx2/driver/osrusbfx2.man new file mode 100644 index 00000000..19f363d5 --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2.man @@ -0,0 +1,309 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes'?> +<instrumentationManifest + xmlns="http://schemas.microsoft.com/win/2004/08/events" + xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" + > + <instrumentation> + <events> + <provider + guid="{69cd60e3-430f-4da4-b1b3-e3bdaf945875}" + messageFileName="%Systemroot%\System32\drivers\umdf\osrusbfx2um.dll" + name="OSRUSBFX2" + resourceFileName="%SystemRoot%\System32\drivers\umdf\osrusbfx2um.dll" + symbol="OSRUSBFX2_PROVIDER" + > + <channels> + <channel + chid="Analytic" + enabled="false" + name="OsrUsbfx2/Analytic" + symbol="OSRUSBFX2_ANALYTIC" + type="Analytic" + /> + <channel + chid="operational" + enabled="true" + isolation="System" + message="$(string.OSRUSBFX2_OPERATIONAL.Name)" + name="OsrUsbFx2/Operational" + symbol="OSRUSBFX2_OPERATIONAL" + type="Operational" + /> + </channels> + <keywords> + <keyword + mask="0x0000000000000010" + message="$(string.OSRUSBFX2_DEVICE_INFO_KEYWORD.message)" + name="deviceinfo" + symbol="OSRUSBFX2_DEVICE_INFO_KEYWORD" + /> + <keyword + mask="0x0000000000000040" + message="$(string.OSRUSBFX2_READ_WRITE_KEYWORD.message)" + name="readwrite" + symbol="OSRUSBFX2_READ_WRITE_KEYWORD" + /> + </keywords> + <opcodes> + <!-- Defining our own custom opcode instead of using standard opcodes defined by winmeta.xml --> + <opcode + name="add" + symbol="OSRUSBFX2_DEVICE_ADD" + value="10" + /> + <opcode + name="fail" + symbol="OSRUSBFX2_FAIL" + value="11" + /> + </opcodes> + <tasks> + <!-- Support for XP and W2K3 : MC.exe will create a MOF file --> + <!-- Requires an associated eventGUID attribute for each task that is defined --> + <!-- For the MOF file : --> + <!-- Semantically, the event GUID represents a set of logical events that are logged by the provider. --> + <task + eventGUID="{872c3c43-6899-4f1d-89b8-51a82f6db657}" + name="deviceInit" + symbol="OSRUSBFX2_DEVICE_INIT" + value="1" + /> + <task + eventGUID="{872c3c45-6899-4f1d-89b8-51a82f6db657}" + name="read" + symbol="OSRUSBFX2_READ" + value="2" + /> + <task + eventGUID="{872c3c46-6899-4f1d-89b8-51a82f6db657}" + name="write" + symbol="OSRUSBFX2_WRITE" + value="3" + /> + </tasks> + <templates> + <template tid="tid_DeviceStatus"> + <data + inType="win:UnicodeString" + name="FriendlyName" + outType="xs:string" + /> + <data + inType="win:UnicodeString" + name="Location" + outType="xs:string" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + </template> + <template tid="tid_ReadWrite"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="Length" + outType="xs:unsignedInt" + /> + </template> + <template tid="tid_ReadWriteFail"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + </template> + <template tid="tid_ReadWriteCompletion"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="Length" + outType="xs:unsignedInt" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + <data + inType="win:UInt32" + name="UsbdStatus" + outType="xs:unsignedInt" + /> + </template> + </templates> + <events> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadStart.EventMessage)" + level="win:Informational" + opcode="win:Start" + symbol="ReadStart" + task="read" + template="tid_ReadWrite" + value="1" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadStop.EventMessage)" + level="win:Informational" + opcode="win:Stop" + symbol="ReadStop" + task="read" + template="tid_ReadWriteCompletion" + value="2" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadFail.EventMessage)" + level="win:Error" + opcode="fail" + symbol="ReadFail" + task="read" + template="tid_ReadWriteFail" + value="3" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteStart.EventMessage)" + level="win:Informational" + opcode="win:Start" + symbol="WriteStart" + task="write" + template="tid_ReadWrite" + value="4" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteStop.EventMessage)" + level="win:Informational" + opcode="win:Stop" + symbol="WriteStop" + task="write" + template="tid_ReadWriteCompletion" + value="5" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteFail.EventMessage)" + level="win:Error" + opcode="fail" + symbol="WriteFail" + task="write" + template="tid_ReadWriteFail" + value="6" + /> + <event + channel="operational" + keywords="deviceinfo" + level="win:Error" + message="$(string.DeviceFailAdd.EventMessage)" + opcode="add" + symbol="FailAddDevice" + task="deviceInit" + template="tid_DeviceStatus" + value="100" + /> + <event + channel="operational" + keywords="deviceinfo" + message="$(string.DeviceReenumerated.EventMessage)" + opcode="win:Start" + symbol="DeviceReenumerated" + task="deviceInit" + template="tid_DeviceStatus" + value="101" + /> + <event + channel="operational" + keywords="deviceinfo" + level="win:Error" + message="$(string.SelectConfigFailure.Message)" + opcode="fail" + symbol="SelectConfigFailure" + task="deviceInit" + template="tid_DeviceStatus" + value="102" + /> + </events> + </provider> + </events> + </instrumentation> + <localization xmlns="http://schemas.microsoft.com/win/2004/08/events"> + <resources culture="en-US"> + <stringTable> + <string + id="OSRUSBFX2_DEVICE_INFO_KEYWORD.message" + value="Device events: fail to load, reenumerate" + /> + <string + id="OSRUSBFX2_READ_WRITE_KEYWORD.message" + value="Read, Write events" + /> + <string + id="OSRUSBFX2_OPERATIONAL.Name" + value="Operational channel eventlog" + /> + <string + id="ReadStart.EventMessage" + value="Read. Device = %1, Length = %2" + /> + <string + id="ReadStop.EventMessage" + value="Read complete. Device = %1, Length = %2, Status = %3, UsbStatus = %4" + /> + <string + id="ReadFail.EventMessage" + value="Read error. Device = %1, Status = %2" + /> + <string + id="WriteStart.EventMessage" + value="Write. Device = %1, Length = %2" + /> + <string + id="WriteStop.EventMessage" + value="Write complete. Device = %1, Length = %2, Status = %3, UsbStatus = %4" + /> + <string + id="WriteFail.EventMessage" + value="Write error. Device = %1, Status = %2" + /> + <string + id="DeviceReenumerated.EventMessage" + value="Device %1 (location %2) was reenumerated" + /> + <string + id="DeviceFailAdd.EventMessage" + value="Fail to add device %1 (location %2), status %3" + /> + <string + id="SelectConfigFailure.Message" + value="This error occurs when an OSR USB Fx2 board is attached to a USB 1.1 port on a machine running Windows Vista. This error occurs because the OSR USB Fx2 board's Interrupt end-point descriptor does not conform to the USB specification. Windows Vista detects this and returns an error. You should plug the device into a USB 2.0 (or higher) port." + /> + </stringTable> + </resources> + </localization> +</instrumentationManifest> diff --git a/usb/umdf2_fx2/driver/osrusbfx2.rc b/usb/umdf2_fx2/driver/osrusbfx2.rc new file mode 100644 index 00000000..84f89a6c --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2.rc @@ -0,0 +1,13 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF Sample Driver for OSR USB-FX2 Learning Kit" +#define VER_INTERNALNAME_STR "osrusbfx2um.dll" +#define VER_ORIGINALFILENAME_STR "osrusbfx2um.dll" + +#include "common.ver" + +#include "fx2Events.rc" diff --git a/usb/umdf2_fx2/driver/osrusbfx2um.inx b/usb/umdf2_fx2/driver/osrusbfx2um.inx new file mode 100644 index 00000000..bd01bb16 --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2um.inx @@ -0,0 +1,103 @@ +;/*++ +; +;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: +; +; OsrUsbFx2Um.INF +; +;Abstract: +; Installation inf for OSR USB User-mode driver on FX2 Learning Kit +; +;--*/ + +[Version] +Signature="$Windows NT$" +Class=Sample +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} +Provider=%MSFTUMDF% +DriverVer=03/25/2005,0.0.0.1 +CatalogFile=wudf.cat + +[Manufacturer] +%MSFTUMDF%=Microsoft,NT$ARCH$ + +[Microsoft.NT$ARCH$] +%OsrUsbDeviceName%=OsrUsb_Install, USB\Vid_045e&Pid_94aa&mi_00 +%OsrUsbDeviceName%=OsrUsb_Install, USB\VID_0547&PID_1002 + +[ClassInstall32] +AddReg=SampleClass_RegistryAdd + +[SampleClass_RegistryAdd] +HKR,,,,%ClassName% +HKR,,Icon,,"-10" + +[SourceDisksFiles] +osrusbfx2um.dll=1 + +[SourceDisksNames] +1 = %MediaDescription% + +; =================== UMDF OsrUsb Device ================================== + +[OsrUsb_Install.NT] +CopyFiles=UMDriverCopy +Include=WINUSB.INF ; Import sections from WINUSB.INF +Needs=WINUSB.NT ; Run the CopyFiles & AddReg directives for WinUsb.INF + +[OsrUsb_Install.NT.hw] +AddReg=OsrUsb_Device_AddReg + +[OsrUsb_Install.NT.Services] +AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall ; flag 0x2 sets this as the service for the device +AddService=WinUsb,0x000001f8,WinUsb_ServiceInstall ; this service is installed because its a filter. + +[OsrUsb_Install.NT.Wdf] +UmdfDispatcher=WinUsb +UmdfService=WUDFOsrUsbFx2, WUDFOsrUsbFx2_Install +UmdfServiceOrder=WUDFOsrUsbFx2 + +[WUDFOsrUsbFx2_Install] +UmdfLibraryVersion=$UMDFVERSION$ +ServiceBinary="%12%\UMDF\osrusbfx2um.dll" + +[OsrUsb_Device_AddReg] +HKR,,"LowerFilters",0x00010008,"WinUsb" ; FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND +HKR,,"WinUsbPowerPolicyOwnershipDisabled",0x00010001,1 ; our driver takes ownership of power policy. Tell WINUSB not to + +[WUDFRD_ServiceInstall] +DisplayName = %WudfRdDisplayName% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WUDFRd.sys + +[WinUsb_ServiceInstall] +DisplayName = %WinUsb_SvcDesc% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WinUSB.sys + +[DestinationDirs] +UMDriverCopy=12,UMDF ; copy to driversMdf +CoInstallers_CopyFiles=11 + +[UMDriverCopy] +osrusbfx2um.dll + +; =================== Generic ================================== + +[Strings] +MSFTUMDF="Microsoft Internal (WDF:UMDF)" +MediaDescription="Microsoft Sample Driver Installation Media" +ClassName="Sample Device" +WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector" +OsrUsbDeviceName="UMDF 2.0 Sample Driver for OSR USB Fx2 Learning Kit" +WinUsb_SvcDesc="WinUSB Driver" diff --git a/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj new file mode 100644 index 00000000..44f6d46f --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj @@ -0,0 +1,216 @@ +<?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>{33535CCD-5A39-4FDC-9C3A-796896CE065B}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{0818D84E-7C44-4668-BCC4-CBE4610E615B}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</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; ioctl.c; bulkrwr.c; Interrupt.c"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction> + <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile> + <WppPreprocessorDefinitions>ENABLE_WPP_RECORDER=1;WPP_MACRO_USE_KM_VERSION_FOR_UM=1</WppPreprocessorDefinitions> + </ClCompile> + <Inf Include=".\osrusbfx2um.inx"> + <Architecture>$(InfArch)</Architecture> + <SpecifyArchitecture>true</SpecifyArchitecture> + <CopyOutput>.\$(IntDir)\osrusbfx2um.inf</CopyOutput> + </Inf> + <MessageCompile Include="osrusbfx2.man"> + <GenerateUserModeLoggingMacros>true</GenerateUserModeLoggingMacros> + <GenerateMofFile>true</GenerateMofFile> + <HeaderFilePath>.\$(IntDir)</HeaderFilePath> + <GeneratedHeaderPath>true</GeneratedHeaderPath> + <RCFilePath>.\$(IntDir)</RCFilePath> + <GeneratedRCAndMessagesPath>true</GeneratedRCAndMessagesPath> + <GeneratedFilesBaseName>fx2Events</GeneratedFilesBaseName> + <UseBaseNameOfInput>true</UseBaseNameOfInput> + </MessageCompile> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2um</TargetName> + <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2um</TargetName> + <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2um</TargetName> + <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2um</TargetName> + <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\WppRecorderUM.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\WppRecorderUM.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\WppRecorderUM.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING;UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\WppRecorderUM.lib</AdditionalDependencies> + </Link> + </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/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters new file mode 100644 index 00000000..e9fac5a4 --- /dev/null +++ b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters @@ -0,0 +1,51 @@ +<?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>{52B04D2F-A9FC-4C03-9A04-DF29F0A760BD}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{0A38487D-5A95-4D22-856A-29C215B94BA6}</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>{455882CC-7C61-4EF5-BA09-0B6A70C234A9}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{FFADC7F2-84FB-45BC-BA65-1447A12B4727}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="bulkrwr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <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="ioctl.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <FilesToPackage Include=".\Debug\\osrusbfx2um.inf"> + <Filter>Driver Files</Filter> + </FilesToPackage> + <Inf Include=".\osrusbfx2um.inx"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <MessageCompile Include="osrusbfx2.man"> + <Filter>Resource Files</Filter> + </MessageCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf2_fx2/driver/trace.h b/usb/umdf2_fx2/driver/trace.h new file mode 100644 index 00000000..5a72dcaf --- /dev/null +++ b/usb/umdf2_fx2/driver/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(RegistryPath) +#define WPP_CLEANUP() + +#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 + + + diff --git a/usb/umdf2_fx2/exe/dump.c b/usb/umdf2_fx2/exe/dump.c new file mode 100644 index 00000000..69074bf1 --- /dev/null +++ b/usb/umdf2_fx2/exe/dump.c @@ -0,0 +1,444 @@ +/*++ + +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: + + DUMP.C + +Abstract: + + Routines to dump the descriptors information in a human readable form. + +Environment: + + user mode only + +--*/ + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include "devioctl.h" + +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(default:4200) +#pragma warning(default:4201) +#pragma warning(default:4214) + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ); + + +char* +usbDescriptorTypeString(UCHAR bDescriptorType ) +/*++ +Routine Description: + + Called to get ascii string of USB descriptor + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bDescriptorType or + PUSB_DEVICE_DESCRIPTOR->bDescriptorType or + PUSB_INTERFACE_DESCRIPTOR->bDescriptorType or + PUSB_STRING_DESCRIPTOR->bDescriptorType or + PUSB_POWER_DESCRIPTOR->bDescriptorType or + PUSB_CONFIGURATION_DESCRIPTOR->bDescriptorType + +Return Value: + + ptr to string + +--*/ +{ + + switch(bDescriptorType) { + + case USB_DEVICE_DESCRIPTOR_TYPE: + return "USB_DEVICE_DESCRIPTOR_TYPE"; + + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + return "USB_CONFIGURATION_DESCRIPTOR_TYPE"; + + + case USB_STRING_DESCRIPTOR_TYPE: + return "USB_STRING_DESCRIPTOR_TYPE"; + + + case USB_INTERFACE_DESCRIPTOR_TYPE: + return "USB_INTERFACE_DESCRIPTOR_TYPE"; + + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + return "USB_ENDPOINT_DESCRIPTOR_TYPE"; + + +#ifdef USB_POWER_DESCRIPTOR_TYPE // this is the older definintion which is actually obsolete + // workaround for temporary bug in 98ddk, older USB100.h file + case USB_POWER_DESCRIPTOR_TYPE: + return "USB_POWER_DESCRIPTOR_TYPE"; +#endif + +#ifdef USB_RESERVED_DESCRIPTOR_TYPE // this is the current version of USB100.h as in NT5DDK + + case USB_RESERVED_DESCRIPTOR_TYPE: + return "USB_RESERVED_DESCRIPTOR_TYPE"; + + case USB_CONFIG_POWER_DESCRIPTOR_TYPE: + return "USB_CONFIG_POWER_DESCRIPTOR_TYPE"; + + case USB_INTERFACE_POWER_DESCRIPTOR_TYPE: + return "USB_INTERFACE_POWER_DESCRIPTOR_TYPE"; +#endif // for current nt5ddk version of USB100.h + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbEndPointTypeString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of endpt descriptor type + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_ENDPOINT_TYPE_MASK; + + + switch( typ) { + case USB_ENDPOINT_TYPE_INTERRUPT: + return "USB_ENDPOINT_TYPE_INTERRUPT"; + + case USB_ENDPOINT_TYPE_BULK: + return "USB_ENDPOINT_TYPE_BULK"; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + return "USB_ENDPOINT_TYPE_ISOCHRONOUS"; + + case USB_ENDPOINT_TYPE_CONTROL: + return "USB_ENDPOINT_TYPE_CONTROL"; + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbConfigAttributesString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of USB_CONFIGURATION_DESCRIPTOR attributes + +Arguments: + + PUSB_CONFIGURATION_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_CONFIG_POWERED_MASK; + + + switch( typ) { + + case USB_CONFIG_BUS_POWERED: + return "USB_CONFIG_BUS_POWERED"; + + case USB_CONFIG_SELF_POWERED: + return "USB_CONFIG_SELF_POWERED"; + + case USB_CONFIG_REMOTE_WAKEUP: + return "USB_CONFIG_REMOTE_WAKEUP"; + + + default: + return "??? UNKNOWN!!"; + } +} + + +void +print_USB_CONFIGURATION_DESCRIPTOR(PUSB_CONFIGURATION_DESCRIPTOR cd) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB config descriptor + +Arguments: + + ptr to USB configuration descriptor + +Return Value: + + none + +--*/ +{ + printf("\n===================\nUSB_CONFIGURATION_DESCRIPTOR\n"); + + printf( + "bLength = 0x%x, decimal %d\n", cd->bLength, cd->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", cd->bDescriptorType, + usbDescriptorTypeString( cd->bDescriptorType ) + ); + + printf( + "wTotalLength = 0x%x, decimal %d\n", cd->wTotalLength, cd->wTotalLength + ); + + printf( + "bNumInterfaces = 0x%x, decimal %d\n", cd->bNumInterfaces, cd->bNumInterfaces + ); + + printf( + "bConfigurationValue = 0x%x, decimal %d\n", + cd->bConfigurationValue, cd->bConfigurationValue + ); + + printf( + "iConfiguration = 0x%x, decimal %d\n", cd->iConfiguration, cd->iConfiguration + ); + + printf( + "bmAttributes = 0x%x ( %s )\n", cd->bmAttributes, + usbConfigAttributesString( cd->bmAttributes ) + ); + + printf( + "MaxPower = 0x%x, decimal %d\n", cd->MaxPower, cd->MaxPower + ); +} + + +void +print_USB_INTERFACE_DESCRIPTOR(PUSB_INTERFACE_DESCRIPTOR id, UINT ix) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB interface descriptor + +Arguments: + + ptr to USB interface descriptor + +Return Value: + + none + +--*/ +{ + printf("\n-----------------------------\nUSB_INTERFACE_DESCRIPTOR #%d\n", ix); + + + printf( + "bLength = 0x%x\n", id->bLength + ); + + + printf( + "bDescriptorType = 0x%x ( %s )\n", id->bDescriptorType, + usbDescriptorTypeString( id->bDescriptorType ) + ); + + + printf( + "bInterfaceNumber = 0x%x\n", id->bInterfaceNumber + ); + printf( + "bAlternateSetting = 0x%x\n", id->bAlternateSetting + ); + printf( + "bNumEndpoints = 0x%x\n", id->bNumEndpoints + ); + printf( + "bInterfaceClass = 0x%x\n", id->bInterfaceClass + ); + printf( + "bInterfaceSubClass = 0x%x\n", id->bInterfaceSubClass + ); + printf( + "bInterfaceProtocol = 0x%x\n", id->bInterfaceProtocol + ); + printf( + "bInterface = 0x%x\n", id->iInterface + ); +} + + +void +print_USB_ENDPOINT_DESCRIPTOR(PUSB_ENDPOINT_DESCRIPTOR ed, int i) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB endpoint descriptor + +Arguments: + + ptr to USB endpoint descriptor, + index of this endpt in interface desc + +Return Value: + + none + +--*/ +{ + printf( + "------------------------------\nUSB_ENDPOINT_DESCRIPTOR for Pipe%02d\n", i + ); + + printf( + "bLength = 0x%x\n", ed->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", ed->bDescriptorType, + usbDescriptorTypeString( ed->bDescriptorType ) + ); + + if ( USB_ENDPOINT_DIRECTION_IN( ed->bEndpointAddress ) ) { + printf( + "bEndpointAddress= 0x%x ( INPUT )\n", ed->bEndpointAddress + ); + } else { + printf( + "bEndpointAddress= 0x%x ( OUTPUT )\n", ed->bEndpointAddress + ); + } + + printf( + "bmAttributes= 0x%x ( %s )\n", ed->bmAttributes, + usbEndPointTypeString ( ed->bmAttributes ) + ); + + printf( + "wMaxPacketSize= 0x%x, decimal %d\n", ed->wMaxPacketSize, + ed->wMaxPacketSize + ); + + printf( + "bInterval = 0x%x, decimal %d\n", ed->bInterval, ed->bInterval + ); +} + + +BOOL +DumpUsbConfig() +/*++ +Routine Description: + + Called to do formatted ascii dump to console of USB + configuration, interface, and endpoint descriptors. + +Arguments: + + none + +Return Value: + + TRUE or FALSE + +--*/ +{ + HANDLE hDev; + UINT success; + int siz, nBytes; + char buf[256] = {'\0'}; + + hDev = OpenDevice(TRUE); + if(hDev == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + siz = sizeof(buf); + + success = DeviceIoControl(hDev, + IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR, + buf, + siz, + buf, + siz, + (PULONG) &nBytes, + NULL); + + if(success == FALSE) { + printf("Ioct - GetConfigDesc failed %d\n", GetLastError()); + } else { + + ULONG i; + UINT j, n; + char *pch; + PUSB_CONFIGURATION_DESCRIPTOR cd; + PUSB_INTERFACE_DESCRIPTOR id; + PUSB_ENDPOINT_DESCRIPTOR ed; + + pch = buf; + n = 0; + + cd = (PUSB_CONFIGURATION_DESCRIPTOR) pch; + + print_USB_CONFIGURATION_DESCRIPTOR( cd ); + + pch += cd->bLength; + + do { + id = (PUSB_INTERFACE_DESCRIPTOR) pch; + + print_USB_INTERFACE_DESCRIPTOR(id, n++); + + pch += id->bLength; + for (j=0; j<id->bNumEndpoints; j++) { + + ed = (PUSB_ENDPOINT_DESCRIPTOR) pch; + + print_USB_ENDPOINT_DESCRIPTOR(ed,j); + + pch += ed->bLength; + } + i = (ULONG)(pch - buf); + + } while (i<cd->wTotalLength); + } + + CloseHandle(hDev); + + return success; + +} + diff --git a/usb/umdf2_fx2/exe/osrusbfx2.vcxproj b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj new file mode 100644 index 00000000..3ac60333 --- /dev/null +++ b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj @@ -0,0 +1,181 @@ +<?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>{020DB89E-97F7-43B1-BC5B-BD2A09EB070D}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A62B86BA-B2B1-4059-959F-064A5F9D7C70}</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 /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</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" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="dump.c" /> + <ClCompile Include="testapp.c" /> + <ResourceCompile Include="testapp.rc" /> + </ItemGroup> + <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/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..39d6f2be --- /dev/null +++ b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters @@ -0,0 +1,30 @@ +<?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>{104452B2-CFF6-4BAD-8E54-179D97D98EF8}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{F8C6B699-E4D1-450D-A1F1-4D3A0670600A}</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>{64683058-E0C9-49C7-996C-E104FFA4D81B}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dump.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="testapp.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="testapp.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf2_fx2/exe/test.cmd b/usb/umdf2_fx2/exe/test.cmd new file mode 100644 index 00000000..30b18b85 --- /dev/null +++ b/usb/umdf2_fx2/exe/test.cmd @@ -0,0 +1,6 @@ +FOR /L %%i IN (0,1,100000) do ( + + osrusbfx2.exe -r 512 -w 512 -c 1000000 -v + +) + diff --git a/usb/umdf2_fx2/exe/testapp.c b/usb/umdf2_fx2/exe/testapp.c new file mode 100644 index 00000000..ab6f483f --- /dev/null +++ b/usb/umdf2_fx2/exe/testapp.c @@ -0,0 +1,1262 @@ +/*++ + +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: + + TESTAPP.C + +Abstract: + + Console test app for osrusbfx2 driver. + +Environment: + + user mode only + +--*/ + + +#include <DriverSpecs.h> +_Analysis_mode_(_Analysis_code_type_user_code_) + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "devioctl.h" +#include "strsafe.h" + +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <setupapi.h> +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(default:4200) +#pragma warning(default:4201) +#pragma warning(default:4214) + +#define WHILE(a) \ +while(__pragma(warning(disable:4127)) a __pragma(warning(disable:4127))) + +#define MAX_DEVPATH_LENGTH 256 +#define NUM_ASYNCH_IO 100 +#define BUFFER_SIZE 1024 +#define READER_TYPE 1 +#define WRITER_TYPE 2 + +BOOL G_fDumpUsbConfig = FALSE; // flags set in response to console command line switches +BOOL G_fDumpReadData = FALSE; +BOOL G_fRead = FALSE; +BOOL G_fWrite = FALSE; +BOOL G_fPlayWithDevice = FALSE; +BOOL G_fPerformAsyncIo = FALSE; +ULONG G_IterationCount = 1; //count of iterations of the test we are to perform +ULONG G_WriteLen = 512; // #bytes to write +ULONG G_ReadLen = 512; // #bytes to read + +BOOL +DumpUsbConfig( // defined in dump.c + ); + +typedef enum _INPUT_FUNCTION { + LIGHT_ONE_BAR = 1, + CLEAR_ONE_BAR, + LIGHT_ALL_BARS, + CLEAR_ALL_BARS, + GET_BAR_GRAPH_LIGHT_STATE, + GET_SWITCH_STATE, + GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE, + GET_7_SEGEMENT_STATE, + SET_7_SEGEMENT_STATE, + RESET_DEVICE, + REENUMERATE_DEVICE, +} INPUT_FUNCTION; + +_Success_(return) +BOOL +GetDevicePath( + IN LPGUID InterfaceGuid, + _Out_writes_z_(BufLen) PCHAR DevicePath, + _In_ size_t BufLen + ) +{ + HDEVINFO HardwareDeviceInfo; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; + ULONG Length, RequiredLength = 0; + BOOL bResult; + HRESULT hr; + + HardwareDeviceInfo = SetupDiGetClassDevs( + InterfaceGuid, + NULL, + NULL, + (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { + printf("SetupDiGetClassDevs failed!\n"); + return FALSE; + } + + DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, + 0, + InterfaceGuid, + 0, + &DeviceInterfaceData); + + if (bResult == FALSE) { + + LPVOID lpMsgBuf; + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &lpMsgBuf, + 0, + NULL + )) { + + printf("SetupDiEnumDeviceInterfaces failed: %s", (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + return FALSE; + } + + SetupDiGetDeviceInterfaceDetail( + HardwareDeviceInfo, + &DeviceInterfaceData, + NULL, + 0, + &RequiredLength, + NULL + ); + + DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) + LocalAlloc(LMEM_FIXED, RequiredLength); + + if (DeviceInterfaceDetailData == NULL) { + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + printf("Failed to allocate memory.\n"); + return FALSE; + } + + DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + Length = RequiredLength; + + bResult = SetupDiGetDeviceInterfaceDetail( + HardwareDeviceInfo, + &DeviceInterfaceData, + DeviceInterfaceDetailData, + Length, + &RequiredLength, + NULL); + + if (bResult == FALSE) { + + LPVOID lpMsgBuf; + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &lpMsgBuf, + 0, + NULL)) { + + printf("Error in SetupDiGetDeviceInterfaceDetail: %s\n", (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + return FALSE; + } + + hr = StringCchCopy(DevicePath, + BufLen, + DeviceInterfaceDetailData->DevicePath); + if (FAILED(hr)) { + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + return FALSE; + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + + return TRUE; + +} + + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ) + +/*++ +Routine Description: + + Called by main() to open an instance of our device after obtaining its name + +Arguments: + + Synchronous - TRUE, if Device is to be opened for synchronous access. + FALSE, otherwise. + +Return Value: + + Device handle on success else INVALID_HANDLE_VALUE + +--*/ + +{ + HANDLE hDev; + char completeDeviceName[MAX_DEVPATH_LENGTH]; + + if ( !GetDevicePath( + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + completeDeviceName, + sizeof(completeDeviceName)) ) + { + return INVALID_HANDLE_VALUE; + } + + printf("DeviceName = (%s)\n", completeDeviceName); + + if(Synchronous) { + hDev = CreateFile(completeDeviceName, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, // default security + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + } else { + + hDev = CreateFile(completeDeviceName, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, // default security + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + } + + if (hDev == INVALID_HANDLE_VALUE) { + printf("Failed to open the device, error - %d", GetLastError()); + } else { + printf("Opened the device successfully.\n"); + } + + return hDev; +} + + + +VOID +Usage() + +/*++ +Routine Description: + + Called by main() to dump usage info to the console when + the app is called with no parms or with an invalid parm + +Arguments: + + None + +Return Value: + + None + +--*/ + +{ + printf("Usage for osrusbfx2 testapp:\n"); + printf("-r [n] where n is number of bytes to read\n"); + printf("-w [n] where n is number of bytes to write\n"); + printf("-c [n] where n is number of iterations (default = 1)\n"); + printf("-v verbose -- dumps read data\n"); + printf("-p to control bar LEDs, seven segment, and dip switch\n"); + printf("-a to perform asynchronous I/O\n"); + printf("-u to dump USB configuration and pipe info \n"); + + return; +} + + +void +Parse( + _In_ int argc, + _In_reads_(argc) LPSTR *argv + ) + +/*++ +Routine Description: + + Called by main() to parse command line parms + +Arguments: + + argc and argv that was passed to main() + +Return Value: + + Sets global flags as per user function request + +--*/ + +{ + int i; + + if ( argc < 2 ) // give usage if invoked with no parms + Usage(); + + for (i=0; i<argc; i++) { + if (argv[i][0] == '-' || + argv[i][0] == '/') { + switch(argv[i][1]) { + case 'r': + case 'R': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { +#pragma warning(suppress: 6385) + G_ReadLen = atoi(&argv[i+1][0]); + G_fRead = TRUE; + } + i++; + break; + case 'w': + case 'W': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_WriteLen = atoi(&argv[i+1][0]); + G_fWrite = TRUE; + } + i++; + break; + case 'c': + case 'C': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_IterationCount = atoi(&argv[i+1][0]); + } + i++; + break; + case 'u': + case 'U': + G_fDumpUsbConfig = TRUE; + break; + case 'p': + case 'P': + G_fPlayWithDevice = TRUE; + break; + case 'a': + case 'A': + G_fPerformAsyncIo = TRUE; + break; + case 'v': + case 'V': + G_fDumpReadData = TRUE; + break; + default: + Usage(); + } + } + } +} + +BOOL +Compare_Buffs( + _In_reads_bytes_(buff1length) char *buff1, + _In_ ULONG buff1length, + _In_reads_bytes_(buff2length) char *buff2, + _In_ ULONG buff2length + ) +/*++ +Routine Description: + + Called to verify read and write buffers match for loopback test + +Arguments: + + buffers to compare and length + +Return Value: + + TRUE if buffers match, else FALSE + +--*/ +{ + int ok = 1; + + if (buff1length != buff2length || memcmp(buff1, buff2, buff1length )) { + // Edi, and Esi point to the mismatching char and ecx indicates the + // remaining length. + ok = 0; + } + + return ok; +} + +#define NPERLN 8 + +VOID +Dump( + UCHAR *b, + int len +) + +/*++ +Routine Description: + + Called to do formatted ascii dump to console of the io buffer + +Arguments: + + buffer and length + +Return Value: + + none + +--*/ + +{ + ULONG i; + ULONG longLen = (ULONG)len / sizeof( ULONG ); + PULONG pBuf = (PULONG) b; + + // dump an ordinal ULONG for each sizeof(ULONG)'th byte + printf("\n****** BEGIN DUMP LEN decimal %d, 0x%x\n", len,len); + for (i=0; i<longLen; i++) { + printf("%04X ", *pBuf++); + if (i % NPERLN == (NPERLN - 1)) { + printf("\n"); + } + } + if (i % NPERLN != 0) { + printf("\n"); + } + printf("\n****** END DUMP LEN decimal %d, 0x%x\n", len,len); +} + + +BOOL +PlayWithDevice() +{ + HANDLE deviceHandle; + DWORD code; + ULONG index; + INPUT_FUNCTION function; + BAR_GRAPH_STATE barGraphState; + ULONG bar; + SWITCH_STATE switchState; + UCHAR sevenSegment = 0; + UCHAR i; + BOOL result = FALSE; + + deviceHandle = OpenDevice(FALSE); + + if (deviceHandle == INVALID_HANDLE_VALUE) { + + printf("Unable to find any OSR FX2 devices!\n"); + + return FALSE; + + } + + // + // Infinitely print out the list of choices, ask for input, process + // the request + // + WHILE(TRUE) { + + printf ("\nUSBFX TEST -- Functions:\n\n"); + printf ("\t1. Light Bar\n"); + printf ("\t2. Clear Bar\n"); + printf ("\t3. Light entire Bar graph\n"); + printf ("\t4. Clear entire Bar graph\n"); + printf ("\t5. Get bar graph state\n"); + printf ("\t6. Get Switch state\n"); + printf ("\t7. Get Switch Interrupt Message\n"); + printf ("\t8. Get 7 segment state\n"); + printf ("\t9. Set 7 segment state\n"); + printf ("\t10. Reset the device\n"); + printf ("\t11. Reenumerate the device\n"); + printf ("\n\t0. Exit\n"); + printf ("\n\tSelection: "); + + if (scanf_s ("%d", &function) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + switch(function) { + + case LIGHT_ONE_BAR: + + printf("Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + printf("Invalid bar number!\n"); + goto Error; + } + + bar--; // normalize to 0 to 7 + + barGraphState.BarsAsUChar = 1 << (UCHAR)bar; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ONE_BAR: + + + printf("Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + printf("Invalid bar number!\n"); + goto Error; + } + + bar--; + + // + // Read the current state + // + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + if (barGraphState.BarsAsUChar & (1 << bar)) { + + printf("Bar is set...Clearing it\n"); + barGraphState.BarsAsUChar &= ~(1 << bar); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + + } + + } else { + + printf("Bar not set.\n"); + + } + + break; + + case LIGHT_ALL_BARS: + + barGraphState.BarsAsUChar = 0xFF; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ALL_BARS: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + + case GET_BAR_GRAPH_LIGHT_STATE: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Bar Graph: \n"); + printf(" Bar8 is %s\n", barGraphState.Bar8 ? "ON" : "OFF"); + printf(" Bar7 is %s\n", barGraphState.Bar7 ? "ON" : "OFF"); + printf(" Bar6 is %s\n", barGraphState.Bar6 ? "ON" : "OFF"); + printf(" Bar5 is %s\n", barGraphState.Bar5 ? "ON" : "OFF"); + printf(" Bar4 is %s\n", barGraphState.Bar4 ? "ON" : "OFF"); + printf(" Bar3 is %s\n", barGraphState.Bar3 ? "ON" : "OFF"); + printf(" Bar2 is %s\n", barGraphState.Bar2 ? "ON" : "OFF"); + printf(" Bar1 is %s\n", barGraphState.Bar1 ? "ON" : "OFF"); + + break; + + case GET_SWITCH_STATE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_READ_SWITCHES, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(SWITCH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Switches: \n"); + printf(" Switch8 is %s\n", switchState.Switch8 ? "ON" : "OFF"); + printf(" Switch7 is %s\n", switchState.Switch7 ? "ON" : "OFF"); + printf(" Switch6 is %s\n", switchState.Switch6 ? "ON" : "OFF"); + printf(" Switch5 is %s\n", switchState.Switch5 ? "ON" : "OFF"); + printf(" Switch4 is %s\n", switchState.Switch4 ? "ON" : "OFF"); + printf(" Switch3 is %s\n", switchState.Switch3 ? "ON" : "OFF"); + printf(" Switch2 is %s\n", switchState.Switch2 ? "ON" : "OFF"); + printf(" Switch1 is %s\n", switchState.Switch1 ? "ON" : "OFF"); + + break; + + case GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(switchState), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Switches: %d\n",index); + printf(" Switch8 is %s\n", switchState.Switch8 ? "ON" : "OFF"); + printf(" Switch7 is %s\n", switchState.Switch7 ? "ON" : "OFF"); + printf(" Switch6 is %s\n", switchState.Switch6 ? "ON" : "OFF"); + printf(" Switch5 is %s\n", switchState.Switch5 ? "ON" : "OFF"); + printf(" Switch4 is %s\n", switchState.Switch4 ? "ON" : "OFF"); + printf(" Switch3 is %s\n", switchState.Switch3 ? "ON" : "OFF"); + printf(" Switch2 is %s\n", switchState.Switch2 ? "ON" : "OFF"); + printf(" Switch1 is %s\n", switchState.Switch1 ? "ON" : "OFF"); + + break; + + case GET_7_SEGEMENT_STATE: + + sevenSegment = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &sevenSegment, // Ptr to OutBuffer + sizeof(UCHAR), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("7 Segment mask: 0x%x\n", sevenSegment); + break; + + case SET_7_SEGEMENT_STATE: + + for (i = 0; i < 8; i++) { + + sevenSegment = 1 << i; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY, + &sevenSegment, // Ptr to InBuffer + sizeof(UCHAR), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("This is %d\n", i); + Sleep(500); + + } + + printf("7 Segment mask: 0x%x\n", sevenSegment); + break; + + case RESET_DEVICE: + + printf("Reset the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_RESET_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case REENUMERATE_DEVICE: + + printf("Re-enumerate the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_REENUMERATE_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + // + // Close the handle to the device and exit out so that + // the driver can unload when the device is surprise-removed + // and reenumerated. + // + default: + + result = TRUE; + goto Error; + + } + + } // end of while loop + +Error: + + CloseHandle(deviceHandle); + return result; + +} + + +ULONG +AsyncIo( + PVOID ThreadParameter + ) +{ + HANDLE hDevice = INVALID_HANDLE_VALUE; + HANDLE hCompletionPort = NULL; + OVERLAPPED *pOvList = NULL; + PUCHAR buf = NULL; + ULONG_PTR i; + ULONG ioType = (ULONG)(ULONG_PTR)ThreadParameter; + ULONG error; + + hDevice = OpenDevice(FALSE); + + if (hDevice == INVALID_HANDLE_VALUE) { + printf("Cannot open device %d\n", GetLastError()); + goto Error; + } + + hCompletionPort = CreateIoCompletionPort(hDevice, NULL, 1, 0); + + if (hCompletionPort == NULL) { + printf("Cannot open completion port %d \n",GetLastError()); + goto Error; + } + + pOvList = (OVERLAPPED *)malloc(NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + + if (pOvList == NULL) { + printf("Cannot allocate overlapped array \n"); + goto Error; + } + + buf = (PUCHAR)malloc(NUM_ASYNCH_IO * BUFFER_SIZE); + + if (buf == NULL) { + printf("Cannot allocate buffer \n"); + goto Error; + } + + ZeroMemory(pOvList, NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + ZeroMemory(buf, NUM_ASYNCH_IO * BUFFER_SIZE); + + // + // Issue asynch I/O + // + + for (i = 0; i < NUM_ASYNCH_IO; i++) { + if (ioType == READER_TYPE) { + if ( ReadFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf(" %Iu th read failed %d \n",i, GetLastError()); + goto Error; + } + } + + } else { + if ( WriteFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf(" %Iu th write failed %d \n",i, GetLastError()); + goto Error; + } + } + } + } + + // + // Wait for the I/Os to complete. If one completes then reissue the I/O + // + + WHILE (1) { + OVERLAPPED *completedOv; + ULONG_PTR key; + ULONG numberOfBytesTransferred; + + if ( GetQueuedCompletionStatus(hCompletionPort, &numberOfBytesTransferred, + &key, &completedOv, INFINITE) == 0) { + printf("GetQueuedCompletionStatus failed %d\n", GetLastError()); + goto Error; + } + + // + // Read successfully completed. Issue another one. + // + + if (ioType == READER_TYPE) { + + i = completedOv - pOvList; + + printf("Number of bytes read by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( ReadFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf("%Iu th Read failed %d \n", i, GetLastError()); + goto Error; + } + } + } else { + + i = completedOv - pOvList; + + printf("Number of bytes written by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( WriteFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf("%Iu th write failed %d \n", i, GetLastError()); + goto Error; + } + } + } + } + +Error: + if (hDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hDevice); + } + + if (hCompletionPort) { + CloseHandle(hCompletionPort); + } + + if (pOvList) { + free(pOvList); + } + if (buf) { + free(buf); + } + + return 1; + +} + + +int +_cdecl +main( + _In_ int argc, + _In_reads_(argc) LPSTR *argv + ) +/*++ +Routine Description: + + Entry point to rwbulk.exe + Parses cmdline, performs user-requested tests + +Arguments: + + argc, argv standard console 'c' app arguments + +Return Value: + + Zero + +--*/ + +{ + char * pinBuf = NULL; + char * poutBuf = NULL; + ULONG nBytesRead; + ULONG nBytesWrite = 0; + int ok; + int retValue = 0; + UINT success; + HANDLE hRead = INVALID_HANDLE_VALUE; + HANDLE hWrite = INVALID_HANDLE_VALUE; + ULONG fail = 0L; + ULONG i; + + + Parse(argc, argv ); + + // + // dump USB configuation and pipe info + // + if (G_fDumpUsbConfig) { + DumpUsbConfig(); + } + + if (G_fPlayWithDevice) { + PlayWithDevice(); + goto exit; + } + + if (G_fPerformAsyncIo) { + HANDLE th1; + + // + // Create a reader thread + // + th1 = CreateThread( NULL, // Default Security Attrib. + 0, // Initial Stack Size, + AsyncIo, // Thread Func + (LPVOID)READER_TYPE, + 0, // Creation Flags + NULL ); // Don't need the Thread Id. + + if (th1 == NULL) { + printf("Couldn't create reader thread - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + // + // Use this thread for peforming write. + // + AsyncIo((PVOID)WRITER_TYPE); + + goto exit; + } + + // + // doing a read, write, or both test + // + if ((G_fRead) || (G_fWrite)) { + + if (G_fRead) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_ReadLen % sizeof( ULONG ) ) { + G_ReadLen++; + } + } + + // + // open the output file + // + hRead = OpenDevice(TRUE); + if(hRead == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + pinBuf = malloc(G_ReadLen); + } + + if (G_fWrite) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_WriteLen % sizeof( ULONG ) ) { + G_WriteLen++; + } + } + + // + // open the output file + // + hWrite = OpenDevice(TRUE); + if(hWrite == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + poutBuf = malloc(G_WriteLen); + } + + for (i = 0; i < G_IterationCount; i++) { + ULONG j; + + if (G_fWrite && poutBuf && hWrite != INVALID_HANDLE_VALUE) { + + PULONG pOut = (PULONG) poutBuf; + ULONG numLongs = G_WriteLen / sizeof( ULONG ); + + // + // put some data in the output buffer + // + for (j=0; j<numLongs; j++) { + *(pOut+j) = j; + } + + // + // send the write + // + success = WriteFile(hWrite, poutBuf, G_WriteLen, &nBytesWrite, NULL); + if(success == 0) { + printf("WriteFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + printf("Write (%04.4u) : request %06.6u bytes -- %06.6u bytes written\n", + i, G_WriteLen, nBytesWrite); + + assert(nBytesWrite == G_WriteLen); + } + + if (G_fRead && pinBuf) { + + success = ReadFile(hRead, pinBuf, G_ReadLen, &nBytesRead, NULL); + if(success == 0) { + printf("ReadFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + printf("Read (%04.4u) : request %06.6u bytes -- %06.6u bytes read\n", + i, G_ReadLen, nBytesRead); + + if (G_fWrite && poutBuf) { + + // + // validate the input buffer against what + // we sent to the 82930 (loopback test) + // + ok = Compare_Buffs(pinBuf, nBytesRead, poutBuf, nBytesWrite); + + if( G_fDumpReadData ) { + printf("Dumping read buffer\n"); + Dump( (PUCHAR) pinBuf, nBytesRead ); + printf("Dumping write buffer\n"); + Dump( (PUCHAR) poutBuf, nBytesRead ); + } + assert(ok); + + if(ok != 1) { + fail++; + } + + assert(G_ReadLen == G_WriteLen); + assert(nBytesRead == G_ReadLen); + } + } + } + + } + +exit: + + if (pinBuf) { + free(pinBuf); + } + + if (poutBuf) { + free(poutBuf); + } + + // close devices if needed + if (hRead != INVALID_HANDLE_VALUE) { + CloseHandle(hRead); + } + + if (hWrite != INVALID_HANDLE_VALUE) { + CloseHandle(hWrite); + } + + return retValue; +} + + diff --git a/usb/umdf2_fx2/exe/testapp.rc b/usb/umdf2_fx2/exe/testapp.rc new file mode 100644 index 00000000..3947204a --- /dev/null +++ b/usb/umdf2_fx2/exe/testapp.rc @@ -0,0 +1,12 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "OSRUSBFX2 Bulk & Isoch Read and Write test App" +#define VER_INTERNALNAME_STR "osrusbfx2.exe" +#define VER_ORIGINALFILENAME_STR "osrusbfx2.exe" + +#include <common.ver> + diff --git a/usb/umdf2_fx2/inc/prototypes.h b/usb/umdf2_fx2/inc/prototypes.h new file mode 100644 index 00000000..cc99cdfe --- /dev/null +++ b/usb/umdf2_fx2/inc/prototypes.h @@ -0,0 +1,14 @@ +DRIVER_INITIALIZE DriverEntry; + +EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd; + +EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDriverContextCleanup; +EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; + +EVT_WDF_IO_QUEUE_IO_READ EvtIoRead; +EVT_WDF_IO_QUEUE_IO_WRITE EvtIoWrite; +EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl; + +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestReadCompletionRoutine; +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestWriteCompletionRoutine; + diff --git a/usb/umdf2_fx2/inc/public.h b/usb/umdf2_fx2/inc/public.h new file mode 100644 index 00000000..12ddf21f --- /dev/null +++ b/usb/umdf2_fx2/inc/public.h @@ -0,0 +1,173 @@ +/*++ + +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: + + public.h + +Abstract: + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + +#pragma warning(push) +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +#include <poppack.h> + +#pragma warning(pop) + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 0x65500 + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#endif diff --git a/usb/umdf2_fx2/umdf2_fx2.sln b/usb/umdf2_fx2/umdf2_fx2.sln new file mode 100644 index 00000000..8f165bef --- /dev/null +++ b/usb/umdf2_fx2/umdf2_fx2.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{A3ECF9EF-7A4E-4E3A-8B6C-F28831959DF5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{1316F001-B1D6-4F04-9298-A553516BACF9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2um", "driver\osrusbfx2um.vcxproj", "{33535CCD-5A39-4FDC-9C3A-796896CE065B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "exe\osrusbfx2.vcxproj", "{020DB89E-97F7-43B1-BC5B-BD2A09EB070D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Debug|Win32.ActiveCfg = Debug|Win32 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Debug|Win32.Build.0 = Debug|Win32 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Release|Win32.ActiveCfg = Release|Win32 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Release|Win32.Build.0 = Release|Win32 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Debug|x64.ActiveCfg = Debug|x64 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Debug|x64.Build.0 = Debug|x64 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Release|x64.ActiveCfg = Release|x64 + {33535CCD-5A39-4FDC-9C3A-796896CE065B}.Release|x64.Build.0 = Release|x64 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Debug|Win32.ActiveCfg = Debug|Win32 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Debug|Win32.Build.0 = Debug|Win32 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Release|Win32.ActiveCfg = Release|Win32 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Release|Win32.Build.0 = Release|Win32 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Debug|x64.ActiveCfg = Debug|x64 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Debug|x64.Build.0 = Debug|x64 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Release|x64.ActiveCfg = Release|x64 + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {33535CCD-5A39-4FDC-9C3A-796896CE065B} = {A3ECF9EF-7A4E-4E3A-8B6C-F28831959DF5} + {020DB89E-97F7-43B1-BC5B-BD2A09EB070D} = {1316F001-B1D6-4F04-9298-A553516BACF9} + EndGlobalSection +EndGlobal diff --git a/usb/umdf_filter_kmdf/Package/package.VcxProj b/usb/umdf_filter_kmdf/Package/package.VcxProj new file mode 100644 index 00000000..cbcac967 --- /dev/null +++ b/usb/umdf_filter_kmdf/Package/package.VcxProj @@ -0,0 +1,91 @@ +<?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="PropertySheets"> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Utility</ConfigurationType> + <DriverType>Package</DriverType> + <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> + <Configuration>Debug</Configuration> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3EF9240F-7E95-49A7-8B0D-5F7061655764}</ProjectGuid> + <SampleGuid>{0CA520A9-E977-438B-8DC7-505D2B17D810}</SampleGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + <ImportToStore>False</ImportToStore> + <InstallMode>None</InstallMode> + <HardwareIdString /> + <CommandLine /> + <ScriptPath /> + <DeployFiles /> + <ScriptName /> + <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery> + <EnableVerifier>False</EnableVerifier> + <AllDrivers>False</AllDrivers> + <VerifyProjectOutput>True</VerifyProjectOutput> + <VerifyDrivers /> + <VerifyFlags>133563</VerifyFlags> + </PropertyGroup> + <ItemDefinitionGroup> + </ItemDefinitionGroup> + <ItemGroup> + <!--Inf Include="DriverInf.inv" /--> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\kmdf_driver\osrusbfx2.vcxproj"> + <Project>{23EAF474-B558-4457-B03C-164DA83B7575}</Project> + </ProjectReference> + <ProjectReference Include="..\umdf_filter\WUDFOsrUsbFilter.vcxproj"> + <Project>{0149B701-5356-434C-AC8C-07CAA1D9A4AA}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters b/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters new file mode 100644 index 00000000..cee9d105 --- /dev/null +++ b/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters @@ -0,0 +1,21 @@ +<?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>{11E4648F-825F-4166-A710-1F8405EB585C}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{702820FE-A863-4886-A39F-1EF5E2CAEB24}</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>{040C9EA5-697C-432B-B344-774708E72655}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{18B9CB91-2A87-4A72-ABFF-A1FB4EACD0AC}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_kmdf/ReadMe.md b/usb/umdf_filter_kmdf/ReadMe.md new file mode 100644 index 00000000..cc12d391 --- /dev/null +++ b/usb/umdf_filter_kmdf/ReadMe.md @@ -0,0 +1,38 @@ +Sample UMDF Filter above KMDF Function Driver for OSR USB-FX2 (UMDF Version 1) +============================================================================== + +The umdf\_filter\_kmdf sample demonstrates how to load a UMDF filter driver as an upper filter driver above the kmdf\_fx2 sample driver. + +The sample includes Event Tracing for Windows (ETW) tracing support, and is written for the OSR USB-FX2 Learning Kit. The specification for the device is at <http://www.osronline.com/hardware/OSRFX2_32.pdf>. + +Overview +-------- + +Here is the overview of the device: + +- The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681). +- It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN). +- Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states. +- Interrupt Endpoint: + - Sends an 8-bit value that represents the state of the switches. + - Sent on startup, resume from suspend, and whenever the switch pack setting changes. + - Firmware does not de-bounce the switch pack. + - One switch change can result in multiple bytes being sent. + - Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack). +- Bulk Endpoints are configured for loopback: + - The device moves data from IN endpoint to OUT endpoint. + - The device does not change the values of the data it receives nor does it internally create any data. + - Endpoints are always double buffered. + - Maximum packet size depends on speed (64 full speed, 512 high speed). +- ETW events: + - Included osrusbfx2.man, which describes events added. + - Three events are targeted to the event log: + - Failure during the add device routine. + - Failure to start the OSR device on a USB 1.1 controller. + - Invocation of the “re-enumerate device” IOCTL. + - Read/write start/stop events can be used to measure the time taken. + +Testing the driver +------------------ + +You can test this sample either by using the [Custom driver access](http://go.microsoft.com/fwlink/p/?LinkID=248288) sample application, or by using the osrusbfx2.exe test application. For information on how to build and use the osrusbfx2.exe application, see the test instructions for the [kmdf\_fx2](http://msdn.microsoft.com/en-us/library/windows/hardware/) sample. diff --git a/usb/umdf_filter_kmdf/inc/WUDFOsrUsbPublic.h b/usb/umdf_filter_kmdf/inc/WUDFOsrUsbPublic.h new file mode 100644 index 00000000..6681fa14 --- /dev/null +++ b/usb/umdf_filter_kmdf/inc/WUDFOsrUsbPublic.h @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + WUDFOsrUsbPublic.h + +Abstract: + + This module contains the common declarations shared by driver + and user applications for the UMDF OSR device sample. + + Note that this driver does NOT use the same device interface GUID + as the KMDF OSR USB sample. + +Environment: + + user and kernel + +--*/ + +#pragma once + +// +// Define an Interface Guid so that app can find the device and talk to it. +// + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + diff --git a/usb/umdf_filter_kmdf/inc/list.h b/usb/umdf_filter_kmdf/inc/list.h new file mode 100644 index 00000000..38d0b1e9 --- /dev/null +++ b/usb/umdf_filter_kmdf/inc/list.h @@ -0,0 +1,77 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + list.h + +Abstract: + + This module contains doubly linked list macros + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + + +FORCEINLINE +VOID +InitializeListHead( + IN PLIST_ENTRY ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +FORCEINLINE +BOOLEAN +RemoveEntryList( + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + PLIST_ENTRY Flink; + + Flink = Entry->Flink; + Blink = Entry->Blink; + Blink->Flink = Flink; + Flink->Blink = Blink; + return (BOOLEAN)(Flink == Blink); +} + +FORCEINLINE +VOID +InsertHeadList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Flink; + + Flink = ListHead->Flink; + Entry->Flink = Flink; + Entry->Blink = ListHead; + Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +FORCEINLINE +VOID +InsertTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + + Blink = ListHead->Blink; + Entry->Flink = ListHead; + Entry->Blink = Blink; + Blink->Flink = Entry; + ListHead->Blink = Entry; +} diff --git a/usb/umdf_filter_kmdf/inc/public.h b/usb/umdf_filter_kmdf/inc/public.h new file mode 100644 index 00000000..22f6cb6d --- /dev/null +++ b/usb/umdf_filter_kmdf/inc/public.h @@ -0,0 +1,217 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + public.h + +Abstract: + + Public definitions for the OSR_FX2 device operations. + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +#include "WudfOsrUsbPublic.h" + + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> + +#pragma warning( push ) +#pragma warning( disable : 4201 ) // nameless struct/union +#pragma warning( disable : 4214 ) // bit-field type other than int + +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +// +// Seven segment display bit values. +// + +// +// Undefine conflicting MFC constant +// +#undef SS_CENTER +#undef SS_LEFT +#undef SS_RIGHT + +#define SS_TOP 0x01 +#define SS_TOP_LEFT 0x40 +#define SS_TOP_RIGHT 0x02 +#define SS_CENTER 0x20 +#define SS_BOTTOM_LEFT 0x10 +#define SS_BOTTOM_RIGHT 0x04 +#define SS_BOTTOM 0x80 +#define SS_DOT 0x08 + +// +// FILE_PLAYBACK +// +// FILE_PLAYBACK structure contains the parameters for the PLAY_FILE I/O Control. +// + +typedef struct _FILE_PLAYBACK +{ + // + // The delay between changes in the display, in milliseconds. + // + + USHORT Delay; + + // + // The data file path. + // + + WCHAR Path[1]; +} FILE_PLAYBACK, *PFILE_PLAYBACK; + +#include <poppack.h> + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 0x65500 + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_PLAY_FILE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#pragma warning(pop) + +#endif + diff --git a/usb/umdf_filter_kmdf/inc/usb_hw.h b/usb/umdf_filter_kmdf/inc/usb_hw.h new file mode 100644 index 00000000..d6e983f1 --- /dev/null +++ b/usb/umdf_filter_kmdf/inc/usb_hw.h @@ -0,0 +1,233 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Usb.h + +Abstract: + + Contains prototypes for interfacing with a USB connected device. These + are copied from the KMDF WDFUSB.H header file (but with the WDF specific + portions removed) + +Environment: + + kernel mode only + +--*/ + +#pragma once + +typedef enum _WINUSB_BMREQUEST_DIRECTION { + BmRequestHostToDevice = BMREQUEST_HOST_TO_DEVICE, + BmRequestDeviceToHost = BMREQUEST_DEVICE_TO_HOST, +} WINUSB_BMREQUEST_DIRECTION; + +typedef enum _WINUSB_BMREQUEST_TYPE { + BmRequestStandard = BMREQUEST_STANDARD, + BmRequestClass = BMREQUEST_CLASS, + BmRequestVendor = BMREQUEST_VENDOR, +} WINUSB_BMREQUEST_TYPE; + +typedef enum _WINUSB_BMREQUEST_RECIPIENT { + BmRequestToDevice = BMREQUEST_TO_DEVICE, + BmRequestToInterface = BMREQUEST_TO_INTERFACE, + BmRequestToEndpoint = BMREQUEST_TO_ENDPOINT, + BmRequestToOther = BMREQUEST_TO_OTHER, +} WINUSB_BMREQUEST_RECIPIENT; + +typedef enum _WINUSB_DEVICE_TRAITS { + WINUSB_DEVICE_TRAIT_SELF_POWERED = 0x00000001, + WINUSB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE = 0x00000002, + WINUSB_DEVICE_TRAIT_AT_HIGH_SPEED = 0x00000004, +} WINUSB_DEVICE_TRAITS; + +typedef enum _WdfUsbTargetDeviceSelectInterfaceType { + WdfUsbTargetDeviceSelectInterfaceTypeInterface = 0x10, + WdfUsbTargetDeviceSelectInterfaceTypeUrb = 0x11, +} WdfUsbTargetDeviceSelectInterfaceType; + + + +typedef union _WINUSB_CONTROL_SETUP_PACKET { + struct { + union { + #pragma warning(disable:4214) // bit field types other than int + struct { + // + // Valid values are BMREQUEST_TO_DEVICE, BMREQUEST_TO_INTERFACE, + // BMREQUEST_TO_ENDPOINT, BMREQUEST_TO_OTHER + // + BYTE Recipient:2; + + BYTE Reserved:3; + + // + // Valid values are BMREQUEST_STANDARD, BMREQUEST_CLASS, + // BMREQUEST_VENDOR + // + BYTE Type:2; + + // + // Valid values are BMREQUEST_HOST_TO_DEVICE, + // BMREQUEST_DEVICE_TO_HOST + // + BYTE Dir:1; + } Request; + #pragma warning(default:4214) // bit field types other than int + BYTE Byte; + } bm; + + BYTE bRequest; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wValue; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wIndex; + + USHORT wLength; + } Packet; + + struct { + BYTE Bytes[8]; + } Generic; + + WINUSB_SETUP_PACKET WinUsb; + +} WINUSB_CONTROL_SETUP_PACKET, *PWINUSB_CONTROL_SETUP_PACKET; + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_CLASS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestClass; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_VENDOR( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestVendor; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_FEATURE( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT FeatureSelector, + USHORT Index, + BOOLEAN SetFeature + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestHostToDevice; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + if (SetFeature) { + Packet->Packet.bRequest = USB_REQUEST_SET_FEATURE; + } + else { + Packet->Packet.bRequest = USB_REQUEST_CLEAR_FEATURE; + } + + Packet->Packet.wValue.Value = FeatureSelector; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestDeviceToHost; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + Packet->Packet.bRequest = USB_REQUEST_GET_STATUS; + Packet->Packet.wIndex.Value = Index; + Packet->Packet.wValue.Value = 0; + + // Packet->Packet.wLength will be set by the formatting function +} + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/Device.c b/usb/umdf_filter_kmdf/kmdf_driver/Device.c new file mode 100644 index 00000000..87ead857 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/Device.c @@ -0,0 +1,1051 @@ +/*++ + +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 <devpkey.h> + +#if defined(EVENT_TRACING) +#include "device.tmh" +#endif + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, OsrFxEvtDeviceAdd) +#pragma alloc_text(PAGE, OsrFxEvtDevicePrepareHardware) +#pragma alloc_text(PAGE, OsrFxEvtDeviceD0Exit) +#pragma alloc_text(PAGE, SelectInterfaces) +#pragma alloc_text(PAGE, OsrFxSetPowerPolicy) +#pragma alloc_text(PAGE, OsrFxReadFdoRegistryKeyValue) +#pragma alloc_text(PAGE, GetDeviceEventLoggingNames) +#pragma alloc_text(PAGE, OsrFxValidateConfigurationDescriptor) +#endif + + +NTSTATUS +OsrFxEvtDeviceAdd( + WDFDRIVER Driver, + 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; + WDF_DEVICE_PNP_CAPABILITIES pnpCaps; + WDF_IO_QUEUE_CONFIG ioQueueConfig; + PDEVICE_CONTEXT pDevContext; + WDFQUEUE queue; + GUID activity; + UNICODE_STRING symbolicLinkName; + WDFSTRING symbolicLinkString; + DEVPROP_BOOLEAN isRestricted; + + 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 wdfusb pipe continuous reader + // as we go in and out of the D0-working state. + // + + pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry; + pnpPowerCallbacks.EvtDeviceD0Exit = OsrFxEvtDeviceD0Exit; + pnpPowerCallbacks.EvtDeviceSelfManagedIoFlush = OsrFxEvtDeviceSelfManagedIoFlush; + + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered); + + // + // 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; + } + + // + // Setup the activity ID so that we can log events using it. + // + + activity = DeviceToActivityId(device); + + // + // Get the DeviceObject context by using accessor function specified in + // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for DEVICE_CONTEXT. + // + pDevContext = GetDeviceContext(device); + + // + // Get the device's friendly name and location so that we can use it in + // error logging. If this fails then it will setup dummy strings. + // + + GetDeviceEventLoggingNames(device); + + // + // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so + // that you don't get the popup in usermode when you surprise remove the device. + // + WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); + pnpCaps.SurpriseRemovalOK = WdfTrue; + + WdfDeviceSetPnpCapabilities(device, &pnpCaps); + + // + // Create a parallel default queue and register an event callback to + // receive ioctl requests. We will create separate queues for + // handling read and write requests. All other requests will be + // completed with error status automatically by the framework. + // + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, + WdfIoQueueDispatchParallel); + + ioQueueConfig.EvtIoDeviceControl = OsrFxEvtIoDeviceControl; + + // + // By default, Static Driver Verifier (SDV) displays a warning if it + // doesn't find the EvtIoStop callback on a power-managed queue. + // The 'assume' below causes SDV to suppress this warning. If the driver + // has not explicitly set PowerManaged to WdfFalse, the framework creates + // power-managed queues when the device is not a filter driver. Normally + // the EvtIoStop is required for power-managed queues, but for this driver + // it is not needed b/c the driver doesn't hold on to the requests for + // long time or forward them to other drivers. + // If the EvtIoStop callback is not implemented, the framework waits for + // all driver-owned requests to be done before moving in the Dx/sleep + // states or before removing the device, which is the correct behavior + // for this type of driver. If the requests were taking an indeterminate + // amount of time to complete, or if the driver forwarded the requests + // to a lower driver/another stack, the queue should have an + // EvtIoStop/EvtIoResume. + // + __analysis_assume(ioQueueConfig.EvtIoStop != 0); + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue);// pointer to default queue + __analysis_assume(ioQueueConfig.EvtIoStop == 0); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed %!STATUS!\n", status); + goto Error; + } + + // + // We will create a separate sequential queue and configure it + // to receive read requests. We also need to register a EvtIoStop + // handler so that we can acknowledge requests that are pending + // at the target driver. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential); + + ioQueueConfig.EvtIoRead = OsrFxEvtIoRead; + ioQueueConfig.EvtIoStop = OsrFxEvtIoStop; + + status = WdfIoQueueCreate( + device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue // queue handle + ); + + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + status = WdfDeviceConfigureRequestDispatching( + device, + queue, + WdfRequestTypeRead); + + if(!NT_SUCCESS (status)){ + NT_ASSERT(NT_SUCCESS(status)); + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status); + goto Error; + } + + + // + // We will create another sequential queue and configure it + // to receive write requests. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential); + + ioQueueConfig.EvtIoWrite = OsrFxEvtIoWrite; + ioQueueConfig.EvtIoStop = OsrFxEvtIoStop; + + status = WdfIoQueueCreate( + device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &queue // queue handle + ); + + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + status = WdfDeviceConfigureRequestDispatching( + device, + queue, + WdfRequestTypeWrite); + + if(!NT_SUCCESS (status)){ + NT_ASSERT(NT_SUCCESS(status)); + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status); + goto Error; + } + + // + // Register a manual I/O queue for handling Interrupt Message Read Requests. + // This queue will be used for storing Requests that need to wait for an + // interrupt to occur before they can be completed. + // + WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchManual); + + // + // This queue is used for requests that dont directly access the device. The + // requests in this queue are serviced only when the device is in a fully + // powered state and sends an interrupt. So we can use a non-power managed + // queue to park the requests since we dont care whether the device is idle + // or fully powered up. + // + ioQueueConfig.PowerManaged = WdfFalse; + + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &pDevContext->InterruptMsgQueue + ); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfIoQueueCreate failed 0x%x\n", status); + goto Error; + } + + // + // Register a device interface so that app can find our device and talk to it. + // + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL); // Reference String + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceCreateDeviceInterface failed %!STATUS!\n", status); + goto Error; + } + + // + // Create the lock that we use to serialize calls to ResetDevice(). As an + // alternative to using a WDFWAITLOCK to serialize the calls, a sequential + // WDFQUEUE can be created and reset IOCTLs would be forwarded to it. + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfWaitLockCreate(&attributes, &pDevContext->ResetDeviceWaitLock); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfWaitLockCreate failed %!STATUS!\n", status); + goto Error; + } + + // + // Get the string for the device interface and set the restricted + // property on it to allow applications bound with device metadata + // to access the interface. + // + if (g_pIoSetDeviceInterfacePropertyData != NULL) { + + status = WdfStringCreate(NULL, + WDF_NO_OBJECT_ATTRIBUTES, + &symbolicLinkString); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfStringCreate failed %!STATUS!\n", status); + goto Error; + } + + status = WdfDeviceRetrieveDeviceInterfaceString(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL, + symbolicLinkString); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceRetrieveDeviceInterfaceString failed %!STATUS!\n", status); + goto Error; + } + + WdfStringGetUnicodeString(symbolicLinkString, &symbolicLinkName); + + isRestricted = DEVPROP_TRUE; + + status = g_pIoSetDeviceInterfacePropertyData(&symbolicLinkName, + &DEVPKEY_DeviceInterface_Restricted, + 0, + 0, + DEVPROP_TYPE_BOOLEAN, + sizeof(isRestricted), + &isRestricted ); + + WdfObjectDelete(symbolicLinkString); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "IoSetDeviceInterfacePropertyData failed %!STATUS!\n", status); + goto Error; + } + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- OsrFxEvtDeviceAdd\n"); + + return status; + +Error: + + // + // Log fail to add device to the event log + // + EventWriteFailAddDevice(&activity, + pDevContext->DeviceName, + pDevContext->Location, + status); + + return status; +} + +NTSTATUS +OsrFxEvtDevicePrepareHardware( + WDFDEVICE Device, + WDFCMRESLIST ResourceList, + 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 + + ResourceList - handle to a resource-list object that identifies the + raw hardware resources that the PnP manager assigned + to the device + + ResourceListTranslated - handle to a resource-list object that + identifies the translated hardware resources + that the PnP manager assigned to the device + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_INFORMATION deviceInfo; + ULONG waitWakeEnable; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + waitWakeEnable = FALSE; + 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; + } + + // + // TODO: If you are fetching configuration descriptor from device for + // selecting a configuration or to parse other descriptors, call OsrFxValidateConfigurationDescriptor + // to do basic validation on the descriptors before you access them . + // + } + + // + // Retrieve USBD version information, port driver capabilites and device + // capabilites such as speed, power, etc. + // + WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo); + + status = WdfUsbTargetDeviceRetrieveInformation( + pDeviceContext->UsbDevice, + &deviceInfo); + if (NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "IsDeviceHighSpeed: %s\n", + (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? "TRUE" : "FALSE"); + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, + "IsDeviceSelfPowered: %s\n", + (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? "TRUE" : "FALSE"); + + waitWakeEnable = deviceInfo.Traits & + WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE; + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, + "IsDeviceRemoteWakeable: %s\n", + waitWakeEnable ? "TRUE" : "FALSE"); + // + // Save these for use later. + // + pDeviceContext->UsbDeviceTraits = deviceInfo.Traits; + } + else { + pDeviceContext->UsbDeviceTraits = 0; + } + + status = SelectInterfaces(Device); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "SelectInterfaces failed 0x%x\n", status); + return status; + } + + // + // Enable wait-wake and idle timeout if the device supports it + // + if (waitWakeEnable) { + status = OsrFxSetPowerPolicy(Device); + if (!NT_SUCCESS (status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "OsrFxSetPowerPolicy failed %!STATUS!\n", status); + return status; + } + } + + status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n"); + + return status; +} + + +NTSTATUS +OsrFxEvtDeviceD0Entry( + WDFDEVICE Device, + 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; + BOOLEAN isTargetStarted; + + pDeviceContext = GetDeviceContext(Device); + isTargetStarted = FALSE; + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, + "-->OsrFxEvtEvtDeviceD0Entry - coming from %s\n", + DbgDevicePowerString(PreviousState)); + + // + // Since continuous reader is configured for this interrupt-pipe, we must explicitly start + // the I/O target to get the framework to post read requests. + // + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe)); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_POWER, "Failed to start interrupt pipe %!STATUS!\n", status); + goto End; + } + + isTargetStarted = TRUE; + +End: + + if (!NT_SUCCESS(status)) { + // + // Failure in D0Entry will lead to device being removed. So let us stop the continuous + // reader in preparation for the ensuing remove. + // + if (isTargetStarted) { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); + } + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtEvtDeviceD0Entry\n"); + + return status; +} + + +NTSTATUS +OsrFxEvtDeviceD0Exit( + WDFDEVICE Device, + 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(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe), WdfIoTargetCancelSentIo); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--OsrFxEvtDeviceD0Exit\n"); + + return STATUS_SUCCESS; +} + +VOID +OsrFxEvtDeviceSelfManagedIoFlush( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This routine handles flush activity for the device's + self-managed I/O operations. + +Arguments: + + Device - Handle to a framework device object. + +Return Value: + + None + +--*/ +{ + // Service the interrupt message queue to drain any outstanding + // requests + OsrUsbIoctlGetInterruptMessage(Device, STATUS_DEVICE_REMOVED); +} + +_IRQL_requires_(PASSIVE_LEVEL) +USBD_STATUS +OsrFxValidateConfigurationDescriptor( + _In_reads_bytes_(BufferLength) PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + _In_ ULONG BufferLength, + _Inout_ PUCHAR *Offset + ) +/*++ + +Routine Description: + + Validates a USB Configuration Descriptor + +Parameters: + + ConfigDesc: Pointer to the entire USB Configuration descriptor returned by the device + + BufferLength: Known size of buffer pointed to by ConfigDesc (Not wTotalLength) + + Offset: if the USBD_STATUS returned is not USBD_STATUS_SUCCESS, offet will + be set to the address within the ConfigDesc buffer where the failure occured. + +Return Value: + + USBD_STATUS + Success implies the configuration descriptor is valid. + +--*/ +{ + + + USBD_STATUS status = USBD_STATUS_SUCCESS; + USHORT ValidationLevel = 3; + + PAGED_CODE(); + + // + // Call USBD_ValidateConfigurationDescriptor to validate the descriptors which are present in this supplied configuration descriptor. + // USBD_ValidateConfigurationDescriptor validates that all descriptors are completely contained within the configuration descriptor buffer. + // It also checks for interface numbers, number of endpoints in an interface etc. + // Please refer to msdn documentation for this function for more information. + // + + status = USBD_ValidateConfigurationDescriptor( ConfigDesc, BufferLength , ValidationLevel , Offset , POOL_TAG ); + if (!(NT_SUCCESS (status)) ){ + return status; + } + + // + // TODO: You should validate the correctness of other descriptors which are not taken care by USBD_ValidateConfigurationDescriptor + // Check that all such descriptors have size >= sizeof(the descriptor they point to) + // Check for any association between them if required + // + + return status; +} + + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +OsrFxSetPowerPolicy( + _In_ WDFDEVICE Device + ) +{ + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; + WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings; + NTSTATUS status = STATUS_SUCCESS; + + PAGED_CODE(); + + // + // Init the idle policy structure. + // + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleUsbSelectiveSuspend); + idleSettings.IdleTimeout = 10000; // 10-sec + + status = WdfDeviceAssignS0IdleSettings(Device, &idleSettings); + if ( !NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status); + return status; + } + + // + // Init wait-wake policy structure. + // + WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings); + + status = WdfDeviceAssignSxWakeSettings(Device, &wakeSettings); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfDeviceAssignSxWakeSettings failed %x\n", status); + return status; + } + + return status; +} + + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SelectInterfaces( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This helper routine selects the configuration, interface and + creates a context for every pipe (end point) in that interface. + +Arguments: + + Device - Handle to a framework device + +Return Value: + + NT status value + +--*/ +{ + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + NTSTATUS status = STATUS_SUCCESS; + PDEVICE_CONTEXT pDeviceContext; + WDFUSBPIPE pipe; + WDF_USB_PIPE_INFORMATION pipeInfo; + UCHAR index; + UCHAR numberConfiguredPipes; + + PAGED_CODE(); + + pDeviceContext = GetDeviceContext(Device); + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams); + + status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, + WDF_NO_OBJECT_ATTRIBUTES, + &configParams); + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n", + status); + + // + // 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 ((pDeviceContext->UsbDeviceTraits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) { + GUID activity = DeviceToActivityId(Device); + + 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" + ); + EventWriteSelectConfigFailure( + &activity, + pDeviceContext->DeviceName, + pDeviceContext->Location, + status + ); + } + + return status; + } + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + + numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes; + + // + // Get pipe handles + // + for(index=0; index < numberConfiguredPipes; index++) { + + WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo); + + pipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + index, //PipeIndex, + &pipeInfo + ); + // + // Tell the framework that it's okay to read less than + // MaximumPacketSize + // + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe); + + if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "Interrupt Pipe is 0x%p\n", pipe); + pDeviceContext->InterruptPipe = pipe; + } + + if(WdfUsbPipeTypeBulk == pipeInfo.PipeType && + WdfUsbTargetPipeIsInEndpoint(pipe)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "BulkInput Pipe is 0x%p\n", pipe); + pDeviceContext->BulkReadPipe = pipe; + } + + if(WdfUsbPipeTypeBulk == pipeInfo.PipeType && + WdfUsbTargetPipeIsOutEndpoint(pipe)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, + "BulkOutput Pipe is 0x%p\n", pipe); + pDeviceContext->BulkWritePipe = pipe; + } + + } + + // + // If we didn't find all the 3 pipes, fail the start. + // + if(!(pDeviceContext->BulkWritePipe + && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) { + status = STATUS_INVALID_DEVICE_STATE; + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, + "Device is not configured properly %!STATUS!\n", + status); + + return status; + } + + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +VOID +GetDeviceEventLoggingNames( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + Retrieve the friendly name and the location string into WDFMEMORY objects + and store them in the device context. + +Arguments: + +Return Value: + + None + +--*/ +{ + PDEVICE_CONTEXT pDevContext = GetDeviceContext(Device); + + WDF_OBJECT_ATTRIBUTES objectAttributes; + + WDFMEMORY deviceNameMemory = NULL; + WDFMEMORY locationMemory = NULL; + + NTSTATUS status; + + PAGED_CODE(); + + // + // We want both memory objects to be children of the device so they will + // be deleted automatically when the device is removed. + // + + WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); + objectAttributes.ParentObject = Device; + + // + // First get the length of the string. If the FriendlyName + // is not there then get the lenght of device description. + // + + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyFriendlyName, + NonPagedPool, + &objectAttributes, + &deviceNameMemory); + + if (!NT_SUCCESS(status)) + { + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyDeviceDescription, + NonPagedPool, + &objectAttributes, + &deviceNameMemory); + } + + if (NT_SUCCESS(status)) + { + pDevContext->DeviceNameMemory = deviceNameMemory; + pDevContext->DeviceName = WdfMemoryGetBuffer(deviceNameMemory, NULL); + } + else + { + pDevContext->DeviceNameMemory = NULL; + pDevContext->DeviceName = L"(error retrieving name)"; + } + + // + // Retrieve the device location string. + // + + status = WdfDeviceAllocAndQueryProperty(Device, + DevicePropertyLocationInformation, + NonPagedPool, + WDF_NO_OBJECT_ATTRIBUTES, + &locationMemory); + + if (NT_SUCCESS(status)) + { + pDevContext->LocationMemory = locationMemory; + pDevContext->Location = WdfMemoryGetBuffer(locationMemory, NULL); + } + else + { + pDevContext->LocationMemory = NULL; + pDevContext->Location = L"(error retrieving location)"; + } + + return; +} + +_IRQL_requires_(PASSIVE_LEVEL) +PCHAR +DbgDevicePowerString( + _In_ WDF_POWER_DEVICE_STATE Type + ) +{ + 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/umdf_filter_kmdf/kmdf_driver/bulkrwr.c b/usb/umdf_filter_kmdf/kmdf_driver/bulkrwr.c new file mode 100644 index 00000000..eabda192 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/bulkrwr.c @@ -0,0 +1,436 @@ +/*++ + +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: + + bulkrwr.c + +Abstract: + + This file has routines to perform reads and writes. + The read and writes are targeted bulk to endpoints. + +Environment: + + Kernel mode + +--*/ + +#include <osrusbfx2.h> + + +#if defined(EVENT_TRACING) +#include "bulkrwr.tmh" +#endif + +#pragma warning(disable:4267) + +VOID +OsrFxEvtIoRead( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t Length + ) +/*++ + +Routine Description: + + Called by the framework when it receives Read or Write requests. + +Arguments: + + Queue - Default queue handle + Request - Handle to the read/write request + Lenght - Length of the data buffer associated with the request. + The default property of the queue is to not dispatch + zero lenght read & write requests to the driver and + complete is with status success. So we will never get + a zero length request. + +Return Value: + + +--*/ +{ + WDFUSBPIPE pipe; + NTSTATUS status; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + GUID activity = RequestToActivityId(Request); + + UNREFERENCED_PARAMETER(Queue); + + // + // Log read start event, using IRP activity ID if available or request + // handle otherwise. + // + + EventWriteReadStart(&activity, WdfIoQueueGetDevice(Queue), (ULONG)Length); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "-->OsrFxEvtIoRead\n"); + + // + // First validate input parameters. + // + if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Transfer exceeds %d\n", + TEST_BOARD_TRANSFER_BUFFER_SIZE); + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkReadPipe; + + status = WdfRequestRetrieveOutputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "WdfRequestRetrieveOutputMemory failed %!STATUS!\n", status); + goto Exit; + } + + // + // The format call validates to make sure that you are reading or + // writing to the right pipe type, sets the appropriate transfer flags, + // creates an URB and initializes the request. + // + status = WdfUsbTargetPipeFormatRequestForRead(pipe, + Request, + reqMemory, + NULL // Offsets + ); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "WdfUsbTargetPipeFormatRequestForRead failed 0x%x\n", status); + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestReadCompletionRoutine, + pipe); + // + // Send the request asynchronously. + // + if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) { + // + // Framework couldn't send the request for some reason. + // + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "WdfRequestSend failed\n"); + status = WdfRequestGetStatus(Request); + goto Exit; + } + + +Exit: + if (!NT_SUCCESS(status)) { + // + // log event read failed + // + EventWriteReadFail(&activity, WdfIoQueueGetDevice(Queue), status); + WdfRequestCompleteWithInformation(Request, status, 0); + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, "<-- OsrFxEvtIoRead\n"); + + return; +} + +VOID +EvtRequestReadCompletionRoutine( + _In_ WDFREQUEST Request, + _In_ WDFIOTARGET Target, + _In_ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + _In_ WDFCONTEXT Context + ) +/*++ + +Routine Description: + + This is the completion routine for reads + If the irp completes with success, we check if we + need to recirculate this irp for another stage of + transfer. + +Arguments: + + Context - Driver supplied context + Device - Device handle + Request - Request handle + Params - request completion params + +Return Value: + None + +--*/ +{ + NTSTATUS status; + size_t bytesRead = 0; + GUID activity = RequestToActivityId(Request); + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesRead = usbCompletionParams->Parameters.PipeRead.Length; + + if (NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, + "Number of bytes read: %I64d\n", (INT64)bytesRead); + } else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, + "Read failed - request status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus); + + } + + // + // Log read stop event, using IRP activity ID if available or request + // handle otherwise. + // + + EventWriteReadStop(&activity, + WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), + bytesRead, + status, + usbCompletionParams->UsbdStatus); + + WdfRequestCompleteWithInformation(Request, status, bytesRead); + + return; +} + +VOID +OsrFxEvtIoWrite( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t Length + ) +/*++ + +Routine Description: + + Called by the framework when it receives Read or Write requests. + +Arguments: + + Queue - Default queue handle + Request - Handle to the read/write request + Lenght - Length of the data buffer associated with the request. + The default property of the queue is to not dispatch + zero lenght read & write requests to the driver and + complete is with status success. So we will never get + a zero length request. + +Return Value: + + +--*/ +{ + NTSTATUS status; + WDFUSBPIPE pipe; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + GUID activity = RequestToActivityId(Request); + + UNREFERENCED_PARAMETER(Queue); + + + // + // Log write start event, using IRP activity ID if available or request + // handle otherwise. + // + EventWriteWriteStart(&activity, WdfIoQueueGetDevice(Queue), (ULONG)Length); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "-->OsrFxEvtIoWrite\n"); + + // + // First validate input parameters. + // + if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Transfer exceeds %d\n", + TEST_BOARD_TRANSFER_BUFFER_SIZE); + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkWritePipe; + + status = WdfRequestRetrieveInputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestRetrieveInputBuffer failed\n"); + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForWrite(pipe, + Request, + reqMemory, + NULL); // Offset + + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, + "WdfUsbTargetPipeFormatRequestForWrite failed 0x%x\n", status); + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestWriteCompletionRoutine, + pipe); + + // + // Send the request asynchronously. + // + if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) { + // + // Framework couldn't send the request for some reason. + // + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestSend failed\n"); + status = WdfRequestGetStatus(Request); + goto Exit; + } + +Exit: + + if (!NT_SUCCESS(status)) { + // + // log event write failed + // + EventWriteWriteFail(&activity, WdfIoQueueGetDevice(Queue), status); + + WdfRequestCompleteWithInformation(Request, status, 0); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- OsrFxEvtIoWrite\n"); + + return; +} + +VOID +EvtRequestWriteCompletionRoutine( + _In_ WDFREQUEST Request, + _In_ WDFIOTARGET Target, + _In_ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + _In_ WDFCONTEXT Context + ) +/*++ + +Routine Description: + + This is the completion routine for writes + If the irp completes with success, we check if we + need to recirculate this irp for another stage of + transfer. + +Arguments: + + Context - Driver supplied context + Device - Device handle + Request - Request handle + Params - request completion params + +Return Value: + None + +--*/ +{ + NTSTATUS status; + size_t bytesWritten = 0; + GUID activity = RequestToActivityId(Request); + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + // + // For usb devices, we should look at the Usb.Completion param. + // + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length; + + if (NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, + "Number of bytes written: %I64d\n", (INT64)bytesWritten); + } else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, + "Write failed: request Status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus); + } + + // + // Log write stop event, using IRP activtiy ID if available or request + // handle otherwise + // + EventWriteWriteStop(&activity, + WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)), + bytesWritten, + status, + usbCompletionParams->UsbdStatus); + + + WdfRequestCompleteWithInformation(Request, status, bytesWritten); + + return; +} + + +VOID +OsrFxEvtIoStop( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ ULONG ActionFlags + ) +/*++ + +Routine Description: + + This callback is invoked on every inflight request when the device + is suspended or removed. Since our inflight read and write requests + are actually pending in the target device, we will just acknowledge + its presence. Until we acknowledge, complete, or requeue the requests + framework will wait before allowing the device suspend or remove to + proceeed. When the underlying USB stack gets the request to suspend or + remove, it will fail all the pending requests. + +Arguments: + + Queue - handle to queue object that is associated with the I/O request + + Request - handle to a request object + + ActionFlags - bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS flags + +Return Value: + None + +--*/ +{ + UNREFERENCED_PARAMETER(Queue); + UNREFERENCED_PARAMETER(ActionFlags); + + if (ActionFlags & WdfRequestStopActionSuspend ) { + WdfRequestStopAcknowledge(Request, FALSE); // Don't requeue + } else if(ActionFlags & WdfRequestStopActionPurge) { + WdfRequestCancelSentRequest(Request); + } + return; +} + + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/driver.c b/usb/umdf_filter_kmdf/kmdf_driver/driver.c new file mode 100644 index 00000000..d3b44573 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/driver.c @@ -0,0 +1,299 @@ +/*++ + +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 started, + (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> + +#if defined(EVENT_TRACING) +// +// 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 trace.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" +#else +ULONG DebugLevel = TRACE_LEVEL_INFORMATION; +ULONG DebugFlag = 0xff; +#endif + +PFN_IO_GET_ACTIVITY_ID_IRP g_pIoGetActivityIdIrp; +PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA g_pIoSetDeviceInterfacePropertyData; + +#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 or another NTSTATUS error code otherwise. + +--*/ +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES attributes; + UNICODE_STRING funcName; + + // + // 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__); + + // + // IRP activity ID functions are available on some versions, save them into + // globals (or NULL if not available) + // + RtlInitUnicodeString(&funcName, L"IoGetActivityIdIrp"); + g_pIoGetActivityIdIrp = (PFN_IO_GET_ACTIVITY_ID_IRP) (ULONG_PTR) + MmGetSystemRoutineAddress(&funcName); + + // + // The Device interface property set is available on some version, save it + // into globals (or NULL if not available) + // + RtlInitUnicodeString(&funcName, L"IoSetDeviceInterfacePropertyData"); + g_pIoSetDeviceInterfacePropertyData = (PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA) (ULONG_PTR) + MmGetSystemRoutineAddress(&funcName); + + // + // Register with ETW (unified tracing) + // + EventRegisterOSRUSBFX2(); + + // + // 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 Object 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); + EventUnregisterOSRUSBFX2(); + } + + return status; +} + +VOID +OsrFxEvtDriverContextCleanup( + WDFOBJECT Driver + ) +/*++ +Routine Description: + + Free resources allocated in DriverEntry that are not automatically + cleaned up by the 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 )); + + UNREFERENCED_PARAMETER(Driver); // For the case when WPP is not being used. + + EventUnregisterOSRUSBFX2(); +} + +#if !defined(EVENT_TRACING) + +VOID +TraceEvents ( + _In_ ULONG DebugPrintLevel, + _In_ ULONG DebugPrintFlag, + _Printf_format_string_ + _In_ PCSTR DebugMessage, + ... + ) + +/*++ + +Routine Description: + + Debug print for the sample driver. + +Arguments: + + DebugPrintLevel - print level between 0 and 3, with 3 the most verbose + DebugPrintFlag - message mask + DebugMessage - format string of the message to print + ... - values used by the format string + +Return Value: + + None. + + --*/ + { +#if DBG +#define TEMP_BUFFER_SIZE 1024 + va_list list; + CHAR debugMessageBuffer[TEMP_BUFFER_SIZE]; + NTSTATUS status; + + va_start(list, DebugMessage); + + if (DebugMessage) { + + // + // Using new safe string functions instead of _vsnprintf. + // This function takes care of NULL terminating if the message + // is longer than the buffer. + // + status = RtlStringCbVPrintfA( debugMessageBuffer, + sizeof(debugMessageBuffer), + DebugMessage, + list ); + if(!NT_SUCCESS(status)) { + + DbgPrint (_DRIVER_NAME_": RtlStringCbVPrintfA failed 0x%x\n", status); + return; + } + if (DebugPrintLevel <= TRACE_LEVEL_ERROR || + (DebugPrintLevel <= DebugLevel && + ((DebugPrintFlag & DebugFlag) == DebugPrintFlag))) { + DbgPrint("%s %s", _DRIVER_NAME_, debugMessageBuffer); + } + } + va_end(list); + + return; +#else + UNREFERENCED_PARAMETER(DebugPrintLevel); + UNREFERENCED_PARAMETER(DebugPrintFlag); + UNREFERENCED_PARAMETER(DebugMessage); +#endif +} + +#endif + + + + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/interrupt.c b/usb/umdf_filter_kmdf/kmdf_driver/interrupt.c new file mode 100644 index 00000000..00ea3550 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/interrupt.c @@ -0,0 +1,184 @@ +/*++ + +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> + +#if defined(EVENT_TRACING) +#include "interrupt.tmh" +#endif + + +_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; + + 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(DeviceContext->InterruptPipe, + &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; + + // + // Handle any pending Interrupt Message IOCTLs. Note that the OSR USB device + // will generate an interrupt message when the the device resumes from a low + // power state. So if the Interrupt Message IOCTL was sent after the device + // has gone to a low power state, the pending Interrupt Message IOCTL will + // get completed in the function call below, before the user twiddles the + // dip switches on the OSR USB device. If this is not the desired behavior + // for your driver, then you could handle this condition by maintaining a + // state variable on D0Entry to track interrupt messages caused by power up. + // + OsrUsbIoctlGetInterruptMessage(device, STATUS_SUCCESS); + +} + +BOOLEAN +OsrFxEvtUsbInterruptReadersFailed( + _In_ WDFUSBPIPE Pipe, + _In_ NTSTATUS Status, + _In_ USBD_STATUS UsbdStatus + ) +{ + WDFDEVICE device = WdfIoTargetGetDevice(WdfUsbTargetPipeGetIoTarget(Pipe)); + PDEVICE_CONTEXT pDeviceContext = GetDeviceContext(device); + + UNREFERENCED_PARAMETER(UsbdStatus); + + // + // Clear the current switch state. + // + pDeviceContext->CurrentSwitchState = 0; + + // + // Service the pending interrupt switch change request + // + OsrUsbIoctlGetInterruptMessage(device, Status); + + return TRUE; +} + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/ioctl.c b/usb/umdf_filter_kmdf/kmdf_driver/ioctl.c new file mode 100644 index 00000000..0f29dc8c --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/ioctl.c @@ -0,0 +1,1057 @@ +/*++ + +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: + + Ioctl.c + +Abstract: + + USB device driver for OSR USB-FX2 Learning Kit + +Environment: + + Kernel mode only + +--*/ + +#include <osrusbfx2.h> + +#if defined(EVENT_TRACING) +#include "ioctl.tmh" +#endif + +#pragma alloc_text(PAGE, OsrFxEvtIoDeviceControl) +#pragma alloc_text(PAGE, ResetPipe) +#pragma alloc_text(PAGE, ResetDevice) +#pragma alloc_text(PAGE, ReenumerateDevice) +#pragma alloc_text(PAGE, GetBarGraphState) +#pragma alloc_text(PAGE, SetBarGraphState) +#pragma alloc_text(PAGE, GetSevenSegmentState) +#pragma alloc_text(PAGE, SetSevenSegmentState) +#pragma alloc_text(PAGE, GetSwitchState) + +VOID +OsrFxEvtIoDeviceControl( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode + ) +/*++ + +Routine Description: + + This event is called when the framework receives IRP_MJ_DEVICE_CONTROL + requests from the system. + +Arguments: + + Queue - Handle to the framework queue object that is associated + with the I/O request. + Request - Handle to a framework request object. + + OutputBufferLength - length of the request's output buffer, + if an output buffer is available. + InputBufferLength - length of the request's input buffer, + if an input buffer is available. + + IoControlCode - the driver-defined or system-defined I/O control code + (IOCTL) that is associated with the request. +Return Value: + + VOID + +--*/ +{ + WDFDEVICE device; + PDEVICE_CONTEXT pDevContext; + size_t bytesReturned = 0; + PBAR_GRAPH_STATE barGraphState = NULL; + PSWITCH_STATE switchState = NULL; + PUCHAR sevenSegment = NULL; + BOOLEAN requestPending = FALSE; + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + + UNREFERENCED_PARAMETER(InputBufferLength); + UNREFERENCED_PARAMETER(OutputBufferLength); + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "--> OsrFxEvtIoDeviceControl\n"); + // + // initialize variables + // + device = WdfIoQueueGetDevice(Queue); + pDevContext = GetDeviceContext(device); + + switch(IoControlCode) { + + case IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR: { + + PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL; + USHORT requiredSize = 0; + + // + // First get the size of the config descriptor + // + status = WdfUsbTargetDeviceRetrieveConfigDescriptor( + pDevContext->UsbDevice, + NULL, + &requiredSize); + + if (status != STATUS_BUFFER_TOO_SMALL) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfUsbTargetDeviceRetrieveConfigDescriptor failed 0x%x\n", status); + break; + } + + // + // Get the buffer - make sure the buffer is big enough + // + status = WdfRequestRetrieveOutputBuffer(Request, + (size_t)requiredSize, // MinimumRequired + &configurationDescriptor, + NULL); + if(!NT_SUCCESS(status)){ + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfRequestRetrieveOutputBuffer failed 0x%x\n", status); + break; + } + + status = WdfUsbTargetDeviceRetrieveConfigDescriptor( + pDevContext->UsbDevice, + configurationDescriptor, + &requiredSize); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "WdfUsbTargetDeviceRetrieveConfigDescriptor failed 0x%x\n", status); + break; + } + + bytesReturned = requiredSize; + + } + break; + + case IOCTL_OSRUSBFX2_RESET_DEVICE: + + status = ResetDevice(device); + break; + + case IOCTL_OSRUSBFX2_REENUMERATE_DEVICE: + + // + // Otherwise, call our function to reenumerate the + // device + // + status = ReenumerateDevice(pDevContext); + + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY: + + // + // Make sure the caller's output buffer is large enough + // to hold the state of the bar graph + // + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(BAR_GRAPH_STATE), + &barGraphState, + NULL); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"); + break; + } + // + // Call our function to get the bar graph state + // + status = GetBarGraphState(pDevContext, barGraphState); + + // + // If we succeeded return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(BAR_GRAPH_STATE); + + } else { + + bytesReturned = 0; + + } + break; + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + + status = WdfRequestRetrieveInputBuffer(Request, + sizeof(BAR_GRAPH_STATE), + &barGraphState, + NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's input buffer is too small for this IOCTL, expecting an BAR_GRAPH_STATE\n"); + break; + } + + // + // Call our routine to set the bar graph state + // + status = SetBarGraphState(pDevContext, barGraphState); + + // + // There's no data returned for this call + // + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY: + + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(UCHAR), + &sevenSegment, + NULL); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting an UCHAR\n"); + break; + } + + // + // Call our function to get the 7 segment state + // + status = GetSevenSegmentState(pDevContext, sevenSegment); + + // + // If we succeeded return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(UCHAR); + + } else { + + bytesReturned = 0; + + } + break; + + case IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY: + + status = WdfRequestRetrieveInputBuffer(Request, + sizeof(UCHAR), + &sevenSegment, + NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's input buffer is too small for this IOCTL, expecting an UCHAR\n"); + bytesReturned = sizeof(UCHAR); + break; + } + + // + // Call our routine to set the 7 segment state + // + status = SetSevenSegmentState(pDevContext, sevenSegment); + + // + // There's no data returned for this call + // + bytesReturned = 0; + break; + + case IOCTL_OSRUSBFX2_READ_SWITCHES: + + status = WdfRequestRetrieveOutputBuffer(Request, + sizeof(SWITCH_STATE), + &switchState, + NULL);// BufferLength + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n"); + bytesReturned = sizeof(SWITCH_STATE); + break; + + } + + // + // Call our routine to get the state of the switches + // + status = GetSwitchState(pDevContext, switchState); + + // + // If successful, return the user their data + // + if (NT_SUCCESS(status)) { + + bytesReturned = sizeof(SWITCH_STATE); + + } else { + // + // Don't return any data + // + bytesReturned = 0; + } + break; + + case IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE: + + // + // Forward the request to an interrupt message queue and dont complete + // the request until an interrupt from the USB device occurs. + // + status = WdfRequestForwardToIoQueue(Request, pDevContext->InterruptMsgQueue); + if (NT_SUCCESS(status)) { + requestPending = TRUE; + } + + break; + + default : + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + if (requestPending == FALSE) { + WdfRequestCompleteWithInformation(Request, status, bytesReturned); + } + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "<-- OsrFxEvtIoDeviceControl\n"); + + return; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ResetPipe( + _In_ WDFUSBPIPE Pipe + ) +/*++ + +Routine Description: + + This routine resets the pipe. + +Arguments: + + Pipe - framework pipe handle + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + + PAGED_CODE(); + + // + // This routine synchronously submits a URB_FUNCTION_RESET_PIPE + // request down the stack. + // + status = WdfUsbTargetPipeResetSynchronously(Pipe, + WDF_NO_HANDLE, // WDFREQUEST + NULL // PWDF_REQUEST_SEND_OPTIONS + ); + + if (NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "ResetPipe - success\n"); + status = STATUS_SUCCESS; + } + else { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetPipe - failed\n"); + } + + return status; +} + +VOID +StopAllPipes( + IN PDEVICE_CONTEXT DeviceContext + ) +{ + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->InterruptPipe), + WdfIoTargetCancelSentIo); + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkReadPipe), + WdfIoTargetCancelSentIo); + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkWritePipe), + WdfIoTargetCancelSentIo); +} + +NTSTATUS +StartAllPipes( + IN PDEVICE_CONTEXT DeviceContext + ) +{ + NTSTATUS status; + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->InterruptPipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkReadPipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(DeviceContext->BulkWritePipe)); + if (!NT_SUCCESS(status)) { + return status; + } + + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ResetDevice( + _In_ WDFDEVICE Device + ) +/*++ + +Routine Description: + + This routine calls WdfUsbTargetDeviceResetPortSynchronously to reset the device if it's still + connected. + +Arguments: + + Device - Handle to a framework device + +Return Value: + + NT status value + +--*/ +{ + PDEVICE_CONTEXT pDeviceContext; + NTSTATUS status; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "--> ResetDevice\n"); + + pDeviceContext = GetDeviceContext(Device); + + // + // A NULL timeout indicates an infinite wake + // + status = WdfWaitLockAcquire(pDeviceContext->ResetDeviceWaitLock, NULL); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetDevice - could not acquire lock\n"); + return status; + } + + StopAllPipes(pDeviceContext); + + status = WdfUsbTargetDeviceResetPortSynchronously(pDeviceContext->UsbDevice); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "ResetDevice failed - 0x%x\n", status); + } + + status = StartAllPipes(pDeviceContext); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "Failed to start all pipes - 0x%x\n", status); + } + + WdfWaitLockRelease(pDeviceContext->ResetDeviceWaitLock); + + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL, "<-- ResetDevice\n"); + return status; +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +ReenumerateDevice( + _In_ PDEVICE_CONTEXT DevContext + ) +/*++ + +Routine Description + + This routine re-enumerates the USB device. + +Arguments: + + pDevContext - One of our device extensions + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + GUID activity; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"--> ReenumerateDevice\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_REENUMERATE, // Request + 0, // Value + 0); // Index + + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + WDF_NO_HANDLE, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + NULL, // MemoryDescriptor + NULL); // BytesTransferred + + if(!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "ReenumerateDevice: Failed to Reenumerate - 0x%x \n", status); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"<-- ReenumerateDevice\n"); + + // + // Send event to eventlog + // + + activity = DeviceToActivityId(WdfObjectContextGetObject(DevContext)); + EventWriteDeviceReenumerated(&activity, + DevContext->DeviceName, + DevContext->Location, + status); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetBarGraphState( + _In_ PDEVICE_CONTEXT DevContext, + _Out_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + +Routine Description + + This routine gets the state of the bar graph on the board + +Arguments: + + DevContext - One of our device extensions + + BarGraphState - Struct that receives the bar graph's state + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetBarGraphState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + // + // Set the buffer to 0, the board will OR in everything that is set + // + BarGraphState->BarsAsUChar = 0; + + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + BarGraphState, + sizeof(BAR_GRAPH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + WDF_NO_HANDLE, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetBarGraphState: Failed to GetBarGraphState - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetBarGraphState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SetBarGraphState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + +Routine Description + + This routine sets the state of the bar graph on the board + +Arguments: + + DevContext - One of our device extensions + + BarGraphState - Struct that describes the bar graph's desired state + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetBarGraphState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + BarGraphState, + sizeof(BAR_GRAPH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "SetBarGraphState: Failed - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "SetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetBarGraphState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetSevenSegmentState( + _In_ PDEVICE_CONTEXT DevContext, + _Out_ PUCHAR SevenSegment + ) +/*++ + +Routine Description + + This routine gets the state of the 7 segment display on the board + by sending a synchronous control command. + + NOTE: It's not a good practice to send a synchronous request in the + context of the user thread because if the transfer takes long + time to complete, you end up holding the user thread. + + I'm choosing to do synchronous transfer because a) I know this one + completes immediately b) and for demonstration. + +Arguments: + + DevContext - One of our device extensions + + SevenSegment - receives the state of the 7 segment display + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Enter\n"); + + PAGED_CODE(); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_7SEGMENT_DISPLAY, // Request + 0, // Value + 0); // Index + + // + // Set the buffer to 0, the board will OR in everything that is set + // + *SevenSegment = 0; + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SevenSegment, + sizeof(UCHAR)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetSevenSegmentState: Failed to get 7 Segment state - 0x%x \n", status); + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Exit\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +SetSevenSegmentState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PUCHAR SevenSegment + ) +/*++ + +Routine Description + + This routine sets the state of the 7 segment display on the board + +Arguments: + + DevContext - One of our device extensions + + SevenSegment - desired state of the 7 segment display + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetSevenSegmentState\n"); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_7SEGMENT_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SevenSegment, + sizeof(UCHAR)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "SetSevenSegmentState: Failed to set 7 Segment state - 0x%x \n", status); + + } else { + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "SetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); + + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetSevenSegmentState\n"); + + return status; + +} + +_IRQL_requires_(PASSIVE_LEVEL) +NTSTATUS +GetSwitchState( + _In_ PDEVICE_CONTEXT DevContext, + _In_ PSWITCH_STATE SwitchState + ) +/*++ + +Routine Description + + This routine gets the state of the switches on the board + +Arguments: + + DevContext - One of our device extensions + +Return Value: + + NT status value + +--*/ +{ + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_REQUEST_SEND_OPTIONS sendOptions; + WDF_MEMORY_DESCRIPTOR memDesc; + ULONG bytesTransferred; + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetSwitchState\n"); + + PAGED_CODE(); + + WDF_REQUEST_SEND_OPTIONS_INIT( + &sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT + ); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( + &sendOptions, + DEFAULT_CONTROL_TRANSFER_TIMEOUT + ); + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_SWITCHES, // Request + 0, // Value + 0); // Index + + SwitchState->SwitchesAsUChar = 0; + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, + SwitchState, + sizeof(SWITCH_STATE)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + DevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, + &controlSetupPacket, + &memDesc, + &bytesTransferred); + + if(!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "GetSwitchState: Failed to Get switches - 0x%x \n", status); + + } else { + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, + "GetSwitchState: Switch mask is 0x%x\n", SwitchState->SwitchesAsUChar); + } + + TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetSwitchState\n"); + + return status; + +} + + +VOID +OsrUsbIoctlGetInterruptMessage( + _In_ WDFDEVICE Device, + _In_ NTSTATUS ReaderStatus + ) +/*++ + +Routine Description + + This method handles the completion of the pended request for the IOCTL + IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE. + +Arguments: + + Device - Handle to a framework device. + +Return Value: + + None. + +--*/ +{ + NTSTATUS status; + WDFREQUEST request; + PDEVICE_CONTEXT pDevContext; + size_t bytesReturned = 0; + PSWITCH_STATE switchState = NULL; + + pDevContext = GetDeviceContext(Device); + + do { + + // + // Check if there are any pending requests in the Interrupt Message Queue. + // If a request is found then complete the pending request. + // + status = WdfIoQueueRetrieveNextRequest(pDevContext->InterruptMsgQueue, &request); + + if (NT_SUCCESS(status)) { + status = WdfRequestRetrieveOutputBuffer(request, + sizeof(SWITCH_STATE), + &switchState, + NULL);// BufferLength + + if (!NT_SUCCESS(status)) { + + TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, + "User's output buffer is too small for this IOCTL, expecting a SWITCH_STATE\n"); + bytesReturned = sizeof(SWITCH_STATE); + + } else { + + // + // Copy the state information saved by the continuous reader. + // + if (NT_SUCCESS(ReaderStatus)) { + switchState->SwitchesAsUChar = pDevContext->CurrentSwitchState; + bytesReturned = sizeof(SWITCH_STATE); + } else { + bytesReturned = 0; + } + } + + // + // Complete the request. If we failed to get the output buffer then + // complete with that status. Otherwise complete with the status from the reader. + // + WdfRequestCompleteWithInformation(request, + NT_SUCCESS(status) ? ReaderStatus : status, + bytesReturned); + status = STATUS_SUCCESS; + + } else if (status != STATUS_NO_MORE_ENTRIES) { + KdPrint(("WdfIoQueueRetrieveNextRequest status %08x\n", status)); + } + + request = NULL; + + } while (status == STATUS_SUCCESS); + + return; + +} + + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.h b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.h new file mode 100644 index 00000000..909e347d --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.h @@ -0,0 +1,335 @@ +/*++ + +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" + +// +// Include auto-generated ETW event functions (created by MC.EXE from +// osrusbfx2.man) +// +#include "fx2Events.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; + + WDFUSBPIPE BulkReadPipe; + + WDFUSBPIPE BulkWritePipe; + + WDFUSBPIPE InterruptPipe; + + WDFWAITLOCK ResetDeviceWaitLock; + + UCHAR CurrentSwitchState; + + WDFQUEUE InterruptMsgQueue; + + ULONG UsbDeviceTraits; + + // + // The following fields are used during event logging to + // report the events relative to this specific instance + // of the device. + // + + WDFMEMORY DeviceNameMemory; + PCWSTR DeviceName; + + WDFMEMORY LocationMemory; + PCWSTR Location; + +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + +extern ULONG DebugLevel; + +typedef +NTSTATUS +(*PFN_IO_GET_ACTIVITY_ID_IRP) ( + _In_ PIRP Irp, + _Out_ LPGUID Guid + ); + +typedef +NTSTATUS +(*PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA) ( + _In_ PUNICODE_STRING SymbolicLinkName, + _In_ CONST DEVPROPKEY *PropertyKey, + _In_ LCID Lcid, + _In_ ULONG Flags, + _In_ DEVPROPTYPE Type, + _In_ ULONG Size, + _In_opt_ PVOID Data + ); + +// +// Global function pointer set in DriverEntry +// Check for NULL before using +// +extern PFN_IO_GET_ACTIVITY_ID_IRP g_pIoGetActivityIdIrp; + +extern PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA g_pIoSetDeviceInterfacePropertyData; + +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 +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 + ); + +VOID +OsrUsbIoctlGetInterruptMessage( + _In_ WDFDEVICE Device, + _In_ NTSTATUS ReaderStatus + ); + +_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; + +EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH OsrFxEvtDeviceSelfManagedIoFlush; + +_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) +VOID +GetDeviceEventLoggingNames( + _In_ WDFDEVICE Device + ); + +_IRQL_requires_(PASSIVE_LEVEL) +PCHAR +DbgDevicePowerString( + _In_ WDF_POWER_DEVICE_STATE Type + ); + + +_IRQL_requires_(PASSIVE_LEVEL) +USBD_STATUS +OsrFxValidateConfigurationDescriptor( + _In_reads_bytes_(BufferLength) PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + _In_ ULONG BufferLength, + _Inout_ PUCHAR *Offset + ); + +FORCEINLINE +GUID +RequestToActivityId( + _In_ WDFREQUEST Request + ) +{ + GUID activity = {0}; + NTSTATUS status = STATUS_SUCCESS; + + if (g_pIoGetActivityIdIrp != NULL) { + + // + // Use activity ID generated by application (or IO manager) + // + status = g_pIoGetActivityIdIrp(WdfRequestWdmGetIrp(Request), &activity); + } + + if (g_pIoGetActivityIdIrp == NULL || !NT_SUCCESS(status)) { + + // + // Fall back to using the WDFREQUEST handle as the activity ID + // + RtlCopyMemory(&activity, &Request, sizeof(WDFREQUEST)); + } + + + return activity; +} + +FORCEINLINE +GUID +DeviceToActivityId( + _In_ WDFDEVICE Device + ) +{ + GUID activity = {0}; + RtlCopyMemory(&activity, &Device, sizeof(WDFDEVICE)); + return activity; +} + + +#endif + + diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.man b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.man new file mode 100644 index 00000000..176dfc89 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.man @@ -0,0 +1,309 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes'?> +<instrumentationManifest + xmlns="http://schemas.microsoft.com/win/2004/08/events" + xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" + > + <instrumentation> + <events> + <provider + guid="{69cd60e3-430f-4da4-b1b3-e3bdaf945875}" + messageFileName="%Systemroot%\System32\drivers\osrusbfx2.SYS" + name="OSRUSBFX2" + resourceFileName="%SystemRoot%\System32\drivers\osrusbfx2.SYS" + symbol="OSRUSBFX2_PROVIDER" + > + <channels> + <channel + chid="Analytic" + enabled="false" + name="OsrUsbfx2/Analytic" + symbol="OSRUSBFX2_ANALYTIC" + type="Analytic" + /> + <channel + chid="operational" + enabled="true" + isolation="System" + message="$(string.OSRUSBFX2_OPERATIONAL.Name)" + name="OsrUsbFx2/Operational" + symbol="OSRUSBFX2_OPERATIONAL" + type="Operational" + /> + </channels> + <keywords> + <keyword + mask="0x0000000000000010" + message="$(string.OSRUSBFX2_DEVICE_INFO_KEYWORD.message)" + name="deviceinfo" + symbol="OSRUSBFX2_DEVICE_INFO_KEYWORD" + /> + <keyword + mask="0x0000000000000040" + message="$(string.OSRUSBFX2_READ_WRITE_KEYWORD.message)" + name="readwrite" + symbol="OSRUSBFX2_READ_WRITE_KEYWORD" + /> + </keywords> + <opcodes> + <!-- Defining our own custom opcode instead of using standard opcodes defined by winmeta.xml --> + <opcode + name="add" + symbol="OSRUSBFX2_DEVICE_ADD" + value="10" + /> + <opcode + name="fail" + symbol="OSRUSBFX2_FAIL" + value="11" + /> + </opcodes> + <tasks> + <!-- Support for XP and W2K3 : MC.exe will create a MOF file --> + <!-- Requires an associated eventGUID attribute for each task that is defined --> + <!-- For the MOF file : --> + <!-- Semantically, the event GUID represents a set of logical events that are logged by the provider. --> + <task + eventGUID="{872c3c43-6899-4f1d-89b8-51a82f6db657}" + name="deviceInit" + symbol="OSRUSBFX2_DEVICE_INIT" + value="1" + /> + <task + eventGUID="{872c3c45-6899-4f1d-89b8-51a82f6db657}" + name="read" + symbol="OSRUSBFX2_READ" + value="2" + /> + <task + eventGUID="{872c3c46-6899-4f1d-89b8-51a82f6db657}" + name="write" + symbol="OSRUSBFX2_WRITE" + value="3" + /> + </tasks> + <templates> + <template tid="tid_DeviceStatus"> + <data + inType="win:UnicodeString" + name="FriendlyName" + outType="xs:string" + /> + <data + inType="win:UnicodeString" + name="Location" + outType="xs:string" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + </template> + <template tid="tid_ReadWrite"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="Length" + outType="xs:unsignedInt" + /> + </template> + <template tid="tid_ReadWriteFail"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + </template> + <template tid="tid_ReadWriteCompletion"> + <data + inType="win:Pointer" + name="Device" + outType="win:HexInt64" + /> + <data + inType="win:UInt32" + name="Length" + outType="xs:unsignedInt" + /> + <data + inType="win:UInt32" + name="NTStatus" + outType="xs:HexInt32" + /> + <data + inType="win:UInt32" + name="UsbdStatus" + outType="xs:unsignedInt" + /> + </template> + </templates> + <events> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadStart.EventMessage)" + level="win:Informational" + opcode="win:Start" + symbol="ReadStart" + task="read" + template="tid_ReadWrite" + value="1" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadStop.EventMessage)" + level="win:Informational" + opcode="win:Stop" + symbol="ReadStop" + task="read" + template="tid_ReadWriteCompletion" + value="2" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.ReadFail.EventMessage)" + level="win:Error" + opcode="fail" + symbol="ReadFail" + task="read" + template="tid_ReadWriteFail" + value="3" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteStart.EventMessage)" + level="win:Informational" + opcode="win:Start" + symbol="WriteStart" + task="write" + template="tid_ReadWrite" + value="4" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteStop.EventMessage)" + level="win:Informational" + opcode="win:Stop" + symbol="WriteStop" + task="write" + template="tid_ReadWriteCompletion" + value="5" + /> + <event + channel="Analytic" + keywords="readwrite" + message="$(string.WriteFail.EventMessage)" + level="win:Error" + opcode="fail" + symbol="WriteFail" + task="write" + template="tid_ReadWriteFail" + value="6" + /> + <event + channel="operational" + keywords="deviceinfo" + level="win:Error" + message="$(string.DeviceFailAdd.EventMessage)" + opcode="add" + symbol="FailAddDevice" + task="deviceInit" + template="tid_DeviceStatus" + value="100" + /> + <event + channel="operational" + keywords="deviceinfo" + message="$(string.DeviceReenumerated.EventMessage)" + opcode="win:Start" + symbol="DeviceReenumerated" + task="deviceInit" + template="tid_DeviceStatus" + value="101" + /> + <event + channel="operational" + keywords="deviceinfo" + level="win:Error" + message="$(string.SelectConfigFailure.Message)" + opcode="fail" + symbol="SelectConfigFailure" + task="deviceInit" + template="tid_DeviceStatus" + value="102" + /> + </events> + </provider> + </events> + </instrumentation> + <localization xmlns="http://schemas.microsoft.com/win/2004/08/events"> + <resources culture="en-US"> + <stringTable> + <string + id="OSRUSBFX2_DEVICE_INFO_KEYWORD.message" + value="Device events: fail to load, reenumerate" + /> + <string + id="OSRUSBFX2_READ_WRITE_KEYWORD.message" + value="Read, Write events" + /> + <string + id="OSRUSBFX2_OPERATIONAL.Name" + value="Operational channel eventlog" + /> + <string + id="ReadStart.EventMessage" + value="Read. Device = %1, Length = %2" + /> + <string + id="ReadStop.EventMessage" + value="Read complete. Device = %1, Length = %2, Status = %3, UsbStatus = %4" + /> + <string + id="ReadFail.EventMessage" + value="Read error. Device = %1, Status = %2" + /> + <string + id="WriteStart.EventMessage" + value="Write. Device = %1, Length = %2" + /> + <string + id="WriteStop.EventMessage" + value="Write complete. Device = %1, Length = %2, Status = %3, UsbStatus = %4" + /> + <string + id="WriteFail.EventMessage" + value="Write error. Device = %1, Status = %2" + /> + <string + id="DeviceReenumerated.EventMessage" + value="Device %1 (location %2) was reenumerated" + /> + <string + id="DeviceFailAdd.EventMessage" + value="Fail to add device %1 (location %2), status %3" + /> + <string + id="SelectConfigFailure.Message" + value="This error occurs when an OSR USB Fx2 board is attached to a USB 1.1 port on a machine running Windows Vista. This error occurs because the OSR USB Fx2 board's Interrupt end-point descriptor does not conform to the USB specification. Windows Vista detects this and returns an error. You should plug the device into a USB 2.0 (or higher) port." + /> + </stringTable> + </resources> + </localization> +</instrumentationManifest> diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.rc b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.rc new file mode 100644 index 00000000..092ec195 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.rc @@ -0,0 +1,18 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "WDF Sample Driver for OSR USB-FX2 Learning Kit" +#define VER_INTERNALNAME_STR "osrusbfx2.sys" +#define VER_ORIGINALFILENAME_STR "osrusbfx2.sys" + +#include "common.ver" + +// +// Include auto-generated string resources (created by MC.EXE from +// osrusbfx2.man) +// + +#include "fx2Events.rc" diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj new file mode 100644 index 00000000..187c5aba --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj @@ -0,0 +1,245 @@ +<?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>{23EAF474-B558-4457-B03C-164DA83B7575}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{634111FB-6184-4A00-8450-38992AB88BED}</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; ioctl.c; bulkrwr.c; Interrupt.c"> + <WppEnabled>true</WppEnabled> + <WppKernelMode>true</WppKernelMode> + <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction> + <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile> + </ClCompile> + <MessageCompile Include="osrusbfx2.man"> + <GenerateKernelModeLoggingMacros>true</GenerateKernelModeLoggingMacros> + <GenerateMofFile>true</GenerateMofFile> + <HeaderFilePath>.\$(IntDir)</HeaderFilePath> + <GeneratedHeaderPath>true</GeneratedHeaderPath> + <RCFilePath>.\$(IntDir)</RCFilePath> + <GeneratedRCAndMessagesPath>true</GeneratedRCAndMessagesPath> + <GeneratedFilesBaseName>fx2Events</GeneratedFilesBaseName> + <UseBaseNameOfInput>true</UseBaseNameOfInput> + </MessageCompile> + <OtherWpp Include="osrusbfx2.rc"> + <WppEnabled>true</WppEnabled> + <WppKernelMode>true</WppKernelMode> + <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction> + <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\usbd.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\usbd.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\usbd.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);EVENT_TRACING</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\usbd.lib</AdditionalDependencies> + </Link> + </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> + <ResourceCompile Include="osrusbfx2.rc" /> + </ItemGroup> + <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/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..2b60d58b --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters @@ -0,0 +1,46 @@ +<?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>{5B33A1A5-0088-41DD-B8DD-CB322223AFD2}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{5E63DCDC-A400-4A86-8C33-C6C83D50CC49}</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>{F97C10AC-837D-4657-B682-DD6E00ADE8A6}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{E7563CE1-E6A4-4746-87FA-4C8E3981C313}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="bulkrwr.c"> + <Filter>Source Files</Filter> + </ClCompile> + <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="ioctl.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <MessageCompile Include="osrusbfx2.man"> + <Filter>Resource Files</Filter> + </MessageCompile> + <ResourceCompile Include="osrusbfx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_kmdf/kmdf_driver/trace.h b/usb/umdf_filter_kmdf/kmdf_driver/trace.h new file mode 100644 index 00000000..518ff5f1 --- /dev/null +++ b/usb/umdf_filter_kmdf/kmdf_driver/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 + + + diff --git a/usb/umdf_filter_kmdf/umdf_filter/OsrUsbFilter.rc b/usb/umdf_filter_kmdf/umdf_filter/OsrUsbFilter.rc new file mode 100644 index 00000000..cec032d9 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/OsrUsbFilter.rc @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------- +// OsrUsbFilter.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OsrUsbFilter User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "OsrUsbFilter" +#define VER_ORIGINALFILENAME_STR "OsrUsbFilter.dll" + +#include "common.ver" diff --git a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj new file mode 100644 index 00000000..bf1103dd --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj @@ -0,0 +1,287 @@ +<?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>{0149B701-5356-434C-AC8C-07CAA1D9A4AA}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{AD8E5857-7AEF-4A01-8436-7748CEF29EC4}</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>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</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="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp; queue.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <Inf Include="WUDFOsrUsbFilterOnKmDriver.inx"> + <Architecture>$(InfArch)</Architecture> + <SpecifyArchitecture>true</SpecifyArchitecture> + <CopyOutput>.\$(IntDir)\WUDFOsrUsbFilterOnKmDriver.Inf</CopyOutput> + </Inf> + <OtherWpp Include="OsrUsbFilter.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFilter.rc" /> + </ItemGroup> + <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/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters new file mode 100644 index 00000000..6c035c03 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters @@ -0,0 +1,51 @@ +<?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>{33CB427D-970A-48D7-9257-328CC86ACBDA}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{3107D133-7EB4-4E28-8B1B-13EF0595395D}</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>{90D3C591-7FB6-4F06-9CDB-1F008F0CD090}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{1440CBCB-215A-492F-906D-F0ABE90BA456}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <Inf Include="WUDFOsrUsbFilterOnKmDriver.inx"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFilter.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx new file mode 100644 index 00000000..429b5afa --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx @@ -0,0 +1,123 @@ +; +; INF for installing OSR USB user-mode filter driver on top of OSR USB KMDF (final) sample driver +; You will need to have the user-mode filter driver and KMDF function driver in one install location +; The KMDF files needed are: +; osrusbfx2.sys (final version) +; WdfCoInstallerxxxx.dll (the KMDF coinstaller) +; + +[Version] +Signature="$WINDOWS NT$" +Class=Sample +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} +Provider=%MSFT% +DriverVer=10/01/2002,6.0.5058.0 +CatalogFile=wudf.cat + + +; ================= Class section ===================== + +[ClassInstall32] +Addreg=SampleClassReg + +[SampleClassReg] +HKR,,,0,%ClassName% +HKR,,Icon,,-5 + + +; ================= Device section ===================== + +[Manufacturer] +%MfgName%=Microsoft,NT$ARCH$ + +; For XP and later +[Microsoft.NT$ARCH$] +%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2, USB\VID_0547&PID_1002 + +[osrusbfx2.NT] +CopyFiles=osrusbfx2.Files.Ext,UMDriverCopy + +[osrusbfx2.NT.hw] +AddReg=OsrUsb_AddReg + + +[osrusbfx2.NT.CoInstallers] +AddReg=CoInstaller_AddReg +CopyFiles=CoInstaller_CopyFiles + +[osrusbfx2.NT.Services] +AddService=WUDFRd,0x000001f8,WUDFRD_ServiceInstall +AddService=osrusbfx2, 0x000001fa, osrusbfx2.AddService ;flag 0x2 sets this as the service for the device + +[osrusbfx2.NT.Wdf] +KmdfService=osrusbfx2, osrusbfx2_wdfsect +UmdfService="WUDFOsrUsbFilter", WudfOsrUsbFilter_Install +UmdfServiceOrder=WUDFOsrUsbFilter + +[OsrUsb_AddReg] +HKR,,"UpperFilters",0x00010008,"WUDFRd" ; FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND + + +[WudfOsrUsbFilter_Install] +UmdfLibraryVersion=$UMDFVERSION$ +DriverCLSID = "{422d8dbc-520d-4d7e-8f53-920e5c867e6c}" +ServiceBinary = "%12%\UMDF\WUDFOsrUsbFilter.dll" + +[osrusbfx2_wdfsect] +KmdfLibraryVersion=$KMDFVERSION$ + +[WUDFRD_ServiceInstall] +DisplayName = %WudfRdDisplayName% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WUDFRd.sys + +[osrusbfx2.AddService] +DisplayName = %osrusbfx2.SvcDesc% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %10%\System32\Drivers\osrusbfx2.sys +AddReg = osrusbfx2_AddReg + +[osrusbfx2.Files.Ext] +osrusbfx2.sys + +[UMDriverCopy] +WudfOsrUsbFilter.dll + +[SourceDisksNames] +1=%Disk_Description%,,, + +[SourceDisksFiles] +osrusbfx2.sys = 1 +WudfOsrUsbFilter.dll=1 +WudfUpdate_$UMDFCOINSTALLERVERSION$.dll=1 + +[DestinationDirs] +UMDriverCopy=12,UMDF ; copy to drivers\umdf +DefaultDestDir = 12 + +;-------------- WDF Coinstaller installation + +[DestinationDirs] +CoInstaller_CopyFiles = 11 + +[CoInstaller_CopyFiles] +WudfUpdate_$UMDFCOINSTALLERVERSION$.dll + +[CoInstaller_AddReg] +HKR,,CoInstallers32,0x00010000,"WudfUpdate_$UMDFCOINSTALLERVERSION$.dll" + +;---------------------------------------------------------------; + +[Strings] +MSFT="Microsoft" +MfgName="OSR" +Disk_Description="OSRUSBFX2 Installation Disk" +USB\VID_045E&PID_930A.DeviceDesc="Microsoft UMDF OSR Usb Sample Device With Filter on kernel-mode Driver" +osrusbfx2.SvcDesc="WDF Sample Driver for OSR USB-FX2 Learning Kit" +ClassName = "Sample Device" +WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector" + diff --git a/usb/umdf_filter_kmdf/umdf_filter/comsup.cpp b/usb/umdf_filter_kmdf/umdf_filter/comsup.cpp new file mode 100644 index 00000000..31257f31 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/comsup.cpp @@ -0,0 +1,351 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// This is the number of characters in a GUID string including the trailing +// NULL. +// + +#define GUID_STRING_CCH (sizeof("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}")) + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/umdf_filter_kmdf/umdf_filter/comsup.h b/usb/umdf_filter_kmdf/umdf_filter/comsup.h new file mode 100644 index 00000000..b96fd982 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/umdf_filter_kmdf/umdf_filter/device.cpp b/usb/umdf_filter_kmdf/umdf_filter/device.cpp new file mode 100644 index 00000000..126637ce --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/device.cpp @@ -0,0 +1,243 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR USB Sample Filter driver's + device callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "device.tmh" + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the OSR USB Sample Filter driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice; + HRESULT hr; + + // + // Configure things like the locking model before we go to create our + // partner device. + // + + // + // We don't need device level locking since we do not keep any state + // across the requests + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // Mark ourselves as a filter + // + + FxDeviceInit->SetFilter(); + + + // + // We are a filter; we don't want to be the power policy owner + // + + FxDeviceInit->SetPowerPolicyOwnership(FALSE); + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + PCMyQueue defaultQueue; + + HRESULT hr; + + hr = CMyQueue::CreateInstance(m_FxDevice, &defaultQueue); + + if (FAILED(hr)) + { + return hr; + } + + hr = defaultQueue->Configure(); + + defaultQueue->Release(); + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the OSR USB Sample Filter driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If OSR USB Sample Filter is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + return CUnknown::QueryInterface(InterfaceId, Object); +} diff --git a/usb/umdf_filter_kmdf/umdf_filter/device.h b/usb/umdf_filter_kmdf/umdf_filter/device.h new file mode 100644 index 00000000..f7a50b1d --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/device.h @@ -0,0 +1,114 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF OSR USB Sample Filter + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Class for the iotrace driver. +// + +class CMyDevice : public CUnknown +{ + +// +// Private data members. +// +private: + + IWDFDevice *m_FxDevice; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) + { + m_FxDevice = NULL; + } + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + HRESULT + Configure( + VOID + ); + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_kmdf/umdf_filter/dllsup.cpp b/usb/umdf_filter_kmdf/umdf_filter/dllsup.cpp new file mode 100644 index 00000000..10ef8a78 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/dllsup.cpp @@ -0,0 +1,183 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the OSR USB Sample Filter + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the OSR USB Sample Filter sample. If + you choose to use a different primary include file, you should ensure + they are defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +// +// Global variable to hold the module handle for this DLL. Initialized during +// DllMain and never cleared. This is used when registering and unregistering +// the driver's COM information. +// + +HINSTANCE g_ModuleHandle = NULL; + +BOOL +WINAPI +DllMain( + HINSTANCE /* ModuleHandle */, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the OSR USB Sample + Filter driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} + diff --git a/usb/umdf_filter_kmdf/umdf_filter/driver.cpp b/usb/umdf_filter_kmdf/umdf_filter/driver.cpp new file mode 100644 index 00000000..c5910c05 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/driver.cpp @@ -0,0 +1,207 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR USB Sample Filter + driver's core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/umdf_filter_kmdf/umdf_filter/driver.h b/usb/umdf_filter_kmdf/umdf_filter/driver.h new file mode 100644 index 00000000..08f36a71 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/driver.h @@ -0,0 +1,145 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF OSR USB Sample Filter + driver's callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the OSR USB Sample Filter driver. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver* /*FxWdfDriver*/ + ) + { + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver * /*FxWdfDriver*/ + ) + { + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_kmdf/umdf_filter/exports.def b/usb/umdf_filter_kmdf/umdf_filter/exports.def new file mode 100644 index 00000000..0fc42817 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/exports.def @@ -0,0 +1,4 @@ +; Skeleton.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/umdf_filter_kmdf/umdf_filter/internal.h b/usb/umdf_filter_kmdf/umdf_filter/internal.h new file mode 100644 index 00000000..516f6d7f --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/internal.h @@ -0,0 +1,111 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF OSR USB Sample Filter + driver. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +// +// Define the tracing flags. +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + MyDriverTraceControl, (73cdcaa5,ce52,43f2,aa2d,5f5a84e22213), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsbFilter" +#define MYDRIVER_COM_DESCRIPTION L"UMDF OSR USB Sample Filter Driver" +#define MYDRIVER_CLASS_ID {0x422d8dbc, 0x520d, 0x4d7e, {0x8f, 0x53, 0x92, 0x0e, 0x5c, 0x86, 0x7e, 0x6c}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_SAMPLE_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/umdf_filter_kmdf/umdf_filter/queue.cpp b/usb/umdf_filter_kmdf/umdf_filter/queue.cpp new file mode 100644 index 00000000..5642ec74 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/queue.cpp @@ -0,0 +1,538 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Queue.cpp + +Abstract: + + This module contains the implementation of the OSR USB Filter Sample driver's + queue callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "queue.h" + +#include "queue.tmh" + +HRESULT +CMyQueue::CreateInstance( + _In_ IWDFDevice * FxDevice, + _Out_ CMyQueue **Queue + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the OSR USB Filter Sample driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + CMyQueue *queue; + + HRESULT hr = S_OK; + + // + // Allocate a new instance of the device class. + // + + queue = new CMyQueue(); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(FxDevice); + } + + if (SUCCEEDED(hr)) + { + queue->AddRef(); + *Queue = queue; + } + + if (NULL != queue) + { + queue->Release(); + } + + return hr; +} + +HRESULT +CMyQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + + if(IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDefaultIoHandler))) + { + hr = S_OK; + *Object = QueryIQueueCallbackDefaultIoHandler(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) + { + hr = S_OK; + *Object = QueryIQueueCallbackWrite(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IRequestCallbackRequestCompletion))) + { + hr = S_OK; + *Object = QueryIRequestCallbackRequestCompletion(); + + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyQueue::Initialize( + _In_ IWDFDevice *FxDevice + ) +/*++ + + Routine Description: + + This method initializes the device callback object. Any operations which + need to be performed before the caller can use the callback object, but + which couldn't be done in the constructor becuase they could fail would + be placed here. + + Arguments: + + FxDevice - the device which this Queue is for. + + Return Value: + + status. + +--*/ +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Create the framework queue + // + + IUnknown *unknown = QueryIUnknown(); + hr = FxDevice->CreateIoQueue( + unknown, + TRUE, // bDefaultQueue + WdfIoQueueDispatchParallel, + FALSE, // bPowerManaged + TRUE, // bAllowZeroLengthRequests + &fxQueue + ); + if (FAILED(hr)) + { + Trace( + TRACE_LEVEL_ERROR, + "%!FUNC!: Could not create default I/O queue, %!hresult!", + hr + ); + } + + unknown->Release(); + + if (SUCCEEDED(hr)) + { + m_FxQueue = fxQueue; + + // + // m_FxQueue is kept as a Weak reference to framework Queue object to avoid + // circular reference. This object's lifetime is contained within + // framework Queue object's lifetime + // + + fxQueue->Release(); + } + + if (SUCCEEDED(hr)) + { + FxDevice->GetDefaultIoTarget(&m_FxIoTarget); + } + + return hr; +} + +void +CMyQueue::InvertBits( + _Inout_ IWDFMemory* FxMemory, + _In_ SIZE_T NumBytes + ) +/*++ + + Routine Description: + + This helper method inverts bits in the buffer of an FxMemory object + + Arguments: + + FxMemory - Framework memory object whose buffer's bits are to be inverted + + NumBytes - Number of bytes for which bits are to be inverted + + Return Value: + + None + +--*/ +{ + PBYTE Buffer = (PBYTE) + FxMemory->GetDataBuffer(NULL); + + for (SIZE_T i = 0; i < NumBytes; i++) + { + memset(Buffer + i, ~(Buffer[i]), sizeof(*Buffer)); + } +} + +void +CMyQueue::OnWrite( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest, + _In_ SIZE_T NumOfBytesToWrite + ) +/*++ + + Routine Description: + + This method is called by Framework Queue object to deliver the Write request + This method inverts the bits in write buffer and forwards the request down the device stack + In case of any failure prior to ForwardRequest, it completets the request with failure + + Arguments: + + pWdfQueue - Framework Queue which is delivering the request + + pWdfRequest - Framework Request + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + + IWDFMemory * FxInputMemory = NULL; + + FxRequest->GetInputMemory(&FxInputMemory); + + // + // Invert bits of the buffer to be written to device + // + + InvertBits(FxInputMemory, NumOfBytesToWrite); + + // + // Forward request down the stack + // When the device below completes the request we will get notified in OnComplete + // and then we will complete the request + // + + ForwardRequest(FxRequest); + + FxInputMemory->Release(); +} + +// +// IQueueCallbackDefaultIoHandler method +// + +void +CMyQueue::OnDefaultIoHandler( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest + ) +/*++ + + Routine Description: + + This method is called by Framework Queue object to deliver all the I/O + Requests for which we do not have a specific handler + (In our case anything other than Write) + + Arguments: + + pWdfQueue - Framework Queue which is delivering the request + + pWdfRequest - Framework Request + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + + // + // We just forward the request down the stack + // When the device below completes the request we will get notified in OnComplete + // and then we will complete the request + // + + ForwardRequest(FxRequest); +} + +void +CMyQueue::ForwardRequest( + _In_ IWDFIoRequest* FxRequest + ) +/*++ + + Routine Description: + + This helper method forwards the request down the stack + + Arguments: + + pWdfRequest - Request to be forwarded + + Return Value: + + None + + Remarks: + + The request gets forwarded to the next device in the stack which can be: + 1. Next device in user-mode stack + 2. Top device in kernel-mode stack (Redirector's Down Device) + + In this routine we: + 1. Set a completion callback + 2. Copy request parameters to next stack location + 3. Asynchronously send the request without any timeout + + When the lower request gets completed we will be notified via the + completion callback, where we will complete our request + + In case of failure this routine completes the request + +--*/ +{ + // + //First set the completion callback + // + + IRequestCallbackRequestCompletion *completionCallback = + QueryIRequestCallbackRequestCompletion(); + + FxRequest->SetCompletionCallback( + completionCallback, + NULL //pContext + ); + + completionCallback->Release(); + + // + //Copy current i/o stack locations parameters to the next stack location + // + + FxRequest->FormatUsingCurrentType( + ); + + // + //Send down the request + // + HRESULT hrSend = S_OK; + + hrSend = FxRequest->Send( + m_FxIoTarget, + 0, //No flag + 0 //No timeout + ); + + if (FAILED(hrSend)) + { + // + //If send failed we need to complete the request with failure + // + FxRequest->CompleteWithInformation(hrSend, 0); + } + + return; +} + +void +CMyQueue::HandleReadRequestCompletion( + IWDFIoRequest* FxRequest, + IWDFIoRequestCompletionParams* CompletionParams + ) +/*++ + + Routine Description: + + This helper method is called by OnCompletion method to complete Read request + We invert the bits in the read buffer + This is so that the client reads back the data it wrote since + we inverted bits during write to device + + Arguments: + + FxRequest - Request object of our layer + + CompletionParams - Parameters with which the lower Request got completed + + Return Value: + + None + + Remarks: + + This method always completes the request since no one else would get a chance to + complete the request + In case of failure it completes the request with failure + +--*/ +{ + HRESULT hrCompletion = CompletionParams->GetCompletionStatus(); + ULONG_PTR BytesRead = CompletionParams->GetInformation(); + + // + // Check + // 1. whether the lower device succeeded the Request (otherwise we will just complete + // the Request with failure + // 2. If data read is of non-zero length, for us to bother to invert its bits + // + + if (SUCCEEDED(hrCompletion) && + (0 != BytesRead) + ) + { + IWDFMemory *FxOutputMemory; + + FxRequest->GetOutputMemory(&FxOutputMemory ); + + InvertBits(FxOutputMemory, BytesRead); + + FxOutputMemory->Release(); + } + + // + // Complete the request + // + + FxRequest->CompleteWithInformation( + hrCompletion, + BytesRead + ); +} + + +void +CMyQueue::OnCompletion( + IWDFIoRequest* FxRequest, + IWDFIoTarget* FxIoTarget, + IWDFRequestCompletionParams* CompletionParams, + PVOID Context + ) +/*++ + + Routine Description: + + This method is called by Framework I/O Target object when + the lower device completets the Request + + Arguments: + + pWdfRequest - Request object of our layer + + pIoTarget - I/O Target object invoking this callback + + pParams - Parameters with which the lower Request got completed + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxIoTarget); + UNREFERENCED_PARAMETER(Context); + + // + // If it is a read request, we invert the bits read since we inverted them during write + // so that application would read the same data as it wrote + // + + if (WdfRequestRead == FxRequest->GetType()) + { + IWDFIoRequestCompletionParams * IoCompletionParams = NULL; + HRESULT hrQI = CompletionParams->QueryInterface(IID_PPV_ARGS(&IoCompletionParams)); + WUDF_SAMPLE_DRIVER_ASSERT(SUCCEEDED(hrQI)); + + HandleReadRequestCompletion( + FxRequest, + IoCompletionParams + ); + + SAFE_RELEASE(IoCompletionParams); + } + else + { + + // + // Otherwise we just complete our Request object with the same parameters + // with which the lower Request got completed + // + + FxRequest->CompleteWithInformation( + CompletionParams->GetCompletionStatus(), + CompletionParams->GetInformation() + ); + } +} + diff --git a/usb/umdf_filter_kmdf/umdf_filter/queue.h b/usb/umdf_filter_kmdf/umdf_filter/queue.h new file mode 100644 index 00000000..216264e9 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter/queue.h @@ -0,0 +1,253 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Queue.h + +Abstract: + + This module contains the type definitions for the OSR USB Filter Sample + driver's queue callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Class for the queue callbacks. +// It implements +// IQueueCallbackDeviceIoControl +// IRequestCallbackRequestCompletion +// Queue callbacks +// +// This class also implements IRequestCallbackRequestCompletion callback +// to get the request completion notification when request is sent down the +// stack. This callback can be implemented on a separate object as well. +// This callback is implemented here only for conenience. +// +class CMyQueue : + public CUnknown, + public IQueueCallbackWrite, + public IQueueCallbackDefaultIoHandler, + public IRequestCallbackRequestCompletion +{ + +// +// Private data members. +// +private: + + // + // Weak reference to framework Queue object which this object implements callbacks for + // This is kept as a weak reference to avoid circular reference + // This object's lifetime is contained within framework Queue object's lifetime + // + + IWDFIoQueue *m_FxQueue; + + // + // I/O Target to which we forward requests. Represents next device in the + // device stack + // + + IWDFIoTarget *m_FxIoTarget; + +// +// Private methods. +// + +private: + + CMyQueue() : + m_FxQueue(NULL), + m_FxIoTarget(NULL) + { + } + + virtual ~CMyQueue() + { + if (NULL != m_FxIoTarget) + { + m_FxIoTarget->Release(); + } + } + + // + // QueryInterface helpers + // + + IRequestCallbackRequestCompletion * + QueryIRequestCallbackRequestCompletion( + VOID + ) + { + AddRef(); + return static_cast<IRequestCallbackRequestCompletion*>(this); + } + + IQueueCallbackWrite * + QueryIQueueCallbackWrite( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackWrite *>(this); + } + + IQueueCallbackDefaultIoHandler * + QueryIQueueCallbackDefaultIoHandler( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDefaultIoHandler *>(this); + } + + // + // Initialize + // + + HRESULT + Initialize( + _In_ IWDFDevice *FxDevice + ); + + // + // Helper method to forward request down the stack + // + + void + ForwardRequest( + _In_ IWDFIoRequest *pWdfRequest + ); + + // + // Helper method to inverts bits in the buffer of a framework Memory object + // + + void + InvertBits( + _Inout_ IWDFMemory* FxMemory, + _In_ SIZE_T NumBytes + ); + + // + // Helper method to handle Read request completion + // + + void + HandleReadRequestCompletion( + IWDFIoRequest* FxRequest, + IWDFIoRequestCompletionParams* CompletionParams + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this class + // + + static + HRESULT + CreateInstance( + _In_ IWDFDevice *FxDevice, + _Out_ CMyQueue **Queue + ); + + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IQueueCallbackWrite method + // + + virtual + void + STDMETHODCALLTYPE + OnWrite( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest, + _In_ SIZE_T NumOfBytesToWrite + ); + + + // + // IQueueCallbackDefaultIoHandler method + // + + virtual + void + STDMETHODCALLTYPE + OnDefaultIoHandler( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest + ); + + // + //IRequestCallbackRequestCompletion + // + + virtual + void + STDMETHODCALLTYPE + OnCompletion( + IWDFIoRequest* FxRequest, + IWDFIoTarget* FxIoTarget, + IWDFRequestCompletionParams* CompletionParams, + PVOID Context + ); +}; + diff --git a/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln b/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln new file mode 100644 index 00000000..610e5fe9 --- /dev/null +++ b/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{C5684CA0-69C7-44A5-9993-99687939133F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{EECFA720-E287-4CEE-A8AA-6BF3777F68B3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kmdf_driver", "Kmdf_driver", "{A0A8D15D-A7A6-4170-AAFA-753B7E798AF4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{3EF9240F-7E95-49A7-8B0D-5F7061655764}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{0149B701-5356-434C-AC8C-07CAA1D9A4AA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf_driver\osrusbfx2.vcxproj", "{23EAF474-B558-4457-B03C-164DA83B7575}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Debug|Win32.ActiveCfg = Debug|Win32 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Debug|Win32.Build.0 = Debug|Win32 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Release|Win32.ActiveCfg = Release|Win32 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Release|Win32.Build.0 = Release|Win32 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Debug|x64.ActiveCfg = Debug|x64 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Debug|x64.Build.0 = Debug|x64 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Release|x64.ActiveCfg = Release|x64 + {3EF9240F-7E95-49A7-8B0D-5F7061655764}.Release|x64.Build.0 = Release|x64 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Debug|Win32.Build.0 = Debug|Win32 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Release|Win32.ActiveCfg = Release|Win32 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Release|Win32.Build.0 = Release|Win32 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Debug|x64.ActiveCfg = Debug|x64 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Debug|x64.Build.0 = Debug|x64 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Release|x64.ActiveCfg = Release|x64 + {0149B701-5356-434C-AC8C-07CAA1D9A4AA}.Release|x64.Build.0 = Release|x64 + {23EAF474-B558-4457-B03C-164DA83B7575}.Debug|Win32.ActiveCfg = Debug|Win32 + {23EAF474-B558-4457-B03C-164DA83B7575}.Debug|Win32.Build.0 = Debug|Win32 + {23EAF474-B558-4457-B03C-164DA83B7575}.Release|Win32.ActiveCfg = Release|Win32 + {23EAF474-B558-4457-B03C-164DA83B7575}.Release|Win32.Build.0 = Release|Win32 + {23EAF474-B558-4457-B03C-164DA83B7575}.Debug|x64.ActiveCfg = Debug|x64 + {23EAF474-B558-4457-B03C-164DA83B7575}.Debug|x64.Build.0 = Debug|x64 + {23EAF474-B558-4457-B03C-164DA83B7575}.Release|x64.ActiveCfg = Release|x64 + {23EAF474-B558-4457-B03C-164DA83B7575}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3EF9240F-7E95-49A7-8B0D-5F7061655764} = {C5684CA0-69C7-44A5-9993-99687939133F} + {0149B701-5356-434C-AC8C-07CAA1D9A4AA} = {EECFA720-E287-4CEE-A8AA-6BF3777F68B3} + {23EAF474-B558-4457-B03C-164DA83B7575} = {A0A8D15D-A7A6-4170-AAFA-753B7E798AF4} + EndGlobalSection +EndGlobal diff --git a/usb/umdf_filter_umdf/Package/package.VcxProj b/usb/umdf_filter_umdf/Package/package.VcxProj new file mode 100644 index 00000000..b9b377e9 --- /dev/null +++ b/usb/umdf_filter_umdf/Package/package.VcxProj @@ -0,0 +1,91 @@ +<?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="PropertySheets"> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Utility</ConfigurationType> + <DriverType>Package</DriverType> + <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> + <Configuration>Debug</Configuration> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{92A41A0C-EC0F-4D98-B4DE-4899B375FD49}</ProjectGuid> + <SampleGuid>{ECED2BAF-D334-46B0-A7A9-734224614A21}</SampleGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <ImportToStore>False</ImportToStore> + <InstallMode>None</InstallMode> + <HardwareIdString /> + <CommandLine /> + <ScriptPath /> + <DeployFiles /> + <ScriptName /> + <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery> + <EnableVerifier>False</EnableVerifier> + <AllDrivers>False</AllDrivers> + <VerifyProjectOutput>True</VerifyProjectOutput> + <VerifyDrivers /> + <VerifyFlags>133563</VerifyFlags> + </PropertyGroup> + <ItemDefinitionGroup> + </ItemDefinitionGroup> + <ItemGroup> + <!--Inf Include="DriverInf.inv" /--> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\umdf_driver\WUDFOsrUsbFx2.vcxproj"> + <Project>{0D3781C2-2236-46B0-806D-387999E500AB}</Project> + </ProjectReference> + <ProjectReference Include="..\umdf_filter\WUDFOsrUsbFilter.vcxproj"> + <Project>{E62A4AAA-870E-4D58-AA10-D9604A2E52E8}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_umdf/Package/package.VcxProj.Filters b/usb/umdf_filter_umdf/Package/package.VcxProj.Filters new file mode 100644 index 00000000..a96565c8 --- /dev/null +++ b/usb/umdf_filter_umdf/Package/package.VcxProj.Filters @@ -0,0 +1,21 @@ +<?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>{4E330348-D3BC-4378-9E28-1C0E89913E9C}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{F5D9FE78-6B2A-4C19-91B7-49A3D081DA74}</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>{32502152-33D3-42BC-8DC3-DBCEC24AAC1F}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{82F51BD2-E3F4-4E26-9787-497F73C1EC82}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_umdf/ReadMe.md b/usb/umdf_filter_umdf/ReadMe.md new file mode 100644 index 00000000..56eb02db --- /dev/null +++ b/usb/umdf_filter_umdf/ReadMe.md @@ -0,0 +1,57 @@ +Sample UMDF Filter above UMDF Function Driver for OSR USB-FX2 (UMDF Version 1) +============================================================================== + +The umdf\_filter\_umdf sample demonstrates how to load a User-Mode Driver Framework (UMDF) filter driver as an upper filter driver above the umdf\_fx2 sample driver. + +This sample is written for the OSR USB-FX2 Learning Kit. The specification for the device is at <http://www.osronline.com/hardware/OSRFX2_32.pdf>. + +Overview +-------- + +Here is the overview of the device: + +- The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681). +- It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN). +- Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states. +- Interrupt Endpoint: + - Sends an 8-bit value that represents the state of the switches. + - Sent on startup, resume from suspend, and whenever the switch pack setting changes. + - Firmware does not de-bounce the switch pack. + - One switch change can result in multiple bytes being sent. + - Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack). +- Bulk Endpoints are configured for loopback: + - The device moves data from IN endpoint to OUT endpoint. + - The device does not change the values of the data it receives nor does it internally create any data. + - Endpoints are always double buffered. + - Maximum packet size depends on speed (64 full speed, 512 high speed). + +Testing the driver +------------------ + +You can test this sample either by using the [Custom driver access](http://go.microsoft.com/fwlink/p/?LinkID=248288) sample application, or by using the osrusbfx2.exe test application. For information on how to build and use the osrusbfx2.exe application, see the test instructions for the [umdf\_fx2](http://msdn.microsoft.com/en-us/library/windows/hardware/) sample. + +Sample Contents +--------------- + +<table> +<colgroup> +<col width="50%" /> +<col width="50%" /> +</colgroup> +<thead> +<tr class="header"> +<th align="left">Folder +Description</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td align="left">usb\umdf_filter_umdf\umdf_driver +This directory contains source code for the umdf_fx2 sample driver.</td> +<td align="left">usb\umdf_filter_umdf\umdf_filter +This directory contains the UMDF filter driver.</td> +</tr> +</tbody> +</table> + + diff --git a/usb/umdf_filter_umdf/inc/WUDFOsrUsbPublic.h b/usb/umdf_filter_umdf/inc/WUDFOsrUsbPublic.h new file mode 100644 index 00000000..6681fa14 --- /dev/null +++ b/usb/umdf_filter_umdf/inc/WUDFOsrUsbPublic.h @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + WUDFOsrUsbPublic.h + +Abstract: + + This module contains the common declarations shared by driver + and user applications for the UMDF OSR device sample. + + Note that this driver does NOT use the same device interface GUID + as the KMDF OSR USB sample. + +Environment: + + user and kernel + +--*/ + +#pragma once + +// +// Define an Interface Guid so that app can find the device and talk to it. +// + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + diff --git a/usb/umdf_filter_umdf/inc/list.h b/usb/umdf_filter_umdf/inc/list.h new file mode 100644 index 00000000..38d0b1e9 --- /dev/null +++ b/usb/umdf_filter_umdf/inc/list.h @@ -0,0 +1,77 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + list.h + +Abstract: + + This module contains doubly linked list macros + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + + +FORCEINLINE +VOID +InitializeListHead( + IN PLIST_ENTRY ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +FORCEINLINE +BOOLEAN +RemoveEntryList( + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + PLIST_ENTRY Flink; + + Flink = Entry->Flink; + Blink = Entry->Blink; + Blink->Flink = Flink; + Flink->Blink = Blink; + return (BOOLEAN)(Flink == Blink); +} + +FORCEINLINE +VOID +InsertHeadList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Flink; + + Flink = ListHead->Flink; + Entry->Flink = Flink; + Entry->Blink = ListHead; + Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +FORCEINLINE +VOID +InsertTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + + Blink = ListHead->Blink; + Entry->Flink = ListHead; + Entry->Blink = Blink; + Blink->Flink = Entry; + ListHead->Blink = Entry; +} diff --git a/usb/umdf_filter_umdf/inc/public.h b/usb/umdf_filter_umdf/inc/public.h new file mode 100644 index 00000000..22f6cb6d --- /dev/null +++ b/usb/umdf_filter_umdf/inc/public.h @@ -0,0 +1,217 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + public.h + +Abstract: + + Public definitions for the OSR_FX2 device operations. + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +#include "WudfOsrUsbPublic.h" + + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> + +#pragma warning( push ) +#pragma warning( disable : 4201 ) // nameless struct/union +#pragma warning( disable : 4214 ) // bit-field type other than int + +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +// +// Seven segment display bit values. +// + +// +// Undefine conflicting MFC constant +// +#undef SS_CENTER +#undef SS_LEFT +#undef SS_RIGHT + +#define SS_TOP 0x01 +#define SS_TOP_LEFT 0x40 +#define SS_TOP_RIGHT 0x02 +#define SS_CENTER 0x20 +#define SS_BOTTOM_LEFT 0x10 +#define SS_BOTTOM_RIGHT 0x04 +#define SS_BOTTOM 0x80 +#define SS_DOT 0x08 + +// +// FILE_PLAYBACK +// +// FILE_PLAYBACK structure contains the parameters for the PLAY_FILE I/O Control. +// + +typedef struct _FILE_PLAYBACK +{ + // + // The delay between changes in the display, in milliseconds. + // + + USHORT Delay; + + // + // The data file path. + // + + WCHAR Path[1]; +} FILE_PLAYBACK, *PFILE_PLAYBACK; + +#include <poppack.h> + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 0x65500 + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_PLAY_FILE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#pragma warning(pop) + +#endif + diff --git a/usb/umdf_filter_umdf/inc/usb_hw.h b/usb/umdf_filter_umdf/inc/usb_hw.h new file mode 100644 index 00000000..d6e983f1 --- /dev/null +++ b/usb/umdf_filter_umdf/inc/usb_hw.h @@ -0,0 +1,233 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Usb.h + +Abstract: + + Contains prototypes for interfacing with a USB connected device. These + are copied from the KMDF WDFUSB.H header file (but with the WDF specific + portions removed) + +Environment: + + kernel mode only + +--*/ + +#pragma once + +typedef enum _WINUSB_BMREQUEST_DIRECTION { + BmRequestHostToDevice = BMREQUEST_HOST_TO_DEVICE, + BmRequestDeviceToHost = BMREQUEST_DEVICE_TO_HOST, +} WINUSB_BMREQUEST_DIRECTION; + +typedef enum _WINUSB_BMREQUEST_TYPE { + BmRequestStandard = BMREQUEST_STANDARD, + BmRequestClass = BMREQUEST_CLASS, + BmRequestVendor = BMREQUEST_VENDOR, +} WINUSB_BMREQUEST_TYPE; + +typedef enum _WINUSB_BMREQUEST_RECIPIENT { + BmRequestToDevice = BMREQUEST_TO_DEVICE, + BmRequestToInterface = BMREQUEST_TO_INTERFACE, + BmRequestToEndpoint = BMREQUEST_TO_ENDPOINT, + BmRequestToOther = BMREQUEST_TO_OTHER, +} WINUSB_BMREQUEST_RECIPIENT; + +typedef enum _WINUSB_DEVICE_TRAITS { + WINUSB_DEVICE_TRAIT_SELF_POWERED = 0x00000001, + WINUSB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE = 0x00000002, + WINUSB_DEVICE_TRAIT_AT_HIGH_SPEED = 0x00000004, +} WINUSB_DEVICE_TRAITS; + +typedef enum _WdfUsbTargetDeviceSelectInterfaceType { + WdfUsbTargetDeviceSelectInterfaceTypeInterface = 0x10, + WdfUsbTargetDeviceSelectInterfaceTypeUrb = 0x11, +} WdfUsbTargetDeviceSelectInterfaceType; + + + +typedef union _WINUSB_CONTROL_SETUP_PACKET { + struct { + union { + #pragma warning(disable:4214) // bit field types other than int + struct { + // + // Valid values are BMREQUEST_TO_DEVICE, BMREQUEST_TO_INTERFACE, + // BMREQUEST_TO_ENDPOINT, BMREQUEST_TO_OTHER + // + BYTE Recipient:2; + + BYTE Reserved:3; + + // + // Valid values are BMREQUEST_STANDARD, BMREQUEST_CLASS, + // BMREQUEST_VENDOR + // + BYTE Type:2; + + // + // Valid values are BMREQUEST_HOST_TO_DEVICE, + // BMREQUEST_DEVICE_TO_HOST + // + BYTE Dir:1; + } Request; + #pragma warning(default:4214) // bit field types other than int + BYTE Byte; + } bm; + + BYTE bRequest; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wValue; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wIndex; + + USHORT wLength; + } Packet; + + struct { + BYTE Bytes[8]; + } Generic; + + WINUSB_SETUP_PACKET WinUsb; + +} WINUSB_CONTROL_SETUP_PACKET, *PWINUSB_CONTROL_SETUP_PACKET; + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_CLASS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestClass; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_VENDOR( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestVendor; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_FEATURE( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT FeatureSelector, + USHORT Index, + BOOLEAN SetFeature + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestHostToDevice; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + if (SetFeature) { + Packet->Packet.bRequest = USB_REQUEST_SET_FEATURE; + } + else { + Packet->Packet.bRequest = USB_REQUEST_CLEAR_FEATURE; + } + + Packet->Packet.wValue.Value = FeatureSelector; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestDeviceToHost; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + Packet->Packet.bRequest = USB_REQUEST_GET_STATUS; + Packet->Packet.wIndex.Value = Index; + Packet->Packet.wValue.Value = 0; + + // Packet->Packet.wLength will be set by the formatting function +} + diff --git a/usb/umdf_filter_umdf/umdf_driver/ControlQueue.cpp b/usb/umdf_filter_umdf/umdf_driver/ControlQueue.cpp new file mode 100644 index 00000000..f4058941 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/ControlQueue.cpp @@ -0,0 +1,564 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "winioctl.h" + +#include "ControlQueue.tmh" + +CMyControlQueue::CMyControlQueue( + _In_ PCMyDevice Device + ) : CMyQueue(Device) +{ + +} + +HRESULT +STDMETHODCALLTYPE +CMyControlQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDeviceIoControl))) + { + hr = S_OK; + *Object = QueryIQueueCallbackDeviceIoControl(); + + } + else + { + hr = CMyQueue::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyControlQueue::CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Aruments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + PCMyControlQueue queue = NULL; + HRESULT hr = S_OK; + + queue = new CMyControlQueue(Device); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Call the queue callback object to initialize itself. This will create + // its partner queue framework object. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(); + } + + if (SUCCEEDED(hr)) + { + *Queue = queue; + } + else + { + SAFE_RELEASE(queue); + } + + return hr; +} + +HRESULT +CMyControlQueue::Initialize( + VOID + ) +{ + HRESULT hr; + + // + // First initialize the base class. This will create the partner FxIoQueue + // object and setup automatic forwarding of I/O controls. + // + + // + // The framework (UMDF) will not deliver a + // request to the driver that arrives on a power-managed queue, unless + // the device is in a powered-up state. If you receive a request on a + // power-managed queue after the device has idled out, + // the framework will not be able to power-up and present the request + // to the driver unless it is the power policy owner (PPO). + // Since this driver is the PPO it can use power managed queues + // + + hr = __super::Initialize(WdfIoQueueDispatchSequential, + false, + true /* use power managed queue */); + + // + // return the status. + // + + return hr; +} + +VOID +STDMETHODCALLTYPE +CMyControlQueue::OnDeviceIoControl( + _In_ IWDFIoQueue *FxQueue, + _In_ IWDFIoRequest *FxRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ) +/*++ + +Routine Description: + + + DeviceIoControl dispatch routine + +Aruments: + + FxQueue - Framework Queue instance + FxRequest - Framework Request instance + ControlCode - IO Control Code + InputBufferSizeInBytes - Lenth of input buffer + OutputBufferSizeInBytes - Lenth of output buffer + + Always succeeds DeviceIoIoctl +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + + IWDFMemory *memory = NULL; + PVOID buffer; + + SIZE_T bigBufferCb; + + ULONG information = 0; + + bool completeRequest = true; + + HRESULT hr = S_OK; + + switch (ControlCode) + { + case IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR: + { + // + // Get the output buffer. + // + + FxRequest->GetOutputMemory(&memory ); + + // + // request the descriptor. + // + + ULONG bufferCb; + + // + // Get the buffer address then release the memory object. + // The memory object remains valid until the request is + // completed. + // + + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + if (bigBufferCb > ULONG_MAX) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + break; + } + else + { + bufferCb = (ULONG) bigBufferCb; + } + + hr = m_Device->GetUsbTargetDevice()->RetrieveDescriptor( + USB_CONFIGURATION_DESCRIPTOR_TYPE, + 0, + 0, + &bufferCb, + (PUCHAR) buffer + ); + + if (SUCCEEDED(hr)) + { + information = bufferCb; + } + + break; + } + + case IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the result of the + // control transfer. + // + + if (OutputBufferSizeInBytes < sizeof(BAR_GRAPH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetOutputMemory(&memory ); + } + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->GetBarGraphDisplay((PBAR_GRAPH_STATE) buffer); + } + + // + // If that worked then record how many bytes of data we're + // returning. + // + + if (SUCCEEDED(hr)) + { + information = sizeof(BAR_GRAPH_STATE); + } + + break; + } + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the input for the + // control transfer. + // + + if (InputBufferSizeInBytes < sizeof(BAR_GRAPH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetInputMemory(&memory); + } + + // + // Get the data buffer and use it to set the bar graph on the + // device. + // + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->SetBarGraphDisplay((PBAR_GRAPH_STATE) buffer); + } + + break; + } + + case IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the result of the + // control transfer. + // + + if (OutputBufferSizeInBytes < sizeof(SEVEN_SEGMENT)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetOutputMemory(&memory ); + } + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + hr = m_Device->GetSevenSegmentDisplay((PSEVEN_SEGMENT) buffer); + } + + // + // If that worked then record how many bytes of data we're + // returning. + // + + if (SUCCEEDED(hr)) + { + information = sizeof(SEVEN_SEGMENT); + } + + break; + } + + case IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the input for the + // control transfer. + // + + if (InputBufferSizeInBytes < sizeof(SEVEN_SEGMENT)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetInputMemory(&memory ); + } + + // + // Get the data buffer and use it to set the bar graph on the + // device. + // + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->SetSevenSegmentDisplay((PSEVEN_SEGMENT) buffer); + } + break; + } + + case IOCTL_OSRUSBFX2_READ_SWITCHES: + { + // + // Make sure the buffer is big enough to hold the input for the + // control transfer. + // + + if (OutputBufferSizeInBytes < sizeof(SWITCH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetOutputMemory(&memory ); + } + + // + // Get the data buffer and use it to set the bar graph on the + // device. + // + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->ReadSwitchState((PSWITCH_STATE) buffer); + } + + if (SUCCEEDED(hr)) + { + information = sizeof(SWITCH_STATE); + } + + break; + } + + case IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE: + { + // + // Make sure the buffer is big enough to hold the switch + // state. + // + + if (OutputBufferSizeInBytes < sizeof(SWITCH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + // + // Forward the request to the switch state change queue. + // + + hr = FxRequest->ForwardToIoQueue( + m_Device->GetSwitchChangeQueue() + ); + + if (SUCCEEDED(hr)) + { + completeRequest = false; + } + } + + break; + } + + case IOCTL_OSRUSBFX2_RESET_DEVICE: + case IOCTL_OSRUSBFX2_REENUMERATE_DEVICE: + { + // + // WinUSB does not allow us to reset or re-enumerate the device. + // Return not-supported for the error in both of these cases. + // + + hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + break; + } + + case IOCTL_OSRUSBFX2_PLAY_FILE: + { + // + // This IOCTL demonstrates how to use impersonation to access + // resources using the credentials provided by the client. Note + // that for impersonation to work it has to be enabled in the device + // INF and the client must allow impersonation when they open the + // device. + // + // This IOCTL opens a file using the path provided by the client + // and then plays the characters in that file out to the seven segment + // display in a worker thread. + // + + PFILE_PLAYBACK playback; + SIZE_T playbackCb; + size_t realPlaybackCb; + + FxRequest->GetInputMemory(&memory); + + if (memory == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); + break; + } + + // + // Get the playback structure from the input buffer. + // + + playback = (PFILE_PLAYBACK) memory->GetDataBuffer(&playbackCb); + + memory->Release(); + + // + // Make sure the length is at least as big as the fixed portion + // of the input structure. + // + + if (playbackCb < (FIELD_OFFSET(FILE_PLAYBACK, Path))) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); + break; + } + + // + // Make sure the file name is at least one character long. + // + + playbackCb -= FIELD_OFFSET(FILE_PLAYBACK, Path); + + if (playbackCb < sizeof(WCHAR)) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); + break; + } + + // + // Verify that the string provided is valid. + // + + hr = StringCbLength(playback->Path, + min(playbackCb, (STRSAFE_MAX_CCH * sizeof(WCHAR))), + &realPlaybackCb); + + if (FAILED(hr)) + { + break; + } + + hr = m_Device->PlaybackFile(playback, FxRequest); + + break; + } + + + + default: + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + break; + } + } + + if (completeRequest) + { + FxRequest->CompleteWithInformation(hr, information); + } + + return; +} diff --git a/usb/umdf_filter_umdf/umdf_driver/ControlQueue.h b/usb/umdf_filter_umdf/umdf_driver/ControlQueue.h new file mode 100644 index 00000000..251521e1 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/ControlQueue.h @@ -0,0 +1,101 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.h + +Abstract: + + This file defines the queue callback object for handling device I/O + control requests. This is a serialized queue. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyControlQueue : public IQueueCallbackDeviceIoControl, + public CMyQueue +{ + HRESULT + Initialize( + VOID + ); + +public: + + CMyControlQueue( + _In_ PCMyDevice Device + ); + + virtual + ~CMyControlQueue( + VOID + ) + { + return; + } + + static + HRESULT + CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + + IQueueCallbackDeviceIoControl * + QueryIQueueCallbackDeviceIoControl( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDeviceIoControl *>(this); + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // Wdf Callbacks + // + + // + // IQueueCallbackDeviceIoControl + // + STDMETHOD_ (void, OnDeviceIoControl)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ); +}; + diff --git a/usb/umdf_filter_umdf/umdf_driver/Device.cpp b/usb/umdf_filter_umdf/umdf_driver/Device.cpp new file mode 100644 index 00000000..2ebf4079 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/Device.cpp @@ -0,0 +1,2087 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR Fx2 driver's + device callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ +#include "internal.h" +#include "initguid.h" +#include "usb_hw.h" +#include <devpkey.h> + +#include "device.tmh" +#define CONCURRENT_READS 2 + +CMyDevice::~CMyDevice( + ) +{ + SAFE_RELEASE(m_pIoTargetInterruptPipeStateMgmt); +} + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the OSR Fx2 driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice2 *fxDevice = NULL; + + HRESULT hr = S_OK; + + // + // TODO: Any per-device initialization which must be done before + // creating the partner object. + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // TODO: If you're writing a filter driver then indicate that here. + // And then don't claim power policy ownership below + // + // FxDeviceInit->SetFilter(); + // + + // + // Set the Fx2 driver as the power policy owner. + // + + FxDeviceInit->SetPowerPolicyOwnership(TRUE); + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + if (SUCCEEDED(hr)) + { + IUnknown *unknown = this->QueryIUnknown(); + IWDFDevice* device1; + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &device1); + + // + // Convert the interface to version 2 + // + + if (SUCCEEDED(hr)) { + device1->QueryInterface(IID_PPV_ARGS(&fxDevice)); + _Analysis_assume_(fxDevice != NULL); + device1->Release(); + } + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + HRESULT hr = S_OK; + + // + // Get the bus type GUID for the device and confirm that we're attached to + // USB. + // + // NOTE: Since this device only supports USB we'd normally trust our INF + // to ensure this. + // + // But if the device also supported 1394 then we could + // use this to determine which type of bus we were attached to. + // + + hr = GetBusTypeGuid(); + + if (FAILED(hr)) + { + return hr; + } + + // + // Create the read-write queue. + // + + hr = CMyReadWriteQueue::CreateInstance(this, &m_ReadWriteQueue); + + if (FAILED(hr)) + { + return hr; + } + + // + // We use default queue for read/write + // + + hr = m_ReadWriteQueue->Configure(); + + m_ReadWriteQueue->Release(); + + // + // Create the control queue and configure forwarding for IOCTL requests. + // + + if (SUCCEEDED(hr)) + { + hr = CMyControlQueue::CreateInstance(this, &m_ControlQueue); + + if (SUCCEEDED(hr)) + { + hr = m_ControlQueue->Configure(); + if (SUCCEEDED(hr)) + { + m_FxDevice->ConfigureRequestDispatching( + m_ControlQueue->GetFxQueue(), + WdfRequestDeviceIoControl, + true + ); + } + m_ControlQueue->Release(); + } + } + + // + // Create a manual I/O queue to hold requests for notification when + // the switch state changes. + // + + hr = m_FxDevice->CreateIoQueue(NULL, + FALSE, + WdfIoQueueDispatchManual, + FALSE, + FALSE, + &m_SwitchChangeQueue); + + + // + // Release creation reference as object tree will keep a reference + // + + m_SwitchChangeQueue->Release(); + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2, + NULL); + } + + // + // Mark the interface as restricted to allow access to applications bound + // using device metadata. Failures here are not fatal so we log them but + // ignore them otherwise. + // + if (SUCCEEDED(hr)) + { + WDF_PROPERTY_STORE_ROOT RootSpecifier; + IWDFUnifiedPropertyStoreFactory * pUnifiedPropertyStoreFactory = NULL; + IWDFUnifiedPropertyStore * pUnifiedPropertyStore = NULL; + DEVPROP_BOOLEAN isRestricted = DEVPROP_TRUE; + HRESULT hrSetProp; + + hrSetProp = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pUnifiedPropertyStoreFactory)); + + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrSetProp)); + + RootSpecifier.LengthCb = sizeof(RootSpecifier); + RootSpecifier.RootClass = WdfPropertyStoreRootClassDeviceInterfaceKey; + RootSpecifier.Qualifier.DeviceInterfaceKey.InterfaceGUID = &GUID_DEVINTERFACE_OSRUSBFX2; + RootSpecifier.Qualifier.DeviceInterfaceKey.ReferenceString = NULL; + + hrSetProp = pUnifiedPropertyStoreFactory->RetrieveUnifiedDevicePropertyStore(&RootSpecifier, + &pUnifiedPropertyStore); + + if (SUCCEEDED(hrSetProp)) + { + hrSetProp = pUnifiedPropertyStore->SetPropertyData(&DEVPKEY_DeviceInterface_Restricted, + 0, // Lcid + 0, // Flags + DEVPROP_TYPE_BOOLEAN, + sizeof(isRestricted), + &isRestricted); + } + + if (FAILED(hrSetProp)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Could not set restricted property %!HRESULT!", + hrSetProp + ); + } + + SAFE_RELEASE(pUnifiedPropertyStoreFactory); + SAFE_RELEASE(pUnifiedPropertyStore); + } + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackHardware))) + { + *Object = QueryIPnpCallbackHardware(); + hr = S_OK; + } + else if (IsEqualIID(InterfaceId, __uuidof(IPnpCallback))) + { + *Object = QueryIPnpCallback(); + hr = S_OK; + } + else if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackSelfManagedIo))) + { + *Object = QueryIPnpCallbackSelfManagedIo(); + hr = S_OK; + } + else if(IsEqualIID(InterfaceId, __uuidof(IUsbTargetPipeContinuousReaderCallbackReadersFailed))) + { + *Object = QueryContinousReaderFailureCompletion(); + hr = S_OK; + } + else if(IsEqualIID(InterfaceId, __uuidof(IUsbTargetPipeContinuousReaderCallbackReadComplete))) + { + *Object = QueryContinousReaderCompletion(); + hr = S_OK; + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyDevice::OnPrepareHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked to ready the driver + to talk to hardware. It opens the handle to the + device and talks to it using the WINUSB interface. + It invokes WINUSB to discver the interfaces and stores + the information related to bulk endpoints. + +Arguments: + + FxDevice : Pointer to the WDF device interface + +Return Value: + + HRESULT + +--*/ +{ + PWSTR deviceName = NULL; + DWORD deviceNameCch = 0; + + HRESULT hr; + + // + // Get the device name. + // Get the length to allocate first + // + + hr = m_FxDevice->RetrieveDeviceName(NULL, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!HRESULT!", + hr + ); + } + + // + // Allocate the buffer + // + + if (SUCCEEDED(hr)) + { + deviceName = new WCHAR[deviceNameCch]; + + if (deviceName == NULL) + { + hr = E_OUTOFMEMORY; + } + } + + // + // Get the actual name + // + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->RetrieveDeviceName(deviceName, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Device name %S", + deviceName + ); + } + + // + // Create USB I/O Targets and configure them + // + + if (SUCCEEDED(hr)) + { + hr = CreateUsbIoTargets(); + } + + if (SUCCEEDED(hr)) + { + ULONG length = sizeof(m_Speed); + + hr = m_pIUsbTargetDevice->RetrieveDeviceInformation(DEVICE_SPEED, + &length, + &m_Speed); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb device speed information %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Speed - %x\n", + m_Speed + ); + } + + if (SUCCEEDED(hr)) + { + hr = ConfigureUsbPipes(); + } + + // Setup power-management settings on the device. + // + + if (SUCCEEDED(hr)) + { + hr = SetPowerManagement(); + } + + // + // + // Clear the seven segement display to indicate that we're done with + // prepare hardware. + // + + if (SUCCEEDED(hr)) + { + hr = IndicateDeviceReady(); + } + + if (SUCCEEDED(hr)) + { + hr = ConfigContReaderForInterruptEndPoint(); + } + + delete[] deviceName; + + return hr; +} + +HRESULT +CMyDevice::OnReleaseHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked when the device is being removed or stopped + It releases all resources allocated for this device. + +Arguments: + + FxDevice - Pointer to the Device object. + +Return Value: + + HRESULT - Always succeeds. + +--*/ +{ + // + // Delete USB Target Device WDF Object, this will in turn + // delete all the children - interface and the pipe objects + // + // This makes sure that + // 1. We drain the the pending read which does not come from an I/O queue + // 2. We remove USB target objects from object tree (and thereby free them) + // before any potential subsequent OnPrepareHardware creates new ones + // + // m_pIUsbTargetDevice could be NULL if OnPrepareHardware failed so we need + // to guard against that + // + + if (m_pIUsbTargetDevice) + { + m_pIUsbTargetDevice->DeleteWdfObject(); + } + + return S_OK; +} + +HRESULT +CMyDevice::CreateUsbIoTargets( + ) +/*++ + +Routine Description: + + This routine creates Usb device, interface and pipe objects + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr; + UCHAR NumEndPoints = 0; + IWDFUsbTargetFactory * pIUsbTargetFactory = NULL; + IWDFUsbTargetDevice * pIUsbTargetDevice = NULL; + IWDFUsbInterface * pIUsbInterface = NULL; + IWDFUsbTargetPipe * pIUsbPipe = NULL; + + hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory)); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb target factory %!HRESULT!", + hr + ); + } + + if (SUCCEEDED(hr)) + { + hr = pIUsbTargetFactory->CreateUsbTargetDevice( + &pIUsbTargetDevice); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!", + hr + ); + } + else + { + m_pIUsbTargetDevice = pIUsbTargetDevice; + + // + // Release the creation reference as object tree will maintain a reference + // + + pIUsbTargetDevice->Release(); + } + } + + if (SUCCEEDED(hr)) + { + UCHAR NumInterfaces = pIUsbTargetDevice->GetNumInterfaces(); + + WUDF_TEST_DRIVER_ASSERT(1 == NumInterfaces); + + hr = pIUsbTargetDevice->RetrieveUsbInterface(0, &pIUsbInterface); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to retrieve USB interface from USB Device I/O Target %!HRESULT!", + hr + ); + } + else + { + m_pIUsbInterface = pIUsbInterface; + + pIUsbInterface->Release(); //release creation reference + } + } + + if (SUCCEEDED(hr)) + { + NumEndPoints = pIUsbInterface->GetNumEndPoints(); + + if (NumEndPoints != NUM_OSRUSB_ENDPOINTS) { + hr = E_UNEXPECTED; + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Has %d endpoints, expected %d, returning %!HRESULT! ", + NumEndPoints, + NUM_OSRUSB_ENDPOINTS, + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + for (UCHAR PipeIndex = 0; PipeIndex < NumEndPoints; PipeIndex++) + { + hr = pIUsbInterface->RetrieveUsbPipeObject(PipeIndex, + &pIUsbPipe); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to retrieve USB Pipe for PipeIndex %d, %!HRESULT!", + PipeIndex, + hr + ); + } + else + { + if ( pIUsbPipe->IsInEndPoint() ) + { + if ( UsbdPipeTypeInterrupt == pIUsbPipe->GetType() ) + { + m_pIUsbInterruptPipe = pIUsbPipe; + + WUDF_TEST_DRIVER_ASSERT (m_pIoTargetInterruptPipeStateMgmt == NULL); + + hr = m_pIUsbInterruptPipe->QueryInterface(__uuidof( + IWDFIoTargetStateManagement), + reinterpret_cast<void**>(&m_pIoTargetInterruptPipeStateMgmt) + ); + if (FAILED(hr)) + { + m_pIoTargetInterruptPipeStateMgmt = NULL; + } + } + else if ( UsbdPipeTypeBulk == pIUsbPipe->GetType() ) + { + m_pIUsbInputPipe = pIUsbPipe; + } + else + { + pIUsbPipe->DeleteWdfObject(); + } + } + else if ( pIUsbPipe->IsOutEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) ) + { + m_pIUsbOutputPipe = pIUsbPipe; + } + else + { + pIUsbPipe->DeleteWdfObject(); + } + + SAFE_RELEASE(pIUsbPipe); //release creation reference + } + } + + if (NULL == m_pIUsbInputPipe || NULL == m_pIUsbOutputPipe) + { + hr = E_UNEXPECTED; + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Input or output pipe not found, returning %!HRESULT!", + hr + ); + } + } + + SAFE_RELEASE(pIUsbTargetFactory); + + return hr; +} + +HRESULT +CMyDevice::ConfigureUsbPipes( + ) +/*++ + +Routine Description: + + This routine retrieves the IDs for the bulk end points of the USB device. + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr = S_OK; + LONG timeout; + + // + // Set timeout policies for input/output pipes + // + + if (SUCCEEDED(hr)) + { + timeout = ENDPOINT_TIMEOUT; + + hr = m_pIUsbInputPipe->SetPipePolicy(PIPE_TRANSFER_TIMEOUT, + sizeof(timeout), + &timeout); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to set timeout policy for input pipe %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + timeout = ENDPOINT_TIMEOUT; + + hr = m_pIUsbOutputPipe->SetPipePolicy(PIPE_TRANSFER_TIMEOUT, + sizeof(timeout), + &timeout); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to set timeout policy for output pipe %!HRESULT!", + hr + ); + } + } + + return hr; +} + +HRESULT +CMyDevice::IndicateDeviceReady( + VOID + ) +/*++ + + Routine Description: + + This method lights the period on the device's seven-segment display to + indicate that the driver's PrepareHardware method has completed. + + Arguments: + + None + + Return Value: + + Status + +--*/ +{ + SEVEN_SEGMENT display = {0}; + + HRESULT hr; + + // + // First read the contents of the seven segment display. + // + + hr = GetSevenSegmentDisplay(&display); + + if (SUCCEEDED(hr)) + { + display.Segments |= 0x08; + + hr = SetSevenSegmentDisplay(&display); + } + + return hr; +} + +HRESULT +CMyDevice::GetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + + Routine Description: + + This method synchronously retrieves the bar graph display information + from the OSR USB-FX2 device. It uses the buffers in the FxRequest + to hold the data it retrieves. + + Arguments: + + FxRequest - the request for the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesReturned; + + HRESULT hr = S_OK; + + // + // Zero the contents of the buffer - the controller OR's in every + // light that's set. + // + + BarGraphState->BarsAsUChar = 0; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_BARGRAPH_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) BarGraphState, + sizeof(BAR_GRAPH_STATE), + &bytesReturned + ); + + return hr; +} + +HRESULT +CMyDevice::SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + + Routine Description: + + This method synchronously sets the bar graph display on the OSR USB-FX2 + device using the buffers in the FxRequest as input. + + Arguments: + + FxRequest - the request to set the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesTransferred; + + HRESULT hr = S_OK; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) BarGraphState, + sizeof(BAR_GRAPH_STATE), + &bytesTransferred + ); + + + return hr; +} + +HRESULT +CMyDevice::GetSevenSegmentDisplay( + _In_ PSEVEN_SEGMENT SevenSegment + ) +/*++ + + Routine Description: + + This method synchronously retrieves the bar graph display information + from the OSR USB-FX2 device. It uses the buffers in the FxRequest + to hold the data it retrieves. + + Arguments: + + FxRequest - the request for the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesReturned; + + HRESULT hr = S_OK; + + // + // Zero the output buffer - the device will or in the bits for + // the lights that are set. + // + + SevenSegment->Segments = 0; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_7SEGMENT_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) SevenSegment, + sizeof(SEVEN_SEGMENT), + &bytesReturned + ); + + return hr; +} + +HRESULT +CMyDevice::SetSevenSegmentDisplay( + _In_ PSEVEN_SEGMENT SevenSegment + ) +/*++ + + Routine Description: + + This method synchronously sets the bar graph display on the OSR USB-FX2 + device using the buffers in the FxRequest as input. + + Arguments: + + FxRequest - the request to set the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesTransferred; + + HRESULT hr = S_OK; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_7SEGMENT_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) SevenSegment, + sizeof(SEVEN_SEGMENT), + &bytesTransferred + ); + + return hr; +} + +HRESULT +CMyDevice::ReadSwitchState( + _In_ PSWITCH_STATE SwitchState + ) +/*++ + + Routine Description: + + This method synchronously retrieves the bar graph display information + from the OSR USB-FX2 device. It uses the buffers in the FxRequest + to hold the data it retrieves. + + Arguments: + + FxRequest - the request for the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesReturned; + + HRESULT hr = S_OK; + + // + // Zero the output buffer - the device will or in the bits for + // the lights that are set. + // + + SwitchState->SwitchesAsUChar = 0; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestDeviceToHost, + BmRequestToDevice, + USBFX2LK_READ_SWITCHES, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) SwitchState, + sizeof(SWITCH_STATE), + &bytesReturned + ); + + return hr; +} + +HRESULT +CMyDevice::SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ) +{ + HRESULT hr = S_OK; + HRESULT hrRequest = S_OK; + IWDFIoRequest *pWdfRequest = NULL; + IWDFDriver * FxDriver = NULL; + IWDFMemory * FxMemory = NULL; + IWDFRequestCompletionParams * FxComplParams = NULL; + IWDFUsbRequestCompletionParams * FxUsbComplParams = NULL; + + *LengthTransferred = 0; + + hr = m_FxDevice->CreateRequest( NULL, //pCallbackInterface + NULL, //pParentObject + &pWdfRequest); + hrRequest = hr; + + if (SUCCEEDED(hr)) + { + m_FxDevice->GetDriver(&FxDriver); + + hr = FxDriver->CreatePreallocatedWdfMemory( Buffer, + BufferLength, + NULL, //pCallbackInterface + pWdfRequest, //pParetObject + &FxMemory ); + } + + if (SUCCEEDED(hr)) + { + hr = m_pIUsbTargetDevice->FormatRequestForControlTransfer( pWdfRequest, + SetupPacket, + FxMemory, + NULL); //TransferOffset + } + + if (SUCCEEDED(hr)) + { + hr = pWdfRequest->Send( m_pIUsbTargetDevice, + WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, + 0); //Timeout + } + + if (SUCCEEDED(hr)) + { + pWdfRequest->GetCompletionParams(&FxComplParams); + + hr = FxComplParams->GetCompletionStatus(); + } + + if (SUCCEEDED(hr)) + { + HRESULT hrQI = FxComplParams->QueryInterface(IID_PPV_ARGS(&FxUsbComplParams)); + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI)); + + WUDF_TEST_DRIVER_ASSERT( WdfUsbRequestTypeDeviceControlTransfer == + FxUsbComplParams->GetCompletedUsbRequestType() ); + + FxUsbComplParams->GetDeviceControlTransferParameters( NULL, + LengthTransferred, + NULL, + NULL ); + } + + SAFE_RELEASE(FxUsbComplParams); + SAFE_RELEASE(FxComplParams); + SAFE_RELEASE(FxMemory); + + if (SUCCEEDED(hrRequest)) + { + pWdfRequest->DeleteWdfObject(); + } + SAFE_RELEASE(pWdfRequest); + + SAFE_RELEASE(FxDriver); + + return hr; +} + +WDF_IO_TARGET_STATE +CMyDevice::GetTargetState( + IWDFIoTarget * pTarget + ) +{ + IWDFIoTargetStateManagement * pStateMgmt = NULL; + WDF_IO_TARGET_STATE state; + + HRESULT hrQI = pTarget->QueryInterface(IID_PPV_ARGS(&pStateMgmt)); + WUDF_TEST_DRIVER_ASSERT((SUCCEEDED(hrQI) && pStateMgmt)); + + state = pStateMgmt->GetState(); + + SAFE_RELEASE(pStateMgmt); + + return state; +} + +VOID +CMyDevice::ServiceSwitchChangeQueue( + _In_ SWITCH_STATE NewState, + _In_ HRESULT CompletionStatus, + _In_opt_ IWDFFile *SpecificFile + ) +/*++ + + Routine Description: + + This method processes switch-state change notification requests as + part of reading the OSR device's interrupt pipe. As each read completes + this pulls all pending I/O off the switch change queue and completes + each request with the current switch state. + + Arguments: + + NewState - the state of the switches + + CompletionStatus - all pending operations are completed with this status. + + SpecificFile - if provided only requests for this file object will get + completed. + + Return Value: + + None + +--*/ +{ + IWDFIoRequest *fxRequest; + + HRESULT enumHr = S_OK; + + do + { + HRESULT hr; + + // + // Get the next request. + // + + if (NULL != SpecificFile) + { + enumHr = m_SwitchChangeQueue->RetrieveNextRequestByFileObject( + SpecificFile, + &fxRequest + ); + } + else + { + enumHr = m_SwitchChangeQueue->RetrieveNextRequest(&fxRequest); + } + + // + // if we got one then complete it. + // + + if (SUCCEEDED(enumHr)) + { + if (SUCCEEDED(CompletionStatus)) + { + IWDFMemory *fxMemory; + + // + // First copy the result to the request buffer. + // + + fxRequest->GetOutputMemory(&fxMemory ); + + hr = fxMemory->CopyFromBuffer(0, + &NewState, + sizeof(SWITCH_STATE)); + fxMemory->Release(); + } + else + { + hr = CompletionStatus; + } + + // + // Complete the request with the status of the copy (or the completion + // status if that was an error). + // + + if (SUCCEEDED(hr)) + { + fxRequest->CompleteWithInformation(hr, sizeof(SWITCH_STATE)); + } + else + { + fxRequest->Complete(hr); + } + + fxRequest->Release(); + } + } + while (SUCCEEDED(enumHr)); +} + +HRESULT +CMyDevice::SetPowerManagement( + VOID + ) +/*++ + + Routine Description: + + This method enables the idle and wake functionality + using UMDF. UMDF has been set as the power policy + owner (PPO) for the device stack and we are using power + managed queues. + + Arguments: + + None + + Return Value: + + Status + +--*/ +{ + HRESULT hr; + + // + // Enable USB selective suspend on the device. + // + + hr = m_FxDevice->AssignS0IdleSettings( IdleUsbSelectiveSuspend, + PowerDeviceMaximum, + IDLE_TIMEOUT_IN_MSEC, + IdleAllowUserControl, + WdfUseDefault); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to assign S0 idle settings for the device %!HRESULT!", + hr + ); + } + + // + // Enable Sx wake settings + // + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->AssignSxWakeSettings( PowerDeviceMaximum, + WakeAllowUserControl, + WdfUseDefault); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to set Sx Wake Settings for the device %!HRESULT!", + hr + ); + } + + } + + + return hr; +} + +HRESULT +CMyDevice::OnD0Entry( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + UNREFERENCED_PARAMETER(previousState); + + // + // Start/Stop the I/O target if you support a continuous reader. + // The rest of the I/O is fed through power managed queues. The queue + // itself will stop feeding I/O to targets (and will wait for any pending + // I/O to complete before going into low power state), hence targets + // don�t need to be stopped/started. The continuous reader I/O is outside + // of power managed queues so we need to Stop the I/O target on D0Exit and + // start it on D0Entry. Please note that bulk pipe target doesn't need to + // be stopped/started because I/O submitted to this pipe comes from power + // managed I/O queue, which delivers I/O only in power on state. + // + + m_pIoTargetInterruptPipeStateMgmt->Start(); + + return S_OK; +} + +HRESULT +CMyDevice::OnD0Exit( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + UNREFERENCED_PARAMETER(previousState); + + // + // Stop the I/O target always succeedes. + // + m_pIoTargetInterruptPipeStateMgmt->Stop(WdfIoTargetCancelSentIo); + return S_OK; +} + +void +CMyDevice::OnSurpriseRemoval( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return; +} + +HRESULT +CMyDevice::OnQueryRemove( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CMyDevice::OnQueryStop( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +// +// Self Managed Io Callbacks +// + +VOID +CMyDevice::OnSelfManagedIoCleanup( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return; +} + +VOID +CMyDevice::OnSelfManagedIoFlush( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + + // + // Complete every switch change operation with an error. + // + ServiceSwitchChangeQueue(m_SwitchState, + HRESULT_FROM_WIN32(ERROR_DEVICE_REMOVED), + NULL); + + return; +} + +HRESULT +CMyDevice::OnSelfManagedIoInit( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CMyDevice::OnSelfManagedIoRestart( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CMyDevice::OnSelfManagedIoStop( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CMyDevice::OnSelfManagedIoSuspend( + _In_ IWDFDevice* pWdfDevice + ) +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + + + +HRESULT +CMyDevice::ConfigContReaderForInterruptEndPoint( + VOID + ) +/*++ + +Routine Description: + + This routine configures a continuous reader on the + interrupt endpoint. It's called from the PrepareHarware event. + +Arguments: + + +Return Value: + + HRESULT value + +--*/ +{ + HRESULT hr, hrQI; + IUsbTargetPipeContinuousReaderCallbackReadComplete *pOnCompletionCallback = NULL; + IUsbTargetPipeContinuousReaderCallbackReadersFailed *pOnFailureCallback= NULL; + IWDFUsbTargetPipe2 * pIUsbInterruptPipe2; + + hrQI = this->QueryInterface(IID_PPV_ARGS(&pOnCompletionCallback)); + WUDF_TEST_DRIVER_ASSERT((SUCCEEDED(hrQI) && pOnCompletionCallback)); + + hrQI = this->QueryInterface(IID_PPV_ARGS(&pOnFailureCallback)); + WUDF_TEST_DRIVER_ASSERT((SUCCEEDED(hrQI) && pOnFailureCallback)); + + hrQI = m_pIUsbInterruptPipe->QueryInterface(IID_PPV_ARGS(&pIUsbInterruptPipe2)); + WUDF_TEST_DRIVER_ASSERT((SUCCEEDED(hrQI) && pIUsbInterruptPipe2)); + + // + // 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 the + // parameter CONCURRENT_READS + // + hr = pIUsbInterruptPipe2->ConfigureContinuousReader( sizeof(m_SwitchStateBuffer), + 0,//header + 0,//trailer + CONCURRENT_READS, + NULL, + pOnCompletionCallback, + m_pIUsbInterruptPipe, + pOnFailureCallback + ); + + if (FAILED(hr)) { + TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, + "OsrFxConfigContReaderForInterruptEndPoint failed %!HRESULT!", + hr); + } + + SAFE_RELEASE(pOnCompletionCallback); + SAFE_RELEASE(pOnFailureCallback); + SAFE_RELEASE(pIUsbInterruptPipe2); + + return hr; +} + + +BOOL +CMyDevice::OnReaderFailure( + IWDFUsbTargetPipe * pPipe, + HRESULT hrCompletion + ) +{ + UNREFERENCED_PARAMETER(pPipe); + + m_InterruptReadProblem = hrCompletion; + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Failure completed with %!HRESULT!", + hrCompletion + ); + + ServiceSwitchChangeQueue(m_SwitchState, + hrCompletion, + NULL); + + return TRUE; +} + +VOID +CMyDevice::OnReaderCompletion( + IWDFUsbTargetPipe * pPipe, + IWDFMemory * pMemory, + SIZE_T NumBytesTransferred, + PVOID Context + ) +{ + WUDF_TEST_DRIVER_ASSERT(pPipe == (IWDFUsbTargetPipe *)Context); + + // + // 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_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Zero length read occured on the Interrupt Pipe's " + "Continuous Reader\n" + ); + return; + } + + WUDF_TEST_DRIVER_ASSERT(NumBytesTransferred == sizeof(m_SwitchState)); + + // + // Get the switch state + // + + PVOID pBuff = pMemory->GetDataBuffer(NULL); + + CopyMemory(&m_SwitchState, pBuff, sizeof(m_SwitchState)); + + + // + // Satisfy application request for switch change notification + // + + ServiceSwitchChangeQueue(m_SwitchState, + S_OK, + NULL); + + // + // Make sure that the request that got completed is the one that we reuse + // Don't Delete the request because it gets reused + // +} + + +HRESULT +CMyDevice::GetBusTypeGuid( + VOID + ) +/*++ + + Routine Description: + + This routine gets the device instance ID then invokes SetupDi to + retrieve the bus type guid for the device. The bus type guid is + stored in object. + + Arguments: + + None + + Return Value: + + Status + +--*/ +{ + ULONG instanceIdCch = 0; + PWSTR instanceId = NULL; + + HDEVINFO deviceInfoSet = NULL; + SP_DEVINFO_DATA deviceInfo = {sizeof(SP_DEVINFO_DATA)}; + + HRESULT hr; + + // + // Retrieve the device instance ID. + // + + hr = m_FxDevice->RetrieveDeviceInstanceId(NULL, &instanceIdCch); + + if (FAILED(hr)) + { + goto Exit; + } + + instanceId = new WCHAR[instanceIdCch]; + + if (instanceId == NULL) + { + hr = E_OUTOFMEMORY; + goto Exit; + } + + hr = m_FxDevice->RetrieveDeviceInstanceId(instanceId, &instanceIdCch); + + if (FAILED(hr)) + { + goto Exit2; + } + + // + // Call SetupDI to open the device info. + // + + deviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL); + + if (deviceInfoSet == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto Exit2; + } + + if (SetupDiOpenDeviceInfo(deviceInfoSet, + instanceId, + NULL, + 0, + &deviceInfo) == FALSE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto Exit3; + } + + if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, + &deviceInfo, + SPDRP_BUSTYPEGUID, + NULL, + (PBYTE) &m_BusTypeGuid, + sizeof(m_BusTypeGuid), + NULL) == FALSE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto Exit3; + } + +Exit3: + SetupDiDestroyDeviceInfoList(deviceInfoSet); + +Exit2: + + delete[] instanceId; + +Exit: + + return hr; +} + +HRESULT +CMyDevice::PlaybackFile( + _In_ PFILE_PLAYBACK PlayInfo, + _In_ IWDFIoRequest *FxRequest + ) +/*++ + + Routine Description: + + This method impersonates the caller, opens the file and prints each + character to the seven segement display. + + Arguments: + + PlayInfo - the playback info from the request. + + FxRequest - the request (used for impersonation) + + Return Value: + + Status + +--*/ + +{ + PLAYBACK_IMPERSONATION_CONTEXT context = {PlayInfo, NULL, S_OK}; + IWDFIoRequest2* fxRequest2; + + HRESULT hr; + + // Convert FxRequest to FxRequest2. No error can occur here. + FxRequest->QueryInterface(IID_PPV_ARGS(&fxRequest2)); + _Analysis_assume_(fxRequest2 != NULL); + + // + // Impersonate and open the playback file. + // + + hr = FxRequest->Impersonate( + SecurityImpersonation, + this->QueryIImpersonateCallback(), + &context + ); + if (FAILED(hr)) + { + goto exit; + } + + // + // Release the reference that was added in QueryIImpersonateCallback() + // + this->Release(); + + hr = context.Hr; + + if (FAILED(hr)) + { + goto exit; + } + + // + // The impersonation callback succeeded - tell code analysis that the + // file handle is non-null + // + + _Analysis_assume_(context.FileHandle != NULL); + + // + // Read from the file one character at a time until we hit + // EOF or the request is cancelled. + // + + do + { + UCHAR c; + ULONG bytesRead; + + // + // Check for cancellation. + // + + if (fxRequest2->IsCanceled()) + { + hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); + } + else + { + BOOL result; + + // + // Read a character from the file and see if we can + // encode it on the display. + // + + result = ReadFile(context.FileHandle, + &c, + sizeof(c), + &bytesRead, + NULL); + + if (result) + { + SEVEN_SEGMENT segment; + BAR_GRAPH_STATE barGraph; + + if (bytesRead > 0) + { + #pragma prefast(suppress:__WARNING_USING_UNINIT_VAR,"Above this->Release() method does not actually free 'this'") + if(EncodeSegmentValue(c, &segment) == true) + { + barGraph.BarsAsUChar = c; + + SetSevenSegmentDisplay(&segment); + SetBarGraphDisplay(&barGraph); + } + + Sleep(PlayInfo->Delay); + } + else + { + hr = S_OK; + break; + } + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + } + + } while(SUCCEEDED(hr)); + + CloseHandle(context.FileHandle); + +exit: + + fxRequest2->Release(); + return hr; +} + +VOID +CMyDevice::OnImpersonate( + _In_ PVOID Context + ) +/*++ + + Routine Description: + + This routine handles the impersonation for the PLAY FILE I/O control. + + Arguments: + + Context - pointer to the impersonation context + + Return Value: + + None + +--*/ +{ + PPLAYBACK_IMPERSONATION_CONTEXT context; + + context = (PPLAYBACK_IMPERSONATION_CONTEXT) Context; + + context->FileHandle = CreateFile(context->PlaybackInfo->Path, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (context->FileHandle == INVALID_HANDLE_VALUE) + { + DWORD error = GetLastError(); + context->Hr = HRESULT_FROM_WIN32(error); + } + else + { + context->Hr = S_OK; + } + + return; +} + +#define SS_LEFT (SS_TOP_LEFT | SS_BOTTOM_LEFT) +#define SS_RIGHT (SS_TOP_RIGHT | SS_BOTTOM_RIGHT) + +bool +CMyDevice::EncodeSegmentValue( + _In_ UCHAR Character, + _Out_ SEVEN_SEGMENT *SevenSegment + ) +{ + UCHAR letterMap[] = { + (SS_TOP | SS_BOTTOM_LEFT | SS_RIGHT | SS_CENTER | SS_BOTTOM), // a + (SS_LEFT | SS_CENTER | SS_BOTTOM | SS_BOTTOM_RIGHT), // b + (SS_CENTER | SS_BOTTOM_LEFT | SS_BOTTOM), // c + (SS_BOTTOM_LEFT | SS_CENTER | SS_BOTTOM | SS_RIGHT), // d + (SS_LEFT | SS_TOP | SS_CENTER | SS_BOTTOM), // e + (SS_LEFT | SS_TOP | SS_CENTER), // f + (SS_TOP | SS_TOP_LEFT | SS_CENTER | SS_BOTTOM | SS_RIGHT), // g + (SS_LEFT | SS_RIGHT | SS_CENTER), // h + (SS_BOTTOM_LEFT), // i + (SS_BOTTOM | SS_RIGHT), // j + (SS_LEFT | SS_CENTER | SS_BOTTOM), // k + (SS_LEFT | SS_BOTTOM), // l + (SS_LEFT | SS_TOP | SS_RIGHT), // m + (SS_BOTTOM_LEFT | SS_CENTER | SS_BOTTOM_RIGHT), // n + (SS_BOTTOM_LEFT | SS_BOTTOM_RIGHT | SS_CENTER | SS_BOTTOM), // o + (SS_LEFT | SS_TOP | SS_CENTER | SS_TOP_RIGHT), // p + (SS_TOP_LEFT | SS_TOP | SS_CENTER | SS_RIGHT), // q + (SS_BOTTOM_LEFT | SS_CENTER), // r + (SS_TOP_LEFT | + SS_TOP | SS_CENTER | SS_BOTTOM | + SS_BOTTOM_RIGHT), // s + (SS_TOP | SS_RIGHT), // t + (SS_LEFT | SS_RIGHT | SS_BOTTOM), // u + (SS_BOTTOM_LEFT | SS_BOTTOM | SS_BOTTOM_RIGHT), // v + (SS_LEFT | SS_BOTTOM | SS_BOTTOM_RIGHT), // w + (SS_LEFT | SS_CENTER | SS_RIGHT), // x + (SS_TOP_LEFT | SS_CENTER | SS_RIGHT), // y + (SS_TOP_RIGHT | + SS_TOP | SS_CENTER | SS_BOTTOM | + SS_BOTTOM_LEFT), // z + }; + + UCHAR numberMap[] = { + (SS_LEFT | SS_TOP | SS_BOTTOM | SS_RIGHT | SS_DOT), // 0 + (SS_RIGHT | SS_DOT), // 1 + (SS_TOP | + SS_TOP_RIGHT | SS_CENTER | SS_BOTTOM_LEFT | + SS_BOTTOM | SS_DOT), // 2 + (SS_TOP | SS_CENTER | SS_BOTTOM | SS_RIGHT | SS_DOT), // 3 + (SS_TOP_LEFT | SS_CENTER | SS_RIGHT | SS_DOT), // 4 + (SS_TOP_LEFT | + SS_TOP | SS_CENTER | SS_BOTTOM | + SS_BOTTOM_RIGHT | SS_DOT), // 5 + (SS_TOP | SS_CENTER | SS_BOTTOM | + SS_LEFT | SS_BOTTOM_RIGHT | SS_DOT), // 6 + (SS_TOP | SS_RIGHT | SS_DOT), // 7 + (SS_TOP | SS_BOTTOM | SS_CENTER | + SS_LEFT | SS_RIGHT | SS_DOT), // 8 + (SS_TOP_LEFT | SS_TOP | SS_CENTER | SS_RIGHT | SS_DOT), // 9 + }; + + if (((Character >= 'a') && (Character <= 'z')) || + ((Character >= 'A') && (Character <= 'Z'))) + { + SevenSegment->Segments = letterMap[tolower(Character) - 'a']; + return true; + } + else if ((Character >= '0') && (Character <= '9')) + { + SevenSegment->Segments = numberMap[Character - '0']; + return true; + } + else + { + SevenSegment->Segments = 0; + return false; + } +} + diff --git a/usb/umdf_filter_umdf/umdf_driver/Device.h b/usb/umdf_filter_umdf/umdf_driver/Device.h new file mode 100644 index 00000000..641a04de --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/Device.h @@ -0,0 +1,604 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF OSR Fx2 sample + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once +#include "internal.h" + +#define ENDPOINT_TIMEOUT 10000 +#define NUM_OSRUSB_ENDPOINTS 3 + +// +// 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 + +typedef struct { + UCHAR Segments; +} SEVEN_SEGMENT, *PSEVEN_SEGMENT; + +// +// Context for the impersonation callback. +// + +typedef struct +{ + PFILE_PLAYBACK PlaybackInfo; + + HANDLE FileHandle; + + HRESULT Hr; +} PLAYBACK_IMPERSONATION_CONTEXT, *PPLAYBACK_IMPERSONATION_CONTEXT; + +// +// Class for the driver. +// + +class CMyDevice : + public CUnknown, + public IPnpCallbackHardware, + public IPnpCallback, + public IPnpCallbackSelfManagedIo, + public IUsbTargetPipeContinuousReaderCallbackReadersFailed, + public IUsbTargetPipeContinuousReaderCallbackReadComplete, + public IImpersonateCallback +{ +// +// Private data members. +// +private: + // + // Weak reference to framework device + // Use IWDFDevice2 so we can set power policy settings + // + IWDFDevice2 *m_FxDevice; + + // + // Weak reference to the control queue + // + PCMyReadWriteQueue m_ReadWriteQueue; + + // + // Weak reference to the control queue + // + PCMyControlQueue m_ControlQueue; + + // + // The bus type for this device (used here for + // illustrative purposes only) + // + + GUID m_BusTypeGuid; + + // + // USB Device I/O Target + // + IWDFUsbTargetDevice * m_pIUsbTargetDevice; + + // + // USB Interface + // + IWDFUsbInterface * m_pIUsbInterface; + + // + // USB Input pipe for Reads + // + IWDFUsbTargetPipe * m_pIUsbInputPipe; + + // + // USB Output pipe for writes + // + IWDFUsbTargetPipe * m_pIUsbOutputPipe; + + // + // USB interrupt pipe + // + IWDFUsbTargetPipe * m_pIUsbInterruptPipe; + + // + // Use I/O target state management interfaces if you are going to + // support a continuous reader. + // + + // + // USB interrupt pipe state management + // + IWDFIoTargetStateManagement * m_pIoTargetInterruptPipeStateMgmt; + + // + // Device Speed (Low, Full, High) + // + UCHAR m_Speed; + + // + // Current switch state + // + SWITCH_STATE m_SwitchState; + + // + // Request to be used for pending reads from interrupt pipe + // (to get switch state change notifications) + // + + IWDFIoRequest * m_RequestForPendingRead; + + // + // If reads stopped because of a transient problem, the error status + // is stored here. + // + + HRESULT m_InterruptReadProblem; + + // + // Switch state buffer - this might hold the transient value + // m_SwitchState holds stable value of the switch state + // + SWITCH_STATE m_SwitchStateBuffer; + + // + // A manual queue to hold requests for changes in the I/O switch state. + // + + IWDFIoQueue * m_SwitchChangeQueue; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) : + m_FxDevice(NULL), + m_ControlQueue(NULL), + m_ReadWriteQueue(NULL), + m_SwitchChangeQueue(NULL), + m_pIUsbTargetDevice(NULL), + m_pIUsbInterface(NULL), + m_pIUsbInputPipe(NULL), + m_pIUsbOutputPipe(NULL), + m_pIUsbInterruptPipe(NULL), + m_Speed(0), + m_InterruptReadProblem(S_OK), + m_RequestForPendingRead(NULL), + m_pIoTargetInterruptPipeStateMgmt(NULL) + { + ZeroMemory(&m_BusTypeGuid, sizeof(m_BusTypeGuid)); + } + + ~CMyDevice( + ); + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + // + // Helper methods + // + + HRESULT + GetBusTypeGuid( + VOID + ); + + HRESULT + CreateUsbIoTargets( + VOID + ); + + + HRESULT + ConfigureUsbPipes( + ); + + HRESULT + SetPowerManagement( + VOID + ); + + HRESULT + IndicateDeviceReady( + VOID + ); + + // + // Helper functions + // + + HRESULT + SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ); + + static + WDF_IO_TARGET_STATE + GetTargetState( + IWDFIoTarget * pTarget + ); + + VOID + ServiceSwitchChangeQueue( + _In_ SWITCH_STATE NewState, + _In_ HRESULT CompletionStatus, + _In_opt_ IWDFFile *SpecificFile + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + HRESULT + Configure( + VOID + ); + + IPnpCallback * + QueryIPnpCallback( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallback *>(this); + } + + IPnpCallbackHardware * + QueryIPnpCallbackHardware( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackHardware *>(this); + } + + IPnpCallbackSelfManagedIo * + QueryIPnpCallbackSelfManagedIo( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackSelfManagedIo *>(this); + } + + + IUsbTargetPipeContinuousReaderCallbackReadersFailed * + QueryContinousReaderFailureCompletion( + VOID + ) + { + AddRef(); + return static_cast<IUsbTargetPipeContinuousReaderCallbackReadersFailed *>(this); + } + + IUsbTargetPipeContinuousReaderCallbackReadComplete * + QueryContinousReaderCompletion( + VOID + ) + { + AddRef(); + return static_cast<IUsbTargetPipeContinuousReaderCallbackReadComplete *>(this); + } + + IImpersonateCallback * + QueryIImpersonateCallback( + VOID + ) + { + AddRef(); + return static_cast<IImpersonateCallback *>(this); + } + + HRESULT + GetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ); + + HRESULT + SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ); + + HRESULT + GetSevenSegmentDisplay( + _In_ PSEVEN_SEGMENT SevenSegment + ); + + HRESULT + SetSevenSegmentDisplay( + _In_ PSEVEN_SEGMENT SevenSegment + ); + + HRESULT + ReadSwitchState( + _In_ PSWITCH_STATE SwitchState + ); + + bool + EncodeSegmentValue( + _In_ UCHAR Character, + _Out_ SEVEN_SEGMENT *SevenSegment + ); + + HRESULT + PlaybackFile( + _In_ PFILE_PLAYBACK PlaybackInfo, + _In_ IWDFIoRequest *FxRequest + ); + + // + //returns a weak reference to the target USB device + //DO NOT release it + // + IWDFUsbTargetDevice * + GetUsbTargetDevice( + ) + { + return m_pIUsbTargetDevice; + } + + // + //returns a weak reference to input pipe + //DO NOT release it + // + IWDFUsbTargetPipe * + GetInputPipe( + ) + { + return m_pIUsbInputPipe; + } + + // + //returns a weak reference to output pipe + //DO NOT release it + // + IWDFUsbTargetPipe * + GetOutputPipe( + ) + { + return m_pIUsbOutputPipe; + } + + IWDFIoQueue * + GetSwitchChangeQueue( + VOID + ) + { + return m_SwitchChangeQueue; + } + + PSWITCH_STATE + GetCurrentSwitchState( + VOID + ) + { + return &m_SwitchState; + } + + + HRESULT + ConfigContReaderForInterruptEndPoint( + VOID + ); +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IPnpCallbackHardware + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnPrepareHardware( + _In_ IWDFDevice *FxDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnReleaseHardware( + _In_ IWDFDevice *FxDevice + ); + + + // + // IPnpCallback + // + virtual + HRESULT + STDMETHODCALLTYPE + OnD0Entry( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnD0Exit( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ); + + virtual + void + STDMETHODCALLTYPE + OnSurpriseRemoval( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnQueryRemove( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnQueryStop( + _In_ IWDFDevice* pWdfDevice + ); + + // + // IPnpCallbackSelfManagedIo + // + virtual + VOID + STDMETHODCALLTYPE + OnSelfManagedIoCleanup( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + VOID + STDMETHODCALLTYPE + OnSelfManagedIoFlush( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoInit( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoRestart( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoStop( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoSuspend( + _In_ IWDFDevice* pWdfDevice + ); + + // + // IUsbTargetPipeContinuousReaderCallbackReadersFailed + // + virtual + BOOL + STDMETHODCALLTYPE + OnReaderFailure( + IWDFUsbTargetPipe * pPipe, + HRESULT hrCompletion + ); + + // + // IUsbTargetPipeContinuousReaderCallbackReadComplete + // + virtual + VOID + STDMETHODCALLTYPE + OnReaderCompletion( + IWDFUsbTargetPipe * pPipe, + IWDFMemory * pMemory, + SIZE_T NumBytesTransferred, + PVOID Context + ); + + // IImpersonateCallback + virtual + VOID + STDMETHODCALLTYPE + OnImpersonate( + _In_ PVOID Context + ); +}; + diff --git a/usb/umdf_filter_umdf/umdf_driver/Driver.cpp b/usb/umdf_filter_umdf/umdf_driver/Driver.cpp new file mode 100644 index 00000000..d6635242 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/Driver.cpp @@ -0,0 +1,220 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR Fx2 driver's + core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/umdf_filter_umdf/umdf_driver/Driver.h b/usb/umdf_filter_umdf/umdf_driver/Driver.h new file mode 100644 index 00000000..d9cafb4e --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/Driver.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF OSR Fx2 sample's + driver callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the OSR Fx2 sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.ctl b/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.ctl new file mode 100644 index 00000000..4dab56ae --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.ctl @@ -0,0 +1 @@ +da5fbdfd-1eae-4ecf-b426-a3818f325ddb WudfOsrUsbFx2TraceGuid diff --git a/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.rc b/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.rc new file mode 100644 index 00000000..36f10ea9 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/OsrUsbFx2.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// OsrUsbDevice.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OSR USB Fx2 User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "WUDFOsrUsbFx2" +#define VER_ORIGINALFILENAME_STR "WUDFOsrUsbFx2.dll" + +#include "common.ver" diff --git a/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.cpp b/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.cpp new file mode 100644 index 00000000..46144829 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.cpp @@ -0,0 +1,425 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "ReadWriteQueue.tmh" + +VOID +CMyReadWriteQueue::OnCompletion( + _In_ IWDFIoRequest* pWdfRequest, + _In_ IWDFIoTarget* pIoTarget, + _In_ IWDFRequestCompletionParams* pParams, + _In_ PVOID pContext + ) +{ + UNREFERENCED_PARAMETER(pIoTarget); + UNREFERENCED_PARAMETER(pContext); + + pWdfRequest->CompleteWithInformation( + pParams->GetCompletionStatus(), + pParams->GetInformation() + ); +} + +void +CMyReadWriteQueue::ForwardFormattedRequest( + _In_ IWDFIoRequest* pRequest, + _In_ IWDFIoTarget* pIoTarget + ) +{ + // + //First set the completion callback + // + + IRequestCallbackRequestCompletion * pCompletionCallback = NULL; + HRESULT hrQI = this->QueryInterface(IID_PPV_ARGS(&pCompletionCallback)); + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && (NULL != pCompletionCallback)); + + pRequest->SetCompletionCallback( + pCompletionCallback, + NULL + ); + + pCompletionCallback->Release(); + pCompletionCallback = NULL; + + // + //Send down the request + // + + HRESULT hrSend = S_OK; + hrSend = pRequest->Send(pIoTarget, + 0, //flags + 0); //timeout + + if (FAILED(hrSend)) + { + pRequest->CompleteWithInformation(hrSend, 0); + } + + return; +} + + +CMyReadWriteQueue::CMyReadWriteQueue( + _In_ PCMyDevice Device + ) : + CMyQueue(Device) +{ +} + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// + +CMyReadWriteQueue::~CMyReadWriteQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Aruments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC! Entry" + ); + +} + + +HRESULT +STDMETHODCALLTYPE +CMyReadWriteQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) + { + hr = S_OK; + *Object = QueryIQueueCallbackWrite(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackRead))) + { + hr = S_OK; + *Object = QueryIQueueCallbackRead(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IRequestCallbackRequestCompletion))) + { + hr = S_OK; + *Object = QueryIRequestCallbackRequestCompletion(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackIoStop))) + { + hr = S_OK; + *Object = QueryIQueueCallbackIoStop(); + } + else + { + hr = CMyQueue::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyReadWriteQueue::CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyReadWriteQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Aruments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + PCMyReadWriteQueue queue; + HRESULT hr = S_OK; + + queue = new CMyReadWriteQueue(Device); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Call the queue callback object to initialize itself. This will create + // its partner queue framework object. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(); + } + + if (SUCCEEDED(hr)) + { + *Queue = queue; + } + else + { + SAFE_RELEASE(queue); + } + + return hr; +} + +HRESULT +CMyReadWriteQueue::Initialize( + ) +{ + HRESULT hr; + + // + // First initialize the base class. This will create the partner FxIoQueue + // object and setup automatic forwarding of I/O controls. + // + + hr = __super::Initialize(WdfIoQueueDispatchParallel, + true, + true); + + // + // return the status. + // + + return hr; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnWrite( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T BytesToWrite + ) +/*++ + +Routine Description: + + + Write dispatch routine + IQueueCallbackWrite + +Aruments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + BytesToWrite - Lenth of bytes in the write buffer + + Allocate and copy data to local buffer +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n", + this, + pWdfRequest, + (ULONG)(ULONG_PTR)BytesToWrite + ); + + HRESULT hr = S_OK; + IWDFMemory * pInputMemory = NULL; + IWDFUsbTargetPipe * pOutputPipe = m_Device->GetOutputPipe(); + + pWdfRequest->GetInputMemory(&pInputMemory); + + hr = pOutputPipe->FormatRequestForWrite( + pWdfRequest, + NULL, //pFile + pInputMemory, + NULL, //Memory offset + NULL //DeviceOffset + ); + + if (FAILED(hr)) + { + pWdfRequest->Complete(hr); + } + else + { + ForwardFormattedRequest(pWdfRequest, pOutputPipe); + } + + SAFE_RELEASE(pInputMemory); + + return; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnRead( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T BytesToRead + ) +/*++ + +Routine Description: + + + Read dispatch routine + IQueueCallbackRead + +Aruments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + BytesToRead - Lenth of bytes in the read buffer + + Copy available data into the read buffer +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n", + this, + pWdfRequest, + (ULONG)(ULONG_PTR)BytesToRead + ); + + HRESULT hr = S_OK; + IWDFMemory * pOutputMemory = NULL; + + pWdfRequest->GetOutputMemory(&pOutputMemory); + + hr = m_Device->GetInputPipe()->FormatRequestForRead( + pWdfRequest, + NULL, //pFile + pOutputMemory, + NULL, //Memory offset + NULL //DeviceOffset + ); + + if (FAILED(hr)) + { + pWdfRequest->Complete(hr); + } + else + { + ForwardFormattedRequest(pWdfRequest, m_Device->GetInputPipe()); + } + + SAFE_RELEASE(pOutputMemory); + + return; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnIoStop( + _In_ IWDFIoQueue * pWdfQueue, + _In_ IWDFIoRequest * pWdfRequest, + _In_ ULONG ActionFlags + ) +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + + // + // The driver owns the request and no locking constraint is safe for + // the queue callbacks + // + if (ActionFlags == WdfRequestStopActionSuspend ) + { + IWDFIoRequest2 * request2 = NULL; + HRESULT hr; + + hr = pWdfRequest->QueryInterface(IID_PPV_ARGS(&request2)); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC!: Failed to QI for IWDFIoRequest2: %!hresult!", + hr); + return; + } + + request2->StopAcknowledge(FALSE); //don't requeue + SAFE_RELEASE(request2); + } + else if(ActionFlags == WdfRequestStopActionPurge) + { + // + // Cancel the sent request since we are asked to purge the request + // + + pWdfRequest->CancelSentRequest(); + } + + return; +} + diff --git a/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.h b/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.h new file mode 100644 index 00000000..4f1a98c1 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/ReadWriteQueue.h @@ -0,0 +1,163 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + + +#define MAX_TRANSFER_SIZE(x) 64*1024*1024 + +// +// Queue Callback Object. +// + +class CMyReadWriteQueue : + public IQueueCallbackRead, + public IQueueCallbackWrite, + public IRequestCallbackRequestCompletion, + public IQueueCallbackIoStop, + public CMyQueue +{ +protected: + HRESULT + Initialize( + ); + + void + ForwardFormattedRequest( + _In_ IWDFIoRequest* pRequest, + _In_ IWDFIoTarget* pIoTarget + ); + +public: + + CMyReadWriteQueue( + _In_ PCMyDevice Device + ); + + virtual ~CMyReadWriteQueue(); + + static + HRESULT + CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyReadWriteQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return CMyQueue::Configure(); + } + + IQueueCallbackWrite * + QueryIQueueCallbackWrite( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackWrite *>(this); + } + + IQueueCallbackRead * + QueryIQueueCallbackRead( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackRead *>(this); + } + + IRequestCallbackRequestCompletion * + QueryIRequestCallbackRequestCompletion( + VOID + ) + { + AddRef(); + return static_cast<IRequestCallbackRequestCompletion *>(this); + } + + IQueueCallbackIoStop* + QueryIQueueCallbackIoStop( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackIoStop *>(this); + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + + // + // Wdf Callbacks + // + + // + // IQueueCallbackWrite + // + STDMETHOD_ (void, OnWrite)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToWrite + ); + + // + // IQueueCallbackRead + // + STDMETHOD_ (void, OnRead)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToRead + ); + + // + //IRequestCallbackRequestCompletion + // + + STDMETHOD_ (void, OnCompletion)( + _In_ IWDFIoRequest* pWdfRequest, + _In_ IWDFIoTarget* pIoTarget, + _In_ IWDFRequestCompletionParams* pParams, + _In_ PVOID pContext + ); + + // + //IQueueCallbackIoStop + // + + STDMETHOD_ (void, OnIoStop)( + _In_ IWDFIoQueue * pWdfQueue, + _In_ IWDFIoRequest * pWdfRequest, + _In_ ULONG ActionFlags + ); + +}; diff --git a/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj new file mode 100644 index 00000000..e5b2d207 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj @@ -0,0 +1,270 @@ +<?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>{0D3781C2-2236-46B0-806D-387999E500AB}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{C4216905-C3FE-44F7-A5AD-0987922D565E}</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>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</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="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp; queue.cpp; ControlQueue.cpp; ReadWriteQueue.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <OtherWpp Include="OsrUsbFx2.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFx2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFx2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFx2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFx2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc" /> + </ItemGroup> + <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/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters new file mode 100644 index 00000000..d0c54d1b --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters @@ -0,0 +1,52 @@ +<?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>{ABA4E4AE-18A0-4313-819F-B0D9DDB54C2E}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{E4C135BD-DEBF-4561-8E32-CA099824DFF6}</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>{2CBEC65A-B61D-4E62-9582-AA80C3C538D0}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{8597CA67-53BC-423A-BF33-07316F805E89}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ControlQueue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReadWriteQueue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_umdf/umdf_driver/comsup.cpp b/usb/umdf_filter_umdf/umdf_driver/comsup.cpp new file mode 100644 index 00000000..9c9aec3b --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/umdf_filter_umdf/umdf_driver/comsup.h b/usb/umdf_filter_umdf/umdf_driver/comsup.h new file mode 100644 index 00000000..dedf78c8 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_driver/dllsup.cpp b/usb/umdf_filter_umdf/umdf_driver/dllsup.cpp new file mode 100644 index 00000000..22dfb3b0 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/dllsup.cpp @@ -0,0 +1,202 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR Fx2 + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the driver uses + L"Microsoft\\UMDF\\OsrUsb" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for this sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing, and saves the module handle away in a + global variable so that it can be referenced should the COM registration + code (Dll[Un]RegisterServer) be called. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + UNREFERENCED_PARAMETER(ModuleHandle); + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllCanUnloadNow( + VOID + ) +/*++ + + Routine Description: + + Called by the COM runtime when determining whether or not this module + can be unloaded. Our answer is always "no". + + Arguments: + + None + + Return Value: + + S_FALSE + +--*/ +{ + return S_FALSE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + OSR Fx2 driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} diff --git a/usb/umdf_filter_umdf/umdf_driver/exports.def b/usb/umdf_filter_umdf/umdf_driver/exports.def new file mode 100644 index 00000000..15f923d3 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/exports.def @@ -0,0 +1,4 @@ +; WudfOsrUsbDriver.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/umdf_filter_umdf/umdf_driver/internal.h b/usb/umdf_filter_umdf/umdf_driver/internal.h new file mode 100644 index 00000000..2d57793d --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/internal.h @@ -0,0 +1,170 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF OSR Fx2 + driver sample. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF Headers +// + +#include "wudfddi.h" + +// +// Include SetupDi functions. +// + +#include "setupapi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Include the safestring functions. +// + +#include "strsafe.h" + +// +// Get limits on common data types (ULONG_MAX for example) +// + +#include "limits.h" + +// +// We need usb I/O targets to talk to the OSR device. +// + +#include "wudfusb.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "public.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "WUDFOsrUsbPublic.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +typedef class CMyControlQueue *PCMyControlQueue; +typedef class CMyReadWriteQueue *PCMyReadWriteQueue; + +typedef class CCancelCallback *PCCancelCallback; + +// +// Define the tracing flags. +// +// TODO: Choose a different trace control GUID +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + WudfOsrUsbFx2TraceGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TEST_TRACE_DRIVER) \ + WPP_DEFINE_BIT(TEST_TRACE_DEVICE) \ + WPP_DEFINE_BIT(TEST_TRACE_QUEUE) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#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) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// +// TODO: Change these values to be appropriate for your driver. +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsb" +#define MYDRIVER_CLASS_ID {0x0865b2b0, 0x6b73, 0x428f, {0xa3, 0xea, 0x21, 0x72, 0x83, 0x2d, 0x6b, 0xfc}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" +#include "ControlQueue.h" +#include "ReadWriteQueue.h" +#include "list.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} + +#define IDLE_TIMEOUT_IN_MSEC 10*1000 diff --git a/usb/umdf_filter_umdf/umdf_driver/queue.cpp b/usb/umdf_filter_umdf/umdf_driver/queue.cpp new file mode 100644 index 00000000..c56b38bb --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/queue.cpp @@ -0,0 +1,147 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "queue.tmh" + +CMyQueue::CMyQueue( + _In_ PCMyDevice Device + ) : + m_FxQueue(NULL), + m_Device(Device) +{ +} + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// + +CMyQueue::~CMyQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Aruments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC! Entry" + ); + +} + + +HRESULT +STDMETHODCALLTYPE +CMyQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + hr = CUnknown::QueryInterface(InterfaceId, Object); + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyQueue::Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ) +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Create the I/O Queue object. + // + + { + IUnknown *callback = QueryIUnknown(); + + hr = m_Device->GetFxDevice()->CreateIoQueue( + callback, + Default, + DispatchType, + PowerManaged, + FALSE, + &fxQueue + ); + callback->Release(); + } + + if (SUCCEEDED(hr)) + { + m_FxQueue = fxQueue; + + // + // Release the creation reference on the queue. This object will be + // destroyed before the queue so we don't need to have a reference out + // on it. + // + + fxQueue->Release(); + } + + return hr; +} + +HRESULT +CMyQueue::Configure( + VOID + ) +{ + return S_OK; +} diff --git a/usb/umdf_filter_umdf/umdf_driver/queue.h b/usb/umdf_filter_umdf/umdf_driver/queue.h new file mode 100644 index 00000000..5659224b --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_driver/queue.h @@ -0,0 +1,93 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyQueue : + public CUnknown +{ +protected: + // + // Unreferenced pointer to the partner Fx device. + // + + IWDFIoQueue *m_FxQueue; + + // + // Unreferenced pointer to the parent device. + // + + PCMyDevice m_Device; + + HRESULT + Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ); + +protected: + + CMyQueue( + _In_ PCMyDevice Device + ); + + virtual ~CMyQueue(); + + HRESULT + Configure( + VOID + ); + +public: + + IWDFIoQueue * + GetFxQueue( + VOID + ) + { + return m_FxQueue; + } + + + PCMyDevice + GetDevice( + VOID + ) + { + return m_Device; + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_filter/OsrUsbFilter.rc b/usb/umdf_filter_umdf/umdf_filter/OsrUsbFilter.rc new file mode 100644 index 00000000..cec032d9 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/OsrUsbFilter.rc @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------- +// OsrUsbFilter.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OsrUsbFilter User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "OsrUsbFilter" +#define VER_ORIGINALFILENAME_STR "OsrUsbFilter.dll" + +#include "common.ver" diff --git a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj new file mode 100644 index 00000000..4968db88 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj @@ -0,0 +1,287 @@ +<?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>{E62A4AAA-870E-4D58-AA10-D9604A2E52E8}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A09CF05A-0501-47A9-98B5-48C0A9487ECA}</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>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</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="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp; queue.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <Inf Include="WUDFOsrUsbFilterOnUmFx2Driver.inx"> + <Architecture>$(InfArch)</Architecture> + <SpecifyArchitecture>true</SpecifyArchitecture> + <CopyOutput>.\$(IntDir)\WUDFOsrUsbFilterOnUmFx2Driver.Inf</CopyOutput> + </Inf> + <OtherWpp Include="OsrUsbFilter.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFilter</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFilter.rc" /> + </ItemGroup> + <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/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters new file mode 100644 index 00000000..f92d33fa --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters @@ -0,0 +1,51 @@ +<?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>{AFBD23B1-572F-4E48-B155-B32902A4661E}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{A72AB5BE-0993-4901-8D44-E3AC062578E8}</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>{3D0316D0-D4C5-4718-8634-6072A187C604}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{10BE8A0E-56B7-4329-8582-2BB1E16F94E1}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <Inf Include="WUDFOsrUsbFilterOnUmFx2Driver.inx"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFilter.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx new file mode 100644 index 00000000..fd920e03 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx @@ -0,0 +1,114 @@ +; +; WUDFOsrUsbFilterOnUmDriver.inf - Install a UM Filter driver on the OSR + USB Device. +; + +[Version] +Signature="$Windows NT$" +Class=Sample +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} +Provider=%MSFTUMDF% +DriverVer=03/25/2005,0.0.0.1 +CatalogFile=wudf.cat + +[Manufacturer] +%MSFTUMDF%=Microsoft,NT$ARCH$ + +[Microsoft.NT$ARCH$] +%OsrUsbDeviceName%=OsrUsb_Install, USB\Vid_045e&Pid_94aa&mi_00 +%OsrUsbDeviceName%=OsrUsb_Install, USB\VID_0547&PID_1002 + +[ClassInstall32] +AddReg=SampleClass_RegistryAdd + +[SampleClass_RegistryAdd] +HKR,,,,%ClassName% +HKR,,Icon,,"-10" + +[SourceDisksFiles] +WudfOsrUsbFilter.dll=1 +WudfOsrUsbFx2.dll=1 +WudfUpdate_$UMDFCOINSTALLERVERSION$.dll=1 + +[SourceDisksNames] +1 = %MediaDescription% + +; =================== UMDF OSR Filter Driver ================================== + +[OsrUsb_Install.NT] +CopyFiles=UMDriverCopy +Include=WINUSB.INF ; Import sections from WINUSB.INF +Needs=WINUSB.NT ; Run the CopyFiles & AddReg directives for WinUsb.INF + +[OsrUsb_Install.NT.hw] +AddReg=OsrUsb_AddReg + +[OsrUsb_Install.NT.Services] +AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall ; flag 0x2 sets this as the service for the device +AddService=WinUsb,0x000001f8,WinUsb_ServiceInstall ; this service is installed because its a filter. + +[OsrUsb_Install.NT.Wdf] +KmdfService=WINUSB, WinUsb_Install +UmdfService=WudfOsrUsbFx2, WudfOsrUsbFx2_Install +UmdfService=WudfOsrUsbFilter, WudfOsrUsbFilter_Install +UmdfServiceOrder=WudfOsrUsbFx2, WUDFOsrUsbFilter +UmdfDispatcher=WinUsb + +[OsrUsb_Install.NT.CoInstallers] +AddReg = CoInstallers_AddReg +CopyFiles = CoInstallers_CopyFiles + +[WinUsb_Install] +KmdfLibraryVersion=$KMDFVERSION$ + +[WudfOsrUsbFilter_Install] +UmdfLibraryVersion=$UMDFVERSION$ +DriverCLSID = "{422d8dbc-520d-4d7e-8f53-920e5c867e6c}" +ServiceBinary = "%12%\UMDF\WUDFOsrUsbFilter.dll" + +[WudfOsrUsbFx2_Install] +UmdfLibraryVersion=$UMDFVERSION$ +DriverCLSID = "{0865b2b0-6b73-428f-a3ea-2172832d6bfc}" +ServiceBinary = "%12%\UMDF\WUDFOsrUsbFx2.dll" + +[OsrUsb_AddReg] +HKR,,"LowerFilters",0x00010008,"WinUsb" ; FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND +HKR,,"WinUsbPowerPolicyOwnershipDisabled",0x00010001,1 ; our driver takes ownership of power policy. Tell WINUSB not to + +[WUDFRD_ServiceInstall] +DisplayName = %WudfRdDisplayName% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WUDFRd.sys + +[WinUsb_ServiceInstall] +DisplayName = %WinUsb_SvcDesc% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WinUSB.sys + +[CoInstallers_AddReg] +HKR,,CoInstallers32,0x00010000,"WudfUpdate_$UMDFCOINSTALLERVERSION$.dll" + +[CoInstallers_CopyFiles] +WudfUpdate_$UMDFCOINSTALLERVERSION$.dll + +[DestinationDirs] +CoInstallers_CopyFiles=11 ; copy to system32 +UMDriverCopy=12,UMDF ; copy to drivers\umdf + +[UMDriverCopy] +WudfOsrUsbFilter.dll +WudfOsrUsbFx2.dll + +; =================== Generic ================================== + +[Strings] +MSFTUMDF="Microsoft Internal (WDF:UMDF)" +MediaDescription="Microsoft UMDF OSR USB Sample Device Installation Media" +ClassName="Sample Device" +OsrUsbDeviceName="Microsoft UMDF OSR Usb Sample Device With Filter on User-mode Driver" +WinUsb_SvcDesc="WinUSB Driver" +WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector" diff --git a/usb/umdf_filter_umdf/umdf_filter/comsup.cpp b/usb/umdf_filter_umdf/umdf_filter/comsup.cpp new file mode 100644 index 00000000..31257f31 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/comsup.cpp @@ -0,0 +1,351 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// This is the number of characters in a GUID string including the trailing +// NULL. +// + +#define GUID_STRING_CCH (sizeof("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}")) + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/umdf_filter_umdf/umdf_filter/comsup.h b/usb/umdf_filter_umdf/umdf_filter/comsup.h new file mode 100644 index 00000000..b96fd982 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_filter/device.cpp b/usb/umdf_filter_umdf/umdf_filter/device.cpp new file mode 100644 index 00000000..126637ce --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/device.cpp @@ -0,0 +1,243 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR USB Sample Filter driver's + device callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "device.tmh" + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the OSR USB Sample Filter driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice; + HRESULT hr; + + // + // Configure things like the locking model before we go to create our + // partner device. + // + + // + // We don't need device level locking since we do not keep any state + // across the requests + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // Mark ourselves as a filter + // + + FxDeviceInit->SetFilter(); + + + // + // We are a filter; we don't want to be the power policy owner + // + + FxDeviceInit->SetPowerPolicyOwnership(FALSE); + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + PCMyQueue defaultQueue; + + HRESULT hr; + + hr = CMyQueue::CreateInstance(m_FxDevice, &defaultQueue); + + if (FAILED(hr)) + { + return hr; + } + + hr = defaultQueue->Configure(); + + defaultQueue->Release(); + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the OSR USB Sample Filter driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If OSR USB Sample Filter is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + return CUnknown::QueryInterface(InterfaceId, Object); +} diff --git a/usb/umdf_filter_umdf/umdf_filter/device.h b/usb/umdf_filter_umdf/umdf_filter/device.h new file mode 100644 index 00000000..f7a50b1d --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/device.h @@ -0,0 +1,114 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF OSR USB Sample Filter + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Class for the iotrace driver. +// + +class CMyDevice : public CUnknown +{ + +// +// Private data members. +// +private: + + IWDFDevice *m_FxDevice; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) + { + m_FxDevice = NULL; + } + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + HRESULT + Configure( + VOID + ); + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_filter/dllsup.cpp b/usb/umdf_filter_umdf/umdf_filter/dllsup.cpp new file mode 100644 index 00000000..10ef8a78 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/dllsup.cpp @@ -0,0 +1,183 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the OSR USB Sample Filter + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the OSR USB Sample Filter sample. If + you choose to use a different primary include file, you should ensure + they are defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +// +// Global variable to hold the module handle for this DLL. Initialized during +// DllMain and never cleared. This is used when registering and unregistering +// the driver's COM information. +// + +HINSTANCE g_ModuleHandle = NULL; + +BOOL +WINAPI +DllMain( + HINSTANCE /* ModuleHandle */, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the OSR USB Sample + Filter driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} + diff --git a/usb/umdf_filter_umdf/umdf_filter/driver.cpp b/usb/umdf_filter_umdf/umdf_filter/driver.cpp new file mode 100644 index 00000000..c5910c05 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/driver.cpp @@ -0,0 +1,207 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF OSR USB Sample Filter + driver's core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/umdf_filter_umdf/umdf_filter/driver.h b/usb/umdf_filter_umdf/umdf_filter/driver.h new file mode 100644 index 00000000..08f36a71 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/driver.h @@ -0,0 +1,145 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF OSR USB Sample Filter + driver's callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the OSR USB Sample Filter driver. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver* /*FxWdfDriver*/ + ) + { + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver * /*FxWdfDriver*/ + ) + { + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; diff --git a/usb/umdf_filter_umdf/umdf_filter/exports.def b/usb/umdf_filter_umdf/umdf_filter/exports.def new file mode 100644 index 00000000..0fc42817 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/exports.def @@ -0,0 +1,4 @@ +; Skeleton.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/umdf_filter_umdf/umdf_filter/internal.h b/usb/umdf_filter_umdf/umdf_filter/internal.h new file mode 100644 index 00000000..516f6d7f --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/internal.h @@ -0,0 +1,111 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF OSR USB Sample Filter + driver. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +// +// Define the tracing flags. +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + MyDriverTraceControl, (73cdcaa5,ce52,43f2,aa2d,5f5a84e22213), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsbFilter" +#define MYDRIVER_COM_DESCRIPTION L"UMDF OSR USB Sample Filter Driver" +#define MYDRIVER_CLASS_ID {0x422d8dbc, 0x520d, 0x4d7e, {0x8f, 0x53, 0x92, 0x0e, 0x5c, 0x86, 0x7e, 0x6c}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_SAMPLE_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/umdf_filter_umdf/umdf_filter/queue.cpp b/usb/umdf_filter_umdf/umdf_filter/queue.cpp new file mode 100644 index 00000000..5642ec74 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/queue.cpp @@ -0,0 +1,538 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Queue.cpp + +Abstract: + + This module contains the implementation of the OSR USB Filter Sample driver's + queue callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "queue.h" + +#include "queue.tmh" + +HRESULT +CMyQueue::CreateInstance( + _In_ IWDFDevice * FxDevice, + _Out_ CMyQueue **Queue + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the OSR USB Filter Sample driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + CMyQueue *queue; + + HRESULT hr = S_OK; + + // + // Allocate a new instance of the device class. + // + + queue = new CMyQueue(); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(FxDevice); + } + + if (SUCCEEDED(hr)) + { + queue->AddRef(); + *Queue = queue; + } + + if (NULL != queue) + { + queue->Release(); + } + + return hr; +} + +HRESULT +CMyQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + + if(IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDefaultIoHandler))) + { + hr = S_OK; + *Object = QueryIQueueCallbackDefaultIoHandler(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) + { + hr = S_OK; + *Object = QueryIQueueCallbackWrite(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IRequestCallbackRequestCompletion))) + { + hr = S_OK; + *Object = QueryIRequestCallbackRequestCompletion(); + + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyQueue::Initialize( + _In_ IWDFDevice *FxDevice + ) +/*++ + + Routine Description: + + This method initializes the device callback object. Any operations which + need to be performed before the caller can use the callback object, but + which couldn't be done in the constructor becuase they could fail would + be placed here. + + Arguments: + + FxDevice - the device which this Queue is for. + + Return Value: + + status. + +--*/ +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Create the framework queue + // + + IUnknown *unknown = QueryIUnknown(); + hr = FxDevice->CreateIoQueue( + unknown, + TRUE, // bDefaultQueue + WdfIoQueueDispatchParallel, + FALSE, // bPowerManaged + TRUE, // bAllowZeroLengthRequests + &fxQueue + ); + if (FAILED(hr)) + { + Trace( + TRACE_LEVEL_ERROR, + "%!FUNC!: Could not create default I/O queue, %!hresult!", + hr + ); + } + + unknown->Release(); + + if (SUCCEEDED(hr)) + { + m_FxQueue = fxQueue; + + // + // m_FxQueue is kept as a Weak reference to framework Queue object to avoid + // circular reference. This object's lifetime is contained within + // framework Queue object's lifetime + // + + fxQueue->Release(); + } + + if (SUCCEEDED(hr)) + { + FxDevice->GetDefaultIoTarget(&m_FxIoTarget); + } + + return hr; +} + +void +CMyQueue::InvertBits( + _Inout_ IWDFMemory* FxMemory, + _In_ SIZE_T NumBytes + ) +/*++ + + Routine Description: + + This helper method inverts bits in the buffer of an FxMemory object + + Arguments: + + FxMemory - Framework memory object whose buffer's bits are to be inverted + + NumBytes - Number of bytes for which bits are to be inverted + + Return Value: + + None + +--*/ +{ + PBYTE Buffer = (PBYTE) + FxMemory->GetDataBuffer(NULL); + + for (SIZE_T i = 0; i < NumBytes; i++) + { + memset(Buffer + i, ~(Buffer[i]), sizeof(*Buffer)); + } +} + +void +CMyQueue::OnWrite( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest, + _In_ SIZE_T NumOfBytesToWrite + ) +/*++ + + Routine Description: + + This method is called by Framework Queue object to deliver the Write request + This method inverts the bits in write buffer and forwards the request down the device stack + In case of any failure prior to ForwardRequest, it completets the request with failure + + Arguments: + + pWdfQueue - Framework Queue which is delivering the request + + pWdfRequest - Framework Request + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + + IWDFMemory * FxInputMemory = NULL; + + FxRequest->GetInputMemory(&FxInputMemory); + + // + // Invert bits of the buffer to be written to device + // + + InvertBits(FxInputMemory, NumOfBytesToWrite); + + // + // Forward request down the stack + // When the device below completes the request we will get notified in OnComplete + // and then we will complete the request + // + + ForwardRequest(FxRequest); + + FxInputMemory->Release(); +} + +// +// IQueueCallbackDefaultIoHandler method +// + +void +CMyQueue::OnDefaultIoHandler( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest + ) +/*++ + + Routine Description: + + This method is called by Framework Queue object to deliver all the I/O + Requests for which we do not have a specific handler + (In our case anything other than Write) + + Arguments: + + pWdfQueue - Framework Queue which is delivering the request + + pWdfRequest - Framework Request + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + + // + // We just forward the request down the stack + // When the device below completes the request we will get notified in OnComplete + // and then we will complete the request + // + + ForwardRequest(FxRequest); +} + +void +CMyQueue::ForwardRequest( + _In_ IWDFIoRequest* FxRequest + ) +/*++ + + Routine Description: + + This helper method forwards the request down the stack + + Arguments: + + pWdfRequest - Request to be forwarded + + Return Value: + + None + + Remarks: + + The request gets forwarded to the next device in the stack which can be: + 1. Next device in user-mode stack + 2. Top device in kernel-mode stack (Redirector's Down Device) + + In this routine we: + 1. Set a completion callback + 2. Copy request parameters to next stack location + 3. Asynchronously send the request without any timeout + + When the lower request gets completed we will be notified via the + completion callback, where we will complete our request + + In case of failure this routine completes the request + +--*/ +{ + // + //First set the completion callback + // + + IRequestCallbackRequestCompletion *completionCallback = + QueryIRequestCallbackRequestCompletion(); + + FxRequest->SetCompletionCallback( + completionCallback, + NULL //pContext + ); + + completionCallback->Release(); + + // + //Copy current i/o stack locations parameters to the next stack location + // + + FxRequest->FormatUsingCurrentType( + ); + + // + //Send down the request + // + HRESULT hrSend = S_OK; + + hrSend = FxRequest->Send( + m_FxIoTarget, + 0, //No flag + 0 //No timeout + ); + + if (FAILED(hrSend)) + { + // + //If send failed we need to complete the request with failure + // + FxRequest->CompleteWithInformation(hrSend, 0); + } + + return; +} + +void +CMyQueue::HandleReadRequestCompletion( + IWDFIoRequest* FxRequest, + IWDFIoRequestCompletionParams* CompletionParams + ) +/*++ + + Routine Description: + + This helper method is called by OnCompletion method to complete Read request + We invert the bits in the read buffer + This is so that the client reads back the data it wrote since + we inverted bits during write to device + + Arguments: + + FxRequest - Request object of our layer + + CompletionParams - Parameters with which the lower Request got completed + + Return Value: + + None + + Remarks: + + This method always completes the request since no one else would get a chance to + complete the request + In case of failure it completes the request with failure + +--*/ +{ + HRESULT hrCompletion = CompletionParams->GetCompletionStatus(); + ULONG_PTR BytesRead = CompletionParams->GetInformation(); + + // + // Check + // 1. whether the lower device succeeded the Request (otherwise we will just complete + // the Request with failure + // 2. If data read is of non-zero length, for us to bother to invert its bits + // + + if (SUCCEEDED(hrCompletion) && + (0 != BytesRead) + ) + { + IWDFMemory *FxOutputMemory; + + FxRequest->GetOutputMemory(&FxOutputMemory ); + + InvertBits(FxOutputMemory, BytesRead); + + FxOutputMemory->Release(); + } + + // + // Complete the request + // + + FxRequest->CompleteWithInformation( + hrCompletion, + BytesRead + ); +} + + +void +CMyQueue::OnCompletion( + IWDFIoRequest* FxRequest, + IWDFIoTarget* FxIoTarget, + IWDFRequestCompletionParams* CompletionParams, + PVOID Context + ) +/*++ + + Routine Description: + + This method is called by Framework I/O Target object when + the lower device completets the Request + + Arguments: + + pWdfRequest - Request object of our layer + + pIoTarget - I/O Target object invoking this callback + + pParams - Parameters with which the lower Request got completed + + Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(FxIoTarget); + UNREFERENCED_PARAMETER(Context); + + // + // If it is a read request, we invert the bits read since we inverted them during write + // so that application would read the same data as it wrote + // + + if (WdfRequestRead == FxRequest->GetType()) + { + IWDFIoRequestCompletionParams * IoCompletionParams = NULL; + HRESULT hrQI = CompletionParams->QueryInterface(IID_PPV_ARGS(&IoCompletionParams)); + WUDF_SAMPLE_DRIVER_ASSERT(SUCCEEDED(hrQI)); + + HandleReadRequestCompletion( + FxRequest, + IoCompletionParams + ); + + SAFE_RELEASE(IoCompletionParams); + } + else + { + + // + // Otherwise we just complete our Request object with the same parameters + // with which the lower Request got completed + // + + FxRequest->CompleteWithInformation( + CompletionParams->GetCompletionStatus(), + CompletionParams->GetInformation() + ); + } +} + diff --git a/usb/umdf_filter_umdf/umdf_filter/queue.h b/usb/umdf_filter_umdf/umdf_filter/queue.h new file mode 100644 index 00000000..216264e9 --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter/queue.h @@ -0,0 +1,253 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Queue.h + +Abstract: + + This module contains the type definitions for the OSR USB Filter Sample + driver's queue callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Class for the queue callbacks. +// It implements +// IQueueCallbackDeviceIoControl +// IRequestCallbackRequestCompletion +// Queue callbacks +// +// This class also implements IRequestCallbackRequestCompletion callback +// to get the request completion notification when request is sent down the +// stack. This callback can be implemented on a separate object as well. +// This callback is implemented here only for conenience. +// +class CMyQueue : + public CUnknown, + public IQueueCallbackWrite, + public IQueueCallbackDefaultIoHandler, + public IRequestCallbackRequestCompletion +{ + +// +// Private data members. +// +private: + + // + // Weak reference to framework Queue object which this object implements callbacks for + // This is kept as a weak reference to avoid circular reference + // This object's lifetime is contained within framework Queue object's lifetime + // + + IWDFIoQueue *m_FxQueue; + + // + // I/O Target to which we forward requests. Represents next device in the + // device stack + // + + IWDFIoTarget *m_FxIoTarget; + +// +// Private methods. +// + +private: + + CMyQueue() : + m_FxQueue(NULL), + m_FxIoTarget(NULL) + { + } + + virtual ~CMyQueue() + { + if (NULL != m_FxIoTarget) + { + m_FxIoTarget->Release(); + } + } + + // + // QueryInterface helpers + // + + IRequestCallbackRequestCompletion * + QueryIRequestCallbackRequestCompletion( + VOID + ) + { + AddRef(); + return static_cast<IRequestCallbackRequestCompletion*>(this); + } + + IQueueCallbackWrite * + QueryIQueueCallbackWrite( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackWrite *>(this); + } + + IQueueCallbackDefaultIoHandler * + QueryIQueueCallbackDefaultIoHandler( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDefaultIoHandler *>(this); + } + + // + // Initialize + // + + HRESULT + Initialize( + _In_ IWDFDevice *FxDevice + ); + + // + // Helper method to forward request down the stack + // + + void + ForwardRequest( + _In_ IWDFIoRequest *pWdfRequest + ); + + // + // Helper method to inverts bits in the buffer of a framework Memory object + // + + void + InvertBits( + _Inout_ IWDFMemory* FxMemory, + _In_ SIZE_T NumBytes + ); + + // + // Helper method to handle Read request completion + // + + void + HandleReadRequestCompletion( + IWDFIoRequest* FxRequest, + IWDFIoRequestCompletionParams* CompletionParams + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this class + // + + static + HRESULT + CreateInstance( + _In_ IWDFDevice *FxDevice, + _Out_ CMyQueue **Queue + ); + + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IQueueCallbackWrite method + // + + virtual + void + STDMETHODCALLTYPE + OnWrite( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest, + _In_ SIZE_T NumOfBytesToWrite + ); + + + // + // IQueueCallbackDefaultIoHandler method + // + + virtual + void + STDMETHODCALLTYPE + OnDefaultIoHandler( + _In_ IWDFIoQueue* FxQueue, + _In_ IWDFIoRequest* FxRequest + ); + + // + //IRequestCallbackRequestCompletion + // + + virtual + void + STDMETHODCALLTYPE + OnCompletion( + IWDFIoRequest* FxRequest, + IWDFIoTarget* FxIoTarget, + IWDFRequestCompletionParams* CompletionParams, + PVOID Context + ); +}; + diff --git a/usb/umdf_filter_umdf/umdf_filter_umdf.sln b/usb/umdf_filter_umdf/umdf_filter_umdf.sln new file mode 100644 index 00000000..50055acd --- /dev/null +++ b/usb/umdf_filter_umdf/umdf_filter_umdf.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{531B99DD-B7DB-431D-A028-6843337B1B2E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{C76583EA-D923-45F8-B74B-A08226D64DE4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_driver", "Umdf_driver", "{BA612164-8359-46AB-8A21-D2AD9B9EDCA5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{92A41A0C-EC0F-4D98-B4DE-4899B375FD49}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{E62A4AAA-870E-4D58-AA10-D9604A2E52E8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2", "umdf_driver\WUDFOsrUsbFx2.vcxproj", "{0D3781C2-2236-46B0-806D-387999E500AB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Debug|Win32.ActiveCfg = Debug|Win32 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Debug|Win32.Build.0 = Debug|Win32 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Release|Win32.ActiveCfg = Release|Win32 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Release|Win32.Build.0 = Release|Win32 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Debug|x64.ActiveCfg = Debug|x64 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Debug|x64.Build.0 = Debug|x64 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Release|x64.ActiveCfg = Release|x64 + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49}.Release|x64.Build.0 = Release|x64 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Debug|Win32.ActiveCfg = Debug|Win32 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Debug|Win32.Build.0 = Debug|Win32 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Release|Win32.ActiveCfg = Release|Win32 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Release|Win32.Build.0 = Release|Win32 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Debug|x64.ActiveCfg = Debug|x64 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Debug|x64.Build.0 = Debug|x64 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Release|x64.ActiveCfg = Release|x64 + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8}.Release|x64.Build.0 = Release|x64 + {0D3781C2-2236-46B0-806D-387999E500AB}.Debug|Win32.ActiveCfg = Debug|Win32 + {0D3781C2-2236-46B0-806D-387999E500AB}.Debug|Win32.Build.0 = Debug|Win32 + {0D3781C2-2236-46B0-806D-387999E500AB}.Release|Win32.ActiveCfg = Release|Win32 + {0D3781C2-2236-46B0-806D-387999E500AB}.Release|Win32.Build.0 = Release|Win32 + {0D3781C2-2236-46B0-806D-387999E500AB}.Debug|x64.ActiveCfg = Debug|x64 + {0D3781C2-2236-46B0-806D-387999E500AB}.Debug|x64.Build.0 = Debug|x64 + {0D3781C2-2236-46B0-806D-387999E500AB}.Release|x64.ActiveCfg = Release|x64 + {0D3781C2-2236-46B0-806D-387999E500AB}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {92A41A0C-EC0F-4D98-B4DE-4899B375FD49} = {531B99DD-B7DB-431D-A028-6843337B1B2E} + {E62A4AAA-870E-4D58-AA10-D9604A2E52E8} = {C76583EA-D923-45F8-B74B-A08226D64DE4} + {0D3781C2-2236-46B0-806D-387999E500AB} = {BA612164-8359-46AB-8A21-D2AD9B9EDCA5} + EndGlobalSection +EndGlobal diff --git a/usb/usbview/ReadMe.md b/usb/usbview/ReadMe.md new file mode 100644 index 00000000..b017a426 --- /dev/null +++ b/usb/usbview/ReadMe.md @@ -0,0 +1,89 @@ +USBView sample application +========================== + +Usbview.exe is a Windows GUI application that allows you to browse all USB controllers and connected USB devices on your system. The left pane in the main application window displays a connection-oriented tree view, and the right pane displays the USB data structures pertaining to the selected USB device, such as the Device, Configuration, Interface, and Endpoint Descriptors, as well as the current device configuration. + +**Important** If you need UsbView as a tool, do not download this sample. Instead get UsbView.exe from the [Windows Driver Kit (WDK)](http://go.microsoft.com/fwlink/p?linkid=391063) in the Windows Kits\\*\<version\>*\\Tools\\*\<arch\>* folder. If you need to see the source code for UsbView, open the **Browse code** tab. + +This functional application sample demonstrates how a user-mode application can enumerate USB host controllers, USB hubs, and attached USB devices, and query information about the devices from the registry and through USB requests to the devices. + +The IOCTL calls (see the system include file USBIOCTL.H) demonstrated by this sample include: + +- [**IOCTL\_GET\_HCD\_DRIVERKEY\_NAME**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537236) +- [**IOCTL\_USB\_GET\_DESCRIPTOR\_FROM\_NODE\_CONNECTION**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537310) +- [**IOCTL\_USB\_GET\_NODE\_CONNECTION\_DRIVERKEY\_NAME**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537317) +- [**IOCTL\_USB\_GET\_NODE\_CONNECTION\_INFORMATION**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537319) +- [**IOCTL\_USB\_GET\_NODE\_CONNECTION\_NAME**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537323) +- [**IOCTL\_USB\_GET\_NODE\_INFORMATION**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537324) +- [**IOCTL\_USB\_GET\_ROOT\_HUB\_NAME**](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537326) + +For information about USB, see [Universal Serial Bus (USB) Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff538930). + +Run the sample +-------------- + +Local debugging +--------------- + +1. Change **Debugger** to launch to **Local Windows Debugger**. +2. On the **Debug** menu, select **Start debugging** or hit **F5**. + +Manual deployment to a remote target computer +--------------------------------------------- + +If you want to debug the sample app on a remote computer, + +1. Copy the executable to a folder on the remote computer. +2. Specify project properties as per the instructions given in [Set Up Remote Debugging for a Visual Studio Project](http://msdn.microsoft.com/en-us/library/8x6by8d2.aspx). +3. Change **Debugger** to launch to **Remote Windows Debugger**. +4. On the **Debug** menu, select **Start debugging** or hit **F5**. + +View a USB device in Usbview +---------------------------- + +1. Attach a USB device to one of USB ports on the computer that has Usbview running. +2. In the device tree, locate the device. For example the device might be under the Intel(R) ICH10 Family USB Universal Host Controller - 3A34 \> Root Hub node. +3. View host controller and port properties on the right pane. + +Code tour +--------- + +<table> +<colgroup> +<col width="50%" /> +<col width="50%" /> +</colgroup> +<thead> +<tr class="header"> +<th align="left">File manifest +Description</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td align="left">Resource.h +ID definitions for GUI controls</td> +<td align="left">Usbdesc.h +USB descriptor type definitions</td> +</tr> +</tbody> +</table> + +The major topics covered in this tour are: + +- GUI handling routines +- Device enumeration routines +- Device information display routines + +The file Usbview.c contains the sample application entry point and GUI handling routines. On entry, the main application window is created, which is actually a dialog box as defined in Usbview.rc. The dialog box consists of a split window with a tree view control on the left side and an edit control on the right side. + +The routine RefreshTree() is called to enumerate USB host controller, hubs, and attached devices and to populate the device tree view control. RefreshTree() calls the routine EnumerateHostControllers() in Enum.c to enumerate USB host controller, hubs, and attached devices. After the device tree view control has been populated, USBView\_OnNotify() is called when an item is selected in the device tree view control. This calls UpdateEditControl() in Display.c to display information about the selected item in the edit control. + +The file Enum.c contains the routines that enumerate the USB bus and populate the tree view control. The USB device enumeration and information collection process is the main point of this sample application. The enumeration process starts at EnumerateHostControllers() and goes like this: + +1. Enumerate Host Controllers and Root Hubs. Host controllers have symbolic link names of the form HCDx, where x starts at 0. Use CreateFile() to open each host controller symbolic link. Create a node in the tree view to represent each host controller. After a host controller has been opened, send the host controller an IOCTL\_USB\_GET\_ROOT\_HUB\_NAME request to get the symbolic link name of the root hub that is part of the host controller. +2. Enumerate Hubs (Root Hubs and External Hubs). Given the name of a hub, use CreateFile() to open the hub. Send the hub an IOCTL\_USB\_GET\_NODE\_INFORMATION request to get info about the hub, such as the number of downstream ports. Create a node in the tree view to represent each hub. +3. Enumerate Downstream Ports. Given a handle to an open hub and the number of downstream ports on the hub, send the hub an IOCTL\_USB\_GET\_NODE\_CONNECTION\_INFORMATION request for each downstream port of the hub to get info about the device (if any) attached to each port. If there is a device attached to a port, send the hub an IOCTL\_USB\_GET\_NODE\_CONNECTION\_NAME request to get the symbolic link name of the hub attached to the downstream port. If there is a hub attached to the downstream port, recurse to step (2). Create a node in the tree view to represent each hub port and attached device. USB configuration and string descriptors are retrieved from attached devices in GetConfigDescriptor() and GetStringDescriptor() by sending an IOCTL\_USB\_GET\_DESCRIPTOR\_FROM\_NODE\_CONNECTION() to the hub to which the device is attached. + +The file Display.c contains routines that display information about selected devices in the application edit control. Information about the device was collected during the enumeration of the device tree. This information includes USB device, configuration, and string descriptors and connection and configuration information that is maintained by the USB stack. The routines in this file simply parse and print the data structures for the device that were collected when it was enumerated. The file Dispaud.c parses and prints data structures that are specific to USB audio class devices. + diff --git a/usb/usbview/app.config b/usb/usbview/app.config new file mode 100644 index 00000000..fe947d6f --- /dev/null +++ b/usb/usbview/app.config @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- This config file is needed for Usbview to run on machines without .net3.5 installed --> +<configuration> +<startup useLegacyV2RuntimeActivationPolicy="true"> + <supportedRuntime version="v4.0.30319" sku=".NETFramework,Version=v4.0,Profile=Full"/> + <supportedRuntime version="v4.0.30319"/> + <supportedRuntime version="v4.0"/> + <supportedRuntime version="v3.5"/> + <supportedRuntime version="v3.0"/> + <supportedRuntime version="v2.0.50727"/> +</startup> +</configuration> diff --git a/usb/usbview/bang.ico b/usb/usbview/bang.ico Binary files differnew file mode 100644 index 00000000..90fe0f22 --- /dev/null +++ b/usb/usbview/bang.ico diff --git a/usb/usbview/codeanalysis.h b/usb/usbview/codeanalysis.h new file mode 100644 index 00000000..2f3d75d4 --- /dev/null +++ b/usb/usbview/codeanalysis.h @@ -0,0 +1,133 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + + CODEANALYSIS.H + +Abstract: + + This header file is used for supressing fxcop errors which are not applicable + +Environment: + + user mode + +Revision History: + + 08-11-11 : created + +--*/ + +#pragma once + +#if CODE_ANALYSIS + +/***************************************************************************** + C O D E A N A L Y S I S S U P P R E S S I O N S + *****************************************************************************/ + +using namespace System::Diagnostics::CodeAnalysis; + +namespace Microsoft +{ + namespace Kits + { + namespace Samples + { + namespace Usb + { + // Justification : C++ Compiler cannot enforce ClsCompliant + [module: SuppressMessage("Microsoft.Design", "CA1014:MarkAssembliesWithClsCompliant")] + + // Justification : The naming of the following types are based on native USB types + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType", MessageId="Bos")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.Hub30DescriptorType.#HubHdrDecLat", MessageId="Hdr")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.MachineInfoType.#UvcMajorSpecVersion", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.MachineInfoType.#UvcMinorSpecVersion", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.MachineInfoType.#UvcMinorVersion", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.MachineInfoType.#UvcMajorVersion", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceClassDetailsType.#UvcVersion", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#BNumDeviceCaps", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#UsbDispContIdCapExtDescriptor", MessageId="Disp")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#BosDescriptor", MessageId="Bos")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.NodeConnectionInfoExType.#IProductStringDescEn", MessageId="Desc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceConfigurationType.#OtgDescriptor", MessageId="Otg")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceConfigurationType.#OtgError", MessageId="Otg")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceConfigurationType.#IadError", MessageId="Iad")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceConfigurationType.#IadDescriptor", MessageId="Iad")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceIADDescriptorType.#StringDesc", MessageId="Desc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceInterfaceDescriptorType.#BNumEndpoints", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceInterfaceDescriptorType.#StringDesc", MessageId="Desc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceInterfaceDescriptorType.#WNumClasses", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.NodeConnectionInfoExStructType.#NumOfOpenPipes", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.NodeConnectionInfoExStructType.#SpeedStr", MessageId="Str")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConfigurationDescriptorType.#ConfStringDesc", MessageId="Desc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConfigurationDescriptorType.#AttributesStr", MessageId="Str")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConfigurationDescriptorType.#ConfigDescError", MessageId="Desc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConfigurationDescriptorType.#BNumInterfaces", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UvcViewAll", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UvcViewAll.#UvcView", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UsbDispContIdCapExtDescriptorType", MessageId="Disp")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDispContIdCapExtDescriptorType.#ContainerIdStr", MessageId="Str")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConnectionStatusType.#DeviceCausedOvercurrent", MessageId="Overcurrent")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceQualifierDescriptorType.#NumConfigurations", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceQualifierDescriptorType.#DeviceNumConfigError", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceDescriptorType.#NumConfigurations", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceType.#BosDescriptor", MessageId="Bos")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UvcViewType", MessageId="Uvc")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceHidDescriptorType.#BNumDescriptors", MessageId="Num")]; + [module: SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#HubInformationEx")]; + [module: SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#HubInformationEx")]; + [module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceConfigurationType.#PreReleaseError", MessageId="PreRelease")]; + [module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbHCPowerStateType.#CanWakeUp", MessageId="WakeUp")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbSuperSpeedExtensionDescriptorType.#BmAttributes", MessageId="Bm")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbUsb20ExtensionDescriptorType.#BmAttributes", MessageId="Bm")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.HubNodeType.#UsbMiParent", MessageId="Mi")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#HwId", MessageId="Hw")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.HostControllerType.#HwId", MessageId="Hw")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UsbDeviceOTGDescriptorType", MessageId="OTG")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceOTGDescriptorType.#BmAttributes", MessageId="Bm")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.HubNodeInformationType.#MiParentNumberOfInterfaces", MessageId="Mi")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.NodeConnectionInfoExType.#IProductStringDescEn", MessageId="En")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="type", Target="Microsoft.Kits.Samples.Usb.UsbDeviceIADDescriptorType", MessageId="IAD")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbConfigurationDescriptorType.#BmAttributes", MessageId="Bm")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#HwId", MessageId="Hw")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceQualifierDescriptorType.#BcdUSB", MessageId="USB")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceDescriptorType.#CdDevice", MessageId="Cd")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceDescriptorType.#CdUSB", MessageId="USB")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceDescriptorType.#CdUSB", MessageId="Cd")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceType.#HwId", MessageId="Hw")]; + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceHidDescriptorType.#BcdHID", MessageId="HID")]; + [module: SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#HubCapabilityEx")] + [module: SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#HubCapabilityEx")] + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.HubCapabilitiesExType.#HubIsMultiTt", MessageId="Multi")] + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.Kits.Samples.Usb.HubCapabilitiesExType.#HubIsMultiTtCapable", MessageId="Multi")] + + [module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId="usbview")]; + [module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="usbview")]; + + // Justification: The version of XSD which is used to generate the objects does not support Collections. + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#UsbSuperSpeedExtensionDescriptor")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#UsbUsb20ExtensionDescriptor")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#UnknownDescriptor")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbBosDescriptorType.#UsbDispContIdCapExtDescriptor")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#UsbDevice")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#DeviceConfiguration")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#NoDevice")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.ExternalHubType.#ExternalHub")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.NodeConnectionInfoExStructType.#Pipe")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbHCPowerStateMappingType.#PowerMap")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#NoDevice")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#ExternalHub")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.RootHubType.#UsbDevice")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceType.#DeviceConfiguration")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UvcViewType.#UsbTree")]; + [module: SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope="member", Target="Microsoft.Kits.Samples.Usb.UsbDeviceHidDescriptorType.#OptionalDescriptor")]; + }; + }; + }; +}; + +#endif diff --git a/usb/usbview/debug.c b/usb/usbview/debug.c new file mode 100644 index 00000000..bdd25589 --- /dev/null +++ b/usb/usbview/debug.c @@ -0,0 +1,209 @@ +/*++ + +Copyright (c) 1997-2008 Microsoft Corporation + +Module Name: + + DEBUG.C + +Abstract: + + This source file contains debug routines. + +Environment: + + user mode + +Revision History: + + 07-08-97 : created + +--*/ + +/***************************************************************************** + I N C L U D E S +*****************************************************************************/ + +#include "uvcview.h" + +#if DBG + +/***************************************************************************** + T Y P E D E F S +*****************************************************************************/ + +typedef struct _ALLOCHEADER +{ + LIST_ENTRY ListEntry; + + PCHAR File; + + ULONG Line; + +} ALLOCHEADER, *PALLOCHEADER; + + +/***************************************************************************** + G L O B A L S +*****************************************************************************/ + +LIST_ENTRY AllocListHead = +{ + &AllocListHead, + &AllocListHead +}; + + +/***************************************************************************** + + MyAlloc() + +*****************************************************************************/ +_Success_(return != NULL) +_Post_writable_byte_size_(dwBytes) +HGLOBAL +MyAlloc ( + _In_ PCHAR File, + ULONG Line, + DWORD dwBytes +) +{ + PALLOCHEADER header; + DWORD dwRequest = dwBytes; + + if (0 == dwBytes) + { + return NULL; + } + + dwBytes += sizeof(ALLOCHEADER); + // check for integer overflow + if (dwBytes > dwRequest) + { + header = (PALLOCHEADER)GlobalAlloc(GPTR, dwBytes); + + if (header != NULL) + { + InsertTailList(&AllocListHead, &header->ListEntry); + + header->File = File; + header->Line = Line; + + return (HGLOBAL)(header + 1); + } + } + return NULL; +} + +/***************************************************************************** + + MyReAlloc() + +*****************************************************************************/ + +_Success_(return != NULL) +_Post_writable_byte_size_(dwBytes) +HGLOBAL +MyReAlloc ( + HGLOBAL hMem, + DWORD dwBytes +) +{ + PALLOCHEADER header; + PALLOCHEADER headerNew; + + if ((NULL == hMem) || (0 == dwBytes)) + { + return NULL; + } + + header = (PALLOCHEADER)hMem; + header--; + + // Remove the old address from the allocation list + // + RemoveEntryList(&header->ListEntry); + + if (dwBytes < (dwBytes + (DWORD) sizeof(ALLOCHEADER))) + { + dwBytes += sizeof(ALLOCHEADER); + headerNew = GlobalReAlloc((HGLOBAL)header, dwBytes, GMEM_MOVEABLE|GMEM_ZEROINIT); + + if (NULL == headerNew) + { + // If GlobalReAlloc fails, the original memory is not freed, + // and the original handle and pointer are still valid. + // Add the old address back to the allocation list. + // + InsertTailList(&AllocListHead, &header->ListEntry); + } + else + { + // Add the new address to the allocation list + // + InsertTailList(&AllocListHead, &headerNew->ListEntry); + + return (HGLOBAL)(headerNew + 1); + } + } + return NULL; +} + + +/***************************************************************************** + + MyFree() + +*****************************************************************************/ + +HGLOBAL +MyFree ( + HGLOBAL hMem +) +{ + PALLOCHEADER header; + + if (hMem) + { + header = (PALLOCHEADER)hMem; + + header--; + + RemoveEntryList(&header->ListEntry); + + return GlobalFree((HGLOBAL)header); + } + + return GlobalFree(hMem); +} + +/***************************************************************************** + + MyCheckForLeaks() + +*****************************************************************************/ + +VOID +MyCheckForLeaks ( + VOID +) +{ + PALLOCHEADER header; + CHAR buf[128]; + + memset(buf, 0, sizeof(buf)); + + while (!IsListEmpty(&AllocListHead)) + { + header = (PALLOCHEADER)RemoveHeadList(&AllocListHead); + + StringCbPrintf(buf, sizeof(buf), + "File: %s, Line: %d\r\n", + header->File, + header->Line); + + OutputDebugString(buf); + } +} + +#endif diff --git a/usb/usbview/devnode.c b/usb/usbview/devnode.c new file mode 100644 index 00000000..6820e3d3 --- /dev/null +++ b/usb/usbview/devnode.c @@ -0,0 +1,336 @@ +/*++ + + Copyright (c) 1998-2011 Microsoft Corporation + + Module Name: + + DEVNODE.C + + --*/ + +/***************************************************************************** + I N C L U D E S + *****************************************************************************/ + +#include "uvcview.h" + +/***************************************************************************** + + DriverNameToDeviceInst() + + Finds the Device instance of the DevNode with the matching DriverName. + Returns FALSE if the matching DevNode is not found and TRUE if found + + *****************************************************************************/ +BOOL +DriverNameToDeviceInst( + _In_reads_bytes_(cbDriverName) PCHAR DriverName, + _In_ size_t cbDriverName, + _Out_ HDEVINFO *pDevInfo, + _Out_writes_bytes_(sizeof(SP_DEVINFO_DATA)) PSP_DEVINFO_DATA pDevInfoData + ) +{ + HDEVINFO deviceInfo = INVALID_HANDLE_VALUE; + BOOL status = TRUE; + ULONG deviceIndex; + SP_DEVINFO_DATA deviceInfoData; + BOOL bResult = FALSE; + PCHAR pDriverName = NULL; + PSTR buf = NULL; + BOOL done = FALSE; + + if (pDevInfo == NULL) + { + return FALSE; + } + + if (pDevInfoData == NULL) + { + return FALSE; + } + + memset(pDevInfoData, 0, sizeof(SP_DEVINFO_DATA)); + + *pDevInfo = INVALID_HANDLE_VALUE; + + // Use local string to guarantee zero termination + pDriverName = (PCHAR) ALLOC((DWORD) cbDriverName + 1); + if (NULL == pDriverName) + { + status = FALSE; + goto Done; + } + StringCbCopyN(pDriverName, cbDriverName + 1, DriverName, cbDriverName); + + // + // We cannot walk the device tree with CM_Get_Sibling etc. unless we assume + // the device tree will stabilize. Any devnode removal (even outside of USB) + // would force us to retry. Instead we use Setup API to snapshot all + // devices. + // + + // Examine all present devices to see if any match the given DriverName + // + deviceInfo = SetupDiGetClassDevs(NULL, + NULL, + NULL, + DIGCF_ALLCLASSES | DIGCF_PRESENT); + + if (deviceInfo == INVALID_HANDLE_VALUE) + { + status = FALSE; + goto Done; + } + + deviceIndex = 0; + deviceInfoData.cbSize = sizeof(deviceInfoData); + + while (done == FALSE) + { + // + // Get devinst of the next device + // + + status = SetupDiEnumDeviceInfo(deviceInfo, + deviceIndex, + &deviceInfoData); + + deviceIndex++; + + if (!status) + { + // + // This could be an error, or indication that all devices have been + // processed. Either way the desired device was not found. + // + + done = TRUE; + break; + } + + // + // Get the DriverName value + // + + bResult = GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_DRIVER, + &buf); + + // If the DriverName value matches, return the DeviceInstance + // + if (bResult == TRUE && buf != NULL && _stricmp(pDriverName, buf) == 0) + { + done = TRUE; + *pDevInfo = deviceInfo; + CopyMemory(pDevInfoData, &deviceInfoData, sizeof(deviceInfoData)); + FREE(buf); + break; + } + + if(buf != NULL) + { + FREE(buf); + buf = NULL; + } + } + +Done: + + if (bResult == FALSE) + { + if (deviceInfo != INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(deviceInfo); + } + } + + if (pDriverName != NULL) + { + FREE(pDriverName); + } + + return status; +} + +/***************************************************************************** + + DriverNameToDeviceProperties() + + Returns the Device properties of the DevNode with the matching DriverName. + Returns NULL if the matching DevNode is not found. + + The caller should free the returned structure using FREE() macro + + *****************************************************************************/ +PUSB_DEVICE_PNP_STRINGS +DriverNameToDeviceProperties( + _In_reads_bytes_(cbDriverName) PCHAR DriverName, + _In_ size_t cbDriverName + ) +{ + HDEVINFO deviceInfo = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA deviceInfoData = {0}; + ULONG len; + BOOL status; + PUSB_DEVICE_PNP_STRINGS DevProps = NULL; + DWORD lastError; + + // Allocate device propeties structure + DevProps = (PUSB_DEVICE_PNP_STRINGS) ALLOC(sizeof(USB_DEVICE_PNP_STRINGS)); + + if(NULL == DevProps) + { + status = FALSE; + goto Done; + } + + // Get device instance + status = DriverNameToDeviceInst(DriverName, cbDriverName, &deviceInfo, &deviceInfoData); + if (status == FALSE) + { + goto Done; + } + + len = 0; + status = SetupDiGetDeviceInstanceId(deviceInfo, + &deviceInfoData, + NULL, + 0, + &len); + lastError = GetLastError(); + + + if (status != FALSE && lastError != ERROR_INSUFFICIENT_BUFFER) + { + status = FALSE; + goto Done; + } + + // + // An extra byte is required for the terminating character + // + + len++; + DevProps->DeviceId = ALLOC(len); + + if (DevProps->DeviceId == NULL) + { + status = FALSE; + goto Done; + } + + status = SetupDiGetDeviceInstanceId(deviceInfo, + &deviceInfoData, + DevProps->DeviceId, + len, + &len); + if (status == FALSE) + { + goto Done; + } + + status = GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_DEVICEDESC, + &DevProps->DeviceDesc); + + if (status == FALSE) + { + goto Done; + } + + + // + // We don't fail if the following registry query fails as these fields are additional information only + // + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_HARDWAREID, + &DevProps->HwId); + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_SERVICE, + &DevProps->Service); + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_CLASS, + &DevProps->DeviceClass); +Done: + + if (deviceInfo != INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(deviceInfo); + } + + if (status == FALSE) + { + if (DevProps != NULL) + { + FreeDeviceProperties(&DevProps); + } + } + return DevProps; +} + +/***************************************************************************** + + FreeDeviceProperties() + + Free the device properties structure + + *****************************************************************************/ +VOID FreeDeviceProperties(_In_ PUSB_DEVICE_PNP_STRINGS *ppDevProps) +{ + if(ppDevProps == NULL) + { + return; + } + + if(*ppDevProps == NULL) + { + return; + } + + if ((*ppDevProps)->DeviceId != NULL) + { + FREE((*ppDevProps)->DeviceId); + } + + if ((*ppDevProps)->DeviceDesc != NULL) + { + FREE((*ppDevProps)->DeviceDesc); + } + + // + // The following are not necessary, but left in case + // in the future there is a later failure where these + // pointer fields would be allocated. + // + + if ((*ppDevProps)->HwId != NULL) + { + FREE((*ppDevProps)->HwId); + } + + if ((*ppDevProps)->Service != NULL) + { + FREE((*ppDevProps)->Service); + } + + if ((*ppDevProps)->DeviceClass != NULL) + { + FREE((*ppDevProps)->DeviceClass); + } + + if ((*ppDevProps)->PowerState != NULL) + { + FREE((*ppDevProps)->PowerState); + } + + FREE(*ppDevProps); + *ppDevProps = NULL; +} diff --git a/usb/usbview/dispaud.c b/usb/usbview/dispaud.c new file mode 100644 index 00000000..f21294a0 --- /dev/null +++ b/usb/usbview/dispaud.c @@ -0,0 +1,1164 @@ +/*++ + +Copyright (c) 1997-2008 Microsoft Corporation + +Module Name: + +DISPAUD.C + +Abstract: + +This source file contains routines which update the edit control +to display information about USB Audio descriptors. + +Environment: + +user mode + +Revision History: + +03-07-1998 : created + +--*/ + +/***************************************************************************** + I N C L U D E S +*****************************************************************************/ + +#include "uvcview.h" + +/***************************************************************************** + G L O B A L S P R I V A T E T O T H I S F I L E +*****************************************************************************/ + +// +// USB Device Class Definition for Terminal Types 0.9 Draft Revision +// +STRINGLIST slAudioTerminalTypes [] = +{ + // + // 2.1 USB Terminal Types + // + {0x0100, "USB Undefined", ""}, + {0x0101, "USB streaming", ""}, + {0x01FF, "USB vendor specific", ""}, + // + // 2.2 Input Terminal Types + // + {0x0200, "Input Undefined", ""}, + {0x0201, "Microphone", ""}, + {0x0202, "Desktop microphone", ""}, + {0x0203, "Personal microphone", ""}, + {0x0204, "Omni-directional microphone", ""}, + {0x0205, "Microphone array", ""}, + {0x0206, "Processing microphone array", ""}, + // + // 2.3 Output Terminal Types + // + {0x0300, "Output Undefined", ""}, + {0x0301, "Speaker", ""}, + {0x0302, "Headphones", ""}, + {0x0303, "Head Mounted Display Audio", ""}, + {0x0304, "Desktop speaker", ""}, + {0x0305, "Room speaker", ""}, + {0x0306, "Communication speaker", ""}, + {0x0307, "Low frequency effects speaker", ""}, + // + // 2.4 Bi-directional Terminal Types + // + {0x0400, "Bi-directional Undefined", ""}, + {0x0401, "Handset", ""}, + {0x0402, "Headset", ""}, + {0x0403, "Speakerphone, no echo reduction", ""}, + {0x0404, "Echo-suppressing speakerphone", ""}, + {0x0405, "Echo-canceling speakerphone", ""}, + // + // 2.5 Telephony Terminal Types + // + {0x0500, "Telephony Undefined", ""}, + {0x0501, "Phone line", ""}, + {0x0502, "Telephone", ""}, + {0x0503, "Down Line Phone", ""}, + // + // 2.6 External Terminal Types + // + {0x0600, "External Undefined", ""}, + {0x0601, "Analog connector", ""}, + {0x0602, "Digital audio interface", ""}, + {0x0603, "Line connector", ""}, + {0x0604, "Legacy audio connector", ""}, + {0x0605, "S/PDIF interface", ""}, + {0x0606, "1394 DA stream", ""}, + {0x0607, "1394 DV stream soundtrack", ""}, + // + // Embedded Function Terminal Types + // + {0x0700, "Embedded Undefined", ""}, + {0x0701, "Level Calibration Noise Source", ""}, + {0x0702, "Equalization Noise", ""}, + {0x0703, "CD player", ""}, + {0x0704, "DAT", ""}, + {0x0705, "DCC", ""}, + {0x0706, "MiniDisk", ""}, + {0x0707, "Analog Tape", ""}, + {0x0708, "Phonograph", ""}, + {0x0709, "VCR Audio", ""}, + {0x070A, "Video Disc Audio", ""}, + {0x070B, "DVD Audio", ""}, + {0x070C, "TV Tuner Audio", ""}, + {0x070D, "Satellite Receiver Audio", ""}, + {0x070E, "Cable Tuner Audio", ""}, + {0x070F, "DSS Audio", ""}, + {0x0710, "Radio Receiver", ""}, + {0x0711, "Radio Transmitter", ""}, + {0x0712, "Multi-track Recorder", ""}, + {0x0713, "Synthesizer", ""}, +}; +STRINGLIST slAudioFormatTypes [] = +{ + // + // A.1.1 Audio Data Format Type I Codes + // + {0x0000, "TYPE_I_UNDEFINED", ""}, + {0x0001, "PCM", ""}, + {0x0002, "PCM8", ""}, + {0x0003, "IEEE_FLOAT", ""}, + {0x0004, "ALAW", ""}, + {0x0005, "MULAW", ""}, + // + // A.1.2 Audio Data Format Type II Codes + // + {0x1000, "TYPE_II_UNDEFINED", ""}, + {0x1001, "MPEG", ""}, + {0x1002, "AC-3", ""}, + // + // A.1.3 Audio Data Format Type III Codes + // + {0x2000, "TYPE_III_UNDEFINED", ""}, + {0x2001, "IEC1937_AC-3", ""}, + {0x2002, "IEC1937_MPEG-1_Layer1", ""}, + {0x2003, "IEC1937_MPEG-1_Layer2/3 or IEC1937_MPEG-2_NOEXT", ""}, + {0x2004, "IEC1937_MPEG-2_EXT", ""}, + {0x2005, "IEC1937_MPEG-2_Layer1_LS", ""}, + {0x2006, "IEC1937_MPEG-2_Layer2/3_LS", ""}, +}; + + + +/***************************************************************************** + L O C A L F U N C T I O N P R O T O T Y P E S +*****************************************************************************/ + +BOOL +DisplayACHeader ( + PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR HeaderDesc +); + +BOOL +DisplayACInputTerminal ( + PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR ITDesc +); + +BOOL +DisplayACOutputTerminal ( + PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR OTDesc +); + +BOOL +DisplayACMixerUnit ( + PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR MixerDesc +); + +BOOL +DisplayACSelectorUnit ( + PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR SelectorDesc +); + +BOOL +DisplayACFeatureUnit ( + PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR FeatureDesc +); + +BOOL +DisplayACProcessingUnit ( + PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR ProcessingDesc +); + +BOOL +DisplayACExtensionUnit ( + PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR ExtensionDesc +); + +BOOL +DisplayASGeneral ( + PUSB_AUDIO_GENERAL_DESCRIPTOR GeneralDesc +); + +BOOL +DisplayCSEndpoint ( + PUSB_AUDIO_ENDPOINT_DESCRIPTOR EndpointDesc +); + +BOOL +DisplayASFormatType ( + PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR FormatDesc +); + +BOOL +DisplayASFormatSpecific ( + PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc +); + +VOID +DisplayBytes ( + PUCHAR Data, + USHORT Len +); + +/***************************************************************************** + L O C A L F U N C T I O N S +*****************************************************************************/ + +/***************************************************************************** + + DisplayAudioDescriptor() + + CommonDesc - An Audio Class Descriptor + + bInterfaceSubClass - The SubClass of the Interface containing the descriptor + +*****************************************************************************/ + +BOOL +DisplayAudioDescriptor ( + PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc, + UCHAR bInterfaceSubClass +) +{ + switch (CommonDesc->bDescriptorType) + { + case USB_AUDIO_CS_INTERFACE: + switch (bInterfaceSubClass) + { + case USB_AUDIO_SUBCLASS_AUDIOCONTROL: + switch (CommonDesc->bDescriptorSubtype) + { + case USB_AUDIO_AC_HEADER: + return DisplayACHeader((PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_INPUT_TERMINAL: + return DisplayACInputTerminal((PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_OUTPUT_TERMINAL: + return DisplayACOutputTerminal((PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_MIXER_UNIT: + return DisplayACMixerUnit((PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_SELECTOR_UNIT: + return DisplayACSelectorUnit((PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_FEATURE_UNIT: + return DisplayACFeatureUnit((PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_PROCESSING_UNIT: + return DisplayACProcessingUnit((PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AC_EXTENSION_UNIT: + return DisplayACExtensionUnit((PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR)CommonDesc); + + default: + break; + } + break; + + case USB_AUDIO_SUBCLASS_AUDIOSTREAMING: + switch (CommonDesc->bDescriptorSubtype) + { + case USB_AUDIO_AS_GENERAL: + return DisplayASGeneral((PUSB_AUDIO_GENERAL_DESCRIPTOR)CommonDesc); + + case USB_AUDIO_AS_FORMAT_TYPE: + return DisplayASFormatType((PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR)CommonDesc); + break; + + case USB_AUDIO_AS_FORMAT_SPECIFIC: + return DisplayASFormatSpecific(CommonDesc); + + default: + break; + } + break; + + default: + break; + } + break; + + case USB_AUDIO_CS_ENDPOINT: + return DisplayCSEndpoint((PUSB_AUDIO_ENDPOINT_DESCRIPTOR)CommonDesc); + + default: + break; + } + + return FALSE; +} + + +/***************************************************************************** + + DisplayACHeader() + +*****************************************************************************/ + +BOOL +DisplayACHeader ( + PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR HeaderDesc +) +{ + UINT i = 0; + + if (HeaderDesc->bLength < sizeof(USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Interface Header Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + HeaderDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + HeaderDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + HeaderDesc->bDescriptorSubtype); + + AppendTextBuffer("bcdADC: 0x%04X\r\n", + HeaderDesc->bcdADC); + + AppendTextBuffer("wTotalLength: 0x%04X\r\n", + HeaderDesc->wTotalLength); + + AppendTextBuffer("bInCollection: 0x%02X\r\n", + HeaderDesc->bInCollection); + + for (i=0; i<HeaderDesc->bInCollection; i++) + { + AppendTextBuffer("baInterfaceNr[%d]: 0x%02X\r\n", + i+1, + HeaderDesc->baInterfaceNr[i]); + } + + return TRUE; +} + + +/***************************************************************************** + + DisplayACInputTerminal() + +*****************************************************************************/ + +BOOL +DisplayACInputTerminal ( + PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR ITDesc +) +{ + PCHAR pStr = NULL; + + if (ITDesc->bLength != sizeof(USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Input Terminal Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + ITDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ITDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + ITDesc->bDescriptorSubtype); + + AppendTextBuffer("bTerminalID: 0x%02X\r\n", + ITDesc->bTerminalID); + + AppendTextBuffer("wTerminalType: 0x%04X", + ITDesc->wTerminalType); + pStr = GetStringFromList(slAudioTerminalTypes, + sizeof(slAudioTerminalTypes) / sizeof(STRINGLIST), + ITDesc->wTerminalType, + "Invalid AC Input Terminal Type"); + AppendTextBuffer(" (%s)\r\n", pStr); + + AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", + ITDesc->bAssocTerminal); + + AppendTextBuffer("bNrChannels: 0x%02X\r\n", + ITDesc->bNrChannels); + + AppendTextBuffer("wChannelConfig: 0x%04X\r\n", + ITDesc->wChannelConfig); + + AppendTextBuffer("iChannelNames: 0x%02X\r\n", + ITDesc->iChannelNames); + + AppendTextBuffer("iTerminal: 0x%02X\r\n", + ITDesc->iTerminal); + + + return TRUE; +} + + +/***************************************************************************** + + DisplayACOutputTerminal() + +*****************************************************************************/ + +BOOL +DisplayACOutputTerminal ( + PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR OTDesc +) +{ + PCHAR pStr = NULL; + + if (OTDesc->bLength != sizeof(USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Output Terminal Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + OTDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + OTDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + OTDesc->bDescriptorSubtype); + + AppendTextBuffer("bTerminalID: 0x%02X\r\n", + OTDesc->bTerminalID); + + AppendTextBuffer("wTerminalType: 0x%04X", + OTDesc->wTerminalType); + + pStr = GetStringFromList(slAudioTerminalTypes, + sizeof(slAudioTerminalTypes) / sizeof(STRINGLIST), + OTDesc->wTerminalType, + "Invalid AC Output Terminal Type"); + AppendTextBuffer(" (%s)\r\n", pStr); + + AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", + OTDesc->bAssocTerminal); + + AppendTextBuffer("bSourceID: 0x%02X\r\n", + OTDesc->bSourceID); + + AppendTextBuffer("iTerminal: 0x%02X\r\n", + OTDesc->iTerminal); + + + return TRUE; +} + + +/***************************************************************************** + + DisplayACMixerUnit() + +*****************************************************************************/ + +BOOL +DisplayACMixerUnit ( + PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR MixerDesc +) +{ + UCHAR i = 0; + PUCHAR data = NULL; + + if (MixerDesc->bLength < 10) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Mixer Unit Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + MixerDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + MixerDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + MixerDesc->bDescriptorSubtype); + + AppendTextBuffer("bUnitID: 0x%02X\r\n", + MixerDesc->bUnitID); + + AppendTextBuffer("bNrInPins: 0x%02X\r\n", + MixerDesc->bNrInPins); + + for (i=0; i<MixerDesc->bNrInPins; i++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i+1, + MixerDesc->baSourceID[i]); + } + + data = &MixerDesc->baSourceID[MixerDesc->bNrInPins]; + + AppendTextBuffer("bNrChannels: 0x%02X\r\n", + *data++); + + AppendTextBuffer("wChannelConfig: 0x%04X\r\n", + *(PUSHORT)data); + + data = (PUCHAR) ((PUSHORT) data + 1); + + AppendTextBuffer("iChannelNames: 0x%02X\r\n", + *data++); + + AppendTextBuffer("bmControls:\r\n"); + + i = MixerDesc->bLength - 10 - MixerDesc->bNrInPins; + + DisplayBytes(data, i); + + data += i; + + AppendTextBuffer("iMixer: 0x%02X\r\n", + *data); + + return TRUE; +} + + +/***************************************************************************** + + DisplayACSelectorUnit() + +*****************************************************************************/ + +BOOL +DisplayACSelectorUnit ( + PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR SelectorDesc +) +{ + UCHAR i = 0; + PUCHAR data = NULL; + + if (SelectorDesc->bLength < 6) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Selector Unit Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + SelectorDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + SelectorDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + SelectorDesc->bDescriptorSubtype); + + AppendTextBuffer("bUnitID: 0x%02X\r\n", + SelectorDesc->bUnitID); + + AppendTextBuffer("bNrInPins: 0x%02X\r\n", + SelectorDesc->bNrInPins); + + for (i=0; i<SelectorDesc->bNrInPins; i++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i+1, + SelectorDesc->baSourceID[i]); + } + + data = &SelectorDesc->baSourceID[SelectorDesc->bNrInPins]; + + AppendTextBuffer("iSelector: 0x%02X\r\n", + *data); + + return TRUE; +} + + +/***************************************************************************** + + DisplayACFeatureUnit() + +*****************************************************************************/ + +BOOL +DisplayACFeatureUnit ( + PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR FeatureDesc +) +{ + UCHAR i = 0; + UCHAR n = 0; + UCHAR ch = 0; + PUCHAR data = NULL; + + AppendTextBuffer("\r\n ===>Audio Control Feature Unit Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + FeatureDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + FeatureDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + FeatureDesc->bDescriptorSubtype); + + AppendTextBuffer("bUnitID: 0x%02X\r\n", + FeatureDesc->bUnitID); + + AppendTextBuffer("bSourceID: 0x%02X\r\n", + FeatureDesc->bSourceID); + + AppendTextBuffer("bControlSize: 0x%02X\r\n", + FeatureDesc->bControlSize); + + + if (FeatureDesc->bLength < 7) + { + AppendTextBuffer("*!*WARNING: bLength is invalid (< 7)\r\n"); + OOPS(); + return FALSE; + } + else if(FeatureDesc->bLength == 7) + { + AppendTextBuffer("Audio controls are not available (bLength = 7)\r\n"); + return TRUE; + } + + n = FeatureDesc->bControlSize; + + if(n == 0) + { + AppendTextBuffer("Audio controls are not available (bControlSize = 0)\r\n"); + return TRUE; + } + + ch = ((FeatureDesc->bLength - 7) / n) - 1; + + // Check if there are extra bytes in descriptor based on formula in Spec + if (FeatureDesc->bLength != (7 + (ch + 1) * n)) + { + // The descriptor length is greater than number of bmaControls + AppendTextBuffer("*!*WARNING: bLength is greater than number of bmaControls (bLength > ( 7 + (ch + 1) * n)\r\n"); + } + + data = &FeatureDesc->bmaControls[0]; + + if (ch == (UCHAR) -1) + { + // This should not happen, but this check is put in place so we don't loop for a long time below + AppendTextBuffer("*!*WARNING: Either bLength or bControlSize are invalid. The calculated logical channel count is -1. ((bLength - 7)/ n) - 1\r\n"); + OOPS(); + return FALSE; + } + + for (i=0; i<=ch; i++) + { + AppendTextBuffer("bmaControls[%d]: ", i); + DisplayBytes(data, n); + + data += n; + } + + + AppendTextBuffer("iFeature: 0x%02X\r\n", + *data); + + return TRUE; +} + + +/***************************************************************************** + + DisplayACProcessingUnit() + +*****************************************************************************/ + +BOOL +DisplayACProcessingUnit ( + PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR ProcessingDesc +) +{ + UCHAR i = 0; + PUCHAR data = NULL; + + if (ProcessingDesc->bLength < sizeof(USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Processing Unit Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + ProcessingDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ProcessingDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + ProcessingDesc->bDescriptorSubtype); + + AppendTextBuffer("bUnitID: 0x%02X\r\n", + ProcessingDesc->bUnitID); + + AppendTextBuffer("wProcessType: 0x%04X", + ProcessingDesc->wProcessType); + + switch (ProcessingDesc->wProcessType) + { + case USB_AUDIO_PROCESS_UNDEFINED: + AppendTextBuffer("(Undefined Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_UPDOWNMIX: + AppendTextBuffer("(Up / Down Mix Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_DOLBYPROLOGIC: + AppendTextBuffer("(Dolby Prologic Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_3DSTEREOEXTENDER: + AppendTextBuffer("(3D-Stereo Extender Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_REVERBERATION: + AppendTextBuffer("(Reverberation Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_CHORUS: + AppendTextBuffer("(Chorus Process)\r\n"); + break; + + case USB_AUDIO_PROCESS_DYNRANGECOMP: + AppendTextBuffer("(Dynamic Range Compressor Process)\r\n"); + break; + + default: + AppendTextBuffer("\r\n"); + break; + } + + AppendTextBuffer("bNrInPins: 0x%02X\r\n", + ProcessingDesc->bNrInPins); + + for (i=0; i<ProcessingDesc->bNrInPins; i++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i+1, + ProcessingDesc->baSourceID[i]); + } + + data = &ProcessingDesc->baSourceID[ProcessingDesc->bNrInPins]; + + AppendTextBuffer("bNrChannels: 0x%02X\r\n", + *data++); + + AppendTextBuffer("wChannelConfig: 0x%04X\r\n", + *(PUSHORT)data); + + data = (PUCHAR) ((PUSHORT) data + 1); + + AppendTextBuffer("iChannelNames: 0x%02X\r\n", + *data++); + + i = *data++; + + AppendTextBuffer("bControlSize: 0x%02X\r\n", + i); + + AppendTextBuffer("bmControls:\r\n"); + + DisplayBytes(data, i); + + data += i; + + AppendTextBuffer("iProcessing: 0x%02X\r\n", + *data++); + + + i = ProcessingDesc->bLength - 13 - ProcessingDesc->bNrInPins - i; + + if (i) + { + AppendTextBuffer("Process Specific:\r\n"); + + DisplayBytes(data, i); + } + + return TRUE; +} + + +/***************************************************************************** + + DisplayACExtensionUnit() + +*****************************************************************************/ + +BOOL +DisplayACExtensionUnit ( + PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR ExtensionDesc +) +{ + UCHAR i = 0; + PUCHAR data = NULL; + + if (ExtensionDesc->bLength < 13) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Control Extension Unit Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + ExtensionDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ExtensionDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + ExtensionDesc->bDescriptorSubtype); + + AppendTextBuffer("bUnitID: 0x%02X\r\n", + ExtensionDesc->bUnitID); + + AppendTextBuffer("wExtensionCode: 0x%04X\r\n", + ExtensionDesc->wExtensionCode); + + + AppendTextBuffer("bNrInPins: 0x%02X\r\n", + ExtensionDesc->bNrInPins); + + for (i=0; i<ExtensionDesc->bNrInPins; i++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i+1, + ExtensionDesc->baSourceID[i]); + } + + data = &ExtensionDesc->baSourceID[ExtensionDesc->bNrInPins]; + + AppendTextBuffer("bNrChannels: 0x%02X\r\n", + *data++); + + AppendTextBuffer("wChannelConfig: 0x%04X\r\n", + *(PUSHORT)data); + + data = (PUCHAR) ((PUSHORT) data + 1); + + AppendTextBuffer("iChannelNames: 0x%02X\r\n", + *data++); + + i = *data++; + + AppendTextBuffer("bControlSize: 0x%02X\r\n", + i); + + AppendTextBuffer("bmControls:\r\n"); + + DisplayBytes(data, i); + + data += i; + + AppendTextBuffer("iExtension: 0x%02X\r\n", + *data); + return TRUE; +} + + +/***************************************************************************** + + DisplayASGeneral() + +*****************************************************************************/ + +BOOL +DisplayASGeneral ( + PUSB_AUDIO_GENERAL_DESCRIPTOR GeneralDesc +) +{ + PCHAR pStr = NULL; + + if (GeneralDesc->bLength != sizeof(USB_AUDIO_GENERAL_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Streaming Class Specific Interface Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + GeneralDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + GeneralDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + GeneralDesc->bDescriptorSubtype); + + AppendTextBuffer("bTerminalLink: 0x%02X\r\n", + GeneralDesc->bTerminalLink); + + AppendTextBuffer("bDelay: 0x%02X\r\n", + GeneralDesc->bDelay); + + AppendTextBuffer("wFormatTag: 0x%04X", + GeneralDesc->wFormatTag); + + pStr = GetStringFromList(slAudioFormatTypes, + sizeof(slAudioFormatTypes) / sizeof(STRINGLIST), + GeneralDesc->wFormatTag, + "Invalid AC Format Type"); + AppendTextBuffer(" (%s)\r\n", pStr); + + return TRUE; +} + + +/***************************************************************************** + + DisplayCSEndpoint() + +*****************************************************************************/ + +BOOL +DisplayCSEndpoint ( + PUSB_AUDIO_ENDPOINT_DESCRIPTOR EndpointDesc +) +{ + if (EndpointDesc->bLength != sizeof(USB_AUDIO_ENDPOINT_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Streaming Class Specific Audio Data Endpoint Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + EndpointDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + EndpointDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + EndpointDesc->bDescriptorSubtype); + + AppendTextBuffer("bmAttributes: 0x%02X\r\n", + EndpointDesc->bmAttributes); + + AppendTextBuffer("bLockDelayUnits: 0x%02X\r\n", + EndpointDesc->bLockDelayUnits); + + AppendTextBuffer("wLockDelay: 0x%04X\r\n", + EndpointDesc->wLockDelay); + + return TRUE; +} + + +/***************************************************************************** + + DisplayASFormatType() + +*****************************************************************************/ + +BOOL +DisplayASFormatType ( + PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR FormatDesc +) +{ + UCHAR i = 0; + UCHAR n = 0; + ULONG freq = 0; + PUCHAR data = NULL; + + if (FormatDesc->bLength < sizeof(USB_AUDIO_COMMON_FORMAT_DESCRIPTOR)) + { + OOPS(); + return FALSE; + } + + AppendTextBuffer("\r\n ===>Audio Streaming Format Type Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + FormatDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + FormatDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + FormatDesc->bDescriptorSubtype); + + AppendTextBuffer("bFormatType: 0x%02X\r\n", + FormatDesc->bFormatType); + + + if (FormatDesc->bFormatType == 0x01 || + FormatDesc->bFormatType == 0x03) + { + PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR FormatI_IIIDesc; + + FormatI_IIIDesc = (PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR)FormatDesc; + + AppendTextBuffer("bNrChannels: 0x%02X\r\n", + FormatI_IIIDesc->bNrChannels); + + AppendTextBuffer("bSubframeSize: 0x%02X\r\n", + FormatI_IIIDesc->bSubframeSize); + + AppendTextBuffer("bBitResolution: 0x%02X\r\n", + FormatI_IIIDesc->bBitResolution); + + AppendTextBuffer("bSamFreqType: 0x%02X\r\n", + FormatI_IIIDesc->bSamFreqType); + + data = (PUCHAR)(FormatI_IIIDesc + 1); + + n = FormatI_IIIDesc->bSamFreqType; + + } + else if (FormatDesc->bFormatType == 0x02) + { + PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR FormatIIDesc; + + FormatIIDesc = (PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR)FormatDesc; + + AppendTextBuffer("wMaxBitRate: 0x%04X\r\n", + FormatIIDesc->wMaxBitRate); + + AppendTextBuffer("wSamplesPerFrame: 0x%04X\r\n", + FormatIIDesc->wSamplesPerFrame); + + AppendTextBuffer("bSamFreqType: 0x%02X\r\n", + FormatIIDesc->bSamFreqType); + + data = (PUCHAR)(FormatIIDesc + 1); + + n = FormatIIDesc->bSamFreqType; + } + else + { + data = NULL; + } + + if (data != NULL) + { + if (n == 0) + { + freq = (data[0]) + (data[1] << 8) + (data[2] << 16); + data += 3; + + AppendTextBuffer("tLowerSamFreq: 0x%06X (%d Hz)\r\n", + freq, + freq); + + freq = (data[0]) + (data[1] << 8) + (data[2] << 16); + data += 3; + + AppendTextBuffer("tUpperSamFreq: 0x%06X (%d Hz)\r\n", + freq, + freq); + } + else + { + for (i=0; i<n; i++) + { + freq = (data[0]) + (data[1] << 8) + (data[2] << 16); + data += 3; + + AppendTextBuffer("tSamFreq[%d]: 0x%06X (%d Hz)\r\n", + i+1, + freq, + freq); + } + } + } + + return TRUE; +} + + +/***************************************************************************** + + DisplayASFormatSpecific() + +*****************************************************************************/ + +BOOL +DisplayASFormatSpecific ( + PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc +) +{ + AppendTextBuffer("\r\n ===>Audio Streaming Format Specific Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + CommonDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + CommonDesc->bDescriptorType); + + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", + CommonDesc->bDescriptorSubtype); + + DisplayBytes((PUCHAR)(CommonDesc + 1), + CommonDesc->bLength); + + return TRUE; +} + +/***************************************************************************** + + DisplayBytes() + +*****************************************************************************/ + +VOID +DisplayBytes ( + PUCHAR Data, + USHORT Len +) +{ + USHORT i; + + for (i = 0; i < Len; i++) + { + AppendTextBuffer("%02X ", Data[i]); + + if (i % 16 == 15) + { + AppendTextBuffer("\r\n"); + } + } + + if (i % 16 != 0) + { + AppendTextBuffer("\r\n"); + } +} + + diff --git a/usb/usbview/display.c b/usb/usbview/display.c new file mode 100644 index 00000000..67c215e4 --- /dev/null +++ b/usb/usbview/display.c @@ -0,0 +1,4814 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + +DISPLAY.C + +Abstract: + +This source file contains the routines which update the edit control +to display information about the selected USB device. + +Environment: + +user mode + +Revision History: + +04-25-97 : created +03-28-03 : extensive changes to support new USBVCD +03-28-08 : extensive changes to support new USB Video Class 1.1 + +--*/ + +/***************************************************************************** +I N C L U D E S +*****************************************************************************/ + +#include "uvcview.h" +#include "h264.h" +#include <usb200.h> + +#include "vndrlist.h" +#include "langidlist.h" + +/***************************************************************************** +D E F I N E S +*****************************************************************************/ + +#define BUFFERALLOCINCREMENT 0x10000 +#define BUFFERMINFREESPACE 0x1000 + +/***************************************************************************** +T Y P E D E F S +*****************************************************************************/ + +// +// Hardcoded information about specific EHCI controllers +// +typedef struct _EHCI_CONTROLLER_DATA +{ + USHORT VendorID; + USHORT DeviceID; + UCHAR DebugPortNumber; +} EHCI_CONTROLLER_DATA, *PEHCI_CONTROLLER_DATA; + + +/***************************************************************************** +G L O B A L S P R I V A T E T O T H I S F I L E +*****************************************************************************/ + +// Workspace for text info which is used to update the edit control +// +CHAR *TextBuffer = NULL; +UINT TextBufferLen = 0; +UINT TextBufferPos = 0; + +STRINGLIST slPowerState [] = +{ + {WdmUsbPowerNotMapped, "S? (unmapped) ", ""}, + + {WdmUsbPowerSystemUnspecified, "S? (unspecified)", ""}, + {WdmUsbPowerSystemWorking, "S0 (working) ", ""}, + {WdmUsbPowerSystemSleeping1, "S1 (sleep) ", ""}, + {WdmUsbPowerSystemSleeping2, "S2 (sleep) ", ""}, + {WdmUsbPowerSystemSleeping3, "S3 (sleep) ", ""}, + {WdmUsbPowerSystemHibernate, "S4 (Hibernate) ", ""}, + {WdmUsbPowerSystemShutdown, "S5 (shutdown) ", ""}, + + {WdmUsbPowerDeviceUnspecified, "D? (unspecified)", ""}, + {WdmUsbPowerDeviceD0, "D0 ", ""}, + {WdmUsbPowerDeviceD1, "D1 ", ""}, + {WdmUsbPowerDeviceD2, "D2 ", ""}, + {WdmUsbPowerDeviceD3, "D3 ", ""}, +}; + +STRINGLIST slControllerFlavor[] = +{ + { USB_HcGeneric, "USB_HcGeneric", "" }, + { OHCI_Generic, "OHCI_Generic", "" }, + { OHCI_Hydra, "OHCI_Hydra", "" }, + { OHCI_NEC, "OHCI_NEC", "" }, + { UHCI_Generic, "UHCI_Generic", "" }, + { UHCI_Piix4, "UHCI_Piix4", "" }, + { UHCI_Piix3, "UHCI_Piix3", "" }, + { UHCI_Ich2, "UHCI_Ich2", "" }, + { UHCI_Reserved204, "UHCI_Reserved204", "" }, + { UHCI_Ich1, "UHCI_Ich1", "" }, + { UHCI_Ich3m, "UHCI_Ich3m", "" }, + { UHCI_Ich4, "UHCI_Ich4", "" }, + { UHCI_Ich5, "UHCI_Ich5", "" }, + { UHCI_Ich6, "UHCI_Ich6", "" }, + { UHCI_Intel, "UHCI_Intel", "" }, + { UHCI_VIA, "UHCI_VIA", "" }, + { UHCI_VIA_x01, "UHCI_VIA_x01", "" }, + { UHCI_VIA_x02, "UHCI_VIA_x02", "" }, + { UHCI_VIA_x03, "UHCI_VIA_x03", "" }, + { UHCI_VIA_x04, "UHCI_VIA_x04", "" }, + { UHCI_VIA_x0E_FIFO, "UHCI_VIA_x0E_FIFO", "" }, + { EHCI_Generic, "EHCI_Generic", "" }, + { EHCI_NEC, "EHCI_NEC", "" }, + { EHCI_Lucent, "EHCI_Lucent", "" }, + { EHCI_NVIDIA_Tegra2, "EHCI_NVIDIA_Tegra2", "" }, + { EHCI_NVIDIA_Tegra3, "EHCI_NVIDIA_Tegra3", "" }, + { EHCI_Intel_Medfield, "EHCI_Intel_Medfield", "" } +}; + +// +// For supporting pre Win8 versions of Windows, a hardcoded list is maintained for determining +// debug port numbers. As usbport.inf is augmented with new host controllers, this list should +// be updated. +// +// The following entries do not have a debug port: +// PCI\VEN_8086&DEV_0806 - "Intel(R) SM35 Express Chipset USB2 Enhanced Host Controller MPH - 0806" +// PCI\VEN_8086&DEV_0811 - "Intel(R) SM35 Express Chipset USB2 Enhanced Host Controller SPM - 0811" +// + +EHCI_CONTROLLER_DATA EhciControllerData[] = +{ + {0x8086, 0x24CD, 1}, // ICH4 - Intel(R) 82801DB/DBM USB 2.0 Enhanced Host Controller - 24CD + {0x8086, 0x24DD, 1}, // ICH5 - Intel(R) 82801EB USB2 Enhanced Host Controller - 24DD + {0x8086, 0x25AD, 1}, // ICH5 - Intel(R) 6300ESB USB2 Enhanced Host Controller - 25AD + {0x8086, 0x265C, 1}, // ICH6 - Intel(R) 82801FB/FBM USB2 Enhanced Host Controller - 265C + {0x8086, 0x268C, 1}, // Intel(R) 631xESB/6321ESB/3100 Chipset USB2 Enhanced Host Controller - 268C + {0x8086, 0x27CC, 1}, // ICH7 - Intel(R) 82801G (ICH7 Family) USB2 Enhanced Host Controller - 27CC + {0x8086, 0x2836, 1}, // ICH8 - Intel(R) ICH8 Family USB2 Enhanced Host Controller - 2836 + {0x8086, 0x283A, 1}, // ICH8 - Intel(R) ICH8 Family USB2 Enhanced Host Controller - 283A + {0x8086, 0x293A, 1}, // ICH9 - Intel(R) ICH9 Family USB2 Enhanced Host Controller - 293A + {0x8086, 0x293C, 1}, // ICH9 - Intel(R) ICH9 Family USB2 Enhanced Host Controller - 293C + {0x8086, 0x3A3A, 1}, // ICH10 - Intel(R) ICH10 Family USB Enhanced Host Controller - 3A3A + {0x8086, 0x3A3C, 1}, // ICH10 - Intel(R) ICH10 Family USB Enhanced Host Controller - 3A3C + {0x8086, 0x3A6A, 1}, // ICH10 - Intel(R) ICH10 Family USB Enhanced Host Controller - 3A6A + {0x8086, 0x3A6C, 1}, // ICH10 - Intel(R) ICH10 Family USB Enhanced Host Controller - 3A6C + {0x8086, 0x3B34, 2}, // 5 series - Intel(R) 5 Series/3400 Series Chipset Family USB Enhanced Host Controller - 3B34 + {0x8086, 0x3B36, 2}, // 5 series - Intel(R) 5 Series/3400 Series Chipset Family USB Universal Host Controller - 3B36 + {0x8086, 0x1C26, 2}, // 6 series - Intel(R) 6 Series/C200 Series Chipset Family USB Enhanced Host Controller - 1C26 + {0x8086, 0x1C2D, 2}, // 6 series - Intel(R) 6 Series/C200 Series Chipset Family USB Enhanced Host Controller - 1C2D + {0x8086, 0x1D26, 2}, // Intel(R) C600/X79 series chipset USB2 Enhanced Host Controller #1 - 1D26 + {0x8086, 0x1D2D, 2}, // Intel(R) C600/X79 series chipset USB2 Enhanced Host Controller #2 - 1D2D + {0x8086, 0x268C, 1}, // Intel(R) 631xESB/6321ESB/3100 Chipset USB2 Enhanced Host Controller - 268C + {0x10DE, 0x00D8, 1}, + {0,0,0}, +}; + + +/***************************************************************************** +L O C A L F U N C T I O N P R O T O T Y P E S +*****************************************************************************/ + +VOID +DisplayPortConnectorProperties ( + _In_ PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 + ); + +void +DisplayDevicePowerState ( + _In_ PDEVICE_INFO_NODE DeviceInfoNode + ); + +VOID +DisplayHubInfo ( + PUSB_HUB_INFORMATION HubInfo, + BOOL DisplayDescriptor + ); + +VOID +DisplayHubInfoEx ( + PUSB_HUB_INFORMATION_EX HubInfoEx + ); + +VOID +DisplayHubCapabilityEx ( + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx + ); + +VOID +DisplayPowerState( + PUSB_POWER_INFO pUPI + ); + +VOID +DisplayConnectionInfo ( + _In_ PUSB_NODE_CONNECTION_INFORMATION_EX ConnectInfo, + _In_ PUSBDEVICEINFO info, + _In_ PSTRING_DESCRIPTOR_NODE StringDescs, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 + ); + +VOID +DisplayPipeInfo ( + ULONG NumPipes, + USB_PIPE_INFO *PipeInfo + ); + +VOID +DisplayConfigDesc ( + PUSBDEVICEINFO info, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + PSTRING_DESCRIPTOR_NODE StringDescs + ); + +VOID +DisplayBosDescriptor ( + PUSB_BOS_DESCRIPTOR BosDesc + ); + +VOID +DisplayDeviceQualifierDescriptor ( + PUSB_DEVICE_QUALIFIER_DESCRIPTOR DevQualDesc + ); + +VOID +DisplayConfigurationDescriptor ( + PUSBDEVICEINFO info, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + PSTRING_DESCRIPTOR_NODE StringDescs + ); + +VOID +DisplayInterfaceDescriptor ( + PUSB_INTERFACE_DESCRIPTOR InterfaceDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +VOID +DisplayEndpointDescriptor ( + _In_ PUSB_ENDPOINT_DESCRIPTOR + EndpointDesc, + _In_opt_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR + EpCompDesc, + _In_opt_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR + SspIsochCompDesc, + _In_ UCHAR InterfaceClass, + _In_ BOOLEAN EpCompDescAvail + ); + +VOID +DisplaySuperSpeedPlusIsochEndpointCompanionDescriptor( + _In_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR SspIsochEpCompDesc + ); + +VOID +DisplayEndointCompanionDescriptor ( + _In_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR EpCompDesc, + _In_opt_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR + SspIsochEpCompDesc, + _In_ UCHAR DescType + ); + + +VOID +DisplayHidDescriptor ( + PUSB_HID_DESCRIPTOR HidDesc + ); + +VOID +DisplayOTGDescriptor ( + PUSB_OTG_DESCRIPTOR OTGDesc + ); + +void +InitializePerDeviceSettings ( + PUSBDEVICEINFO info + ); + +UINT +IsUVCDevice ( + PUSBDEVICEINFO info + ); + +VOID +DisplayIADDescriptor ( + PUSB_IAD_DESCRIPTOR IADDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + int nInterfaces, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +VOID +DisplayUSEnglishStringDescriptor ( + UCHAR Index, + PSTRING_DESCRIPTOR_NODE USStringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +VOID +DisplayUnknownDescriptor ( + PUSB_COMMON_DESCRIPTOR CommonDesc + ); + +VOID +DisplayRemainingUnknownDescriptor( + PUCHAR DescriptorData, + ULONG Start, + ULONG Stop + ); + +PCHAR +GetVendorString ( + USHORT idVendor + ); + +PCHAR +GetLangIDString ( + USHORT idLang + ); + +UINT +GetConfigurationSize ( + PUSBDEVICEINFO info + ); + +UINT +GetInterfaceCount ( + PUSBDEVICEINFO info + ); + + +/***************************************************************************** +L O C A L F U N C T I O N S +*****************************************************************************/ + +/***************************************************************************** + +NextDescriptor() + +*****************************************************************************/ +//__forceinline +PUSB_COMMON_DESCRIPTOR +NextDescriptor( + _In_ PUSB_COMMON_DESCRIPTOR Descriptor + ) +{ + if (Descriptor->bLength == 0) + { + return NULL; + } + return (PUSB_COMMON_DESCRIPTOR)((PUCHAR)Descriptor + Descriptor->bLength); +} + +/***************************************************************************** + +GetNextDescriptor() + +*****************************************************************************/ +PUSB_COMMON_DESCRIPTOR +GetNextDescriptor( + _In_reads_bytes_(TotalLength) + PUSB_COMMON_DESCRIPTOR FirstDescriptor, + _In_ + ULONG TotalLength, + _In_ + PUSB_COMMON_DESCRIPTOR StartDescriptor, + _In_ long + DescriptorType + ) +{ + PUSB_COMMON_DESCRIPTOR currentDescriptor = NULL; + PUSB_COMMON_DESCRIPTOR endDescriptor = NULL; + + endDescriptor = (PUSB_COMMON_DESCRIPTOR)((PUCHAR)FirstDescriptor + TotalLength); + + if (StartDescriptor >= endDescriptor || + NextDescriptor(StartDescriptor)>= endDescriptor) + { + return NULL; + } + + if (DescriptorType == -1) // -1 means any type + { + return NextDescriptor(StartDescriptor); + } + + currentDescriptor = StartDescriptor; + + while (((currentDescriptor = NextDescriptor(currentDescriptor)) < endDescriptor) + && currentDescriptor != NULL) + { + if (currentDescriptor->bDescriptorType == (UCHAR)DescriptorType) + { + return currentDescriptor; + } + } + return NULL; +} + + + +/***************************************************************************** + +CreateTextBuffer() + +*****************************************************************************/ + +BOOL +CreateTextBuffer ( + ) +{ + // Allocate the buffer + // + TextBuffer = ALLOC(BUFFERALLOCINCREMENT); + + if (TextBuffer == NULL) + { + OOPS(); + + return FALSE; + } + + TextBufferLen = BUFFERALLOCINCREMENT; + + // Reset the buffer position and terminate the buffer + // + memset(TextBuffer, 0, BUFFERALLOCINCREMENT); + TextBufferPos = 0; + + return TRUE; +} + + +/***************************************************************************** + +DestroyTextBuffer() + +*****************************************************************************/ + +VOID +DestroyTextBuffer ( + ) +{ + if (TextBuffer != NULL) + { + FREE(TextBuffer); + + TextBuffer = NULL; + } +} + + +/***************************************************************************** + +ResetTextBuffer() + +*****************************************************************************/ + +BOOL +ResetTextBuffer ( + ) +{ + // Fail if the text buffer has not been allocated + // + if (TextBuffer == NULL) + { + OOPS(); + + return FALSE; + } + + // Reset the buffer position and terminate the buffer + // + *TextBuffer = 0; + TextBufferPos = 0; + + return TRUE; +} + + +/***************************************************************************** + +GetTextBufferPos() + +*****************************************************************************/ + +UINT +GetTextBufferPos ( + ) +{ + return TextBufferPos; +} + + +/***************************************************************************** + +AppendTextBuffer() + +*****************************************************************************/ + +VOID __cdecl +AppendTextBuffer ( + LPCTSTR lpFormat, + ... + ) +{ + va_list arglist; + HRESULT hr = S_OK; + int nPos = TextBufferPos; + char LocalTextBuffer[512]; + + va_start(arglist, lpFormat); + + // Make sure we have a healthy amount of space free in the buffer, + // reallocating the buffer if necessary. + // + + if (TextBufferLen - TextBufferPos < BUFFERMINFREESPACE) + { + CHAR *TextBufferTmp; + UINT uNewTextBufferLen = 0; + hr = UIntAdd(TextBufferLen, BUFFERALLOCINCREMENT, &uNewTextBufferLen); + + if (hr != S_OK) + { + // we've exceeded DWORD length of (2^32)-1 for buffer + OOPS(); + + return; + } + + TextBufferTmp = REALLOC(TextBuffer, uNewTextBufferLen); + + if (TextBufferTmp != NULL) + { + TextBuffer = TextBufferTmp; + TextBufferLen += BUFFERALLOCINCREMENT; // update TextBufferLen to reflect the new, bigger size of the text buffer + } + else + { + // If GlobalReAlloc fails, the original memory is not freed, + // and the original handle and pointer are still valid. + // + + OOPS(); + + return; + } + } + + // Add the text to the end of the buffer + // + hr = StringCchVPrintf(LocalTextBuffer, sizeof(LocalTextBuffer), lpFormat, arglist); + if (SUCCEEDED(hr)) + { + size_t cbMax = 512; + size_t pcb = 0; + + // Ensure TextBuffer is zero terminated + // The text buffer size is specified by TextBufferLen. + // the text buffer size will be bigger than BUFFERALLOCINCREMENT if the buffer has been reallocated more than + // once (which would happen if it had to be made bigger to hold more text) + hr = StringCbLength((LPCTSTR) TextBuffer, + TextBufferLen, // the maximum number of bytes allowed in TextBuffer. + &pcb); + + if (FAILED(hr)) // buffer is not null-terminated, go ahead and do that + { + TextBuffer[TextBufferLen-1] = 0; + } + hr = StringCbLength((LPCTSTR) LocalTextBuffer, cbMax, &pcb); + if (SUCCEEDED(hr)) + { + StringCbCatN(TextBuffer, TextBufferLen, LocalTextBuffer, pcb); + + // Increment the text position by the number of charcters we just added to it. + TextBufferPos += (UINT) pcb; + } + + // If DebugLog flag set, send output to the debugger + // + if (gLogDebug) + { + OutputDebugString(TextBuffer + nPos); // print the string just added to the text buffer + } + } +} + +//***************************************************************************** +// +// GetTextBuffer +// +// Returns the display text buffer +// +//***************************************************************************** +PCHAR GetTextBuffer(void) +{ + return (TextBuffer); +} + + +//***************************************************************************** +// +// GetEhciDebugPort +// +// Returns debug port value if present for EHCI controller. 0 if its not present +// +//***************************************************************************** +ULONG GetEhciDebugPort(ULONG vendorId, ULONG deviceId) +{ + int i = 0; + ULONG debugPort = 0; + + for (i = 0; EhciControllerData[i].VendorID != 0; i++) + { + if (vendorId == EhciControllerData[i].VendorID && + deviceId == EhciControllerData[i].DeviceID) + { + debugPort = EhciControllerData[i].DebugPortNumber; + break; + } + } + + return debugPort; +} + +//***************************************************************************** +// +// UpdateTreeItemDeviceInfo +// +// hTreeItem - Handle of selected TreeView item for which information should +// be added to the TextBuffer global +// +// The functions returns error status if AppendTextBuffer() used in Display*() functions +// fails. The display text would be missing or truncated in such cases. +//***************************************************************************** +HRESULT +UpdateTreeItemDeviceInfo( + HWND hTreeWnd, + HTREEITEM hTreeItem + ) +{ + TV_ITEM tvi; + PVOID info; + ULONG i; + HRESULT hr = S_OK; + PCHAR tviName = NULL; + + SetLastError(0); + +#ifndef H264_SUPPORT + UNREFERENCED_PARAMETER(bShowVersion) +#endif + +#ifdef H264_SUPPORT + ResetErrorCounts(); +#endif + + tviName = ALLOC(256); + + if(NULL == tviName) + { + OOPS(); + hr = E_OUTOFMEMORY; + return hr; + } + + // + // Get the name of the TreeView item, along with the a pointer to the + // info we stored about the item in the item's lParam. + // + + tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM; + tvi.hItem = hTreeItem; + tvi.pszText = (LPSTR) tviName; + tvi.cchTextMax = 256; + + TreeView_GetItem(hTreeWnd, + &tvi); + + info = (PVOID)tvi.lParam; + + AppendTextBuffer(tviName); + AppendTextBuffer("\r\n"); + + // + // If we didn't store any info for the item, just display the item's + // name, else display the info we stored for the item. + // + if (NULL != info) + { + PUSB_NODE_INFORMATION HubInfo = NULL; + PCHAR HubName = NULL; + PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo = NULL; + PUSB_DESCRIPTOR_REQUEST ConfigDesc = NULL; + PSTRING_DESCRIPTOR_NODE StringDescs = NULL; + PUSB_HUB_INFORMATION_EX HubInfoEx = NULL; + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx = NULL; + PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps = NULL; + PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 = NULL; + PUSB_DESCRIPTOR_REQUEST BosDesc = NULL; + PDEVICE_INFO_NODE DeviceInfoNode = NULL; + + // The TextBuffer has the TreeView name; add 2 lines for display + AppendTextBuffer("\r\n\r\n"); + + switch (*(PUSBDEVICEINFOTYPE)info) + { + case HostControllerInfo: + { + HTREEITEM rootHubItem = NULL; + BOOL dbgPortFound = FALSE; + + AppendTextBuffer("DriverKey: %s\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->DriverKey); + + AppendTextBuffer("VendorID: %04X\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->VendorID); + + AppendTextBuffer("DeviceID: %04X\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->DeviceID); + + AppendTextBuffer("SubSysID: %08X\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->SubSysID); + + AppendTextBuffer("Revision: %02X\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->Revision); + + // + // Search for the debug port number. If running on Win8 or later, + // the USB_PORT_CONNECTOR_PROPERTIES structure will contain the + // port number. If that fails, the list of known host controllers + // with debug ports will be searched. + // + + AppendTextBuffer("\r\nDebug Port Number: "); + + rootHubItem = TreeView_GetChild(hTreeWnd, hTreeItem); + + if (rootHubItem != NULL) + { + HTREEITEM portItem = NULL; + PVOID portInfo; + + portItem = TreeView_GetChild(hTreeWnd, rootHubItem); + + while (portItem != NULL) + { + tvi.mask = TVIF_PARAM; + tvi.hItem = portItem; + tvi.pszText = NULL; + tvi.cchTextMax = 0; + + TreeView_GetItem(hTreeWnd, &tvi); + + portInfo = (PVOID)tvi.lParam; + + // + // Note that an empty port is a port without a device attached + // is still a DeviceInfo instance. + // + + if ((*(PUSBDEVICEINFOTYPE)portInfo) == DeviceInfo) + { + ConnectionInfo = ((PUSBDEVICEINFO)portInfo)->ConnectionInfo; + PortConnectorProps = ((PUSBDEVICEINFO)portInfo)->PortConnectorProps; + } + else if ((*(PUSBDEVICEINFOTYPE)portInfo) == ExternalHubInfo) + { + ConnectionInfo = ((PUSBEXTERNALHUBINFO)portInfo)->ConnectionInfo; + PortConnectorProps = ((PUSBEXTERNALHUBINFO)portInfo)->PortConnectorProps; + + } + + if (ConnectionInfo != NULL && + PortConnectorProps != NULL && + PortConnectorProps->UsbPortProperties.PortIsDebugCapable) + { + dbgPortFound = TRUE; + AppendTextBuffer("%d\r\n", ((PUSBDEVICEINFO)portInfo)->ConnectionInfo->ConnectionIndex); + break; + } + portItem = TreeView_GetNextSibling(hTreeWnd, portItem); + } + + // + // Resetting ConnectionInfo and PortConnectorProps to NULL so that they won't be erroneously + // be displayed below. + // + + ConnectionInfo = NULL; + PortConnectorProps = NULL; + } + if (dbgPortFound == FALSE) + { + for (i = 0; EhciControllerData[i].VendorID; i++) + { + if (((PUSBHOSTCONTROLLERINFO)info)->VendorID == + EhciControllerData[i].VendorID && + ((PUSBHOSTCONTROLLERINFO)info)->DeviceID == + EhciControllerData[i].DeviceID) + { + dbgPortFound = TRUE; + AppendTextBuffer("%d\r\n", EhciControllerData[i].DebugPortNumber); + break; + } + } + } + if (dbgPortFound == FALSE) + { + AppendTextBuffer("None\r\n"); + } + + // + // Display bus/device/function to help with setting debug + // settings. + // + if (((PUSBHOSTCONTROLLERINFO)info)->BusDeviceFunctionValid) + { + AppendTextBuffer("Bus.Device.Function (in decimal): %d.%d.%d\r\n", + ((PUSBHOSTCONTROLLERINFO)info)->BusNumber, + ((PUSBHOSTCONTROLLERINFO)info)->BusDevice, + ((PUSBHOSTCONTROLLERINFO)info)->BusFunction); + } + + // Display the USB Host Controller Power State Info + { + PUSB_POWER_INFO pUPI = (PUSB_POWER_INFO) &((PUSBHOSTCONTROLLERINFO)info)->USBPowerInfo[0]; + int nIndex = 0; + int nPowerState = WdmUsbPowerSystemWorking; + + AppendTextBuffer("\r\nHost Controller Power State Mappings\r\n"); + AppendTextBuffer("System State\t\tHost Controller\t\tRoot Hub\tUSB wakeup\tPowered\r\n"); + for ( ; nPowerState < WdmUsbPowerSystemShutdown; nIndex++, nPowerState++, pUPI++) + { + DisplayPowerState(pUPI); + } + + AppendTextBuffer("%s\t%s\r\n", + "Last Sleep State", + GetPowerStateString(pUPI->LastSystemSleepState) + ); + } + + break; + } + + case RootHubInfo: + HubInfo = ((PUSBROOTHUBINFO)info)->HubInfo; + HubName = ((PUSBROOTHUBINFO)info)->HubName; + HubCapabilityEx = ((PUSBROOTHUBINFO)info)->HubCapabilityEx; + + AppendTextBuffer("Root Hub: %s\r\n", + HubName); + + break; + + case ExternalHubInfo: + HubInfo = ((PUSBEXTERNALHUBINFO)info)->HubInfo; + HubName = ((PUSBEXTERNALHUBINFO)info)->HubName; + HubInfoEx = ((PUSBEXTERNALHUBINFO)info)->HubInfoEx; + HubCapabilityEx = ((PUSBEXTERNALHUBINFO)info)->HubCapabilityEx; + ConnectionInfo = ((PUSBEXTERNALHUBINFO)info)->ConnectionInfo; + ConnectionInfoV2 = ((PUSBEXTERNALHUBINFO)info)->ConnectionInfoV2; + PortConnectorProps = ((PUSBEXTERNALHUBINFO)info)->PortConnectorProps; + ConfigDesc = ((PUSBEXTERNALHUBINFO)info)->ConfigDesc; + StringDescs = ((PUSBEXTERNALHUBINFO)info)->StringDescs; + BosDesc = ((PUSBEXTERNALHUBINFO)info)->BosDesc; + DeviceInfoNode = ((PUSBEXTERNALHUBINFO)info)->DeviceInfoNode; + + AppendTextBuffer("External Hub: %s\r\n", + HubName); + break; + + case DeviceInfo: + ConnectionInfo = ((PUSBDEVICEINFO)info)->ConnectionInfo; + ConnectionInfoV2 = ((PUSBDEVICEINFO)info)->ConnectionInfoV2; + PortConnectorProps = ((PUSBDEVICEINFO)info)->PortConnectorProps; + ConfigDesc = ((PUSBDEVICEINFO)info)->ConfigDesc; + StringDescs = ((PUSBDEVICEINFO)info)->StringDescs; + BosDesc = ((PUSBDEVICEINFO)info)->BosDesc; + DeviceInfoNode = ((PUSBDEVICEINFO)info)->DeviceInfoNode; + break; + } + + if (PortConnectorProps) + { + DisplayPortConnectorProperties(PortConnectorProps, ConnectionInfoV2); + } + + if (DeviceInfoNode) + { + DisplayDevicePowerState(DeviceInfoNode); + } + + if (HubInfo) + { + DisplayHubInfo(&HubInfo->u.HubInformation, + (HubInfoEx == NULL)); + } + + if (HubInfoEx) + { + DisplayHubInfoEx(HubInfoEx); + } + + if(HubCapabilityEx) + { + DisplayHubCapabilityEx(HubCapabilityEx); + } + + if (ConnectionInfo) + { + DisplayConnectionInfo(ConnectionInfo, + (PUSBDEVICEINFO)info, + StringDescs, + ConnectionInfoV2); + } + + if (ConfigDesc) + { + DisplayConfigDesc((PUSBDEVICEINFO)info, + (PUSB_CONFIGURATION_DESCRIPTOR)(ConfigDesc + 1), + StringDescs); + } + + if (BosDesc) + { + DisplayBosDescriptor((PUSB_BOS_DESCRIPTOR)(BosDesc + 1)); + } + } + + if(tviName != NULL) + { + FREE(tviName); + } + + // AppendTextBuffer() which is used in Display*() functions uses GlobalRealloc() which can fail if realloc fails. + // Obtain last error code from GetLastError() and propagate the error to caller. + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + +//***************************************************************************** +// +// UpdateEditControl() +// +// hTreeItem - Handle of selected TreeView item for which information should +// be displayed in the edit control. +// +//***************************************************************************** + +VOID +UpdateEditControl ( + HWND hEditWnd, + HWND hTreeWnd, + HTREEITEM hTreeItem +) +{ + HRESULT hr = S_OK; + + // Start with an empty text buffer. + // + if (!ResetTextBuffer()) + { + return; + } + + // Get the item information in global TextBuffer + hr = UpdateTreeItemDeviceInfo(hTreeWnd, hTreeItem); + + if(FAILED(hr)) + { + OOPS(); + } + + // All done formatting text buffer with info, now update the edit + // control with the contents of the text buffer + // + SetWindowText(hEditWnd, TextBuffer); + +} + +/***************************************************************************** + +DisplayPortConnectorProperties() + +PortConnectorProps - Info about the port connector properties. + +*****************************************************************************/ + +void +DisplayPortConnectorProperties ( + _In_ PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 + ) +{ + AppendTextBuffer("Is Port User Connectable: %s\r\n", + PortConnectorProps->UsbPortProperties.PortIsUserConnectable + ? "yes" : "no"); + + AppendTextBuffer("Is Port Debug Capable: %s\r\n", + PortConnectorProps->UsbPortProperties.PortIsDebugCapable + ? "yes" : "no"); + AppendTextBuffer("Companion Port Number: %d\r\n", + PortConnectorProps->CompanionPortNumber); + AppendTextBuffer("Companion Hub Symbolic Link Name: %ws\r\n", + PortConnectorProps->CompanionHubSymbolicLinkName); + if (ConnectionInfoV2 != NULL) + { + AppendTextBuffer("Protocols Supported:\r\n"); + AppendTextBuffer(" USB 1.1: %s\r\n", + ConnectionInfoV2->SupportedUsbProtocols.Usb110 + ? "yes" : "no"); + AppendTextBuffer(" USB 2.0: %s\r\n", + ConnectionInfoV2->SupportedUsbProtocols.Usb200 + ? "yes" : "no"); + AppendTextBuffer(" USB 3.0: %s\r\n", + ConnectionInfoV2->SupportedUsbProtocols.Usb300 + ? "yes" : "no"); + } + + AppendTextBuffer("\r\n"); +} + +/***************************************************************************** + +DisplayDevicePowerState() + +DeviceInfoNode - Structure containing info used to acquire device state + +*****************************************************************************/ + +void +DisplayDevicePowerState ( + _In_ PDEVICE_INFO_NODE DeviceInfoNode + ) +{ + + DEVICE_POWER_STATE powerState; + + powerState = AcquireDevicePowerState(DeviceInfoNode); + + AppendTextBuffer("Device Power State: "); + if (powerState >= PowerDeviceD0 && powerState <= PowerDeviceD3) + { + AppendTextBuffer("PowerDeviceD%d\r\n", powerState-1); + } + else + { + AppendTextBuffer("Invalid Device Power State Value %d\r\n", powerState); + } + + AppendTextBuffer("\r\n"); +} + + +/***************************************************************************** + +DisplayHubDescriptorBase() + +HubDescriptor - hub descriptor, could also be PUSB_30_HUB_DESCRIPTOR which has + these field in common at the beginning of the data structure: + + - UCHAR bLength; + - UCHAR bDescriptorType; + - UCHAR bNumberOfPorts; + - USHORT wHubCharacteristics; + - UCHAR bPowerOnToPowerGood; + - UCHAR bHubControlCurrent; + +*****************************************************************************/ +VOID +DisplayHubDescriptorBase( + PUSB_HUB_DESCRIPTOR HubDescriptor + ) +{ + USHORT wHubChar = 0; + + AppendTextBuffer("Number of Ports: %d\r\n", + HubDescriptor->bNumberOfPorts); + + wHubChar = HubDescriptor->wHubCharacteristics; + + switch (wHubChar & 0x0003) + { + case 0x0000: + AppendTextBuffer("Power switching: Ganged\r\n"); + break; + + case 0x0001: + AppendTextBuffer("Power switching: Individual\r\n"); + break; + + case 0x0002: + case 0x0003: + AppendTextBuffer("Power switching: None\r\n"); + break; + } + + switch (wHubChar & 0x0004) + { + case 0x0000: + AppendTextBuffer("Compound device: No\r\n"); + break; + + case 0x0004: + AppendTextBuffer("Compound device: Yes\r\n"); + break; + } + + switch (wHubChar & 0x0018) + { + case 0x0000: + AppendTextBuffer("Over-current Protection: Global\r\n"); + break; + + case 0x0008: + AppendTextBuffer("Over-current Protection: Individual\r\n"); + break; + + case 0x0010: + case 0x0018: + AppendTextBuffer("No Over-current Protection (Bus Power Only)\r\n"); + break; + } +} + + + +/***************************************************************************** + +DisplayHubInfo() + +HubInfo - Info about the hub. + +*****************************************************************************/ + +VOID +DisplayHubInfo ( + PUSB_HUB_INFORMATION HubInfo, + BOOL DisplayDescriptor + ) +{ + AppendTextBuffer("Hub Power: %s\r\n", + HubInfo->HubIsBusPowered ? + "Bus Power" : "Self Power"); + + if (DisplayDescriptor == TRUE) + { + DisplayHubDescriptorBase(&HubInfo->HubDescriptor); + } +} + +/***************************************************************************** + +DisplayHubInfoEx() + +HubInfo - Extended info about the hub. + +*****************************************************************************/ + + +VOID +DisplayHubInfoEx ( + PUSB_HUB_INFORMATION_EX HubInfoEx + ) +{ + AppendTextBuffer("Hub type: "); + + switch (HubInfoEx->HubType) { + + case UsbRootHub: + AppendTextBuffer("USB Root Hub\r\n"); + break; + + case Usb20Hub: + AppendTextBuffer("USB 2.0 Hub\r\n"); + DisplayHubDescriptorBase((PUSB_HUB_DESCRIPTOR)&HubInfoEx->u.UsbHubDescriptor); + break; + + case Usb30Hub: + AppendTextBuffer("USB 3.0 Hub\r\n"); + + // + // Note that the DisplayHubDescriptorBase will display the fields of either + // the legacy hub descriptor and the USB 3.0 descriptor which have the same + // offset + // + + DisplayHubDescriptorBase((PUSB_HUB_DESCRIPTOR)&HubInfoEx->u.UsbHubDescriptor); + AppendTextBuffer("Packet Header Decode Latency: 0x%x\r\n", HubInfoEx->u.Usb30HubDescriptor.bHubHdrDecLat); + AppendTextBuffer("Delay: 0x%x ns\r\n", HubInfoEx->u.Usb30HubDescriptor.wHubDelay); + + break; + + default: + AppendTextBuffer("ERROR: Unknown hub type %d\r\n", HubInfoEx->HubType); + break; + } + + AppendTextBuffer("\r\n"); +} + + + +/***************************************************************************** + +DisplayHubCapabilityEx() + +HubCapabilityInfo - Hub capability information + +*****************************************************************************/ + +VOID +DisplayHubCapabilityEx ( + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx + ) +{ + if(HubCapabilityEx != NULL) + { + AppendTextBuffer("High speed capable: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsHighSpeedCapable + ? "Yes" : "No"); + AppendTextBuffer("High speed: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsHighSpeed + ? "Yes" : "No"); + AppendTextBuffer("Multiple transaction translations capable: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsMultiTtCapable + ? "Yes" : "No"); + AppendTextBuffer("Performs multiple transaction translations simultaneously: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsMultiTt + ? "Yes" : "No"); + AppendTextBuffer("Hub wakes when device is connected: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsArmedWakeOnConnect + ? "Yes" : "No"); + AppendTextBuffer("Hub is bus powered: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsBusPowered + ? "Yes" : "No"); + AppendTextBuffer("Hub is root: %s\r\n", + HubCapabilityEx->CapabilityFlags.HubIsRoot + ? "Yes" : "No"); + } +} + +/***************************************************************************** + +DisplayConnectionInfo() + +ConnectInfo - Info about the connection. + +PUSB_NODE_CONNECTION_INFORMATION_EX ConnectInfo, +PSTRING_DESCRIPTOR_NODE StringDescs + +DisplayConnectionInfo(info->ConnectionInfo, +info->StringDescs); + +DisplayConnectionInfo ( +PUSB_NODE_CONNECTION_INFORMATION_EX ConnectInfo, +PSTRING_DESCRIPTOR_NODE StringDescs +) + +*****************************************************************************/ + +VOID +DisplayConnectionInfo ( + _In_ PUSB_NODE_CONNECTION_INFORMATION_EX ConnectInfo, + _In_ PUSBDEVICEINFO info, + _In_ PSTRING_DESCRIPTOR_NODE StringDescs, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 +) +{ + + //@@DisplayConnectionInfo - Device Information + PCHAR VendorString = NULL; + UINT tog = 1; + UINT uIADcount = 0; + + // No device connected + if (ConnectInfo->ConnectionStatus == NoDeviceConnected) + { + AppendTextBuffer("ConnectionStatus: NoDeviceConnected\r\n"); + return; + } + + // This is the entry point to the device display functions. + // First, save this device's PUSBDEVICEINFO address + // In a future version of this test, we will keep track of the the + // descriptor that we're parsing (# of bytes from beginning of info->configuration descriptor) + // Then we can linked descriptors by reading forward through the remaining descriptors + // while still keeping our place in this main DisplayConnectionInfo() and called + // functions. + // + // We also initialize some global flags in uvcview.h that are used to + // verify items in MJPEG, Uncompressed and Vendor Frame descriptors + // + InitializePerDeviceSettings(info); + + if(gDoAnnotation) + { + + AppendTextBuffer(" ---===>Device Information<===---\r\n"); + + if (ConnectInfo->DeviceDescriptor.iProduct) + { + DisplayUSEnglishStringDescriptor(ConnectInfo->DeviceDescriptor.iProduct, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + } + + AppendTextBuffer("\r\nConnectionStatus: %s\r\n", + ConnectionStatuses[ConnectInfo->ConnectionStatus]); + + AppendTextBuffer("Current Config Value: 0x%02X", + ConnectInfo->CurrentConfigurationValue); + } + + switch (ConnectInfo->Speed){ + case UsbLowSpeed: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Device Bus Speed: Low\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + gDeviceSpeed = UsbLowSpeed; + break; + + case UsbFullSpeed: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Device Bus Speed: Full"); + if (ConnectionInfoV2 != NULL) + { + if (ConnectionInfoV2->Flags.DeviceIsSuperSpeedPlusCapableOrHigher) + { + AppendTextBuffer(" (is SuperSpeedPlus or higher capable)\r\n"); + } + else if (ConnectionInfoV2->Flags.DeviceIsSuperSpeedCapableOrHigher) + { + AppendTextBuffer(" (is SuperSpeed or higher capable)\r\n"); + } + else + { + AppendTextBuffer(" (is not SuperSpeed or higher capable)\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + gDeviceSpeed = UsbFullSpeed; + break; + case UsbHighSpeed: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Device Bus Speed: High"); + if (ConnectionInfoV2 != NULL) + { + if (ConnectionInfoV2->Flags.DeviceIsSuperSpeedPlusCapableOrHigher) + { + AppendTextBuffer(" (is SuperSpeedPlus or higher capable)\r\n"); + } + else if (ConnectionInfoV2->Flags.DeviceIsSuperSpeedCapableOrHigher) + { + AppendTextBuffer(" (is SuperSpeed or higher capable)\r\n"); + } + else + { + AppendTextBuffer(" (is not SuperSpeed or higher capable)\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + gDeviceSpeed = UsbHighSpeed; + break; + + case UsbSuperSpeed: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Device Bus Speed: Super%s\r\n", + ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher + ? "SpeedPlus" + : "Speed"); + } + else + { + AppendTextBuffer("\r\n"); + } + gDeviceSpeed = UsbSuperSpeed; + break; + + default: + if(gDoAnnotation){AppendTextBuffer(" -> Device Bus Speed: Unknown\r\n");} + else {AppendTextBuffer("\r\n");} + } + + if(gDoAnnotation){ + AppendTextBuffer("Device Address: 0x%02X\r\n", + ConnectInfo->DeviceAddress); + + AppendTextBuffer("Open Pipes: %2d\r\n", + ConnectInfo->NumberOfOpenPipes); + } + + // No open pipes means the USB stack has not loaded the device + if (ConnectInfo->NumberOfOpenPipes == 0) + { + AppendTextBuffer("*!*ERROR: No open pipes!\r\n"); + } + + AppendTextBuffer("\r\n ===>Device Descriptor<===\r\n"); + //@@DisplayConnectionInfo - Device Descriptor + + if (ConnectInfo->DeviceDescriptor.bLength != 18) + { + //@@TestCase A1.1 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + ConnectInfo->DeviceDescriptor.bLength, + 18); + OOPS(); + } + + AppendTextBuffer("bLength: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.bDescriptorType); + + //@@TestCase A1.2 + //@@Not implemented - Priority 1 + //@@Descriptor Field - bcdUSB + //@@Need to check that any UVC device is set to 0x0200 or later. + AppendTextBuffer("bcdUSB: 0x%04X\r\n", + ConnectInfo->DeviceDescriptor.bcdUSB); + + AppendTextBuffer("bDeviceClass: 0x%02X", + ConnectInfo->DeviceDescriptor.bDeviceClass); + + // Quit on these device failures + if ((ConnectInfo->ConnectionStatus == DeviceFailedEnumeration) || + (ConnectInfo->ConnectionStatus == DeviceGeneralFailure)) + { + AppendTextBuffer("\r\n*!*ERROR: Device enumeration failure\r\n"); + return; + } + + // Is this an IAD device? + uIADcount = IsIADDevice((PUSBDEVICEINFO) info); + + if (uIADcount) + { + // this device configuration has 1 or more IAD descriptors + if (ConnectInfo->DeviceDescriptor.bDeviceClass == USB_MISCELLANEOUS_DEVICE) + { + tog = 0; + if (gDoAnnotation) + { + AppendTextBuffer(" -> This is a Multi-interface Function Code Device\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } else { + AppendTextBuffer("\r\n*!*ERROR: device class should be Multi-interface Function 0x%02X\r\n"\ + " When IAD descriptor is used\r\n", + USB_MISCELLANEOUS_DEVICE); + } + // Is this a UVC device? + g_chUVCversion = IsUVCDevice((PUSBDEVICEINFO) info); + } + else + { + // this is not an IAD device + switch (ConnectInfo->DeviceDescriptor.bDeviceClass) + { + case USB_INTERFACE_CLASS_DEVICE: + if(gDoAnnotation) + {AppendTextBuffer(" -> This is an Interface Class Defined Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_COMMUNICATION_DEVICE: + tog = 0; + if(gDoAnnotation) + {AppendTextBuffer(" -> This is a Communication Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_HUB_DEVICE: + tog = 0; + if(gDoAnnotation) + {AppendTextBuffer(" -> This is a HUB Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_DIAGNOSTIC_DEVICE: + tog = 0; + if(gDoAnnotation) + {AppendTextBuffer(" -> This is a Diagnostic Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_WIRELESS_CONTROLLER_DEVICE: + tog = 0; + if(gDoAnnotation) + {AppendTextBuffer(" -> This is a Wireless Controller(Bluetooth) Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_VENDOR_SPECIFIC_DEVICE: + tog = 0; + if(gDoAnnotation) + {AppendTextBuffer(" -> This is a Vendor Specific Device\r\n");} + else {AppendTextBuffer("\r\n");} + break; + + case USB_MISCELLANEOUS_DEVICE: + tog = 0; + //@@TestCase A1.3 + //@@ERROR + //@@Descriptor Field - bDeviceClass + //@@Multi-interface Function code used for non-IAD device + AppendTextBuffer("\r\n*!*ERROR: Multi-interface Function code %d used for "\ + "device with no IAD descriptors\r\n", + ConnectInfo->DeviceDescriptor.bDeviceClass); + break; + + default: + //@@TestCase A1.4 + //@@ERROR + //@@Descriptor Field - bDeviceClass + //@@An unknown device class has been defined + AppendTextBuffer("\r\n*!*ERROR: unknown bDeviceClass %d\r\n", + ConnectInfo->DeviceDescriptor.bDeviceClass); + OOPS(); + break; + } + } + + AppendTextBuffer("bDeviceSubClass: 0x%02X", + ConnectInfo->DeviceDescriptor.bDeviceSubClass); + + // check the subclass + if (uIADcount) + { + // this device configuration has 1 or more IAD descriptors + if (ConnectInfo->DeviceDescriptor.bDeviceSubClass == USB_COMMON_SUB_CLASS) + { + if (gDoAnnotation) + { + AppendTextBuffer(" -> This is the Common Class Sub Class\r\n"); + } else + { + AppendTextBuffer("\r\n"); + } + } + else + { + //@@TestCase A1.5 + //@@ERROR + //@@Descriptor Field - bDeviceSubClass + //@@An invalid device sub class used for Multi-interface Function (IAD) device + AppendTextBuffer("\r\n*!*ERROR: device SubClass should be USB Common Sub Class %d\r\n"\ + " When IAD descriptor is used\r\n", + USB_COMMON_SUB_CLASS); + OOPS(); + } + } + else + { + // Not an IAD device, so all subclass values are invalid + if(ConnectInfo->DeviceDescriptor.bDeviceSubClass > 0x00 && + ConnectInfo->DeviceDescriptor.bDeviceSubClass < 0xFF) + { + //@@TestCase A1.6 + //@@ERROR + //@@Descriptor Field - bDeviceSubClass + //@@An invalid device sub class has been defined + AppendTextBuffer("\r\n*!*ERROR: bDeviceSubClass of %d is invalid\r\n", + ConnectInfo->DeviceDescriptor.bDeviceSubClass); + OOPS(); + } else + { + AppendTextBuffer("\r\n"); + } + } + + AppendTextBuffer("bDeviceProtocol: 0x%02X", + ConnectInfo->DeviceDescriptor.bDeviceProtocol); + + // check the protocol + if (uIADcount) + { + // this device configuration has 1 or more IAD descriptors + if (ConnectInfo->DeviceDescriptor.bDeviceProtocol == USB_IAD_PROTOCOL) + { + if (gDoAnnotation) + { + AppendTextBuffer(" -> This is the Interface Association Descriptor protocol\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } + else + { + //@@TestCase A1.7 + //@@ERROR + //@@Descriptor Field - bDeviceSubClass + //@@An invalid device sub class used for Multi-interface Function (IAD) device + AppendTextBuffer("\r\n*!*ERROR: device Protocol should be USB IAD Protocol %d\r\n"\ + " When IAD descriptor is used\r\n", + USB_IAD_PROTOCOL); + OOPS(); + } + } + else + { + // Not an IAD device, so all subclass values are invalid + if(ConnectInfo->DeviceDescriptor.bDeviceProtocol > 0x00 && + ConnectInfo->DeviceDescriptor.bDeviceProtocol < 0xFF && tog==1) + { + //@@TestCase A1.8 + //@@ERROR + //@@Descriptor Field - bDeviceProtocol + //@@An invalid device protocol has been defined + AppendTextBuffer("\r\n*!*ERROR: bDeviceProtocol of %d is invalid\r\n", + ConnectInfo->DeviceDescriptor.bDeviceProtocol); + OOPS(); + } + else + { + AppendTextBuffer("\r\n"); + } + } + + AppendTextBuffer("bMaxPacketSize0: 0x%02X", + ConnectInfo->DeviceDescriptor.bMaxPacketSize0); + + if(gDoAnnotation) + { + AppendTextBuffer(" = (%d) Bytes\r\n", + ConnectInfo->DeviceDescriptor.bMaxPacketSize0); + } + else + { + AppendTextBuffer("\r\n"); + } + + switch (gDeviceSpeed){ + case UsbLowSpeed: + if(ConnectInfo->DeviceDescriptor.bMaxPacketSize0 != 8) + { + //@@TestCase A1.9 + //@@ERROR + //@@Descriptor Field - bMaxPacketSize0 + //@@An invalid bMaxPacketSize0 has been defined for a low speed device + AppendTextBuffer("*!*ERROR: Low Speed Devices require bMaxPacketSize0 = 8\r\n"); + OOPS(); + } + break; + case UsbFullSpeed: + if(!(ConnectInfo->DeviceDescriptor.bMaxPacketSize0 == 8 || + ConnectInfo->DeviceDescriptor.bMaxPacketSize0 == 16 || + ConnectInfo->DeviceDescriptor.bMaxPacketSize0 == 32 || + ConnectInfo->DeviceDescriptor.bMaxPacketSize0 == 64)) + { + //@@TestCase A1.10 + //@@ERROR + //@@Descriptor Field - bMaxPacketSize0 + //@@An invalid bMaxPacketSize0 has been defined for a full speed device + AppendTextBuffer("*!*ERROR: Full Speed Devices require bMaxPacketSize0 = 8, 16, 32, or 64\r\n"); + OOPS(); + } + break; + case UsbHighSpeed: + if(ConnectInfo->DeviceDescriptor.bMaxPacketSize0 != 64) + { + //@@TestCase A1.11 + //@@ERROR + //@@Descriptor Field - bMaxPacketSize0 + //@@An invalid bMaxPacketSize0 has been defined for a high speed device + AppendTextBuffer("*!*ERROR: High Speed Devices require bMaxPacketSize0 = 64\r\n"); + OOPS(); + } + break; + case UsbSuperSpeed: + if(ConnectInfo->DeviceDescriptor.bMaxPacketSize0 != 9) + { + AppendTextBuffer("*!*ERROR: SuperSpeed Devices require bMaxPacketSize0 = 9 (512)\r\n"); + OOPS(); + } + break; + } + + AppendTextBuffer("idVendor: 0x%04X", + ConnectInfo->DeviceDescriptor.idVendor); + + if (gDoAnnotation) + { + VendorString = GetVendorString(ConnectInfo->DeviceDescriptor.idVendor); + if (VendorString != NULL) + { + AppendTextBuffer(" = %s\r\n", + VendorString); + } + } + else {AppendTextBuffer("\r\n");} + + AppendTextBuffer("idProduct: 0x%04X\r\n", + ConnectInfo->DeviceDescriptor.idProduct); + + AppendTextBuffer("bcdDevice: 0x%04X\r\n", + ConnectInfo->DeviceDescriptor.bcdDevice); + + AppendTextBuffer("iManufacturer: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.iManufacturer); + + if (ConnectInfo->DeviceDescriptor.iManufacturer && gDoAnnotation) + { + DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iManufacturer, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + } + + AppendTextBuffer("iProduct: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.iProduct); + + if (ConnectInfo->DeviceDescriptor.iProduct && gDoAnnotation) + { + DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iProduct, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + } + + AppendTextBuffer("iSerialNumber: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.iSerialNumber); + + if (ConnectInfo->DeviceDescriptor.iSerialNumber && gDoAnnotation) + { + DisplayStringDescriptor(ConnectInfo->DeviceDescriptor.iSerialNumber, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + } + + AppendTextBuffer("bNumConfigurations: 0x%02X\r\n", + ConnectInfo->DeviceDescriptor.bNumConfigurations); + + if(ConnectInfo->DeviceDescriptor.bNumConfigurations != 1) + { + //@@TestCase A1.12 + //@@CAUTION + //@@Descriptor Field - bNumConfigurations + //@@Most host controllers do not handle more than one configuration + AppendTextBuffer("*!*CAUTION: Most host controllers will only work with "\ + "one configuration per speed\r\n"); + OOPS(); + } + + if (ConnectInfo->NumberOfOpenPipes) + { + AppendTextBuffer("\r\n ---===>Open Pipes<===---\r\n"); + DisplayPipeInfo(ConnectInfo->NumberOfOpenPipes, + ConnectInfo->PipeList); + } + + return; +} + +/***************************************************************************** + +DisplayPipeInfo() + +NumPipes - Number of pipe for we info should be displayed. + +PipeInfo - Info about the pipes. + +*****************************************************************************/ + +VOID +DisplayPipeInfo ( + ULONG NumPipes, + USB_PIPE_INFO *PipeInfo + ) +{ + ULONG i = 0; + + for (i = 0; i < NumPipes; i++) + { + DisplayEndpointDescriptor(&PipeInfo[i].EndpointDescriptor, NULL, NULL, 0, FALSE); + } + +} + +/***************************************************************************** + +GetControllerFlavorString() + +Returns the text for given controller flavor + +*****************************************************************************/ +PCHAR GetControllerFlavorString(USB_CONTROLLER_FLAVOR flavor) +{ + return(GetStringFromList(slControllerFlavor, + sizeof(slControllerFlavor) / sizeof(STRINGLIST), + flavor, + STR_UNKNOWN_CONTROLLER_FLAVOR)); +} + + + +/***************************************************************************** + +GetPowerStateString() + +Returns the descriptive string for given power state + +*****************************************************************************/ +PCHAR GetPowerStateString(WDMUSB_POWER_STATE powerState) +{ + return(GetStringFromList(slPowerState, + sizeof(slPowerState) / sizeof(STRINGLIST), + powerState, + STR_INVALID_POWER_STATE)); +} + +/***************************************************************************** + +DisplayPowerState() + +PUSB_POWER_INFO pUPI - USBUSER.H USB_Power_Info data + +*****************************************************************************/ + +VOID +DisplayPowerState( + PUSB_POWER_INFO pUPI + ) +{ + AppendTextBuffer("%s\t%s\t%s%s\t\t%s\r\n", + GetPowerStateString(pUPI->SystemState), + GetPowerStateString(pUPI->HcDevicePowerState), + GetPowerStateString(pUPI->RhDevicePowerState), + pUPI->CanWakeup ? "Yes" : "", + pUPI->IsPowered ? "Yes" : "" + ); + return; +} + + + +/***************************************************************************** + +ValidateDescAddress() + +Given a descriptor address and the Configuration Descriptor length + (saved in DisplayConfigDesc(), and initialized for each new device) +return TRUE if the descriptor is within the Configuration length +else FALSE + +*****************************************************************************/ + +BOOL +ValidateDescAddress ( + PUSB_COMMON_DESCRIPTOR commonDesc + ) +{ + if ((PUCHAR) commonDesc + commonDesc->bLength <= g_descEnd) + { + return TRUE; + } + return FALSE; +} + +/***************************************************************************** + +DisplayConfigDesc() + +ConfigDesc - The Configuration Descriptor, and associated Interface and +Endpoint Descriptors + +*****************************************************************************/ + +VOID +DisplayConfigDesc ( + PUSBDEVICEINFO info, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + PSTRING_DESCRIPTOR_NODE StringDescs + ) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + UCHAR bInterfaceClass = 0; + UCHAR bInterfaceSubClass = 0; + UCHAR bInterfaceProtocol = 0; + BOOL displayUnknown = FALSE; + + BOOL isSS; + + isSS = info->ConnectionInfoV2 + && info->ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedOrHigher + ? TRUE + : FALSE; + + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + + // initialize global Configuration start/end address and string desc address + g_pConfigDesc = ConfigDesc; + g_pStringDescs = StringDescs; + g_descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + + AppendTextBuffer("\r\n ---===>Full Configuration Descriptor<===---\r\n"); + + do + { + displayUnknown = FALSE; + + switch (commonDesc->bDescriptorType) + { + case USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE: + //@@DisplayConfigDesc - Device Qualifier Descriptor + if (commonDesc->bLength != sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)) + { + //@@TestCase A2.1 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d for Device Qualifier incorrect, "\ + "should be %d\r\n", + commonDesc->bLength, + sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)); + OOPS(); + displayUnknown = TRUE; + break; + } + DisplayDeviceQualifierDescriptor((PUSB_DEVICE_QUALIFIER_DESCRIPTOR)commonDesc); + break; + + case USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE: + //@@DisplayConfigDesc - Other Speed Configuration Descriptor + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + //@@TestCase A2.2 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d for Other Speed Configuration "\ + "incorrect, should be %d\r\n", + commonDesc->bLength, + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + OOPS(); + displayUnknown = TRUE; + } + DisplayConfigurationDescriptor( + (PUSBDEVICEINFO) info, + (PUSB_CONFIGURATION_DESCRIPTOR)commonDesc, + StringDescs); + break; + + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + //@@DisplayConfigDesc - Configuration Descriptor + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + //@@TestCase A2.3 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d for Configuration incorrect, "\ + "should be %d\r\n", + commonDesc->bLength, + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + OOPS(); + displayUnknown = TRUE; + break; + } + DisplayConfigurationDescriptor((PUSBDEVICEINFO)info, + (PUSB_CONFIGURATION_DESCRIPTOR)commonDesc, + StringDescs); + break; + + case USB_INTERFACE_DESCRIPTOR_TYPE: + //@@DisplayConfigDesc - Interface Descriptor + if ((commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR)) && + (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2))) + { + //@@TestCase A2.4 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d for Interface incorrect, "\ + "should be %d or %d\r\n", + commonDesc->bLength, + sizeof(USB_INTERFACE_DESCRIPTOR), + sizeof(USB_INTERFACE_DESCRIPTOR2)); + OOPS(); + displayUnknown = TRUE; + break; + } + bInterfaceClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceClass; + bInterfaceSubClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceSubClass; + bInterfaceProtocol = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceProtocol; + + DisplayInterfaceDescriptor( + (PUSB_INTERFACE_DESCRIPTOR)commonDesc, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + + break; + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + { + PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR epCompDesc = NULL; + PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR + sspIsochCompDesc = NULL; + + + //@@DisplayConfigDesc - Endpoint Descriptor + if ((commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR)) && + (commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR2))) + { + //@@TestCase A2.5 + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to + //@@ the required length in the USB Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d for Endpoint incorrect, "\ + "should be %d or %d\r\n", + commonDesc->bLength, + sizeof(USB_ENDPOINT_DESCRIPTOR), + sizeof(USB_ENDPOINT_DESCRIPTOR2)); + OOPS(); + displayUnknown = TRUE; + break; + } + + if (isSS) + { + epCompDesc = (PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR) + GetNextDescriptor((PUSB_COMMON_DESCRIPTOR)ConfigDesc, ConfigDesc->wTotalLength, commonDesc, -1); + } + + if (epCompDesc != NULL && + epCompDesc->bmAttributes.Isochronous.SspCompanion == 1) + { + sspIsochCompDesc = (PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR) + GetNextDescriptor((PUSB_COMMON_DESCRIPTOR)ConfigDesc, + ConfigDesc->wTotalLength, + (PUSB_COMMON_DESCRIPTOR)epCompDesc, + -1); + } + + DisplayEndpointDescriptor((PUSB_ENDPOINT_DESCRIPTOR)commonDesc, + epCompDesc, + sspIsochCompDesc, + bInterfaceClass, + TRUE); + + if (sspIsochCompDesc != NULL) + { + commonDesc = (PUSB_COMMON_DESCRIPTOR)sspIsochCompDesc; + } + else if (epCompDesc != NULL) + { + commonDesc = (PUSB_COMMON_DESCRIPTOR)epCompDesc; + } + } + + break; + + case USB_HID_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_HID_DESCRIPTOR)) + { + OOPS(); + displayUnknown = TRUE; + break; + } + DisplayHidDescriptor((PUSB_HID_DESCRIPTOR)commonDesc); + break; + + case USB_OTG_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_OTG_DESCRIPTOR)) + { + OOPS(); + displayUnknown = TRUE; + break; + } + DisplayOTGDescriptor((PUSB_OTG_DESCRIPTOR)commonDesc); + break; + + case USB_IAD_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_IAD_DESCRIPTOR)) + { + OOPS(); + displayUnknown = TRUE; + break; + } + DisplayIADDescriptor((PUSB_IAD_DESCRIPTOR)commonDesc, StringDescs, + ConfigDesc->bNumInterfaces, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + break; + + default: + //@@DisplayConfigDesc - Interface Class Device + // TODO: BUG: bInterfaceClass is initialized before this code + switch (bInterfaceClass) + { + case USB_DEVICE_CLASS_AUDIO: + displayUnknown = ! DisplayAudioDescriptor( + (PUSB_AUDIO_COMMON_DESCRIPTOR)commonDesc, + bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_VIDEO: + displayUnknown = ! DisplayVideoDescriptor( + (PVIDEO_SPECIFIC)commonDesc, + bInterfaceSubClass, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + break; + + case USB_DEVICE_CLASS_RESERVED: + //@@TestCase A2.6 + //@@ERROR + //@@Descriptor Field - bInterfaceClass + //@@An unknown interface class has been defined + AppendTextBuffer("*!*ERROR: %d is a Reserved USB Device Interface Class\r\n", + USB_DEVICE_CLASS_RESERVED); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_COMMUNICATIONS: + AppendTextBuffer(" -> This is a Communications (CDC Control) USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_HUMAN_INTERFACE: + AppendTextBuffer(" -> This is a HID USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_MONITOR: + AppendTextBuffer(" -> This is a Monitor USB Device Interface Class (This may be obsolete)\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: + AppendTextBuffer(" -> This is a Physical Interface USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_POWER: + if(bInterfaceSubClass == 1 && bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is an Image USB Device Interface Class\r\n"); + } + else + { + AppendTextBuffer(" -> This is a Power USB Device Interface Class (This may be obsolete)\r\n"); + } + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_PRINTER: + AppendTextBuffer(" -> This is a Printer USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_STORAGE: + AppendTextBuffer(" -> This is a Mass Storage USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DEVICE_CLASS_HUB: + AppendTextBuffer(" -> This is a HUB USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_CDC_DATA_INTERFACE: + AppendTextBuffer(" -> This is a CDC Data USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_CHIP_SMART_CARD_INTERFACE: + AppendTextBuffer(" -> This is a Chip/Smart Card USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_CONTENT_SECURITY_INTERFACE: + AppendTextBuffer(" -> This is a Content Security USB Device Interface Class\r\n"); + displayUnknown = TRUE; + break; + + case USB_DIAGNOSTIC_DEVICE_INTERFACE: + if(bInterfaceSubClass == 1 && bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is a Reprogrammable USB2 Compliance Diagnostic Device USB Device\r\n"); + } + else + { + //@@TestCase A2.7 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@An unknown diagnostic interface class device has been defined + AppendTextBuffer("*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + displayUnknown = TRUE; + break; + + case USB_WIRELESS_CONTROLLER_INTERFACE: + if(bInterfaceSubClass == 1 && bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is a Wireless RF Controller USB Device Interface Class with Bluetooth Programming Interface\r\n"); + } + else + { + //@@TestCase A2.8 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@An unknown wireless controller interface class device has been defined + AppendTextBuffer("*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + displayUnknown = TRUE; + break; + + case USB_APPLICATION_SPECIFIC_INTERFACE: + AppendTextBuffer(" -> This is an Application Specific USB Device Interface Class\r\n"); + + switch(bInterfaceSubClass) + { + case 1: + AppendTextBuffer(" -> This is a Device Firmware Application Specific USB Device Interface Class\r\n"); + break; + case 2: + AppendTextBuffer(" -> This is an IrDA Bridge Application Specific USB Device Interface Class\r\n"); + break; + case 3: + AppendTextBuffer(" -> This is a Test & Measurement Class (USBTMC) Application Specific USB Device Interface Class\r\n"); + break; + default: + //@@TestCase A2.9 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@A possibly invalid interface class has been defined + AppendTextBuffer("*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + displayUnknown = TRUE; + break; + + default: + if (bInterfaceClass == USB_DEVICE_CLASS_VENDOR_SPECIFIC) + { + AppendTextBuffer(" -> This is a Vendor Specific USB Device Interface Class\r\n"); + } + else + { + //@@TestCase A2.10 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@An unknown interface class has been defined + AppendTextBuffer("*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + displayUnknown = TRUE; + break; + } + break; + } + + if (displayUnknown) + { + DisplayUnknownDescriptor(commonDesc); + } + } while ((commonDesc = GetNextDescriptor((PUSB_COMMON_DESCRIPTOR)ConfigDesc, + ConfigDesc->wTotalLength, + commonDesc, + -1)) != NULL); + +#ifdef H264_SUPPORT + DoAdditionalErrorChecks(); +#endif +} + + +/***************************************************************************** + +DisplayDeviceQualifierDescriptor() + +*****************************************************************************/ + +VOID +DisplayDeviceQualifierDescriptor ( + PUSB_DEVICE_QUALIFIER_DESCRIPTOR DevQualDesc + ) +{ + //@@DisplayDeviceQualifierDescriptor - Device Qualifier Descriptor + + AppendTextBuffer("\r\n ===>Device Qualifier Descriptor<===\r\n"); + + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + DevQualDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + DevQualDesc->bDescriptorType); + + AppendTextBuffer("bcdUSB: 0x%04X\r\n", + DevQualDesc->bcdUSB); + + AppendTextBuffer("bDeviceClass: 0x%02X", + DevQualDesc->bDeviceClass); + + switch (DevQualDesc->bDeviceClass) + { + case USB_INTERFACE_CLASS_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is an Interface Class Defined Device\r\n"); + } + break; + + case USB_COMMUNICATION_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is a Communication Device\r\n"); + } + break; + + case USB_HUB_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is a HUB Device\r\n"); + } + break; + + case USB_DIAGNOSTIC_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is a Diagnostic Device\r\n"); + } + break; + + case USB_WIRELESS_CONTROLLER_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is a Wireless Controller(Bluetooth) Device\r\n"); + } + break; + + case USB_VENDOR_SPECIFIC_DEVICE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> This is a Vendor Specific Device\r\n"); + } + break; + + default: + //@@TestCase A3.1 + //@@ERROR + //@@Descriptor Field - bDeviceClass + //@@An unknown device class has been defined + AppendTextBuffer("*!*ERROR: bDeviceClass of %d is invalid\r\n", + DevQualDesc->bDeviceClass); + OOPS(); + break; + } + + AppendTextBuffer("bDeviceSubClass: 0x%02X\r\n", + DevQualDesc->bDeviceSubClass); + + if(DevQualDesc->bDeviceSubClass > 0x00 && DevQualDesc->bDeviceSubClass < 0xFF) + { + //@@TestCase A3.2 + //@@ERROR + //@@Descriptor Field - bDeviceSubClass + //@@An unknown device sub class has been defined + AppendTextBuffer("*!*ERROR: bDeviceSubClass of %d is invalid\r\n", + DevQualDesc->bDeviceSubClass); + OOPS(); + } + + AppendTextBuffer("bDeviceProtocol: 0x%02X\r\n", + DevQualDesc->bDeviceProtocol); + + if(DevQualDesc->bDeviceProtocol > 0x00 && DevQualDesc->bDeviceProtocol < 0xFF) + { + //@@TestCase A3.4 + //@@ERROR + //@@Descriptor Field - bDeviceProtocol + //@@An invalid device protocol has been defined + AppendTextBuffer("*!*ERROR: bDeviceProtocol of %d is invalid", + DevQualDesc->bDeviceProtocol); + OOPS(); + } + + //@@TestCase A3.5 + //@@Priority 1 + //@@Descriptor Field - bcdDevice + //@@We should test to verify a valid bMaxPacketSize0 based on speed + AppendTextBuffer("bMaxPacketSize0: 0x%02X", + DevQualDesc->bMaxPacketSize0); + + if(gDoAnnotation) + { + AppendTextBuffer(" = (%d) Bytes\r\n", + DevQualDesc->bMaxPacketSize0); + } + else {AppendTextBuffer("\r\n");} + + AppendTextBuffer("bNumConfigurations: 0x%02X\r\n", + DevQualDesc->bNumConfigurations); + + if(DevQualDesc->bNumConfigurations != 1) + { + //@@TestCase A3.6 + //@@CAUTION + //@@Descriptor Field - bNumConfigurations + //@@Most host controllers do not handle more than one configuration + AppendTextBuffer("*!*CAUTION: Most host controllers will only work with one configuration per speed\r\n"); + OOPS(); + } + + AppendTextBuffer("bReserved: 0x%02X\r\n", + DevQualDesc->bReserved); + + if(DevQualDesc->bReserved != 0) + { + AppendTextBuffer("*!*WARNING: bReserved needs to be set to 0 to be valid\r\n"); + OOPS(); + } + + +} + +VOID +DisplayUsb20CapabilityExtensionDescriptor ( + PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR extCapDesc + ) +{ + AppendTextBuffer("\r\n ===>USB 2.0 Extension Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + extCapDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + extCapDesc->bDescriptorType); + AppendTextBuffer("bDevCapabilityType: 0x%02X\r\n", + extCapDesc->bDevCapabilityType); + AppendTextBuffer("bmAttributes: 0x%08X", + extCapDesc->bmAttributes); + if (extCapDesc->bmAttributes.AsUlong & USB_DEVICE_CAPABILITY_USB20_EXTENSION_BMATTRIBUTES_RESERVED_MASK) + { + if(gDoAnnotation) + { + AppendTextBuffer("\r\n*!*ERROR: bits 31..2 and bit 0 are reserved and must be 0\r\n"); + } + } + if (extCapDesc->bmAttributes.LPMCapable == 1) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Supports Link Power Management protocol\r\n"); + } + } + if (extCapDesc->bmAttributes.AsUlong == 0) + { + AppendTextBuffer("\r\n"); + } +} + +VOID +DisplaySuperSpeedCapabilityExtensionDescriptor ( + PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR ssCapDesc + ) +{ + AppendTextBuffer("\r\n ===>SuperSpeed USB Device Capability Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + ssCapDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ssCapDesc->bDescriptorType); + AppendTextBuffer("bDevCapabilityType: 0x%02X\r\n", + ssCapDesc->bDevCapabilityType); + AppendTextBuffer("bmAttributes: 0x%02X\r\n", + ssCapDesc->bmAttributes); + if (ssCapDesc->bmAttributes & USB_DEVICE_CAPABILITY_SUPERSPEED_BMATTRIBUTES_RESERVED_MASK) + { + if(gDoAnnotation) + { + AppendTextBuffer("\r\n*!*ERROR: bits 7:2 and bit 0 are reserved\r\n"); + } + } + if (ssCapDesc->bmAttributes & USB_DEVICE_CAPABILITY_SUPERSPEED_BMATTRIBUTES_LTM_CAPABLE) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> capable of generating Latency Tolerance Messages\r\n"); + } + } + AppendTextBuffer("wSpeedsSupported: 0x%02X\r\n", + ssCapDesc->wSpeedsSupported); + + if (ssCapDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_LOW) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Supports low-speed operation\r\n"); + } + } + if (ssCapDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_FULL) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Supports full-speed operation\r\n"); + } + } + if (ssCapDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_HIGH) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Supports high-speed operation\r\n"); + } + } + if (ssCapDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_SUPER) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Supports SuperSpeed operation\r\n"); + } + } + if (ssCapDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_RESERVED_MASK) + { + if(gDoAnnotation) + { + AppendTextBuffer("\r\n*!*ERROR: bits 15:4 are reserved\r\n"); + } + } + if (!gDoAnnotation) + { + AppendTextBuffer("\r\n"); + } + AppendTextBuffer("bFunctionalitySupport: 0x%02X", + ssCapDesc->bFunctionalitySupport); + if(gDoAnnotation) + { + switch (ssCapDesc->bFunctionalitySupport) + { + case UsbLowSpeed: + AppendTextBuffer(" -> lowest speed = low-speed\r\n"); + break; + case UsbFullSpeed: + AppendTextBuffer(" -> lowest speed = full-speed\r\n"); + break; + case UsbHighSpeed: + AppendTextBuffer(" -> lowest speed = high-speed\r\n"); + break; + case UsbSuperSpeed: + AppendTextBuffer(" -> lowest speed = SuperSpeed\r\n"); + break; + default: + AppendTextBuffer("\r\n*!*ERROR: Invalid value\r\n"); + break; + } + } + else + { + AppendTextBuffer("\r\n"); + } + + AppendTextBuffer("bU1DevExitLat: 0x%02X", + ssCapDesc->bU1DevExitLat); + if(gDoAnnotation) + { + if (ssCapDesc->bU1DevExitLat <= USB_DEVICE_CAPABILITY_SUPERSPEED_U1_DEVICE_EXIT_MAX_VALUE) + { + AppendTextBuffer(" -> less than %d micro-seconds\r\n", + ssCapDesc->bU1DevExitLat); + } + else + { + AppendTextBuffer("\r\n*!*ERROR: Invalid value\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + + AppendTextBuffer("wU2DevExitLat: 0x%04X", + ssCapDesc->wU2DevExitLat); + if(gDoAnnotation) + { + if (ssCapDesc->wU2DevExitLat <= USB_DEVICE_CAPABILITY_SUPERSPEED_U2_DEVICE_EXIT_MAX_VALUE) + { + AppendTextBuffer(" -> less than %d micro-seconds\r\n", + ssCapDesc->wU2DevExitLat); + } + else + { + AppendTextBuffer("\r\n*!*ERROR: Invalid value\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } +} + + +VOID +DisplayContainerIdCapabilityExtensionDescriptor ( + PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR containerIdCapDesc + ) +{ + LPGUID pGuid; + + AppendTextBuffer("\r\n ===>Container ID Capability Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + containerIdCapDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + containerIdCapDesc->bDescriptorType); + AppendTextBuffer("bDevCapabilityType: 0x%02X\r\n", + containerIdCapDesc->bDevCapabilityType); + AppendTextBuffer("bReserved: 0x%02X\r\n", + containerIdCapDesc->bReserved); + if (containerIdCapDesc->bReserved != 0) + { + if(gDoAnnotation) + { + AppendTextBuffer("*!*ERROR: field is reserved\r\n"); + } + } + + pGuid = (LPGUID)containerIdCapDesc->ContainerID; + AppendTextBuffer("Container ID: "); + AppendTextBuffer("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\r\n", + pGuid->Data1, + pGuid->Data2, + pGuid->Data3, + pGuid->Data4[0], + pGuid->Data4[1], + pGuid->Data4[2], + pGuid->Data4[3], + pGuid->Data4[4], + pGuid->Data4[5], + pGuid->Data4[6], + pGuid->Data4[7]); +} + +/***************************************************************************** + +DisplayBosDescriptor() + +BosDesc - The Binary Object Store (BOS) Descriptor, and associated Descriptors + +*****************************************************************************/ + +VOID +DisplayBosDescriptor ( + PUSB_BOS_DESCRIPTOR BosDesc + ) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + PUSB_DEVICE_CAPABILITY_DESCRIPTOR capDesc = NULL; + + AppendTextBuffer("\r\n ===>BOS Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + BosDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + BosDesc->bDescriptorType); + AppendTextBuffer("wTotalLength: 0x%04X\r\n", + BosDesc->wTotalLength); + AppendTextBuffer("bNumDeviceCaps: 0x%02X\r\n", + BosDesc->bNumDeviceCaps); + + commonDesc = (PUSB_COMMON_DESCRIPTOR)BosDesc; + + while ((commonDesc = GetNextDescriptor((PUSB_COMMON_DESCRIPTOR)BosDesc, + BosDesc->wTotalLength, + commonDesc, + -1)) != NULL) + { + switch (commonDesc->bDescriptorType) + { + case USB_DEVICE_CAPABILITY_DESCRIPTOR_TYPE: + + capDesc = (PUSB_DEVICE_CAPABILITY_DESCRIPTOR)commonDesc; + + switch (capDesc->bDevCapabilityType) + { + case USB_DEVICE_CAPABILITY_USB20_EXTENSION: + DisplayUsb20CapabilityExtensionDescriptor((PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR)capDesc); + break; + case USB_DEVICE_CAPABILITY_SUPERSPEED_USB: + DisplaySuperSpeedCapabilityExtensionDescriptor((PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR)capDesc); + break; + case USB_DEVICE_CAPABILITY_CONTAINER_ID: + DisplayContainerIdCapabilityExtensionDescriptor((PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR)capDesc); + break; + default: + AppendTextBuffer("\r\n ===>Unknown Capability Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + capDesc->bLength); + AppendTextBuffer("bType: 0x%02X\r\n", + capDesc->bLength); + AppendTextBuffer("bDevCapabilityType: 0x%02X\r\n", + capDesc->bDevCapabilityType); + + DisplayRemainingUnknownDescriptor((PUCHAR)commonDesc, + (ULONG)sizeof(USB_DEVICE_CAPABILITY_DESCRIPTOR), + commonDesc->bLength); + break; + } + break; + + default: + DisplayUnknownDescriptor(commonDesc); + break; + } + } +} + + +/***************************************************************************** + +DisplayConfigurationDescriptor() + +*****************************************************************************/ + +VOID +DisplayConfigurationDescriptor ( + PUSBDEVICEINFO info, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, + PSTRING_DESCRIPTOR_NODE StringDescs + ) +{ + UINT uCount = 0; + BOOL isSS; + + + isSS = info->ConnectionInfoV2 + && (info->ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedOrHigher || + info->ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher) + ? TRUE + : FALSE; + + AppendTextBuffer("\r\n ===>Configuration Descriptor<===\r\n"); + //@@DisplayConfigurationDescriptor - Configuration Descriptor + + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + ConfigDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + ConfigDesc->bDescriptorType); + + //@@TestCase A4.1 + //@@Priority 1 + //@@Descriptor Field - wTotalLength + //@@Verify Configuration length is valid + AppendTextBuffer("wTotalLength: 0x%04X", + ConfigDesc->wTotalLength); + uCount = GetConfigurationSize(info); + if (uCount != ConfigDesc->wTotalLength) { + AppendTextBuffer("\r\n*!*ERROR: Invalid total configuration size 0x%02X, should be 0x%02X\r\n", + ConfigDesc->wTotalLength, uCount); + } else { + AppendTextBuffer(" -> Validated\r\n"); + } + + //@@TestCase A4.2 + //@@Priority 1 + //@@Descriptor Field - bNumInterfaces + //@@Verify the number of interfaces is valid + AppendTextBuffer("bNumInterfaces: 0x%02X\r\n", + ConfigDesc->bNumInterfaces); + +/* Need to check spec vs composite devices + uCount = GetInterfaceCount(info); + if (uCount != ConfigDesc->bNumInterfaces) { + AppendTextBuffer("\r\n*!*ERROR: Invalid total Interfaces %d, should be %d\r\n", + ConfigDesc->bNumInterfaces, uCount); + } else { + AppendTextBuffer(" -> Validated\r\n"); + } +*/ + + AppendTextBuffer("bConfigurationValue: 0x%02X\r\n", + ConfigDesc->bConfigurationValue); + + if(ConfigDesc->bConfigurationValue != 1) + { + //@@TestCase A4.3 + //@@CAUTION + //@@Descriptor Field - bConfigurationValue + //@@Most host controllers do not handle more than one configuration + AppendTextBuffer("*!*CAUTION: Most host controllers will only work with one configuration per speed\r\n"); + OOPS(); + } + + AppendTextBuffer("iConfiguration: 0x%02X\r\n", + ConfigDesc->iConfiguration); + + if (ConfigDesc->iConfiguration && gDoAnnotation) + { + DisplayStringDescriptor(ConfigDesc->iConfiguration, + StringDescs, + info->DeviceInfoNode != NULL? info->DeviceInfoNode->LatestDevicePowerState: PowerDeviceUnspecified); + } + + AppendTextBuffer("bmAttributes: 0x%02X", + ConfigDesc->bmAttributes); + + if (info->ConnectionInfo->DeviceDescriptor.bcdUSB == 0x0100) + { + if (ConfigDesc->bmAttributes & USB_CONFIG_SELF_POWERED) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Self Powered\r\n"); + } + } + if (ConfigDesc->bmAttributes & USB_CONFIG_BUS_POWERED) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Bus Powered\r\n"); + } + } + } + else + { + if (ConfigDesc->bmAttributes & USB_CONFIG_SELF_POWERED) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Self Powered\r\n"); + } + } + else + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Bus Powered\r\n"); + } + } + if ((ConfigDesc->bmAttributes & USB_CONFIG_BUS_POWERED) == 0) + { + AppendTextBuffer("\r\n*!*ERROR: Bit 7 is reserved and must be set\r\n"); + OOPS(); + } + } + + if (ConfigDesc->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Remote Wakeup\r\n"); + } + } + + if (ConfigDesc->bmAttributes & USB_CONFIG_RESERVED) + { + //@@TestCase A4.4 + //@@WARNING + //@@Descriptor Field - bmAttributes + //@@A bit has been set in reserved space + AppendTextBuffer("\r\n*!*ERROR: Bits 4...0 are reserved\r\n"); + OOPS(); + } + + AppendTextBuffer("MaxPower: 0x%02X", + ConfigDesc->MaxPower); + + if(gDoAnnotation) + { + AppendTextBuffer(" = %3d mA\r\n", + isSS ? ConfigDesc->MaxPower * 8 : ConfigDesc->MaxPower * 2); + } + else {AppendTextBuffer("\r\n");} + +} + +/***************************************************************************** + +DisplayInterfaceDescriptor() + +*****************************************************************************/ + +VOID +DisplayInterfaceDescriptor ( + PUSB_INTERFACE_DESCRIPTOR InterfaceDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayInterfaceDescriptor - Interface Descriptor + AppendTextBuffer("\r\n ===>Interface Descriptor<===\r\n"); + + //length checked in DisplayConfigDesc() + AppendTextBuffer("bLength: 0x%02X\r\n", + InterfaceDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + InterfaceDesc->bDescriptorType); + + //@@TestCase A5.1 + //@@Priority 1 + //@@Descriptor Field - bInterfaceNumber + //@@Question - Should we test to verify bInterfaceNumber is valid? + AppendTextBuffer("bInterfaceNumber: 0x%02X\r\n", + InterfaceDesc->bInterfaceNumber); + + //@@TestCase A5.2 + //@@Priority 1 + //@@Descriptor Field - bAlternateSetting + //@@Question - Should we test to verify bAlternateSetting is valid? + AppendTextBuffer("bAlternateSetting: 0x%02X\r\n", + InterfaceDesc->bAlternateSetting); + + //@@TestCase A5.3 + //@@Priority 1 + //@@Descriptor Field - bNumEndpoints + //@@Question - Should we test to verify bNumEndpoints is valid? + AppendTextBuffer("bNumEndpoints: 0x%02X\r\n", + InterfaceDesc->bNumEndpoints); + + AppendTextBuffer("bInterfaceClass: 0x%02X", + InterfaceDesc->bInterfaceClass); + + switch (InterfaceDesc->bInterfaceClass) + { + case USB_DEVICE_CLASS_AUDIO: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Audio Interface Class\r\n"); + } + + AppendTextBuffer("bInterfaceSubClass: 0x%02X", + InterfaceDesc->bInterfaceSubClass); + + if(gDoAnnotation) + { + switch (InterfaceDesc->bInterfaceSubClass) + { + case USB_AUDIO_SUBCLASS_AUDIOCONTROL: + AppendTextBuffer(" -> Audio Control Interface SubClass\r\n"); + break; + + case USB_AUDIO_SUBCLASS_AUDIOSTREAMING: + AppendTextBuffer(" -> Audio Streaming Interface SubClass\r\n"); + break; + + case USB_AUDIO_SUBCLASS_MIDISTREAMING: + AppendTextBuffer(" -> MIDI Streaming Interface SubClass\r\n"); + break; + + default: + //@@TestCase A5.4 + //@@CAUTION + //@@Descriptor Field - bInterfaceSubClass + //@@Invalid bInterfaceSubClass + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid bInterfaceSubClass\r\n"); + OOPS(); + break; + } + } + break; + + case USB_DEVICE_CLASS_VIDEO: + if(gDoAnnotation) + AppendTextBuffer(" -> Video Interface Class\r\n"); + + AppendTextBuffer("bInterfaceSubClass: 0x%02X", + InterfaceDesc->bInterfaceSubClass); + + switch(InterfaceDesc->bInterfaceSubClass) + { + case VIDEO_SUBCLASS_CONTROL: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Video Control Interface SubClass\r\n"); + } + break; + + case VIDEO_SUBCLASS_STREAMING: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Video Streaming Interface SubClass\r\n"); + } + break; + + default: + //@@TestCase A5.5 + //@@CAUTION + //@@Descriptor Field - bInterfaceSubClass + //@@Invalid bInterfaceSubClass + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid bInterfaceSubClass\r\n"); + OOPS(); + break; + } + break; + + case USB_DEVICE_CLASS_HUMAN_INTERFACE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> HID Interface Class\r\n"); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_HUB: + if(gDoAnnotation) + { + AppendTextBuffer(" -> HUB Interface Class\r\n"); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_RESERVED: + //@@TestCase A5.6 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@A reserved USB Device Interface Class has been defined + AppendTextBuffer("\r\n*!*CAUTION: %d is a Reserved USB Device Interface Class\r\n", + USB_DEVICE_CLASS_RESERVED); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_COMMUNICATIONS: + AppendTextBuffer(" -> This is Communications (CDC Control) USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_MONITOR: + AppendTextBuffer(" -> This is a Monitor USB Device Interface Class*** (This may be obsolete)\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: + AppendTextBuffer(" -> This is a Physical Interface USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_POWER: + if(InterfaceDesc->bInterfaceSubClass == 1 && InterfaceDesc->bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is an Image USB Device Interface Class\r\n"); + } + else + { + AppendTextBuffer(" -> This is a Power USB Device Interface Class (This may be obsolete)\r\n"); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_PRINTER: + AppendTextBuffer(" -> This is a Printer USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DEVICE_CLASS_STORAGE: + AppendTextBuffer(" -> This is a Mass Storage USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_CDC_DATA_INTERFACE: + AppendTextBuffer(" -> This is a CDC Data USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_CHIP_SMART_CARD_INTERFACE: + AppendTextBuffer(" -> This is a Chip/Smart Card USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_CONTENT_SECURITY_INTERFACE: + AppendTextBuffer(" -> This is a Content Security USB Device Interface Class\r\n"); + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_DIAGNOSTIC_DEVICE_INTERFACE: + if(InterfaceDesc->bInterfaceSubClass == 1 && InterfaceDesc->bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is a Reprogrammable USB2 Compliance Diagnostic Device USB Device\r\n"); + } + else + { + //@@TestCase A5.7 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_WIRELESS_CONTROLLER_INTERFACE: + if(InterfaceDesc->bInterfaceSubClass == 1 && InterfaceDesc->bInterfaceProtocol == 1) + { + AppendTextBuffer(" -> This is a Wireless RF Controller USB Device Interface Class with Bluetooth Programming Interface\r\n"); + } + else + { + //@@TestCase A5.8 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + case USB_APPLICATION_SPECIFIC_INTERFACE: + AppendTextBuffer(" -> This is an Application Specific USB Device Interface Class\r\n"); + + switch(InterfaceDesc->bInterfaceSubClass) + { + case 1: + AppendTextBuffer(" -> This is a Device Firmware Application Specific USB Device Interface Class\r\n"); + break; + case 2: + AppendTextBuffer(" -> This is an IrDA Bridge Application Specific USB Device Interface Class\r\n"); + break; + case 3: + AppendTextBuffer(" -> This is a Test & Measurement Class (USBTMC) Application Specific USB Device Interface Class\r\n"); + break; + default: + //@@TestCase A5.9 + //@@CAUTION + //@@Descriptor Field - bInterfaceClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + + default: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Interface Class Unknown to USBView\r\n"); + } + AppendTextBuffer("bInterfaceSubClass: 0x%02X\r\n", + InterfaceDesc->bInterfaceSubClass); + break; + } + + AppendTextBuffer("bInterfaceProtocol: 0x%02X\r\n", + InterfaceDesc->bInterfaceProtocol); + + //This is basically the check for PC_PROTOCOL_UNDEFINED + if ((InterfaceDesc->bInterfaceClass == USB_DEVICE_CLASS_VIDEO) || + (InterfaceDesc->bInterfaceClass == USB_DEVICE_CLASS_AUDIO)) + { + if(InterfaceDesc->bInterfaceProtocol != PC_PROTOCOL_UNDEFINED) + { + //@@TestCase A5.10 + //@@WARNING + //@@Descriptor Field - iInterface + //@@bInterfaceProtocol must be set to PC_PROTOCOL_UNDEFINED + AppendTextBuffer("*!*WARNING: must be set to PC_PROTOCOL_UNDEFINED %d for this class\r\n", + PC_PROTOCOL_UNDEFINED); + OOPS(); + } + } + + AppendTextBuffer("iInterface: 0x%02X\r\n", + InterfaceDesc->iInterface); + + if(gDoAnnotation) + { + if (InterfaceDesc->iInterface) + { + DisplayStringDescriptor(InterfaceDesc->iInterface, + StringDescs, + LatestDevicePowerState); + } + } + + if (InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR2)) + { + PUSB_INTERFACE_DESCRIPTOR2 interfaceDesc2; + + interfaceDesc2 = (PUSB_INTERFACE_DESCRIPTOR2)InterfaceDesc; + + AppendTextBuffer("wNumClasses: 0x%04X\r\n", + interfaceDesc2->wNumClasses); + } + +} + +/***************************************************************************** + +DisplayEndpointDescriptor() + +*****************************************************************************/ + +VOID +DisplayEndpointDescriptor ( + _In_ PUSB_ENDPOINT_DESCRIPTOR + EndpointDesc, + _In_opt_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR + EpCompDesc, + _In_opt_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR + SspIsochEpCompDesc, + _In_ UCHAR InterfaceClass, + _In_ BOOLEAN EpCompDescAvail + ) +{ + UCHAR epType = EndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK; + PUSB_HIGH_SPEED_MAXPACKET hsMaxPacket; + + AppendTextBuffer("\r\n ===>Endpoint Descriptor<===\r\n"); + //@@DisplayEndpointDescriptor - Endpoint Descriptor + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + EndpointDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + EndpointDesc->bDescriptorType); + + AppendTextBuffer("bEndpointAddress: 0x%02X", + EndpointDesc->bEndpointAddress); + + if(gDoAnnotation) + { + if(USB_ENDPOINT_DIRECTION_OUT(EndpointDesc->bEndpointAddress)) + { + AppendTextBuffer(" -> Direction: OUT - EndpointID: %d\r\n", + (EndpointDesc->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK)); + } + else if(USB_ENDPOINT_DIRECTION_IN(EndpointDesc->bEndpointAddress)) + { + AppendTextBuffer(" -> Direction: IN - EndpointID: %d\r\n", + (EndpointDesc->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK)); + } + else + { + //@@TestCase A6.1 + //@@ERROR + //@@Descriptor Field - bEndpointAddress + //@@An invalid endpoint addressl has been defined + AppendTextBuffer("\r\n*!*ERROR: This appears to be an invalid bEndpointAddress\r\n"); + OOPS(); + } + } + else {AppendTextBuffer("\r\n");} + + AppendTextBuffer("bmAttributes: 0x%02X", + EndpointDesc->bmAttributes); + + if(gDoAnnotation) + { + AppendTextBuffer(" -> "); + + switch (epType) + { + case USB_ENDPOINT_TYPE_CONTROL: + AppendTextBuffer("Control Transfer Type\r\n"); + if (EndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_CONTROL_RESERVED_MASK) + { + AppendTextBuffer("\r\n*!*ERROR: Bits 7..2 are reserved and must be set to 0\r\n"); + OOPS(); + } + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + AppendTextBuffer("Isochronous Transfer Type, Synchronization Type = "); + + switch (USB_ENDPOINT_TYPE_ISOCHRONOUS_SYNCHRONIZATION(EndpointDesc->bmAttributes)) + { + case USB_ENDPOINT_TYPE_ISOCHRONOUS_SYNCHRONIZATION_NO_SYNCHRONIZATION: + AppendTextBuffer("No Synchronization"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_SYNCHRONIZATION_ASYNCHRONOUS: + AppendTextBuffer("Asynchronous"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_SYNCHRONIZATION_ADAPTIVE: + AppendTextBuffer("Adaptive"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_SYNCHRONIZATION_SYNCHRONOUS: + AppendTextBuffer("Synchronous"); + break; + } + AppendTextBuffer(", Usage Type = "); + + switch (USB_ENDPOINT_TYPE_ISOCHRONOUS_USAGE(EndpointDesc->bmAttributes)) + { + case USB_ENDPOINT_TYPE_ISOCHRONOUS_USAGE_DATA_ENDOINT: + AppendTextBuffer("Data Endpoint\r\n"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_USAGE_FEEDBACK_ENDPOINT: + AppendTextBuffer("Feedback Endpoint\r\n"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_USAGE_IMPLICIT_FEEDBACK_DATA_ENDPOINT: + AppendTextBuffer("Implicit Feedback Data Endpoint\r\n"); + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS_USAGE_RESERVED: + //@@TestCase A6.2 + //@@ERROR + //@@Descriptor Field - bmAttributes + //@@A reserved bit has a value + AppendTextBuffer("\r\n*!*ERROR: This value is Reserved\r\n"); + OOPS(); + break; + } + if (EndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_ISOCHRONOUS_RESERVED_MASK) + { + AppendTextBuffer("\r\n*!*ERROR: Bits 7..6 are reserved and must be set to 0\r\n"); + OOPS(); + } + break; + + case USB_ENDPOINT_TYPE_BULK: + AppendTextBuffer("Bulk Transfer Type\r\n"); + if (EndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_BULK_RESERVED_MASK) + { + AppendTextBuffer("\r\n*!*ERROR: Bits 7..2 are reserved and must be set to 0\r\n"); + OOPS(); + } + break; + + case USB_ENDPOINT_TYPE_INTERRUPT: + + if (gDeviceSpeed != UsbSuperSpeed) + { + AppendTextBuffer("Interrupt Transfer Type\r\n"); + if (EndpointDesc->bmAttributes & USB_20_ENDPOINT_TYPE_INTERRUPT_RESERVED_MASK) + { + AppendTextBuffer("\r\n*!*ERROR: Bits 7..2 are reserved and must be set to 0\r\n"); + OOPS(); + } + } + else + { + AppendTextBuffer("Interrupt Transfer Type, Usage Type = "); + + switch (USB_30_ENDPOINT_TYPE_INTERRUPT_USAGE(EndpointDesc->bmAttributes)) + { + case USB_30_ENDPOINT_TYPE_INTERRUPT_USAGE_PERIODIC: + AppendTextBuffer("Periodic\r\n"); + break; + + case USB_30_ENDPOINT_TYPE_INTERRUPT_USAGE_NOTIFICATION: + AppendTextBuffer("Notification\r\n"); + break; + + case USB_30_ENDPOINT_TYPE_INTERRUPT_USAGE_RESERVED10: + case USB_30_ENDPOINT_TYPE_INTERRUPT_USAGE_RESERVED11: + AppendTextBuffer("\r\n*!*ERROR: This value is Reserved\r\n"); + OOPS(); + break; + } + + if (EndpointDesc->bmAttributes & USB_30_ENDPOINT_TYPE_INTERRUPT_RESERVED_MASK) + { + AppendTextBuffer("\r\n*!*ERROR: Bits 7..6 and 3..2 are reserved and must be set to 0\r\n"); + OOPS(); + } + + if (EpCompDescAvail) + { + if (EpCompDesc == NULL) + { + AppendTextBuffer("\r\n*!*ERROR: Endpoint Companion Descriptor missing\r\n"); + OOPS(); + } + else if (EpCompDesc->bmAttributes.Isochronous.SspCompanion == 1 && + SspIsochEpCompDesc == NULL) + { + AppendTextBuffer("\r\n*!*ERROR: SuperSpeedPlus Isoch Endpoint Companion Descriptor missing\r\n"); + OOPS(); + } + } + } + break; + } + } + else + { + AppendTextBuffer("\r\n"); + } + + //@@TestCase A6.3 + //@@Priority 1 + //@@Descriptor Field - bInterfaceNumber + //@@Question - Should we test to verify bInterfaceNumber is valid? + AppendTextBuffer("wMaxPacketSize: 0x%04X", + EndpointDesc->wMaxPacketSize); + if(gDoAnnotation) + { + switch (gDeviceSpeed) + { + case UsbSuperSpeed: + switch (epType) + { + case USB_ENDPOINT_TYPE_BULK: + if (EndpointDesc->wMaxPacketSize != USB_ENDPOINT_SUPERSPEED_BULK_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: SuperSpeed Bulk endpoints must be %d bytes\r\n", + USB_ENDPOINT_SUPERSPEED_BULK_MAX_PACKET_SIZE); + } + else + { + AppendTextBuffer("\r\n"); + } + break; + + case USB_ENDPOINT_TYPE_CONTROL: + if (EndpointDesc->wMaxPacketSize != USB_ENDPOINT_SUPERSPEED_CONTROL_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: SuperSpeed Control endpoints must be %d bytes\r\n", + USB_ENDPOINT_SUPERSPEED_CONTROL_MAX_PACKET_SIZE); + } + else + { + AppendTextBuffer("\r\n"); + } + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + + if (EpCompDesc != NULL) + { + if (EpCompDesc->bMaxBurst > 0) + { + if (EndpointDesc->wMaxPacketSize != USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: SuperSpeed isochronous endpoints must have wMaxPacketSize value of %d bytes\r\n", + USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE); + AppendTextBuffer(" when the SuperSpeed endpoint companion descriptor bMaxBurst value is greater than 0\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } + else if (EndpointDesc->wMaxPacketSize > USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: Invalid SuperSpeed isochronous maximum packet size\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + break; + + case USB_ENDPOINT_TYPE_INTERRUPT: + + if (EpCompDesc != NULL) + { + if (EpCompDesc->bMaxBurst > 0) + { + if (EndpointDesc->wMaxPacketSize != USB_ENDPOINT_SUPERSPEED_INTERRUPT_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: SuperSpeed interrupt endpoints must have wMaxPacketSize value of %d bytes\r\n", + USB_ENDPOINT_SUPERSPEED_INTERRUPT_MAX_PACKET_SIZE); + AppendTextBuffer(" when the SuperSpeed endpoint companion descriptor bMaxBurst value is greater than 0\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } + else if (EndpointDesc->wMaxPacketSize > USB_ENDPOINT_SUPERSPEED_INTERRUPT_MAX_PACKET_SIZE) + { + AppendTextBuffer("\r\n*!*ERROR: Invalid SuperSpeed interrupt maximum packet size\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + } + else + { + AppendTextBuffer("\r\n"); + } + break; + } + break; + + case UsbHighSpeed: + hsMaxPacket = (PUSB_HIGH_SPEED_MAXPACKET)&EndpointDesc->wMaxPacketSize; + + switch (epType) + { + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + case USB_ENDPOINT_TYPE_INTERRUPT: + switch (hsMaxPacket->HSmux) { + case 0: + if ((hsMaxPacket->MaxPacket < 1) || (hsMaxPacket->MaxPacket >1024)) + { + AppendTextBuffer("*!*ERROR: Invalid maximum packet size, should be between 1 and 1024\r\n"); + } + break; + + case 1: + if ((hsMaxPacket->MaxPacket < 513) || (hsMaxPacket->MaxPacket >1024)) + { + AppendTextBuffer("*!*ERROR: Invalid maximum packet size, should be between 513 and 1024\r\n"); + } + break; + + case 2: + if ((hsMaxPacket->MaxPacket < 683) || (hsMaxPacket->MaxPacket >1024)) + { + AppendTextBuffer("*!*ERROR: Invalid maximum packet size, should be between 683 and 1024\r\n"); + } + break; + + case 3: + AppendTextBuffer("*!*ERROR: Bits 12-11 set to Reserved value in wMaxPacketSize\r\n"); + break; + } + + AppendTextBuffer(" = %d transactions per microframe, 0x%02X max bytes\r\n", hsMaxPacket->HSmux + 1, hsMaxPacket->MaxPacket); + break; + + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_CONTROL: + AppendTextBuffer(" = 0x%02X max bytes\r\n", hsMaxPacket->MaxPacket); + break; + } + break; + + case UsbFullSpeed: + // full speed + AppendTextBuffer(" = 0x%02X bytes\r\n", + EndpointDesc->wMaxPacketSize & 0x7FF); + break; + default: + // low or invalid speed + if (InterfaceClass == USB_DEVICE_CLASS_VIDEO) + { + AppendTextBuffer(" = Invalid bus speed for USB Video Class\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + break; + } + } + else + { + AppendTextBuffer("\r\n"); + } + + if (EndpointDesc->wMaxPacketSize & 0xE000) + { + //@@TestCase A6.4 + //@@Priority 1 + //@@OTG Descriptor Field - wMaxPacketSize + //@@Attribute bits D7-2 reserved (reset to 0) + AppendTextBuffer("*!*ERROR: wMaxPacketSize bits 15-13 should be 0\r\n"); + } + + if (EndpointDesc->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR)) + { + //@@TestCase A6.5 + //@@Priority 1 + //@@Descriptor Field - bInterfaceNumber + //@@Question - Should we test to verify bInterfaceNumber is valid? + AppendTextBuffer("bInterval: 0x%02X\r\n", + EndpointDesc->bInterval); + } + else + { + PUSB_ENDPOINT_DESCRIPTOR2 endpointDesc2; + + endpointDesc2 = (PUSB_ENDPOINT_DESCRIPTOR2)EndpointDesc; + + AppendTextBuffer("wInterval: 0x%04X\r\n", + endpointDesc2->wInterval); + + AppendTextBuffer("bSyncAddress: 0x%02X\r\n", + endpointDesc2->bSyncAddress); + } + + if (EpCompDesc != NULL) + { + DisplayEndointCompanionDescriptor(EpCompDesc, SspIsochEpCompDesc, epType); + } + if (SspIsochEpCompDesc != NULL) + { + DisplaySuperSpeedPlusIsochEndpointCompanionDescriptor(SspIsochEpCompDesc); + } + +} + +/***************************************************************************** + +DisplaySuperSpeedPlusIsochEndpointCompanionDescriptor() + +*****************************************************************************/ +VOID +DisplaySuperSpeedPlusIsochEndpointCompanionDescriptor( + _In_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR SspIsochEpCompDesc + ) + { + AppendTextBuffer("\r\n ===>SuperSpeedPlus Isochronous Endpoint Companion Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + SspIsochEpCompDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + SspIsochEpCompDesc->bDescriptorType); + + AppendTextBuffer("wReserved: 0x%02X\r\n", + SspIsochEpCompDesc->wReserved); + + if (gDoAnnotation) + { + if (SspIsochEpCompDesc->wReserved != 0) + { + AppendTextBuffer("*!*ERROR: field is reserved\r\n"); + } + } + + AppendTextBuffer("dwBytesPerInterval: 0x%04X\r\n", + SspIsochEpCompDesc->dwBytesPerInterval); +} + +/***************************************************************************** + +DisplayEndointCompanionDescriptor() + +*****************************************************************************/ +VOID +DisplayEndointCompanionDescriptor ( + _In_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR EpCompDesc, + _In_opt_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR SspIsochEpCompDesc, + _In_ UCHAR DescType + ) +{ + AppendTextBuffer("\r\n ===>SuperSpeed Endpoint Companion Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + EpCompDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + EpCompDesc->bDescriptorType); + + AppendTextBuffer("bMaxBurst: 0x%02X\r\n", + EpCompDesc->bMaxBurst); + + AppendTextBuffer("bmAttributes: 0x%02X", + EpCompDesc->bmAttributes.AsUchar); + if(gDoAnnotation) + { + switch (DescType) + { + case USB_ENDPOINT_TYPE_CONTROL: + case USB_ENDPOINT_TYPE_INTERRUPT: + if (EpCompDesc->bmAttributes.AsUchar != 0) + { + AppendTextBuffer("*!*ERROR: Control/Interrupt SuperSpeed endpoints do not support streams\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + break; + case USB_ENDPOINT_TYPE_BULK: + if(EpCompDesc->bmAttributes.Bulk.MaxStreams == 0) + { + AppendTextBuffer("The bulk endpoint does not define streams (MaxStreams == 0)\r\n"); + } + else + { + AppendTextBuffer(" = %d streams supported\r\n", 1 << EpCompDesc->bmAttributes.Bulk.MaxStreams); + } + + if (EpCompDesc->bmAttributes.Bulk.Reserved1 != 0) + { + AppendTextBuffer("*!*ERROR: bmAttributes bits 7-5 should be 0\r\n"); + } + break; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + if (EpCompDesc->bmAttributes.Isochronous.SspCompanion == 0) + { + if (EpCompDesc->bMaxBurst == 0 && + EpCompDesc->bmAttributes.Isochronous.Mult != 0) + { + AppendTextBuffer("*!*ERROR: SuperSpeed isochronous endpoint multiplier value should be zero if bMaxBurst is zero\r\n"); + } + else + { + AppendTextBuffer(" = %d maximum number of packets within a service interval\r\n", + (EpCompDesc->bmAttributes.Isochronous.Mult + 1)*(EpCompDesc->bMaxBurst + 1)); + + if (EpCompDesc->bmAttributes.Isochronous.Mult > USB_SUPERSPEED_ISOCHRONOUS_MAX_MULTIPLIER) + { + AppendTextBuffer("*!*ERROR: Maximum SuperSpeed isochronous endpoint multiplier value exceeded\r\n"); + } + } + } + else + { + if (EpCompDesc->bMaxBurst != 0) + { + AppendTextBuffer(" = %d maximum number of packets within a service interval\r\n", + (SspIsochEpCompDesc->dwBytesPerInterval*USB_ENDPOINT_SUPERSPEED_ISO_MAX_PACKET_SIZE) / + EpCompDesc->bMaxBurst); + } + } + + if (EpCompDesc->bmAttributes.Isochronous.Reserved2 != 0) + { + AppendTextBuffer("*!*ERROR: bmAttributes bits 7-2 should be 0\r\n"); + } + else + { + AppendTextBuffer("\r\n"); + } + break; + } + } + AppendTextBuffer("wBytesPerInterval: 0x%04X\r\n", + EpCompDesc->wBytesPerInterval); + + if (EpCompDesc->bmAttributes.Isochronous.SspCompanion == 1 && + EpCompDesc->wBytesPerInterval != 0x1) + { + AppendTextBuffer("*!*ERROR: SuperSpeed endpoint wBytesPerInterval value should be 1 if \ + SuperSpeedPlus Isoch companion descriptor is present\r\n"); + } +} + + +/***************************************************************************** + +DisplayHidDescriptor() + +*****************************************************************************/ + +VOID +DisplayHidDescriptor ( + PUSB_HID_DESCRIPTOR HidDesc + ) +{ + UCHAR i = 0; + + AppendTextBuffer("\r\n ===>HID Descriptor<===\r\n"); + + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + HidDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + HidDesc->bDescriptorType); + AppendTextBuffer("bcdHID: 0x%04X\r\n", + HidDesc->bcdHID); + AppendTextBuffer("bCountryCode: 0x%02X\r\n", + HidDesc->bCountryCode); + AppendTextBuffer("bNumDescriptors: 0x%02X\r\n", + HidDesc->bNumDescriptors); + + for (i=0; i<HidDesc->bNumDescriptors; i++) + { + if (HidDesc->OptionalDescriptors[i].bDescriptorType == 0x22) { + AppendTextBuffer("bDescriptorType: 0x%02X (Report Descriptor)\r\n", + HidDesc->OptionalDescriptors[i].bDescriptorType); + } + else { + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + HidDesc->OptionalDescriptors[i].bDescriptorType); + } + + AppendTextBuffer("wDescriptorLength: 0x%04X\r\n", + HidDesc->OptionalDescriptors[i].wDescriptorLength); + } +} + +/***************************************************************************** + +DisplayOTGDescriptor() + +*****************************************************************************/ + +VOID +DisplayOTGDescriptor ( + PUSB_OTG_DESCRIPTOR OTGDesc + ) +{ + AppendTextBuffer("\r\n ===>OTG Descriptor<===\r\n"); + + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + OTGDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + OTGDesc->bDescriptorType); + AppendTextBuffer("bmAttributes: 0x%02X", + OTGDesc->bmAttributes); + + switch (OTGDesc->bmAttributes) + { + case 0: + break; + case 1: + if(gDoAnnotation) + { + AppendTextBuffer(" -> SRP support\r\n"); + } + break; + case 2: + if(gDoAnnotation) + { + AppendTextBuffer(" -> HNP support\r\n"); + } + break; + case 3: + if(gDoAnnotation) + { + AppendTextBuffer(" -> SRP and HNP support\r\n"); + } + break; + default: + //@@TestCase A6.5 + //@@Priority 1 + //@@OTG Descriptor Field - bmAttributes + //@@Attribute bits D7-2 reserved (reset to 0) + AppendTextBuffer("*!*ERROR: bmAttributes bits 2-7 are reserved "\ + "(should be 0)\r\n"); + OOPS(); + break; + } +} + +/***************************************************************************** + +InitializeGlobalFlags () + +Initialize the global device flags in UVCView.h + +*****************************************************************************/ + +void +InitializePerDeviceSettings ( + PUSBDEVICEINFO info + ) +{ + // Save base address for this current device's info (including Configuration descriptor) + CurrentUSBDeviceInfo = info; + + // Initialize Configuration descriptor length + dwConfigLength = 0; + + // Save # of bytes from start of Configuration descriptor + // (Update this in the descriptor parsing routines) + dwConfigIndex = 0; + + // Flags used in dispvid.c to display default Frame descriptor for MJPEG, + // Uncompressed, Vendor and FrameBased Formats + g_chMJPEGFrameDefault = 0; + g_chUNCFrameDefault = 0; + g_chVendorFrameDefault = 0; + g_chFrameBasedFrameDefault = 0; + + // Spec version of UVC device + g_chUVCversion = 0; + + // Start and end address of the configuration descriptor and start of the string descriptors + g_pConfigDesc = NULL; + g_pStringDescs = NULL; + g_descEnd = NULL; + + // + // The GetConfigDescriptor() function in enum.c does not always work + // If that fails, the Configuration descriptor will be NULL + // and we can only display the device descriptor + // + CurrentConfigDesc = NULL; + if (NULL != info) + { + if (NULL != info->ConfigDesc) + { + CurrentConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1); + + // Save the LENGTH of the Config descriptor + // Note that IsIADDevice() saves the ADDRESS of the END of the Config desc + // Be aware of the difference + dwConfigLength = CurrentConfigDesc->wTotalLength; + } + } + + return; +} + +/***************************************************************************** + +IsUVCDevice() + +Return Spec version of UVC device + 0x0 = Not a UVC device + 0x10 = UVC 1.0 + 0x11 = UVC 1.1 + + *****************************************************************************/ + +UINT +IsUVCDevice ( + PUSBDEVICEINFO info + ) +{ + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc = NULL; + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + PUCHAR descEnd = NULL; + UINT uUVCversion = 0; + + // + // The GetConfigDescriptor() function in enum.c does not always work + // If that fails, the Configuration descriptor will be NULL + // and we can only display the device descriptor + // + if (NULL == info) + { + return 0; + } + if (NULL == info->ConfigDesc) + { + return 0; + } + ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1); + if (NULL == ConfigDesc) + { + return 0; + } + + // We've got a good Configuration Descriptor + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + + // walk through all the descriptors looking for the VIDEO_CONTROL_HEADER_UNIT + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + if ((commonDesc->bDescriptorType == CS_INTERFACE) && + (commonDesc->bLength > sizeof(VIDEO_CONTROL_HEADER_UNIT))) + { + // Right type, size. Now check subtype + PVIDEO_CONTROL_HEADER_UNIT pCSVC = NULL; + pCSVC = (PVIDEO_CONTROL_HEADER_UNIT) commonDesc; + if (VC_HEADER == pCSVC->bDescriptorSubtype) + { + // found the Class-specific VC Interface Header descriptor + uUVCversion = pCSVC->bcdVideoSpec; + // Save the version to global + g_chUVCversion = uUVCversion; + // We're done + break; + } + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uUVCversion); +} + +/***************************************************************************** + +IsIADDevice() + +*****************************************************************************/ + +UINT +IsIADDevice ( + PUSBDEVICEINFO info + ) +{ + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc = NULL; + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + PUCHAR descEnd = NULL; + UINT uIADcount = 0; + + // + // The GetConfigDescriptor() function in enum.c does not always work + // If that fails, the Configuration descriptor will be NULL + // and we can only display the device descriptor + // + if (NULL == info) + { + return 0; + } + if (NULL == info->ConfigDesc) + { + return 0; + } + + ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1); + if (NULL != ConfigDesc) + { + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + } + + // return total number of IAD descriptors in this device configuration + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + if (commonDesc->bDescriptorType == USB_IAD_DESCRIPTOR_TYPE) + { + uIADcount++; + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uIADcount); +} + +/***************************************************************************** + +DisplayIADDescriptor() + +*****************************************************************************/ + +VOID +DisplayIADDescriptor ( + PUSB_IAD_DESCRIPTOR IADDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + int nInterfaces, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + AppendTextBuffer("\r\n ===>IAD Descriptor<===\r\n"); + + //length checked in DisplayConfigDesc() + + AppendTextBuffer("bLength: 0x%02X\r\n", + IADDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + IADDesc->bDescriptorType); + AppendTextBuffer("bFirstInterface: 0x%02X\r\n", + IADDesc->bFirstInterface); + AppendTextBuffer("bInterfaceCount: 0x%02X\r\n", + IADDesc->bInterfaceCount); + if (IADDesc->bInterfaceCount == 1) + { + //@@TestCase A7.1 + //@@Priority 1 + //@@Standard IAD Descriptor Field - bInterfaceCount + //@@The number of interfaces must be greater than 1 + AppendTextBuffer("*!*ERROR: bInterfaceCount must be greater than 1 \r\n"); + OOPS(); + } + if (nInterfaces < IADDesc->bFirstInterface + IADDesc->bInterfaceCount) + { + //@@TestCase A7.2 + //@@Priority 1 + //@@Standard IAD Descriptor Field - bInterfaceCount + //@@The total number of interfaces must be greater than or equal to + //@@ the highest linked interface number (base interface number plus count) + AppendTextBuffer("*!*ERROR: The total number of interfaces (%d) must be greater "\ + "than or equal to\r\n", + nInterfaces); + AppendTextBuffer(" the highest linked interface number (base %d + "\ + "count %d = %d)\r\n", + IADDesc->bFirstInterface, IADDesc->bInterfaceCount, + (IADDesc->bFirstInterface + IADDesc->bInterfaceCount)); + OOPS(); + } + AppendTextBuffer("bFunctionClass: 0x%02X", + IADDesc->bFunctionClass); + if (IADDesc->bFunctionClass == 0) + { + //@@TestCase A7.3 + //@@Priority 1 + //@@Standard IAD Descriptor Field - bFunctionClass + //@@"A value of zero is not allowed in this descriptor" + AppendTextBuffer("\r\n*!*ERROR: bFunctionClass contains an illegal value 0 \r\n"); + OOPS(); + } + + switch (IADDesc->bFunctionClass) + { + case USB_DEVICE_CLASS_AUDIO: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Audio Interface Class\r\n"); + } + + AppendTextBuffer("bFunctionSubClass: 0x%02X", + IADDesc->bFunctionSubClass); + + if(gDoAnnotation) + { + switch (IADDesc->bFunctionSubClass) + { + case USB_AUDIO_SUBCLASS_AUDIOCONTROL: + AppendTextBuffer(" -> Audio Control Interface SubClass\r\n"); + break; + + case USB_AUDIO_SUBCLASS_AUDIOSTREAMING: + AppendTextBuffer(" -> Audio Streaming Interface SubClass\r\n"); + break; + + case USB_AUDIO_SUBCLASS_MIDISTREAMING: + AppendTextBuffer(" -> MIDI Streaming Interface SubClass\r\n"); + break; + + default: + //@@TestCase A7.4 + //@@CAUTION + //@@Descriptor Field - bFunctionSubClass + //@@Invalid bFunctionSubClass + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid bFunctionSubClass\r\n"); + OOPS(); + break; + } + } + break; + + case USB_DEVICE_CLASS_VIDEO: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Video Interface Class\r\n"); + } + + AppendTextBuffer("bFunctionSubClass: 0x%02X", + IADDesc->bFunctionSubClass); + + switch(IADDesc->bFunctionSubClass) + { + case SC_VIDEO_INTERFACE_COLLECTION: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Video Interface Collection\r\n"); + } + break; + + default: + //@@TestCase A7.5 + //@@CAUTION + //@@Descriptor Field - bFunctionSubClass + //@@Invalid bFunctionSubClass + AppendTextBuffer("\r\n*!*ERROR: This should be USB_VIDEO_SC_VIDEO_INTERFACE_COLLECTION %d\r\n", + SC_VIDEO_INTERFACE_COLLECTION); + OOPS(); + break; + } + break; + + case USB_DEVICE_CLASS_HUMAN_INTERFACE: + if(gDoAnnotation) + { + AppendTextBuffer(" -> HID Interface Class\r\n"); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_HUB: + if(gDoAnnotation) + { + AppendTextBuffer(" -> HUB Interface Class\r\n"); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_RESERVED: + //@@TestCase A7.6 + //@@CAUTION + //@@Descriptor Field - bFunctionClass + //@@A reserved USB Device Interface Class has been defined + AppendTextBuffer("\r\n*!*CAUTION: %d is a Reserved USB Device Interface Class\r\n", + USB_DEVICE_CLASS_RESERVED); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_COMMUNICATIONS: + AppendTextBuffer(" -> This is Communications (CDC Control) USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_MONITOR: + AppendTextBuffer(" -> This is a Monitor USB Device Interface Class*** (This may be obsolete)\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: + AppendTextBuffer(" -> This is a Physical Interface USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_POWER: + if(IADDesc->bFunctionSubClass == 1 && IADDesc->bFunctionProtocol == 1) + { + AppendTextBuffer(" -> This is an Image USB Device Interface Class\r\n"); + } + else + { + AppendTextBuffer(" -> This is a Power USB Device Interface Class (This may be obsolete)\r\n"); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_PRINTER: + AppendTextBuffer(" -> This is a Printer USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DEVICE_CLASS_STORAGE: + AppendTextBuffer(" -> This is a Mass Storage USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_CDC_DATA_INTERFACE: + AppendTextBuffer(" -> This is a CDC Data USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_CHIP_SMART_CARD_INTERFACE: + AppendTextBuffer(" -> This is a Chip/Smart Card USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_CONTENT_SECURITY_INTERFACE: + AppendTextBuffer(" -> This is a Content Security USB Device Interface Class\r\n"); + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_DIAGNOSTIC_DEVICE_INTERFACE: + if(IADDesc->bFunctionSubClass == 1 && IADDesc->bFunctionProtocol == 1) + { + AppendTextBuffer(" -> This is a Reprogrammable USB2 Compliance Diagnostic Device USB Device\r\n"); + } + else + { + //@@TestCase A7.7 + //@@CAUTION + //@@Descriptor Field - bFunctionClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_WIRELESS_CONTROLLER_INTERFACE: + if(IADDesc->bFunctionSubClass == 1 && IADDesc->bFunctionProtocol == 1) + { + AppendTextBuffer(" -> This is a Wireless RF Controller USB Device Interface Class with Bluetooth Programming Interface\r\n"); + } + else + { + //@@TestCase A7.8 + //@@CAUTION + //@@Descriptor Field - bFunctionClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + case USB_APPLICATION_SPECIFIC_INTERFACE: + AppendTextBuffer(" -> This is an Application Specific USB Device Interface Class\r\n"); + + switch(IADDesc->bFunctionSubClass) + { + case 1: + AppendTextBuffer(" -> This is a Device Firmware Application Specific USB Device Interface Class\r\n"); + break; + case 2: + AppendTextBuffer(" -> This is an IrDA Bridge Application Specific USB Device Interface Class\r\n"); + break; + case 3: + AppendTextBuffer(" -> This is a Test & Measurement Class (USBTMC) Application Specific USB Device Interface Class\r\n"); + break; + default: + //@@TestCase A7.9 + //@@CAUTION + //@@Descriptor Field - bFunctionClass + //@@Invalid Interface Class + AppendTextBuffer("\r\n*!*CAUTION: This appears to be an invalid Interface Class\r\n"); + OOPS(); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + + default: + if(gDoAnnotation) + { + AppendTextBuffer(" -> Interface Class Unknown to USBView\r\n"); + } + AppendTextBuffer("bFunctionSubClass: 0x%02X\r\n", + IADDesc->bFunctionSubClass); + break; + } + + AppendTextBuffer("bFunctionProtocol: 0x%02X", + IADDesc->bFunctionProtocol); + + // check protocol for our class + if ((IADDesc->bFunctionClass == USB_DEVICE_CLASS_VIDEO)) + { + // USB Video Class + if(IADDesc->bFunctionProtocol == PC_PROTOCOL_UNDEFINED) + { + // correct protocol for UVC + if(gDoAnnotation) + { + AppendTextBuffer(" -> PC_PROTOCOL_UNDEFINED protocol\r\n"); + } else { + AppendTextBuffer("\r\n"); + } + } else { + // incorrect protocol for UVC + //@@TestCase A7.10 + //@@WARNING + //@@Descriptor Field - iInterface + //@@bFunctionProtocol must be set to PC_PROTOCOL_UNDEFINED + AppendTextBuffer("*!*WARNING: must be set to PC_PROTOCOL_UNDEFINED %d for this class\r\n", + PC_PROTOCOL_UNDEFINED); + OOPS(); + } + } else { + AppendTextBuffer("\r\n"); + } + + AppendTextBuffer("iFunction: 0x%02X\r\n", + IADDesc->iFunction); + + if(gDoAnnotation) + { + if (IADDesc->iFunction) + { + DisplayStringDescriptor(IADDesc->iFunction, + StringDescs, + LatestDevicePowerState); + } + } +} + +/***************************************************************************** + +GetConfigurationSize() + +*****************************************************************************/ + +UINT +GetConfigurationSize ( + PUSBDEVICEINFO info + ) +{ + PUSB_CONFIGURATION_DESCRIPTOR + ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1); + PUSB_COMMON_DESCRIPTOR + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + PUCHAR + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + UINT uCount = 0; + + // return this device configuration's total sum of descriptor lengths + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + uCount += commonDesc->bLength; + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uCount); +} + +/***************************************************************************** + +GetInterfaceCount() + +*****************************************************************************/ + +UINT +GetInterfaceCount ( + PUSBDEVICEINFO info + ) +{ + // how do we handle composite devices? + PUSB_CONFIGURATION_DESCRIPTOR + ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(info->ConfigDesc + 1); + PUSB_COMMON_DESCRIPTOR + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + PUCHAR + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + UINT uCount = 0; + + // return this device configuration's total number of interface descriptors + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + if (commonDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + { + uCount++; + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uCount); +} + + +/***************************************************************************** + +DisplayUSEnglishStringDescriptor() + +*****************************************************************************/ + +VOID +DisplayUSEnglishStringDescriptor ( + UCHAR Index, + PSTRING_DESCRIPTOR_NODE USStringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + ULONG nBytes = 0; + BOOLEAN FoundMatchingString = FALSE; + CHAR pString[512]; + + //@@DisplayUSEnglishStringDescriptor - String Descriptor + while (USStringDescs) + { + if (USStringDescs->DescriptorIndex == Index) + { + if (USStringDescs->LanguageID != 0x0409) + continue; + + FoundMatchingString = TRUE; + + AppendTextBuffer("English product name: \""); + memset(pString, 0, 512); + nBytes = WideCharToMultiByte( + CP_ACP, // CodePage + WC_NO_BEST_FIT_CHARS, + USStringDescs->StringDescriptor->bString, + (USStringDescs->StringDescriptor->bLength - 2) / 2, + pString, + 512, + NULL, // lpDefaultChar + NULL); // pUsedDefaultChar + if (nBytes) + AppendTextBuffer("%s\"\r\n", pString); + else + AppendTextBuffer("\"\r\n", pString); + return; + } + USStringDescs = USStringDescs->Next; + } + + //@@TestCase A8.1 + //@@WARNING + //@@Descriptor Field - string index + //@@No support for english + if (!FoundMatchingString) + { + if (LatestDevicePowerState == PowerDeviceD0) + { + AppendTextBuffer("*!*ERROR: No String Descriptor for index %d!\r\n", Index); + OOPS(); + } + else + { + AppendTextBuffer("String Descriptor for index %d not available while device is in low power state.\r\n", Index); + } + } + else + { + AppendTextBuffer("*!*ERROR: The index selected does not support English(US)\r\n"); + OOPS(); + } + return; + +} + + +/***************************************************************************** + +DisplayStringDescriptor() + +*****************************************************************************/ +VOID +DisplayStringDescriptor ( + UCHAR Index, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + ULONG nBytes = 0; + BOOLEAN FoundMatchingString = FALSE; + PCHAR pStr = NULL; + CHAR pString[512]; + + //@@DisplayStringDescriptor - String Descriptor + + while (StringDescs) + { + if (StringDescs->DescriptorIndex == Index) + { + FoundMatchingString = TRUE; + if(gDoAnnotation) + { + pStr= GetLangIDString(StringDescs->LanguageID); + if(pStr) + { + AppendTextBuffer(" %s \"", + pStr); + } + else + { + //@@TestCase A9.1 + //@@WARNING + //@@Descriptor Field - string index + //@@The Language ID does not match any known languages supported by USB ORG + AppendTextBuffer("*!*WARNING: %d is an invalid Language ID\r\n", + Index); + OOPS(); + } + } + else + { + AppendTextBuffer(" 0x%04X: \"", StringDescs->LanguageID); + } + memset(pString, 0, 512); + + if (StringDescs->StringDescriptor->bLength > sizeof(USHORT)) + { + nBytes = WideCharToMultiByte( + CP_ACP, // CodePage + WC_NO_BEST_FIT_CHARS, + StringDescs->StringDescriptor->bString, + (StringDescs->StringDescriptor->bLength - 2) / 2, + pString, + 512, + NULL, // lpDefaultChar + NULL); // pUsedDefaultChar + if (nBytes) + { + AppendTextBuffer("%s\"\r\n", pString); + } + else + { + AppendTextBuffer("\"\r\n"); + } + } + else + { + // + // This is NULL string which is invalid + // + AppendTextBuffer("\"\r\n"); + } + } + StringDescs = StringDescs->Next; + } + + if (!FoundMatchingString) + { + if (LatestDevicePowerState == PowerDeviceD0) + { + AppendTextBuffer("*!*ERROR: No String Descriptor for index %d!\r\n", Index); + OOPS(); + } + else + { + AppendTextBuffer("String Descriptor for index %d not available while device is in low power state.\r\n", Index); + } + } +} + +/***************************************************************************** + +DisplayUnknownDescriptor() + +*****************************************************************************/ +VOID +DisplayUnknownDescriptor ( + PUSB_COMMON_DESCRIPTOR CommonDesc + ) +{ + AppendTextBuffer("\r\n ===>Descriptor Hex Dump<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", + CommonDesc->bLength); + + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", + CommonDesc->bDescriptorType); + + DisplayRemainingUnknownDescriptor((PUCHAR)CommonDesc, 0, CommonDesc->bLength); +} + +VOID +DisplayRemainingUnknownDescriptor( + PUCHAR DescriptorData, + ULONG Start, + ULONG Stop + ) +{ + ULONG i; + + for (i = Start; i < Stop; i++) + { + AppendTextBuffer("%02X ", + DescriptorData[i]); + + if (i % 16 == 15) + { + AppendTextBuffer("\r\n"); + } + } + + if (i % 16 != 0) + { + AppendTextBuffer("\r\n"); + } +} + + + +/***************************************************************************** + +GetVendorString() + +idVendor - USB Vendor ID + +Return Value - Vendor name string associated with idVendor, or NULL if +no vendor name string is found which is associated with idVendor. + +*****************************************************************************/ + +PCHAR +GetVendorString ( + USHORT idVendor + ) +{ + PUSBVENDORID vendorID = NULL; + + if (idVendor == 0x0000) + { + return NULL; + } + + vendorID = USBVendorIDs; + + while (vendorID->usVendorID != 0x0000) + { + if (vendorID->usVendorID == idVendor) + { + break; + } + vendorID++; + } + + return (vendorID->szVendor); +} + +/***************************************************************************** + +GetLangIDString() + +idVendor - USB Vendor ID + +Return Value - Vendor name string associated with idVendor, or NULL if +no vendor name string is found which is associated with idVendor. + +*****************************************************************************/ + +PCHAR +GetLangIDString ( + USHORT idLang + ) +{ + PUSBLANGID langID = NULL; + + if (idLang != 0x0000) + { + langID = USBLangIDs; + + while (langID->usLangID != 0x0000) + { + if (langID->usLangID == idLang) + { + return (langID->szLanguage); + } + langID++; + } + } + + return NULL; +} + +/***************************************************************************** + +GetStringFromList() + +PSTRINGLIST slList, - pointer to STRINGLIST used + +ULONG ulNumElements, - + number of elements in that STRINGLIST calc before call with sizeof(slList) / sizeof(STRINGLIST), +ULONG or ULONGLONG (if H264_SUPPORT is defined)ulFlag - - flag to look for +PCHAR szDefault - string to return if no match + +Return a string associated with a value from a stringtable. + +example: + GetStringFromList(slPowerState, + sizeof(slPowerState) / sizeof(STRINGLIST), + pUPI->SystemState, + "Invalid Power State") + +*****************************************************************************/ + +PCHAR +GetStringFromList( + PSTRINGLIST slList, + ULONG ulNumElements, +#ifdef H264_SUPPORT + ULONGLONG ulFlag, +#else + ULONG ulFlag, +#endif + _In_ PCHAR szDefault + ) +{ + // ulIndex is zero based, but ulNumElements is 1 based + // subtract 1 from ulNumElements so that are same base +#ifdef H264_SUPPORT + ULONGLONG ulIndex = 0; +#else + ULONG ulIndex = 0; +#endif + ulNumElements--; + + + for ( ; ulIndex <= ulNumElements; ulIndex++) + { + if (ulFlag == slList[ulIndex].ulFlag) + { + return (slList[ulIndex].pszString); + } + } + + return szDefault; +} + diff --git a/usb/usbview/dispvid.c b/usb/usbview/dispvid.c new file mode 100644 index 00000000..fa7765fb --- /dev/null +++ b/usb/usbview/dispvid.c @@ -0,0 +1,5649 @@ +/*++ + +Copyright (c) 2002-2008 Microsoft Corporation + +Module Name: + +DISPVID.C + +Abstract: + +This source file contains routines which update the edit control +to display information about USB Video descriptors. + +Environment: + +user mode + +Revision History: + +11-22-2002 : created +03-28-2003 : major revisions from latest specs. +03-28-2008 : include USB Video Class 1.1 + +--*/ + +//***************************************************************************** +// I N C L U D E S +//***************************************************************************** + +#include "uvcview.h" +#include "h264.h" + +//***************************************************************************** +// G L O B A L S P R I V A T E T O T H I S F I L E +//***************************************************************************** + +int StillMethod = 0; + +// +// USB Device Class Definition for Video Devices 0.8b version +// +// 3.6.2.3 Camera Terminal Descriptor +// +STRINGLIST slCameraControl1 [] = +{ + {1, "Scanning Mode", ""}, + {2, "Auto-Exposure Mode", ""}, + {4, "Auto-Exposure Priority", ""}, + {8, "Exposure Time (Absolute)", ""}, + {0x10, "Exposure Time (Relative)", ""}, + {0x20, "Focus (Absolute)", ""}, + {0x40, "Focus (Relative)", ""}, + {0x80, "Iris (Absolute)", ""}, +}; +STRINGLIST slCameraControl2 [] = +{ + {1, "Iris (Relative)", ""}, + {2, "Zoom (Absolute)", ""}, + {4, "Zoom (Relative)", ""}, + {8, "PanTilt (Absolute)", ""}, + {0x10, "PanTilt (Relative)", ""}, + {0x20, "Roll (Absolute)", ""}, + {0x40, "Roll (Relative)", ""}, + {0x80, "Reserved", ""}, +}; +STRINGLIST slCameraControl3 [] = +{ + {1, "Reserved", ""}, + {2, "Focus, Auto", ""}, + {4, "Privacy", ""}, + {8, "Focus, Simple", ""}, + {0x10, "Window", ""}, + {0x20, "Region of Interest", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + +// 3.6.2.5 Processing Unit Descriptor +// +STRINGLIST slProcessorControls1 [] = +{ + {1, "Brightness", ""}, + {2, "Contrast", ""}, + {4, "Hue", ""}, + {8, "Saturation", ""}, + {0x10, "Sharpness", ""}, + {0x20, "Gamma", ""}, + {0x40, "White Balance Temperature", ""}, + {0x80, "White Balance Component", ""}, +}; +STRINGLIST slProcessorControls2 [] = +{ + {1, "Backlight Compensation", ""}, + {2, "Gain", ""}, + {4, "Power Line Frequency", ""}, + {8, "Hue, Auto", ""}, + {0x10, "White Balance Temperature, Auto", ""}, + {0x20, "White Balance Component, Auto", ""}, + {0x40, "Digital Multiplier", ""}, + {0x80, "Digital Multiplier Limit", ""}, +}; +STRINGLIST slProcessorControls3 [] = +{ + {1, "Analog Video Standard", ""}, + {2, "Analog Video Lock Status", ""}, + {4, "Contrast, Auto", ""}, + {8, "Reserved", ""}, + {0x10, "Reserved", ""}, + {0x20, "Reserved", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + + +STRINGLIST slProcessorVideoStandards [] = +{ + {1, "None", ""}, + {2, "NTSC - 525/60", ""}, + {4, "PAL - 625/50", ""}, + {8, "SECAM - 625/50", ""}, + {0x10, "NTSC - 625/50", ""}, + {0x20, "PAL - 525/60", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + +// 3.8.2.1 Input Header Descriptor +// +STRINGLIST slInputHeaderControls[]= +{ + {1, "Key Frame Rate" , ""}, + {2, "P Frame Rate" , ""}, + {4, "Compression Quality" , ""}, + {8, "Compression Window Size", ""}, + {0x10, "Generate Key Frame" , ""}, + {0x20, "Update Frame Segment" , ""}, + {0x40, "Reserved" , ""}, + {0x80, "Reserved" , ""}, +}; + +STRINGLIST slOutputHeaderControls[]= +{ + {1, "Key Frame Rate" , ""}, + {2, "P Frame Rate" , ""}, + {4, "Compression Quality" , ""}, + {8, "Compression Window Size", ""}, + {0x10, "Reserved" , ""}, + {0x20, "Reserved" , ""}, + {0x40, "Reserved" , ""}, + {0x80, "Reserved" , ""}, +}; + +STRINGLIST slMediaTransportControls[]= +{ + {1, "Transport Control" , ""}, + {2, "Absolute Track Number Control", ""}, + {4, "Media Information" , ""}, + {8, "Time Code Information" , ""}, + {0x10, "Reserved" , ""}, + {0x20, "Reserved" , ""}, + {0x40, "Reserved" , ""}, + {0x80, "Reserved" , ""}, +}; + +STRINGLIST slMediaTransportModes1[]= +{ + {1, "Play Forward", ""}, + {2, "Pause", ""}, + {4, "Rewind", ""}, + {8, "Fast Forward", ""}, + {0x10, "High Speed Rewind", ""}, + {0x20, "Stop", ""}, + {0x40, "Eject", ""}, + {0x80, "Play Next Frame", ""}, +}; + +STRINGLIST slMediaTransportModes2[]= +{ + {1, "Play Slowest Forward", ""}, + {2, "Play Slow Forward 4", ""}, + {4, "Play Slow Forward 3", ""}, + {8, "Play Slow Forward 2", ""}, + {0x10, "Play Slow Forward 1", ""}, + {0x20, "Play X1", ""}, + {0x40, "Play Fast Forward 1", ""}, + {0x80, "Play Fast Forward 2", ""}, +}; + +STRINGLIST slMediaTransportModes3[]= +{ + {1, "Play Fast Forward 3", ""}, + {2, "Play Fast Forward 4", ""}, + {4, "Play Fastest Forward", ""}, + {8, "Play Previous Frame", ""}, + {0x10, "Play Slowest Reverse", ""}, + {0x20, "Play Slow Reverse 4", ""}, + {0x40, "Play Slow Reverse 3", ""}, + {0x80, "Play Slow Reverse 2", ""}, +}; + +STRINGLIST slMediaTransportModes4[]= +{ + {1, "Play Slow Reverse 1", ""}, + {2, "Play X1 Reverse", ""}, + {4, "Play Fast Reverse 1", ""}, + {8, "Play Fast Reverse 2", ""}, + {0x10, "Play Fast Reverse 3", ""}, + {0x20, "Play Fast Reverse 4", ""}, + {0x40, "Play Fastest Reverse", ""}, + {0x80, "Record StateStart", ""}, +}; + +STRINGLIST slMediaTransportModes5[]= +{ + {1, "Record Pause", ""}, + {2, "Reserved", ""}, + {4, "Reserved", ""}, + {8, "Reserved", ""}, + {0x10, "Reserved", ""}, + {0x20, "Reserved", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + +STRINGLIST slInputTermTypes[]= +{ + {0x0100, "TT_VENDOR_SPECIFIC", "I//O"}, + {0x0101, "TT_STREAMING", "I//O"}, + {0x0400, "EXTERNAL_VENDOR_SPECIFIC", "I//O"}, + {0x0401, "COMPOSITE_CONNECTOR", "I//O"}, + {0x0402, "SVIDEO_CONNECTOR", "I//O"}, + {0x0403, "COMPONENT_CONNECTOR", "I//O"}, + {0x0200, "ITT_VENDOR_SPECIFIC", "I"}, + {0x0201, "ITT_CAMERA", "I"}, + {0x0202, "ITT_MEDIA_TRANSPORT_INPUT", "I"}, +}; +STRINGLIST slOutputTermTypes[]= +{ + {0x0100, "TT_VENDOR_SPECIFIC", "I//O"}, + {0x0101, "TT_STREAMING", "I//O"}, + {0x0400, "EXTERNAL_VENDOR_SPECIFIC", "I//O"}, + {0x0401, "COMPOSITE_CONNECTOR", "I//O"}, + {0x0402, "SVIDEO_CONNECTOR", "I//O"}, + {0x0403, "COMPONENT_CONNECTOR", "I//O"}, + {0x0300, "OTT_VENDOR_SPECIFIC", "O"}, + {0x0301, "OTT_DISPLAY", "O"}, + {0x0302, "OTT_MEDIA_TRANSPORT_OUTPUT", "O"}, +}; + +//***************************************************************************** +// L O C A L F U N C T I O N P R O T O T Y P E S +//***************************************************************************** + +BOOL +DisplayVCHeader ( + PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc + ); +BOOL +DisplayVCInputTerminal ( + PVIDEO_INPUT_TERMINAL VidITDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +BOOL +DisplayVCOutputTerminal ( + PVIDEO_OUTPUT_TERMINAL VidOTDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +BOOL +DisplayVCCameraTerminal ( + PVIDEO_CAMERA_TERMINAL CameraDesc + ); +BOOL +DisplayVCMediaTransInputTerminal ( + PVIDEO_INPUT_MTT VCMedTransInDesc + ); +BOOL +DisplayVCMediaTransOutputTerminal ( + PVIDEO_OUTPUT_MTT VCMedTransOutDesc + ); +BOOL +DisplayVCSelectorUnit ( + PVIDEO_SELECTOR_UNIT VidSelectorDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +BOOL +DisplayVCProcessingUnit ( + PVIDEO_PROCESSING_UNIT VidProcessingDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +BOOL +DisplayVCExtensionUnit ( + PVIDEO_EXTENSION_UNIT VidExtensionDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +BOOL +DisplayVidInHeader ( + PVIDEO_STREAMING_INPUT_HEADER VidInHeaderDesc + ); +BOOL +DisplayVidOutHeader ( + PVIDEO_STREAMING_OUTPUT_HEADER VidOutHeaderDesc + ); +BOOL +DisplayStillImageFrame ( + PVIDEO_STILL_IMAGE_FRAME StillFrameDesc + ); +BOOL +DisplayColorMatching ( + PVIDEO_COLORFORMAT ColorMatchDesc + ); +BOOL +DisplayUncompressedFormat ( + PVIDEO_FORMAT_UNCOMPRESSED UnCompFormatDesc + ); +BOOL +DisplayUncompressedFrameType ( + PVIDEO_FRAME_UNCOMPRESSED UnCompFrameDesc + ); +BOOL +DisplayUnComContinuousFrameType( + PVIDEO_FRAME_UNCOMPRESSED UContinuousDesc + ); +BOOL +DisplayUnComDiscreteFrameType( + PVIDEO_FRAME_UNCOMPRESSED UDiscreteDesc + ); +BOOL +DisplayMJPEGFormat ( + PVIDEO_FORMAT_MJPEG MJPEGFormatDesc + ); +BOOL +DisplayMJPEGFrameType ( + PVIDEO_FRAME_MJPEG MJPEGFrameDesc + ); +BOOL +DisplayMJPEGContinuousFrameType( + PVIDEO_FRAME_MJPEG MContinuousDesc + ); +BOOL +DisplayMJPEGDiscreteFrameType( + PVIDEO_FRAME_MJPEG MDiscreteDesc + ); +BOOL +DisplayMPEG1SSFormat ( + PVIDEO_FORMAT_MPEG1SS MPEG1SSFormatDesc + ); +BOOL +DisplayMPEG2PSFormat ( + PVIDEO_FORMAT_MPEG2PS MPEG2PSFormatDesc + ); +BOOL +DisplayMPEG2TSFormat ( + PVIDEO_FORMAT_MPEG2TS MPEG2TSFormatDesc + ); +BOOL +DisplayMPEG4SLFormat ( + PVIDEO_FORMAT_MPEG4SL MPEG4SLFormatDesc + ); +BOOL +DisplayDVFormat ( + PVIDEO_FORMAT_DV DVFormatDesc + ); +BOOL +DisplayVendorVidFormat ( + PVIDEO_FORMAT_VENDOR VendorVidFormatDesc + ); +BOOL +DisplayVendorVidFrameType ( + PVIDEO_FRAME_VENDOR VendorVidFrameDesc + ); +BOOL +DisplayVendorVidContinuousFrameType( + PVIDEO_FRAME_VENDOR VContinuousDesc + ); +BOOL +DisplayVendorVidDiscreteFrameType( + PVIDEO_FRAME_VENDOR VDiscreteDesc + ); +BOOL +DisplayFramePayloadFormat( + PVIDEO_FORMAT_FRAME FramePayloadFormatDesc + ); +BOOL +DisplayFramePayloadFrame( + PVIDEO_FRAME_FRAME FramePayloadFrameDesc + ); +BOOL +DisplayFramePayloadContinuousFrameType( + PVIDEO_FRAME_FRAME FContinuousDesc + ); +BOOL +DisplayFramePayloadDiscreteFrameType( + PVIDEO_FRAME_FRAME FDiscreteDesc + ); +BOOL +DisplayStreamPayload( + PVIDEO_FORMAT_STREAM StreamPayloadDesc + ); +BOOL +DisplayVSEndpoint ( + PVIDEO_CS_INTERRUPT VidEndpointDesc + ); +VOID +VDisplayBytes ( + PUCHAR Data, + USHORT Len + ); +PCHAR +VidFormatGUIDCodeToName ( + REFGUID VidFormatGUIDCode + ); +UINT +GetVCInterfaceSize ( + PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc + ); +UINT +CheckForColorMatchingDesc ( + PVIDEO_SPECIFIC FormatDesc, + UCHAR bNumFrameDescriptors, + UCHAR bDescriptorSubtype + ); +UINT +GetVSInterfaceSize ( + PUSB_COMMON_DESCRIPTOR VidInHeaderDesc, + USHORT wTotalLength + ); +BOOL +ValidateTerminalID( + UINT uTerminalID + ); +VOID +VDisplayDescString ( + UINT uControlSize, + PUCHAR pControl , + PSTRINGLIST pslControl + ); + +//***************************************************************************** +// L O C A L F U N C T I O N S +//***************************************************************************** + +//***************************************************************************** +// +// DisplayVideoDescriptor() UPDATED +// +// VidCommonDesc - An Video Class Descriptor +// +// bInterfaceSubClass - The SubClass of the Interface containing the descriptor +// +//***************************************************************************** + +BOOL +DisplayVideoDescriptor ( + PVIDEO_SPECIFIC VidCommonDesc, + UCHAR bInterfaceSubClass, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVideoDescriptor -Class-Specific Video Descriptor + switch (VidCommonDesc->bDescriptorType) + { + case CS_INTERFACE: + //@@DisplayVideoDescriptor -Class-Specific Video Interface Descriptor + switch (bInterfaceSubClass) + { + case VIDEO_SUBCLASS_CONTROL: + //@@DisplayVideoDescriptor -Class-Specific Video Control Interface Descriptor + switch (VidCommonDesc->bDescriptorSubtype) + { + case VC_HEADER: + return DisplayVCHeader( + (PVIDEO_CONTROL_HEADER_UNIT)VidCommonDesc); + + case INPUT_TERMINAL: + return DisplayVCInputTerminal( + (PVIDEO_INPUT_TERMINAL)VidCommonDesc, + StringDescs, + LatestDevicePowerState); + + case OUTPUT_TERMINAL: + return DisplayVCOutputTerminal( + (PVIDEO_OUTPUT_TERMINAL)VidCommonDesc, + StringDescs, + LatestDevicePowerState); + + case SELECTOR_UNIT: + return DisplayVCSelectorUnit( + (PVIDEO_SELECTOR_UNIT)VidCommonDesc, + StringDescs, + LatestDevicePowerState); + + case PROCESSING_UNIT: + return DisplayVCProcessingUnit( + (PVIDEO_PROCESSING_UNIT)VidCommonDesc, + StringDescs, + LatestDevicePowerState); + + case EXTENSION_UNIT: + return DisplayVCExtensionUnit( + (PVIDEO_EXTENSION_UNIT)VidCommonDesc, + StringDescs, + LatestDevicePowerState); + +#ifdef H264_SUPPORT + case H264_ENCODING_UNIT: + return DisplayVCH264EncodingUnit( + (PVIDEO_ENCODING_UNIT)VidCommonDesc + ); + +#endif + +#ifdef H264_SUPPORT + case MAX_TYPE_UNIT+1: + // for H.264, the bDescriptorSubtype = 7, which is equal to MAX_TYPE_UNIT + // so now MAX_TYPE_UNIT needs to be set to 8 + //(TODO: need to change nt\sdpublic\internal\drivers\inc\uvcdesc.h's define + // of MAX_TYPE_UNIT from7 to 8, and ad the type for H.264 = 8) +#else + case MAX_TYPE_UNIT: +#endif + //@@TestCase B1.1 + //@@CAUTION + //@@Descriptor Field - bDescriptorSubtype + //@@An undefined descriptor subtype has been defined + AppendTextBuffer("*!*CAUTION: This is an undefined class specific "\ + "Video Control bDescriptorSubtype\r\n"); + break; + + default: + //@@TestCase B1.2 + //@@ERROR + //@@Descriptor Field - bDescriptorSubtype + //@@An unknown descriptor subtype has been defined + AppendTextBuffer("*!*ERROR: unknown bDescriptorSubtype\r\n"); + OOPS(); + break; + } + break; + + case VIDEO_SUBCLASS_STREAMING: + //@@DisplayVideoDescriptor -Class-Specific Video Streaming Interface Descriptor + switch (VidCommonDesc->bDescriptorSubtype) + { + case VS_INPUT_HEADER: + return DisplayVidInHeader( + (PVIDEO_STREAMING_INPUT_HEADER)VidCommonDesc); + + case VS_OUTPUT_HEADER: + return DisplayVidOutHeader( + (PVIDEO_STREAMING_OUTPUT_HEADER)VidCommonDesc); + + case VS_STILL_IMAGE_FRAME: + return DisplayStillImageFrame( + (PVIDEO_STILL_IMAGE_FRAME)VidCommonDesc); + + case VS_FORMAT_UNCOMPRESSED: +#ifdef H264_SUPPORT + { + BOOL retCode = DisplayUncompressedFormat( (PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc ); + g_expectedNumberOfUncompressedFrameFrameDescriptors += ((PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc)->bNumFrameDescriptors; + return retCode; + } +#else + return DisplayUncompressedFormat( + (PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc); +#endif + + case VS_FRAME_UNCOMPRESSED: +#ifdef H264_SUPPORT + { + BOOL retCode = DisplayUncompressedFrameType( (PVIDEO_FRAME_UNCOMPRESSED)VidCommonDesc ); + g_numberOfUncompressedFrameFrameDescriptors++; + return retCode; + } +#else + return DisplayUncompressedFrameType( + (PVIDEO_FRAME_UNCOMPRESSED)VidCommonDesc); +#endif + +#ifdef H264_SUPPORT + case VS_FORMAT_H264: + { + BOOL retCode = DisplayVCH264Format( (PVIDEO_FORMAT_H264)VidCommonDesc ); + g_expectedNumberOfH264FrameDescriptors += ((PVIDEO_FORMAT_H264)VidCommonDesc)->bNumFrameDescriptors; + return retCode; + } + + case VS_FRAME_H264: + { + BOOL retCode = DisplayVCH264FrameType( (PVIDEO_FRAME_H264)VidCommonDesc ); + g_numberOfH264FrameDescriptors++; + return retCode; + } +#endif + + case VS_FORMAT_MJPEG: +#ifdef H264_SUPPORT // additional checks + { + BOOL retCode = DisplayMJPEGFormat( (PVIDEO_FORMAT_MJPEG)VidCommonDesc ); + g_expectedNumberOfMJPEGFrameDescriptors += ((PVIDEO_FORMAT_MJPEG)VidCommonDesc)->bNumFrameDescriptors; + return retCode; + } +#else + return DisplayMJPEGFormat( + (PVIDEO_FORMAT_MJPEG)VidCommonDesc); +#endif + + case VS_FRAME_MJPEG: +#ifdef H264_SUPPORT + { + BOOL retCode = DisplayMJPEGFrameType( (PVIDEO_FRAME_MJPEG)VidCommonDesc ); + g_numberOfMJPEGFrameDescriptors++; + return retCode; + } + +#else + return DisplayMJPEGFrameType( + (PVIDEO_FRAME_MJPEG)VidCommonDesc); +#endif + + + + case VS_FORMAT_MPEG1: + { + if (UVC10 == g_chUVCversion) + { + return DisplayMPEG1SSFormat( + (PVIDEO_FORMAT_MPEG1SS)VidCommonDesc); + } + else // this format is obsoleted in UVC version >= 1.1 + { + AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); + OOPS(); + break; + } + } + + case VS_FORMAT_MPEG2PS: + { + if (UVC10 == g_chUVCversion) + { + return DisplayMPEG2PSFormat( + (PVIDEO_FORMAT_MPEG2PS)VidCommonDesc); + } + else // this format is obsoleted in UVC version >= 1.1 + { + AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); + OOPS(); + break; + } + } + + case VS_FORMAT_MPEG2TS: + return DisplayMPEG2TSFormat( + (PVIDEO_FORMAT_MPEG2TS)VidCommonDesc); + + case VS_FORMAT_MPEG4SL: + { + if (UVC10 == g_chUVCversion) + { + return DisplayMPEG4SLFormat( + (PVIDEO_FORMAT_MPEG4SL)VidCommonDesc); + } + else // this format is obsoleted in UVC version >= 1.1 + { + AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); + OOPS(); + break; + } + } + + case VS_FORMAT_DV: + return DisplayDVFormat( + (PVIDEO_FORMAT_DV)VidCommonDesc); + + case VS_COLORFORMAT: + return DisplayColorMatching( + (PVIDEO_COLORFORMAT)VidCommonDesc); + + case VS_FORMAT_VENDOR: + { + if (UVC10 == g_chUVCversion) + { + return DisplayVendorVidFormat( + (PVIDEO_FORMAT_VENDOR)VidCommonDesc); + } + else // this format is obsoleted in UVC version >= 1.1 + { + AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); + OOPS(); + break; + } + } + + case VS_FRAME_VENDOR: + { + if (UVC10 == g_chUVCversion) + { + return DisplayVendorVidFrameType( + (PVIDEO_FRAME_VENDOR)VidCommonDesc); + } + else // this format is obsoleted in UVC version >= 1.1 + { + AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); + OOPS(); + break; + } + } + + case VS_FORMAT_FRAME_BASED: + { + if (UVC10 != g_chUVCversion) + { + return DisplayFramePayloadFormat( + (PVIDEO_FORMAT_FRAME)VidCommonDesc); + } + else // this format did not exist in UVC 1.0 + { + AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); + OOPS(); + break; + } + } + + case VS_FRAME_FRAME_BASED: + { + if (UVC10 != g_chUVCversion) + { + return DisplayFramePayloadFrame( + (PVIDEO_FRAME_FRAME)VidCommonDesc); + } + else // this format did not exist in UVC 1.0 + { + AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); + OOPS(); + break; + } + } + + case VS_FORMAT_STREAM_BASED: + { + if (UVC10 != g_chUVCversion) + { + return DisplayStreamPayload( + (PVIDEO_FORMAT_STREAM)VidCommonDesc); + } + else // this format did not exist in UVC 1.0 + { + AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); + OOPS(); + break; + } + } + + case VS_DESCRIPTOR_UNDEFINED: + //@@TestCase B1.3 + //@@CAUTION + //@@Descriptor Field - bDescriptorSubtype + //@@An undefined descriptor subtype has been defined + AppendTextBuffer("*!*CAUTION: This is an undefined class specific Video "\ + "Streaming bDescriptorSubtype\r\n"); + break; + + default: + //@@TestCase B1.4 + //@@ERROR + //@@Descriptor Field - bDescriptorSubtype + //@@An unknown descriptor subtype has been defined + AppendTextBuffer("*!*ERROR: unknown bDescriptorSubtype\r\n"); + OOPS(); + break; + } + break; + + default: + //@@TestCase B1.6 + //@@ERROR + //@@Descriptor Field - bInterfaceSubClass + //@@An unknown interface sub-class has been defined + AppendTextBuffer("*!*ERROR: unknown bInterfaceSubClass\r\n"); + OOPS(); + break; + } + break; + + case CS_ENDPOINT: + //@@DisplayVideoDescriptor -Class-Specific Video Endpoint Descriptor + switch (VidCommonDesc->bDescriptorSubtype) + { + //@@TestCase B1.7 + //@@CAUTION + //@@Descriptor Field - bInterfaceSubtype + //@@An undefined descriptor subtype has been defined + case EP_UNDEFINED: + AppendTextBuffer("*!*CAUTION: This is an undefined bDescriptorSubtype\r\n"); + break; + //@@TestCase B1.8 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - bDescriptorSubtype + //@@Question: How valid are VIDEO_EP_GENERAL and VIDEO_EP_ENDPOINT? Should we test? + case EP_GENERAL: + break; + case EP_ENDPOINT: + break; + case EP_INTERRUPT: + return DisplayVSEndpoint( + (PVIDEO_CS_INTERRUPT)VidCommonDesc); + break; + default: + //@@TestCase B1.9 + //@@ERROR + //@@Descriptor Field - bDescriptorSubtype + //@@An unknown descriptor subtype has been defined + AppendTextBuffer("*!*CAUTION: Unknown bDescriptorSubtype"); + break; + } + break; + //@@DisplayVideoDescriptor -Class-Specific Video Device Descriptor + //@@DisplayVideoDescriptor -Class-Specific Video Configuration Descriptor + //@@DisplayVideoDescriptor -Class-Specific Video String Descriptor + //@@DisplayVideoDescriptor -Class-Specific Video Undefined Descriptor + //@@TestCase B1.10 + //@@Not yet implemented - Priority 3 + //@@Descriptor -Class-Specific Device, Configuration, String, Undefined + //@@Descriptor Field - bDescriptorType + //@@Question: How valid are these Descriptor Types? Should we test? + + /* case USB_VIDEO_CS_DEVICE: + AppendTextBuffer("USB_VIDEO_CS_DEVICE bDescriptorType\r\n"); + break; + + case USB_VIDEO_CS_CONFIGURATION: + AppendTextBuffer("USB_VIDEO_CS_CONFIGURATION bDescriptorType\r\n"); + break; + + case USB_VIDEO_CS_STRING: + AppendTextBuffer("USB_VIDEO_CS_STRING bDescriptorType\r\n"); + break; + + case USB_VIDEO_CS_UNDEFINED: + AppendTextBuffer("USB_VIDEO_CS_UNDEFINED bDescriptorType\r\n"); + break; + */ + default: + //@@TestCase B1.11 + //@@ERROR + //@@Descriptor Field - bDescriptorType + //@@An unknown descriptor type has been defined + AppendTextBuffer("*!*CAUTION: Unknown bDescriptorSubtype"); + OOPS(); + break; + } + + return FALSE; +} + + +//***************************************************************************** +// +// DisplayVCHeader() +// +//***************************************************************************** + +BOOL +DisplayVCHeader ( + PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc + ) +{ + //@@DisplayVCHeader -Video Control Interface Header + UINT i = 0; + UINT uSize = 0; + PUCHAR pData = NULL; + + AppendTextBuffer("\r\n ===>Class-Specific Video Control Interface Header "\ + "Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VCInterfaceDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VCInterfaceDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VCInterfaceDesc->bDescriptorSubtype); + if ( UVC10 == g_chUVCversion ) + { + AppendTextBuffer("bcdVDC: 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); + } + else + { + AppendTextBuffer("bcdUVC: 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); + } + AppendTextBuffer("wTotalLength: 0x%04X", VCInterfaceDesc->wTotalLength); + + // Verify the total interface size (size of this header and all descriptors + // following until and not including the first endpoint) + uSize = GetVCInterfaceSize(VCInterfaceDesc); + if (uSize != VCInterfaceDesc->wTotalLength) { + AppendTextBuffer("\r\n*!*ERROR: Invalid total interface size 0x%02X, should be 0x%02X\r\n", + VCInterfaceDesc->wTotalLength, uSize); + } else { + AppendTextBuffer(" -> Validated\r\n"); + } + AppendTextBuffer("dwClockFreq: 0x%08X", + VCInterfaceDesc->dwClockFreq); + if (gDoAnnotation) + { + AppendTextBuffer(" = (%d) Hz", VCInterfaceDesc->dwClockFreq); + } + AppendTextBuffer("\r\nbInCollection: 0x%02X\r\n", + VCInterfaceDesc->bInCollection); + + // baInterfaceNr is a variable length field + // Size is in bInCollection + for (i = 1, pData = (PUCHAR) &VCInterfaceDesc->bInCollection; + i <= VCInterfaceDesc->bInCollection; i++, pData++) + { + AppendTextBuffer("baInterfaceNr[%d]: 0x%02X\r\n", + i, *pData); + } + + uSize = (sizeof(VIDEO_CONTROL_HEADER_UNIT) + VCInterfaceDesc->bInCollection); + if (VCInterfaceDesc->bLength != uSize) + { + //@@TestCase B2.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is less than required length in + //@@ the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + VCInterfaceDesc->bLength, uSize); + OOPS(); + } + + //@@TestCase B2.2 (also in Descript.c) + //@@WARNING + //@@Descriptor Field - bcdVDC + //@@The bcdVDC version of the device is not the same as the version of used by USBView + if(VCInterfaceDesc->bcdVideoSpec < BCDVDC) + { + AppendTextBuffer("*!*WARNING: This device is set to the old USB Video "\ + "Class spec version 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); + OOPS(); + } + + if (VCInterfaceDesc->dwClockFreq < 1) + { + //@@TestCase B2.3 (Descript.c Line 70) + //@@WARNING + //@@dwClockFrequency should be greater than 0 + //@@Question should we check that any non-zero value is accurate + AppendTextBuffer("*!*ERROR: dwClockFreq must be non-zero\r\n"); + OOPS(); + } + + //@@TestCase B2.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - baInterfaceNr + //@@We should test to verify each interface number is valid? + // for (i=0; i<VCInterfaceDesc->bInCollection; i++) + // {AppendTextBuffer("baInterfaceNr[%d]: 0x%02X\r\n", i+1, + // VCInterfaceDesc->baInterfaceNr[i]);} + + + if (gDoAnnotation) + { + switch(g_chUVCversion) + { + case UVC10: + AppendTextBuffer("USB Video Class device: spec version 1.0\r\n"); + break; + case UVC11: + AppendTextBuffer("USB Video Class device: spec version 1.1\r\n"); + break; +#ifdef H264_SUPPORT + case UVC15: + AppendTextBuffer("USB Video Class device: spec version 1.5\r\n"); + break; +#endif + + default: + break; + } + } + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCInputTerminal() +// +//***************************************************************************** + +BOOL +DisplayVCInputTerminal ( + PVIDEO_INPUT_TERMINAL VidITDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVCInputTerminal -Video Control Input Terminal + PCHAR pStr = NULL; + + AppendTextBuffer("\r\n ===>Video Control Input Terminal Descriptor<===\r\n"); + + AppendTextBuffer("bLength: 0x%02X\r\n", VidITDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidITDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidITDesc->bDescriptorSubtype); + AppendTextBuffer("bTerminalID: 0x%02X\r\n", VidITDesc->bTerminalID); + AppendTextBuffer("wTerminalType: 0x%04X", VidITDesc->wTerminalType); + if(gDoAnnotation) + { + pStr = GetStringFromList(slInputTermTypes, + sizeof(slInputTermTypes) / sizeof(STRINGLIST), + VidITDesc->wTerminalType, + "Invalid Input Terminal Type"); + AppendTextBuffer(" = (%s)", pStr); + } + AppendTextBuffer("\r\n"); + + AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidITDesc->bAssocTerminal); + AppendTextBuffer("iTerminal: 0x%02X\r\n", VidITDesc->iTerminal); + if (gDoAnnotation) + { + if (VidITDesc->iTerminal) + { + // if executing this code, the configuration descriptor has been + // obtained. If a device is suspended, then its configuration + // descriptor was not obtained and we do not want errors to be + // displayed when string descriptors were not obtained. + DisplayStringDescriptor(VidITDesc->iTerminal, StringDescs, LatestDevicePowerState); + } + } + + if (VidITDesc->bLength < sizeof(VIDEO_INPUT_TERMINAL)) + { + //@@TestCase B3.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is less than required length in + //@@ the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d is too small\r\n", VidITDesc->bLength); + OOPS(); + } + + if (VidITDesc->bTerminalID < 1) + { + //@@TestCase B3.2 (descript.c line 133) + //@@ERROR + //@@Descriptor Field - bTerminalID + //@@bTerminalID should be greater than 0 + //@@Question: Should test to verify terminal number is valid + AppendTextBuffer("*!*ERROR: bTerminalID of %d is too small\r\n", VidITDesc->bTerminalID); + OOPS(); + } + + if (!(pStr)) + { + //@@TestCase B3.3 + //@@CAUTION + //@@Descriptor Field - wTerminalType + //@@No valid Terminal Type was found + AppendTextBuffer("*!*CAUTION: 0x%04X is an unknown wTerminalType for an Input "\ + "Terminal\r\n", VidITDesc->wTerminalType); + OOPS(); + } + + //@@TestCase B3.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bAssocTerminal + //@@Should test to verify terminal number is valid? + // AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidITDesc->bAssocTerminal); + + switch (VidITDesc->wTerminalType) + { + case 0x0100: // TT_VENDOR_SPECIFIC Terminal Type + break; + case 0x0101: // TT_STREAMING Terminal Type + break; + case 0x0200: // ITT_VENDOR_SPECIFIC Terminal Type + break; + case 0x0201: // ITT_CAMERA Terminal Type + return DisplayVCCameraTerminal( + (PVIDEO_CAMERA_TERMINAL)VidITDesc); + case 0x0202: // ITT_MEDIA_TRANSPORT_INPUT Terminal Type + return DisplayVCMediaTransInputTerminal( + (PVIDEO_INPUT_MTT)VidITDesc); + case 0x0400: // EXTERNAL_VENDOR_SPECIFIC Terminal Type + break; + case 0x0401: // COMPOSITE_CONNECTOR Terminal Type + break; + case 0x0402: // SVIDEO_CONNECTOR Terminal Type + break; + case 0x0403: // COMPONENT_CONNECTOR Terminal Type + break; + default: + break; + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCOutputTerminal() +// +//***************************************************************************** + +BOOL +DisplayVCOutputTerminal ( + PVIDEO_OUTPUT_TERMINAL VidOTDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVCOutputTerminal -Video Control Output Terminal + PCHAR pStr = NULL; + + AppendTextBuffer("\r\n ===>Video Control Output Terminal Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidOTDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidOTDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidOTDesc->bDescriptorSubtype); + AppendTextBuffer("bTerminalID: 0x%02X\r\n", VidOTDesc->bTerminalID); + AppendTextBuffer("wTerminalType: 0x%04X", VidOTDesc->wTerminalType); + if(gDoAnnotation) + { + pStr = GetStringFromList(slOutputTermTypes, + sizeof(slOutputTermTypes) / sizeof(STRINGLIST), + VidOTDesc->wTerminalType, + "Invalid Output Terminal Type"); + AppendTextBuffer(" = (%s)", pStr); + } + AppendTextBuffer("\r\n"); + AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidOTDesc->bAssocTerminal); + AppendTextBuffer("bSourceID: 0x%02X\r\n", VidOTDesc->bSourceID); + AppendTextBuffer("iTerminal: 0x%02X\r\n", VidOTDesc->iTerminal); + if (gDoAnnotation) + { + if (VidOTDesc->iTerminal) + { + // if executing this code, the configuration descriptor has been + // obtained. If a device is suspended, then its configuration + // descriptor was not obtained and we do not want errors to be + // displayed when string descriptors were not obtained. + DisplayStringDescriptor(VidOTDesc->iTerminal, StringDescs, LatestDevicePowerState); + } + } + + if (VidOTDesc->bLength < sizeof(PVIDEO_OUTPUT_TERMINAL)) + { + //@@TestCase B4.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is less than required length in + //@@ the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d is too small\r\n", VidOTDesc->bLength); + OOPS(); + } + + if (VidOTDesc->bTerminalID < 1) + { + //@@TestCase B4.2 (see Descript.c line 328) + //@@ERROR + //@@Descriptor Field - bTerminalID + //@@bTerminalID should be greater than 0 + //@@Question: Should test to verify terminal number is valid + AppendTextBuffer("*!*ERROR: bTerminalID of %d is too small\r\n", VidOTDesc->bTerminalID); + OOPS(); + } + + + if (!(pStr)) + { + //@@TestCase B4.3 + //@@ERROR + //@@Descriptor Field - wTerminalType + //@@No valid Terminal Type was found + AppendTextBuffer("*!*ERROR: 0x%04X is an invalid wTerminalType for an Output Terminal\r\n", + VidOTDesc->wTerminalType); + OOPS(); + } + + //@@TestCase B4.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bAssocTerminal + //@@We should test to verify terminal number is valid + // AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidOTDesc->bAssocTerminal); + + if (VidOTDesc->bSourceID < 1) + { + //@@TestCase B4.5 (see Descript.c line 333) + //@@ERROR + //@@Descriptor Field - bSourceID + //@@bSourceID should be greater than 0 + //@@Question: Should test to verify source number is valid + AppendTextBuffer("*!*ERROR: bSourceID of %d is too small\r\n", VidOTDesc->bSourceID); + OOPS(); + } + + switch (VidOTDesc->wTerminalType) + { + case 0x0100: // TT_VENDOR_SPECIFIC Terminal Type + break; + case 0x0101: // TT_STREAMING Terminal Type + break; + case 0x0300: // OTT_VENDOR_SPECIFIC Terminal Type + break; + case 0x0301: // OTT_DISPLAY Terminal Type + break; + case 0x0302: // OTT_MEDIA_TRANSPORT_OUTPUT Terminal Type + return DisplayVCMediaTransOutputTerminal( + (PVIDEO_OUTPUT_MTT)VidOTDesc); + case 0x0400: // EXTERNAL_VENDOR_SPECIFIC Terminal Type + break; + case 0x0401: // COMPOSITE_CONNECTOR Terminal Type + break; + case 0x0402: // SVIDEO_CONNECTOR Terminal Type + break; + case 0x0403: // COMPONENT_CONNECTOR Terminal Type + break; + default: + break; + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCMediaTransInputTerminal() +// +//***************************************************************************** + +BOOL +DisplayVCMediaTransInputTerminal( + PVIDEO_INPUT_MTT MediaTransportInDesc + ) +{ + //@@DisplayVCMediaTransInputTerminal -Video Control Media Transport Input Terminal + UCHAR p = 0; + PUCHAR pData = NULL; + size_t bLength = 0; + + bLength = SizeOfVideoInputMTT(MediaTransportInDesc); + + AppendTextBuffer("===>Additional Media Transport Input Terminal Data\r\n"); + AppendTextBuffer("bControlSize: 0x%02X\r\n", + MediaTransportInDesc->bControlSize); + + // point to bControlSize + pData = & MediaTransportInDesc->bControlSize; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportControls, + sizeof(slMediaTransportControls) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportCtrl bmControl value")); + + cMask = cMask << 1; + } + } + + // point to bTransportModeSize + pData = pData + 2 ; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes1, + sizeof(slMediaTransportModes1) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + + // Is there a second control? + if (1 < * pData) + { + // map the second control + for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 2); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes2, + sizeof(slMediaTransportModes2) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a third control? + if (2 < * pData) + { + // map the third control + for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 3); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes3, + sizeof(slMediaTransportModes3) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a fourth control? + if (3 < * pData) + { + // map the fourth control + for ( uBitIndex = 24, cMask = 1; uBitIndex < 32; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 4); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes4, + sizeof(slMediaTransportModes4) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a fifth control? + if (4 < * pData) + { + // map the fifth control + for ( uBitIndex = 32, cMask = 1; uBitIndex < 40; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 5); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes5, + sizeof(slMediaTransportModes5) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + } + + // The size of a Media Transport Descriptor is + // the size of the Descriptor plus + // (bControlSize - 1) plus + // IF bmControls & 1 THEN 1 (bTransportModeSize) plus + // bTransportModeSize + // +// p = sizeof(VIDEO_INPUT_MTT) + +// (MediaTransportInDesc->bControlSize - 1); +// if (MediaTransportInDesc->bmControls[0] & 1) +// p += 1 + (*pData); + if (MediaTransportInDesc->bLength != bLength) + { + //@@TestCase B5.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@Invalid Descriptor length + AppendTextBuffer("*!*ERROR: Invalid descriptor bLength 0x%02X. "\ + "Should be 0x%02X\r\n", + MediaTransportInDesc->bLength, p); + OOPS(); + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCMediaTransOutputTerminal() +// +//***************************************************************************** + +BOOL +DisplayVCMediaTransOutputTerminal( + PVIDEO_OUTPUT_MTT MediaTransportOutDesc + ) +{ + //@@DisplayVCMediaTransOutputTerminal -Video Control Media Transport Output Terminal + UCHAR p = 0; + PUCHAR pData = NULL; + + AppendTextBuffer("===>Additional Media Transport Output Terminal Data\r\n"); + AppendTextBuffer("bControlSize: 0x%02X\r\n", + MediaTransportOutDesc->bControlSize); + + // point to bControlSize + pData = & MediaTransportOutDesc->bControlSize; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportControls, + sizeof(slMediaTransportControls) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportCtrl bmControl value")); + + cMask = cMask << 1; + } + } + + // point to bTransportModeSize + pData = pData + 2 ; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes1, + sizeof(slMediaTransportModes1) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + + // Is there a second control? + if (1 < * pData) + { + // map the second control + for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 2); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes2, + sizeof(slMediaTransportModes2) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a third control? + if (2 < * pData) + { + // map the third control + for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 3); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes3, + sizeof(slMediaTransportModes3) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a fourth control? + if (3 < * pData) + { + // map the fourth control + for ( uBitIndex = 24, cMask = 1; uBitIndex < 32; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 4); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes4, + sizeof(slMediaTransportModes4) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + // Is there a fifth control? + if (4 < * pData) + { + // map the fourth control + for ( uBitIndex = 32, cMask = 1; uBitIndex < 40; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 5); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slMediaTransportModes5, + sizeof(slMediaTransportModes5) / sizeof(STRINGLIST), + cMask, + "Invalid MediaTransportMode value")); + + cMask = cMask << 1; + } + } + } + + // The size of a Media Transport Descriptor is + // the size of the Descriptor plus + // (bControlSize - 1) plus + // IF bmControls & 1 THEN 1 (bTransportModeSize) plus + // bTransportModeSize + // + p = sizeof(VIDEO_OUTPUT_MTT) + + (MediaTransportOutDesc->bControlSize - 1); + if (MediaTransportOutDesc->bmControls[0] & 1) + p += 1 + (*pData); + if (MediaTransportOutDesc->bLength != p) + { + //@@TestCase B5.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@Invalid Descriptor length + AppendTextBuffer("*!*ERROR: Invalid descriptor bLength 0x%02X. "\ + "Should be 0x%02X\r\n", + MediaTransportOutDesc->bLength, p); + OOPS(); + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCCameraTerminal() +// +//***************************************************************************** + +BOOL +DisplayVCCameraTerminal( + PVIDEO_CAMERA_TERMINAL CameraDesc + ) +{ + //@@DisplayVCCameraTerminal -Video Control Camera Terminal + UCHAR p = 0; + PUCHAR pData = NULL; + + AppendTextBuffer("===>Camera Input Terminal Data\r\n"); + AppendTextBuffer("wObjectiveFocalLengthMin: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMin); + AppendTextBuffer("wObjectiveFocalLengthMax: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMax); + AppendTextBuffer("wOcularFocalLength: 0x%04X\r\n", CameraDesc->wOcularFocalLength); + AppendTextBuffer("bControlSize: 0x%02X\r\n", CameraDesc->bControlSize); + + pData = &CameraDesc->bControlSize; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slCameraControl1, + sizeof(slCameraControl1) / sizeof(STRINGLIST), + cMask, + "Invalid CamCtrl bmControl value")); + + cMask = cMask << 1; + } + + // Is there a second control? + if (1 < * pData) + { + // map the second control + for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 2); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slCameraControl2, + sizeof(slCameraControl2) / sizeof(STRINGLIST), + cMask, + "Invalid CamCtrl bmControl value")); + + cMask = cMask << 1; + } + } + // Is there a third control? + if (2 < * pData) + { + // map the third control + for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 3); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slCameraControl3, + sizeof(slCameraControl3) / sizeof(STRINGLIST), + cMask, + "Invalid CamCtrl bmControl value")); + + cMask = cMask << 1; + } + } + } + + p = (sizeof(VIDEO_CAMERA_TERMINAL) + CameraDesc->bControlSize); + if (CameraDesc->bLength != p) + { + //@@TestCase B7.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The descriptor should be the size of the descriptor structure + //@@ plus the number of controls + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + CameraDesc->bLength, p); + OOPS(); + } + + //@@TestCase B7.2 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - wObjectiveFocalLengthMin + //@@Question - Should we do any checking here? What are the acceptable boundaries? + //@@Question - Is zero an acceptable value? + // AppendTextBuffer("wObjectiveFocalLengthMin: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMin); + + //@@TestCase B7.3 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - wObjectiveFocalLengthMax + //@@Question - Should we do any checking here? What are the acceptable boundaries + //@@Question - Is zero an acceptable value? + // AppendTextBuffer("wObjectiveFocalLengthMax: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMax); + + //@@TestCase B7.4 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - wOcularFocalLength + //@@Question - Should we do any checking here? What are the acceptable boundaries + //@@Question - Is zero an acceptable value? + // AppendTextBuffer("wOcularFocalLength: 0x%04X\r\n", CameraDesc->wOcularFocalLength); + + //@@TestCase B7.5 + //@@ERROR + //@@Descriptor Field - wObjectiveFocalLengthMin and wObjectiveFocalLengthMax + //@@Verify that wObjectiveFocalLengthMax is greater than wObjectiveFocalLengthMin + if(CameraDesc->wObjectiveFocalLengthMin > CameraDesc->wObjectiveFocalLengthMax) + { + AppendTextBuffer("*!*ERROR: wObjectiveFocalLengthMin is larger than wObjectiveFocalLengthMax\r\n"); + OOPS(); + } + + //@@TestCase B7.6 + //@@ERROR + //@@Descriptor Field - bControlSize + //@@Verify that wObjectiveFocalLengthMax is 3 or less + if(CameraDesc->bControlSize > 3) + { + AppendTextBuffer("*!*ERROR: bControlSize must be 3 or less\r\n"); + OOPS(); + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayVCSelectorUnit() +// +//***************************************************************************** + +BOOL +DisplayVCSelectorUnit ( + PVIDEO_SELECTOR_UNIT VidSelectorDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVCSelectorUnit -Video Control Selector Unit + UCHAR i = 0; + UCHAR p = 0; + PUCHAR pData = NULL; + + AppendTextBuffer("\r\n ===>Video Control Selector Unit Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidSelectorDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidSelectorDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidSelectorDesc->bDescriptorSubtype); + AppendTextBuffer("bUnitID: 0x%02X\r\n", VidSelectorDesc->bUnitID); + AppendTextBuffer("bNrInPins: 0x%02X\r\n", VidSelectorDesc->bNrInPins); + if (gDoAnnotation) + { + AppendTextBuffer("===>List of Connected Unit and Terminal ID's\r\n"); + } + // baSourceID is a variable length field + // Size is in bNrInPins, must be at least 1 (so index starts at 1) + for (i = 1, pData = (PUCHAR) &VidSelectorDesc->baSourceID; + i <= VidSelectorDesc->bNrInPins; i++, pData++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i, *pData); + } + + // get address of iSelector, the last field in this descriptor + pData = (PUCHAR) VidSelectorDesc + (VidSelectorDesc->bLength - 1); + AppendTextBuffer("iSelector: 0x%02X\r\n", *pData); + if (gDoAnnotation) + { + if (*pData) + { + // if executing this code, the configuration descriptor has been + // obtained. If a device is suspended, then its configuration + // descriptor was not obtained and we do not want errors to be + // displayed when string descriptors were not obtained. + DisplayStringDescriptor(*pData, StringDescs, LatestDevicePowerState); + } + } + + p = (sizeof(VIDEO_SELECTOR_UNIT) + VidSelectorDesc->bNrInPins + 1); + if (VidSelectorDesc->bLength != p) + { + //@@TestCase B8.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The descriptor should be the size of the descriptor structure plus the number of pins + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + VidSelectorDesc->bLength, p); + OOPS(); + } + + if (VidSelectorDesc->bUnitID < 1) + { + //@@TestCase B8.2 (Descript.c Line 396) + //@@ERROR + //@@Descriptor Field - bUnitID + //@@bUnitID must be greater than 0 + //@@Question: Should we test to verify unit number is unique? + AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); + OOPS(); + } + + if (VidSelectorDesc->bNrInPins < 1) + { + //@@TestCase B8.3 + //@@ERROR + //@@Descriptor Field - bNrInPins + //@@bNrInPins should be greater than 0 + //@@Question: Should test to verify total in pins is valid + AppendTextBuffer("*!*ERROR: bNrInPins must be non-zero\r\n"); + OOPS(); + } + + // baSourceID is a variable length field + // Size is in bNrInPins, must be at least 1 (so index starts at 1) + for (i = 1, pData = (PUCHAR) &VidSelectorDesc->baSourceID; + i <= VidSelectorDesc->bNrInPins; i++, pData++) + { + if (*pData < 1) + { + //@@TestCase B8.4 + //@@ERROR + //@@Descriptor Field - baSourceID[] + //@@baSourceID should be greater than 0 + AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", i); + OOPS(); + } else { + if (! ValidateTerminalID(*pData)) { + //@@TestCase B8.5 + //@@ERROR + //@@Descriptor Field - baSourceID[] + //@@baSourceID should be a valid terminal ID + AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", i); + OOPS(); + } + } + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCProcessingUnit() +// +//***************************************************************************** + +BOOL +DisplayVCProcessingUnit ( + PVIDEO_PROCESSING_UNIT VidProcessingDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVCProcessingUnit -Video Control Processor Unit + PUCHAR pData = NULL; + UCHAR bLength = 0; + + AppendTextBuffer("\r\n ===>Video Control Processing Unit Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidProcessingDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidProcessingDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidProcessingDesc->bDescriptorSubtype); + AppendTextBuffer("bUnitID: 0x%02X\r\n", VidProcessingDesc->bUnitID); + AppendTextBuffer("bSourceID: 0x%02X\r\n", VidProcessingDesc->bSourceID); + AppendTextBuffer("wMaxMultiplier: 0x%04X\r\n", VidProcessingDesc->wMaxMultiplier); + AppendTextBuffer("bControlSize: 0x%02X\r\n", VidProcessingDesc->bControlSize); + + pData = &VidProcessingDesc->bControlSize; + + // Are there any controls? + if (0 < * pData) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 1); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slProcessorControls1, + sizeof(slProcessorControls1) / sizeof(STRINGLIST), + cMask, + "Invalid PU bmControl value")); + + cMask = cMask << 1; + } + + // Is there a second control? + if (1 < * pData) + { + // map the second control + for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 2); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slProcessorControls2, + sizeof(slProcessorControls2) / sizeof(STRINGLIST), + cMask, + "Invalid PU bmControl value")); + + cMask = cMask << 1; + } + } + + // Is there a third control? + if (2 < * pData) + { + // map the third control + for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + 3); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slProcessorControls3, + sizeof(slProcessorControls3) / sizeof(STRINGLIST), + cMask, + "Invalid PU bmControl value")); + + cMask = cMask << 1; + } + } + } + + // get address of iProcessing + if (UVC10 != g_chUVCversion) + { + // size of descriptor is struct size plus control size plus 2 if UVC11 + bLength = sizeof(VIDEO_PROCESSING_UNIT) + 2 + VidProcessingDesc->bControlSize; + pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 2); + } + else // UVC 1.0 + { + // size of descriptor is struct size plus control size plus 1 if UVC10 + bLength = sizeof(VIDEO_PROCESSING_UNIT) + 1 + VidProcessingDesc->bControlSize; + pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 1); + } + AppendTextBuffer("iProcessing : 0x%02X\r\n", *pData); + if (gDoAnnotation) + { + if (*pData) + { + // if executing this code, the configuration descriptor has been + // obtained. If a device is suspended, then its configuration + // descriptor was not obtained and we do not want errors to be + // displayed when string descriptors were not obtained. + DisplayStringDescriptor(*pData, StringDescs, LatestDevicePowerState); + } + } + + // check for new UVC 1.1 bmVideoStandards fields + if (UVC10 != g_chUVCversion) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 1); + + AppendTextBuffer("bmVideoStandards : "); + VDisplayBytes(pData, 1); + + // map the first control + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slProcessorVideoStandards, + sizeof(slProcessorVideoStandards) / sizeof(STRINGLIST), + cMask, + "Invalid PU bmVideoStandards value")); + + cMask = cMask << 1; + } + } + + if (VidProcessingDesc->bLength != bLength) + { + //@@TestCase B9.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + AppendTextBuffer("*!*ERROR: bLength of 0x%02X incorrect, should be 0x%02X\r\n", + VidProcessingDesc->bLength, bLength); + OOPS(); + } + + if (VidProcessingDesc->bUnitID < 1) + { + //@@TestCase B9.2 (Descript.c Line 466) + //@@ERROR + //@@Descriptor Field - bUnitID + //@@bUnitID must be greater than 0 + //@@Question: Should we test to verify unit number is unique? + AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); + OOPS(); + } + + if (VidProcessingDesc->bSourceID < 1) + { + //@@TestCase B9.3 (Descript.c Line 471) + //@@ERROR + //@@Descriptor Field - bSourceID + //@@bSourceID must be non-zero + //@@Question: Should we test to verify the bSourceID is valid? + AppendTextBuffer("*!*ERROR: bSourceID must be non-zero\r\n"); + OOPS(); + } + + //@@TestCase B9.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - wMaxMultiplier + //@@We should test to verify multiplier is valid + // AppendTextBuffer("wMaxMultiplier: 0x%04X\r\n", VidProcessingDesc->wMaxMultiplier); + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCExtensionUnit() +// +//***************************************************************************** + +BOOL +DisplayVCExtensionUnit ( + PVIDEO_EXTENSION_UNIT VidExtensionDesc, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ) +{ + //@@DisplayVCExtensionUnit -Video Control Extension Unit + int i = 0; + UCHAR p = 0; + UCHAR bControlSize = 0; + PUCHAR pData = NULL; + OLECHAR szGUID[256]; + size_t bLength = 0; + + bLength = SizeOfVideoExtensionUnit(VidExtensionDesc); + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) &VidExtensionDesc->guidExtensionCode, (LPOLESTR) szGUID, 255); + i++; + + AppendTextBuffer("\r\n ===>Video Control Extension Unit Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidExtensionDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidExtensionDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidExtensionDesc->bDescriptorSubtype); + AppendTextBuffer("bUnitID: 0x%02X\r\n", VidExtensionDesc->bUnitID); + AppendTextBuffer("guidExtensionCode: %S\r\n", szGUID); + AppendTextBuffer("bNumControls: 0x%02X\r\n", VidExtensionDesc->bNumControls); + AppendTextBuffer("bNrInPins: 0x%02X\r\n", VidExtensionDesc->bNrInPins); + if (gDoAnnotation) + { + AppendTextBuffer("===>List of Connected Units and Terminal ID's\r\n"); + } + // baSourceID is a variable length field + // Size is in bNrInPins, must be at least 1 (so index starts at 1) + for (i = 1, pData = (PUCHAR) &VidExtensionDesc->baSourceID; + i <= VidExtensionDesc->bNrInPins; i++, pData++) + { + AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", + i, *pData); + } + // point to bControlSize (address of bNrInPins plus number of fields in bNrInPins + // plus 1 for next field) + pData = &VidExtensionDesc->bNrInPins + VidExtensionDesc->bNrInPins +1; + bControlSize = *pData; + AppendTextBuffer("bControlSize: 0x%02X\r\n", bControlSize); + + // Are there any controls? + if ( bControlSize > 0) + { + AppendTextBuffer("bmControls : "); + VDisplayBytes(pData + 1, *pData); + + // Map one byte at a time of the bmControls field in the Video Control Extension Unit Descriptor + for (i = 1; i <= bControlSize; i++) + { + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + // map byte + for ( ; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData + i); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex + 8 * (i-1), + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + "Vendor-Specific (Optional)"); + + cMask = cMask << 1; + } + } + } + + // get address of iExtension + pData = &VidExtensionDesc->bNrInPins + VidExtensionDesc->bNrInPins + bControlSize + 2; +// pData = (PUCHAR) VidExtensionDesc + (VidExtensionDesc->bLength - 1); + AppendTextBuffer("iExtension: 0x%02X\r\n", *pData); + if (gDoAnnotation) + { + if (*pData) + { + DisplayStringDescriptor(*pData,StringDescs, LatestDevicePowerState); + } + } + + // size of descriptor struct size (23) + bNrInPins + bControlSize + iExtension size + // +// p = (sizeof(VIDEO_EXTENSION_UNIT) +// + VidExtensionDesc->bNrInPins + bControlSize + 1); + if (VidExtensionDesc->bLength != bLength) + { + //@@TestCase B10.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of 0x%02X incorrect, should be 0x%02X\r\n", + VidExtensionDesc->bLength, p); + OOPS(); + } + + if (VidExtensionDesc->bUnitID < 1) + { + //@@TestCase B10.2 (Descript.c Line 517) + //@@ERROR + //@@Descriptor Field - bUnitID + //@@bUnitID must be non-zero + //@@Question: Should we test to verify bUnitID is valid + AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); + OOPS(); + } + + //bugbug do we need two + if (VidExtensionDesc->bNrInPins < 1) + { + //@@TestCase B10.3 (Descript.c Line 522) + //@@ERROR + //@@Descriptor Field - bNrInPins + //@@bNrInPins must be non-zero + //@@Question: Should we test to verify bNrInPins is valid + AppendTextBuffer("*!*ERROR: bNrInPins must be non-zero\r\n"); + OOPS(); + } + + for (i = 1, pData = (PUCHAR) &VidExtensionDesc->baSourceID; + i <= VidExtensionDesc->bNrInPins; i++, pData++) + { + if (*pData == 0) + { + //@@TestCase B10.4 (Descript.c Line 527) + //@@ERROR + //@@Descriptor Field - baSourceID[] + //@@baSourceID[] must be non-zero + //@@Question: Should we test to verify baSourceID is valid + AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", *pData); + OOPS(); + } + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayVidInHeaderl() +// +//***************************************************************************** + +BOOL +DisplayVidInHeader ( + PVIDEO_STREAMING_INPUT_HEADER VidInHeaderDesc + ) +{ + //@@DisplayVidInHeader -Video Streaming Video Input Header + UINT p = 0; + UINT uCount = 0; + PUCHAR pData = NULL; + + AppendTextBuffer("\r\n ===>Video Class-Specific VS Video Input Header Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidInHeaderDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidInHeaderDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidInHeaderDesc->bDescriptorSubtype); + AppendTextBuffer("bNumFormats: 0x%02X\r\n", VidInHeaderDesc->bNumFormats); + AppendTextBuffer("wTotalLength: 0x%04X", VidInHeaderDesc->wTotalLength); + + uCount = GetVSInterfaceSize((PUSB_COMMON_DESCRIPTOR) VidInHeaderDesc, VidInHeaderDesc->wTotalLength); + if (uCount != VidInHeaderDesc->wTotalLength) { + AppendTextBuffer("\r\n*!*ERROR: invalid interface size 0x%02X, should be 0x%02X\r\n", + VidInHeaderDesc->wTotalLength, uCount); + } else { + AppendTextBuffer(" -> Validated\r\n"); + } + + AppendTextBuffer("bEndpointAddress: 0x%02X", + VidInHeaderDesc->bEndpointAddress); + if (USB_ENDPOINT_DIRECTION_IN(VidInHeaderDesc->bEndpointAddress)) + { + if (gDoAnnotation) + { + AppendTextBuffer(" -> Direction: IN - EndpointID: %d", + (VidInHeaderDesc->bEndpointAddress & 0x0F)); + } + AppendTextBuffer("\r\n"); + } + AppendTextBuffer("bmInfo: 0x%02X", VidInHeaderDesc->bmInfo); + if (gDoAnnotation) + { + AppendTextBuffer(" -> Dynamic Format Change %sSupported", + ! (VidInHeaderDesc->bmInfo & 0x01) ? "not " : " "); + } + AppendTextBuffer("\r\nbTerminalLink: 0x%02X\r\n", + VidInHeaderDesc->bTerminalLink); + AppendTextBuffer("bStillCaptureMethod: 0x%02X", + VidInHeaderDesc->bStillCaptureMethod); + + // globally save the StillMethod, then verify value + StillMethod = VidInHeaderDesc->bStillCaptureMethod; + if (StillMethod > 3) + { + //@@TestCase B11.1 (Descript.c Line 798) + //@@ERROR + //@@Descriptor Field - bStillCaptureMethod + //@@bStillCaptureMethod is greater than 3 + AppendTextBuffer("*!*ERROR: invalid bStillCaptureMethod 0x%02X\r\n", + VidInHeaderDesc->bStillCaptureMethod); + if (gDoAnnotation) + { + AppendTextBuffer(" -> Invalid Still Capture Method"); + } + } + else + { + if (0 == StillMethod) + { + AppendTextBuffer(" -> No Still Capture"); + } + else + { + AppendTextBuffer(" -> Still Capture Method %d", + VidInHeaderDesc->bStillCaptureMethod); + } + } + + AppendTextBuffer("\r\nbTriggerSupport: 0x%02X", + VidInHeaderDesc->bTriggerSupport); + if(gDoAnnotation) + { + AppendTextBuffer(" -> "); + if (! VidInHeaderDesc->bTriggerSupport) + AppendTextBuffer("No "); + AppendTextBuffer("Hardware Triggering Support"); + } + AppendTextBuffer("\r\n"); + + AppendTextBuffer("bTriggerUsage: 0x%02X", + VidInHeaderDesc->bTriggerUsage); + if (gDoAnnotation) + { + if (VidInHeaderDesc->bTriggerSupport != 0) + { + if (VidInHeaderDesc->bTriggerUsage == 0) + AppendTextBuffer(" -> Host will initiate still image capture"); + if (VidInHeaderDesc->bTriggerUsage == 1) + AppendTextBuffer(" -> Host will notify client application of button event"); + } + } + + AppendTextBuffer("\r\nbControlSize: 0x%02X\r\n", + VidInHeaderDesc->bControlSize); + + // are there formats to display? + if (VidInHeaderDesc->bNumFormats) + { + UINT uFormatIndex = 1; + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + // There are (bNumFormats) bmaControls fields, each with size (bControlSize) + pData = (PUCHAR) &(VidInHeaderDesc->bControlSize); + + // VidInHeaderDesc->bNumFormats -> number of formats + // VidInHeaderDesc->bControlSize -> size of EACH format control + // ((PUCHAR) &VidInHeaderDesc->bControlSize) + 1 -> address of first format control + for ( pData++ ; uFormatIndex <= VidInHeaderDesc->bNumFormats; uFormatIndex++ ) + { + AppendTextBuffer("Video Payload Format %d ", uFormatIndex); + + // Handle case of 0 control size + if (! VidInHeaderDesc->bControlSize) + { + AppendTextBuffer("0x00\r\n"); + } + else + { + VDisplayBytes(pData, VidInHeaderDesc->bControlSize); + + // map the first control + for (uBitIndex = 0, cMask = 1; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pData); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slInputHeaderControls, + sizeof(slInputHeaderControls) / sizeof(STRINGLIST), + cMask, + "Invalid Control value")); + + cMask = cMask << 1; + } + } + pData += VidInHeaderDesc->bControlSize; + } + } + + p = (sizeof(VIDEO_STREAMING_INPUT_HEADER) + + (VidInHeaderDesc->bNumFormats * VidInHeaderDesc->bControlSize)); + if (VidInHeaderDesc->bLength != p) + { + //@@TestCase B11.2 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The descriptor should be the size of the descriptor structure + //@@ plus the number of formats times the size of each format + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + VidInHeaderDesc->bLength, p); + OOPS(); + } + + if (VidInHeaderDesc->bNumFormats < 1) + { + //@@TestCase B11.3 (Descript.c Line778) + //@@ERROR + //@@Descriptor Field - bNumFormats + //@@bNumFormats must be non-zero + //@@Question: Should we test to verify the non-zero value for bNumFormats is valid + AppendTextBuffer("*!*ERROR: bNumFormats must be non-zero\r\n", + VidInHeaderDesc->bNumFormats); + OOPS(); + } + + if (VidInHeaderDesc->bEndpointAddress < 1) + { + //@@TestCase B11.4 (Descript.c Line788) + //@@ERROR + //@@Descriptor Field - bEndpointAddress + //@@bEndpointAddress should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bEndpointAddress is valid + AppendTextBuffer("*!*ERROR: bEndpointAddress of %d is too small\r\n", + VidInHeaderDesc->bEndpointAddress); + OOPS(); + } + + //@@TestCase B11.5 + //@@ERROR + //@@Descriptor Field - bEndPointAddress + //@@The bEndPointAddress is set incorrectly according to the USB Video Device Specification + if (!USB_ENDPOINT_DIRECTION_IN(VidInHeaderDesc->bEndpointAddress)){ + AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress needs to have the Direction IN for this header\r\n"); + OOPS();} + + //@@TestCase B11.6 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmInfo + //@@We should validate that reserved bits are set to zero. + // AppendTextBuffer("bmInfo: 0x%02X", VidInHeaderDesc->bmInfo); + + if (VidInHeaderDesc->bTerminalLink < 1) + { + //@@TestCase B11.7 (Descript.c Line 793) + //@@ERROR + //@@Descriptor Field - bTerminalLink + //@@bTerminalLink should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bTerminalLink is valid + AppendTextBuffer("*!*ERROR: bTerminalLink of %d is too small\r\n", + VidInHeaderDesc->bTerminalLink); + OOPS(); + } + + //@@TestCase B11.8 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bTriggerSupport + //@@We should validate that reserved bits are set to zero. + // AppendTextBuffer("bTriggerSupport: 0x%02X", VidInHeaderDesc->bTriggerSupport); + + //@@TestCase B11.9 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bTriggerUsage + //@@We should validate that reserved bits are set to zero. + // AppendTextBuffer("bTriggerUsage: 0x%02X", VidInHeaderDesc->bTriggerUsage); + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVidOutHeader() +// +//***************************************************************************** + +BOOL +DisplayVidOutHeader ( + PVIDEO_STREAMING_OUTPUT_HEADER VidOutHeaderDesc + ) +{ + //@@DisplayVidOutHeader -Video Streaming Video Output Header + UINT uCount = 0; + UCHAR bLength = sizeof(VIDEO_STREAMING_OUTPUT_HEADER); + + AppendTextBuffer("\r\n ===>Video Class-Specific VS Video Output Header Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VidOutHeaderDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidOutHeaderDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidOutHeaderDesc->bDescriptorSubtype); + AppendTextBuffer("bNumFormats: 0x%02X\r\n", VidOutHeaderDesc->bNumFormats); + AppendTextBuffer("wTotalLength: 0x%04X", VidOutHeaderDesc->wTotalLength); + + uCount = GetVSInterfaceSize((PUSB_COMMON_DESCRIPTOR) VidOutHeaderDesc, VidOutHeaderDesc->wTotalLength); + if (uCount != VidOutHeaderDesc->wTotalLength) { + AppendTextBuffer("\r\n*!*ERROR: invalid interface size 0x%02X, should be 0x%02X\r\n", + VidOutHeaderDesc->wTotalLength, uCount); + } else { + AppendTextBuffer(" -> Validated\r\n"); + } + + AppendTextBuffer("bEndpointAddress: 0x%02X", VidOutHeaderDesc->bEndpointAddress); + if(USB_ENDPOINT_DIRECTION_OUT(VidOutHeaderDesc->bEndpointAddress)) { + if (gDoAnnotation) + { + AppendTextBuffer(" -> Direction: OUT - EndpointID: %d", + (VidOutHeaderDesc->bEndpointAddress & 0x0F)); + } + AppendTextBuffer("\r\n"); + } + AppendTextBuffer("bTerminalLink: 0x%02X\r\n", VidOutHeaderDesc->bTerminalLink); + + // UVC11 Video Output Header has additional fields, larger size +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) +#else + if (UVC11 == g_chUVCversion) +#endif + { + UCHAR bControlSize = 0; + PUCHAR pControls = NULL; + + // bControlSize field is next after bTerminalLink + pControls = &(VidOutHeaderDesc->bTerminalLink)+1; + bControlSize = *(pControls); + // point to first bmaControls + pControls++; + + // Size of UVC 1.1 Video Output Header is 1.0 size + // plus 1 (bControlSize field) plus (number of formats * bControlSize) + bLength += 1 + (VidOutHeaderDesc->bNumFormats * bControlSize); + + // Need new uvcdesc.h to handle new fields + AppendTextBuffer("bControlSize: 0x%02X\r\n", bControlSize); + + // are there formats to display? + if (VidOutHeaderDesc->bNumFormats) + { + UINT uFormatIndex = 1; + UINT uBitIndex = 0; + BYTE cCheckBit = 0; + BYTE cMask = 1; + + // There are (bNumFormats) bmaControls fields, each with size (bControlSize) + for ( ; uFormatIndex <= VidOutHeaderDesc->bNumFormats; uFormatIndex++, pControls ++) + { + AppendTextBuffer("Video Payload Format %d ", uFormatIndex); + + // Handle case of 0 control size + if (0 == bControlSize) + { + AppendTextBuffer("0x00\r\n"); + } + else + { + VDisplayBytes(pControls, bControlSize); + + // map the first control + for (uBitIndex = 0, cMask = 1; uBitIndex < 8; uBitIndex++ ) + { + cCheckBit = cMask & *(pControls); + + AppendTextBuffer(" D%02d = %d %s %s\r\n", + uBitIndex, + cCheckBit ? 1 : 0, + cCheckBit ? "yes - " : " no - ", + GetStringFromList(slOutputHeaderControls, + sizeof(slOutputHeaderControls) / sizeof(STRINGLIST), + cMask, + "Invalid control value")); + + cMask = cMask << 1; + } + } + } // for ( pData++ ; uFormatIndex <= VidOutHeaderDesc->bNumFormats; uFormatIndex++ ) + } // if (VidOutHeaderDesc->bNumFormats) + } // if (UVC11 == g_chUVCversion) + + if (VidOutHeaderDesc->bLength != bLength) + { + //@@TestCase B12.1 (also in Descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + VidOutHeaderDesc->bLength, + sizeof(VIDEO_STREAMING_OUTPUT_HEADER)); + OOPS(); + } + + if (VidOutHeaderDesc->bNumFormats < 1) + { + //@@TestCase B12.2 (Descript.c Line 827) + //@@ERROR + //@@Descriptor Field - bNumFormats + //@@bNumFormats should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bNumFormats is valid + AppendTextBuffer("*!*ERROR: bNumFormats of %d is too small\r\n", + VidOutHeaderDesc->bNumFormats); + OOPS(); + } + + if (VidOutHeaderDesc->wTotalLength < VidOutHeaderDesc->bLength) + { + //@@TestCase B12.3 (Descript.c Line 832) + //@@ERROR + //@@Descriptor Field - wTotalLength + //@@wTotalLength should be greater than bLength + //@@Question: Should we calculate wTotalLength to verify the value is valid + AppendTextBuffer("*!*ERROR: wTotalLength of %d is small than the bLength of %d\r\n", + VidOutHeaderDesc->wTotalLength, + VidOutHeaderDesc->bLength); + OOPS(); + } + + if (VidOutHeaderDesc->bEndpointAddress < 1) + { + //@@TestCase B12.4 (Descript.c Line 837) + //@@ERROR + //@@Descriptor Field - bEndpointAddress + //@@bEndpointAddress should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bEndpointAddress is valid + AppendTextBuffer("*!*ERROR: bEndpointAddress of %d is too small\r\n", + VidOutHeaderDesc->bEndpointAddress); + OOPS(); + } + + if(!(USB_ENDPOINT_DIRECTION_OUT(VidOutHeaderDesc->bEndpointAddress))) { + //@@TestCase B12.5 + //@@ERROR + //@@Descriptor Field - bEndPointAddress + //@@The bEndPointAddress is set for the wrong direction + AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress needs to have the Direction OUT for this header\r\n"); + OOPS();} + + if (VidOutHeaderDesc->bTerminalLink < 1) + { + //@@TestCase B12.6 (Descript.c Line 842) + //@@ERROR + //@@Descriptor Field - bTerminalLink + //@@bTerminalLink should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bTerminalLink is valid + AppendTextBuffer("*!*ERROR: bTerminalLink of %d is too small\r\n", + VidOutHeaderDesc->bTerminalLink); + OOPS(); + } + + return TRUE; + +} + + +//***************************************************************************** +// +// DisplayStillImageFrame() +// +//***************************************************************************** + +BOOL +DisplayStillImageFrame ( + PVIDEO_STILL_IMAGE_FRAME StillFrameDesc + ) +{ + //@@DisplayStillImageFrame -Still Image Frame + VIDEO_STILL_IMAGE_RECT * pXY; + PUCHAR pbCurr = NULL; + UINT i = 0; + UINT uNumComp = 0; + UINT uSize = 0; + size_t bLength = 0; + + bLength = SizeOfVideoStillImageFrame(StillFrameDesc); + + AppendTextBuffer("\r\n ===>Still Image Frame Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", StillFrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", StillFrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", StillFrameDesc->bDescriptorSubtype); + AppendTextBuffer("bEndpointAddress: 0x%02X\r\n", StillFrameDesc->bEndpointAddress); + AppendTextBuffer("bNumImageSizePatterns: 0x%02X\r\n", + StillFrameDesc->bNumImageSizePatterns); + if (StillFrameDesc->bNumImageSizePatterns < 1) + { + //@@TestCase B13.1 (also Descript.c Line 886) + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bNumImageSizePatterns + //@@The bNumImageSizePatterns should be greater than 0 + //@@Question: Should we test to verify the non-zero value for bNumImageSizePatterns is valid + AppendTextBuffer("*!*ERROR: bNumImageSizePatterns must be non-zero\r\n"); + OOPS(); + } + + // point to first StillFrameDesc->dwStillImage structure + pXY = (VIDEO_STILL_IMAGE_RECT *) &StillFrameDesc->aStillRect[0]; + + for (i = 1; i <= StillFrameDesc->bNumImageSizePatterns; i++, pXY++) + { + AppendTextBuffer("wWidth[%d]: 0x%04X\r\n", + i, pXY->wWidth); + AppendTextBuffer("wHeight[%d]: 0x%04X\r\n", + i, pXY->wHeight); + } + // point to bNumCompressionPattern field (after variable count field dwStillImage) + pbCurr = (PUCHAR) pXY; + // get number of compression patterns + uNumComp = *pbCurr; + + AppendTextBuffer("bNumCompressionPattern: 0x%02X\r\n", *pbCurr++); + for (i = 1; i <= uNumComp; i++) + { + AppendTextBuffer("bCompression[%d]: 0x%02X\r\n", + i, *pbCurr++); + } + + switch(StillMethod) { + case 0: + //@@TestCase B13.2 + //@@ERROR + //@@Descriptor Field - Still Image Frame Type Descriptor + //@@An still method type has been defined that shouldn't use a Still Image Frame + AppendTextBuffer("*!*ERROR: VS Video Input Header set to "\ + "No Still Method support\r\n"); + OOPS(); + case 1: + //@@TestCase B13.3 + //@@ERROR + //@@Descriptor Field - Still Image Frame Type Descriptor + //@@An still method type has been defined that shouldn't use a Still Image Frame + AppendTextBuffer("*!*ERROR: VS Video Input Header set to "\ + "Still Method One support with a Still Image Frame descriptor\r\n"); + OOPS(); + default: + break;} + + if (StillFrameDesc->bLength != bLength) + { + //@@TestCase B13.4 (Also in descript.c) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is incorrect + AppendTextBuffer("*!*ERROR: bLength 0x%02X incorrect, should be 0x%02X\r\n", + StillFrameDesc->bLength, uSize); + OOPS(); + } + + //@@TestCase B13.5 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bEndpointAddress + //@@Should test to verify endpoint validity + // AppendTextBuffer("bEndpointAddress: 0x%02X", StillFrameDesc->bEndpointAddress); + + if(USB_ENDPOINT_DIRECTION_IN(StillFrameDesc->bEndpointAddress) && StillMethod==3){ + if((StillFrameDesc->bEndpointAddress) == 0){ + //@@TestCase B13.6 + //@@ERROR + //@@Descriptor Field - bEndPointAddress + //@@bEndPointAddress should be non-zero for 0 when using StillMethod 3 + AppendTextBuffer("\r\n*!*ERROR: bEndpointAddress is reported as %d. "\ + "This should be non-zero when using StillMethod 3.\r\n", + (StillFrameDesc->bEndpointAddress)); + OOPS(); } + if (gDoAnnotation) + { + AppendTextBuffer(" -> Direction: IN - EndpointID: %d", + (StillFrameDesc->bEndpointAddress & 0x0F)); + } + AppendTextBuffer("\r\n"); + } + else if(USB_ENDPOINT_DIRECTION_OUT(StillFrameDesc->bEndpointAddress) && StillMethod==2) { + if((StillFrameDesc->bEndpointAddress & 0x0F) != 0) { + //@@TestCase B13.7 + //@@ERROR + //@@Descriptor Field - bEndPointAddress + //@@The EndpointID of bEndPointAddress should be set for 0 when using StillMethod 2 + AppendTextBuffer("\r\n*!*ERROR: The EndpointID of the "\ + "bEndpointAddress is reported as %d. This should be 0.\r\n", + (StillFrameDesc->bEndpointAddress & 0x0F)); + OOPS(); } + else {AppendTextBuffer("\r\n");}} + else if (StillFrameDesc->bEndpointAddress != 0) { + //@@TestCase B13.8 + //@@ERROR + //@@Descriptor Field - bEndPointAddress + //@@The bEndPointAddress should be set for 0 when not using StillMethod 2 or 3 + AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress should be 0.\r\n"); + OOPS(); } + else {AppendTextBuffer("\r\n");} + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayColorMatching() +// +//***************************************************************************** + +BOOL +DisplayColorMatching ( + PVIDEO_COLORFORMAT ColorMatchDesc + ) +{ + //@@DisplayColorMatching -Color Matching + + AppendTextBuffer("\r\n ===>Color Matching Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", ColorMatchDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", ColorMatchDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", ColorMatchDesc->bDescriptorSubtype); + AppendTextBuffer("bColorPrimaries: 0x%02X\r\n", ColorMatchDesc->bColorPrimaries); + AppendTextBuffer("bTransferCharacteristics: 0x%02X\r\n", ColorMatchDesc->bTransferCharacteristics); + AppendTextBuffer("bMatrixCoefficients: 0x%02X\r\n", ColorMatchDesc->bMatrixCoefficients); + + if (ColorMatchDesc->bLength != sizeof(VIDEO_COLORFORMAT)) + { + //@@TestCase B14.1 (Descript.c Line 1596) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + ColorMatchDesc->bLength, + sizeof(VIDEO_COLORFORMAT)); + OOPS(); + } + + //@@TestCase B14.2 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bColorPrimaries + //@@Question - Should we test to verify bColorPrimaries + // AppendTextBuffer("bColorPrimaries: 0x%02X\r\n", ColorMatchDesc->bColorPrimaries); + + //@@TestCase B14.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bTransferCharacteristics + //@@Question - Should we test to verify bTransferCharacteristics + // AppendTextBuffer("bTransferCharacteristics: 0x%02X\r\n", ColorMatchDesc->bTransferCharacteristics); + + //@@TestCase B14.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bMatrixCoefficients + //@@Question - Should we test to verify bMatrixCoefficients + // AppendTextBuffer("bMatrixCoefficients: 0x%02X\r\n", ColorMatchDesc->bMatrixCoefficients); + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayUncompressedFormat() +// +//***************************************************************************** + +BOOL +DisplayUncompressedFormat ( + PVIDEO_FORMAT_UNCOMPRESSED UnCompFormatDesc + ) +{ + //@@DisplayUncompressedFormat - Uncompressed Format + int i = 0; + PCHAR pStr = NULL; + OLECHAR szGUID[256]; + + // Initialize the default Frame + g_chUNCFrameDefault = UnCompFormatDesc->bDefaultFrameIndex; + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) &UnCompFormatDesc->guidFormat, (LPOLESTR) szGUID, 255); + i++; + + AppendTextBuffer("\r\n ===>Video Streaming Uncompressed Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", UnCompFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", UnCompFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", UnCompFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", UnCompFormatDesc->bFormatIndex); + AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", UnCompFormatDesc->bNumFrameDescriptors); + AppendTextBuffer("guidFormat: %S", szGUID); + + pStr = VidFormatGUIDCodeToName((REFGUID) &UnCompFormatDesc->guidFormat); + if ( pStr ) + { + if ( gDoAnnotation ) + { + AppendTextBuffer(" = %s Format", pStr); + } + } + AppendTextBuffer("\r\n"); + AppendTextBuffer("bBitsPerPixel: 0x%02X\r\n", UnCompFormatDesc->bBitsPerPixel); + AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", UnCompFormatDesc->bDefaultFrameIndex); + + if (UnCompFormatDesc->bLength != sizeof(VIDEO_FORMAT_UNCOMPRESSED)) + { + //@@TestCase B15.1 (descript.c line 925) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required + //@@length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + UnCompFormatDesc->bLength, + sizeof(VIDEO_FORMAT_UNCOMPRESSED)); + OOPS(); + } + + if (UnCompFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B15.2 (descript.c line 930) + //@@ERROR + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + if (UnCompFormatDesc->bNumFrameDescriptors == 0 ) + { + //@@TestCase B15.3 (descript.c line 930) + //@@ERROR + //@@Descriptor Field - bNumFrameDescriptors + //@@bNumFrameDescriptors is set to zero which is not in accordance with the + //@@USB Video Device Specification + AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, must have at least 1 Frame descriptor\r\n"); + OOPS(); + } + + if(!(pStr)) + { + //@@TestCase B15.4 + //@@WARNING + //@@Descriptor Field - guidFormat + //@@guidFormat is set to unknown or undefined format + AppendTextBuffer("\r\n*!*WARNING: guidFormat is an unknown format\r\n"); + OOPS(); + } + + if (UnCompFormatDesc->bBitsPerPixel == 0 ) + { + //@@TestCase B15.5 (descript.c line 940) + //@@ERROR + //@@Descriptor Field - bBitsPerPixel + //@@bBitsPerPixel is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bBitsPerPixel = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (UnCompFormatDesc->bDefaultFrameIndex == 0 || UnCompFormatDesc->bDefaultFrameIndex > + UnCompFormatDesc->bNumFrameDescriptors) + { + //@@TestCase B15.6 (desctipt.c line 945) + //@@ERROR + //@@Descriptor Field - bDefaultFrameIndex + //@@The value for bDefaultFrameIndex is not greater than 0 or less than or equal to bNumFrameDescriptors + AppendTextBuffer("*!*ERROR: The value %d for the bDefaultFrameIndex is out of range, this invalidates the descriptor\r\n*!*The proper range is 1 to %d)", + UnCompFormatDesc->bDefaultFrameIndex, + UnCompFormatDesc->bNumFrameDescriptors); + OOPS(); + } + + AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", + UnCompFormatDesc->bAspectRatioX); + AppendTextBuffer("bAspectRatioY: 0x%02X", + UnCompFormatDesc->bAspectRatioY); + + if (((UnCompFormatDesc->bmInterlaceFlags & 0x01) && + (UnCompFormatDesc->bAspectRatioY != 0 && + UnCompFormatDesc->bAspectRatioX != 0))) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", + (UnCompFormatDesc->bAspectRatioX),(UnCompFormatDesc->bAspectRatioY)); + } + else + { + if (UnCompFormatDesc->bAspectRatioY != 0 || UnCompFormatDesc->bAspectRatioX != 0) + { + //@@TestCase B15.7 + //@@ERROR + //@@Descriptor Field - bAspectRatioX, bAspectRatioY + //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero + //@@ if stream is non-interlaced + AppendTextBuffer("\r\n*!*ERROR: Both bAspectRatioX and bAspectRatioY "\ + "must equal 0 if stream is non-interlaced"); + OOPS(); + } + } + } + AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", + UnCompFormatDesc->bmInterlaceFlags); + + if (gDoAnnotation) + { + AppendTextBuffer(" D0 = 0x%02X Interlaced stream or variable: %s\r\n", + (UnCompFormatDesc->bmInterlaceFlags & 1), + (UnCompFormatDesc->bmInterlaceFlags & 1) ? "Yes" : "No"); + AppendTextBuffer(" D1 = 0x%02X Fields per frame: %s\r\n", + ((UnCompFormatDesc->bmInterlaceFlags >> 1) & 1), + ((UnCompFormatDesc->bmInterlaceFlags >> 1) & 1) ? "1 field" : "2 fields"); + AppendTextBuffer(" D2 = 0x%02X Field 1 first: %s\r\n", + ((UnCompFormatDesc->bmInterlaceFlags >> 2) & 1), + ((UnCompFormatDesc->bmInterlaceFlags >> 2) & 1) ? "Yes" : "No"); + //@@TestCase B15.9 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmInterlaceFlags + //@@Validate that reserved bits (D3) are set to zero. + AppendTextBuffer(" D3 = 0x%02X Reserved%s\r\n", + ((UnCompFormatDesc->bmInterlaceFlags >> 3) & 1), + ((UnCompFormatDesc->bmInterlaceFlags >> 3) & 1) ? + "\r\n*!*ERROR: Reserved to 0" : "" ); + AppendTextBuffer(" D4..5 = 0x%02X Field patterns ->", + ((UnCompFormatDesc->bmInterlaceFlags >> 4) & 3)); + switch(UnCompFormatDesc->bmInterlaceFlags & 0x30) + { + case 0x00: + AppendTextBuffer(" Field 1 only"); + break; + case 0x10: + AppendTextBuffer(" Field 2 only"); + break; + case 0x20: + AppendTextBuffer(" Regular Pattern of fields 1 and 2"); + break; + case 0x30: + AppendTextBuffer(" Random Pattern of fields 1 and 2"); + break; + } + AppendTextBuffer("\r\n D6..7 = 0x%02X Display Mode ->", + ((UnCompFormatDesc->bmInterlaceFlags >> 6) & 3)); + + switch(UnCompFormatDesc->bmInterlaceFlags & 0xC0) + { + case 0x00: + AppendTextBuffer(" Bob only"); + break; + case 0x40: + AppendTextBuffer(" Weave only"); + break; + case 0x80: + AppendTextBuffer(" Bob or weave"); + break; + case 0xC0: + //@@TestCase B15.10 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - bmInterlaceFlags + //@@Question - Should we validate that reserved bits are set to zero? + AppendTextBuffer(" Reserved"); + break; + } + } + + //@@TestCase B15.11 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bCopyProtect + //@@Question - Are their reserved bits and should we validate that + //@@ reserved bits are set to zero? + AppendTextBuffer("\r\nbCopyProtect: 0x%02X", + UnCompFormatDesc->bCopyProtect); + if (gDoAnnotation) + { + if (UnCompFormatDesc->bCopyProtect) + AppendTextBuffer(" -> Duplication Restricted"); + else + AppendTextBuffer(" -> Duplication Unrestricted"); + } + AppendTextBuffer("\r\n"); + + //@@TestCase B15.12 + //@@We should check to make sure that a Color Matching Descriptor is included in the device + // Check that the correct number of Frame Descriptors and one Color Matching + // descriptor follow + CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) UnCompFormatDesc, + UnCompFormatDesc->bNumFrameDescriptors, VS_FRAME_UNCOMPRESSED); + + return TRUE; + } + + +//***************************************************************************** +// +// DisplayUncompressedFrameType() +// +//***************************************************************************** + +BOOL +DisplayUncompressedFrameType ( + PVIDEO_FRAME_UNCOMPRESSED UnCompFrameDesc + ) +{ + size_t bLength = 0; + bLength = SizeOfVideoFrameUncompressed(UnCompFrameDesc); + + //@@DisplayUncompressedFrameType -Uncompressed Frame + + AppendTextBuffer("\r\n ===>Video Streaming Uncompressed Frame Type Descriptor<===\r\n"); + if (gDoAnnotation) + { + if(UnCompFrameDesc->bFrameIndex == g_chUNCFrameDefault) + { + AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); + } + } + AppendTextBuffer("bLength: 0x%02X\r\n", UnCompFrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", UnCompFrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", UnCompFrameDesc->bDescriptorSubtype); + AppendTextBuffer("bFrameIndex: 0x%02X\r\n", UnCompFrameDesc->bFrameIndex); + AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); + AppendTextBuffer("wWidth: 0x%04X = %d\r\n", UnCompFrameDesc->wWidth, UnCompFrameDesc->wWidth); + AppendTextBuffer("wHeight: 0x%04X = %d\r\n", UnCompFrameDesc->wHeight, UnCompFrameDesc->wHeight); + AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", UnCompFrameDesc->dwMinBitRate); + AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", UnCompFrameDesc->dwMaxBitRate); + AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", UnCompFrameDesc->dwMaxVideoFrameBufferSize); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + UnCompFrameDesc->dwDefaultFrameInterval, + ((double)UnCompFrameDesc->dwDefaultFrameInterval)/10000.0, + (10000000.0/((double)UnCompFrameDesc->dwDefaultFrameInterval)) + ); + AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", UnCompFrameDesc->bFrameIntervalType); + + if (UnCompFrameDesc->bLength != bLength) + { + //@@TestCase B15.1 (descript.c line 925) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required + //@@length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + UnCompFrameDesc->bLength, bLength); + OOPS(); + } + + if (UnCompFrameDesc->bFrameIndex == 0 ) + { + //@@TestCase B16.2 (descript.c line 991) + //@@ERROR + //@@Descriptor Field - bFrameIndex + //@@bFrameIndex must be nonzero + AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + //@@TestCase B16.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmCapabilities + //@@Question: Should we try to verify that bmCapabilities is valid? + // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); + + if (UnCompFrameDesc->wWidth == 0 ) + { + //@@TestCase B16.4 (descript.c line 996) + //@@ERROR + //@@Descriptor Field - wWidth + //@@wWidth must be nonzero + AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); + OOPS(); + } + + if (UnCompFrameDesc->wHeight == 0 ) + { + //@@TestCase B16.5 (descript.c line 1001) + //@@ERROR + //@@Descriptor Field - wHeight + //@@wHeight must be nonzero + AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); + OOPS(); + } + + if (UnCompFrameDesc->dwMinBitRate == 0 ) + { + //@@TestCase B16.6 (descript.c line 1006) + //@@ERROR + //@@Descriptor Field - dwMinBitRate + //@@dwMinBitRate must be nonzero + AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); + OOPS(); + } + + if (UnCompFrameDesc->dwMaxBitRate == 0 ) + { + //@@TestCase B16.7 (descript.c line 1011) + //@@ERROR + //@@Descriptor Field - dwMaxBitRate + //@@dwMaxBitRate must be nonzero + AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); + OOPS(); + } + + if(UnCompFrameDesc->dwMinBitRate > UnCompFrameDesc->dwMaxBitRate) + { + //@@TestCase B16.8 + //@@ERROR + //@@Descriptor Field - dwMinBitRate and dwMaxBitRate + //@@Verify that dwMaxBitRate is greater than dwMinBitRate + AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); + OOPS(); + } + else + { + if (UnCompFrameDesc->bFrameIntervalType == 1 && + UnCompFrameDesc->dwMinBitRate != UnCompFrameDesc->dwMaxBitRate) + { + //@@TestCase B16.9 + //@@WARNING + //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate + //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 + AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ + "should equal dwMaxBitRate\r\n"); + OOPS(); + } + } + + if (UnCompFrameDesc->dwMaxVideoFrameBufferSize == 0 ) + { + //@@TestCase B16.10 (descript.c line 1015) + //@@WARNING + //@@Descriptor Field - bFrameIndex + //@@bFrameIndex must be nonzero + AppendTextBuffer("*!*WARNING: dwMaxVideoFrameBufferSize must be nonzero\r\n"); + OOPS(); + } + + if (UnCompFrameDesc->dwDefaultFrameInterval == 0 ) + { + //@@TestCase B16.11 (descript.c line 1020) + //@@WARNING + //@@Descriptor Field - dwDefaultFrameInterval + //@@dwDefaultFrameInterval must be nonzero + AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); + OOPS(); + } + if (0 == UnCompFrameDesc->bFrameIntervalType) + { + DisplayUnComContinuousFrameType(UnCompFrameDesc); + } + else + { + DisplayUnComDiscreteFrameType(UnCompFrameDesc); + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayUnComContinuousFrameType() +// +//***************************************************************************** + +BOOL +DisplayUnComContinuousFrameType( + PVIDEO_FRAME_UNCOMPRESSED UContinuousDesc + ) +{ + //@@DisplayUnComContinuousFrameType -Uncompressed Continuous Frame + ULONG dwMinFrameInterval = UContinuousDesc->adwFrameInterval[0]; + ULONG dwMaxFrameInterval = UContinuousDesc->adwFrameInterval[1]; + ULONG dwFrameIntervalStep = UContinuousDesc->adwFrameInterval[2]; + + AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + + AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMinFrameInterval, + ((double)dwMinFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); + + AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMaxFrameInterval, + ((double)dwMaxFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); + + AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); + + if (dwMinFrameInterval == 0 ) + { + //@@TestCase B17.2 (descript.c line 1025) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval + //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (dwMaxFrameInterval == 0 ) + { + //@@TestCase B17.3 (descript.c line 1025) + //@@ERROR + //@@Descriptor Field - dwMaxFrameInterval + //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(dwMinFrameInterval > dwMaxFrameInterval) + { + //@@TestCase B17.4 (descript.c 1043) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval + AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); + OOPS(); + } + else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) + { + //@@TestCase B17.5 + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) + { + //@@TestCase B17.6 + //@@CAUTION + //@@Descriptor Field - dwFrameIntervalStep + //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero + AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) + { + //@@TestCase B17.7 (descript.c 1052) + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); + OOPS(); + } + + if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) + { + //@@TestCase B17.8 (descript.c line 1032) + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval + AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between dwMinFrameInterval and dwMaxFrameInterval\r\n"); + OOPS(); + } + + return TRUE; +} + +//***************************************************************************** +// +// DisplayUnComDiscreteFrameType() +// +//***************************************************************************** + +BOOL +DisplayUnComDiscreteFrameType( + PVIDEO_FRAME_UNCOMPRESSED UDiscreteDesc + ) +{ + //@@DisplayUnComDiscreteFrameType -Uncompressed Discrete Frame + UINT iNdex = 1; + UINT iCurFrame = 0; + ULONG * ulFrameInterval = NULL; + + AppendTextBuffer("===>Additional Discrete Frame Type Data\r\n"); + + // There are (UDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) + for (; iNdex <= UDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) + { + ulFrameInterval = &UDiscreteDesc->adwFrameInterval[iCurFrame]; + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + iNdex, *ulFrameInterval, + ((double)*ulFrameInterval)/10000.0, + (10000000.0/((double)*ulFrameInterval)) + ); + if (0 == *ulFrameInterval) + { + //@@TestCase B18.1 (descript.c line 1061) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[x] must be non-zero + AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); + OOPS(); + } + if ((iNdex > 1)&&(*ulFrameInterval <= UDiscreteDesc->adwFrameInterval[iCurFrame - 1])) + { + //@@TestCase B18.2 (descript.c line 1067) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] + AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ + "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); + OOPS(); + } + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayMJPEGFormat() +// +//***************************************************************************** + +BOOL +DisplayMJPEGFormat ( + PVIDEO_FORMAT_MJPEG MJPEGFormatDesc + ) +{ + //@@DisplayMJPEGFormat - MJPEG Format + // Initialize the default Frame + g_chMJPEGFrameDefault = MJPEGFormatDesc->bDefaultFrameIndex; + + AppendTextBuffer("\r\n ===>Video Streaming MJPEG Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", MJPEGFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MJPEGFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MJPEGFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MJPEGFormatDesc->bFormatIndex); + AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", MJPEGFormatDesc->bNumFrameDescriptors); + + if (MJPEGFormatDesc->bLength != sizeof(VIDEO_FORMAT_MJPEG)) + { + //@@TestCase B19.1 (descript.c line 1098) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the + //@@ required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + MJPEGFormatDesc->bLength, + sizeof(VIDEO_FORMAT_MJPEG)); + OOPS(); + } + + if (MJPEGFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B19.2 (descript.c line 1103) + //@@ERROR + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with + //@@ the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bFormatIndex must be non-zero\r\n"); + OOPS(); + } + + if (MJPEGFormatDesc->bNumFrameDescriptors == 0 ) + { + //@@TestCase B19.3 (descript.c line 1108) + //@@ERROR + //@@Descriptor Field - bNumFrameDescriptors + //@@bNumFrameDescriptors is set to zero which is not in accordance + //@@ with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bNumFrameDescriptors must be non-zero\r\n"); + OOPS(); + } + + AppendTextBuffer("bmFlags: 0x%02X", + (MJPEGFormatDesc->bmFlags & 0x01)); + + //@@TestCase B19.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmFlags + //@@We should validate that reserved bits are set to zero. + if (gDoAnnotation) + { + if(MJPEGFormatDesc->bmFlags & 0x01) + { + AppendTextBuffer(" -> Sample Size is Fixed"); + } + else + { + AppendTextBuffer(" -> Sample Size is Not Fixed"); + } + } + AppendTextBuffer("\r\nbDefaultFrameIndex: 0x%02X\r\n", + MJPEGFormatDesc->bDefaultFrameIndex); + + if (MJPEGFormatDesc->bDefaultFrameIndex == 0 || + MJPEGFormatDesc->bDefaultFrameIndex > + MJPEGFormatDesc->bNumFrameDescriptors) + { + //@@TestCase B19.5 (descript.c line 1113) + //@@ERROR + //@@Descriptor Field - bDefaultFrameIndex + //@@bDefaultFrameIndex is not in the domain of constrained by + //@@ bNumFrameDescriptors + AppendTextBuffer("*!*ERROR: bDefaultFrameIndex 0x%02X invalid, should "\ + "be between 1 and 0x%02x/r/n", + MJPEGFormatDesc->bDefaultFrameIndex, + MJPEGFormatDesc->bNumFrameDescriptors); + OOPS(); + } + + AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", + MJPEGFormatDesc->bAspectRatioX); + AppendTextBuffer("bAspectRatioY: 0x%02X", + MJPEGFormatDesc->bAspectRatioY); + + if(((MJPEGFormatDesc->bmInterlaceFlags & 0x01) && + ((MJPEGFormatDesc->bAspectRatioY != 0) && + (MJPEGFormatDesc->bAspectRatioX != 0)))) + { + if (gDoAnnotation) + { + AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", + (MJPEGFormatDesc->bAspectRatioX), (MJPEGFormatDesc->bAspectRatioY)); + } + } + else + { + if (MJPEGFormatDesc->bAspectRatioY != 0 || MJPEGFormatDesc->bAspectRatioX != 0) + { + //@@TestCase B19.6 + //@@ERROR + //@@Descriptor Field - bAspectRatioX and bAspectRatioY + //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero + //@@ if stream is non-interlaced + AppendTextBuffer("\r\n*!*ERROR: bAspectRatioX and bAspectRatioY must "\ + "be 0 if stream non-Interlaced"); + OOPS(); + } + } + AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", + MJPEGFormatDesc->bmInterlaceFlags); + + if (gDoAnnotation) + { + AppendTextBuffer(" D00 = %x %sInterlaced stream or variable\r\n", + (MJPEGFormatDesc->bmInterlaceFlags & 1), + (MJPEGFormatDesc->bmInterlaceFlags & 1) ? "" : " non-"); + AppendTextBuffer(" D01 = %x %s per frame\r\n", + ((MJPEGFormatDesc->bmInterlaceFlags >> 1) & 1), + ((MJPEGFormatDesc->bmInterlaceFlags >> 1) & 1) ? " 1 field" : " 2 fields"); + AppendTextBuffer(" D02 = %x Field 1 %sfirst\r\n", + ((MJPEGFormatDesc->bmInterlaceFlags >> 2) & 1), + ((MJPEGFormatDesc->bmInterlaceFlags >> 2) & 1) ? "" : "not "); + //@@TestCase B19.7 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmInterlaceFlags + //@@Validate that reserved bits (D3) are set to zero. + AppendTextBuffer(" D03 = %x Reserved%s\r\n", + ((MJPEGFormatDesc->bmInterlaceFlags >> 3) & 1), + ((MJPEGFormatDesc->bmInterlaceFlags >> 3) & 1) ? + "\r\n*!*ERROR: non zero" : "" ); + AppendTextBuffer(" D4..5 = %x Field patterns ->", + ((MJPEGFormatDesc->bmInterlaceFlags >> 4) & 3)); + switch (MJPEGFormatDesc->bmInterlaceFlags & 0x30) + { + case 0x00: + AppendTextBuffer(" Field 1 only"); + break; + case 0x10: + AppendTextBuffer(" Field 2 only"); + break; + case 0x20: + AppendTextBuffer(" Regular Pattern of fields 1 and 2"); + break; + case 0x30: + AppendTextBuffer(" Random Pattern of fields 1 and 2"); + break; + } + AppendTextBuffer("\r\n D6..7 = %x Display Mode ->", + ((MJPEGFormatDesc->bmInterlaceFlags >> 6) & 3)); + switch(MJPEGFormatDesc->bmInterlaceFlags & 0xC0) + { + case 0x00: + AppendTextBuffer(" Bob only"); + break; + case 0x40: + AppendTextBuffer(" Weave only"); + break; + case 0x80: + AppendTextBuffer(" Bob or weave"); + break; + case 0xC0: + //@@TestCase B19.8 + //@@Not yet implemented - Priority 3 + //@@Descriptor Field - bmInterlaceFlags + //@@Question - Should we validate that reserved bits are set to zero? + AppendTextBuffer(" Reserved"); + break; + } + } + + //@@TestCase B19.9 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bCopyProtect + //@@Question - Are their reserved bits and should we validate that + //@@ reserved bits are set to zero? + AppendTextBuffer("\r\nbCopyProtect: 0x%02X", + MJPEGFormatDesc->bCopyProtect); + if (gDoAnnotation) + { + if (MJPEGFormatDesc->bCopyProtect) + AppendTextBuffer(" -> Duplication Restricted"); + else + AppendTextBuffer(" -> Duplication Unrestricted"); + } + AppendTextBuffer("\r\n"); + + // Check that the correct number of Frame Descriptors and one Color Matching + // descriptor follow + CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) MJPEGFormatDesc, + MJPEGFormatDesc->bNumFrameDescriptors, VS_FRAME_MJPEG); + + return TRUE; +} + +//***************************************************************************** +// +// DisplayMJPEGFrameType() +// +//***************************************************************************** + +BOOL +DisplayMJPEGFrameType ( + PVIDEO_FRAME_MJPEG MJPEGFrameDesc + ) +{ + //@@DisplayMJPEGFrameType -MJPEG Frame + size_t bLength = 0; + bLength = SizeOfVideoFrameMjpeg(MJPEGFrameDesc); + + AppendTextBuffer("\r\n ===>Video Streaming MJPEG Frame Type Descriptor<===\r\n"); + if (gDoAnnotation) + { + if(MJPEGFrameDesc->bFrameIndex == g_chMJPEGFrameDefault) + { + AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); + } + } + AppendTextBuffer("bLength: 0x%02X\r\n", MJPEGFrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MJPEGFrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MJPEGFrameDesc->bDescriptorSubtype); + AppendTextBuffer("bFrameIndex: 0x%02X\r\n", MJPEGFrameDesc->bFrameIndex); + AppendTextBuffer("bmCapabilities: 0x%02X\r\n", MJPEGFrameDesc->bmCapabilities); + AppendTextBuffer("wWidth: 0x%04X = %d\r\n", MJPEGFrameDesc->wWidth, MJPEGFrameDesc->wWidth); + AppendTextBuffer("wHeight: 0x%04X = %d\r\n", MJPEGFrameDesc->wHeight, MJPEGFrameDesc->wHeight); + AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", MJPEGFrameDesc->dwMinBitRate); + AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", MJPEGFrameDesc->dwMaxBitRate); + AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", MJPEGFrameDesc->dwMaxVideoFrameBufferSize); + + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + MJPEGFrameDesc->dwDefaultFrameInterval, + ((double)MJPEGFrameDesc->dwDefaultFrameInterval)/10000.0, + (10000000.0/((double)MJPEGFrameDesc->dwDefaultFrameInterval)) + ); + AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", MJPEGFrameDesc->bFrameIntervalType); + + if (MJPEGFrameDesc->bLength != bLength) + { + //@@TestCase B20.1 (descript.c line 1154) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is less than required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d is incorrect, should be %d\r\n", + MJPEGFrameDesc->bLength, bLength); + OOPS(); + } + + if (MJPEGFrameDesc->bFrameIndex == 0 ) + { + //@@TestCase B20.2 (descript.c line 1159) + //@@WARNING + //@@Descriptor Field - bFrameIndex + //@@bFrameIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFrameIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + //@@TestCase B20.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bmCapabilities + //@@Question: Should we try to verify that bmCapabilities is valid? + // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", MJPEGFrameDesc->bmCapabilities); + + if (MJPEGFrameDesc->wWidth == 0 ) + { + //@@TestCase B20.4 (descript.c line 1164) + //@@ERROR + //@@Descriptor Field - wWidth + //@@wWidth is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: wWidth = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (MJPEGFrameDesc->wHeight == 0 ) + { + //@@TestCase B20.5 (descript.c line 1169) + //@@ERROR + //@@Descriptor Field - wHeight + //@@wHeight is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: wHeight = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (MJPEGFrameDesc->dwMinBitRate == 0 ) + { + //@@TestCase B20.6 (descript.c line 1174) + //@@ERROR + //@@Descriptor Field - dwMinBitRate + //@@dwMinBitRate is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinBitRate = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (MJPEGFrameDesc->dwMaxBitRate == 0 ) + { + //@@TestCase B20.7 (descript.c line 1179) + //@@ERROR + //@@Descriptor Field - dwMaxBitRate + //@@dwMaxBitRate is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxBitRate = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(MJPEGFrameDesc->dwMinBitRate > MJPEGFrameDesc->dwMaxBitRate) + { + //@@TestCase B20.8 + //@@ERROR + //@@Descriptor Field - dwMinBitRate and dwMaxBitRate + //@@Verify that dwMaxBitRate is greater than dwMinBitRate + AppendTextBuffer("*!*ERROR: dwMinBitRate > dwMaxBitRate, this invalidates the descriptor\r\n"); + OOPS(); + } + else if(MJPEGFrameDesc->bFrameIntervalType == 1 && MJPEGFrameDesc->dwMinBitRate != MJPEGFrameDesc->dwMaxBitRate) + { + //@@TestCase B20.9 + //@@WARNING + //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate + //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 + AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate should equal dwMaxBitRate\r\n"); + OOPS(); + } + + if (MJPEGFrameDesc->dwMaxVideoFrameBufferSize == 0 ) + { + //@@TestCase B20.10 (descript.c line 1183) + //@@ERROR + //@@Descriptor Field - dwMaxVideoFrameBufferSize + //@@dwMaxVideoFrameBufferSize is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxVideoFrameBufferSize = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (MJPEGFrameDesc->dwMaxVideoFrameBufferSize == 0 ) + { + //@@TestCase B20.11 (descript.c line 1188) + //@@ERROR + //@@Descriptor Field - dwDefaultFrameInterval + //@@dwDefaultFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwDefaultFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (0 == MJPEGFrameDesc->bFrameIntervalType) + { + DisplayMJPEGContinuousFrameType(MJPEGFrameDesc); + } + else + { + DisplayMJPEGDiscreteFrameType(MJPEGFrameDesc); + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayMJPEGContinuousFrameType() +// +//***************************************************************************** + +BOOL +DisplayMJPEGContinuousFrameType( + PVIDEO_FRAME_MJPEG MContinuousDesc + ) +{ + //@@DisplayMJPEGContinuousFrameType - MJPEG Continuous Frame + ULONG dwMinFrameInterval = MContinuousDesc->adwFrameInterval[0]; + ULONG dwMaxFrameInterval = MContinuousDesc->adwFrameInterval[1]; + ULONG dwFrameIntervalStep = MContinuousDesc->adwFrameInterval[2]; + + AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + + AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMinFrameInterval, + ((double)dwMinFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); + + AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMaxFrameInterval, + ((double)dwMaxFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); + + AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); + + if (dwMinFrameInterval == 0 ) + { + //@@TestCase B21.2 (descript.c line 1188) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval + //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (dwMaxFrameInterval == 0 ) + { + //@@TestCase B21.3 (descript.c line 1188) + //@@ERROR + //@@Descriptor Field - dwMaxFrameInterval + //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(dwMinFrameInterval > dwMaxFrameInterval) + { + //@@TestCase B21.4 (descript.c line 1211) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval + AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); + OOPS(); + } + else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) + { + //@@TestCase B21.5 + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) + { + //@@TestCase B21.6 + //@@CAUTION + //@@Descriptor Field - dwFrameIntervalStep + //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero + AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) + { + //@@TestCase B21.7 (descript.c line 1220) + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); + OOPS(); + } + + if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) + { + //@@TestCase B21.8 (descript.c line 1200) + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval + AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between \r\n *!*dwMinFrameInterval and dwMaxFrameInterval\r\n"); + OOPS(); + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayMJPEGDiscreteFrameType() +// +//***************************************************************************** + +BOOL +DisplayMJPEGDiscreteFrameType( + PVIDEO_FRAME_MJPEG MDiscreteDesc + ) +{ + //@@DisplayMJPEGDiscreteFrameType -MJPEG Discrete Frame + UINT iNdex = 1; + UINT iCurFrame = 0; + ULONG * ulFrameInterval = NULL; + + AppendTextBuffer("===>Additional Discrete Frame TypeData\r\n"); + + // There are (MDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) + for (; iNdex <= MDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) + { + ulFrameInterval = &MDiscreteDesc->adwFrameInterval[iCurFrame]; + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + iNdex, *ulFrameInterval, + ((double)*ulFrameInterval)/10000.0, + (10000000.0/((double)*ulFrameInterval)) + ); + if (0 == *ulFrameInterval) + { + //@@TestCase B22.1 (descript.c line 1229) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[x] must be non-zero + AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); + OOPS(); + } + if ((iNdex > 1)&&(*ulFrameInterval <= MDiscreteDesc->adwFrameInterval[iCurFrame - 1])) + { + //@@TestCase B22.2 (descript.c line 1235) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] + AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ + "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); + OOPS(); + } + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayMPEG1SSFormat() +// +//***************************************************************************** + +BOOL +DisplayMPEG1SSFormat ( + PVIDEO_FORMAT_MPEG1SS MPEG1SSFormatDesc + ) +{ + //@@DisplayMPEG1SSFormat -MPEG1 SS Format + AppendTextBuffer("\r\n ===>Video Streaming MPEG1-SS Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", MPEG1SSFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG1SSFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG1SSFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG1SSFormatDesc->bFormatIndex); + AppendTextBuffer("wPacketLength: 0x%02X\r\n", MPEG1SSFormatDesc->bPacketLength); + AppendTextBuffer("wPackLength: 0x%02X\r\n", MPEG1SSFormatDesc->bPackLength); + AppendTextBuffer("bPackdataType: 0x%02X", (MPEG1SSFormatDesc->bPackDataType)); + if(gDoAnnotation) { + if(MPEG1SSFormatDesc->bPackDataType & 0x01){AppendTextBuffer(" -> Pack data size fixed\r\n");} + else {AppendTextBuffer(" -> Pack data size variable\r\n"); }} + else {AppendTextBuffer("\r\n");} + + + if (MPEG1SSFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG1SS)) + { + //@@TestCase B23.1 (descript.c line 1514) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", + MPEG1SSFormatDesc->bLength, + sizeof(VIDEO_FORMAT_MPEG1SS)); + OOPS(); + } + + if (MPEG1SSFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B23.2 (descript.c line 1519) + //@@WARNING + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + //@@TestCase B23.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bPackdataType + //@@Question - Should we validate that reserved bits are set to zero? + // AppendTextBuffer("bPackdataType: 0x%02X", (MPEG1SSFormatDesc->bPackdataType & 0x01)); + + // This descriptor is deprecated for UVC 1.1 +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); + } +#else + if (UVC11 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); + } +#endif + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayMPEG2PSFormat() +// +//***************************************************************************** + +BOOL +DisplayMPEG2PSFormat ( + PVIDEO_FORMAT_MPEG2PS MPEG2PSFormatDesc + ) +{ + //@@DisplayMPEG2PSFormat -MPEG2 PS Format + AppendTextBuffer("\r\n ===>Video Streaming MPEG2-PS Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", MPEG2PSFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG2PSFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG2PSFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG2PSFormatDesc->bFormatIndex); + AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG2PSFormatDesc->bPacketLength); + AppendTextBuffer("bPackLength: 0x%02X\r\n", MPEG2PSFormatDesc->bPackLength); + AppendTextBuffer("bPackDataType: 0x%02X", (MPEG2PSFormatDesc->bPackDataType)); + + if (MPEG2PSFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG2PS)) + { + //@@TestCase B24.1 (descript.c line 1542) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", + MPEG2PSFormatDesc->bLength, + sizeof(VIDEO_FORMAT_MPEG2PS)); + OOPS(); + AppendTextBuffer("*!*USBView will try to display the rest of the descriptor but results may not be accurate\r\n"); + } + + if (MPEG2PSFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B24.2 (descript.c line 1547) + //@@WARNING + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + //@@TestCase B24.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bPackdataType + //@@Question - Should we validate that reserved bits are set to zero? + // AppendTextBuffer("bPackdataType: 0x%02X", (MPEG2PSFormatDesc->bPackdataType & 0x01)); + + // This descriptor is deprecated for UVC 1.1 +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); + } +#else + if (UVC11 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); + } +#endif + + return TRUE; + +} + + +//***************************************************************************** +// +// DisplayMPEG2TSFormat() +// +//***************************************************************************** + +BOOL +DisplayMPEG2TSFormat ( + PVIDEO_FORMAT_MPEG2TS MPEG2TSFormatDesc + ) +{ + //@@DisplayMPEG2TSFormat -MPEG2 TS Format + UCHAR bLength = sizeof(VIDEO_FORMAT_MPEG2TS); + + AppendTextBuffer("\r\n ===>Video Streaming MPEG2-TS Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", MPEG2TSFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG2TSFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG2TSFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG2TSFormatDesc->bFormatIndex); + AppendTextBuffer("bDataOffset: 0x%02X\r\n", MPEG2TSFormatDesc->bDataOffset); + AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG2TSFormatDesc->bPacketLength); + AppendTextBuffer("bStrideLength: 0x%02X\r\n", MPEG2TSFormatDesc->bStrideLength); + +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) +#else + if (UVC11 == g_chUVCversion) +#endif + { + int i = 0; + PCHAR pStr = NULL; + OLECHAR szGUID[256]; + GUID * pStrideGuid = NULL; + + pStrideGuid = (GUID *) (&MPEG2TSFormatDesc->bStrideLength + 1); + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) pStrideGuid, (LPOLESTR) szGUID, 255); + i++; + AppendTextBuffer("guidStrideFormat: %S", szGUID); + pStr = VidFormatGUIDCodeToName((REFGUID) pStrideGuid); + if(gDoAnnotation) + { + if (pStr) + { + AppendTextBuffer(" = %s Format", pStr); + } + } + AppendTextBuffer("\r\n"); + bLength = sizeof(VIDEO_FORMAT_MPEG2TS) + sizeof(GUID); + } + + if (MPEG2TSFormatDesc->bLength != bLength) + { + //@@TestCase B25.1 (descript.c line 1486) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + MPEG2TSFormatDesc->bLength, + sizeof(VIDEO_FORMAT_MPEG2TS)); + OOPS(); + } + + if (MPEG2TSFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B25.2 (descript.c line 1491) + //@@WARNING + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + //@@TestCase B25.3 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bDataOffset, wPacket and wStride + //@@Question - Should we check that if bDataOffset is 0 that wPacket and wStride should equal each other + // AppendTextBuffer("bDataOffset: 0x%02X\r\n", MPEG2TSFormatDesc->bDataOffset); + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayMPEG4SLFormat() +// +//***************************************************************************** + +BOOL +DisplayMPEG4SLFormat ( + PVIDEO_FORMAT_MPEG4SL MPEG4SLFormatDesc + ) +{ + //@@DisplayMPEG4SLFormat -MPEG4 SL Format + + AppendTextBuffer("\r\n ===>Video Streaming MPEG4-SL Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", MPEG4SLFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG4SLFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG4SLFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG4SLFormatDesc->bFormatIndex); + AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG4SLFormatDesc->bPacketLength); + + if (MPEG4SLFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG4SL)) + { + //@@TestCase B26.1 (descript.c line 1568) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", + MPEG4SLFormatDesc->bLength, + sizeof(VIDEO_FORMAT_MPEG4SL)); + OOPS(); + } + + if (MPEG4SLFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B26.2 (descript.c line 1573) + //@@WARNING + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + // This descriptor is deprecated for UVC 1.1 +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); + } +#else + if (UVC11 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); + } +#endif + return TRUE; +} + + +//***************************************************************************** +// +// DisplayStreamPayload() +// +//***************************************************************************** + +BOOL +DisplayStreamPayload ( + PVIDEO_FORMAT_STREAM StreamPayloadDesc + ) +{ + //@@DisplayStreamPayload -Stream Based Payload Format + PCHAR pStr = NULL; + OLECHAR szGUID[256]; + int i = 0; + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) &StreamPayloadDesc->guidFormat, (LPOLESTR) szGUID, 255); + i++; + + AppendTextBuffer("\r\n ===>Video Streaming Stream Based Payload Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", StreamPayloadDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", StreamPayloadDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", StreamPayloadDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", StreamPayloadDesc->bFormatIndex); + AppendTextBuffer("guidFormat: %S", szGUID); + + pStr = VidFormatGUIDCodeToName((REFGUID) &StreamPayloadDesc->guidFormat); + if(gDoAnnotation) + { + if (pStr) + { + AppendTextBuffer(" = %s Format", pStr); + } + } + AppendTextBuffer("\r\n"); + AppendTextBuffer("dwPacketLength: 0x%02X\r\n", StreamPayloadDesc->dwPacketLength); + + if (StreamPayloadDesc->bLength != sizeof(VIDEO_FORMAT_STREAM)) + { + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + StreamPayloadDesc->bLength, + sizeof(PVIDEO_FORMAT_STREAM)); + OOPS(); + } + + if (StreamPayloadDesc->bFormatIndex == 0 ) + { + //@@WARNING + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + // This descriptor is new for UVC 1.1 + if (UVC10 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayDVFormat() +// +//***************************************************************************** + +BOOL +DisplayDVFormat ( + PVIDEO_FORMAT_DV DVFormatDesc + ) +{ + //@@DisplayDVFormat -Digital Video Format + + AppendTextBuffer("\r\n ===>Video Streaming DV Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", DVFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", DVFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", DVFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", DVFormatDesc->bFormatIndex); + AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", DVFormatDesc->dwMaxVideoFrameBufferSize); + AppendTextBuffer("bFormatType: 0x%02X\r\n", DVFormatDesc->bFormatType); + if (gDoAnnotation) + { + AppendTextBuffer(" D0..6 = Format Type ->"); + switch(DVFormatDesc->bFormatType & 0x03) + { + case 0x00: + AppendTextBuffer(" SD-DV\r\n"); + break; + case 0x01: + AppendTextBuffer(" SDL-DV\r\n"); + break; + case 0x02: + AppendTextBuffer(" HD-DV\r\n"); + break; + default: + AppendTextBuffer(" Unknown Format\r\n"); + break; + } + if (DVFormatDesc->bFormatType & 0x80) + AppendTextBuffer(" D7 = 60Hz"); + else + AppendTextBuffer(" D7 = 50Hz"); + AppendTextBuffer("\r\n");} + + if (DVFormatDesc->bLength != sizeof(VIDEO_FORMAT_DV)) + { + //@@TestCase B27.1 (descript.c line 1453) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + DVFormatDesc->bLength, + sizeof(VIDEO_FORMAT_DV)); + OOPS(); + } + + if (DVFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B27.2 (descript.c line 1458) + //@@ERROR + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex invalid + AppendTextBuffer("*!*ERROR: bFormatIndex of 0x%02X is invalid\r\n", + DVFormatDesc->bFormatIndex); + OOPS(); + } + + if (DVFormatDesc->dwMaxVideoFrameBufferSize == 0 ) + { + //@@TestCase B27.3 (descript.c line 1463) + //@@ERROR + //@@Descriptor Field - dwMaxVideoFrameBufferSize + //@@dwMaxVideoFrameBufferSize invalid + AppendTextBuffer("*!*ERROR: dwMaxVideoFrameBufferSize of 0x%02X is invalid\r\n", + DVFormatDesc->dwMaxVideoFrameBufferSize); + OOPS(); + } + + //@@TestCase B27.4 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bFormatType + //@@Question - Should we validate that reserved bits are set to zero? + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVidVendorFormat() +// +//***************************************************************************** + +BOOL +DisplayVendorVidFormat ( + PVIDEO_FORMAT_VENDOR VendorVidFormatDesc + ) +{ + //@@DisplayVendorVidFormat -Vendor Video Format + OLECHAR szGUID[256]; + int i = 0; + + // Initialize the default Frame + g_chVendorFrameDefault = VendorVidFormatDesc->bDefaultFrameIndex; + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidMajorFormat, (LPOLESTR) szGUID, 255); + i++; + + AppendTextBuffer("\r\n ===>Video Streaming Vendor Video Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", VendorVidFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VendorVidFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VendorVidFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", VendorVidFormatDesc->bFormatIndex); + AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", VendorVidFormatDesc->bNumFrameDescriptors); + AppendTextBuffer("guidMajorFormat: %S\r\n", szGUID); + i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidSubFormat, (LPOLESTR) szGUID, 255); + i++; + AppendTextBuffer("guidSubFormat: %S\r\n", szGUID); + i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidSpecifier, (LPOLESTR) szGUID, 255); + i++; + AppendTextBuffer("guidSpecifier: %S\r\n", szGUID); + AppendTextBuffer("bPayloadClass: 0x%02X\r\n", VendorVidFormatDesc->bPayloadClass); + AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", VendorVidFormatDesc->bDefaultFrameIndex); + AppendTextBuffer("bCopyProtect: 0x%02X", VendorVidFormatDesc->bCopyProtect); + if(gDoAnnotation) { + if(VendorVidFormatDesc->bCopyProtect) { AppendTextBuffer(" -> Duplication Restricted\r\n");} + else {AppendTextBuffer(" -> Duplication Unrestricted\r\n");}} + else {AppendTextBuffer("\r\n");} + + if (VendorVidFormatDesc->bLength != sizeof(VIDEO_FORMAT_VENDOR)) + { + //@@TestCase B28.1 (descript.c line 1297) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", + VendorVidFormatDesc->bLength, + sizeof(VIDEO_FORMAT_VENDOR)); + OOPS(); + } + + if (VendorVidFormatDesc->bFormatIndex == 0 ) + { + //@@TestCase B28.2 (descript.c line 1302) + //@@ERROR + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (VendorVidFormatDesc->bNumFrameDescriptors == 0 ) + { + //@@TestCase B28.3 (descript.c line 1307) + //@@ERROR + //@@Descriptor Field - bNumFrameDescriptors + //@@bNumFrameDescriptors is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(VendorVidFormatDesc->bPayloadClass > 1) + { + //@@TestCase B28.4 + //@@WARNING + //@@Descriptor Field - bPayloadClass + //@@bPayloadClass is using reserved space + AppendTextBuffer("*!*WARNING: bPayloadClass is incorrectly using reserved space\r\n"); + OOPS(); + } + else + { + if (gDoAnnotation) + { + if(VendorVidFormatDesc->bPayloadClass == 1) { AppendTextBuffer(" -> Using a Frame Based Payload\r\n");} + else { AppendTextBuffer(" -> Using a Stream Based Payload\r\n");} + } + else {AppendTextBuffer("\r\n");} + } + + if (VendorVidFormatDesc->bDefaultFrameIndex == 0 ) + { + //@@TestCase B28.5 (descript.c line 1312) + //@@ERROR + //@@Descriptor Field - bDefaultFrameIndex + //@@bDefaultFrameIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bDefaultFrameIndex = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (VendorVidFormatDesc->bDefaultFrameIndex == 0 || VendorVidFormatDesc->bDefaultFrameIndex > VendorVidFormatDesc->bNumFrameDescriptors) + { + //@@TestCase B28.6 + //@@WARNING + //@@Descriptor Field - bDefaultFrameIndex + //@@bDefaultFrameIndex is out of range + AppendTextBuffer("*!*WARNING: The value %d for the bDefaultFrameIndex is out of range this invalidates the descriptor\r\n*!* The proper range is 1 to %d)", + VendorVidFormatDesc->bDefaultFrameIndex, + VendorVidFormatDesc->bNumFrameDescriptors); + OOPS(); + } + + //@@TestCase B28.7 + //@@Not yet implemented - Priority 1 + //@@Descriptor Field - bCopyProtect + //@@Question - Are their reserved bits and should we validate that reserved bits are set to zero? + // AppendTextBuffer("bCopyProtect: 0x%02X", VendorVidFormatDesc->bCopyProtect); + + // Check that the correct number of Frame Descriptors and one Color Matching + // descriptor follow + CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) VendorVidFormatDesc, + VendorVidFormatDesc->bNumFrameDescriptors, VS_FRAME_VENDOR); + + // This descriptor is deprecated for UVC 1.1 +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); + } +#else + if (UVC11 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); + } +#endif + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVendorVidFrameType() +// +//***************************************************************************** + +BOOL +DisplayVendorVidFrameType ( + PVIDEO_FRAME_VENDOR VendorVidFrameDesc + ) +{ + //@@DisplayVendorVidFrameType -Vendor Video Frame + size_t bLength = 0; + bLength = SizeOfVideoFrameVendor(VendorVidFrameDesc); + + AppendTextBuffer("\r\n ===>Video Streaming Vendor Video Frame Type Descriptor<===\r\n"); + if (gDoAnnotation) + { + if(VendorVidFrameDesc->bFrameIndex == g_chVendorFrameDefault) + { + AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); + } + } + AppendTextBuffer("bLength: 0x%02X\r\n", VendorVidFrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VendorVidFrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VendorVidFrameDesc->bDescriptorSubtype); + AppendTextBuffer("bFrameIndex: 0x%02X\r\n", VendorVidFrameDesc->bFrameIndex); + + if (VendorVidFrameDesc->bLength != bLength) + { + //@@TestCase B29.1 (descript.c line 1352) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is less than required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + VendorVidFrameDesc->bLength, bLength); + OOPS(); + } + + if (VendorVidFrameDesc->bFrameIndex == 0 ) + { + //@@TestCase B29.2 (descript.c line 1357) + //@@ERROR + //@@Descriptor Field - bFrameIndex + //@@bFrameIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + AppendTextBuffer("bmCapabilities: 0x%02X", VendorVidFrameDesc->bmCapabilities); + + if(VendorVidFrameDesc->bmCapabilities & 0x01){ + if(gDoAnnotation) { AppendTextBuffer(" -> Still Images are supported\r\n");} + else {AppendTextBuffer("\r\n");} } + else if (VendorVidFrameDesc->bmCapabilities & 0xFF) + { + //@@TestCase B29.3 + //@@WARNING + //@@Descriptor Field - bmCapabilities + //@@bmCapabilities has a bit using reserved areas that should be set to zero + AppendTextBuffer("\r\n*!*WARNING: bmCapabilities is using reserved areas.\r\n"); + OOPS(); } + else {AppendTextBuffer("\r\n");} + AppendTextBuffer("wWidth: 0x%04X = %d\r\n", VendorVidFrameDesc->wWidth, VendorVidFrameDesc->wWidth); + AppendTextBuffer("wHeight: 0x%04X = %d\r\n", VendorVidFrameDesc->wHeight, VendorVidFrameDesc->wHeight); + AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", VendorVidFrameDesc->dwMinBitRate); + AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", VendorVidFrameDesc->dwMaxBitRate); + AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", VendorVidFrameDesc->dwMaxVideoFrameBufferSize); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + VendorVidFrameDesc->dwDefaultFrameInterval, + ((double)VendorVidFrameDesc->dwDefaultFrameInterval)/10000.0, + (10000000.0/((double)VendorVidFrameDesc->dwDefaultFrameInterval)) + ); + AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", VendorVidFrameDesc->bFrameIntervalType); + + if (VendorVidFrameDesc->wWidth == 0 ) + { + //@@TestCase B29.4 (descript.c line 1362) + //@@ERROR + //@@Descriptor Field - wWidth + //@@wWidth is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); + OOPS(); + } + + if (VendorVidFrameDesc->wHeight == 0 ) + { + //@@TestCase B29.5 (descript.c line 1367) + //@@ERROR + //@@Descriptor Field - wHeight + //@@wHeight is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); + OOPS(); + } + + if (VendorVidFrameDesc->dwMinBitRate == 0 ) + { + //@@TestCase B29.6 (descript.c line 1372) + //@@ERROR + //@@Descriptor Field - dwMinBitRate + //@@dwMinBitRate is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); + OOPS(); + } + + if (VendorVidFrameDesc->dwMaxBitRate == 0 ) + { + //@@TestCase B29.7 (descript.c line 1377) + //@@ERROR + //@@Descriptor Field - dwMaxBitRate + //@@dwMaxBitRate is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); + OOPS(); + } + + if(VendorVidFrameDesc->dwMinBitRate > VendorVidFrameDesc->dwMaxBitRate) + { + //@@TestCase B29.8 + //@@ERROR + //@@Descriptor Field - dwMinBitRate and dwMaxBitRate + //@@Verify that dwMaxBitRate is greater than dwMinBitRate + AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); + OOPS(); + } + else + { + if (VendorVidFrameDesc->bFrameIntervalType == 1 && + VendorVidFrameDesc->dwMinBitRate != VendorVidFrameDesc->dwMaxBitRate) + { + //@@TestCase B29.9 + //@@WARNING + //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate + //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 + AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ + "should equal dwMaxBitRate\r\n"); + OOPS(); + } + } + + if (VendorVidFrameDesc->dwMaxVideoFrameBufferSize == 0 ) + { + //@@TestCase B29.10 (descript.c line 1382) + //@@WARNING + //@@Descriptor Field - dwMaxVideoFrameBufferSize + //@@dwMaxVideoFrameBufferSize is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*WARNING: dwMaxVideoFrameBufferSize must be nonzero\r\n"); + OOPS(); + } + if (VendorVidFrameDesc->dwDefaultFrameInterval == 0 ) + { + //@@TestCase B29.11 (descript.c line 1020) + //@@WARNING + //@@Descriptor Field - dwDefaultFrameInterval + //@@dwDefaultFrameInterval must be nonzero + AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); + OOPS(); + } + + if (VendorVidFrameDesc->bFrameIntervalType == 0) + { + DisplayVendorVidContinuousFrameType(VendorVidFrameDesc); + } + else + { + DisplayVendorVidDiscreteFrameType(VendorVidFrameDesc); + } + // This descriptor is deprecated for UVC 1.1 +#ifdef H264_SUPPORT + if (UVC10 != g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); + } +#else + if (UVC11 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); + } +#endif + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVendorVidContinuousFrameType() +// +//***************************************************************************** + +BOOL +DisplayVendorVidContinuousFrameType( + PVIDEO_FRAME_VENDOR VContinuousDesc + ) +{ + //@@DisplayVendorVidContinuousFrameType -Vendor Video Continuous Frame + ULONG dwMinFrameInterval = VContinuousDesc->adwFrameInterval[0]; + ULONG dwMaxFrameInterval = VContinuousDesc->adwFrameInterval[1]; + ULONG dwFrameIntervalStep = VContinuousDesc->adwFrameInterval[2]; + + AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + + AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMinFrameInterval, + ((double)dwMinFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); + + AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMaxFrameInterval, + ((double)dwMaxFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); + AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); + + if (dwMinFrameInterval == 0 ) + { + //@@TestCase B30.2 (descript.c line 1388) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval + //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (dwMaxFrameInterval == 0 ) + { + //@@TestCase B30.3 (descript.c line 1388) + //@@ERROR + //@@Descriptor Field - dwMaxFrameInterval + //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(dwMinFrameInterval > dwMaxFrameInterval) + { + //@@TestCase B30.4 (descript.c line 1405) + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval + AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); + OOPS(); + } + else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) + { + //@@TestCase B30.5 + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) + { + //@@TestCase B30.6 + //@@CAUTION + //@@Descriptor Field - dwFrameIntervalStep + //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero + AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) + { + //@@TestCase B30.7 (descript.c line 1414) + //@@ERROR + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep + AppendTextBuffer("*!*ERROR: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); + OOPS(); + } + + if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) + { + //@@TestCase B30.8 (descript.c line 1394) + //@@ERROR + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval + AppendTextBuffer("*!*ERROR: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between \r\n dwMinFrameInterval and dwMaxFrameInterval\r\n"); + OOPS(); + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVendorVidDiscreteFrameType() +// +//***************************************************************************** + +BOOL +DisplayVendorVidDiscreteFrameType( + PVIDEO_FRAME_VENDOR VDiscreteDesc + ) +{ + //@@DisplayVendorVidDiscreteFrameType -Vendor Video Discrete Frame + UINT iNdex = 1; + UINT iCurFrame = 0; + ULONG * ulFrameInterval = NULL; + + AppendTextBuffer("===>Additional Discrete Frame TypeData\r\n"); + + // There are (VDiscreteDesc->bFrameIntervalType) dwFrameIntervals + for (; iNdex <= VDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) + { + ulFrameInterval = &VDiscreteDesc->adwFrameInterval[iCurFrame]; + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + iNdex, *ulFrameInterval, + ((double)*ulFrameInterval)/10000.0, + (10000000.0/((double)*ulFrameInterval)) + ); + if (0 == *ulFrameInterval) + { + //@@TestCase B31.1 (descript.c line 1061) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[x] must be non-zero + AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); + OOPS(); + } + if ((iNdex > 1)&&(*ulFrameInterval <= VDiscreteDesc->adwFrameInterval[iCurFrame - 1])) + { + //@@TestCase B31.2 (descript.c line 1067) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] + AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ + "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); + OOPS(); + } + } + + return TRUE; +} + +//***************************************************************************** +// +// DisplayFramePayloadFormat() +// +//***************************************************************************** + +BOOL +DisplayFramePayloadFormat ( + PVIDEO_FORMAT_FRAME FramePayloadFormatDesc + ) +{ + //@@DisplayFramePayloadFormat - FrameBased Payload Format + PCHAR pStr = NULL; + OLECHAR szGUID[256]; + int i = 0; + + // Initialize the default Frame + g_chFrameBasedFrameDefault = FramePayloadFormatDesc->bDefaultFrameIndex; + + memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); + i = StringFromGUID2((REFGUID) &FramePayloadFormatDesc->guidFormat, (LPOLESTR) szGUID, 255); + i++; + + AppendTextBuffer("\r\n ===>Video Streaming Frame Based Payload Format Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X\r\n", FramePayloadFormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", FramePayloadFormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", FramePayloadFormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X\r\n", FramePayloadFormatDesc->bFormatIndex); + AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", FramePayloadFormatDesc->bNumFrameDescriptors); + AppendTextBuffer("guidFormat: %S", szGUID); + + pStr = VidFormatGUIDCodeToName((REFGUID) &FramePayloadFormatDesc->guidFormat); + if ( pStr ) + { + if ( gDoAnnotation ) + { + AppendTextBuffer(" = %s Format", pStr); + } + } + AppendTextBuffer("\r\n"); + AppendTextBuffer("bBitsPerPixel: 0x%02X\r\n", FramePayloadFormatDesc->bBitsPerPixel); + AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", FramePayloadFormatDesc->bDefaultFrameIndex); + + if (FramePayloadFormatDesc->bLength != sizeof(VIDEO_FORMAT_FRAME)) + { + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required + //@@length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + FramePayloadFormatDesc->bLength, + sizeof(VIDEO_FORMAT_FRAME)); + OOPS(); + } + + if (FramePayloadFormatDesc->bFormatIndex == 0 ) + { + //@@ERROR + //@@Descriptor Field - bFormatIndex + //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + if (FramePayloadFormatDesc->bNumFrameDescriptors == 0 ) + { + //@@ERROR + //@@Descriptor Field - bNumFrameDescriptors + //@@bNumFrameDescriptors is set to zero which is not in accordance with the + //@@USB Video Device Specification + AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, must have at least 1 Frame descriptor\r\n"); + OOPS(); + } + + if(!(pStr)) + { + //@@WARNING + //@@Descriptor Field - guidFormat + //@@guidFormat is set to unknown or undefined format + AppendTextBuffer("\r\n*!*WARNING: guidFormat is an unknown format\r\n"); + OOPS(); + } + + if (FramePayloadFormatDesc->bBitsPerPixel == 0 ) + { + //@@ERROR + //@@Descriptor Field - bBitsPerPixel + //@@bBitsPerPixel is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bBitsPerPixel = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (FramePayloadFormatDesc->bDefaultFrameIndex == 0 || FramePayloadFormatDesc->bDefaultFrameIndex > + FramePayloadFormatDesc->bNumFrameDescriptors) + { + //@@ERROR + //@@Descriptor Field - bDefaultFrameIndex + //@@The value for bDefaultFrameIndex is not greater than 0 or less than or equal to bNumFrameDescriptors + AppendTextBuffer("*!*ERROR: The value %d for the bDefaultFrameIndex is out of range, this invalidates the descriptor\r\n*!*The proper range is 1 to %d)", + FramePayloadFormatDesc->bDefaultFrameIndex, + FramePayloadFormatDesc->bNumFrameDescriptors); + OOPS(); + } + + AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", + FramePayloadFormatDesc->bAspectRatioX); + AppendTextBuffer("bAspectRatioY: 0x%02X", + FramePayloadFormatDesc->bAspectRatioY); + + if (((FramePayloadFormatDesc->bmInterlaceFlags & 0x01) && + (FramePayloadFormatDesc->bAspectRatioY != 0 && + FramePayloadFormatDesc->bAspectRatioX != 0))) + { + if(gDoAnnotation) + { + AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", + (FramePayloadFormatDesc->bAspectRatioX),(FramePayloadFormatDesc->bAspectRatioY)); + } + else + { + if (FramePayloadFormatDesc->bAspectRatioY != 0 || FramePayloadFormatDesc->bAspectRatioX != 0) + { + //@@ERROR + //@@Descriptor Field - bAspectRatioX, bAspectRatioY + //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero + //@@ if stream is non-interlaced + AppendTextBuffer("\r\n*!*ERROR: Both bAspectRatioX and bAspectRatioY "\ + "must equal 0 if stream is non-interlaced"); + OOPS(); + } + } + } + AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", + FramePayloadFormatDesc->bmInterlaceFlags); + + if (gDoAnnotation) + { + AppendTextBuffer(" D0 = 0x%02X Interlaced stream or variable: %s\r\n", + (FramePayloadFormatDesc->bmInterlaceFlags & 1), + (FramePayloadFormatDesc->bmInterlaceFlags & 1) ? "Yes" : "No"); + AppendTextBuffer(" D1 = 0x%02X Fields per frame: %s\r\n", + ((FramePayloadFormatDesc->bmInterlaceFlags >> 1) & 1), + ((FramePayloadFormatDesc->bmInterlaceFlags >> 1) & 1) ? "1 field" : "2 fields"); + AppendTextBuffer(" D2 = 0x%02X Field 1 first: %s\r\n", + ((FramePayloadFormatDesc->bmInterlaceFlags >> 2) & 1), + ((FramePayloadFormatDesc->bmInterlaceFlags >> 2) & 1) ? "Yes" : "No"); + //@@Descriptor Field - bmInterlaceFlags + //@@Validate that reserved bits (D3) are set to zero. + AppendTextBuffer(" D3 = 0x%02X Reserved%s\r\n", + ((FramePayloadFormatDesc->bmInterlaceFlags >> 3) & 1), + ((FramePayloadFormatDesc->bmInterlaceFlags >> 3) & 1) ? + "\r\n*!*ERROR: Reserved to 0" : "" ); + AppendTextBuffer(" D4..5 = 0x%02X Field patterns ->", + ((FramePayloadFormatDesc->bmInterlaceFlags >> 4) & 3)); + switch(FramePayloadFormatDesc->bmInterlaceFlags & 0x30) + { + case 0x00: + AppendTextBuffer(" Field 1 only"); + break; + case 0x10: + AppendTextBuffer(" Field 2 only"); + break; + case 0x20: + AppendTextBuffer(" Regular Pattern of fields 1 and 2"); + break; + case 0x30: + AppendTextBuffer(" Random Pattern of fields 1 and 2"); + break; + } + AppendTextBuffer("\r\n D6..7 = 0x%02X Display Mode ->", + ((FramePayloadFormatDesc->bmInterlaceFlags >> 6) & 3)); + + switch(FramePayloadFormatDesc->bmInterlaceFlags & 0xC0) + { + case 0x00: + AppendTextBuffer(" Bob only"); + break; + case 0x40: + AppendTextBuffer(" Weave only"); + break; + case 0x80: + AppendTextBuffer(" Bob or weave"); + break; + case 0xC0: + //@@Descriptor Field - bmInterlaceFlags + //@@Question - Should we validate that reserved bits are set to zero? + AppendTextBuffer(" Reserved"); + break; + } + } + + //@@Descriptor Field - bCopyProtect + //@@Question - Are their reserved bits and should we validate that + //@@ reserved bits are set to zero? + AppendTextBuffer("\r\nbCopyProtect: 0x%02X", + FramePayloadFormatDesc->bCopyProtect); + if (gDoAnnotation) + { + if (FramePayloadFormatDesc->bCopyProtect) + AppendTextBuffer(" -> Duplication Restricted"); + else + AppendTextBuffer(" -> Duplication Unrestricted"); + } + + //@@Descriptor Field - bVariableSize + AppendTextBuffer("\r\nbVariableSize: 0x%02X", + FramePayloadFormatDesc->bVariableSize); + if (gDoAnnotation) + { + if (FramePayloadFormatDesc->bVariableSize) + AppendTextBuffer(" -> Variable Size"); + else + AppendTextBuffer(" -> Fixed Size"); + } + AppendTextBuffer("\r\n"); + + // Check that the correct number of Frame Descriptors and one Color Matching + // descriptor follow + CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) FramePayloadFormatDesc, + FramePayloadFormatDesc->bNumFrameDescriptors, VS_FRAME_FRAME_BASED); + + // This descriptor is new for UVC 1.1 + if (UVC10 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); + } + return TRUE; + } + + +//***************************************************************************** +// +// DisplayFramePayloadFrame() +// +//***************************************************************************** + +BOOL +DisplayFramePayloadFrame ( + PVIDEO_FRAME_FRAME FramePayloadFrameDesc + ) +{ + size_t bLength = 0; + bLength = SizeOfVideoFrameFrame(FramePayloadFrameDesc); + + //@@DisplayFramePayloadFrame -Frame Based Payload Frame + + AppendTextBuffer("\r\n ===>Video Streaming Frame Based Payload Frame Type Descriptor<===\r\n"); + if (gDoAnnotation) + { + if(FramePayloadFrameDesc->bFrameIndex == g_chFrameBasedFrameDefault) + { + AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); + } + } + AppendTextBuffer("bLength: 0x%02X\r\n", FramePayloadFrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", FramePayloadFrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", FramePayloadFrameDesc->bDescriptorSubtype); + AppendTextBuffer("bFrameIndex: 0x%02X\r\n", FramePayloadFrameDesc->bFrameIndex); + AppendTextBuffer("bmCapabilities: 0x%02X\r\n", FramePayloadFrameDesc->bmCapabilities); + AppendTextBuffer("wWidth: 0x%04X = %d\r\n", FramePayloadFrameDesc->wWidth, FramePayloadFrameDesc->wWidth); + AppendTextBuffer("wHeight: 0x%04X = %d\r\n", FramePayloadFrameDesc->wHeight, FramePayloadFrameDesc->wHeight); + AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", FramePayloadFrameDesc->dwMinBitRate); + AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", FramePayloadFrameDesc->dwMaxBitRate); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + FramePayloadFrameDesc->dwDefaultFrameInterval, + ((double)FramePayloadFrameDesc->dwDefaultFrameInterval)/10000.0, + (10000000.0/((double)FramePayloadFrameDesc->dwDefaultFrameInterval)) + ); + AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", FramePayloadFrameDesc->bFrameIntervalType); + + if (FramePayloadFrameDesc->bLength != bLength) + { + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required + //@@length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", + FramePayloadFrameDesc->bLength, bLength); + OOPS(); + } + + if (FramePayloadFrameDesc->bFrameIndex == 0 ) + { + //@@ERROR + //@@Descriptor Field - bFrameIndex + //@@bFrameIndex must be nonzero + AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); + OOPS(); + } + + //@@Descriptor Field - bmCapabilities + //@@Question: Should we try to verify that bmCapabilities is valid? + // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); + + if (FramePayloadFrameDesc->wWidth == 0 ) + { + //@@ERROR + //@@Descriptor Field - wWidth + //@@wWidth must be nonzero + AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); + OOPS(); + } + + if (FramePayloadFrameDesc->wHeight == 0 ) + { + //@@ERROR + //@@Descriptor Field - wHeight + //@@wHeight must be nonzero + AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); + OOPS(); + } + + if (FramePayloadFrameDesc->dwMinBitRate == 0 ) + { + //@@ERROR + //@@Descriptor Field - dwMinBitRate + //@@dwMinBitRate must be nonzero + AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); + OOPS(); + } + + if (FramePayloadFrameDesc->dwMaxBitRate == 0 ) + { + //@@ERROR + //@@Descriptor Field - dwMaxBitRate + //@@dwMaxBitRate must be nonzero + AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); + OOPS(); + } + + if(FramePayloadFrameDesc->dwMinBitRate > FramePayloadFrameDesc->dwMaxBitRate) + { + //@@ERROR + //@@Descriptor Field - dwMinBitRate and dwMaxBitRate + //@@Verify that dwMaxBitRate is greater than dwMinBitRate + AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); + OOPS(); + } + else + { + if (FramePayloadFrameDesc->bFrameIntervalType == 1 && + FramePayloadFrameDesc->dwMinBitRate != FramePayloadFrameDesc->dwMaxBitRate) + { + //@@WARNING + //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate + //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 + AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ + "should equal dwMaxBitRate\r\n"); + OOPS(); + } + } + + if (FramePayloadFrameDesc->dwDefaultFrameInterval == 0 ) + { + //@@TestCase B16.11 (descript.c line 1020) + //@@WARNING + //@@Descriptor Field - dwDefaultFrameInterval + //@@dwDefaultFrameInterval must be nonzero + AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); + OOPS(); + } + + if (0 == FramePayloadFrameDesc->bFrameIntervalType) + { + DisplayFramePayloadContinuousFrameType(FramePayloadFrameDesc); + } + else + { + DisplayFramePayloadDiscreteFrameType(FramePayloadFrameDesc); + } + // This descriptor is new for UVC 1.1 + if (UVC10 == g_chUVCversion) + { + AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayFramePayloadContinuousFrameType() +// +//***************************************************************************** + +BOOL +DisplayFramePayloadContinuousFrameType( + PVIDEO_FRAME_FRAME FContinuousDesc + ) +{ + //@@DisplayFramePayloadContinuousFrameType -Frame Payload Continuous Frame + ULONG dwMinFrameInterval = FContinuousDesc->adwFrameInterval[0]; + ULONG dwMaxFrameInterval = FContinuousDesc->adwFrameInterval[1]; + ULONG dwFrameIntervalStep = FContinuousDesc->adwFrameInterval[2]; + + AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + + AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMinFrameInterval, + ((double)dwMinFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); + + AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", + dwMaxFrameInterval, + ((double)dwMaxFrameInterval)/10000.0, + (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); + + AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); + + if (dwMinFrameInterval == 0 ) + { + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval + //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if (dwMaxFrameInterval == 0 ) + { + //@@ERROR + //@@Descriptor Field - dwMaxFrameInterval + //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification + AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); + OOPS(); + } + + if(dwMinFrameInterval > dwMaxFrameInterval) + { + //@@ERROR + //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval + AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); + OOPS(); + } + else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) + { + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) + { + //@@CAUTION + //@@Descriptor Field - dwFrameIntervalStep + //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero + AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); + OOPS(); + } + else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) + { + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep + AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); + OOPS(); + } + + if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) + { + //@@WARNING + //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval + //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval + AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between dwMinFrameInterval and dwMaxFrameInterval\r\n"); + OOPS(); + } + + return TRUE; +} + +//***************************************************************************** +// +// DisplayFramePayloadDiscreteFrameType() +// +//***************************************************************************** + +BOOL +DisplayFramePayloadDiscreteFrameType( + PVIDEO_FRAME_FRAME FDiscreteDesc + ) +{ + //@@DisplayFramePayloadDiscreteFrameType -Frame Based Payload Discrete Frame + UINT iNdex = 1; + UINT iCurFrame = 0; + ULONG * ulFrameInterval = NULL; + + AppendTextBuffer("===>Additional Discrete Frame Type Data\r\n"); + + // There are (UDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) + for (; iNdex <= FDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) + { + ulFrameInterval = &FDiscreteDesc->adwFrameInterval[iCurFrame]; + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", + iNdex, *ulFrameInterval, + ((double)*ulFrameInterval)/10000.0, + (10000000.0/((double)*ulFrameInterval)) + ); + if (0 == *ulFrameInterval) + { + //@@TestCase B18.1 (descript.c line 1061) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[x] must be non-zero + AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); + OOPS(); + } + if ((iNdex > 1)&&(*ulFrameInterval <= FDiscreteDesc->adwFrameInterval[iCurFrame - 1])) + { + //@@TestCase B18.2 (descript.c line 1067) + //@@ERROR + //@@Descriptor Field - dwFrameInterval[x] + //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] + AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ + "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); + OOPS(); + } + } + return TRUE; +} + +//***************************************************************************** +// +// DisplayVSEndpoint() +// +//***************************************************************************** + +BOOL +DisplayVSEndpoint ( + PVIDEO_CS_INTERRUPT VidEndpointDesc + ) +{ + //@@DisplayVSEndpoint - Video Streaming Endpoint + AppendTextBuffer("\r\n ===>Class-specific VC Interrupt Endpoint Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X \r\n", VidEndpointDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidEndpointDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidEndpointDesc->bDescriptorSubtype); + AppendTextBuffer("wMaxTransferSize: 0x%04X", VidEndpointDesc->wMaxTransferSize); + if(gDoAnnotation) { + AppendTextBuffer(" = (%d) Bytes\r\n", VidEndpointDesc->wMaxTransferSize);} + else {AppendTextBuffer("\r\n");} + + if (VidEndpointDesc->bLength != sizeof(VIDEO_CS_INTERRUPT)) + { + //@@TestCase B32.1 (descript.c line 1616) + //@@ERROR + //@@Descriptor Field - bLength + //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification + AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", + VidEndpointDesc->bLength, + sizeof(VIDEO_CS_INTERRUPT)); + OOPS(); + } + + return TRUE; +} + +//***************************************************************************** +// +// VDisplayBytes() +// +//***************************************************************************** + +VOID +VDisplayBytes ( + PUCHAR Data, + USHORT Len + ) +{ + USHORT i = 0; + + for (i = 0; i < Len; i++) + { + AppendTextBuffer("0x%02X ", Data[i]); + + if (i % 16 == 15) + { + AppendTextBuffer("\r\n"); + } + } + + if (i % 16 != 0) + { + AppendTextBuffer("\r\n"); + } +} + +//***************************************************************************** +// +// VidFormatGUIDCodeToName() +// +//***************************************************************************** + + +PCHAR +VidFormatGUIDCodeToName ( + REFGUID VidFormatGUIDCode + ) +{ + // GUID pYUY2 = YUY2_Format; + // GUID pNV12 = NV12_Format; + if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &YUY2_Format)) + { + return (PCHAR) &"YUY2"; + } + if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &NV12_Format)) + { + return (PCHAR) &"NV12"; + } +#ifdef H264_SUPPORT + // GUID pH264 = H264_Format; + if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &H264_Format)) + { + return (PCHAR) &"H.264"; + } +#endif + + return FALSE; +} + +/***************************************************************************** + +GetVCInterfaceSize() + +*****************************************************************************/ + +UINT +GetVCInterfaceSize ( + PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc + ) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = (PUSB_COMMON_DESCRIPTOR) VCInterfaceDesc; + PUCHAR descEnd = (PUCHAR) VCInterfaceDesc + VCInterfaceDesc->wTotalLength; + UINT uCount = 0; + + // return this interface's sum of descriptor lengths + // starting from this header until (and not including) the first endpoint + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + if (commonDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) + break; + uCount += commonDesc->bLength; + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uCount); +} + +/***************************************************************************** + +CheckForColorMatchingDesc () + +Given starting address of format descriptor; +number of frame descriptors; +subtype of frame to look for; + +1) walk through each descriptor += if desc is frame of given subtype, update counter += if desc is still frame, update counter += if desc is color matching descriptor, update counter +! if frame is something else, break (all these frames should be consecutive) +! if next frame is beyond ending address of configuration, break + +PASS +frame count == numframes passed in +color match == 1 +still frames are handled in the video stream input header and the frame displays + +*****************************************************************************/ + +UINT +CheckForColorMatchingDesc ( + PVIDEO_SPECIFIC pFormatDesc, + UCHAR bNumFrameDescriptors, + UCHAR bDescriptorSubtype + ) +{ + UINT uFrameCount = 0; + UINT uStillFrameCount = 0; + UINT uColorCount = 0; + + // DONE if the descriptor address is beyond the configuration range + for ( ; ValidateDescAddress ((PUSB_COMMON_DESCRIPTOR) pFormatDesc); ) + { + // DONE if it's not an interface desc + if (CS_INTERFACE != pFormatDesc->bDescriptorType) + { + break; + } + switch (pFormatDesc->bDescriptorSubtype) + { + case VS_STILL_IMAGE_FRAME: + uStillFrameCount++; + break; + case VS_COLORFORMAT: + uColorCount++; + break; + default: + if (bDescriptorSubtype == pFormatDesc->bDescriptorSubtype) + { + uFrameCount++; + } + break; + } + pFormatDesc = (PVIDEO_SPECIFIC) ((PUCHAR) pFormatDesc + pFormatDesc->bLength); + } + if (uFrameCount != bNumFrameDescriptors) + { + AppendTextBuffer("*!*ERROR: Found %d frame descriptors (should be %d)\r\n", + uFrameCount, bNumFrameDescriptors); + } + // We already check Still Frames in the Video Info Header and Still Frames displays + if (0 == uColorCount) + { + AppendTextBuffer("*!*ERROR: no Color Matching Descriptor for this format\r\n"); + } + return (uColorCount); +} + +/***************************************************************************** + +GetVSInterfaceSize() + +*****************************************************************************/ + +UINT +GetVSInterfaceSize ( + PUSB_COMMON_DESCRIPTOR VidInHeaderDesc, + USHORT wTotalLength + ) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = (PUSB_COMMON_DESCRIPTOR) VidInHeaderDesc; + PUCHAR descEnd = (PUCHAR) VidInHeaderDesc + wTotalLength; + UINT uCount = 0; + + // return this interface's sum of descriptor lengths + // starting from this header until (and not including) the first endpoint + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + if (commonDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) + break; + uCount += commonDesc->bLength; + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + return (uCount); +} + +/***************************************************************************** + +ValidateTerminalID() + +*****************************************************************************/ + +BOOL +ValidateTerminalID( + UINT uTerminalID + ) +{ + UNREFERENCED_PARAMETER(uTerminalID); + return (TRUE); +} diff --git a/usb/usbview/enum.c b/usb/usbview/enum.c new file mode 100644 index 00000000..6cea7473 --- /dev/null +++ b/usb/usbview/enum.c @@ -0,0 +1,3366 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + + ENUM.C + +Abstract: + + This source file contains the routines which enumerate the USB bus + and populate the TreeView control. + + The enumeration process goes like this: + + (1) Enumerate Host Controllers and Root Hubs + EnumerateHostControllers() + EnumerateHostController() + Host controllers currently have symbolic link names of the form HCDx, + where x starts at 0. Use CreateFile() to open each host controller + symbolic link. Create a node in the TreeView to represent each host + controller. + + GetRootHubName() + After a host controller has been opened, send the host controller an + IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of + the root hub that is part of the host controller. + + (2) Enumerate Hubs (Root Hubs and External Hubs) + EnumerateHub() + Given the name of a hub, use CreateFile() to map the hub. Send the + hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the + hub, such as the number of downstream ports. Create a node in the + TreeView to represent each hub. + + (3) Enumerate Downstream Ports + EnumerateHubPorts() + Given an handle to an open hub and the number of downstream ports on + the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX + request for each downstream port of the hub to get info about the + device (if any) attached to each port. If there is a device attached + to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request + to get the symbolic link name of the hub attached to the downstream + port. If there is a hub attached to the downstream port, recurse to + step (2). + + GetAllStringDescriptors() + GetConfigDescriptor() + Create a node in the TreeView to represent each hub port + and attached device. + + +Environment: + + user mode + +Revision History: + + 04-25-97 : created + +--*/ + +//***************************************************************************** +// I N C L U D E S +//***************************************************************************** + +#include "uvcview.h" + +//***************************************************************************** +// D E F I N E S +//***************************************************************************** + +#define NUM_STRING_DESC_TO_GET 32 + +//***************************************************************************** +// L O C A L F U N C T I O N P R O T O T Y P E S +//***************************************************************************** + +VOID +EnumerateHostControllers ( + HTREEITEM hTreeParent, + ULONG *DevicesConnected +); + +VOID +EnumerateHostController ( + HTREEITEM hTreeParent, + HANDLE hHCDev, + _Inout_ PCHAR leafName, + _In_ HANDLE deviceInfo, + _In_ PSP_DEVINFO_DATA deviceInfoData +); + +VOID +EnumerateHub ( + HTREEITEM hTreeParent, + _In_reads_(cbHubName) PCHAR HubName, + _In_ size_t cbHubName, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2, + _In_opt_ PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps, + _In_opt_ PUSB_DESCRIPTOR_REQUEST ConfigDesc, + _In_opt_ PUSB_DESCRIPTOR_REQUEST BosDesc, + _In_opt_ PSTRING_DESCRIPTOR_NODE StringDescs, + _In_opt_ PUSB_DEVICE_PNP_STRINGS DevProps +); + +VOID +EnumerateHubPorts ( + HTREEITEM hTreeParent, + HANDLE hHubDevice, + ULONG NumPorts +); + +PCHAR GetRootHubName ( + HANDLE HostController +); + +PCHAR GetExternalHubName ( + HANDLE Hub, + ULONG ConnectionIndex +); + +PCHAR GetHCDDriverKeyName ( + HANDLE HCD +); + +PCHAR GetDriverKeyName ( + HANDLE Hub, + ULONG ConnectionIndex +); + +PUSB_DESCRIPTOR_REQUEST +GetConfigDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + UCHAR DescriptorIndex + ); + +PUSB_DESCRIPTOR_REQUEST +GetBOSDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex + ); + +DWORD +GetHostControllerPowerMap( + HANDLE hHCDev, + PUSBHOSTCONTROLLERINFO hcInfo); + +DWORD +GetHostControllerInfo( + HANDLE hHCDev, + PUSBHOSTCONTROLLERINFO hcInfo); + +PCHAR WideStrToMultiStr ( + _In_reads_bytes_(cbWideStr) PWCHAR WideStr, + _In_ size_t cbWideStr + ); + +BOOL +AreThereStringDescriptors ( + PUSB_DEVICE_DESCRIPTOR DeviceDesc, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc +); + +PSTRING_DESCRIPTOR_NODE +GetAllStringDescriptors ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + PUSB_DEVICE_DESCRIPTOR DeviceDesc, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc +); + +PSTRING_DESCRIPTOR_NODE +GetStringDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + UCHAR DescriptorIndex, + USHORT LanguageID +); + +HRESULT +GetStringDescriptors ( + _In_ HANDLE hHubDevice, + _In_ ULONG ConnectionIndex, + _In_ UCHAR DescriptorIndex, + _In_ ULONG NumLanguageIDs, + _In_reads_(NumLanguageIDs) USHORT *LanguageIDs, + _In_ PSTRING_DESCRIPTOR_NODE StringDescNodeHead +); + +void +EnumerateAllDevices(); + + +void +EnumerateAllDevicesWithGuid( + PDEVICE_GUID_LIST DeviceList, + LPGUID Guid + ); + +void +FreeDeviceInfoNode( + _In_ PDEVICE_INFO_NODE *ppNode + ); + +PDEVICE_INFO_NODE +FindMatchingDeviceNodeForDriverName( + _In_ PSTR DriverKeyName, + _In_ BOOLEAN IsHub + ); + + +//***************************************************************************** +// G L O B A L S +//***************************************************************************** + +// List of enumerated host controllers. +// +LIST_ENTRY EnumeratedHCListHead = +{ + &EnumeratedHCListHead, + &EnumeratedHCListHead +}; + +DEVICE_GUID_LIST gHubList; +DEVICE_GUID_LIST gDeviceList; + + +//***************************************************************************** +// G L O B A L S P R I V A T E T O T H I S F I L E +//***************************************************************************** + +PCHAR ConnectionStatuses[] = +{ + "", // 0 - NoDeviceConnected + "", // 1 - DeviceConnected + "FailedEnumeration", // 2 - DeviceFailedEnumeration + "GeneralFailure", // 3 - DeviceGeneralFailure + "Overcurrent", // 4 - DeviceCausedOvercurrent + "NotEnoughPower", // 5 - DeviceNotEnoughPower + "NotEnoughBandwidth", // 6 - DeviceNotEnoughBandwidth + "HubNestedTooDeeply", // 7 - DeviceHubNestedTooDeeply + "InLegacyHub", // 8 - DeviceInLegacyHub + "Enumerating", // 9 - DeviceEnumerating + "Reset" // 10 - DeviceReset +}; + +ULONG TotalDevicesConnected; + + +//***************************************************************************** +// +// EnumerateHostControllers() +// +// hTreeParent - Handle of the TreeView item under which host controllers +// should be added. +// +//***************************************************************************** + +VOID +EnumerateHostControllers ( + HTREEITEM hTreeParent, + ULONG *DevicesConnected +) +{ + HANDLE hHCDev = NULL; + HDEVINFO deviceInfo = NULL; + SP_DEVINFO_DATA deviceInfoData; + SP_DEVICE_INTERFACE_DATA deviceInterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData = NULL; + ULONG index = 0; + ULONG requiredLength = 0; + BOOL success; + + TotalDevicesConnected = 0; + TotalHubs = 0; + + EnumerateAllDevices(); + + // Iterate over host controllers using the new GUID based interface + // + deviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER, + NULL, + NULL, + (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + for (index=0; + SetupDiEnumDeviceInfo(deviceInfo, + index, + &deviceInfoData); + index++) + { + deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + success = SetupDiEnumDeviceInterfaces(deviceInfo, + 0, + (LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER, + index, + &deviceInterfaceData); + + if (!success) + { + OOPS(); + break; + } + + success = SetupDiGetDeviceInterfaceDetail(deviceInfo, + &deviceInterfaceData, + NULL, + 0, + &requiredLength, + NULL); + + if (!success && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + OOPS(); + break; + } + + deviceDetailData = ALLOC(requiredLength); + if (deviceDetailData == NULL) + { + OOPS(); + break; + } + + deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + success = SetupDiGetDeviceInterfaceDetail(deviceInfo, + &deviceInterfaceData, + deviceDetailData, + requiredLength, + &requiredLength, + NULL); + + if (!success) + { + OOPS(); + break; + } + + hHCDev = CreateFile(deviceDetailData->DevicePath, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + + // If the handle is valid, then we've successfully opened a Host + // Controller. Display some info about the Host Controller itself, + // then enumerate the Root Hub attached to the Host Controller. + // + if (hHCDev != INVALID_HANDLE_VALUE) + { + EnumerateHostController(hTreeParent, + hHCDev, + deviceDetailData->DevicePath, + deviceInfo, + &deviceInfoData); + + CloseHandle(hHCDev); + } + + FREE(deviceDetailData); + } + + SetupDiDestroyDeviceInfoList(deviceInfo); + + *DevicesConnected = TotalDevicesConnected; + + return; +} + +//***************************************************************************** +// +// EnumerateHostController() +// +// hTreeParent - Handle of the TreeView item under which host controllers +// should be added. +// +//***************************************************************************** + +VOID +EnumerateHostController ( + HTREEITEM hTreeParent, + HANDLE hHCDev, _Inout_ PCHAR leafName, + _In_ HANDLE deviceInfo, + _In_ PSP_DEVINFO_DATA deviceInfoData +) +{ + PCHAR driverKeyName = NULL; + HTREEITEM hHCItem = NULL; + PCHAR rootHubName = NULL; + PLIST_ENTRY listEntry = NULL; + PUSBHOSTCONTROLLERINFO hcInfo = NULL; + PUSBHOSTCONTROLLERINFO hcInfoInList = NULL; + DWORD dwSuccess; + BOOL success = FALSE; + ULONG deviceAndFunction = 0; + PUSB_DEVICE_PNP_STRINGS DevProps = NULL; + + + // Allocate a structure to hold information about this host controller. + // + hcInfo = (PUSBHOSTCONTROLLERINFO)ALLOC(sizeof(USBHOSTCONTROLLERINFO)); + + // just return if could not alloc memory + if (NULL == hcInfo) + return; + + hcInfo->DeviceInfoType = HostControllerInfo; + + // Obtain the driver key name for this host controller. + // + driverKeyName = GetHCDDriverKeyName(hHCDev); + + if (NULL == driverKeyName) + { + // Failure obtaining driver key name. + OOPS(); + FREE(hcInfo); + return; + } + + // Don't enumerate this host controller again if it already + // on the list of enumerated host controllers. + // + listEntry = EnumeratedHCListHead.Flink; + + while (listEntry != &EnumeratedHCListHead) + { + hcInfoInList = CONTAINING_RECORD(listEntry, + USBHOSTCONTROLLERINFO, + ListEntry); + + if (strcmp(driverKeyName, hcInfoInList->DriverKey) == 0) + { + // Already on the list, exit + // + FREE(driverKeyName); + FREE(hcInfo); + return; + } + + listEntry = listEntry->Flink; + } + + // Obtain host controller device properties + { + size_t cbDriverName = 0; + HRESULT hr = S_OK; + + hr = StringCbLength(driverKeyName, MAX_DRIVER_KEY_NAME, &cbDriverName); + if (SUCCEEDED(hr)) + { + DevProps = DriverNameToDeviceProperties(driverKeyName, cbDriverName); + } + } + + hcInfo->DriverKey = driverKeyName; + + if (DevProps) + { + ULONG ven, dev, subsys, rev; + ven = dev = subsys = rev = 0; + + if (sscanf_s(DevProps->DeviceId, + "PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", + &ven, &dev, &subsys, &rev) != 4) + { + OOPS(); + } + + hcInfo->VendorID = ven; + hcInfo->DeviceID = dev; + hcInfo->SubSysID = subsys; + hcInfo->Revision = rev; + hcInfo->UsbDeviceProperties = DevProps; + } + else + { + OOPS(); + } + + if (DevProps != NULL && DevProps->DeviceDesc != NULL) + { + leafName = DevProps->DeviceDesc; + } + else + { + OOPS(); + } + + // Get the USB Host Controller power map + dwSuccess = GetHostControllerPowerMap(hHCDev, hcInfo); + + if (ERROR_SUCCESS != dwSuccess) + { + OOPS(); + } + + + // Get bus, device, and function + // + hcInfo->BusDeviceFunctionValid = FALSE; + + success = SetupDiGetDeviceRegistryProperty(deviceInfo, + deviceInfoData, + SPDRP_BUSNUMBER, + NULL, + (PBYTE)&hcInfo->BusNumber, + sizeof(hcInfo->BusNumber), + NULL); + + if (success) + { + success = SetupDiGetDeviceRegistryProperty(deviceInfo, + deviceInfoData, + SPDRP_ADDRESS, + NULL, + (PBYTE)&deviceAndFunction, + sizeof(deviceAndFunction), + NULL); + } + + if (success) + { + hcInfo->BusDevice = deviceAndFunction >> 16; + hcInfo->BusFunction = deviceAndFunction & 0xffff; + hcInfo->BusDeviceFunctionValid = TRUE; + } + + // Get the USB Host Controller info + dwSuccess = GetHostControllerInfo(hHCDev, hcInfo); + + if (ERROR_SUCCESS != dwSuccess) + { + OOPS(); + } + + // Add this host controller to the USB device tree view. + // + hHCItem = AddLeaf(hTreeParent, + (LPARAM)hcInfo, + leafName, + hcInfo->Revision == UsbSuperSpeed ? GoodSsDeviceIcon : GoodDeviceIcon); + + if (NULL == hHCItem) + { + // Failure adding host controller to USB device tree + // view. + + OOPS(); + FREE(driverKeyName); + FREE(hcInfo); + return; + } + + // Add this host controller to the list of enumerated + // host controllers. + // + InsertTailList(&EnumeratedHCListHead, + &hcInfo->ListEntry); + + // Get the name of the root hub for this host + // controller and then enumerate the root hub. + // + rootHubName = GetRootHubName(hHCDev); + + if (rootHubName != NULL) + { + size_t cbHubName = 0; + HRESULT hr = S_OK; + + hr = StringCbLength(rootHubName, MAX_DRIVER_KEY_NAME, &cbHubName); + if (SUCCEEDED(hr)) + { + EnumerateHub(hHCItem, + rootHubName, + cbHubName, + NULL, // ConnectionInfo + NULL, // ConnectionInfoV2 + NULL, // PortConnectorProps + NULL, // ConfigDesc + NULL, // BosDesc + NULL, // StringDescs + NULL); // We do not pass DevProps for RootHub + } + } + else + { + // Failure obtaining root hub name. + + OOPS(); + } + + return; +} + + +//***************************************************************************** +// +// EnumerateHub() +// +// hTreeParent - Handle of the TreeView item under which this hub should be +// added. +// +// HubName - Name of this hub. This pointer is kept so the caller can neither +// free nor reuse this memory. +// +// ConnectionInfo - NULL if this is a root hub, else this is the connection +// info for an external hub. This pointer is kept so the caller can neither +// free nor reuse this memory. +// +// ConfigDesc - NULL if this is a root hub, else this is the Configuration +// Descriptor for an external hub. This pointer is kept so the caller can +// neither free nor reuse this memory. +// +// StringDescs - NULL if this is a root hub. +// +// DevProps - Device properties of the hub +// +//***************************************************************************** + +VOID +EnumerateHub ( + HTREEITEM hTreeParent, + _In_reads_(cbHubName) PCHAR HubName, + _In_ size_t cbHubName, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo, + _In_opt_ PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2, + _In_opt_ PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps, + _In_opt_ PUSB_DESCRIPTOR_REQUEST ConfigDesc, + _In_opt_ PUSB_DESCRIPTOR_REQUEST BosDesc, + _In_opt_ PSTRING_DESCRIPTOR_NODE StringDescs, + _In_opt_ PUSB_DEVICE_PNP_STRINGS DevProps + ) +{ + // Initialize locals to not allocated state so the error cleanup routine + // only tries to cleanup things that were successfully allocated. + // + PUSB_NODE_INFORMATION hubInfo = NULL; + PUSB_HUB_INFORMATION_EX hubInfoEx = NULL; + PUSB_HUB_CAPABILITIES_EX hubCapabilityEx = NULL; + HANDLE hHubDevice = INVALID_HANDLE_VALUE; + HTREEITEM hItem = NULL; + PVOID info = NULL; + PCHAR deviceName = NULL; + ULONG nBytes = 0; + BOOL success = 0; + DWORD dwSizeOfLeafName = 0; + CHAR leafName[512] = {0}; + HRESULT hr = S_OK; + size_t cchHeader = 0; + size_t cchFullHubName = 0; + + // Allocate some space for a USBDEVICEINFO structure to hold the + // hub info, hub name, and connection info pointers. GPTR zero + // initializes the structure for us. + // + info = ALLOC(sizeof(USBEXTERNALHUBINFO)); + if (info == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + // Allocate some space for a USB_NODE_INFORMATION structure for this Hub + // + hubInfo = (PUSB_NODE_INFORMATION)ALLOC(sizeof(USB_NODE_INFORMATION)); + if (hubInfo == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + hubInfoEx = (PUSB_HUB_INFORMATION_EX)ALLOC(sizeof(USB_HUB_INFORMATION_EX)); + if (hubInfoEx == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + hubCapabilityEx = (PUSB_HUB_CAPABILITIES_EX)ALLOC(sizeof(USB_HUB_CAPABILITIES_EX)); + if(hubCapabilityEx == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + // Keep copies of the Hub Name, Connection Info, and Configuration + // Descriptor pointers + // + ((PUSBROOTHUBINFO)info)->HubInfo = hubInfo; + ((PUSBROOTHUBINFO)info)->HubName = HubName; + + if (ConnectionInfo != NULL) + { + ((PUSBEXTERNALHUBINFO)info)->DeviceInfoType = ExternalHubInfo; + ((PUSBEXTERNALHUBINFO)info)->ConnectionInfo = ConnectionInfo; + ((PUSBEXTERNALHUBINFO)info)->ConfigDesc = ConfigDesc; + ((PUSBEXTERNALHUBINFO)info)->StringDescs = StringDescs; + ((PUSBEXTERNALHUBINFO)info)->PortConnectorProps = PortConnectorProps; + ((PUSBEXTERNALHUBINFO)info)->HubInfoEx = hubInfoEx; + ((PUSBEXTERNALHUBINFO)info)->HubCapabilityEx = hubCapabilityEx; + ((PUSBEXTERNALHUBINFO)info)->BosDesc = BosDesc; + ((PUSBEXTERNALHUBINFO)info)->ConnectionInfoV2 = ConnectionInfoV2; + ((PUSBEXTERNALHUBINFO)info)->UsbDeviceProperties = DevProps; + } + else + { + ((PUSBROOTHUBINFO)info)->DeviceInfoType = RootHubInfo; + ((PUSBROOTHUBINFO)info)->HubInfoEx = hubInfoEx; + ((PUSBROOTHUBINFO)info)->HubCapabilityEx = hubCapabilityEx; + ((PUSBROOTHUBINFO)info)->PortConnectorProps = PortConnectorProps; + ((PUSBROOTHUBINFO)info)->UsbDeviceProperties = DevProps; + } + + // Allocate a temp buffer for the full hub device name. + // + hr = StringCbLength("\\\\.\\", MAX_DEVICE_PROP, &cchHeader); + if (FAILED(hr)) + { + goto EnumerateHubError; + } + cchFullHubName = cchHeader + cbHubName + 1; + deviceName = (PCHAR)ALLOC((DWORD) cchFullHubName); + if (deviceName == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + // Create the full hub device name + // + hr = StringCchCopyN(deviceName, cchFullHubName, "\\\\.\\", cchHeader); + if (FAILED(hr)) + { + goto EnumerateHubError; + } + hr = StringCchCatN(deviceName, cchFullHubName, HubName, cbHubName); + if (FAILED(hr)) + { + goto EnumerateHubError; + } + + // Try to hub the open device + // + hHubDevice = CreateFile(deviceName, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL); + + // Done with temp buffer for full hub device name + // + FREE(deviceName); + + if (hHubDevice == INVALID_HANDLE_VALUE) + { + OOPS(); + goto EnumerateHubError; + } + + // + // Now query USBHUB for the USB_NODE_INFORMATION structure for this hub. + // This will tell us the number of downstream ports to enumerate, among + // other things. + // + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_NODE_INFORMATION, + hubInfo, + sizeof(USB_NODE_INFORMATION), + hubInfo, + sizeof(USB_NODE_INFORMATION), + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto EnumerateHubError; + } + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_HUB_INFORMATION_EX, + hubInfoEx, + sizeof(USB_HUB_INFORMATION_EX), + hubInfoEx, + sizeof(USB_HUB_INFORMATION_EX), + &nBytes, + NULL); + + // + // Fail gracefully for downlevel OS's from Win8 + // + if (!success || nBytes < sizeof(USB_HUB_INFORMATION_EX)) + { + FREE(hubInfoEx); + hubInfoEx = NULL; + if (ConnectionInfo != NULL) + { + ((PUSBEXTERNALHUBINFO)info)->HubInfoEx = NULL; + } + else + { + ((PUSBROOTHUBINFO)info)->HubInfoEx = NULL; + } + } + + // + // Obtain Hub Capabilities + // + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_HUB_CAPABILITIES_EX, + hubCapabilityEx, + sizeof(USB_HUB_CAPABILITIES_EX), + hubCapabilityEx, + sizeof(USB_HUB_CAPABILITIES_EX), + &nBytes, + NULL); + + // + // Fail gracefully + // + if (!success || nBytes < sizeof(USB_HUB_CAPABILITIES_EX)) + { + FREE(hubCapabilityEx); + hubCapabilityEx = NULL; + if (ConnectionInfo != NULL) + { + ((PUSBEXTERNALHUBINFO)info)->HubCapabilityEx = NULL; + } + else + { + ((PUSBROOTHUBINFO)info)->HubCapabilityEx = NULL; + } + } + + // Build the leaf name from the port number and the device description + // + dwSizeOfLeafName = sizeof(leafName); + if (ConnectionInfo) + { + StringCchPrintf(leafName, dwSizeOfLeafName, "[Port%d] ", ConnectionInfo->ConnectionIndex); + StringCchCat(leafName, + dwSizeOfLeafName, + ConnectionStatuses[ConnectionInfo->ConnectionStatus]); + StringCchCatN(leafName, + dwSizeOfLeafName, + " : ", + sizeof(" : ")); + } + + if (DevProps) + { + size_t cbDeviceDesc = 0; + hr = StringCbLength(DevProps->DeviceDesc, MAX_DRIVER_KEY_NAME, &cbDeviceDesc); + if(SUCCEEDED(hr)) + { + StringCchCatN(leafName, + dwSizeOfLeafName, + DevProps->DeviceDesc, + cbDeviceDesc); + } + } + else + { + if(ConnectionInfo != NULL) + { + // External hub + StringCchCatN(leafName, + dwSizeOfLeafName, + HubName, + cbHubName); + } + else + { + // Root hub + StringCchCatN(leafName, + dwSizeOfLeafName, + "RootHub", + sizeof("RootHub")); + } + } + + // Now add an item to the TreeView with the PUSBDEVICEINFO pointer info + // as the LPARAM reference value containing everything we know about the + // hub. + // + hItem = AddLeaf(hTreeParent, + (LPARAM)info, + leafName, + HubIcon); + + if (hItem == NULL) + { + OOPS(); + goto EnumerateHubError; + } + + // Now recursively enumerate the ports of this hub. + // + EnumerateHubPorts( + hItem, + hHubDevice, + hubInfo->u.HubInformation.HubDescriptor.bNumberOfPorts + ); + + + CloseHandle(hHubDevice); + return; + +EnumerateHubError: + // + // Clean up any stuff that got allocated + // + + if (hHubDevice != INVALID_HANDLE_VALUE) + { + CloseHandle(hHubDevice); + hHubDevice = INVALID_HANDLE_VALUE; + } + + if (hubInfo) + { + FREE(hubInfo); + } + + if (hubInfoEx) + { + FREE(hubInfoEx); + } + + if (info) + { + FREE(info); + } + + if (HubName) + { + FREE(HubName); + } + + if (ConnectionInfo) + { + FREE(ConnectionInfo); + } + + if (ConfigDesc) + { + FREE(ConfigDesc); + } + + if (BosDesc) + { + FREE(BosDesc); + } + + if (StringDescs != NULL) + { + PSTRING_DESCRIPTOR_NODE Next; + + do { + + Next = StringDescs->Next; + FREE(StringDescs); + StringDescs = Next; + + } while (StringDescs != NULL); + } +} + +//***************************************************************************** +// +// EnumerateHubPorts() +// +// hTreeParent - Handle of the TreeView item under which the hub port should +// be added. +// +// hHubDevice - Handle of the hub device to enumerate. +// +// NumPorts - Number of ports on the hub. +// +//***************************************************************************** + +VOID +EnumerateHubPorts ( + HTREEITEM hTreeParent, + HANDLE hHubDevice, + ULONG NumPorts +) +{ + ULONG index = 0; + BOOL success = 0; + HRESULT hr = S_OK; + PCHAR driverKeyName = NULL; + PUSB_DEVICE_PNP_STRINGS DevProps; + DWORD dwSizeOfLeafName = 0; + CHAR leafName[512]; + int icon = 0; + + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfoEx; + PUSB_PORT_CONNECTOR_PROPERTIES pPortConnectorProps; + USB_PORT_CONNECTOR_PROPERTIES portConnectorProps; + PUSB_DESCRIPTOR_REQUEST configDesc; + PUSB_DESCRIPTOR_REQUEST bosDesc; + PSTRING_DESCRIPTOR_NODE stringDescs; + PUSBDEVICEINFO info; + PUSB_NODE_CONNECTION_INFORMATION_EX_V2 connectionInfoExV2; + PDEVICE_INFO_NODE pNode; + + // Loop over all ports of the hub. + // + // Port indices are 1 based, not 0 based. + // + for (index = 1; index <= NumPorts; index++) + { + ULONG nBytesEx; + ULONG nBytes = 0; + + connectionInfoEx = NULL; + pPortConnectorProps = NULL; + ZeroMemory(&portConnectorProps, sizeof(portConnectorProps)); + configDesc = NULL; + bosDesc = NULL; + stringDescs = NULL; + info = NULL; + connectionInfoExV2 = NULL; + pNode = NULL; + DevProps = NULL; + ZeroMemory(leafName, sizeof(leafName)); + + // + // Allocate space to hold the connection info for this port. + // For now, allocate it big enough to hold info for 30 pipes. + // + // Endpoint numbers are 0-15. Endpoint number 0 is the standard + // control endpoint which is not explicitly listed in the Configuration + // Descriptor. There can be an IN endpoint and an OUT endpoint at + // endpoint numbers 1-15 so there can be a maximum of 30 endpoints + // per device configuration. + // + // Should probably size this dynamically at some point. + // + + nBytesEx = sizeof(USB_NODE_CONNECTION_INFORMATION_EX) + + (sizeof(USB_PIPE_INFO) * 30); + + connectionInfoEx = (PUSB_NODE_CONNECTION_INFORMATION_EX)ALLOC(nBytesEx); + + if (connectionInfoEx == NULL) + { + OOPS(); + break; + } + + connectionInfoExV2 = (PUSB_NODE_CONNECTION_INFORMATION_EX_V2) + ALLOC(sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2)); + + if (connectionInfoExV2 == NULL) + { + OOPS(); + FREE(connectionInfoEx); + break; + } + + // + // Now query USBHUB for the structures + // for this port. This will tell us if a device is attached to this + // port, among other things. + // The fault tolerate code is executed first. + // + + portConnectorProps.ConnectionIndex = index; + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_PORT_CONNECTOR_PROPERTIES, + &portConnectorProps, + sizeof(USB_PORT_CONNECTOR_PROPERTIES), + &portConnectorProps, + sizeof(USB_PORT_CONNECTOR_PROPERTIES), + &nBytes, + NULL); + + if (success && nBytes == sizeof(USB_PORT_CONNECTOR_PROPERTIES)) + { + pPortConnectorProps = (PUSB_PORT_CONNECTOR_PROPERTIES) + ALLOC(portConnectorProps.ActualLength); + + if (pPortConnectorProps != NULL) + { + pPortConnectorProps->ConnectionIndex = index; + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_PORT_CONNECTOR_PROPERTIES, + pPortConnectorProps, + portConnectorProps.ActualLength, + pPortConnectorProps, + portConnectorProps.ActualLength, + &nBytes, + NULL); + + if (!success || nBytes < portConnectorProps.ActualLength) + { + FREE(pPortConnectorProps); + pPortConnectorProps = NULL; + } + } + } + + connectionInfoExV2->ConnectionIndex = index; + connectionInfoExV2->Length = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2); + connectionInfoExV2->SupportedUsbProtocols.Usb300 = 1; + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, + connectionInfoExV2, + sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2), + connectionInfoExV2, + sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2), + &nBytes, + NULL); + + if (!success || nBytes < sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2)) + { + FREE(connectionInfoExV2); + connectionInfoExV2 = NULL; + } + + connectionInfoEx->ConnectionIndex = index; + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, + connectionInfoEx, + nBytesEx, + connectionInfoEx, + nBytesEx, + &nBytesEx, + NULL); + + if (success) + { + // + // Since the USB_NODE_CONNECTION_INFORMATION_EX is used to display + // the device speed, but the hub driver doesn't support indication + // of superspeed, we overwrite the value if the super speed + // data structures are available and indicate the device is operating + // at SuperSpeed. + // + + if (connectionInfoEx->Speed == UsbHighSpeed + && connectionInfoExV2 != NULL + && (connectionInfoExV2->Flags.DeviceIsOperatingAtSuperSpeedOrHigher || + connectionInfoExV2->Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher)) + { + connectionInfoEx->Speed = UsbSuperSpeed; + } + } + else + { + PUSB_NODE_CONNECTION_INFORMATION connectionInfo = NULL; + + // Try using IOCTL_USB_GET_NODE_CONNECTION_INFORMATION + // instead of IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX + // + + nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION) + + sizeof(USB_PIPE_INFO) * 30; + + connectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)ALLOC(nBytes); + + if (connectionInfo == NULL) + { + OOPS(); + + FREE(connectionInfoEx); + if (pPortConnectorProps != NULL) + { + FREE(pPortConnectorProps); + } + if (connectionInfoExV2 != NULL) + { + FREE(connectionInfoExV2); + } + continue; + } + + connectionInfo->ConnectionIndex = index; + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, + connectionInfo, + nBytes, + connectionInfo, + nBytes, + &nBytes, + NULL); + + if (!success) + { + OOPS(); + + FREE(connectionInfo); + FREE(connectionInfoEx); + if (pPortConnectorProps != NULL) + { + FREE(pPortConnectorProps); + } + if (connectionInfoExV2 != NULL) + { + FREE(connectionInfoExV2); + } + continue; + } + + // Copy IOCTL_USB_GET_NODE_CONNECTION_INFORMATION into + // IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX structure. + // + connectionInfoEx->ConnectionIndex = connectionInfo->ConnectionIndex; + connectionInfoEx->DeviceDescriptor = connectionInfo->DeviceDescriptor; + connectionInfoEx->CurrentConfigurationValue = connectionInfo->CurrentConfigurationValue; + connectionInfoEx->Speed = connectionInfo->LowSpeed ? UsbLowSpeed : UsbFullSpeed; + connectionInfoEx->DeviceIsHub = connectionInfo->DeviceIsHub; + connectionInfoEx->DeviceAddress = connectionInfo->DeviceAddress; + connectionInfoEx->NumberOfOpenPipes = connectionInfo->NumberOfOpenPipes; + connectionInfoEx->ConnectionStatus = connectionInfo->ConnectionStatus; + + memcpy(&connectionInfoEx->PipeList[0], + &connectionInfo->PipeList[0], + sizeof(USB_PIPE_INFO) * 30); + + FREE(connectionInfo); + } + + // Update the count of connected devices + // + if (connectionInfoEx->ConnectionStatus == DeviceConnected) + { + TotalDevicesConnected++; + } + + if (connectionInfoEx->DeviceIsHub) + { + TotalHubs++; + } + + // If there is a device connected, get the Device Description + // + if (connectionInfoEx->ConnectionStatus != NoDeviceConnected) + { + driverKeyName = GetDriverKeyName(hHubDevice, index); + + if (driverKeyName) + { + size_t cbDriverName = 0; + + hr = StringCbLength(driverKeyName, MAX_DRIVER_KEY_NAME, &cbDriverName); + if (SUCCEEDED(hr)) + { + DevProps = DriverNameToDeviceProperties(driverKeyName, cbDriverName); + pNode = FindMatchingDeviceNodeForDriverName(driverKeyName, connectionInfoEx->DeviceIsHub); + } + FREE(driverKeyName); + } + + } + + // If there is a device connected to the port, try to retrieve the + // Configuration Descriptor from the device. + // + if (gDoConfigDesc && + connectionInfoEx->ConnectionStatus == DeviceConnected) + { + configDesc = GetConfigDescriptor(hHubDevice, + index, + 0); + } + else + { + configDesc = NULL; + } + + if (configDesc != NULL && + connectionInfoEx->DeviceDescriptor.bcdUSB >= 0x0210) + { + bosDesc = GetBOSDescriptor(hHubDevice, + index); + } + else + { + bosDesc = NULL; + } + + if (configDesc != NULL && + AreThereStringDescriptors(&connectionInfoEx->DeviceDescriptor, + (PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1))) + { + stringDescs = GetAllStringDescriptors ( + hHubDevice, + index, + &connectionInfoEx->DeviceDescriptor, + (PUSB_CONFIGURATION_DESCRIPTOR)(configDesc+1)); + } + else + { + stringDescs = NULL; + } + + // If the device connected to the port is an external hub, get the + // name of the external hub and recursively enumerate it. + // + if (connectionInfoEx->DeviceIsHub) + { + PCHAR extHubName; + size_t cbHubName = 0; + + extHubName = GetExternalHubName(hHubDevice, index); + if (extHubName != NULL) + { + hr = StringCbLength(extHubName, MAX_DRIVER_KEY_NAME, &cbHubName); + if (SUCCEEDED(hr)) + { + EnumerateHub(hTreeParent, //hPortItem, + extHubName, + cbHubName, + connectionInfoEx, + connectionInfoExV2, + pPortConnectorProps, + configDesc, + bosDesc, + stringDescs, + DevProps); + } + } + } + else + { + // Allocate some space for a USBDEVICEINFO structure to hold the + // hub info, hub name, and connection info pointers. GPTR zero + // initializes the structure for us. + // + info = (PUSBDEVICEINFO) ALLOC(sizeof(USBDEVICEINFO)); + + if (info == NULL) + { + OOPS(); + if (configDesc != NULL) + { + FREE(configDesc); + } + if (bosDesc != NULL) + { + FREE(bosDesc); + } + FREE(connectionInfoEx); + + if (pPortConnectorProps != NULL) + { + FREE(pPortConnectorProps); + } + if (connectionInfoExV2 != NULL) + { + FREE(connectionInfoExV2); + } + break; + } + + info->DeviceInfoType = DeviceInfo; + info->ConnectionInfo = connectionInfoEx; + info->PortConnectorProps = pPortConnectorProps; + info->ConfigDesc = configDesc; + info->StringDescs = stringDescs; + info->BosDesc = bosDesc; + info->ConnectionInfoV2 = connectionInfoExV2; + info->UsbDeviceProperties = DevProps; + info->DeviceInfoNode = pNode; + + StringCchPrintf(leafName, sizeof(leafName), "[Port%d] ", index); + + // Add error description if ConnectionStatus is other than NoDeviceConnected / DeviceConnected + StringCchCat(leafName, + sizeof(leafName), + ConnectionStatuses[connectionInfoEx->ConnectionStatus]); + + if (DevProps) + { + size_t cchDeviceDesc = 0; + + hr = StringCbLength(DevProps->DeviceDesc, MAX_DEVICE_PROP, &cchDeviceDesc); + if (FAILED(hr)) + { + OOPS(); + } + dwSizeOfLeafName = sizeof(leafName); + StringCchCatN(leafName, + dwSizeOfLeafName - 1, + " : ", + sizeof(" : ")); + StringCchCatN(leafName, + dwSizeOfLeafName - 1, + DevProps->DeviceDesc, + cchDeviceDesc ); + } + + if (connectionInfoEx->ConnectionStatus == NoDeviceConnected) + { + if (connectionInfoExV2 != NULL && + connectionInfoExV2->SupportedUsbProtocols.Usb300 == 1) + { + icon = NoSsDeviceIcon; + } + else + { + icon = NoDeviceIcon; + } + } + else if (connectionInfoEx->CurrentConfigurationValue) + { + if (connectionInfoEx->Speed == UsbSuperSpeed) + { + icon = GoodSsDeviceIcon; + } + else + { + icon = GoodDeviceIcon; + } + } + else + { + icon = BadDeviceIcon; + } + + AddLeaf(hTreeParent, //hPortItem, + (LPARAM)info, + leafName, + icon); + } + } // for +} + + +//***************************************************************************** +// +// WideStrToMultiStr() +// +//***************************************************************************** + +PCHAR WideStrToMultiStr ( + _In_reads_bytes_(cbWideStr) PWCHAR WideStr, + _In_ size_t cbWideStr + ) +{ + ULONG nBytes = 0; + PCHAR MultiStr = NULL; + PWCHAR pWideStr = NULL; + + // Use local string to guarantee zero termination + pWideStr = (PWCHAR) ALLOC((DWORD) cbWideStr + sizeof(WCHAR)); + if (NULL == pWideStr) + { + return NULL; + } + memset(pWideStr, 0, cbWideStr + sizeof(WCHAR)); + memcpy(pWideStr, WideStr, cbWideStr); + + // Get the length of the converted string + // + nBytes = WideCharToMultiByte( + CP_ACP, + WC_NO_BEST_FIT_CHARS, + pWideStr, + -1, + NULL, + 0, + NULL, + NULL); + + if (nBytes == 0) + { + FREE(pWideStr); + return NULL; + } + + // Allocate space to hold the converted string + // + MultiStr = ALLOC(nBytes); + if (MultiStr == NULL) + { + FREE(pWideStr); + return NULL; + } + + // Convert the string + // + nBytes = WideCharToMultiByte( + CP_ACP, + WC_NO_BEST_FIT_CHARS, + pWideStr, + -1, + MultiStr, + nBytes, + NULL, + NULL); + + if (nBytes == 0) + { + FREE(MultiStr); + FREE(pWideStr); + return NULL; + } + + FREE(pWideStr); + return MultiStr; +} + +//***************************************************************************** +// +// GetRootHubName() +// +//***************************************************************************** + +PCHAR GetRootHubName ( + HANDLE HostController +) +{ + BOOL success = 0; + ULONG nBytes = 0; + USB_ROOT_HUB_NAME rootHubName; + PUSB_ROOT_HUB_NAME rootHubNameW = NULL; + PCHAR rootHubNameA = NULL; + + // Get the length of the name of the Root Hub attached to the + // Host Controller + // + success = DeviceIoControl(HostController, + IOCTL_USB_GET_ROOT_HUB_NAME, + 0, + 0, + &rootHubName, + sizeof(rootHubName), + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetRootHubNameError; + } + + // Allocate space to hold the Root Hub name + // + nBytes = rootHubName.ActualLength; + + rootHubNameW = ALLOC(nBytes); + if (rootHubNameW == NULL) + { + OOPS(); + goto GetRootHubNameError; + } + + // Get the name of the Root Hub attached to the Host Controller + // + success = DeviceIoControl(HostController, + IOCTL_USB_GET_ROOT_HUB_NAME, + NULL, + 0, + rootHubNameW, + nBytes, + &nBytes, + NULL); + if (!success) + { + OOPS(); + goto GetRootHubNameError; + } + + // Convert the Root Hub name + // + rootHubNameA = WideStrToMultiStr(rootHubNameW->RootHubName, nBytes - sizeof(USB_ROOT_HUB_NAME) + sizeof(WCHAR)); + + // All done, free the uncoverted Root Hub name and return the + // converted Root Hub name + // + FREE(rootHubNameW); + + return rootHubNameA; + +GetRootHubNameError: + // There was an error, free anything that was allocated + // + if (rootHubNameW != NULL) + { + FREE(rootHubNameW); + rootHubNameW = NULL; + } + return NULL; +} + + +//***************************************************************************** +// +// GetExternalHubName() +// +//***************************************************************************** + +PCHAR GetExternalHubName ( + HANDLE Hub, + ULONG ConnectionIndex +) +{ + BOOL success = 0; + ULONG nBytes = 0; + USB_NODE_CONNECTION_NAME extHubName; + PUSB_NODE_CONNECTION_NAME extHubNameW = NULL; + PCHAR extHubNameA = NULL; + + // Get the length of the name of the external hub attached to the + // specified port. + // + extHubName.ConnectionIndex = ConnectionIndex; + + success = DeviceIoControl(Hub, + IOCTL_USB_GET_NODE_CONNECTION_NAME, + &extHubName, + sizeof(extHubName), + &extHubName, + sizeof(extHubName), + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetExternalHubNameError; + } + + // Allocate space to hold the external hub name + // + nBytes = extHubName.ActualLength; + + if (nBytes <= sizeof(extHubName)) + { + OOPS(); + goto GetExternalHubNameError; + } + + extHubNameW = ALLOC(nBytes); + + if (extHubNameW == NULL) + { + OOPS(); + goto GetExternalHubNameError; + } + + // Get the name of the external hub attached to the specified port + // + extHubNameW->ConnectionIndex = ConnectionIndex; + + success = DeviceIoControl(Hub, + IOCTL_USB_GET_NODE_CONNECTION_NAME, + extHubNameW, + nBytes, + extHubNameW, + nBytes, + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetExternalHubNameError; + } + + // Convert the External Hub name + // + extHubNameA = WideStrToMultiStr(extHubNameW->NodeName, nBytes - sizeof(USB_NODE_CONNECTION_NAME) + sizeof(WCHAR)); + + // All done, free the uncoverted external hub name and return the + // converted external hub name + // + FREE(extHubNameW); + + return extHubNameA; + + +GetExternalHubNameError: + // There was an error, free anything that was allocated + // + if (extHubNameW != NULL) + { + FREE(extHubNameW); + extHubNameW = NULL; + } + + return NULL; +} + + +//***************************************************************************** +// +// GetDriverKeyName() +// +//***************************************************************************** + +PCHAR GetDriverKeyName ( + HANDLE Hub, + ULONG ConnectionIndex +) +{ + BOOL success = 0; + ULONG nBytes = 0; + USB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyName; + PUSB_NODE_CONNECTION_DRIVERKEY_NAME driverKeyNameW = NULL; + PCHAR driverKeyNameA = NULL; + + // Get the length of the name of the driver key of the device attached to + // the specified port. + // + driverKeyName.ConnectionIndex = ConnectionIndex; + + success = DeviceIoControl(Hub, + IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, + &driverKeyName, + sizeof(driverKeyName), + &driverKeyName, + sizeof(driverKeyName), + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetDriverKeyNameError; + } + + // Allocate space to hold the driver key name + // + nBytes = driverKeyName.ActualLength; + + if (nBytes <= sizeof(driverKeyName)) + { + OOPS(); + goto GetDriverKeyNameError; + } + + driverKeyNameW = ALLOC(nBytes); + if (driverKeyNameW == NULL) + { + OOPS(); + goto GetDriverKeyNameError; + } + + // Get the name of the driver key of the device attached to + // the specified port. + // + driverKeyNameW->ConnectionIndex = ConnectionIndex; + + success = DeviceIoControl(Hub, + IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, + driverKeyNameW, + nBytes, + driverKeyNameW, + nBytes, + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetDriverKeyNameError; + } + + // Convert the driver key name + // + driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName, nBytes - sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME) + sizeof(WCHAR)); + + // All done, free the uncoverted driver key name and return the + // converted driver key name + // + FREE(driverKeyNameW); + + return driverKeyNameA; + + +GetDriverKeyNameError: + // There was an error, free anything that was allocated + // + if (driverKeyNameW != NULL) + { + FREE(driverKeyNameW); + driverKeyNameW = NULL; + } + + return NULL; +} + + +//***************************************************************************** +// +// GetHCDDriverKeyName() +// +//***************************************************************************** + +PCHAR GetHCDDriverKeyName ( + HANDLE HCD +) +{ + BOOL success = 0; + ULONG nBytes = 0; + USB_HCD_DRIVERKEY_NAME driverKeyName = {0}; + PUSB_HCD_DRIVERKEY_NAME driverKeyNameW = NULL; + PCHAR driverKeyNameA = NULL; + + ZeroMemory(&driverKeyName, sizeof(driverKeyName)); + + // Get the length of the name of the driver key of the HCD + // + success = DeviceIoControl(HCD, + IOCTL_GET_HCD_DRIVERKEY_NAME, + &driverKeyName, + sizeof(driverKeyName), + &driverKeyName, + sizeof(driverKeyName), + &nBytes, + NULL); + + if (!success) + { + OOPS(); + goto GetHCDDriverKeyNameError; + } + + // Allocate space to hold the driver key name + // + nBytes = driverKeyName.ActualLength; + if (nBytes <= sizeof(driverKeyName)) + { + OOPS(); + goto GetHCDDriverKeyNameError; + } + + driverKeyNameW = ALLOC(nBytes); + if (driverKeyNameW == NULL) + { + OOPS(); + goto GetHCDDriverKeyNameError; + } + + // Get the name of the driver key of the device attached to + // the specified port. + // + + success = DeviceIoControl(HCD, + IOCTL_GET_HCD_DRIVERKEY_NAME, + driverKeyNameW, + nBytes, + driverKeyNameW, + nBytes, + &nBytes, + NULL); + if (!success) + { + OOPS(); + goto GetHCDDriverKeyNameError; + } + + // + // Convert the driver key name + // Pass the length of the DriverKeyName string + // + + driverKeyNameA = WideStrToMultiStr(driverKeyNameW->DriverKeyName, nBytes - sizeof(USB_HCD_DRIVERKEY_NAME) + sizeof(WCHAR)); + + // All done, free the uncoverted driver key name and return the + // converted driver key name + // + FREE(driverKeyNameW); + + return driverKeyNameA; + +GetHCDDriverKeyNameError: + // There was an error, free anything that was allocated + // + if (driverKeyNameW != NULL) + { + FREE(driverKeyNameW); + driverKeyNameW = NULL; + } + + return NULL; +} + + +//***************************************************************************** +// +// GetConfigDescriptor() +// +// hHubDevice - Handle of the hub device containing the port from which the +// Configuration Descriptor will be requested. +// +// ConnectionIndex - Identifies the port on the hub to which a device is +// attached from which the Configuration Descriptor will be requested. +// +// DescriptorIndex - Configuration Descriptor index, zero based. +// +//***************************************************************************** + +PUSB_DESCRIPTOR_REQUEST +GetConfigDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + UCHAR DescriptorIndex +) +{ + BOOL success = 0; + ULONG nBytes = 0; + ULONG nBytesReturned = 0; + + UCHAR configDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + + sizeof(USB_CONFIGURATION_DESCRIPTOR)]; + + PUSB_DESCRIPTOR_REQUEST configDescReq = NULL; + PUSB_CONFIGURATION_DESCRIPTOR configDesc = NULL; + + + // Request the Configuration Descriptor the first time using our + // local buffer, which is just big enough for the Cofiguration + // Descriptor itself. + // + nBytes = sizeof(configDescReqBuf); + + configDescReq = (PUSB_DESCRIPTOR_REQUEST)configDescReqBuf; + configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(configDescReq+1); + + // Zero fill the entire request structure + // + memset(configDescReq, 0, nBytes); + + // Indicate the port from which the descriptor will be requested + // + configDescReq->ConnectionIndex = ConnectionIndex; + + // + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + // + configDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) + | DescriptorIndex; + + configDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + // + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + configDescReq, + nBytes, + configDescReq, + nBytes, + &nBytesReturned, + NULL); + + if (!success) + { + OOPS(); + return NULL; + } + + if (nBytes != nBytesReturned) + { + OOPS(); + return NULL; + } + + if (configDesc->wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + OOPS(); + return NULL; + } + + // Now request the entire Configuration Descriptor using a dynamically + // allocated buffer which is sized big enough to hold the entire descriptor + // + nBytes = sizeof(USB_DESCRIPTOR_REQUEST) + configDesc->wTotalLength; + + configDescReq = (PUSB_DESCRIPTOR_REQUEST)ALLOC(nBytes); + + if (configDescReq == NULL) + { + OOPS(); + return NULL; + } + + configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)(configDescReq+1); + + // Indicate the port from which the descriptor will be requested + // + configDescReq->ConnectionIndex = ConnectionIndex; + + // + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + // + configDescReq->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) + | DescriptorIndex; + + configDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + // + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + configDescReq, + nBytes, + configDescReq, + nBytes, + &nBytesReturned, + NULL); + + if (!success) + { + OOPS(); + FREE(configDescReq); + return NULL; + } + + if (nBytes != nBytesReturned) + { + OOPS(); + FREE(configDescReq); + return NULL; + } + + if (configDesc->wTotalLength != (nBytes - sizeof(USB_DESCRIPTOR_REQUEST))) + { + OOPS(); + FREE(configDescReq); + return NULL; + } + + return configDescReq; +} + + + +//***************************************************************************** +// +// GetBOSDescriptor() +// +// hHubDevice - Handle of the hub device containing the port from which the +// Configuration Descriptor will be requested. +// +// ConnectionIndex - Identifies the port on the hub to which a device is +// attached from which the BOS Descriptor will be requested. +// +//***************************************************************************** + +PUSB_DESCRIPTOR_REQUEST +GetBOSDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex +) +{ + BOOL success = 0; + ULONG nBytes = 0; + ULONG nBytesReturned = 0; + + UCHAR bosDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + + sizeof(USB_BOS_DESCRIPTOR)]; + + PUSB_DESCRIPTOR_REQUEST bosDescReq = NULL; + PUSB_BOS_DESCRIPTOR bosDesc = NULL; + + + // Request the BOS Descriptor the first time using our + // local buffer, which is just big enough for the BOS + // Descriptor itself. + // + nBytes = sizeof(bosDescReqBuf); + + bosDescReq = (PUSB_DESCRIPTOR_REQUEST)bosDescReqBuf; + bosDesc = (PUSB_BOS_DESCRIPTOR)(bosDescReq+1); + + // Zero fill the entire request structure + // + memset(bosDescReq, 0, nBytes); + + // Indicate the port from which the descriptor will be requested + // + bosDescReq->ConnectionIndex = ConnectionIndex; + + // + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + // + bosDescReq->SetupPacket.wValue = (USB_BOS_DESCRIPTOR_TYPE << 8); + + bosDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + // + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + bosDescReq, + nBytes, + bosDescReq, + nBytes, + &nBytesReturned, + NULL); + + if (!success) + { + OOPS(); + return NULL; + } + + if (nBytes != nBytesReturned) + { + OOPS(); + return NULL; + } + + if (bosDesc->wTotalLength < sizeof(USB_BOS_DESCRIPTOR)) + { + OOPS(); + return NULL; + } + + // Now request the entire BOS Descriptor using a dynamically + // allocated buffer which is sized big enough to hold the entire descriptor + // + nBytes = sizeof(USB_DESCRIPTOR_REQUEST) + bosDesc->wTotalLength; + + bosDescReq = (PUSB_DESCRIPTOR_REQUEST)ALLOC(nBytes); + + if (bosDescReq == NULL) + { + OOPS(); + return NULL; + } + + bosDesc = (PUSB_BOS_DESCRIPTOR)(bosDescReq+1); + + // Indicate the port from which the descriptor will be requested + // + bosDescReq->ConnectionIndex = ConnectionIndex; + + // + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + // + bosDescReq->SetupPacket.wValue = (USB_BOS_DESCRIPTOR_TYPE << 8); + + bosDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + // + + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + bosDescReq, + nBytes, + bosDescReq, + nBytes, + &nBytesReturned, + NULL); + + if (!success) + { + OOPS(); + FREE(bosDescReq); + return NULL; + } + + if (nBytes != nBytesReturned) + { + OOPS(); + FREE(bosDescReq); + return NULL; + } + + if (bosDesc->wTotalLength != (nBytes - sizeof(USB_DESCRIPTOR_REQUEST))) + { + OOPS(); + FREE(bosDescReq); + return NULL; + } + + return bosDescReq; +} + + +//***************************************************************************** +// +// AreThereStringDescriptors() +// +// DeviceDesc - Device Descriptor for which String Descriptors should be +// checked. +// +// ConfigDesc - Configuration Descriptor (also containing Interface Descriptor) +// for which String Descriptors should be checked. +// +//***************************************************************************** + +BOOL +AreThereStringDescriptors ( + PUSB_DEVICE_DESCRIPTOR DeviceDesc, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc +) +{ + PUCHAR descEnd = NULL; + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + + // + // Check Device Descriptor strings + // + + if (DeviceDesc->iManufacturer || + DeviceDesc->iProduct || + DeviceDesc->iSerialNumber + ) + { + return TRUE; + } + + + // + // Check the Configuration and Interface Descriptor strings + // + + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + switch (commonDesc->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + case USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + OOPS(); + break; + } + if (((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration) + { + return TRUE; + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + + case USB_INTERFACE_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR) && + commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2)) + { + OOPS(); + break; + } + if (((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface) + { + return TRUE; + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + + default: + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + } + break; + } + + return FALSE; +} + + +//***************************************************************************** +// +// GetAllStringDescriptors() +// +// hHubDevice - Handle of the hub device containing the port from which the +// String Descriptors will be requested. +// +// ConnectionIndex - Identifies the port on the hub to which a device is +// attached from which the String Descriptors will be requested. +// +// DeviceDesc - Device Descriptor for which String Descriptors should be +// requested. +// +// ConfigDesc - Configuration Descriptor (also containing Interface Descriptor) +// for which String Descriptors should be requested. +// +//***************************************************************************** + +PSTRING_DESCRIPTOR_NODE +GetAllStringDescriptors ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + PUSB_DEVICE_DESCRIPTOR DeviceDesc, + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc +) +{ + PSTRING_DESCRIPTOR_NODE supportedLanguagesString = NULL; + ULONG numLanguageIDs = 0; + USHORT *languageIDs = NULL; + + PUCHAR descEnd = NULL; + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + UCHAR uIndex = 1; + UCHAR bInterfaceClass = 0; + BOOL getMoreStrings = FALSE; + HRESULT hr = S_OK; + + // + // Get the array of supported Language IDs, which is returned + // in String Descriptor 0 + // + supportedLanguagesString = GetStringDescriptor(hHubDevice, + ConnectionIndex, + 0, + 0); + + if (supportedLanguagesString == NULL) + { + return NULL; + } + + numLanguageIDs = (supportedLanguagesString->StringDescriptor->bLength - 2) / 2; + + languageIDs = &supportedLanguagesString->StringDescriptor->bString[0]; + + // + // Get the Device Descriptor strings + // + + if (DeviceDesc->iManufacturer) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + DeviceDesc->iManufacturer, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + + if (DeviceDesc->iProduct) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + DeviceDesc->iProduct, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + + if (DeviceDesc->iSerialNumber) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + DeviceDesc->iSerialNumber, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + + // + // Get the Configuration and Interface Descriptor strings + // + + descEnd = (PUCHAR)ConfigDesc + ConfigDesc->wTotalLength; + + commonDesc = (PUSB_COMMON_DESCRIPTOR)ConfigDesc; + + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + switch (commonDesc->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + OOPS(); + break; + } + if (((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + ((PUSB_CONFIGURATION_DESCRIPTOR)commonDesc)->iConfiguration, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + + case USB_IAD_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_IAD_DESCRIPTOR)) + { + OOPS(); + break; + } + if (((PUSB_IAD_DESCRIPTOR)commonDesc)->iFunction) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + ((PUSB_IAD_DESCRIPTOR)commonDesc)->iFunction, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + + case USB_INTERFACE_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR) && + commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2)) + { + OOPS(); + break; + } + if (((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface) + { + GetStringDescriptors(hHubDevice, + ConnectionIndex, + ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->iInterface, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + + // + // We need to display more string descriptors for the following + // interface classes + // + bInterfaceClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceClass; + if (bInterfaceClass == USB_DEVICE_CLASS_VIDEO) + { + getMoreStrings = TRUE; + } + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + + default: + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + continue; + } + break; + } + + if (getMoreStrings) + { + // + // We might need to display strings later that are referenced only in + // class-specific descriptors. Get String Descriptors 1 through 32 (an + // arbitrary upper limit for Strings needed due to "bad devices" + // returning an infinite repeat of Strings 0 through 4) until one is not + // found. + // + // There are also "bad devices" that have issues even querying 1-32, but + // historically USBView made this query, so the query should be safe for + // video devices. + // + for (uIndex = 1; SUCCEEDED(hr) && (uIndex < NUM_STRING_DESC_TO_GET); uIndex++) + { + hr = GetStringDescriptors(hHubDevice, + ConnectionIndex, + uIndex, + numLanguageIDs, + languageIDs, + supportedLanguagesString); + } + } + + return supportedLanguagesString; +} + + + +//***************************************************************************** +// +// GetStringDescriptor() +// +// hHubDevice - Handle of the hub device containing the port from which the +// String Descriptor will be requested. +// +// ConnectionIndex - Identifies the port on the hub to which a device is +// attached from which the String Descriptor will be requested. +// +// DescriptorIndex - String Descriptor index. +// +// LanguageID - Language in which the string should be requested. +// +//***************************************************************************** + +PSTRING_DESCRIPTOR_NODE +GetStringDescriptor ( + HANDLE hHubDevice, + ULONG ConnectionIndex, + UCHAR DescriptorIndex, + USHORT LanguageID +) +{ + BOOL success = 0; + ULONG nBytes = 0; + ULONG nBytesReturned = 0; + + UCHAR stringDescReqBuf[sizeof(USB_DESCRIPTOR_REQUEST) + + MAXIMUM_USB_STRING_LENGTH]; + + PUSB_DESCRIPTOR_REQUEST stringDescReq = NULL; + PUSB_STRING_DESCRIPTOR stringDesc = NULL; + PSTRING_DESCRIPTOR_NODE stringDescNode = NULL; + + nBytes = sizeof(stringDescReqBuf); + + stringDescReq = (PUSB_DESCRIPTOR_REQUEST)stringDescReqBuf; + stringDesc = (PUSB_STRING_DESCRIPTOR)(stringDescReq+1); + + // Zero fill the entire request structure + // + memset(stringDescReq, 0, nBytes); + + // Indicate the port from which the descriptor will be requested + // + stringDescReq->ConnectionIndex = ConnectionIndex; + + // + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + // + stringDescReq->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) + | DescriptorIndex; + + stringDescReq->SetupPacket.wIndex = LanguageID; + + stringDescReq->SetupPacket.wLength = (USHORT)(nBytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + // + success = DeviceIoControl(hHubDevice, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + stringDescReq, + nBytes, + stringDescReq, + nBytes, + &nBytesReturned, + NULL); + + // + // Do some sanity checks on the return from the get descriptor request. + // + + if (!success) + { + OOPS(); + return NULL; + } + + if (nBytesReturned < 2) + { + OOPS(); + return NULL; + } + + if (stringDesc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE) + { + OOPS(); + return NULL; + } + + if (stringDesc->bLength != nBytesReturned - sizeof(USB_DESCRIPTOR_REQUEST)) + { + OOPS(); + return NULL; + } + + if (stringDesc->bLength % 2 != 0) + { + OOPS(); + return NULL; + } + + // + // Looks good, allocate some (zero filled) space for the string descriptor + // node and copy the string descriptor to it. + // + + stringDescNode = (PSTRING_DESCRIPTOR_NODE)ALLOC(sizeof(STRING_DESCRIPTOR_NODE) + + stringDesc->bLength); + + if (stringDescNode == NULL) + { + OOPS(); + return NULL; + } + + stringDescNode->DescriptorIndex = DescriptorIndex; + stringDescNode->LanguageID = LanguageID; + + memcpy(stringDescNode->StringDescriptor, + stringDesc, + stringDesc->bLength); + + return stringDescNode; +} + + +//***************************************************************************** +// +// GetStringDescriptors() +// +// hHubDevice - Handle of the hub device containing the port from which the +// String Descriptor will be requested. +// +// ConnectionIndex - Identifies the port on the hub to which a device is +// attached from which the String Descriptor will be requested. +// +// DescriptorIndex - String Descriptor index. +// +// NumLanguageIDs - Number of languages in which the string should be +// requested. +// +// LanguageIDs - Languages in which the string should be requested. +// +// StringDescNodeHead - First node in linked list of device's string descriptors +// +// Return Value: HRESULT indicating whether the string is on the list +// +//***************************************************************************** + +HRESULT +GetStringDescriptors ( + _In_ HANDLE hHubDevice, + _In_ ULONG ConnectionIndex, + _In_ UCHAR DescriptorIndex, + _In_ ULONG NumLanguageIDs, + _In_reads_(NumLanguageIDs) USHORT *LanguageIDs, + _In_ PSTRING_DESCRIPTOR_NODE StringDescNodeHead +) +{ + PSTRING_DESCRIPTOR_NODE tail = NULL; + PSTRING_DESCRIPTOR_NODE trailing = NULL; + ULONG i = 0; + + // + // Go to the end of the linked list, searching for the requested index to + // see if we've already retrieved it + // + for (tail = StringDescNodeHead; tail != NULL; tail = tail->Next) + { + if (tail->DescriptorIndex == DescriptorIndex) + { + return S_OK; + } + + trailing = tail; + } + + tail = trailing; + + // + // Get the next String Descriptor. If this is NULL, then we're done (return) + // Otherwise, loop through all Language IDs + // + for (i = 0; (tail != NULL) && (i < NumLanguageIDs); i++) + { + tail->Next = GetStringDescriptor(hHubDevice, + ConnectionIndex, + DescriptorIndex, + LanguageIDs[i]); + + tail = tail->Next; + } + + if (tail == NULL) + { + return E_FAIL; + } else { + return S_OK; + } +} + + +//***************************************************************************** +// +// CleanupItem() +// +//***************************************************************************** + +VOID +CleanupItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext +) +{ + TV_ITEM tvi; + PVOID info = NULL; + + UNREFERENCED_PARAMETER(pContext); + + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hTreeItem; + + TreeView_GetItem(hTreeWnd, + &tvi); + + info = (PVOID)tvi.lParam; + + if (info) + { + PCHAR DriverKey = NULL; + PUSB_NODE_INFORMATION HubInfo = NULL; + PCHAR HubName = NULL; + PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfoEx = NULL; + PUSB_DESCRIPTOR_REQUEST ConfigDesc = NULL; + PUSB_DESCRIPTOR_REQUEST BosDesc = NULL; + PSTRING_DESCRIPTOR_NODE StringDescs = NULL; + PUSB_HUB_INFORMATION_EX HubInfoEx = NULL; + PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps = NULL; + PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2 = NULL; + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx = NULL; + PUSB_DEVICE_PNP_STRINGS UsbDeviceProperties = NULL; + PUSB_CONTROLLER_INFO_0 ControllerInfo = NULL; + + // + // All structures except DEVICE_INFO_NODE are free'd up here. DEVICE_INFO_NODE structures are free'd while + // destroying device info lists (ClearDeviceList()) + // + switch (*(PUSBDEVICEINFOTYPE)info) + { + case HostControllerInfo: + // + // Remove this host controller from the list of enumerated + // host controllers. + // + RemoveEntryList(&((PUSBHOSTCONTROLLERINFO)info)->ListEntry); + DriverKey = ((PUSBHOSTCONTROLLERINFO)info)->DriverKey; + ControllerInfo = ((PUSBHOSTCONTROLLERINFO)info)->ControllerInfo; + UsbDeviceProperties = ((PUSBHOSTCONTROLLERINFO)info)->UsbDeviceProperties; + break; + + case RootHubInfo: + HubInfo = ((PUSBROOTHUBINFO)info)->HubInfo; + HubInfoEx = ((PUSBROOTHUBINFO)info)->HubInfoEx; + HubName = ((PUSBROOTHUBINFO)info)->HubName; + PortConnectorProps = ((PUSBROOTHUBINFO)info)->PortConnectorProps; + UsbDeviceProperties = ((PUSBROOTHUBINFO)info)->UsbDeviceProperties; + HubCapabilityEx = ((PUSBROOTHUBINFO)info)->HubCapabilityEx; + break; + + case ExternalHubInfo: + HubInfo = ((PUSBEXTERNALHUBINFO)info)->HubInfo; + HubInfoEx = ((PUSBEXTERNALHUBINFO)info)->HubInfoEx; + HubName = ((PUSBEXTERNALHUBINFO)info)->HubName; + ConnectionInfoEx = ((PUSBEXTERNALHUBINFO)info)->ConnectionInfo; + PortConnectorProps = ((PUSBEXTERNALHUBINFO)info)->PortConnectorProps; + ConfigDesc = ((PUSBEXTERNALHUBINFO)info)->ConfigDesc; + BosDesc = ((PUSBEXTERNALHUBINFO)info)->BosDesc; + StringDescs = ((PUSBEXTERNALHUBINFO)info)->StringDescs; + ConnectionInfoV2 = ((PUSBEXTERNALHUBINFO)info)->ConnectionInfoV2; + UsbDeviceProperties = ((PUSBEXTERNALHUBINFO)info)->UsbDeviceProperties; + HubCapabilityEx = ((PUSBEXTERNALHUBINFO)info)->HubCapabilityEx; + break; + + case DeviceInfo: + ConnectionInfoEx = ((PUSBDEVICEINFO)info)->ConnectionInfo; + PortConnectorProps = ((PUSBDEVICEINFO)info)->PortConnectorProps; + ConfigDesc = ((PUSBDEVICEINFO)info)->ConfigDesc; + BosDesc = ((PUSBDEVICEINFO)info)->BosDesc; + StringDescs = ((PUSBDEVICEINFO)info)->StringDescs; + ConnectionInfoV2 = ((PUSBDEVICEINFO)info)->ConnectionInfoV2; + UsbDeviceProperties = ((PUSBDEVICEINFO)info)->UsbDeviceProperties; + break; + } + + if(UsbDeviceProperties) + { + FreeDeviceProperties(&UsbDeviceProperties); + } + + if(ControllerInfo) + { + FREE(ControllerInfo); + } + + if(HubCapabilityEx) + { + FREE(HubCapabilityEx); + } + + if (DriverKey) + { + FREE(DriverKey); + } + + if (HubInfo) + { + FREE(HubInfo); + } + + if (HubName) + { + FREE(HubName); + } + + if (ConfigDesc) + { + FREE(ConfigDesc); + } + + if (BosDesc) + { + FREE(BosDesc); + } + + if (StringDescs) + { + PSTRING_DESCRIPTOR_NODE Next; + + do { + + Next = StringDescs->Next; + FREE(StringDescs); + StringDescs = Next; + + } while (StringDescs); + } + + if (ConnectionInfoEx) + { + FREE(ConnectionInfoEx); + } + + if (HubInfoEx) + { + FREE(HubInfoEx); + } + + if (PortConnectorProps) + { + FREE(PortConnectorProps); + } + + if (ConnectionInfoV2) + { + FREE(ConnectionInfoV2); + } + + FREE(info); + } +} + +//***************************************************************************** +// +// GetHostControllerPowerMap() +// +// HANDLE hHCDev +// - handle to USB Host Controller +// +// PUSBHOSTCONTROLLERINFO hcInfo +// - data structure to receive the Power Map Info +// +// return DWORD dwError +// - return ERROR_SUCCESS or last error +// +//***************************************************************************** + +DWORD +GetHostControllerPowerMap( + HANDLE hHCDev, + PUSBHOSTCONTROLLERINFO hcInfo) +{ + USBUSER_POWER_INFO_REQUEST UsbPowerInfoRequest; + PUSB_POWER_INFO pUPI = &UsbPowerInfoRequest.PowerInformation ; + DWORD dwError = 0; + DWORD dwBytes = 0; + BOOL bSuccess = FALSE; + int nIndex = 0; + int nPowerState = WdmUsbPowerSystemWorking; + + for ( ; nPowerState <= WdmUsbPowerSystemShutdown; nIndex++, nPowerState++) + { + // zero initialize our request + memset(&UsbPowerInfoRequest, 0, sizeof(UsbPowerInfoRequest)); + + // set the header and request sizes + UsbPowerInfoRequest.Header.UsbUserRequest = USBUSER_GET_POWER_STATE_MAP; + UsbPowerInfoRequest.Header.RequestBufferLength = sizeof(UsbPowerInfoRequest); + UsbPowerInfoRequest.PowerInformation.SystemState = nPowerState; + + // + // Now query USBHUB for the USB_POWER_INFO structure for this hub. + // For Selective Suspend support + // + bSuccess = DeviceIoControl(hHCDev, + IOCTL_USB_USER_REQUEST, + &UsbPowerInfoRequest, + sizeof(UsbPowerInfoRequest), + &UsbPowerInfoRequest, + sizeof(UsbPowerInfoRequest), + &dwBytes, + NULL); + + if (!bSuccess) + { + dwError = GetLastError(); + OOPS(); + } + else + { + // copy the data into our USB Host Controller's info structure + memcpy( &(hcInfo->USBPowerInfo[nIndex]), pUPI, sizeof(USB_POWER_INFO)); + } + } + + return dwError; +} + +void +EnumerateAllDevices() +{ + EnumerateAllDevicesWithGuid(&gDeviceList, + (LPGUID)&GUID_DEVINTERFACE_USB_DEVICE); + + EnumerateAllDevicesWithGuid(&gHubList, + (LPGUID)&GUID_DEVINTERFACE_USB_HUB); +} + + +//***************************************************************************** +// +// GetHostControllerInfo() +// +// HANDLE hHCDev +// - handle to USB Host Controller +// +// PUSBHOSTCONTROLLERINFO hcInfo +// - data structure to receive the Power Map Info +// +// return DWORD dwError +// - return ERROR_SUCCESS or last error +// +//***************************************************************************** + +DWORD +GetHostControllerInfo( + HANDLE hHCDev, + PUSBHOSTCONTROLLERINFO hcInfo) +{ + USBUSER_CONTROLLER_INFO_0 UsbControllerInfo; + DWORD dwError = 0; + DWORD dwBytes = 0; + BOOL bSuccess = FALSE; + + memset(&UsbControllerInfo, 0, sizeof(UsbControllerInfo)); + + // set the header and request sizes + UsbControllerInfo.Header.UsbUserRequest = USBUSER_GET_CONTROLLER_INFO_0; + UsbControllerInfo.Header.RequestBufferLength = sizeof(UsbControllerInfo); + + // + // Query for the USB_CONTROLLER_INFO_0 structure + // + bSuccess = DeviceIoControl(hHCDev, + IOCTL_USB_USER_REQUEST, + &UsbControllerInfo, + sizeof(UsbControllerInfo), + &UsbControllerInfo, + sizeof(UsbControllerInfo), + &dwBytes, + NULL); + + if (!bSuccess) + { + dwError = GetLastError(); + OOPS(); + } + else + { + hcInfo->ControllerInfo = (PUSB_CONTROLLER_INFO_0) ALLOC(sizeof(USB_CONTROLLER_INFO_0)); + if(NULL == hcInfo->ControllerInfo) + { + dwError = GetLastError(); + OOPS(); + } + else + { + // copy the data into our USB Host Controller's info structure + memcpy(hcInfo->ControllerInfo, &UsbControllerInfo.Info0, sizeof(USB_CONTROLLER_INFO_0)); + } + } + return dwError; +} + +_Success_(return == TRUE) +BOOL +GetDeviceProperty( + _In_ HDEVINFO DeviceInfoSet, + _In_ PSP_DEVINFO_DATA DeviceInfoData, + _In_ DWORD Property, + _Outptr_ LPTSTR *ppBuffer + ) +{ + BOOL bResult; + DWORD requiredLength = 0; + DWORD lastError; + + if (ppBuffer == NULL) + { + return FALSE; + } + + *ppBuffer = NULL; + + bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet, + DeviceInfoData, + Property , + NULL, + NULL, + 0, + &requiredLength); + lastError = GetLastError(); + + if ((requiredLength == 0) || (bResult != FALSE && lastError != ERROR_INSUFFICIENT_BUFFER)) + { + return FALSE; + } + + *ppBuffer = ALLOC(requiredLength); + + if (*ppBuffer == NULL) + { + return FALSE; + } + + bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet, + DeviceInfoData, + Property , + NULL, + (PBYTE) *ppBuffer, + requiredLength, + &requiredLength); + if(bResult == FALSE) + { + FREE(*ppBuffer); + *ppBuffer = NULL; + return FALSE; + } + + return TRUE; +} + + +void +EnumerateAllDevicesWithGuid( + PDEVICE_GUID_LIST DeviceList, + LPGUID Guid + ) +{ + if (DeviceList->DeviceInfo != INVALID_HANDLE_VALUE) + { + ClearDeviceList(DeviceList); + } + + DeviceList->DeviceInfo = SetupDiGetClassDevs(Guid, + NULL, + NULL, + (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + if (DeviceList->DeviceInfo != INVALID_HANDLE_VALUE) + { + ULONG index; + DWORD error; + + error = 0; + index = 0; + + while (error != ERROR_NO_MORE_ITEMS) + { + BOOL success; + PDEVICE_INFO_NODE pNode; + + pNode = ALLOC(sizeof(DEVICE_INFO_NODE)); + if (pNode == NULL) + { + OOPS(); + break; + } + pNode->DeviceInfo = DeviceList->DeviceInfo; + pNode->DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + pNode->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + success = SetupDiEnumDeviceInfo(DeviceList->DeviceInfo, + index, + &pNode->DeviceInfoData); + + index++; + + if (success == FALSE) + { + error = GetLastError(); + + if (error != ERROR_NO_MORE_ITEMS) + { + OOPS(); + } + + FreeDeviceInfoNode(&pNode); + } + else + { + BOOL bResult; + ULONG requiredLength; + + bResult = GetDeviceProperty(DeviceList->DeviceInfo, + &pNode->DeviceInfoData, + SPDRP_DEVICEDESC, + &pNode->DeviceDescName); + if (bResult == FALSE) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + bResult = GetDeviceProperty(DeviceList->DeviceInfo, + &pNode->DeviceInfoData, + SPDRP_DRIVER, + &pNode->DeviceDriverName); + if (bResult == FALSE) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + pNode->DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + success = SetupDiEnumDeviceInterfaces(DeviceList->DeviceInfo, + 0, + Guid, + index-1, + &pNode->DeviceInterfaceData); + if (!success) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + success = SetupDiGetDeviceInterfaceDetail(DeviceList->DeviceInfo, + &pNode->DeviceInterfaceData, + NULL, + 0, + &requiredLength, + NULL); + + error = GetLastError(); + + if (!success && error != ERROR_INSUFFICIENT_BUFFER) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + pNode->DeviceDetailData = ALLOC(requiredLength); + + if (pNode->DeviceDetailData == NULL) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + pNode->DeviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + success = SetupDiGetDeviceInterfaceDetail(DeviceList->DeviceInfo, + &pNode->DeviceInterfaceData, + pNode->DeviceDetailData, + requiredLength, + &requiredLength, + NULL); + if (!success) + { + FreeDeviceInfoNode(&pNode); + OOPS(); + break; + } + + InsertTailList(&DeviceList->ListHead, &pNode->ListEntry); + } + } + } +} + +DEVICE_POWER_STATE +AcquireDevicePowerState( + _Inout_ PDEVICE_INFO_NODE pNode + ) +{ + CM_POWER_DATA cmPowerData = {0}; + BOOL bResult; + + bResult = SetupDiGetDeviceRegistryProperty(pNode->DeviceInfo, + &pNode->DeviceInfoData, + SPDRP_DEVICE_POWER_DATA, + NULL, + (PBYTE)&cmPowerData, + sizeof(cmPowerData), + NULL); + + pNode->LatestDevicePowerState = bResult ? cmPowerData.PD_MostRecentPowerState : PowerDeviceUnspecified; + + return pNode->LatestDevicePowerState; +} + + +void +ClearDeviceList( + PDEVICE_GUID_LIST DeviceList + ) +{ + if (DeviceList->DeviceInfo != INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(DeviceList->DeviceInfo); + DeviceList->DeviceInfo = INVALID_HANDLE_VALUE; + } + + while (!IsListEmpty(&DeviceList->ListHead)) + { + PDEVICE_INFO_NODE pNode = NULL; + PLIST_ENTRY pEntry; + + pEntry = RemoveHeadList(&DeviceList->ListHead); + + pNode = CONTAINING_RECORD(pEntry, + DEVICE_INFO_NODE, + ListEntry); + + FreeDeviceInfoNode(&pNode); + } +} + +VOID +FreeDeviceInfoNode( + _In_ PDEVICE_INFO_NODE *ppNode + ) +{ + if (ppNode == NULL) + { + return; + } + + if (*ppNode == NULL) + { + return; + } + + if ((*ppNode)->DeviceDetailData != NULL) + { + FREE((*ppNode)->DeviceDetailData); + } + + if ((*ppNode)->DeviceDescName != NULL) + { + FREE((*ppNode)->DeviceDescName); + } + + if ((*ppNode)->DeviceDriverName != NULL) + { + FREE((*ppNode)->DeviceDriverName); + } + + FREE(*ppNode); + *ppNode = NULL; +} + +PDEVICE_INFO_NODE +FindMatchingDeviceNodeForDriverName( + _In_ PSTR DriverKeyName, + _In_ BOOLEAN IsHub + ) +{ + PDEVICE_INFO_NODE pNode = NULL; + PDEVICE_GUID_LIST pList = NULL; + PLIST_ENTRY pEntry = NULL; + + pList = IsHub ? &gHubList : &gDeviceList; + + pEntry = pList->ListHead.Flink; + + while (pEntry != &pList->ListHead) + { + pNode = CONTAINING_RECORD(pEntry, + DEVICE_INFO_NODE, + ListEntry); + if (_stricmp(DriverKeyName, pNode->DeviceDriverName) == 0) + { + return pNode; + } + + pEntry = pEntry->Flink; + } + + return NULL; +} + diff --git a/usb/usbview/h264.c b/usb/usbview/h264.c new file mode 100644 index 00000000..da9e695b --- /dev/null +++ b/usb/usbview/h264.c @@ -0,0 +1,750 @@ +//***************************************************************************** +// I N C L U D E S +//***************************************************************************** + +#include "uvcview.h" +#include "h264.h" + +#ifdef H264_SUPPORT + +//***************************************************************************** +// G L O B A L S +//***************************************************************************** +// H.264 format +UCHAR g_expectedNumberOfH264FrameDescriptors = 0; +UCHAR g_numberOfH264FrameDescriptors = 0; + +// MJPEG format +UCHAR g_expectedNumberOfMJPEGFrameDescriptors = 0; +UCHAR g_numberOfMJPEGFrameDescriptors = 0; + +// Uncompressed frame format +UCHAR g_expectedNumberOfUncompressedFrameFrameDescriptors = 0; +UCHAR g_numberOfUncompressedFrameFrameDescriptors = 0; + +//***************************************************************************** +// +// external function prototypes +// +//***************************************************************************** +extern VOID VDisplayBytes (PUCHAR Data, USHORT Len ); + +//***************************************************************************** +// +// H.264 video format descriptor string tables +// +//***************************************************************************** +STRINGLIST slSliceModes[]= +{ + {1, "Maximum number of Macroblocks per slice mode", ""}, + {2, "Target compressed size per slice mode", ""}, + {4, "Number of slices per frame mode", ""}, + {8, "Number of Macroblock rows per slice mode", ""}, + {0x10, "Reserved", ""}, + {0x20, "Reserved", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + + +STRINGLIST slSyncFrameTypes[]= +{ + {1, "Reset" , ""}, + {2, "IDR frame with SPS and PPS", ""}, + {4, "IDR frame (with SPS and PPS) that is a long-term reference frame", ""}, + {8, "Non-IDR random-access I frame (with SPS and PPS)", ""}, + {0x10, "Non-IDR random-access I frame (with SPS and PPS) that is a long-term reference frame", ""}, + {0x20, "P frame that is a long-term reference frame", ""}, + {0x40, "Gradual Decoder Refresh frames", ""}, + {0x80, "Reserved", ""}, +}; + + +//***************************************************************************** +// +// H.264 video frame rate descriptor string tables +// +//***************************************************************************** +STRINGLIST slUsage[]= +{ + {0x00000001, "Real-time/UCConfig mode 0", ""}, // 0 + {0x00000002, "Real-time/UCConfig mode 1", ""}, + {0x00000004, "Real-time/UCConfig mode 2Q" ""}, + {0x00000008, "Real-time/UCConfig mode 2S" ""}, + {0x00000010, "Real-time/UCConfig mode 3", ""}, + {0x00000020, "Reserved", ""}, + {0x00000040, "Reserved", ""}, + {0x00000080, "Reserved", ""}, + + {0x00000100, "Broadcast mode 0", ""}, // 8 + {0x00000200, "Broadcast mode 1", ""}, + {0x00000400, "Broadcast mode 2", ""}, + {0x00000800, "Broadcast mode 3", ""}, + {0x00001000, "Broadcast mode 4", ""}, + {0x00002000, "Broadcast mode 5", ""}, + {0x00004000, "Broadcast mode 6", ""}, + {0x00008000, "Broadcast mode 7", ""}, + + {0x00010000, "File Storage mode with I and P slices (e.g. IPPP)", ""}, // 16 + {0x00020000, "File Storage mode with I, P, and B slices (e.g. IB...BP)", ""}, // 17 + {0x00040000, "File storage all I frame mode", ""}, // 18 + {0x00080000, "Reserved", ""}, // 19 + {0x00100000, "Reserved", ""}, // 20 + {0x00200000, "Reserved", ""}, // 21 + {0x00400000, "Reserved", ""}, // 22 + {0x00800000, "Reserved", ""}, // 23 + + {0x01000000, "MVC Stereo High Mode", ""}, // 24 + {0x02000000, "MVC Multiview Mode", ""}, // 25 + {0x04000000, "Reserved", ""}, // 26 + {0x08000000, "Reserved", ""}, // 27 + {0x10000000, "Reserved", ""}, // 28 + {0x20000000, "Reserved", ""}, // 29 + {0x40000000, "Reserved", ""}, // 30 + {0x80000000, "Reserved", ""}, // 31 + + }; +STRINGLIST slCapabilities[]= +{ + {0x0001, "CAVLC only", ""}, + {0x0002, "CABAC only", ""}, + {0x0004, "Constant frame rate", ""}, + {0x0008, "Separate QP for luma/chroma", ""}, + {0x0010, "Separate QP for Cb/Cr", ""}, + {0x0020, "No picture reordering", ""}, + {0x0040, "Long-term reference frame", ""}, + {0x0080, "Reserved", ""}, + {0x0100, "Reserved", ""}, + {0x0200, "Reserved", ""}, + {0x0400, "Reserved", ""}, + {0x0800, "Reserved", ""}, + {0x1000, "Reserved", ""}, + {0x2000, "Reserved", ""}, + {0x4000, "Reserved", ""}, + {0x8000, "Reserved", ""}, + }; + + + +STRINGLIST slRateControlModes[]= +{ + {1, "Variable Bit Rate (VBR) with underflow allowed (H.264 low_delay_hrd_flag = 1)", ""}, + {2, "Constant Bit Rate (CBR) (H.264 low_delay_hrd_flag = 0)", ""}, + {4, "Constant QP", ""}, + {8, "Global VBR with underflow allowed (H.264 low_delay_hrd_flag = 1)", ""}, + {0x10, "VBR without underflow (H.264 low_delay_hrd_flag = 0)", ""}, + {0x20, "Global VBR without underflow (H.264 low_delay_hrd_flag = 0)", ""}, + {0x40, "Reserved", ""}, + {0x80, "Reserved", ""}, +}; + + +STRINGLIST slProfiles[]= +{ + {0x4200, "Baseline Profile", ""}, + {0x4240, "Constrained Baseline Profile", ""}, + {0x4D00, "Main Profile", ""}, + {0x5300, "Scalable Baseline Profile", ""}, + {0x5304, "Scalable Constrained Baseline Profile", ""}, + {0x5600, "Scalable High Profile", ""}, + {0x5604, "Scalable Constrained High Profile", ""}, + {0x6400, "High Profile", ""}, + {0x640C, "Constrained High Profile", ""}, + {0x7600, "Multiview High Profile", ""}, + {0x8000, "Stereo High Profile", ""}, + }; + +//***************************************************************************** +// +// H.264 video encoding unit descriptor string tables +// +//***************************************************************************** + +STRINGLIST slEncodingUnitControls[]= +{ + {0x000001, "Select Layer", ""}, // D0 + {0x000002, "Profile and Toolset", ""}, // D1 + {0x000004, "Video Resolution", ""}, // D2 + {0x000008, "Minimum Frame Interval", ""}, // D3 + {0x000010, "Slice Mode", ""}, // D4 + {0x000020, "Rate Control Mode", ""}, // D5 + {0x000040, "Average Bit Rate", ""}, // D6 + {0x000080, "CPB Size ", ""}, // D7 + {0x000100, "Peak Bit Rate", ""}, // D8 + {0x000200, "Quantization Parameter", ""}, // D9 + {0x000400, "Synchronization and Long-Term Reference Frame", ""}, // D10 + {0x000800, "Long-Term Buffer Size", ""}, // D11 + {0x001000, "Picture Long-Term Reference", ""}, // D12 + {0x002000, "Valid LTR", ""}, // D13 + {0x004000, "Level IDC", ""}, // D14 + {0x008000, "SEI Message", ""}, // D15 + {0x010000, "QP Range", ""}, // D16 + {0x020000, "Priority ID", ""}, // D17 + {0x040000, "Start or Stop Layer/View", ""}, // D18 + {0x080000, "Error Resiliency", ""}, // D19 + {0x100000, "Reserved", ""}, // D20 + {0x200000, "Reserved", ""}, // D21 + {0x400000, "Reserved", ""}, // D22 + {0x800000, "Reserved", ""}, // D23 + }; + +//***************************************************************************** +// +// commaPrintNumber() +// +//***************************************************************************** +char * commaPrintNumber( ULONG number ) +{ + static char comma = ','; + static char retbuf[30]; + int digitCount = 0; + + // null-terminate the string + char * pOutputString = &retbuf[ sizeof(retbuf)-1 ]; + *pOutputString = '\0'; + + do + { + // for every 3rd digit, add a comma to the output string + if ( ( digitCount%3 ) == 0 && ( digitCount != 0 ) ) + { + *--pOutputString = comma; + } + *--pOutputString = '0' + number % 10; + number /= 10; + digitCount++; + } + while( number != 0 ); + + return pOutputString; +} + +//***************************************************************************** +// +// DisplayBitmapData() +// +// Note that USB is always oriented Little Endian (least significant byte +// at the lowest address). +// +// Inputs: +// PUCHAR pData - pointer to least significant byte of the data +// UCHAR byteCount - number of bytes to print in the pData data buffer +// char * stringLabel - string label to print for user's to identify the data type +// +//***************************************************************************** +void DisplayBitmapData(_In_reads_(byteCount) PUCHAR pData, UCHAR byteCount, _In_ char * stringLabel) +{ + UCHAR byteIndex; + UCHAR data; + UCHAR mask; + UCHAR bitIndex; + UCHAR checkBit = 0; // the bit we want to print + + // print the label and all the bytes on the first line + AppendTextBuffer("%s : ", stringLabel); + VDisplayBytes( pData, byteCount ); + + for ( byteIndex = 0; byteIndex < byteCount; byteIndex++ ) + { + data = pData[ byteIndex ]; + checkBit = 0; // the control bit value we are going to print + for ( mask = 1, bitIndex = 0; bitIndex < 8; bitIndex++ ) + { + checkBit = data & mask; + AppendTextBuffer(" D%02d = %d %s\r\n", + bitIndex + 8 * byteIndex, // increment bit count + checkBit ? 1 : 0, + checkBit ? "yes" : " no"); + mask = mask << 1; + } + + } +} + +//***************************************************************************** +// +// DisplayBitmapDataWithStrings() +// +// Note that USB is always oriented Little Endian (least significant byte +// at the lowest address). +// +// This calls GetSTringFromList() to insert a string that corresonds to +// the bit value being print. +// +// Inputs: +// PUCHAR pData - pointer to least significant byte of the data +// UCHAR byteCount - number of bytes to print in the pData data buffer +// char * stringLabel - string label to print for user's to identify the data type +// STRINGLIST stringList - string table in which to look up bitmap strings +// ULONG numEntriesInTable - number of entrys (strings) in the table +//***************************************************************************** +void DisplayBitmapDataWithStrings( _In_reads_(byteCount) PUCHAR pData, UCHAR byteCount, + _In_ char * stringLabel, _In_ PSTRINGLIST stringList, + ULONG numEntriesInTable) +{ + + UCHAR byteIndex; + UCHAR data; + UCHAR byteMask; + ULONGLONG stringMask; + UCHAR bitIndex; + UCHAR checkBit = 0; // the bit we want to print + + // print the label and all the bytes on the first line + AppendTextBuffer("%s : ", stringLabel); + VDisplayBytes( pData, byteCount ); + + for ( stringMask = 1, byteIndex = 0; byteIndex < byteCount; byteIndex++ ) + { + data = pData[ byteIndex ]; + checkBit = 0; // the control bit value we are going to print + for ( byteMask = 1, bitIndex = 0; bitIndex < 8; bitIndex++ ) + { + checkBit = data & byteMask; + AppendTextBuffer(" D%02d = %d %s %s\r\n", + bitIndex + 8 * byteIndex, // increment bit count + checkBit ? 1 : 0, + checkBit ? "yes - " : " no - ", + GetStringFromList(stringList, + numEntriesInTable, + stringMask, + "Reserved")); + + byteMask = byteMask << 1; + stringMask = stringMask << 1; + } + + } +} + +//***************************************************************************** +// +// DisplayVCH264Format() +// +//***************************************************************************** +BOOL DisplayVCH264Format( _In_reads_(sizeof(VIDEO_FORMAT_H264)) PVIDEO_FORMAT_H264 H264FormatDesc ) +{ + if ( H264FormatDesc->bSimulcastSupport == 0 ) + { + AppendTextBuffer("\r\n ===>Video Streaming H.264 Format Type Descriptor<===\r\n"); + } + else + { + AppendTextBuffer("\r\n ===>Video Streaming H.264 Simulcast Format Type Descriptor<===\r\n"); + } + AppendTextBuffer("bLength: 0x%02X = %d\r\n", H264FormatDesc->bLength, H264FormatDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X \r\n", H264FormatDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X \r\n", H264FormatDesc->bDescriptorSubtype); + AppendTextBuffer("bFormatIndex: 0x%02X = %d\r\n", H264FormatDesc->bFormatIndex, H264FormatDesc->bFormatIndex); + AppendTextBuffer("bNumFrameDescriptors: 0x%02X = %d\r\n", H264FormatDesc->bNumFrameDescriptors, H264FormatDesc->bNumFrameDescriptors); + AppendTextBuffer("bDefaultFrameIndex: 0x%02X = %d\r\n", H264FormatDesc->bDefaultFrameIndex, H264FormatDesc->bDefaultFrameIndex); + AppendTextBuffer("bMaxCodecConfigDelay: 0x%02X = %d frames\r\n", H264FormatDesc->bMaxCodecConfigDelay, H264FormatDesc->bMaxCodecConfigDelay); + DisplayBitmapDataWithStrings( H264FormatDesc->bmSupportedSliceModes, sizeof(H264FormatDesc->bmSupportedSliceModes), "bmSupportedSliceModes", slSliceModes, sizeof(slSliceModes)/sizeof(STRINGLIST) ); + DisplayBitmapDataWithStrings( H264FormatDesc->bmSupportedSyncFrameTypes, sizeof(H264FormatDesc->bmSupportedSyncFrameTypes), "bmSupportedSyncFrameTypes", slSyncFrameTypes, sizeof(slSyncFrameTypes)/sizeof(STRINGLIST) ); + + // handle bResolutionScaling + if ( H264FormatDesc->bResolutionScaling == 0 ) + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Not Supported\r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + else if ( H264FormatDesc->bResolutionScaling == 1 ) + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Limited to 1.5 or 2.0 scaling in both directions, while maintaining the aspect ratio.\r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + else if ( H264FormatDesc->bResolutionScaling == 2 ) + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Limited to 1.0, 1.5 or 2.0 scaling in either direction.\r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + else if ( H264FormatDesc->bResolutionScaling == 3 ) + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Limited to resolutions reported by the associated Frame Descriptors\r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + else if ( H264FormatDesc->bResolutionScaling == 4 ) + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Arbitrary scaling\r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + else // 5 ... 255 + { + AppendTextBuffer("bResolutionScaling: 0x%02X = %d, Reserved \r\n", + H264FormatDesc->bResolutionScaling, + H264FormatDesc->bResolutionScaling ); + } + + // handle bSimulcastSupport + if ( H264FormatDesc->bSimulcastSupport == 0 ) + { + AppendTextBuffer("bSimulcastSupport: 0x%02X = %d, one stream\r\n", + H264FormatDesc->bSimulcastSupport, + H264FormatDesc->bSimulcastSupport ); + } + else if ( H264FormatDesc->bSimulcastSupport == 1 ) + { + AppendTextBuffer("bSimulcastSupport: 0x%02X = %d, multiple streams\r\n", + H264FormatDesc->bSimulcastSupport, + H264FormatDesc->bSimulcastSupport ); + } + else // ( H264FormatDesc->bSimulcastSupport > 1 ) + { + AppendTextBuffer("bSimulcastSupport: 0x%02X = %d *!*ERROR: unknown bSimulcastSupport \r\n", + H264FormatDesc->bSimulcastSupport, + H264FormatDesc->bSimulcastSupport, + H264FormatDesc->bSimulcastSupport ); + } + + + DisplayBitmapDataWithStrings( &(H264FormatDesc->bmSupportedRateControlModes), sizeof(H264FormatDesc->bmSupportedRateControlModes), "bmSupportedRateControlModes", slRateControlModes, sizeof(slRateControlModes)/sizeof(STRINGLIST) ); + + // Note that USB is Little Endian according to the UVC 2.0 spec + + + // Resolutions with no scalability + AppendTextBuffer("wMaxMBperSecOneResolutionNoScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecOneResolutionNoScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecOneResolutionNoScalability) ); + + AppendTextBuffer("wMaxMBperSecTwoResolutionsNoScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecTwoResolutionsNoScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecTwoResolutionsNoScalability) ); + + AppendTextBuffer("wMaxMBperSecThreeResolutionsNoScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecThreeResolutionsNoScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecThreeResolutionsNoScalability) ); + + AppendTextBuffer("wMaxMBperSecFourResolutionsNoScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecFourResolutionsNoScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecFourResolutionsNoScalability) ); + + // Resolutions with temporal scalability + AppendTextBuffer("wMaxMBperSecOneResolutionTemporalScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecOneResolutionTemporalScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecOneResolutionTemporalScalability) ); + + AppendTextBuffer("wMaxMBperSecTwoResolutionsTemporalScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalScalability) ); + + AppendTextBuffer("wMaxMBperSecThreeResolutionsTemporalScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalScalability) ); + + AppendTextBuffer("wMaxMBperSecFourResolutionsTemporalScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecFourResolutionsTemporalScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecFourResolutionsTemporalScalability) ); + + // Resolutions with temporal and quality scalability + AppendTextBuffer("wMaxMBperSecOneResolutionTemporalQualityScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecOneResolutionTemporalQualityScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecOneResolutionTemporalQualityScalability) ); + + AppendTextBuffer("wMaxMBperSecTwoResolutionsTemporalQualityScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalQualityScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalQualityScalability) ); + + + AppendTextBuffer("wMaxMBperSecThreeResolutionsTemporalQualityScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalQualityScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalQualityScalability) ); + + AppendTextBuffer("wMaxMBperSecFourResolutionsTemporalQualityScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecFourResolutionsTemporalQualityScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecFourResolutionsTemporalQualityScalability) ); + + // Resolutions with temporal and spatial scalability + AppendTextBuffer("wMaxMBperSecOneResolutionTemporalSpatialScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecOneResolutionTemporalSpatialScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecOneResolutionTemporalSpatialScalability) ); + + AppendTextBuffer("wMaxMBperSecTwoResolutionsTemporalSpatialScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalSpatialScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecTwoResolutionsTemporalSpatialScalability) ); + + + AppendTextBuffer("wMaxMBperSecThreeResolutionsTemporalSpatialScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalSpatialScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecThreeResolutionsTemporalSpatialScalability) ); + + AppendTextBuffer("wMaxMBperSecFourResolutionsTemporalSpatialScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecFourResolutionsTemporalSpatialScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecFourResolutionsTemporalSpatialScalability) ); + + // Resolutions with full scalability + AppendTextBuffer("wMaxMBperSecOneResolutionFullScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecOneResolutionFullScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecOneResolutionFullScalability) ); + + AppendTextBuffer("wMaxMBperSecTwoResolutionsFullScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecTwoResolutionsFullScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecTwoResolutionsFullScalability) ); + + AppendTextBuffer("wMaxMBperSecThreeResolutionsFullScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecThreeResolutionsFullScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecThreeResolutionsFullScalability) ); + + AppendTextBuffer("wMaxMBperSecFourResolutionsFullScalability: 0x%04X (%s MB/sec)\r\n", + H264FormatDesc->wMaxMBperSecFourResolutionsFullScalability, + commaPrintNumber(1000*H264FormatDesc->wMaxMBperSecFourResolutionsFullScalability) ); + + + return TRUE; +} + +//***************************************************************************** +// +// DisplayVCH264FrameType() +// +//***************************************************************************** +BOOL DisplayVCH264FrameType( _In_reads_(sizeof(VIDEO_FRAME_H264)) PVIDEO_FRAME_H264 H264FrameDesc ) +{ + + ULONG frameIntervalIndex; + ULONG value; + ULONG i; + + AppendTextBuffer("\r\n ===>Video Streaming H.264 Frame Type Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X = %d\r\n", H264FrameDesc->bLength, H264FrameDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X \r\n", H264FrameDesc->bDescriptorType); + AppendTextBuffer("bDescriptorSubtype: 0x%02X \r\n", H264FrameDesc->bDescriptorSubtype); + AppendTextBuffer("bFrameIndex: 0x%02X = %d\r\n", H264FrameDesc->bFrameIndex, H264FrameDesc->bFrameIndex); + AppendTextBuffer("wWidth: 0x%04X = %d\r\n", H264FrameDesc->wWidth, H264FrameDesc->wWidth); + AppendTextBuffer("wHeight: 0x%04X = %d\r\n", H264FrameDesc->wHeight, H264FrameDesc->wHeight); + AppendTextBuffer("wSARwidth: 0x%04X = %d\r\n", H264FrameDesc->wSARwidth, H264FrameDesc->wSARwidth); + AppendTextBuffer("wSARheight: 0x%04X = %d\r\n", H264FrameDesc->wSARheight, H264FrameDesc->wSARheight); + AppendTextBuffer("wProfile: 0x%04X - %s\r\n", H264FrameDesc->wProfile, + GetStringFromList( slProfiles, // string table + sizeof(slProfiles)/sizeof(STRINGLIST), // number of strings in the table + H264FrameDesc->wProfile, // index of string we want to look up in the string table + "Unknown profile" ) ); // string to use if the lookup fails + + AppendTextBuffer("bLevelIDC: 0x%02X = %d = Level %01.01lf \r\n", + H264FrameDesc->bLevelIDC, H264FrameDesc->bLevelIDC, H264FrameDesc->bLevelIDC/10.0 ); + + AppendTextBuffer("wConstrainedToolset: 0x%04X %s\r\n", H264FrameDesc->wConstrainedToolset, + ((H264FrameDesc->wConstrainedToolset == 0) ? "- Reserved" : "*!*ERROR: field is reserved and should be zero")); + + DisplayBitmapDataWithStrings( H264FrameDesc->bmSupportedUsages, sizeof(H264FrameDesc->bmSupportedUsages), "bmSupportedUsages", slUsage, sizeof(slUsage)/sizeof(STRINGLIST) ); + DisplayBitmapDataWithStrings( H264FrameDesc->bmCapabilities, sizeof(H264FrameDesc->bmCapabilities), "bmCapabilities", slCapabilities, sizeof(slCapabilities)/sizeof(STRINGLIST) ); + + + // bmSVCCapabilities[4] + AppendTextBuffer("%s : ", "bmSVCCapabilities"); + VDisplayBytes( &(H264FrameDesc->bmSVCCapabilities[0]), sizeof(H264FrameDesc->bmSVCCapabilities) ); + AppendTextBuffer(" D2..D0 = %d Maximum number of temporal layers = %d\r\n", + H264FrameDesc->bmSVCCapabilities[0] & 0x7, + (H264FrameDesc->bmSVCCapabilities[0] & 0x7) + 1 ); + AppendTextBuffer(" D3 = %d %s - Rewrite Support\r\n", (H264FrameDesc->bmSVCCapabilities[0] & 0x8) >> 3, + ((H264FrameDesc->bmSVCCapabilities[0] & 0x8) >> 3) ? "yes" : " no" ); + AppendTextBuffer(" D6..D4 = %d Maximum number of CGS layers = %d\r\n", + (H264FrameDesc->bmSVCCapabilities[0] & 0x70) >> 4, + ((H264FrameDesc->bmSVCCapabilities[0] & 0x70) >> 4) + 1 ); + + value = ( H264FrameDesc->bmSVCCapabilities[1] << 8 ) | H264FrameDesc->bmSVCCapabilities[0]; + value >>= 7; // shift bit 7 right so that it ends up in the lsb of value + value &= 0x7; + AppendTextBuffer(" D9..D7 = %d Number of MGS sublayers\r\n", value ); + + AppendTextBuffer(" D10 = %d %s - Additional SNR scalability support in spatial enhancement layers\r\n", + (H264FrameDesc->bmSVCCapabilities[1] & 0x4) >> 2, + ((H264FrameDesc->bmSVCCapabilities[1] & 0x4) >> 2) ? "yes" : " no"); + AppendTextBuffer(" D13..D11 = %d Maximum number of spatial layers = %d\r\n", + (H264FrameDesc->bmSVCCapabilities[1] & 0x38) >> 3, + ((H264FrameDesc->bmSVCCapabilities[1] & 0x38) >> 3) + 1 ); + + value = ( H264FrameDesc->bmSVCCapabilities[3] << 16 ) | ( H264FrameDesc->bmSVCCapabilities[2] << 8 ) | H264FrameDesc->bmSVCCapabilities[1]; + value >>= 6; // get bit 14 at LSB + for ( i = 0; i < 18; i++ ) // bits 31...14 + { + AppendTextBuffer(" D%02d = %d %s - Reserved \r\n", 14 + i, value & 0x1, (value & 0x1) ? "yes" : " no" ); + value >>= 1; + } + + // bmMVCCapabilities[4] + AppendTextBuffer("%s : ", "bmMVCCapabilities"); + VDisplayBytes( &(H264FrameDesc->bmMVCCapabilities[0]), sizeof(H264FrameDesc->bmMVCCapabilities) ); + AppendTextBuffer(" D2..D0 = %d Maximum number of temporal layers = %d\r\n", + H264FrameDesc->bmMVCCapabilities[0] & 0x7, + ((H264FrameDesc->bmMVCCapabilities[0] & 0x7) + 1) ); + + value = (H264FrameDesc->bmMVCCapabilities[1] << 8) | H264FrameDesc->bmMVCCapabilities[0]; + value >>= 3; // shift bit 3 right so that it ends up in the lsb of value + value &= 0xff; + AppendTextBuffer(" D10..D3 = %d Maximum number of view components = %d\r\n", + value, value + 1); + + value = ( (H264FrameDesc->bmMVCCapabilities[3] << 16) | (H264FrameDesc->bmMVCCapabilities[2] << 8) | H264FrameDesc->bmMVCCapabilities[1] ); + value >>= 3; // shift bit 11 right so that it ends up in the lsb of value + for ( i = 0; i < 21; i++ ) // bits 31...11 + { + AppendTextBuffer(" D%02d = %d %s - Reserved \r\n", 11 + i, value & 0x1, (value & 0x1) ? "yes" : " no" ); + value >>= 1; + } + + + AppendTextBuffer("dwMinBitRate: 0x%08X = %s bps\r\n", H264FrameDesc->dwMinBitRate, commaPrintNumber(H264FrameDesc->dwMinBitRate)); + AppendTextBuffer("dwMaxBitRate: 0x%08X = %s bps\r\n", H264FrameDesc->dwMaxBitRate, commaPrintNumber(H264FrameDesc->dwMaxBitRate)); + + // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz) \r\n", + H264FrameDesc->dwDefaultFrameInterval, ((double)H264FrameDesc->dwDefaultFrameInterval)/10000.0, (10000000.0/((double)H264FrameDesc->dwDefaultFrameInterval))); + AppendTextBuffer("bNumFrameIntervals: 0x%02X = %d\r\n", H264FrameDesc->bNumFrameIntervals, H264FrameDesc->bNumFrameIntervals); + + + // frame interval 100 ns units. + + //To convert the frame interval to seconds we would divide by 10,000,000. + // 100 ns = 10^(-7) seconds = 1/10,000,000 + + // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse + + // To convert the frame interval to milliseconds, we divide by 10,000. + // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds + // = 1/10,000 milliseconds + + for ( frameIntervalIndex = 0; frameIntervalIndex < H264FrameDesc->bNumFrameIntervals; frameIntervalIndex++ ) + { + value = (ULONG)H264FrameDesc->dwFrameInterval[ frameIntervalIndex ]; + AppendTextBuffer("dwFrameInterval[%d]: 0x%08x = %lf mSec (%4.2f Hz)\r\n", frameIntervalIndex, value, ((double)value)/10000.0, (10000000.0/((double)value)) ); + + } + + return TRUE; +} + + +//***************************************************************************** +// +// DisplayVCH264EncodingUnit() +// +//***************************************************************************** +BOOL DisplayVCH264EncodingUnit( + _In_reads_(sizeof(VIDEO_ENCODING_UNIT)) PVIDEO_ENCODING_UNIT VidEncodingDesc + ) +{ + + PUCHAR pControlsRunTimeData = NULL; + + AppendTextBuffer("\r\n ===>Video Control Encoding Unit Descriptor<===\r\n"); + AppendTextBuffer("bLength: 0x%02X = %d\r\n", VidEncodingDesc->bLength, VidEncodingDesc->bLength); + AppendTextBuffer("bDescriptorType: 0x%02X \r\n", VidEncodingDesc->bDescriptorType ); + AppendTextBuffer("bDescriptorSubtype: 0x%02X \r\n", VidEncodingDesc->bDescriptorSubtype ); + AppendTextBuffer("bUnitID: 0x%02X = %d\r\n", VidEncodingDesc->bUnitID, VidEncodingDesc->bUnitID); + AppendTextBuffer("bSourceID: 0x%02X = %d\r\n", VidEncodingDesc->bSourceID, VidEncodingDesc->bSourceID); + AppendTextBuffer("iEncoding: 0x%02X = %d\r\n", VidEncodingDesc->iEncoding, VidEncodingDesc->iEncoding); + AppendTextBuffer("bControlSize: 0x%02X = %d\r\n", VidEncodingDesc->bControlSize, VidEncodingDesc->bControlSize); + + if ( VidEncodingDesc->bControlSize > 0) + { + // Encoding Unit Descriptor bmControls field + DisplayBitmapDataWithStrings( VidEncodingDesc->bmControls, VidEncodingDesc->bControlSize /* print bControlSize bytes worth of bitmap info */, + "bmControls", slEncodingUnitControls, sizeof(slEncodingUnitControls)/sizeof(STRINGLIST) ); + + // Encoding Unit Descriptor bmControlsRuntime field + pControlsRunTimeData = ((UCHAR *)(&VidEncodingDesc->bmControls)) + VidEncodingDesc->bControlSize; + DisplayBitmapDataWithStrings( pControlsRunTimeData, VidEncodingDesc->bControlSize /* print bControlSize bytes worth of bitmap info */, + "bmControlsRuntime", slEncodingUnitControls, sizeof(slEncodingUnitControls)/sizeof(STRINGLIST) ); + } + return TRUE; +} + +//***************************************************************************** +// +// DoAdditionalErrorChecks() +// +// Currently this function only checks to see that the number of frame +// descriptors actually found equals the number specified in the corresponding +// format descriptor. +// +// Because this potentially involves parsing multiple frame descriptors, we +// call this routine after the video descriptor has been parsed and displayed. +// +//***************************************************************************** +void DoAdditionalErrorChecks() +{ + if( g_expectedNumberOfH264FrameDescriptors > 0 || g_numberOfH264FrameDescriptors > 0 + || g_expectedNumberOfUncompressedFrameFrameDescriptors > 0 || g_numberOfUncompressedFrameFrameDescriptors > 0 + || g_expectedNumberOfMJPEGFrameDescriptors > 0 || g_numberOfMJPEGFrameDescriptors > 0) + { + AppendTextBuffer("\r\n ===>Additional Error Checking<===\r\n"); + + // H.264 frame descriptor + if( g_expectedNumberOfH264FrameDescriptors > 0 || g_numberOfH264FrameDescriptors > 0) + { + if ( g_expectedNumberOfH264FrameDescriptors == g_numberOfH264FrameDescriptors ) + { + AppendTextBuffer("PASS: number of H.264 frame descriptors (%d) == number of frame descriptors (%d) specified in H.264 format descriptor(s)\r\n", + g_expectedNumberOfH264FrameDescriptors, g_numberOfH264FrameDescriptors ); + } + else + { + AppendTextBuffer("FAIL: number of H.264 frame descriptors (%d) != number of frame descriptors (%d) specified in H.264 format descriptor(s)\r\n", + g_expectedNumberOfH264FrameDescriptors, g_numberOfH264FrameDescriptors ); + } + } + + // uncompressed frame descriptor + if( g_expectedNumberOfUncompressedFrameFrameDescriptors > 0 || g_numberOfUncompressedFrameFrameDescriptors > 0) + { + + if ( g_expectedNumberOfUncompressedFrameFrameDescriptors == g_numberOfUncompressedFrameFrameDescriptors ) + { + AppendTextBuffer("PASS: number of uncompressed-frame frame descriptors (%d) == number of frame descriptors (%d) specified in uncompressed format descriptor(s)\r\n", + g_expectedNumberOfUncompressedFrameFrameDescriptors, g_numberOfUncompressedFrameFrameDescriptors ); + } + else + { + AppendTextBuffer("FAIL: number of uncompressed-frame frame descriptors (%d) != number of frame descriptors (%d) specified in uncompressed format descriptor(s)\r\n", + g_expectedNumberOfUncompressedFrameFrameDescriptors, g_numberOfUncompressedFrameFrameDescriptors ); + } + } + + // MJPEG frame descriptor + if( g_expectedNumberOfMJPEGFrameDescriptors > 0 || g_numberOfMJPEGFrameDescriptors > 0) + { + if ( g_expectedNumberOfMJPEGFrameDescriptors == g_numberOfMJPEGFrameDescriptors ) + { + AppendTextBuffer("PASS: number of MJPEG frame descriptors (%d) == number of frame descriptors (%d) specified in MJPEG format descriptor(s)\r\n", + g_expectedNumberOfMJPEGFrameDescriptors, g_numberOfMJPEGFrameDescriptors ); + } + else + { + AppendTextBuffer("FAIL: number of MJPEG frame descriptors (%d) != number of frame descriptors (%d) specified in MJPEG format descriptor(s)\r\n", + g_expectedNumberOfMJPEGFrameDescriptors, g_numberOfMJPEGFrameDescriptors ); + } + } + } +} + +//***************************************************************************** +// +// ResetErrorCounts() +// +//***************************************************************************** +void ResetErrorCounts() +{ + + // H.264 format + g_expectedNumberOfH264FrameDescriptors = 0; + g_numberOfH264FrameDescriptors = 0; + + // MJPEG format + g_expectedNumberOfMJPEGFrameDescriptors = 0; + g_numberOfMJPEGFrameDescriptors = 0; + + // Uncompressed frame format + g_expectedNumberOfUncompressedFrameFrameDescriptors = 0; + g_numberOfUncompressedFrameFrameDescriptors = 0; +} + +#endif //H264_SUPPORT diff --git a/usb/usbview/h264.h b/usb/usbview/h264.h new file mode 100644 index 00000000..f0283968 --- /dev/null +++ b/usb/usbview/h264.h @@ -0,0 +1,164 @@ +#pragma once + +#ifdef H264_SUPPORT + +//***************************************************************************** +// +// external variables +// +//***************************************************************************** +extern UCHAR g_expectedNumberOfH264FrameDescriptors; +extern UCHAR g_numberOfH264FrameDescriptors; + +extern UCHAR g_expectedNumberOfMJPEGFrameDescriptors; +extern UCHAR g_numberOfMJPEGFrameDescriptors; + +extern UCHAR g_expectedNumberOfUncompressedFrameFrameDescriptors; +extern UCHAR g_numberOfUncompressedFrameFrameDescriptors; + +#endif + + + +//***************************************************************************** +// +// defines +// +//***************************************************************************** + +//Version information printed at lower left of UI Window and top of output text window +#define USBVIEW_MAJOR_VERSION 2 +#define USBVIEW_MINOR_VERSION 0 +#define UVC_SPEC_MAJOR_VERSION 1 +#define UVC_SPEC_MINOR_VERSION 5 + + +// definitions take from the proposed UVC 1.5 spec +#define VS_FORMAT_H264 0x13 +#define VS_FRAME_H264 0x14 + + +// Video Class-Specific VC Interface Descriptor Subtypes +// Note, this needs to be added to the list already in C:\nt\sdpublic\internal\drivers\inc\uvcdesc.h +// Also, note that MAX_TYPE_UNIT needs to be bumped up by 1 to account for this new subtype.. +#define H264_ENCODING_UNIT 7 + +//***************************************************************************** +// +// struct definitions +// +//***************************************************************************** + +// VideoStreaming H.264 Format Descriptor +#pragma pack(push, 1) // pack on a 1 byte boundary +typedef struct _VIDEO_FORMAT_H264 +{ // offset (in bytes): + UCHAR bLength; // 0 + UCHAR bDescriptorType; // 1 + UCHAR bDescriptorSubtype; // 2 + UCHAR bFormatIndex; // 3 + UCHAR bNumFrameDescriptors; // 4 + UCHAR bDefaultFrameIndex; // 5 + UCHAR bMaxCodecConfigDelay; // 6 + UCHAR bmSupportedSliceModes[1]; // 7 + UCHAR bmSupportedSyncFrameTypes[1]; // 8 + UCHAR bResolutionScaling; // 9 + UCHAR bSimulcastSupport; // 10 + UCHAR bmSupportedRateControlModes; // 11 + + USHORT wMaxMBperSecOneResolutionNoScalability; // 12 + USHORT wMaxMBperSecTwoResolutionsNoScalability; // 14 + USHORT wMaxMBperSecThreeResolutionsNoScalability; // 16 + USHORT wMaxMBperSecFourResolutionsNoScalability; // 18 + + USHORT wMaxMBperSecOneResolutionTemporalScalability; // 20 + USHORT wMaxMBperSecTwoResolutionsTemporalScalability; // 22 + USHORT wMaxMBperSecThreeResolutionsTemporalScalability; // 24 + USHORT wMaxMBperSecFourResolutionsTemporalScalability; // 26 + + USHORT wMaxMBperSecOneResolutionTemporalQualityScalability; // 28 + USHORT wMaxMBperSecTwoResolutionsTemporalQualityScalability; // 30 + USHORT wMaxMBperSecThreeResolutionsTemporalQualityScalability; // 32 + USHORT wMaxMBperSecFourResolutionsTemporalQualityScalability; // 34 + + USHORT wMaxMBperSecOneResolutionTemporalSpatialScalability; // 36 + USHORT wMaxMBperSecTwoResolutionsTemporalSpatialScalability; // 38 + USHORT wMaxMBperSecThreeResolutionsTemporalSpatialScalability; // 40 + USHORT wMaxMBperSecFourResolutionsTemporalSpatialScalability; // 42 + + USHORT wMaxMBperSecOneResolutionFullScalability; // 44 + USHORT wMaxMBperSecTwoResolutionsFullScalability; // 46 + USHORT wMaxMBperSecThreeResolutionsFullScalability; // 48 + USHORT wMaxMBperSecFourResolutionsFullScalability; // 50 +} VIDEO_FORMAT_H264, *PVIDEO_FORMAT_H264; +#pragma pack(pop) + + +// VideoStreaming H.264 Frame Descriptor +#pragma pack(push, 1) // pack on a 1 byte boundary + +// Disable warning on zero sized array in CPP compiler +#pragma warning(push) +#pragma warning(disable:4200) // Zero sized array + +typedef struct _VIDEO_FRAME_H264 +{ // offset (in bytes): + UCHAR bLength; // 0 + UCHAR bDescriptorType; // 1 + UCHAR bDescriptorSubtype; // 2 + UCHAR bFrameIndex; // 3 + USHORT wWidth; // 4 + USHORT wHeight; // 6 + USHORT wSARwidth; // 8 + USHORT wSARheight; // 10 + USHORT wProfile; // 12 + UCHAR bLevelIDC; // 14 + USHORT wConstrainedToolset; // 15 + UCHAR bmSupportedUsages[4]; // 17 + UCHAR bmCapabilities[2]; // 21 + UCHAR bmSVCCapabilities[4]; // 23 + UCHAR bmMVCCapabilities[4]; // 27 + ULONG dwMinBitRate; // 31 + ULONG dwMaxBitRate; // 35 + ULONG dwDefaultFrameInterval; // 39 + UCHAR bNumFrameIntervals; // 43 + ULONG dwFrameInterval[]; // 44 variable-length parameter +} VIDEO_FRAME_H264, *PVIDEO_FRAME_H264; +#pragma warning(pop) +#pragma pack(pop) + + +// VideoControl Encoding Unit Descriptor +#pragma pack(push, 1) // pack on a 1 byte boundary +#pragma warning(push) +#pragma warning(disable:4200) // Zero sized array +typedef struct //_VIDEO_ENCODING_UNIT +{ // offset (in bytes): + UCHAR bLength; // 0 + UCHAR bDescriptorType; // 1 + UCHAR bDescriptorSubtype; // 2 + UCHAR bUnitID; // 3 + UCHAR bSourceID; // 4 + UCHAR iEncoding; // 5 + UCHAR bControlSize; // 6 + UCHAR bmControls[]; // 7 - variable-length parameter (bControlSize specifies the size) +} VIDEO_ENCODING_UNIT, *PVIDEO_ENCODING_UNIT; +// after bmControls[] there is also the variable-length parameter (bControlSize specifies the size: +// UCHAR bmControlsRunTime[] +#pragma warning(pop) +#pragma pack(pop) + + + +//***************************************************************************** +// +// function prototypes +// +//***************************************************************************** +BOOL DisplayVCH264Format( _In_reads_(sizeof(VIDEO_FORMAT_H264)) PVIDEO_FORMAT_H264 H264FormatDesc ); +BOOL DisplayVCH264FrameType( _In_reads_(sizeof(VIDEO_FRAME_H264)) PVIDEO_FRAME_H264 H264FrameDesc ); +BOOL DisplayVCH264EncodingUnit( _In_reads_(sizeof(VIDEO_ENCODING_UNIT)) PVIDEO_ENCODING_UNIT VidEncodingDesc ); +void DisplayBitmapData( _In_reads_(byteCount) PUCHAR pData, UCHAR byteCount, _In_ char * stringLabel); +void DisplayBitmapDataWithStrings( _In_reads_(byteCount) PUCHAR pData, UCHAR byteCount, _In_ char * stringLabel, _In_ PSTRINGLIST stringList, ULONG numEntriesInTable ); +void DoAdditionalErrorChecks(); +void ResetErrorCounts(); diff --git a/usb/usbview/hub.ico b/usb/usbview/hub.ico Binary files differnew file mode 100644 index 00000000..d0620df8 --- /dev/null +++ b/usb/usbview/hub.ico diff --git a/usb/usbview/langidlist.h b/usb/usbview/langidlist.h new file mode 100644 index 00000000..2b12bcf9 --- /dev/null +++ b/usb/usbview/langidlist.h @@ -0,0 +1,206 @@ +/*++ + +Copyright (c) 2003-2008 Microsoft Corporation + +Module Name: + + LANGIDLIST.H + +Abstract: + + This file LANGIDLIST.H contains content from USB.org, and was reviewed + by LCA in June 2011. Per discussion with USB consortium counsel their + material is "free to any use". + + This header file contains a list of all currently known USB Language IDs + and the language name associated with each Language ID. + + + +Source: + http://www.usb.org + +Environment: + + Kernel & user mode + +Revision History: + + 03-28-03 : created + +--*/ + +#ifndef __LANGIDLIST_H__ +#define __LANGIDLIST_H__ + +// +// Language ID structure +// +typedef struct { + USHORT usLangID; + PCHAR szLanguage; +} USBLANGID, *PUSBLANGID; + +// +// This list built from information obtained on Nov-30-2000 from +// http://www.usb.org +// +// This information has not been independently verified and no claims +// are made here as to its accuracy. +// + +USBLANGID USBLangIDs[] = +{ + {1078 , /* 0x0436 */ "Afrikaans"}, + {1052 , /* 0x041c */ "Albanian"}, + {1025 , /* 0x0401 */ "Arabic (Saudi Arabia)"}, + {2049 , /* 0x0801 */ "Arabic (Iraq)"}, + {3073 , /* 0x0c01 */ "Arabic (Egypt)"}, + {4097 , /* 0x1001 */ "Arabic (Libya)"}, + {5121 , /* 0x1401 */ "Arabic (Algeria)"}, + {6145 , /* 0x1801 */ "Arabic (Morocco)"}, + {7169 , /* 0x1c01 */ "Arabic (Tunisia)"}, + {8193 , /* 0x2001 */ "Arabic (Oman)"}, + {9217 , /* 0x2401 */ "Arabic (Yemen)"}, + {10241 , /* 0x2801 */ "Arabic (Syria)"}, + {11265 , /* 0x2c01 */ "Arabic (Jordan)"}, + {12289 , /* 0x3001 */ "Arabic (Lebanon)"}, + {13313 , /* 0x3401 */ "Arabic (Kuwait)"}, + {14337 , /* 0x3801 */ "Arabic (U.A.E.)"}, + {15361 , /* 0x3c01 */ "Arabic (Bahrain)"}, + {16385 , /* 0x4001 */ "Arabic (Qatar) "}, + {1067 , /* 0x042b */ "Armenian"}, + {1101 , /* 0x044d */ "Assamese"}, + {1068 , /* 0x042c */ "Azeri (Latin)"}, + {2092 , /* 0x082c */ "Azeri (Cyrillic)"}, + {1069 , /* 0x042d */ "Basque"}, + {1059 , /* 0x0423 */ "Belarussian"}, + {1093 , /* 0x0445 */ "Bengali"}, + {1026 , /* 0x0402 */ "Bulgarian"}, + {1109 , /* 0x0455 */ "Burmese"}, + {1027 , /* 0x0403 */ "Catalan"}, + {1028 , /* 0x0404 */ "Chinese (Taiwan)"}, + {2052 , /* 0x0804 */ "Chinese (PRC)"}, + {3076 , /* 0x0c04 */ "Chinese (Hong Kong SAR, PRC)"}, + {4100 , /* 0x1004 */ "Chinese (Singapore)"}, + {5124 , /* 0x1404 */ "Chinese (MACAO SAR)"}, + {1050 , /* 0x041a */ "Croatian"}, + {1029 , /* 0x0405 */ "Czech"}, + {1030 , /* 0x0406 */ "Danish"}, + {1043 , /* 0x0413 */ "Dutch (Netherlands)"}, + {2067 , /* 0x0813 */ "Dutch (Belgium)"}, + {1033 , /* 0x0409 */ "English (United States)"}, + {2057 , /* 0x0809 */ "English (United Kingdom)"}, + {3081 , /* 0x0c09 */ "English (Australian)"}, + {4105 , /* 0x1009 */ "English (Canadian)"}, + {5129 , /* 0x1409 */ "English (New Zealand)"}, + {6153 , /* 0x1809 */ "English (Ireland)"}, + {7177 , /* 0x1c09 */ "English (South Africa)"}, + {8201 , /* 0x2009 */ "English (Jamaica)"}, + {9225 , /* 0x2409 */ "English (Caribbean)"}, + {10249 , /* 0x2809 */ "English (Belize)"}, + {11273 , /* 0x2c09 */ "English (Trinidad)"}, + {12297 , /* 0x3009 */ "English (Zimbabwe)"}, + {13321 , /* 0x3409 */ "English (Philippines)"}, + {1061 , /* 0x0425 */ "Estonian"}, + {1080 , /* 0x0438 */ "Faeroese"}, + {1065 , /* 0x0429 */ "Farsi "}, + {1035 , /* 0x040b */ "Finnish"}, + {1036 , /* 0x040c */ "French (Standard)"}, + {2060 , /* 0x080c */ "French (Belgian)"}, + {3084 , /* 0x0c0c */ "French (Canadian)"}, + {4108 , /* 0x100c */ "French (Switzerland)"}, + {5132 , /* 0x140c */ "French (Luxembourg)"}, + {6156 , /* 0x180c */ "French (Monaco)"}, + {1079 , /* 0x0437 */ "Georgian"}, + {1031 , /* 0x0407 */ "German (Standard)"}, + {2055 , /* 0x0807 */ "German (Switzerland)"}, + {3079 , /* 0x0c07 */ "German (Austria)"}, + {4103 , /* 0x1007 */ "German (Luxembourg)"}, + {5127 , /* 0x1407 */ "German (Liechtenstein)"}, + {1032 , /* 0x0408 */ "Greek"}, + {1095 , /* 0x0447 */ "Gujarati"}, + {1037 , /* 0x040d */ "Hebrew"}, + {1081 , /* 0x0439 */ "Hindi"}, + {1038 , /* 0x040e */ "Hungarian"}, + {1039 , /* 0x040f */ "Icelandic"}, + {1057 , /* 0x0421 */ "Indonesian"}, + {1040 , /* 0x0410 */ "Italian (Standard)"}, + {2064 , /* 0x0810 */ "Italian (Switzerland)"}, + {1041 , /* 0x0411 */ "Japanese"}, + {1099 , /* 0x044b */ "Kannada"}, + {2144 , /* 0x0860 */ "Kashmiri (India)"}, + {1087 , /* 0x043f */ "Kazakh"}, + {1111 , /* 0x0457 */ "Konkani"}, + {1042 , /* 0x0412 */ "Korean"}, + {2066 , /* 0x0812 */ "Korean (Johab)"}, + {1062 , /* 0x0426 */ "Latvian"}, + {1063 , /* 0x0427 */ "Lithuanian"}, + {2087 , /* 0x0827 */ "Lithuanian (Classic)"}, + {1071 , /* 0x042f */ "Macedonia, Former Yugoslav Republic of"}, + {1086 , /* 0x043e */ "Malay (Malaysian)"}, + {2110 , /* 0x083e */ "Malay (Brunei Darussalam)"}, + {1100 , /* 0x044c */ "Malayalam"}, + {1112 , /* 0x0458 */ "Manipuri"}, + {1102 , /* 0x044e */ "Marathi"}, + {2145 , /* 0x0861 */ "Nepali (India)"}, + {1044 , /* 0x0414 */ "Norwegian (Bokmal)"}, + {2068 , /* 0x0814 */ "Norwegian (Nynorsk)"}, + {1096 , /* 0x0448 */ "Odia"}, + {1045 , /* 0x0415 */ "Polish"}, + {1046 , /* 0x0416 */ "Portuguese (Brazil)"}, + {2070 , /* 0x0816 */ "Portuguese (Portugal)"}, + {1094 , /* 0x0446 */ "Punjabi"}, + {1048 , /* 0x0418 */ "Romanian"}, + {1049 , /* 0x0419 */ "Russian"}, + {1103 , /* 0x044f */ "Sanskrit"}, + {3098 , /* 0x0c1a */ "Serbian (Cyrillic)"}, + {2074 , /* 0x081a */ "Serbian (Latin)"}, + {1113 , /* 0x0459 */ "Sindhi"}, + {1051 , /* 0x041b */ "Slovak"}, + {1060 , /* 0x0424 */ "Slovenian"}, + {1034 , /* 0x040a */ "Spanish (Traditional Sort)"}, + {2058 , /* 0x080a */ "Spanish (Mexican)"}, + {3082 , /* 0x0c0a */ "Spanish (Modern Sort)"}, + {4106 , /* 0x100a */ "Spanish (Guatemala)"}, + {5130 , /* 0x140a */ "Spanish (Costa Rica)"}, + {6154 , /* 0x180a */ "Spanish (Panama)"}, + {7178 , /* 0x1c0a */ "Spanish (Dominican Republic)"}, + {8202 , /* 0x200a */ "Spanish (Venezuela)"}, + {9226 , /* 0x240a */ "Spanish (Colombia)"}, + {10250 , /* 0x280a */ "Spanish (Peru)"}, + {11274 , /* 0x2c0a */ "Spanish (Argentina)"}, + {12298 , /* 0x300a */ "Spanish (Ecuador)"}, + {13322 , /* 0x340a */ "Spanish (Chile)"}, + {14346 , /* 0x380a */ "Spanish (Uruguay)"}, + {15370 , /* 0x3c0a */ "Spanish (Paraguay)"}, + {16394 , /* 0x400a */ "Spanish (Bolivia)"}, + {17418 , /* 0x440a */ "Spanish (El Salvador)"}, + {18442 , /* 0x480a */ "Spanish (Honduras)"}, + {19466 , /* 0x4c0a */ "Spanish (Nicaragua)"}, + {20490 , /* 0x500a */ "Spanish (Puerto Rico)"}, + {1072 , /* 0x0430 */ "Sutu"}, + {1089 , /* 0x0441 */ "Swahili (Kenya)"}, + {1053 , /* 0x041d */ "Swedish"}, + {2077 , /* 0x081d */ "Swedish (Finland)"}, + {1097 , /* 0x0449 */ "Tamil"}, + {1092 , /* 0x0444 */ "Tatar (Tatarstan)"}, + {1098 , /* 0x044a */ "Telugu"}, + {1054 , /* 0x041e */ "Thai"}, + {1055 , /* 0x041f */ "Turkish"}, + {1058 , /* 0x0422 */ "Ukrainian"}, + {1056 , /* 0x0420 */ "Urdu (Pakistan)"}, + {2080 , /* 0x0820 */ "Urdu (India)"}, + {1091 , /* 0x0443 */ "Uzbek (Latin)"}, + {2115 , /* 0x0843 */ "Uzbek (Cyrillic)"}, + {1066 , /* 0x042a */ "Vietnamese"}, + {1279 , /* 0x04ff */ "HID (Usage Data Descriptor)"}, + {61695 , /* 0xf0ff */ "HID (Vendor Defined 1)"}, + {62719 , /* 0xf4ff */ "HID (Vendor Defined 2)"}, + {63743 , /* 0xf8ff */ "HID (Vendor Defined 3)"}, + {64767 , /* 0xfcff */ "HID (Vendor Defined 4)"}, + { 0x00, "End"} +}; + +#endif /* __LANGIDLIST_H__ */ + diff --git a/usb/usbview/monitor.ico b/usb/usbview/monitor.ico Binary files differnew file mode 100644 index 00000000..e015959f --- /dev/null +++ b/usb/usbview/monitor.ico diff --git a/usb/usbview/port.ico b/usb/usbview/port.ico Binary files differnew file mode 100644 index 00000000..98c8aa04 --- /dev/null +++ b/usb/usbview/port.ico diff --git a/usb/usbview/resource.h b/usb/usbview/resource.h new file mode 100644 index 00000000..2e621f9c --- /dev/null +++ b/usb/usbview/resource.h @@ -0,0 +1,51 @@ +/*++ +Copyright (c) 1998-2008 Microsoft Corporation, All Rights Reserved. +--*/ + +#define IDD_MAINDIALOG 101 +#define IDR_MENU 102 +#define IDD_ABOUT 103 +#define IDI_ICON 104 +#define IDC_SPLIT 105 +#define IDACCEL 106 + +#define IDI_BADICON 107 +#define IDI_COMPUTER 108 +#define IDI_HUB 109 +#define IDI_NODEVICE 110 +#define IDI_SSICON 111 +#define IDI_NOSSDEVICE 112 + +#define IDC_TREE 1000 +#define IDC_EDIT 1001 +#define IDC_STATUS 1002 + +#define IDS_STRINGBASE 2000 +#define IDS_STANDARD_FONT 2001 +#define IDS_STANDARD_FONT_HEIGHT 2002 +#define IDS_STANDARD_FONT_WIDTH 2003 +#define IDS_USBVIEW_USAGE 2004 +#define IDS_USBVIEW_PRESSKEY 2005 +#define IDS_USBVIEW_INVALIDARG 2006 +#define IDS_USBVIEW_FILE_EXISTS_TXT 2007 +#define IDS_USBVIEW_FILE_EXISTS_XML 2008 +#define IDS_USBVIEW_INTERNAL_ERROR 2009 +#define IDS_USBVIEW_SAVED_TO 2010 +#define IDS_USBVIEW_INVALID_FILENAME 2011 + +#define IDC_VERSION 3000 +#define IDC_UVCVERSION 3001 + +#define ID_EXIT 40001 +#define ID_REFRESH 40002 +#define ID_AUTO_REFRESH 40003 +#define ID_CONFIG_DESCRIPTORS 40004 +#define ID_ABOUT 40005 +#define ID_ANNOTATION 40007 +#define ID_UNUSED 40008 +#define ID_LOG_DEBUG 40009 +#define ID_SAVE 40010 +#define ID_SAVEALL 40011 +#define ID_SAVEXML 40012 +#define IDC_STATIC 0xFFFFFFFF + diff --git a/usb/usbview/split.cur b/usb/usbview/split.cur Binary files differnew file mode 100644 index 00000000..41d65e3c --- /dev/null +++ b/usb/usbview/split.cur diff --git a/usb/usbview/ssport.ico b/usb/usbview/ssport.ico Binary files differnew file mode 100644 index 00000000..e0f712ae --- /dev/null +++ b/usb/usbview/ssport.ico diff --git a/usb/usbview/ssusb.ico b/usb/usbview/ssusb.ico Binary files differnew file mode 100644 index 00000000..71f0ebe1 --- /dev/null +++ b/usb/usbview/ssusb.ico diff --git a/usb/usbview/usb.ico b/usb/usbview/usb.ico Binary files differnew file mode 100644 index 00000000..e615d3e2 --- /dev/null +++ b/usb/usbview/usb.ico diff --git a/usb/usbview/usbdesc.h b/usb/usbview/usbdesc.h new file mode 100644 index 00000000..5b2622a2 --- /dev/null +++ b/usb/usbview/usbdesc.h @@ -0,0 +1,388 @@ +/*++ + +Copyright (c) 1997-2008 Microsoft Corporation + +Module Name: + + USBDESC.H + +Abstract: + + This is a header file for USB descriptors which are not yet in + a standard system header file. + +Environment: + + user mode + +Revision History: + + 03-06-1998 : created + 03-28-2003 : minor changes to support UVC and USB200 + +--*/ + +#pragma pack(push, 1) + +/***************************************************************************** + D E F I N E S +*****************************************************************************/ + +// +//Device Descriptor bDeviceClass values +// +#define USB_INTERFACE_CLASS_DEVICE 0x00 +#define USB_COMMUNICATION_DEVICE 0x02 +#define USB_HUB_DEVICE 0x09 +#define USB_DIAGNOSTIC_DEVICE 0xDC +#define USB_WIRELESS_CONTROLLER_DEVICE 0xE0 +#define USB_MISCELLANEOUS_DEVICE 0xEF +#define USB_VENDOR_SPECIFIC_DEVICE 0xFF + +// +//Device Descriptor bDeviceSubClass values +// +#define USB_COMMON_SUB_CLASS 0x02 + +// +//Interface Descriptor bInterfaceClass values: +// +//#define USB_AUDIO_INTERFACE 0x01 +//#define USB_CDC_CONTROL_INTERFACE 0x02 +//#define USB_HID_INTERFACE 0x03 +//#define USB_PHYSICAL_INTERFACE 0x05 +//#define USB_IMAGE_INTERFACE 0x06 +//#define USB_PRINTER_INTERFACE 0x07 +//#define USB_MASS_STORAGE_INTERFACE 0x08 +//#define USB_HUB_INTERFACE 0x09 +#define USB_CDC_DATA_INTERFACE 0x0A +#define USB_CHIP_SMART_CARD_INTERFACE 0x0B +#define USB_CONTENT_SECURITY_INTERFACE 0x0D +#define USB_DIAGNOSTIC_DEVICE_INTERFACE 0xDC +#define USB_WIRELESS_CONTROLLER_INTERFACE 0xE0 +#define USB_APPLICATION_SPECIFIC_INTERFACE 0xFE +//#define USB_VENDOR_SPECIFIC_INTERFACE 0xFF +#define USB_HID_DESCRIPTOR_TYPE 0x21 + +// +//IAD protocol values +// +#define USB_IAD_PROTOCOL 0x01 + +// +//USB 2.0 Specification Changes - New Descriptors +// +#define USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE 0x07 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08 +#define USB_OTG_DESCRIPTOR_TYPE 0x09 +#define USB_DEBUG_DESCRIPTOR_TYPE 0x0A +#define USB_IAD_DESCRIPTOR_TYPE 0x0B + +// +// USB Device Class Definition for Audio Devices +// Appendix A. Audio Device Class Codes +// + +// A.2 Audio Interface Subclass Codes +// +#define USB_AUDIO_SUBCLASS_UNDEFINED 0x00 +#define USB_AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define USB_AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define USB_AUDIO_SUBCLASS_MIDISTREAMING 0x03 + +// A.4 Audio Class-Specific Descriptor Types +// +#define USB_AUDIO_CS_UNDEFINED 0x20 +#define USB_AUDIO_CS_DEVICE 0x21 +#define USB_AUDIO_CS_CONFIGURATION 0x22 +#define USB_AUDIO_CS_STRING 0x23 +#define USB_AUDIO_CS_INTERFACE 0x24 +#define USB_AUDIO_CS_ENDPOINT 0x25 + +// A.5 Audio Class-Specific AC (Audio Control) Interface Descriptor Subtypes +// +#define USB_AUDIO_AC_UNDEFINED 0x00 +#define USB_AUDIO_AC_HEADER 0x01 +#define USB_AUDIO_AC_INPUT_TERMINAL 0x02 +#define USB_AUDIO_AC_OUTPUT_TERMINAL 0x03 +#define USB_AUDIO_AC_MIXER_UNIT 0x04 +#define USB_AUDIO_AC_SELECTOR_UNIT 0x05 +#define USB_AUDIO_AC_FEATURE_UNIT 0x06 +#define USB_AUDIO_AC_PROCESSING_UNIT 0x07 +#define USB_AUDIO_AC_EXTENSION_UNIT 0x08 + +// A.6 Audio Class-Specific AS (Audio Streaming) Interface Descriptor Subtypes +// +#define USB_AUDIO_AS_UNDEFINED 0x00 +#define USB_AUDIO_AS_GENERAL 0x01 +#define USB_AUDIO_AS_FORMAT_TYPE 0x02 +#define USB_AUDIO_AS_FORMAT_SPECIFIC 0x03 + +// A.7 Processing Unit Process Types +// +#define USB_AUDIO_PROCESS_UNDEFINED 0x00 +#define USB_AUDIO_PROCESS_UPDOWNMIX 0x01 +#define USB_AUDIO_PROCESS_DOLBYPROLOGIC 0x02 +#define USB_AUDIO_PROCESS_3DSTEREOEXTENDER 0x03 +#define USB_AUDIO_PROCESS_REVERBERATION 0x04 +#define USB_AUDIO_PROCESS_CHORUS 0x05 +#define USB_AUDIO_PROCESS_DYNRANGECOMP 0x06 + + +/***************************************************************************** + T Y P E D E F S +*****************************************************************************/ + +// HID Class HID Descriptor +// +typedef struct _USB_HID_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + USHORT bcdHID; + UCHAR bCountryCode; + UCHAR bNumDescriptors; + struct + { + UCHAR bDescriptorType; + USHORT wDescriptorLength; + } OptionalDescriptors[1]; +} USB_HID_DESCRIPTOR, *PUSB_HID_DESCRIPTOR; + + +// OTG Descriptor +// +typedef struct _USB_OTG_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bmAttributes; +} USB_OTG_DESCRIPTOR, *PUSB_OTG_DESCRIPTOR; + +// IAD Descriptor +// +typedef struct _USB_IAD_DESCRIPTOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bFirstInterface; + UCHAR bInterfaceCount; + UCHAR bFunctionClass; + UCHAR bFunctionSubClass; + UCHAR bFunctionProtocol; + UCHAR iFunction; +} USB_IAD_DESCRIPTOR, *PUSB_IAD_DESCRIPTOR; + + +// Common Class Endpoint Descriptor +// +typedef struct _USB_ENDPOINT_DESCRIPTOR2 { + UCHAR bLength; // offset 0, size 1 + UCHAR bDescriptorType; // offset 1, size 1 + UCHAR bEndpointAddress; // offset 2, size 1 + UCHAR bmAttributes; // offset 3, size 1 + USHORT wMaxPacketSize; // offset 4, size 2 + USHORT wInterval; // offset 6, size 2 + UCHAR bSyncAddress; // offset 8, size 1 +} USB_ENDPOINT_DESCRIPTOR2, *PUSB_ENDPOINT_DESCRIPTOR2; + +// Common Class Interface Descriptor +// +typedef struct _USB_INTERFACE_DESCRIPTOR2 { + UCHAR bLength; // offset 0, size 1 + UCHAR bDescriptorType; // offset 1, size 1 + UCHAR bInterfaceNumber; // offset 2, size 1 + UCHAR bAlternateSetting; // offset 3, size 1 + UCHAR bNumEndpoints; // offset 4, size 1 + UCHAR bInterfaceClass; // offset 5, size 1 + UCHAR bInterfaceSubClass; // offset 6, size 1 + UCHAR bInterfaceProtocol; // offset 7, size 1 + UCHAR iInterface; // offset 8, size 1 + USHORT wNumClasses; // offset 9, size 2 +} USB_INTERFACE_DESCRIPTOR2, *PUSB_INTERFACE_DESCRIPTOR2; + + +// +// USB Device Class Definition for Audio Devices +// + +typedef struct _USB_AUDIO_COMMON_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; +} USB_AUDIO_COMMON_DESCRIPTOR, +*PUSB_AUDIO_COMMON_DESCRIPTOR; + +// 4.3.2 Class-Specific AC (Audio Control) Interface Descriptor +// +typedef struct _USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + USHORT bcdADC; + USHORT wTotalLength; + UCHAR bInCollection; + UCHAR baInterfaceNr[1]; +} USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR, +*PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR; + +// 4.3.2.1 Input Terminal Descriptor +// +typedef struct _USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bNrChannels; + USHORT wChannelConfig; + UCHAR iChannelNames; + UCHAR iTerminal; +} USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR, +*PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR; + +// 4.3.2.2 Output Terminal Descriptor +// +typedef struct _USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bSourceID; + UCHAR iTerminal; +} USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR, +*PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR; + +// 4.3.2.3 Mixer Unit Descriptor +// +typedef struct _USB_AUDIO_MIXER_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; +} USB_AUDIO_MIXER_UNIT_DESCRIPTOR, +*PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR; + +// 4.3.2.4 Selector Unit Descriptor +// +typedef struct _USB_AUDIO_SELECTOR_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID[1]; +} USB_AUDIO_SELECTOR_UNIT_DESCRIPTOR, +*PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR; + +// 4.3.2.5 Feature Unit Descriptor +// +typedef struct _USB_AUDIO_FEATURE_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bSourceID; + UCHAR bControlSize; + UCHAR bmaControls[1]; +} USB_AUDIO_FEATURE_UNIT_DESCRIPTOR, +*PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR; + +// 4.3.2.6 Processing Unit Descriptor +// +typedef struct _USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wProcessType; + UCHAR bNrInPins; + UCHAR baSourceID[1]; +} USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR, +*PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR; + +// 4.3.2.7 Extension Unit Descriptor +// +typedef struct _USB_AUDIO_EXTENSION_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + USHORT wExtensionCode; + UCHAR bNrInPins; + UCHAR baSourceID[1]; +} USB_AUDIO_EXTENSION_UNIT_DESCRIPTOR, +*PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR; + +// 4.5.2 Class-Specific AS Interface Descriptor +// +typedef struct _USB_AUDIO_GENERAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalLink; + UCHAR bDelay; + USHORT wFormatTag; +} USB_AUDIO_GENERAL_DESCRIPTOR, +*PUSB_AUDIO_GENERAL_DESCRIPTOR; + +// 4.6.1.2 Class-Specific AS Endpoint Descriptor +// +typedef struct _USB_AUDIO_ENDPOINT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bmAttributes; + UCHAR bLockDelayUnits; + USHORT wLockDelay; +} USB_AUDIO_ENDPOINT_DESCRIPTOR, +*PUSB_AUDIO_ENDPOINT_DESCRIPTOR; + +// +// USB Device Class Definition for Audio Data Formats +// + +typedef struct _USB_AUDIO_COMMON_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; +} USB_AUDIO_COMMON_FORMAT_DESCRIPTOR, +*PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR; + + +// 2.1.5 Type I Format Type Descriptor +// 2.3.1 Type III Format Type Descriptor +// +typedef struct _USB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + UCHAR bNrChannels; + UCHAR bSubframeSize; + UCHAR bBitResolution; + UCHAR bSamFreqType; +} USB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR, +*PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR; + + +// 2.2.6 Type II Format Type Descriptor +// +typedef struct _USB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatType; + USHORT wMaxBitRate; + USHORT wSamplesPerFrame; + UCHAR bSamFreqType; +} USB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR, +*PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR; + +#pragma pack(pop) diff --git a/usb/usbview/usbschema.hpp b/usb/usbview/usbschema.hpp new file mode 100644 index 00000000..9c9e402a --- /dev/null +++ b/usb/usbview/usbschema.hpp @@ -0,0 +1,5815 @@ +// +// This file is auto-generated from XSD using the command: +// xsd.exe /language:CPP /c /order /namespace:Microsoft.Kits.Samples.Usb +// + +#pragma once + +#using <mscorlib.dll> +#using <System.dll> +#using <System.Xml.dll> + +using namespace System::Security::Permissions; +// +// This source code was auto-generated by xsd, Version=4.0.30319.17357. +// +namespace Microsoft { + namespace Kits { + namespace Samples { + namespace Usb { + using namespace System::Xml::Serialization; + using namespace System; + ref class UvcViewAll; + ref class UvcViewType; + ref class MachineInfoType; + ref class NoDeviceType; + ref class PortConnectorType; + ref class UsbPortPropertiesType; + ref class NodeConnectionInfoExV2Type; + ref class UsbDispContIdCapExtDescriptorType; + ref class UsbUsb20ExtensionDescriptorType; + ref class UsbSuperSpeedExtensionDescriptorType; + ref class UsbBosDescriptorType; + ref class UsbDeviceUnknownDescriptorType; + ref class UsbDeviceIADDescriptorType; + ref class UsbDeviceClassType; + ref class UsbDeviceOTGDescriptorType; + ref class UsbDeviceHidOptionalDescriptorsType; + ref class UsbDeviceHidDescriptorType; + ref class UsbDeviceInterfaceDescriptorType; + ref class UsbDeviceQualifierDescriptorType; + ref class UsbConfigurationDescriptorType; + ref class UsbDeviceConfigurationType; + ref class EndpointDescriptorType; + ref class UsbDeviceType; + ref class NodeConnectionInfoExType; + ref class NodeConnectionInfoExStructType; + ref class UsbDeviceDescriptorType; + ref class UsbPipeInfoType; + ref class UsbDeviceClassDetailsType; + ref class ExternalHubType; + ref class HubNodeInformationType; + ref class HubInformationType; + ref class HubDescriptorType; + ref class HubCharacteristicsType; + ref class HubInformationExType; + ref class Hub30DescriptorType; + ref class HubCapabilitiesExType; + ref class RootHubType; + ref class UsbHCPowerStateType; + ref class UsbHCPowerStateMappingType; + ref class UsbHCDeviceInfoType; + ref class HostControllerType; + + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public enum class UsbConnectionSpeedType { + + /// <remarks/> + Low, + + /// <remarks/> + Full, + + /// <remarks/> + High, + + /// <remarks/> + Super, + + /// <remarks/> + Unknown, + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public enum class UsbConnectionStatusType { + + /// <remarks/> + NoDeviceConnected, + + /// <remarks/> + DeviceConnected, + + /// <remarks/> + DeviceFailedEnumeration, + + /// <remarks/> + DeviceGeneralFailure, + + /// <remarks/> + DeviceCausedOvercurrent, + + /// <remarks/> + DeviceNotEnoughPower, + + /// <remarks/> + DeviceNotEnoughBandwidth, + + /// <remarks/> + DeviceHubNestedTooDeeply, + + /// <remarks/> + DeviceInLegacyHub, + + /// <remarks/> + DeviceEnumerating, + + /// <remarks/> + DeviceReset, + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public enum class DevicePowerStateType { + + /// <remarks/> + PowerDeviceUnspecified, + + /// <remarks/> + PowerDeviceD0, + + /// <remarks/> + PowerDeviceD1, + + /// <remarks/> + PowerDeviceD2, + + /// <remarks/> + PowerDeviceD3, + + /// <remarks/> + PowerDeviceMaximum, + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public enum class HubNodeType { + + /// <remarks/> + UsbHub, + + /// <remarks/> + UsbMiParent, + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public enum class HubTypeType { + + /// <remarks/> + UsbRootHub, + + /// <remarks/> + Usb20Hub, + + /// <remarks/> + Usb30Hub, + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(AnonymousType=true, Namespace=L"USB"), + System::Xml::Serialization::XmlRootAttribute(Namespace=L"USB", IsNullable=false)] + public ref class UvcViewAll { + + private: Microsoft::Kits::Samples::Usb::UvcViewType^ uvcViewField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::UvcViewType^ UvcView { + Microsoft::Kits::Samples::Usb::UvcViewType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UvcViewType^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UvcViewType { + + private: Microsoft::Kits::Samples::Usb::MachineInfoType^ machineInfoField; + + private: cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ usbTreeField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::MachineInfoType^ MachineInfo { + Microsoft::Kits::Samples::Usb::MachineInfoType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::MachineInfoType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlArrayAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1), + System::Xml::Serialization::XmlArrayItemAttribute(L"UsbController", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, IsNullable=false)] + property cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ UsbTree { + cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class MachineInfoType { + + private: System::Byte uvcMajorVersionField; + + private: System::Byte uvcMinorVersionField; + + private: System::Byte uvcMajorSpecVersionField; + + private: System::Byte uvcMinorSpecVersionField; + + private: System::DateTime collectionTimeField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::Byte UvcMajorVersion { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::Byte UvcMinorVersion { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::Byte UvcMajorSpecVersion { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::Byte UvcMinorSpecVersion { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::DateTime CollectionTime { + System::DateTime get(); + System::Void set(System::DateTime value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class NoDeviceType { + + private: Microsoft::Kits::Samples::Usb::PortConnectorType^ portConnectorField; + + private: System::String^ usbPortNumberField; + + private: System::String^ nameField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::PortConnectorType^ PortConnector { + Microsoft::Kits::Samples::Usb::PortConnectorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbPortNumber { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ Name { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class PortConnectorType { + + private: System::UInt64 connectionIndexField; + + private: System::UInt64 actualLengthField; + + private: Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ usbPortPropertiesField; + + private: System::UInt16 companionIndexField; + + private: System::UInt16 companionPortNumberField; + + private: System::String^ companionHubSymbolicLinkNameField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::UInt64 ConnectionIndex { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::UInt64 ActualLength { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ UsbPortProperties { + Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::UInt16 CompanionIndex { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::UInt16 CompanionPortNumber { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::String^ CompanionHubSymbolicLinkName { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbPortPropertiesType { + + private: System::Boolean portIsUserConnectableField; + + private: System::Boolean portIsDebugCapableField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::Boolean PortIsUserConnectable { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::Boolean PortIsDebugCapable { + System::Boolean get(); + System::Void set(System::Boolean value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class NodeConnectionInfoExV2Type { + + private: System::UInt64 connectionIndexField; + + private: System::UInt64 lengthField; + + private: System::Boolean usb110SupportedField; + + private: System::Boolean usb200SupportedField; + + private: System::Boolean usb300SupportedField; + + private: System::Boolean deviceIsOperatingAtSuperSpeedOrHigherField; + + private: System::Boolean deviceIsSuperSpeedCapableOrHigherField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::UInt64 ConnectionIndex { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::UInt64 Length { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::Boolean Usb110Supported { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::Boolean Usb200Supported { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::Boolean Usb300Supported { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::Boolean DeviceIsOperatingAtSuperSpeedOrHigher { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::Boolean DeviceIsSuperSpeedCapableOrHigher { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=7)] + property System::Boolean DeviceIsOperatingAtSuperSpeedPlusOrHigher { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property System::Boolean DeviceIsSuperSpeedPlusCapableOrHigher { + System::Boolean get(); + System::Void set(System::Boolean value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDispContIdCapExtDescriptorType { + + private: System::String^ reservedBitErrorField; + + private: System::String^ containerIdStrField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bReservedField; + + private: System::Byte bDevCapabilityTypeField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ ReservedBitError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ ContainerIdStr { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BReserved { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDevCapabilityType { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbUsb20ExtensionDescriptorType { + + private: System::String^ reservedBitErrorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bDevCapabilityTypeField; + + private: System::UInt64 bmAttributesField; + + private: System::Boolean supportsLinkPowerManagementField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ ReservedBitError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDevCapabilityType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt64 BmAttributes { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean SupportsLinkPowerManagement { + System::Boolean get(); + System::Void set(System::Boolean value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbSuperSpeedExtensionDescriptorType { + + private: System::String^ reservedAttributesBitErrorField; + + private: System::String^ reservedSpeedBitErrorField; + + private: System::String^ reservedSpeedErrorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bDevCapabilityTypeField; + + private: System::UInt64 bmAttributesField; + + private: System::Boolean latencyToleranceMsgCapableField; + + private: System::Byte bFunctionalitySupportField; + + private: System::Byte bU1DevExitLatField; + + private: System::UInt16 wSpeedsSupportedField; + + private: System::UInt16 wU2DevExitLatField; + + private: System::Boolean supportsLowSpeedField; + + private: System::Boolean supportsFullSpeedField; + + private: System::Boolean supportsHighSpeedField; + + private: System::Boolean supportsSuperSpeedField; + + private: System::String^ lowestSpeedField; + + private: System::String^ u1DevExitLatencyStringField; + + private: System::String^ u2DevExitLatencyStringField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ ReservedAttributesBitError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ ReservedSpeedBitError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ ReservedSpeedError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDevCapabilityType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt64 BmAttributes { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean LatencyToleranceMsgCapable { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BFunctionalitySupport { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BU1DevExitLat { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WSpeedsSupported { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WU2DevExitLat { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean SupportsLowSpeed { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean SupportsFullSpeed { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean SupportsHighSpeed { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean SupportsSuperSpeed { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ LowestSpeed { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ U1DevExitLatencyString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ U2DevExitLatencyString { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbBosDescriptorType { + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ unknownDescriptorField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ usbSuperSpeedExtensionDescriptorField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ usbUsb20ExtensionDescriptorField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ usbDispContIdCapExtDescriptorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::UInt16 wTotalLengthField; + + private: System::Byte bNumDeviceCapsField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UnknownDescriptor", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=0)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ UnknownDescriptor { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UsbSuperSpeedExtensionDescriptor", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=1)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ UsbSuperSpeedExtensionDescriptor { + cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UsbUsb20ExtensionDescriptor", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=2)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ UsbUsb20ExtensionDescriptor { + cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UsbDispContIdCapExtDescriptor", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=3)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ UsbDispContIdCapExtDescriptor { + cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WTotalLength { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BNumDeviceCaps { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceUnknownDescriptorType { + + private: System::String^ unknownDescriptorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ UnknownDescriptor { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceIADDescriptorType { + + private: Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ functionDetailsField; + + private: System::String^ interfaceErrorField; + + private: System::String^ functionClassErrorField; + + private: System::String^ protocolField; + + private: System::String^ stringDescField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bFirstInterfaceField; + + private: System::Byte bInterfaceCountField; + + private: System::Byte bFunctionClassField; + + private: System::Byte bFunctionSubclassField; + + private: System::Byte bFunctionProtocolField; + + private: System::Byte iFunctionField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ FunctionDetails { + Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ InterfaceError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ FunctionClassError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::String^ Protocol { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ StringDesc { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BFirstInterface { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BInterfaceCount { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BFunctionClass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BFunctionSubclass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BFunctionProtocol { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte IFunction { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceClassType { + + private: System::String^ deviceClassField; + + private: System::String^ deviceSubclassField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ DeviceSubclass { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceOTGDescriptorType { + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bmAttributesField; + + private: System::String^ attributesStringField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BmAttributes { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ AttributesString { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceHidOptionalDescriptorsType { + + private: System::Byte bDescriptorTypeField; + + private: System::UInt16 wDescriptorLengthField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WDescriptorLength { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceHidDescriptorType { + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ optionalDescriptorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::UInt16 bcdHIDField; + + private: System::Byte bCountryCodeField; + + private: System::Byte bNumDescriptorsField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"OptionalDescriptor", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=0)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ OptionalDescriptor { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 BcdHID { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BCountryCode { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BNumDescriptors { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceInterfaceDescriptorType { + + private: Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ interfaceDetailsField; + + private: System::String^ protocolErrorField; + + private: System::String^ stringDescField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::Byte bInterfaceNumberField; + + private: System::Byte bAlternateSettingField; + + private: System::Byte bNumEndpointsField; + + private: System::Byte bInterfaceClassField; + + private: System::Byte bInterfaceSubclassField; + + private: System::Byte bInterfaceProtocolField; + + private: System::Byte iInterfaceField; + + private: System::UInt16 wNumClassesField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ InterfaceDetails { + Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ ProtocolError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ StringDesc { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BInterfaceNumber { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BAlternateSetting { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BNumEndpoints { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BInterfaceClass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BInterfaceSubclass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BInterfaceProtocol { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte IInterface { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WNumClasses { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceQualifierDescriptorType { + + private: System::String^ deviceClassField; + + private: System::Byte maxPacketSizeInBytesField; + + private: System::Boolean maxPacketSizeInBytesFieldSpecified; + + private: System::String^ deviceClassErrorField; + + private: System::String^ deviceSubclassErrorField; + + private: System::String^ deviceProtocolErrorField; + + private: System::String^ deviceNumConfigErrorField; + + private: System::String^ reservedErrorField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::UInt16 bcdUSBField; + + private: System::Byte bDeviceClassField; + + private: System::Byte bDeviceSubclassField; + + private: System::Byte bDeviceProtocolField; + + private: System::Byte bMaxPacketSize0Field; + + private: System::Byte numConfigurationsField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::Byte MaxPacketSizeInBytes { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlIgnoreAttribute] + property System::Boolean MaxPacketSizeInBytesSpecified { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ DeviceClassError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::String^ DeviceSubclassError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ DeviceProtocolError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::String^ DeviceNumConfigError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::String^ ReservedError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 BcdUSB { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDeviceClass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDeviceSubclass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDeviceProtocol { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BMaxPacketSize0 { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte NumConfigurations { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbConfigurationDescriptorType { + + private: System::String^ configDescErrorField; + + private: System::String^ confValueErrorField; + + private: System::String^ confStringDescField; + + private: System::String^ attributesStrField; + + private: System::String^ maxCurrentField; + + private: System::Byte bLengthField; + + private: System::Byte bDescriptorTypeField; + + private: System::UInt16 wTotalLengthField; + + private: System::Byte bNumInterfacesField; + + private: System::Byte bConfigurationValueField; + + private: System::Byte iConfigurationField; + + private: System::Byte bmAttributesField; + + private: System::Byte maxPowerField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ ConfigDescError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ ConfValueError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ ConfStringDesc { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::String^ AttributesStr { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ MaxCurrent { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BDescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WTotalLength { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BNumInterfaces { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BConfigurationValue { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte IConfiguration { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte BmAttributes { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte MaxPower { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceConfigurationType { + + private: System::String^ deviceQualifierErrorField; + + private: System::String^ speedConfigurationErrorField; + + private: System::String^ deviceConfigurationErrorField; + + private: System::String^ interfaceErrorField; + + private: System::String^ preReleaseErrorField; + + private: System::String^ endpointErrorField; + + private: System::String^ hidErrorField; + + private: System::String^ otgErrorField; + + private: System::String^ iadErrorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ deviceDetailsField; + + private: Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ configurationDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ deviceQualifierDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ interfaceDescriptorField; + + private: Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ endpointDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ hidDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ otgDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ iadDescriptorField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ unknownDescriptorField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ DeviceQualifierError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ SpeedConfigurationError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ DeviceConfigurationError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::String^ InterfaceError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ PreReleaseError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::String^ EndpointError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::String^ HidError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=7)] + property System::String^ OtgError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property System::String^ IadError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=9)] + property Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ DeviceDetails { + Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=10)] + property Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ ConfigurationDescriptor { + Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=11)] + property Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ DeviceQualifierDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=12)] + property Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ InterfaceDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=13)] + property Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ EndpointDescriptor { + Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=14)] + property Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ HidDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=15)] + property Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ OtgDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=16)] + property Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ IadDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=17)] + property Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ UnknownDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class EndpointDescriptorType { + + private: System::Byte lengthField; + + private: System::Byte descriptorTypeField; + + private: System::Byte endpointAddressField; + + private: System::Byte attributesField; + + private: System::UInt16 maxPacketSizeField; + + private: System::Byte intervalField; + + private: System::UInt16 wIntervalField; + + private: System::Byte syncAddressField; + + private: System::String^ endpointDirectionField; + + private: System::Byte endpointIdField; + + private: System::String^ endpointTypeField; + + private: System::String^ endpointPacketInfoField; + + private: System::String^ endpointPacketSizeValidationField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte Length { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte EndpointAddress { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte Attributes { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 MaxPacketSize { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte Interval { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 WInterval { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte SyncAddress { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ EndpointDirection { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte EndpointId { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ EndpointType { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ EndpointPacketInfo { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ EndpointPacketSizeValidation { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceType { + + private: Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ connectionInfoField; + + private: Microsoft::Kits::Samples::Usb::PortConnectorType^ portConnectorField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ deviceConfigurationField; + + private: Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ bosDescriptorField; + + private: Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ connectionInfoV2Field; + + private: System::String^ usbPortNumberField; + + private: System::String^ serviceNameField; + + private: System::String^ hwIdField; + + private: System::String^ deviceIdField; + + private: System::String^ deviceNameField; + + private: System::String^ deviceClassField; + + private: System::String^ usbProtocolField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ ConnectionInfo { + Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property Microsoft::Kits::Samples::Usb::PortConnectorType^ PortConnector { + Microsoft::Kits::Samples::Usb::PortConnectorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"DeviceConfiguration", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=2)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ DeviceConfiguration { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ BosDescriptor { + Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ ConnectionInfoV2 { + Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbPortNumber { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ ServiceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HwId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbProtocol { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class NodeConnectionInfoExType { + + private: Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ connectionInfoStructField; + + private: System::String^ iProductStringDescEnField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ deviceClassDetailsField; + + private: System::Byte maxPacketSizeInBytesField; + + private: System::String^ vendorStringField; + + private: System::String^ manufacturerStringField; + + private: System::String^ productStringField; + + private: System::String^ langIdStringField; + + private: System::String^ serialStringField; + + private: System::String^ pipeInfoErrorField; + + private: System::String^ lengthErrorField; + + private: System::String^ deviceErrorField; + + private: System::String^ packetSizeErrorField; + + private: System::String^ configurationCountErrorField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ ConnectionInfoStruct { + Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ IProductStringDescEn { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ DeviceClassDetails { + Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::Byte MaxPacketSizeInBytes { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ VendorString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::String^ ManufacturerString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::String^ ProductString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=7)] + property System::String^ LangIdString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property System::String^ SerialString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=9)] + property System::String^ PipeInfoError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=10)] + property System::String^ LengthError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=11)] + property System::String^ DeviceError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=12)] + property System::String^ PacketSizeError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=13)] + property System::String^ ConfigurationCountError { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class NodeConnectionInfoExStructType { + + private: System::UInt64 connectionIndexField; + + private: Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ deviceDescriptorField; + + private: System::Byte currentConfigurationValueField; + + private: System::Byte speedField; + + private: Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType speedStrField; + + private: System::Boolean deviceIsHubField; + + private: System::Byte deviceAddressField; + + private: System::UInt64 numOfOpenPipesField; + + private: Microsoft::Kits::Samples::Usb::UsbConnectionStatusType usbConnectionStatusField; + + private: Microsoft::Kits::Samples::Usb::DevicePowerStateType devicePowerStateField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ pipeField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::UInt64 ConnectionIndex { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ DeviceDescriptor { + Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::Byte CurrentConfigurationValue { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::Byte Speed { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType SpeedStr { + Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::Boolean DeviceIsHub { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::Byte DeviceAddress { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=7)] + property System::UInt64 NumOfOpenPipes { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property Microsoft::Kits::Samples::Usb::UsbConnectionStatusType UsbConnectionStatus { + Microsoft::Kits::Samples::Usb::UsbConnectionStatusType get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbConnectionStatusType value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=9)] + property Microsoft::Kits::Samples::Usb::DevicePowerStateType DevicePowerState { + Microsoft::Kits::Samples::Usb::DevicePowerStateType get(); + System::Void set(Microsoft::Kits::Samples::Usb::DevicePowerStateType value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"Pipe", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=10)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ Pipe { + cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceDescriptorType { + + private: System::Byte lengthField; + + private: System::Byte descriptorTypeField; + + private: System::UInt16 cdUSBField; + + private: System::Byte deviceClassField; + + private: System::Byte deviceSubclassField; + + private: System::Byte deviceProtocolField; + + private: System::Byte maxPacketSize0Field; + + private: System::UInt16 idVendorField; + + private: System::UInt16 idProductField; + + private: System::UInt16 cdDeviceField; + + private: System::Byte iManufacturerField; + + private: System::Byte iProductField; + + private: System::Byte iSerialNumberField; + + private: System::Byte numConfigurationsField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte Length { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 CdUSB { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DeviceClass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DeviceSubclass { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DeviceProtocol { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte MaxPacketSize0 { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 IdVendor { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 IdProduct { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 CdDevice { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte IManufacturer { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte IProduct { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte ISerialNumber { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte NumConfigurations { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbPipeInfoType { + + private: Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ endpointDescriptorField; + + private: System::UInt64 scheduleOffsetField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ EndpointDescriptor { + Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::UInt64 ScheduleOffset { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbDeviceClassDetailsType { + + private: System::String^ deviceTypeField; + + private: System::String^ deviceTypeErrorField; + + private: System::String^ subclassTypeField; + + private: System::String^ subclassTypeErrorField; + + private: System::String^ deviceProtocolField; + + private: System::String^ deviceProtocolErrorField; + + private: System::UInt32 uvcVersionField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::String^ DeviceType { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ DeviceTypeError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ SubclassType { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::String^ SubclassTypeError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::String^ DeviceProtocol { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::String^ DeviceProtocolError { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::UInt32 UvcVersion { + System::UInt32 get(); + System::Void set(System::UInt32 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class ExternalHubType { + + private: Microsoft::Kits::Samples::Usb::HubNodeInformationType^ hubNodeInformationField; + + private: System::String^ hubNameField; + + private: Microsoft::Kits::Samples::Usb::HubInformationExType^ hubInformationExField; + + private: Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ hubCapabilityExField; + + private: Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ connectionInfoField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ usbDeviceField; + + private: cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ noDeviceField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ deviceConfigurationField; + + private: Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ bosDescriptorField; + + private: Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ connectionInfoV2Field; + + private: cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ externalHubField; + + private: Microsoft::Kits::Samples::Usb::PortConnectorType^ portConnectorField; + + private: System::String^ serviceNameField; + + private: System::String^ hwIdField; + + private: System::String^ deviceIdField; + + private: System::String^ deviceNameField; + + private: System::String^ deviceClassField; + + private: System::String^ usbProtocolField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::HubNodeInformationType^ HubNodeInformation { + Microsoft::Kits::Samples::Usb::HubNodeInformationType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubNodeInformationType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ HubName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::HubInformationExType^ HubInformationEx { + Microsoft::Kits::Samples::Usb::HubInformationExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubInformationExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ HubCapabilityEx { + Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ ConnectionInfo { + Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UsbDevice", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=5)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ UsbDevice { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"NoDevice", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ NoDevice { + cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"DeviceConfiguration", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=7)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ DeviceConfiguration { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ BosDescriptor { + Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=9)] + property Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ ConnectionInfoV2 { + Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"ExternalHub", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=10)] + property cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ ExternalHub { + cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=11)] + property Microsoft::Kits::Samples::Usb::PortConnectorType^ PortConnector { + Microsoft::Kits::Samples::Usb::PortConnectorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ ServiceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HwId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbProtocol { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubNodeInformationType { + + private: Microsoft::Kits::Samples::Usb::HubNodeType hubNodeField; + + private: Microsoft::Kits::Samples::Usb::HubInformationType^ hubInformationField; + + private: System::UInt64 miParentNumberOfInterfacesField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::HubNodeType HubNode { + Microsoft::Kits::Samples::Usb::HubNodeType get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubNodeType value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property Microsoft::Kits::Samples::Usb::HubInformationType^ HubInformation { + Microsoft::Kits::Samples::Usb::HubInformationType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubInformationType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::UInt64 MiParentNumberOfInterfaces { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubInformationType { + + private: System::Boolean isRootHubField; + + private: System::Boolean isBusPoweredField; + + private: Microsoft::Kits::Samples::Usb::HubDescriptorType^ hubDescriptorField; + + private: Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ hubCharacteristicsField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::Boolean IsRootHub { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::Boolean IsBusPowered { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::HubDescriptorType^ HubDescriptor { + Microsoft::Kits::Samples::Usb::HubDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ HubCharacteristics { + Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubDescriptorType { + + private: System::Byte descriptorLengthField; + + private: System::Byte descriptorTypeField; + + private: System::Byte numberOfPortsField; + + private: System::Byte powerOntoPowerGoodField; + + private: System::Byte hubControlCurrentField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DescriptorLength { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte NumberOfPorts { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte PowerOntoPowerGood { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte HubControlCurrent { + System::Byte get(); + System::Void set(System::Byte value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubCharacteristicsType { + + private: System::UInt32 hubCharacteristicsValueField; + + private: System::String^ powerSwitchingField; + + private: System::Boolean compoundDeviceField; + + private: System::String^ overCurrentProtectionField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt32 HubCharacteristicsValue { + System::UInt32 get(); + System::Void set(System::UInt32 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ PowerSwitching { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean CompoundDevice { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ OverCurrentProtection { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubInformationExType { + + private: Microsoft::Kits::Samples::Usb::HubTypeType hubTypeField; + + private: System::UInt16 highestPortNumberField; + + private: Microsoft::Kits::Samples::Usb::HubDescriptorType^ hubDescriptorField; + + private: Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ hub30DescriptorField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::HubTypeType HubType { + Microsoft::Kits::Samples::Usb::HubTypeType get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubTypeType value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::UInt16 HighestPortNumber { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::HubDescriptorType^ HubDescriptor { + Microsoft::Kits::Samples::Usb::HubDescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubDescriptorType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ Hub30Descriptor { + Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class Hub30DescriptorType { + + private: System::Byte lengthField; + + private: System::Byte descriptorTypeField; + + private: System::Byte numberOfPortsField; + + private: System::UInt16 hubCharacteristicsField; + + private: System::Byte powerOntoPowerGoodField; + + private: System::Byte hubControlCurrentField; + + private: System::Byte hubHdrDecLatField; + + private: System::UInt16 hubDelayField; + + private: System::UInt16 deviceRemovableField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte Length { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte DescriptorType { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte NumberOfPorts { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 HubCharacteristics { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte PowerOntoPowerGood { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte HubControlCurrent { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Byte HubHdrDecLat { + System::Byte get(); + System::Void set(System::Byte value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 HubDelay { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::UInt16 DeviceRemovable { + System::UInt16 get(); + System::Void set(System::UInt16 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HubCapabilitiesExType { + + private: System::Boolean hubIsHighSpeedCapableField; + + private: System::Boolean hubIsHighSpeedField; + + private: System::Boolean hubIsMultiTtCapableField; + + private: System::Boolean hubIsMultiTtField; + + private: System::Boolean hubIsRootField; + + private: System::Boolean hubIsArmedWakeOnConnectField; + + private: System::Boolean hubIsBusPoweredField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsHighSpeedCapable { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsHighSpeed { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsMultiTtCapable { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsMultiTt { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsRoot { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsArmedWakeOnConnect { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean HubIsBusPowered { + System::Boolean get(); + System::Void set(System::Boolean value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class RootHubType { + + private: Microsoft::Kits::Samples::Usb::HubNodeInformationType^ hubNodeInformationField; + + private: System::String^ hubNameField; + + private: Microsoft::Kits::Samples::Usb::HubInformationExType^ hubInformationExField; + + private: Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ hubCapabilityExField; + + private: cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ externalHubField; + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ usbDeviceField; + + private: cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ noDeviceField; + + private: System::String^ serviceNameField; + + private: System::String^ hwIdField; + + private: System::String^ deviceIdField; + + private: System::String^ deviceNameField; + + private: System::String^ deviceClassField; + + private: System::String^ usbProtocolField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::HubNodeInformationType^ HubNodeInformation { + Microsoft::Kits::Samples::Usb::HubNodeInformationType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubNodeInformationType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ HubName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::HubInformationExType^ HubInformationEx { + Microsoft::Kits::Samples::Usb::HubInformationExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubInformationExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ HubCapabilityEx { + Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"ExternalHub", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=4)] + property cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ ExternalHub { + cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"UsbDevice", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, + Order=5)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ UsbDevice { + cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"NoDevice", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ NoDevice { + cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ ServiceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HwId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbProtocol { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbHCPowerStateType { + + private: System::String^ systemStateField; + + private: System::String^ hostControllerStateField; + + private: System::String^ hubStateField; + + private: System::Boolean canWakeUpField; + + private: System::Boolean isPoweredField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ SystemState { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HostControllerState { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HubState { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean CanWakeUp { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::Boolean IsPowered { + System::Boolean get(); + System::Void set(System::Boolean value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbHCPowerStateMappingType { + + private: cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ powerMapField; + + private: System::String^ lastSleepStateField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(L"PowerMap", Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ PowerMap { + cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ get(); + System::Void set(cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::String^ LastSleepState { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class UsbHCDeviceInfoType { + + private: System::Int64 vendorIdField; + + private: System::Int64 deviceIdField; + + private: System::String^ driverKeyField; + + private: System::Int64 subSysIdField; + + private: System::Int64 revisionField; + + private: System::UInt64 debugPortField; + + private: System::UInt64 numberOfRootPortsField; + + private: System::UInt64 controllerFlavorField; + + private: System::String^ controllerFlavorStringField; + + private: System::Boolean portSwitchingEnabledField; + + private: System::Boolean selectiveSuspendEnabledField; + + private: System::UInt64 legacyBiosField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property System::Int64 VendorId { + System::Int64 get(); + System::Void set(System::Int64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property System::Int64 DeviceId { + System::Int64 get(); + System::Void set(System::Int64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property System::String^ DriverKey { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=3)] + property System::Int64 SubSysId { + System::Int64 get(); + System::Void set(System::Int64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=4)] + property System::Int64 Revision { + System::Int64 get(); + System::Void set(System::Int64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=5)] + property System::UInt64 DebugPort { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=6)] + property System::UInt64 NumberOfRootPorts { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=7)] + property System::UInt64 ControllerFlavor { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=8)] + property System::String^ ControllerFlavorString { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=9)] + property System::Boolean PortSwitchingEnabled { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=10)] + property System::Boolean SelectiveSuspendEnabled { + System::Boolean get(); + System::Void set(System::Boolean value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=11)] + property System::UInt64 LegacyBios { + System::UInt64 get(); + System::Void set(System::UInt64 value); + } + }; + + /// <remarks/> + [System::CodeDom::Compiler::GeneratedCodeAttribute(L"xsd", L"4.0.30319.17357"), + System::SerializableAttribute, + System::Diagnostics::DebuggerStepThroughAttribute, + System::ComponentModel::DesignerCategoryAttribute(L"code"), + System::Xml::Serialization::XmlTypeAttribute(Namespace=L"USB")] + public ref class HostControllerType { + + private: Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ controllerInfoField; + + private: Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ powerMappingField; + + private: Microsoft::Kits::Samples::Usb::RootHubType^ rootHubField; + + private: System::String^ serviceNameField; + + private: System::String^ hwIdField; + + private: System::String^ deviceIdField; + + private: System::String^ deviceNameField; + + private: System::String^ deviceClassField; + + private: System::String^ usbProtocolField; + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=0)] + property Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ ControllerInfo { + Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=1)] + property Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ PowerMapping { + Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlElementAttribute(Form=System::Xml::Schema::XmlSchemaForm::Unqualified, Order=2)] + property Microsoft::Kits::Samples::Usb::RootHubType^ RootHub { + Microsoft::Kits::Samples::Usb::RootHubType^ get(); + System::Void set(Microsoft::Kits::Samples::Usb::RootHubType^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ ServiceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ HwId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceId { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceName { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ DeviceClass { + System::String^ get(); + System::Void set(System::String^ value); + } + + /// <remarks/> + public: [System::Xml::Serialization::XmlAttributeAttribute] + property System::String^ UsbProtocol { + System::String^ get(); + System::Void set(System::String^ value); + } + }; + } + } + } +} +namespace Microsoft { + namespace Kits { + namespace Samples { + namespace Usb { + + + + + + + + inline Microsoft::Kits::Samples::Usb::UvcViewType^ UvcViewAll::UvcView::get() { + return this->uvcViewField; + } + inline System::Void UvcViewAll::UvcView::set(Microsoft::Kits::Samples::Usb::UvcViewType^ value) { + this->uvcViewField = value; + } + + + inline Microsoft::Kits::Samples::Usb::MachineInfoType^ UvcViewType::MachineInfo::get() { + return this->machineInfoField; + } + inline System::Void UvcViewType::MachineInfo::set(Microsoft::Kits::Samples::Usb::MachineInfoType^ value) { + this->machineInfoField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ UvcViewType::UsbTree::get() { + return this->usbTreeField; + } + inline System::Void UvcViewType::UsbTree::set(cli::array< Microsoft::Kits::Samples::Usb::HostControllerType^ >^ value) { + this->usbTreeField = value; + } + + + inline System::Byte MachineInfoType::UvcMajorVersion::get() { + return this->uvcMajorVersionField; + } + inline System::Void MachineInfoType::UvcMajorVersion::set(System::Byte value) { + this->uvcMajorVersionField = value; + } + + inline System::Byte MachineInfoType::UvcMinorVersion::get() { + return this->uvcMinorVersionField; + } + inline System::Void MachineInfoType::UvcMinorVersion::set(System::Byte value) { + this->uvcMinorVersionField = value; + } + + inline System::Byte MachineInfoType::UvcMajorSpecVersion::get() { + return this->uvcMajorSpecVersionField; + } + inline System::Void MachineInfoType::UvcMajorSpecVersion::set(System::Byte value) { + this->uvcMajorSpecVersionField = value; + } + + inline System::Byte MachineInfoType::UvcMinorSpecVersion::get() { + return this->uvcMinorSpecVersionField; + } + inline System::Void MachineInfoType::UvcMinorSpecVersion::set(System::Byte value) { + this->uvcMinorSpecVersionField = value; + } + + inline System::DateTime MachineInfoType::CollectionTime::get() { + return this->collectionTimeField; + } + inline System::Void MachineInfoType::CollectionTime::set(System::DateTime value) { + this->collectionTimeField = value; + } + + + inline Microsoft::Kits::Samples::Usb::PortConnectorType^ NoDeviceType::PortConnector::get() { + return this->portConnectorField; + } + inline System::Void NoDeviceType::PortConnector::set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value) { + this->portConnectorField = value; + } + + inline System::String^ NoDeviceType::UsbPortNumber::get() { + return this->usbPortNumberField; + } + inline System::Void NoDeviceType::UsbPortNumber::set(System::String^ value) { + this->usbPortNumberField = value; + } + + inline System::String^ NoDeviceType::Name::get() { + return this->nameField; + } + inline System::Void NoDeviceType::Name::set(System::String^ value) { + this->nameField = value; + } + + + inline System::UInt64 PortConnectorType::ConnectionIndex::get() { + return this->connectionIndexField; + } + inline System::Void PortConnectorType::ConnectionIndex::set(System::UInt64 value) { + this->connectionIndexField = value; + } + + inline System::UInt64 PortConnectorType::ActualLength::get() { + return this->actualLengthField; + } + inline System::Void PortConnectorType::ActualLength::set(System::UInt64 value) { + this->actualLengthField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ PortConnectorType::UsbPortProperties::get() { + return this->usbPortPropertiesField; + } + inline System::Void PortConnectorType::UsbPortProperties::set(Microsoft::Kits::Samples::Usb::UsbPortPropertiesType^ value) { + this->usbPortPropertiesField = value; + } + + inline System::UInt16 PortConnectorType::CompanionIndex::get() { + return this->companionIndexField; + } + inline System::Void PortConnectorType::CompanionIndex::set(System::UInt16 value) { + this->companionIndexField = value; + } + + inline System::UInt16 PortConnectorType::CompanionPortNumber::get() { + return this->companionPortNumberField; + } + inline System::Void PortConnectorType::CompanionPortNumber::set(System::UInt16 value) { + this->companionPortNumberField = value; + } + + inline System::String^ PortConnectorType::CompanionHubSymbolicLinkName::get() { + return this->companionHubSymbolicLinkNameField; + } + inline System::Void PortConnectorType::CompanionHubSymbolicLinkName::set(System::String^ value) { + this->companionHubSymbolicLinkNameField = value; + } + + + inline System::Boolean UsbPortPropertiesType::PortIsUserConnectable::get() { + return this->portIsUserConnectableField; + } + inline System::Void UsbPortPropertiesType::PortIsUserConnectable::set(System::Boolean value) { + this->portIsUserConnectableField = value; + } + + inline System::Boolean UsbPortPropertiesType::PortIsDebugCapable::get() { + return this->portIsDebugCapableField; + } + inline System::Void UsbPortPropertiesType::PortIsDebugCapable::set(System::Boolean value) { + this->portIsDebugCapableField = value; + } + + + inline System::UInt64 NodeConnectionInfoExV2Type::ConnectionIndex::get() { + return this->connectionIndexField; + } + inline System::Void NodeConnectionInfoExV2Type::ConnectionIndex::set(System::UInt64 value) { + this->connectionIndexField = value; + } + + inline System::UInt64 NodeConnectionInfoExV2Type::Length::get() { + return this->lengthField; + } + inline System::Void NodeConnectionInfoExV2Type::Length::set(System::UInt64 value) { + this->lengthField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::Usb110Supported::get() { + return this->usb110SupportedField; + } + inline System::Void NodeConnectionInfoExV2Type::Usb110Supported::set(System::Boolean value) { + this->usb110SupportedField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::Usb200Supported::get() { + return this->usb200SupportedField; + } + inline System::Void NodeConnectionInfoExV2Type::Usb200Supported::set(System::Boolean value) { + this->usb200SupportedField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::Usb300Supported::get() { + return this->usb300SupportedField; + } + inline System::Void NodeConnectionInfoExV2Type::Usb300Supported::set(System::Boolean value) { + this->usb300SupportedField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::DeviceIsOperatingAtSuperSpeedOrHigher::get() { + return this->deviceIsOperatingAtSuperSpeedOrHigherField; + } + inline System::Void NodeConnectionInfoExV2Type::DeviceIsOperatingAtSuperSpeedOrHigher::set(System::Boolean value) { + this->deviceIsOperatingAtSuperSpeedOrHigherField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::DeviceIsSuperSpeedCapableOrHigher::get() { + return this->deviceIsSuperSpeedCapableOrHigherField; + } + inline System::Void NodeConnectionInfoExV2Type::DeviceIsSuperSpeedCapableOrHigher::set(System::Boolean value) { + this->deviceIsSuperSpeedCapableOrHigherField = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::DeviceIsOperatingAtSuperSpeedPlusOrHigher::get() { + return this->deviceIsOperatingAtSuperSpeedPlusOrHigher; + } + inline System::Void NodeConnectionInfoExV2Type::DeviceIsOperatingAtSuperSpeedPlusOrHigher::set(System::Boolean value) { + this->deviceIsOperatingAtSuperSpeedPlusOrHigher = value; + } + + inline System::Boolean NodeConnectionInfoExV2Type::DeviceIsSuperSpeedPlusCapableOrHigher::get() { + return this->deviceIsSuperSpeedPlusCapableOrHigher; + } + inline System::Void NodeConnectionInfoExV2Type::DeviceIsSuperSpeedPlusCapableOrHigher::set(System::Boolean value) { + this->deviceIsSuperSpeedPlusCapableOrHigher = value; + } + + inline System::String^ UsbDispContIdCapExtDescriptorType::ReservedBitError::get() { + return this->reservedBitErrorField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::ReservedBitError::set(System::String^ value) { + this->reservedBitErrorField = value; + } + + inline System::String^ UsbDispContIdCapExtDescriptorType::ContainerIdStr::get() { + return this->containerIdStrField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::ContainerIdStr::set(System::String^ value) { + this->containerIdStrField = value; + } + + inline System::Byte UsbDispContIdCapExtDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDispContIdCapExtDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbDispContIdCapExtDescriptorType::BReserved::get() { + return this->bReservedField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::BReserved::set(System::Byte value) { + this->bReservedField = value; + } + + inline System::Byte UsbDispContIdCapExtDescriptorType::BDevCapabilityType::get() { + return this->bDevCapabilityTypeField; + } + inline System::Void UsbDispContIdCapExtDescriptorType::BDevCapabilityType::set(System::Byte value) { + this->bDevCapabilityTypeField = value; + } + + + inline System::String^ UsbUsb20ExtensionDescriptorType::ReservedBitError::get() { + return this->reservedBitErrorField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::ReservedBitError::set(System::String^ value) { + this->reservedBitErrorField = value; + } + + inline System::Byte UsbUsb20ExtensionDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbUsb20ExtensionDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbUsb20ExtensionDescriptorType::BDevCapabilityType::get() { + return this->bDevCapabilityTypeField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::BDevCapabilityType::set(System::Byte value) { + this->bDevCapabilityTypeField = value; + } + + inline System::UInt64 UsbUsb20ExtensionDescriptorType::BmAttributes::get() { + return this->bmAttributesField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::BmAttributes::set(System::UInt64 value) { + this->bmAttributesField = value; + } + + inline System::Boolean UsbUsb20ExtensionDescriptorType::SupportsLinkPowerManagement::get() { + return this->supportsLinkPowerManagementField; + } + inline System::Void UsbUsb20ExtensionDescriptorType::SupportsLinkPowerManagement::set(System::Boolean value) { + this->supportsLinkPowerManagementField = value; + } + + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::ReservedAttributesBitError::get() { + return this->reservedAttributesBitErrorField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::ReservedAttributesBitError::set(System::String^ value) { + this->reservedAttributesBitErrorField = value; + } + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::ReservedSpeedBitError::get() { + return this->reservedSpeedBitErrorField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::ReservedSpeedBitError::set(System::String^ value) { + this->reservedSpeedBitErrorField = value; + } + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::ReservedSpeedError::get() { + return this->reservedSpeedErrorField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::ReservedSpeedError::set(System::String^ value) { + this->reservedSpeedErrorField = value; + } + + inline System::Byte UsbSuperSpeedExtensionDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbSuperSpeedExtensionDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbSuperSpeedExtensionDescriptorType::BDevCapabilityType::get() { + return this->bDevCapabilityTypeField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BDevCapabilityType::set(System::Byte value) { + this->bDevCapabilityTypeField = value; + } + + inline System::UInt64 UsbSuperSpeedExtensionDescriptorType::BmAttributes::get() { + return this->bmAttributesField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BmAttributes::set(System::UInt64 value) { + this->bmAttributesField = value; + } + + inline System::Boolean UsbSuperSpeedExtensionDescriptorType::LatencyToleranceMsgCapable::get() { + return this->latencyToleranceMsgCapableField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::LatencyToleranceMsgCapable::set(System::Boolean value) { + this->latencyToleranceMsgCapableField = value; + } + + inline System::Byte UsbSuperSpeedExtensionDescriptorType::BFunctionalitySupport::get() { + return this->bFunctionalitySupportField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BFunctionalitySupport::set(System::Byte value) { + this->bFunctionalitySupportField = value; + } + + inline System::Byte UsbSuperSpeedExtensionDescriptorType::BU1DevExitLat::get() { + return this->bU1DevExitLatField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::BU1DevExitLat::set(System::Byte value) { + this->bU1DevExitLatField = value; + } + + inline System::UInt16 UsbSuperSpeedExtensionDescriptorType::WSpeedsSupported::get() { + return this->wSpeedsSupportedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::WSpeedsSupported::set(System::UInt16 value) { + this->wSpeedsSupportedField = value; + } + + inline System::UInt16 UsbSuperSpeedExtensionDescriptorType::WU2DevExitLat::get() { + return this->wU2DevExitLatField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::WU2DevExitLat::set(System::UInt16 value) { + this->wU2DevExitLatField = value; + } + + inline System::Boolean UsbSuperSpeedExtensionDescriptorType::SupportsLowSpeed::get() { + return this->supportsLowSpeedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::SupportsLowSpeed::set(System::Boolean value) { + this->supportsLowSpeedField = value; + } + + inline System::Boolean UsbSuperSpeedExtensionDescriptorType::SupportsFullSpeed::get() { + return this->supportsFullSpeedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::SupportsFullSpeed::set(System::Boolean value) { + this->supportsFullSpeedField = value; + } + + inline System::Boolean UsbSuperSpeedExtensionDescriptorType::SupportsHighSpeed::get() { + return this->supportsHighSpeedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::SupportsHighSpeed::set(System::Boolean value) { + this->supportsHighSpeedField = value; + } + + inline System::Boolean UsbSuperSpeedExtensionDescriptorType::SupportsSuperSpeed::get() { + return this->supportsSuperSpeedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::SupportsSuperSpeed::set(System::Boolean value) { + this->supportsSuperSpeedField = value; + } + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::LowestSpeed::get() { + return this->lowestSpeedField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::LowestSpeed::set(System::String^ value) { + this->lowestSpeedField = value; + } + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::U1DevExitLatencyString::get() { + return this->u1DevExitLatencyStringField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::U1DevExitLatencyString::set(System::String^ value) { + this->u1DevExitLatencyStringField = value; + } + + inline System::String^ UsbSuperSpeedExtensionDescriptorType::U2DevExitLatencyString::get() { + return this->u2DevExitLatencyStringField; + } + inline System::Void UsbSuperSpeedExtensionDescriptorType::U2DevExitLatencyString::set(System::String^ value) { + this->u2DevExitLatencyStringField = value; + } + + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ UsbBosDescriptorType::UnknownDescriptor::get() { + return this->unknownDescriptorField; + } + inline System::Void UsbBosDescriptorType::UnknownDescriptor::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ >^ value) { + this->unknownDescriptorField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ UsbBosDescriptorType::UsbSuperSpeedExtensionDescriptor::get() { + return this->usbSuperSpeedExtensionDescriptorField; + } + inline System::Void UsbBosDescriptorType::UsbSuperSpeedExtensionDescriptor::set(cli::array< Microsoft::Kits::Samples::Usb::UsbSuperSpeedExtensionDescriptorType^ >^ value) { + this->usbSuperSpeedExtensionDescriptorField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ UsbBosDescriptorType::UsbUsb20ExtensionDescriptor::get() { + return this->usbUsb20ExtensionDescriptorField; + } + inline System::Void UsbBosDescriptorType::UsbUsb20ExtensionDescriptor::set(cli::array< Microsoft::Kits::Samples::Usb::UsbUsb20ExtensionDescriptorType^ >^ value) { + this->usbUsb20ExtensionDescriptorField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ UsbBosDescriptorType::UsbDispContIdCapExtDescriptor::get() { + return this->usbDispContIdCapExtDescriptorField; + } + inline System::Void UsbBosDescriptorType::UsbDispContIdCapExtDescriptor::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDispContIdCapExtDescriptorType^ >^ value) { + this->usbDispContIdCapExtDescriptorField = value; + } + + inline System::Byte UsbBosDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbBosDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbBosDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbBosDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::UInt16 UsbBosDescriptorType::WTotalLength::get() { + return this->wTotalLengthField; + } + inline System::Void UsbBosDescriptorType::WTotalLength::set(System::UInt16 value) { + this->wTotalLengthField = value; + } + + inline System::Byte UsbBosDescriptorType::BNumDeviceCaps::get() { + return this->bNumDeviceCapsField; + } + inline System::Void UsbBosDescriptorType::BNumDeviceCaps::set(System::Byte value) { + this->bNumDeviceCapsField = value; + } + + + inline System::String^ UsbDeviceUnknownDescriptorType::UnknownDescriptor::get() { + return this->unknownDescriptorField; + } + inline System::Void UsbDeviceUnknownDescriptorType::UnknownDescriptor::set(System::String^ value) { + this->unknownDescriptorField = value; + } + + inline System::Byte UsbDeviceUnknownDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceUnknownDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceUnknownDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceUnknownDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + + inline Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ UsbDeviceIADDescriptorType::FunctionDetails::get() { + return this->functionDetailsField; + } + inline System::Void UsbDeviceIADDescriptorType::FunctionDetails::set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value) { + this->functionDetailsField = value; + } + + inline System::String^ UsbDeviceIADDescriptorType::InterfaceError::get() { + return this->interfaceErrorField; + } + inline System::Void UsbDeviceIADDescriptorType::InterfaceError::set(System::String^ value) { + this->interfaceErrorField = value; + } + + inline System::String^ UsbDeviceIADDescriptorType::FunctionClassError::get() { + return this->functionClassErrorField; + } + inline System::Void UsbDeviceIADDescriptorType::FunctionClassError::set(System::String^ value) { + this->functionClassErrorField = value; + } + + inline System::String^ UsbDeviceIADDescriptorType::Protocol::get() { + return this->protocolField; + } + inline System::Void UsbDeviceIADDescriptorType::Protocol::set(System::String^ value) { + this->protocolField = value; + } + + inline System::String^ UsbDeviceIADDescriptorType::StringDesc::get() { + return this->stringDescField; + } + inline System::Void UsbDeviceIADDescriptorType::StringDesc::set(System::String^ value) { + this->stringDescField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceIADDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceIADDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BFirstInterface::get() { + return this->bFirstInterfaceField; + } + inline System::Void UsbDeviceIADDescriptorType::BFirstInterface::set(System::Byte value) { + this->bFirstInterfaceField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BInterfaceCount::get() { + return this->bInterfaceCountField; + } + inline System::Void UsbDeviceIADDescriptorType::BInterfaceCount::set(System::Byte value) { + this->bInterfaceCountField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BFunctionClass::get() { + return this->bFunctionClassField; + } + inline System::Void UsbDeviceIADDescriptorType::BFunctionClass::set(System::Byte value) { + this->bFunctionClassField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BFunctionSubclass::get() { + return this->bFunctionSubclassField; + } + inline System::Void UsbDeviceIADDescriptorType::BFunctionSubclass::set(System::Byte value) { + this->bFunctionSubclassField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::BFunctionProtocol::get() { + return this->bFunctionProtocolField; + } + inline System::Void UsbDeviceIADDescriptorType::BFunctionProtocol::set(System::Byte value) { + this->bFunctionProtocolField = value; + } + + inline System::Byte UsbDeviceIADDescriptorType::IFunction::get() { + return this->iFunctionField; + } + inline System::Void UsbDeviceIADDescriptorType::IFunction::set(System::Byte value) { + this->iFunctionField = value; + } + + + inline System::String^ UsbDeviceClassType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void UsbDeviceClassType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::String^ UsbDeviceClassType::DeviceSubclass::get() { + return this->deviceSubclassField; + } + inline System::Void UsbDeviceClassType::DeviceSubclass::set(System::String^ value) { + this->deviceSubclassField = value; + } + + + inline System::Byte UsbDeviceOTGDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceOTGDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceOTGDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceOTGDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbDeviceOTGDescriptorType::BmAttributes::get() { + return this->bmAttributesField; + } + inline System::Void UsbDeviceOTGDescriptorType::BmAttributes::set(System::Byte value) { + this->bmAttributesField = value; + } + + inline System::String^ UsbDeviceOTGDescriptorType::AttributesString::get() { + return this->attributesStringField; + } + inline System::Void UsbDeviceOTGDescriptorType::AttributesString::set(System::String^ value) { + this->attributesStringField = value; + } + + + inline System::Byte UsbDeviceHidOptionalDescriptorsType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceHidOptionalDescriptorsType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::UInt16 UsbDeviceHidOptionalDescriptorsType::WDescriptorLength::get() { + return this->wDescriptorLengthField; + } + inline System::Void UsbDeviceHidOptionalDescriptorsType::WDescriptorLength::set(System::UInt16 value) { + this->wDescriptorLengthField = value; + } + + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ UsbDeviceHidDescriptorType::OptionalDescriptor::get() { + return this->optionalDescriptorField; + } + inline System::Void UsbDeviceHidDescriptorType::OptionalDescriptor::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceHidOptionalDescriptorsType^ >^ value) { + this->optionalDescriptorField = value; + } + + inline System::Byte UsbDeviceHidDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceHidDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceHidDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceHidDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::UInt16 UsbDeviceHidDescriptorType::BcdHID::get() { + return this->bcdHIDField; + } + inline System::Void UsbDeviceHidDescriptorType::BcdHID::set(System::UInt16 value) { + this->bcdHIDField = value; + } + + inline System::Byte UsbDeviceHidDescriptorType::BCountryCode::get() { + return this->bCountryCodeField; + } + inline System::Void UsbDeviceHidDescriptorType::BCountryCode::set(System::Byte value) { + this->bCountryCodeField = value; + } + + inline System::Byte UsbDeviceHidDescriptorType::BNumDescriptors::get() { + return this->bNumDescriptorsField; + } + inline System::Void UsbDeviceHidDescriptorType::BNumDescriptors::set(System::Byte value) { + this->bNumDescriptorsField = value; + } + + + inline Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ UsbDeviceInterfaceDescriptorType::InterfaceDetails::get() { + return this->interfaceDetailsField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::InterfaceDetails::set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value) { + this->interfaceDetailsField = value; + } + + inline System::String^ UsbDeviceInterfaceDescriptorType::ProtocolError::get() { + return this->protocolErrorField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::ProtocolError::set(System::String^ value) { + this->protocolErrorField = value; + } + + inline System::String^ UsbDeviceInterfaceDescriptorType::StringDesc::get() { + return this->stringDescField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::StringDesc::set(System::String^ value) { + this->stringDescField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BInterfaceNumber::get() { + return this->bInterfaceNumberField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BInterfaceNumber::set(System::Byte value) { + this->bInterfaceNumberField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BAlternateSetting::get() { + return this->bAlternateSettingField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BAlternateSetting::set(System::Byte value) { + this->bAlternateSettingField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BNumEndpoints::get() { + return this->bNumEndpointsField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BNumEndpoints::set(System::Byte value) { + this->bNumEndpointsField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BInterfaceClass::get() { + return this->bInterfaceClassField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BInterfaceClass::set(System::Byte value) { + this->bInterfaceClassField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BInterfaceSubclass::get() { + return this->bInterfaceSubclassField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BInterfaceSubclass::set(System::Byte value) { + this->bInterfaceSubclassField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::BInterfaceProtocol::get() { + return this->bInterfaceProtocolField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::BInterfaceProtocol::set(System::Byte value) { + this->bInterfaceProtocolField = value; + } + + inline System::Byte UsbDeviceInterfaceDescriptorType::IInterface::get() { + return this->iInterfaceField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::IInterface::set(System::Byte value) { + this->iInterfaceField = value; + } + + inline System::UInt16 UsbDeviceInterfaceDescriptorType::WNumClasses::get() { + return this->wNumClassesField; + } + inline System::Void UsbDeviceInterfaceDescriptorType::WNumClasses::set(System::UInt16 value) { + this->wNumClassesField = value; + } + + + inline System::String^ UsbDeviceQualifierDescriptorType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void UsbDeviceQualifierDescriptorType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::MaxPacketSizeInBytes::get() { + return this->maxPacketSizeInBytesField; + } + inline System::Void UsbDeviceQualifierDescriptorType::MaxPacketSizeInBytes::set(System::Byte value) { + this->maxPacketSizeInBytesField = value; + } + + inline System::Boolean UsbDeviceQualifierDescriptorType::MaxPacketSizeInBytesSpecified::get() { + return this->maxPacketSizeInBytesFieldSpecified; + } + inline System::Void UsbDeviceQualifierDescriptorType::MaxPacketSizeInBytesSpecified::set(System::Boolean value) { + this->maxPacketSizeInBytesFieldSpecified = value; + } + + inline System::String^ UsbDeviceQualifierDescriptorType::DeviceClassError::get() { + return this->deviceClassErrorField; + } + inline System::Void UsbDeviceQualifierDescriptorType::DeviceClassError::set(System::String^ value) { + this->deviceClassErrorField = value; + } + + inline System::String^ UsbDeviceQualifierDescriptorType::DeviceSubclassError::get() { + return this->deviceSubclassErrorField; + } + inline System::Void UsbDeviceQualifierDescriptorType::DeviceSubclassError::set(System::String^ value) { + this->deviceSubclassErrorField = value; + } + + inline System::String^ UsbDeviceQualifierDescriptorType::DeviceProtocolError::get() { + return this->deviceProtocolErrorField; + } + inline System::Void UsbDeviceQualifierDescriptorType::DeviceProtocolError::set(System::String^ value) { + this->deviceProtocolErrorField = value; + } + + inline System::String^ UsbDeviceQualifierDescriptorType::DeviceNumConfigError::get() { + return this->deviceNumConfigErrorField; + } + inline System::Void UsbDeviceQualifierDescriptorType::DeviceNumConfigError::set(System::String^ value) { + this->deviceNumConfigErrorField = value; + } + + inline System::String^ UsbDeviceQualifierDescriptorType::ReservedError::get() { + return this->reservedErrorField; + } + inline System::Void UsbDeviceQualifierDescriptorType::ReservedError::set(System::String^ value) { + this->reservedErrorField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::UInt16 UsbDeviceQualifierDescriptorType::BcdUSB::get() { + return this->bcdUSBField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BcdUSB::set(System::UInt16 value) { + this->bcdUSBField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BDeviceClass::get() { + return this->bDeviceClassField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BDeviceClass::set(System::Byte value) { + this->bDeviceClassField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BDeviceSubclass::get() { + return this->bDeviceSubclassField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BDeviceSubclass::set(System::Byte value) { + this->bDeviceSubclassField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BDeviceProtocol::get() { + return this->bDeviceProtocolField; + } + inline System::Void UsbDeviceQualifierDescriptorType::BDeviceProtocol::set(System::Byte value) { + this->bDeviceProtocolField = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::BMaxPacketSize0::get() { + return this->bMaxPacketSize0Field; + } + inline System::Void UsbDeviceQualifierDescriptorType::BMaxPacketSize0::set(System::Byte value) { + this->bMaxPacketSize0Field = value; + } + + inline System::Byte UsbDeviceQualifierDescriptorType::NumConfigurations::get() { + return this->numConfigurationsField; + } + inline System::Void UsbDeviceQualifierDescriptorType::NumConfigurations::set(System::Byte value) { + this->numConfigurationsField = value; + } + + + inline System::String^ UsbConfigurationDescriptorType::ConfigDescError::get() { + return this->configDescErrorField; + } + inline System::Void UsbConfigurationDescriptorType::ConfigDescError::set(System::String^ value) { + this->configDescErrorField = value; + } + + inline System::String^ UsbConfigurationDescriptorType::ConfValueError::get() { + return this->confValueErrorField; + } + inline System::Void UsbConfigurationDescriptorType::ConfValueError::set(System::String^ value) { + this->confValueErrorField = value; + } + + inline System::String^ UsbConfigurationDescriptorType::ConfStringDesc::get() { + return this->confStringDescField; + } + inline System::Void UsbConfigurationDescriptorType::ConfStringDesc::set(System::String^ value) { + this->confStringDescField = value; + } + + inline System::String^ UsbConfigurationDescriptorType::AttributesStr::get() { + return this->attributesStrField; + } + inline System::Void UsbConfigurationDescriptorType::AttributesStr::set(System::String^ value) { + this->attributesStrField = value; + } + + inline System::String^ UsbConfigurationDescriptorType::MaxCurrent::get() { + return this->maxCurrentField; + } + inline System::Void UsbConfigurationDescriptorType::MaxCurrent::set(System::String^ value) { + this->maxCurrentField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::BLength::get() { + return this->bLengthField; + } + inline System::Void UsbConfigurationDescriptorType::BLength::set(System::Byte value) { + this->bLengthField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::BDescriptorType::get() { + return this->bDescriptorTypeField; + } + inline System::Void UsbConfigurationDescriptorType::BDescriptorType::set(System::Byte value) { + this->bDescriptorTypeField = value; + } + + inline System::UInt16 UsbConfigurationDescriptorType::WTotalLength::get() { + return this->wTotalLengthField; + } + inline System::Void UsbConfigurationDescriptorType::WTotalLength::set(System::UInt16 value) { + this->wTotalLengthField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::BNumInterfaces::get() { + return this->bNumInterfacesField; + } + inline System::Void UsbConfigurationDescriptorType::BNumInterfaces::set(System::Byte value) { + this->bNumInterfacesField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::BConfigurationValue::get() { + return this->bConfigurationValueField; + } + inline System::Void UsbConfigurationDescriptorType::BConfigurationValue::set(System::Byte value) { + this->bConfigurationValueField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::IConfiguration::get() { + return this->iConfigurationField; + } + inline System::Void UsbConfigurationDescriptorType::IConfiguration::set(System::Byte value) { + this->iConfigurationField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::BmAttributes::get() { + return this->bmAttributesField; + } + inline System::Void UsbConfigurationDescriptorType::BmAttributes::set(System::Byte value) { + this->bmAttributesField = value; + } + + inline System::Byte UsbConfigurationDescriptorType::MaxPower::get() { + return this->maxPowerField; + } + inline System::Void UsbConfigurationDescriptorType::MaxPower::set(System::Byte value) { + this->maxPowerField = value; + } + + + inline System::String^ UsbDeviceConfigurationType::DeviceQualifierError::get() { + return this->deviceQualifierErrorField; + } + inline System::Void UsbDeviceConfigurationType::DeviceQualifierError::set(System::String^ value) { + this->deviceQualifierErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::SpeedConfigurationError::get() { + return this->speedConfigurationErrorField; + } + inline System::Void UsbDeviceConfigurationType::SpeedConfigurationError::set(System::String^ value) { + this->speedConfigurationErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::DeviceConfigurationError::get() { + return this->deviceConfigurationErrorField; + } + inline System::Void UsbDeviceConfigurationType::DeviceConfigurationError::set(System::String^ value) { + this->deviceConfigurationErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::InterfaceError::get() { + return this->interfaceErrorField; + } + inline System::Void UsbDeviceConfigurationType::InterfaceError::set(System::String^ value) { + this->interfaceErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::PreReleaseError::get() { + return this->preReleaseErrorField; + } + inline System::Void UsbDeviceConfigurationType::PreReleaseError::set(System::String^ value) { + this->preReleaseErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::EndpointError::get() { + return this->endpointErrorField; + } + inline System::Void UsbDeviceConfigurationType::EndpointError::set(System::String^ value) { + this->endpointErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::HidError::get() { + return this->hidErrorField; + } + inline System::Void UsbDeviceConfigurationType::HidError::set(System::String^ value) { + this->hidErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::OtgError::get() { + return this->otgErrorField; + } + inline System::Void UsbDeviceConfigurationType::OtgError::set(System::String^ value) { + this->otgErrorField = value; + } + + inline System::String^ UsbDeviceConfigurationType::IadError::get() { + return this->iadErrorField; + } + inline System::Void UsbDeviceConfigurationType::IadError::set(System::String^ value) { + this->iadErrorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ UsbDeviceConfigurationType::DeviceDetails::get() { + return this->deviceDetailsField; + } + inline System::Void UsbDeviceConfigurationType::DeviceDetails::set(Microsoft::Kits::Samples::Usb::UsbDeviceClassType^ value) { + this->deviceDetailsField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ UsbDeviceConfigurationType::ConfigurationDescriptor::get() { + return this->configurationDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::ConfigurationDescriptor::set(Microsoft::Kits::Samples::Usb::UsbConfigurationDescriptorType^ value) { + this->configurationDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ UsbDeviceConfigurationType::DeviceQualifierDescriptor::get() { + return this->deviceQualifierDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::DeviceQualifierDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceQualifierDescriptorType^ value) { + this->deviceQualifierDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ UsbDeviceConfigurationType::InterfaceDescriptor::get() { + return this->interfaceDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::InterfaceDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceInterfaceDescriptorType^ value) { + this->interfaceDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ UsbDeviceConfigurationType::EndpointDescriptor::get() { + return this->endpointDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::EndpointDescriptor::set(Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ value) { + this->endpointDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ UsbDeviceConfigurationType::HidDescriptor::get() { + return this->hidDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::HidDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceHidDescriptorType^ value) { + this->hidDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ UsbDeviceConfigurationType::OtgDescriptor::get() { + return this->otgDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::OtgDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceOTGDescriptorType^ value) { + this->otgDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ UsbDeviceConfigurationType::IadDescriptor::get() { + return this->iadDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::IadDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceIADDescriptorType^ value) { + this->iadDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ UsbDeviceConfigurationType::UnknownDescriptor::get() { + return this->unknownDescriptorField; + } + inline System::Void UsbDeviceConfigurationType::UnknownDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceUnknownDescriptorType^ value) { + this->unknownDescriptorField = value; + } + + + inline System::Byte EndpointDescriptorType::Length::get() { + return this->lengthField; + } + inline System::Void EndpointDescriptorType::Length::set(System::Byte value) { + this->lengthField = value; + } + + inline System::Byte EndpointDescriptorType::DescriptorType::get() { + return this->descriptorTypeField; + } + inline System::Void EndpointDescriptorType::DescriptorType::set(System::Byte value) { + this->descriptorTypeField = value; + } + + inline System::Byte EndpointDescriptorType::EndpointAddress::get() { + return this->endpointAddressField; + } + inline System::Void EndpointDescriptorType::EndpointAddress::set(System::Byte value) { + this->endpointAddressField = value; + } + + inline System::Byte EndpointDescriptorType::Attributes::get() { + return this->attributesField; + } + inline System::Void EndpointDescriptorType::Attributes::set(System::Byte value) { + this->attributesField = value; + } + + inline System::UInt16 EndpointDescriptorType::MaxPacketSize::get() { + return this->maxPacketSizeField; + } + inline System::Void EndpointDescriptorType::MaxPacketSize::set(System::UInt16 value) { + this->maxPacketSizeField = value; + } + + inline System::Byte EndpointDescriptorType::Interval::get() { + return this->intervalField; + } + inline System::Void EndpointDescriptorType::Interval::set(System::Byte value) { + this->intervalField = value; + } + + inline System::UInt16 EndpointDescriptorType::WInterval::get() { + return this->wIntervalField; + } + inline System::Void EndpointDescriptorType::WInterval::set(System::UInt16 value) { + this->wIntervalField = value; + } + + inline System::Byte EndpointDescriptorType::SyncAddress::get() { + return this->syncAddressField; + } + inline System::Void EndpointDescriptorType::SyncAddress::set(System::Byte value) { + this->syncAddressField = value; + } + + inline System::String^ EndpointDescriptorType::EndpointDirection::get() { + return this->endpointDirectionField; + } + inline System::Void EndpointDescriptorType::EndpointDirection::set(System::String^ value) { + this->endpointDirectionField = value; + } + + inline System::Byte EndpointDescriptorType::EndpointId::get() { + return this->endpointIdField; + } + inline System::Void EndpointDescriptorType::EndpointId::set(System::Byte value) { + this->endpointIdField = value; + } + + inline System::String^ EndpointDescriptorType::EndpointType::get() { + return this->endpointTypeField; + } + inline System::Void EndpointDescriptorType::EndpointType::set(System::String^ value) { + this->endpointTypeField = value; + } + + inline System::String^ EndpointDescriptorType::EndpointPacketInfo::get() { + return this->endpointPacketInfoField; + } + inline System::Void EndpointDescriptorType::EndpointPacketInfo::set(System::String^ value) { + this->endpointPacketInfoField = value; + } + + inline System::String^ EndpointDescriptorType::EndpointPacketSizeValidation::get() { + return this->endpointPacketSizeValidationField; + } + inline System::Void EndpointDescriptorType::EndpointPacketSizeValidation::set(System::String^ value) { + this->endpointPacketSizeValidationField = value; + } + + + inline Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ UsbDeviceType::ConnectionInfo::get() { + return this->connectionInfoField; + } + inline System::Void UsbDeviceType::ConnectionInfo::set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ value) { + this->connectionInfoField = value; + } + + inline Microsoft::Kits::Samples::Usb::PortConnectorType^ UsbDeviceType::PortConnector::get() { + return this->portConnectorField; + } + inline System::Void UsbDeviceType::PortConnector::set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value) { + this->portConnectorField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ UsbDeviceType::DeviceConfiguration::get() { + return this->deviceConfigurationField; + } + inline System::Void UsbDeviceType::DeviceConfiguration::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ value) { + this->deviceConfigurationField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ UsbDeviceType::BosDescriptor::get() { + return this->bosDescriptorField; + } + inline System::Void UsbDeviceType::BosDescriptor::set(Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ value) { + this->bosDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ UsbDeviceType::ConnectionInfoV2::get() { + return this->connectionInfoV2Field; + } + inline System::Void UsbDeviceType::ConnectionInfoV2::set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ value) { + this->connectionInfoV2Field = value; + } + + inline System::String^ UsbDeviceType::UsbPortNumber::get() { + return this->usbPortNumberField; + } + inline System::Void UsbDeviceType::UsbPortNumber::set(System::String^ value) { + this->usbPortNumberField = value; + } + + inline System::String^ UsbDeviceType::ServiceName::get() { + return this->serviceNameField; + } + inline System::Void UsbDeviceType::ServiceName::set(System::String^ value) { + this->serviceNameField = value; + } + + inline System::String^ UsbDeviceType::HwId::get() { + return this->hwIdField; + } + inline System::Void UsbDeviceType::HwId::set(System::String^ value) { + this->hwIdField = value; + } + + inline System::String^ UsbDeviceType::DeviceId::get() { + return this->deviceIdField; + } + inline System::Void UsbDeviceType::DeviceId::set(System::String^ value) { + this->deviceIdField = value; + } + + inline System::String^ UsbDeviceType::DeviceName::get() { + return this->deviceNameField; + } + inline System::Void UsbDeviceType::DeviceName::set(System::String^ value) { + this->deviceNameField = value; + } + + inline System::String^ UsbDeviceType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void UsbDeviceType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::String^ UsbDeviceType::UsbProtocol::get() { + return this->usbProtocolField; + } + inline System::Void UsbDeviceType::UsbProtocol::set(System::String^ value) { + this->usbProtocolField = value; + } + + + inline Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ NodeConnectionInfoExType::ConnectionInfoStruct::get() { + return this->connectionInfoStructField; + } + inline System::Void NodeConnectionInfoExType::ConnectionInfoStruct::set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExStructType^ value) { + this->connectionInfoStructField = value; + } + + inline System::String^ NodeConnectionInfoExType::IProductStringDescEn::get() { + return this->iProductStringDescEnField; + } + inline System::Void NodeConnectionInfoExType::IProductStringDescEn::set(System::String^ value) { + this->iProductStringDescEnField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ NodeConnectionInfoExType::DeviceClassDetails::get() { + return this->deviceClassDetailsField; + } + inline System::Void NodeConnectionInfoExType::DeviceClassDetails::set(Microsoft::Kits::Samples::Usb::UsbDeviceClassDetailsType^ value) { + this->deviceClassDetailsField = value; + } + + inline System::Byte NodeConnectionInfoExType::MaxPacketSizeInBytes::get() { + return this->maxPacketSizeInBytesField; + } + inline System::Void NodeConnectionInfoExType::MaxPacketSizeInBytes::set(System::Byte value) { + this->maxPacketSizeInBytesField = value; + } + + inline System::String^ NodeConnectionInfoExType::VendorString::get() { + return this->vendorStringField; + } + inline System::Void NodeConnectionInfoExType::VendorString::set(System::String^ value) { + this->vendorStringField = value; + } + + inline System::String^ NodeConnectionInfoExType::ManufacturerString::get() { + return this->manufacturerStringField; + } + inline System::Void NodeConnectionInfoExType::ManufacturerString::set(System::String^ value) { + this->manufacturerStringField = value; + } + + inline System::String^ NodeConnectionInfoExType::ProductString::get() { + return this->productStringField; + } + inline System::Void NodeConnectionInfoExType::ProductString::set(System::String^ value) { + this->productStringField = value; + } + + inline System::String^ NodeConnectionInfoExType::LangIdString::get() { + return this->langIdStringField; + } + inline System::Void NodeConnectionInfoExType::LangIdString::set(System::String^ value) { + this->langIdStringField = value; + } + + inline System::String^ NodeConnectionInfoExType::SerialString::get() { + return this->serialStringField; + } + inline System::Void NodeConnectionInfoExType::SerialString::set(System::String^ value) { + this->serialStringField = value; + } + + inline System::String^ NodeConnectionInfoExType::PipeInfoError::get() { + return this->pipeInfoErrorField; + } + inline System::Void NodeConnectionInfoExType::PipeInfoError::set(System::String^ value) { + this->pipeInfoErrorField = value; + } + + inline System::String^ NodeConnectionInfoExType::LengthError::get() { + return this->lengthErrorField; + } + inline System::Void NodeConnectionInfoExType::LengthError::set(System::String^ value) { + this->lengthErrorField = value; + } + + inline System::String^ NodeConnectionInfoExType::DeviceError::get() { + return this->deviceErrorField; + } + inline System::Void NodeConnectionInfoExType::DeviceError::set(System::String^ value) { + this->deviceErrorField = value; + } + + inline System::String^ NodeConnectionInfoExType::PacketSizeError::get() { + return this->packetSizeErrorField; + } + inline System::Void NodeConnectionInfoExType::PacketSizeError::set(System::String^ value) { + this->packetSizeErrorField = value; + } + + inline System::String^ NodeConnectionInfoExType::ConfigurationCountError::get() { + return this->configurationCountErrorField; + } + inline System::Void NodeConnectionInfoExType::ConfigurationCountError::set(System::String^ value) { + this->configurationCountErrorField = value; + } + + + inline System::UInt64 NodeConnectionInfoExStructType::ConnectionIndex::get() { + return this->connectionIndexField; + } + inline System::Void NodeConnectionInfoExStructType::ConnectionIndex::set(System::UInt64 value) { + this->connectionIndexField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ NodeConnectionInfoExStructType::DeviceDescriptor::get() { + return this->deviceDescriptorField; + } + inline System::Void NodeConnectionInfoExStructType::DeviceDescriptor::set(Microsoft::Kits::Samples::Usb::UsbDeviceDescriptorType^ value) { + this->deviceDescriptorField = value; + } + + inline System::Byte NodeConnectionInfoExStructType::CurrentConfigurationValue::get() { + return this->currentConfigurationValueField; + } + inline System::Void NodeConnectionInfoExStructType::CurrentConfigurationValue::set(System::Byte value) { + this->currentConfigurationValueField = value; + } + + inline System::Byte NodeConnectionInfoExStructType::Speed::get() { + return this->speedField; + } + inline System::Void NodeConnectionInfoExStructType::Speed::set(System::Byte value) { + this->speedField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType NodeConnectionInfoExStructType::SpeedStr::get() { + return this->speedStrField; + } + inline System::Void NodeConnectionInfoExStructType::SpeedStr::set(Microsoft::Kits::Samples::Usb::UsbConnectionSpeedType value) { + this->speedStrField = value; + } + + inline System::Boolean NodeConnectionInfoExStructType::DeviceIsHub::get() { + return this->deviceIsHubField; + } + inline System::Void NodeConnectionInfoExStructType::DeviceIsHub::set(System::Boolean value) { + this->deviceIsHubField = value; + } + + inline System::Byte NodeConnectionInfoExStructType::DeviceAddress::get() { + return this->deviceAddressField; + } + inline System::Void NodeConnectionInfoExStructType::DeviceAddress::set(System::Byte value) { + this->deviceAddressField = value; + } + + inline System::UInt64 NodeConnectionInfoExStructType::NumOfOpenPipes::get() { + return this->numOfOpenPipesField; + } + inline System::Void NodeConnectionInfoExStructType::NumOfOpenPipes::set(System::UInt64 value) { + this->numOfOpenPipesField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbConnectionStatusType NodeConnectionInfoExStructType::UsbConnectionStatus::get() { + return this->usbConnectionStatusField; + } + inline System::Void NodeConnectionInfoExStructType::UsbConnectionStatus::set(Microsoft::Kits::Samples::Usb::UsbConnectionStatusType value) { + this->usbConnectionStatusField = value; + } + + inline Microsoft::Kits::Samples::Usb::DevicePowerStateType NodeConnectionInfoExStructType::DevicePowerState::get() { + return this->devicePowerStateField; + } + inline System::Void NodeConnectionInfoExStructType::DevicePowerState::set(Microsoft::Kits::Samples::Usb::DevicePowerStateType value) { + this->devicePowerStateField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ NodeConnectionInfoExStructType::Pipe::get() { + return this->pipeField; + } + inline System::Void NodeConnectionInfoExStructType::Pipe::set(cli::array< Microsoft::Kits::Samples::Usb::UsbPipeInfoType^ >^ value) { + this->pipeField = value; + } + + + inline System::Byte UsbDeviceDescriptorType::Length::get() { + return this->lengthField; + } + inline System::Void UsbDeviceDescriptorType::Length::set(System::Byte value) { + this->lengthField = value; + } + + inline System::Byte UsbDeviceDescriptorType::DescriptorType::get() { + return this->descriptorTypeField; + } + inline System::Void UsbDeviceDescriptorType::DescriptorType::set(System::Byte value) { + this->descriptorTypeField = value; + } + + inline System::UInt16 UsbDeviceDescriptorType::CdUSB::get() { + return this->cdUSBField; + } + inline System::Void UsbDeviceDescriptorType::CdUSB::set(System::UInt16 value) { + this->cdUSBField = value; + } + + inline System::Byte UsbDeviceDescriptorType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void UsbDeviceDescriptorType::DeviceClass::set(System::Byte value) { + this->deviceClassField = value; + } + + inline System::Byte UsbDeviceDescriptorType::DeviceSubclass::get() { + return this->deviceSubclassField; + } + inline System::Void UsbDeviceDescriptorType::DeviceSubclass::set(System::Byte value) { + this->deviceSubclassField = value; + } + + inline System::Byte UsbDeviceDescriptorType::DeviceProtocol::get() { + return this->deviceProtocolField; + } + inline System::Void UsbDeviceDescriptorType::DeviceProtocol::set(System::Byte value) { + this->deviceProtocolField = value; + } + + inline System::Byte UsbDeviceDescriptorType::MaxPacketSize0::get() { + return this->maxPacketSize0Field; + } + inline System::Void UsbDeviceDescriptorType::MaxPacketSize0::set(System::Byte value) { + this->maxPacketSize0Field = value; + } + + inline System::UInt16 UsbDeviceDescriptorType::IdVendor::get() { + return this->idVendorField; + } + inline System::Void UsbDeviceDescriptorType::IdVendor::set(System::UInt16 value) { + this->idVendorField = value; + } + + inline System::UInt16 UsbDeviceDescriptorType::IdProduct::get() { + return this->idProductField; + } + inline System::Void UsbDeviceDescriptorType::IdProduct::set(System::UInt16 value) { + this->idProductField = value; + } + + inline System::UInt16 UsbDeviceDescriptorType::CdDevice::get() { + return this->cdDeviceField; + } + inline System::Void UsbDeviceDescriptorType::CdDevice::set(System::UInt16 value) { + this->cdDeviceField = value; + } + + inline System::Byte UsbDeviceDescriptorType::IManufacturer::get() { + return this->iManufacturerField; + } + inline System::Void UsbDeviceDescriptorType::IManufacturer::set(System::Byte value) { + this->iManufacturerField = value; + } + + inline System::Byte UsbDeviceDescriptorType::IProduct::get() { + return this->iProductField; + } + inline System::Void UsbDeviceDescriptorType::IProduct::set(System::Byte value) { + this->iProductField = value; + } + + inline System::Byte UsbDeviceDescriptorType::ISerialNumber::get() { + return this->iSerialNumberField; + } + inline System::Void UsbDeviceDescriptorType::ISerialNumber::set(System::Byte value) { + this->iSerialNumberField = value; + } + + inline System::Byte UsbDeviceDescriptorType::NumConfigurations::get() { + return this->numConfigurationsField; + } + inline System::Void UsbDeviceDescriptorType::NumConfigurations::set(System::Byte value) { + this->numConfigurationsField = value; + } + + + inline Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ UsbPipeInfoType::EndpointDescriptor::get() { + return this->endpointDescriptorField; + } + inline System::Void UsbPipeInfoType::EndpointDescriptor::set(Microsoft::Kits::Samples::Usb::EndpointDescriptorType^ value) { + this->endpointDescriptorField = value; + } + + inline System::UInt64 UsbPipeInfoType::ScheduleOffset::get() { + return this->scheduleOffsetField; + } + inline System::Void UsbPipeInfoType::ScheduleOffset::set(System::UInt64 value) { + this->scheduleOffsetField = value; + } + + + inline System::String^ UsbDeviceClassDetailsType::DeviceType::get() { + return this->deviceTypeField; + } + inline System::Void UsbDeviceClassDetailsType::DeviceType::set(System::String^ value) { + this->deviceTypeField = value; + } + + inline System::String^ UsbDeviceClassDetailsType::DeviceTypeError::get() { + return this->deviceTypeErrorField; + } + inline System::Void UsbDeviceClassDetailsType::DeviceTypeError::set(System::String^ value) { + this->deviceTypeErrorField = value; + } + + inline System::String^ UsbDeviceClassDetailsType::SubclassType::get() { + return this->subclassTypeField; + } + inline System::Void UsbDeviceClassDetailsType::SubclassType::set(System::String^ value) { + this->subclassTypeField = value; + } + + inline System::String^ UsbDeviceClassDetailsType::SubclassTypeError::get() { + return this->subclassTypeErrorField; + } + inline System::Void UsbDeviceClassDetailsType::SubclassTypeError::set(System::String^ value) { + this->subclassTypeErrorField = value; + } + + inline System::String^ UsbDeviceClassDetailsType::DeviceProtocol::get() { + return this->deviceProtocolField; + } + inline System::Void UsbDeviceClassDetailsType::DeviceProtocol::set(System::String^ value) { + this->deviceProtocolField = value; + } + + inline System::String^ UsbDeviceClassDetailsType::DeviceProtocolError::get() { + return this->deviceProtocolErrorField; + } + inline System::Void UsbDeviceClassDetailsType::DeviceProtocolError::set(System::String^ value) { + this->deviceProtocolErrorField = value; + } + + inline System::UInt32 UsbDeviceClassDetailsType::UvcVersion::get() { + return this->uvcVersionField; + } + inline System::Void UsbDeviceClassDetailsType::UvcVersion::set(System::UInt32 value) { + this->uvcVersionField = value; + } + + + inline Microsoft::Kits::Samples::Usb::HubNodeInformationType^ ExternalHubType::HubNodeInformation::get() { + return this->hubNodeInformationField; + } + inline System::Void ExternalHubType::HubNodeInformation::set(Microsoft::Kits::Samples::Usb::HubNodeInformationType^ value) { + this->hubNodeInformationField = value; + } + + inline System::String^ ExternalHubType::HubName::get() { + return this->hubNameField; + } + inline System::Void ExternalHubType::HubName::set(System::String^ value) { + this->hubNameField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubInformationExType^ ExternalHubType::HubInformationEx::get() { + return this->hubInformationExField; + } + inline System::Void ExternalHubType::HubInformationEx::set(Microsoft::Kits::Samples::Usb::HubInformationExType^ value) { + this->hubInformationExField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ ExternalHubType::HubCapabilityEx::get() { + return this->hubCapabilityExField; + } + inline System::Void ExternalHubType::HubCapabilityEx::set(Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ value) { + this->hubCapabilityExField = value; + } + + inline Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ ExternalHubType::ConnectionInfo::get() { + return this->connectionInfoField; + } + inline System::Void ExternalHubType::ConnectionInfo::set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExType^ value) { + this->connectionInfoField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ ExternalHubType::UsbDevice::get() { + return this->usbDeviceField; + } + inline System::Void ExternalHubType::UsbDevice::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ value) { + this->usbDeviceField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ ExternalHubType::NoDevice::get() { + return this->noDeviceField; + } + inline System::Void ExternalHubType::NoDevice::set(cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ value) { + this->noDeviceField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ ExternalHubType::DeviceConfiguration::get() { + return this->deviceConfigurationField; + } + inline System::Void ExternalHubType::DeviceConfiguration::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceConfigurationType^ >^ value) { + this->deviceConfigurationField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ ExternalHubType::BosDescriptor::get() { + return this->bosDescriptorField; + } + inline System::Void ExternalHubType::BosDescriptor::set(Microsoft::Kits::Samples::Usb::UsbBosDescriptorType^ value) { + this->bosDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ ExternalHubType::ConnectionInfoV2::get() { + return this->connectionInfoV2Field; + } + inline System::Void ExternalHubType::ConnectionInfoV2::set(Microsoft::Kits::Samples::Usb::NodeConnectionInfoExV2Type^ value) { + this->connectionInfoV2Field = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ ExternalHubType::ExternalHub::get() { + return this->externalHubField; + } + inline System::Void ExternalHubType::ExternalHub::set(cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ value) { + this->externalHubField = value; + } + + inline Microsoft::Kits::Samples::Usb::PortConnectorType^ ExternalHubType::PortConnector::get() { + return this->portConnectorField; + } + inline System::Void ExternalHubType::PortConnector::set(Microsoft::Kits::Samples::Usb::PortConnectorType^ value) { + this->portConnectorField = value; + } + + inline System::String^ ExternalHubType::ServiceName::get() { + return this->serviceNameField; + } + inline System::Void ExternalHubType::ServiceName::set(System::String^ value) { + this->serviceNameField = value; + } + + inline System::String^ ExternalHubType::HwId::get() { + return this->hwIdField; + } + inline System::Void ExternalHubType::HwId::set(System::String^ value) { + this->hwIdField = value; + } + + inline System::String^ ExternalHubType::DeviceId::get() { + return this->deviceIdField; + } + inline System::Void ExternalHubType::DeviceId::set(System::String^ value) { + this->deviceIdField = value; + } + + inline System::String^ ExternalHubType::DeviceName::get() { + return this->deviceNameField; + } + inline System::Void ExternalHubType::DeviceName::set(System::String^ value) { + this->deviceNameField = value; + } + + inline System::String^ ExternalHubType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void ExternalHubType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::String^ ExternalHubType::UsbProtocol::get() { + return this->usbProtocolField; + } + inline System::Void ExternalHubType::UsbProtocol::set(System::String^ value) { + this->usbProtocolField = value; + } + + + inline Microsoft::Kits::Samples::Usb::HubNodeType HubNodeInformationType::HubNode::get() { + return this->hubNodeField; + } + inline System::Void HubNodeInformationType::HubNode::set(Microsoft::Kits::Samples::Usb::HubNodeType value) { + this->hubNodeField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubInformationType^ HubNodeInformationType::HubInformation::get() { + return this->hubInformationField; + } + inline System::Void HubNodeInformationType::HubInformation::set(Microsoft::Kits::Samples::Usb::HubInformationType^ value) { + this->hubInformationField = value; + } + + inline System::UInt64 HubNodeInformationType::MiParentNumberOfInterfaces::get() { + return this->miParentNumberOfInterfacesField; + } + inline System::Void HubNodeInformationType::MiParentNumberOfInterfaces::set(System::UInt64 value) { + this->miParentNumberOfInterfacesField = value; + } + + + inline System::Boolean HubInformationType::IsRootHub::get() { + return this->isRootHubField; + } + inline System::Void HubInformationType::IsRootHub::set(System::Boolean value) { + this->isRootHubField = value; + } + + inline System::Boolean HubInformationType::IsBusPowered::get() { + return this->isBusPoweredField; + } + inline System::Void HubInformationType::IsBusPowered::set(System::Boolean value) { + this->isBusPoweredField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubDescriptorType^ HubInformationType::HubDescriptor::get() { + return this->hubDescriptorField; + } + inline System::Void HubInformationType::HubDescriptor::set(Microsoft::Kits::Samples::Usb::HubDescriptorType^ value) { + this->hubDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ HubInformationType::HubCharacteristics::get() { + return this->hubCharacteristicsField; + } + inline System::Void HubInformationType::HubCharacteristics::set(Microsoft::Kits::Samples::Usb::HubCharacteristicsType^ value) { + this->hubCharacteristicsField = value; + } + + + inline System::Byte HubDescriptorType::DescriptorLength::get() { + return this->descriptorLengthField; + } + inline System::Void HubDescriptorType::DescriptorLength::set(System::Byte value) { + this->descriptorLengthField = value; + } + + inline System::Byte HubDescriptorType::DescriptorType::get() { + return this->descriptorTypeField; + } + inline System::Void HubDescriptorType::DescriptorType::set(System::Byte value) { + this->descriptorTypeField = value; + } + + inline System::Byte HubDescriptorType::NumberOfPorts::get() { + return this->numberOfPortsField; + } + inline System::Void HubDescriptorType::NumberOfPorts::set(System::Byte value) { + this->numberOfPortsField = value; + } + + inline System::Byte HubDescriptorType::PowerOntoPowerGood::get() { + return this->powerOntoPowerGoodField; + } + inline System::Void HubDescriptorType::PowerOntoPowerGood::set(System::Byte value) { + this->powerOntoPowerGoodField = value; + } + + inline System::Byte HubDescriptorType::HubControlCurrent::get() { + return this->hubControlCurrentField; + } + inline System::Void HubDescriptorType::HubControlCurrent::set(System::Byte value) { + this->hubControlCurrentField = value; + } + + + inline System::UInt32 HubCharacteristicsType::HubCharacteristicsValue::get() { + return this->hubCharacteristicsValueField; + } + inline System::Void HubCharacteristicsType::HubCharacteristicsValue::set(System::UInt32 value) { + this->hubCharacteristicsValueField = value; + } + + inline System::String^ HubCharacteristicsType::PowerSwitching::get() { + return this->powerSwitchingField; + } + inline System::Void HubCharacteristicsType::PowerSwitching::set(System::String^ value) { + this->powerSwitchingField = value; + } + + inline System::Boolean HubCharacteristicsType::CompoundDevice::get() { + return this->compoundDeviceField; + } + inline System::Void HubCharacteristicsType::CompoundDevice::set(System::Boolean value) { + this->compoundDeviceField = value; + } + + inline System::String^ HubCharacteristicsType::OverCurrentProtection::get() { + return this->overCurrentProtectionField; + } + inline System::Void HubCharacteristicsType::OverCurrentProtection::set(System::String^ value) { + this->overCurrentProtectionField = value; + } + + + inline Microsoft::Kits::Samples::Usb::HubTypeType HubInformationExType::HubType::get() { + return this->hubTypeField; + } + inline System::Void HubInformationExType::HubType::set(Microsoft::Kits::Samples::Usb::HubTypeType value) { + this->hubTypeField = value; + } + + inline System::UInt16 HubInformationExType::HighestPortNumber::get() { + return this->highestPortNumberField; + } + inline System::Void HubInformationExType::HighestPortNumber::set(System::UInt16 value) { + this->highestPortNumberField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubDescriptorType^ HubInformationExType::HubDescriptor::get() { + return this->hubDescriptorField; + } + inline System::Void HubInformationExType::HubDescriptor::set(Microsoft::Kits::Samples::Usb::HubDescriptorType^ value) { + this->hubDescriptorField = value; + } + + inline Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ HubInformationExType::Hub30Descriptor::get() { + return this->hub30DescriptorField; + } + inline System::Void HubInformationExType::Hub30Descriptor::set(Microsoft::Kits::Samples::Usb::Hub30DescriptorType^ value) { + this->hub30DescriptorField = value; + } + + + inline System::Byte Hub30DescriptorType::Length::get() { + return this->lengthField; + } + inline System::Void Hub30DescriptorType::Length::set(System::Byte value) { + this->lengthField = value; + } + + inline System::Byte Hub30DescriptorType::DescriptorType::get() { + return this->descriptorTypeField; + } + inline System::Void Hub30DescriptorType::DescriptorType::set(System::Byte value) { + this->descriptorTypeField = value; + } + + inline System::Byte Hub30DescriptorType::NumberOfPorts::get() { + return this->numberOfPortsField; + } + inline System::Void Hub30DescriptorType::NumberOfPorts::set(System::Byte value) { + this->numberOfPortsField = value; + } + + inline System::UInt16 Hub30DescriptorType::HubCharacteristics::get() { + return this->hubCharacteristicsField; + } + inline System::Void Hub30DescriptorType::HubCharacteristics::set(System::UInt16 value) { + this->hubCharacteristicsField = value; + } + + inline System::Byte Hub30DescriptorType::PowerOntoPowerGood::get() { + return this->powerOntoPowerGoodField; + } + inline System::Void Hub30DescriptorType::PowerOntoPowerGood::set(System::Byte value) { + this->powerOntoPowerGoodField = value; + } + + inline System::Byte Hub30DescriptorType::HubControlCurrent::get() { + return this->hubControlCurrentField; + } + inline System::Void Hub30DescriptorType::HubControlCurrent::set(System::Byte value) { + this->hubControlCurrentField = value; + } + + inline System::Byte Hub30DescriptorType::HubHdrDecLat::get() { + return this->hubHdrDecLatField; + } + inline System::Void Hub30DescriptorType::HubHdrDecLat::set(System::Byte value) { + this->hubHdrDecLatField = value; + } + + inline System::UInt16 Hub30DescriptorType::HubDelay::get() { + return this->hubDelayField; + } + inline System::Void Hub30DescriptorType::HubDelay::set(System::UInt16 value) { + this->hubDelayField = value; + } + + inline System::UInt16 Hub30DescriptorType::DeviceRemovable::get() { + return this->deviceRemovableField; + } + inline System::Void Hub30DescriptorType::DeviceRemovable::set(System::UInt16 value) { + this->deviceRemovableField = value; + } + + + inline System::Boolean HubCapabilitiesExType::HubIsHighSpeedCapable::get() { + return this->hubIsHighSpeedCapableField; + } + inline System::Void HubCapabilitiesExType::HubIsHighSpeedCapable::set(System::Boolean value) { + this->hubIsHighSpeedCapableField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsHighSpeed::get() { + return this->hubIsHighSpeedField; + } + inline System::Void HubCapabilitiesExType::HubIsHighSpeed::set(System::Boolean value) { + this->hubIsHighSpeedField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsMultiTtCapable::get() { + return this->hubIsMultiTtCapableField; + } + inline System::Void HubCapabilitiesExType::HubIsMultiTtCapable::set(System::Boolean value) { + this->hubIsMultiTtCapableField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsMultiTt::get() { + return this->hubIsMultiTtField; + } + inline System::Void HubCapabilitiesExType::HubIsMultiTt::set(System::Boolean value) { + this->hubIsMultiTtField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsRoot::get() { + return this->hubIsRootField; + } + inline System::Void HubCapabilitiesExType::HubIsRoot::set(System::Boolean value) { + this->hubIsRootField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsArmedWakeOnConnect::get() { + return this->hubIsArmedWakeOnConnectField; + } + inline System::Void HubCapabilitiesExType::HubIsArmedWakeOnConnect::set(System::Boolean value) { + this->hubIsArmedWakeOnConnectField = value; + } + + inline System::Boolean HubCapabilitiesExType::HubIsBusPowered::get() { + return this->hubIsBusPoweredField; + } + inline System::Void HubCapabilitiesExType::HubIsBusPowered::set(System::Boolean value) { + this->hubIsBusPoweredField = value; + } + + + inline Microsoft::Kits::Samples::Usb::HubNodeInformationType^ RootHubType::HubNodeInformation::get() { + return this->hubNodeInformationField; + } + inline System::Void RootHubType::HubNodeInformation::set(Microsoft::Kits::Samples::Usb::HubNodeInformationType^ value) { + this->hubNodeInformationField = value; + } + + inline System::String^ RootHubType::HubName::get() { + return this->hubNameField; + } + inline System::Void RootHubType::HubName::set(System::String^ value) { + this->hubNameField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubInformationExType^ RootHubType::HubInformationEx::get() { + return this->hubInformationExField; + } + inline System::Void RootHubType::HubInformationEx::set(Microsoft::Kits::Samples::Usb::HubInformationExType^ value) { + this->hubInformationExField = value; + } + + inline Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ RootHubType::HubCapabilityEx::get() { + return this->hubCapabilityExField; + } + inline System::Void RootHubType::HubCapabilityEx::set(Microsoft::Kits::Samples::Usb::HubCapabilitiesExType^ value) { + this->hubCapabilityExField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ RootHubType::ExternalHub::get() { + return this->externalHubField; + } + inline System::Void RootHubType::ExternalHub::set(cli::array< Microsoft::Kits::Samples::Usb::ExternalHubType^ >^ value) { + this->externalHubField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ RootHubType::UsbDevice::get() { + return this->usbDeviceField; + } + inline System::Void RootHubType::UsbDevice::set(cli::array< Microsoft::Kits::Samples::Usb::UsbDeviceType^ >^ value) { + this->usbDeviceField = value; + } + + inline cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ RootHubType::NoDevice::get() { + return this->noDeviceField; + } + inline System::Void RootHubType::NoDevice::set(cli::array< Microsoft::Kits::Samples::Usb::NoDeviceType^ >^ value) { + this->noDeviceField = value; + } + + inline System::String^ RootHubType::ServiceName::get() { + return this->serviceNameField; + } + inline System::Void RootHubType::ServiceName::set(System::String^ value) { + this->serviceNameField = value; + } + + inline System::String^ RootHubType::HwId::get() { + return this->hwIdField; + } + inline System::Void RootHubType::HwId::set(System::String^ value) { + this->hwIdField = value; + } + + inline System::String^ RootHubType::DeviceId::get() { + return this->deviceIdField; + } + inline System::Void RootHubType::DeviceId::set(System::String^ value) { + this->deviceIdField = value; + } + + inline System::String^ RootHubType::DeviceName::get() { + return this->deviceNameField; + } + inline System::Void RootHubType::DeviceName::set(System::String^ value) { + this->deviceNameField = value; + } + + inline System::String^ RootHubType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void RootHubType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::String^ RootHubType::UsbProtocol::get() { + return this->usbProtocolField; + } + inline System::Void RootHubType::UsbProtocol::set(System::String^ value) { + this->usbProtocolField = value; + } + + + inline System::String^ UsbHCPowerStateType::SystemState::get() { + return this->systemStateField; + } + inline System::Void UsbHCPowerStateType::SystemState::set(System::String^ value) { + this->systemStateField = value; + } + + inline System::String^ UsbHCPowerStateType::HostControllerState::get() { + return this->hostControllerStateField; + } + inline System::Void UsbHCPowerStateType::HostControllerState::set(System::String^ value) { + this->hostControllerStateField = value; + } + + inline System::String^ UsbHCPowerStateType::HubState::get() { + return this->hubStateField; + } + inline System::Void UsbHCPowerStateType::HubState::set(System::String^ value) { + this->hubStateField = value; + } + + inline System::Boolean UsbHCPowerStateType::CanWakeUp::get() { + return this->canWakeUpField; + } + inline System::Void UsbHCPowerStateType::CanWakeUp::set(System::Boolean value) { + this->canWakeUpField = value; + } + + inline System::Boolean UsbHCPowerStateType::IsPowered::get() { + return this->isPoweredField; + } + inline System::Void UsbHCPowerStateType::IsPowered::set(System::Boolean value) { + this->isPoweredField = value; + } + + + inline cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ UsbHCPowerStateMappingType::PowerMap::get() { + return this->powerMapField; + } + inline System::Void UsbHCPowerStateMappingType::PowerMap::set(cli::array< Microsoft::Kits::Samples::Usb::UsbHCPowerStateType^ >^ value) { + this->powerMapField = value; + } + + inline System::String^ UsbHCPowerStateMappingType::LastSleepState::get() { + return this->lastSleepStateField; + } + inline System::Void UsbHCPowerStateMappingType::LastSleepState::set(System::String^ value) { + this->lastSleepStateField = value; + } + + + inline System::Int64 UsbHCDeviceInfoType::VendorId::get() { + return this->vendorIdField; + } + inline System::Void UsbHCDeviceInfoType::VendorId::set(System::Int64 value) { + this->vendorIdField = value; + } + + inline System::Int64 UsbHCDeviceInfoType::DeviceId::get() { + return this->deviceIdField; + } + inline System::Void UsbHCDeviceInfoType::DeviceId::set(System::Int64 value) { + this->deviceIdField = value; + } + + inline System::String^ UsbHCDeviceInfoType::DriverKey::get() { + return this->driverKeyField; + } + inline System::Void UsbHCDeviceInfoType::DriverKey::set(System::String^ value) { + this->driverKeyField = value; + } + + inline System::Int64 UsbHCDeviceInfoType::SubSysId::get() { + return this->subSysIdField; + } + inline System::Void UsbHCDeviceInfoType::SubSysId::set(System::Int64 value) { + this->subSysIdField = value; + } + + inline System::Int64 UsbHCDeviceInfoType::Revision::get() { + return this->revisionField; + } + inline System::Void UsbHCDeviceInfoType::Revision::set(System::Int64 value) { + this->revisionField = value; + } + + inline System::UInt64 UsbHCDeviceInfoType::DebugPort::get() { + return this->debugPortField; + } + inline System::Void UsbHCDeviceInfoType::DebugPort::set(System::UInt64 value) { + this->debugPortField = value; + } + + inline System::UInt64 UsbHCDeviceInfoType::NumberOfRootPorts::get() { + return this->numberOfRootPortsField; + } + inline System::Void UsbHCDeviceInfoType::NumberOfRootPorts::set(System::UInt64 value) { + this->numberOfRootPortsField = value; + } + + inline System::UInt64 UsbHCDeviceInfoType::ControllerFlavor::get() { + return this->controllerFlavorField; + } + inline System::Void UsbHCDeviceInfoType::ControllerFlavor::set(System::UInt64 value) { + this->controllerFlavorField = value; + } + + inline System::String^ UsbHCDeviceInfoType::ControllerFlavorString::get() { + return this->controllerFlavorStringField; + } + inline System::Void UsbHCDeviceInfoType::ControllerFlavorString::set(System::String^ value) { + this->controllerFlavorStringField = value; + } + + inline System::Boolean UsbHCDeviceInfoType::PortSwitchingEnabled::get() { + return this->portSwitchingEnabledField; + } + inline System::Void UsbHCDeviceInfoType::PortSwitchingEnabled::set(System::Boolean value) { + this->portSwitchingEnabledField = value; + } + + inline System::Boolean UsbHCDeviceInfoType::SelectiveSuspendEnabled::get() { + return this->selectiveSuspendEnabledField; + } + inline System::Void UsbHCDeviceInfoType::SelectiveSuspendEnabled::set(System::Boolean value) { + this->selectiveSuspendEnabledField = value; + } + + inline System::UInt64 UsbHCDeviceInfoType::LegacyBios::get() { + return this->legacyBiosField; + } + inline System::Void UsbHCDeviceInfoType::LegacyBios::set(System::UInt64 value) { + this->legacyBiosField = value; + } + + + inline Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ HostControllerType::ControllerInfo::get() { + return this->controllerInfoField; + } + inline System::Void HostControllerType::ControllerInfo::set(Microsoft::Kits::Samples::Usb::UsbHCDeviceInfoType^ value) { + this->controllerInfoField = value; + } + + inline Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ HostControllerType::PowerMapping::get() { + return this->powerMappingField; + } + inline System::Void HostControllerType::PowerMapping::set(Microsoft::Kits::Samples::Usb::UsbHCPowerStateMappingType^ value) { + this->powerMappingField = value; + } + + inline Microsoft::Kits::Samples::Usb::RootHubType^ HostControllerType::RootHub::get() { + return this->rootHubField; + } + inline System::Void HostControllerType::RootHub::set(Microsoft::Kits::Samples::Usb::RootHubType^ value) { + this->rootHubField = value; + } + + inline System::String^ HostControllerType::ServiceName::get() { + return this->serviceNameField; + } + inline System::Void HostControllerType::ServiceName::set(System::String^ value) { + this->serviceNameField = value; + } + + inline System::String^ HostControllerType::HwId::get() { + return this->hwIdField; + } + inline System::Void HostControllerType::HwId::set(System::String^ value) { + this->hwIdField = value; + } + + inline System::String^ HostControllerType::DeviceId::get() { + return this->deviceIdField; + } + inline System::Void HostControllerType::DeviceId::set(System::String^ value) { + this->deviceIdField = value; + } + + inline System::String^ HostControllerType::DeviceName::get() { + return this->deviceNameField; + } + inline System::Void HostControllerType::DeviceName::set(System::String^ value) { + this->deviceNameField = value; + } + + inline System::String^ HostControllerType::DeviceClass::get() { + return this->deviceClassField; + } + inline System::Void HostControllerType::DeviceClass::set(System::String^ value) { + this->deviceClassField = value; + } + + inline System::String^ HostControllerType::UsbProtocol::get() { + return this->usbProtocolField; + } + inline System::Void HostControllerType::UsbProtocol::set(System::String^ value) { + this->usbProtocolField = value; + } + } + } + } +} + diff --git a/usb/usbview/usbviddesc.h b/usb/usbview/usbviddesc.h new file mode 100644 index 00000000..a0853ea0 --- /dev/null +++ b/usb/usbview/usbviddesc.h @@ -0,0 +1,743 @@ +/*++ + +Copyright (c) 2002-2003 Microsoft Corporation + +Module Name: + + USBVIDDESC.H + +Abstract: + + This is a header file for USB Video Class Specific descriptors which are not yet in + a standard system header file. + +Environment: + + user mode + +Revision History: + + 11-20-2002 : created + 03-28-2003 : major updates to support latest UVC specs + +--*/ + +#pragma pack(push, 1) + +/***************************************************************************** + D E F I N E S +*****************************************************************************/ + +//global version for USB Video Class spec version +#define BCDVDC 0x0083 + +// +// USB Device Class Definition for Video Devices v8.c +// Appendix A. Video Device Class Codes +// + +// A.1 Video Interface Class Code +//TBD Normally would be in USB100.h but not official yet +#define USB_DEVICE_CLASS_VIDEO 0x0E +#define USB_DEVICE_CLASS_VIDEO_PRERELEASE 0xFF +//CC_VIDEO in spec. The rest of the codes will be USB_VIDEO plus text from spec codes + +// A.2 Video Interface Subclass Codes +// +#define USB_VIDEO_SC_UNDEFINED 0x00 +#define USB_VIDEO_SC_VIDEOCONTROL 0x01 +#define USB_VIDEO_SC_VIDEOSTREAMING 0x02 +#define USB_VIDEO_SC_VIDEO_INTERFACE_COLLECTION 0x03 + +// A.3 Video Interface Protocol Codes +// +#define USB_VIDEO_PC_PROTOCOL_UNDEFINED 0x00 + +// A.4 Video Class-Specific Descriptor Types +// +#define USB_VIDEO_CS_UNDEFINED 0x20 +#define USB_VIDEO_CS_DEVICE 0x21 +#define USB_VIDEO_CS_CONFIGURATION 0x22 +#define USB_VIDEO_CS_STRING 0x23 +#define USB_VIDEO_CS_INTERFACE 0x24 +#define USB_VIDEO_CS_ENDPOINT 0x25 + +// A.5 Video Class-Specific VC (Video Control) Interface Descriptor Subtypes +// +#define USB_VIDEO_VC_DESCRIPTOR_UNDEFINED 0x00 +#define USB_VIDEO_VC_HEADER 0x01 +#define USB_VIDEO_VC_INPUT_TERMINAL 0x02 +#define USB_VIDEO_VC_OUTPUT_TERMINAL 0x03 +#define USB_VIDEO_VC_SELECTOR_UNIT 0x04 +#define USB_VIDEO_VC_PROCESSING_UNIT 0x05 +#define USB_VIDEO_VC_EXTENSION_UNIT 0x06 + +// A.6 Video Class-Specific VS (Video Streaming) Interface Descriptor Subtypes +// +#define USB_VIDEO_VS_UNDEFINED 0x00 +#define USB_VIDEO_VS_INPUT_HEADER 0x01 +#define USB_VIDEO_VS_OUTPUT_HEADER 0x02 +#define USB_VIDEO_VS_STILL_IMAGE_FRAME 0x03 +#define USB_VIDEO_VS_FORMAT_UNCOMPRESSED 0x04 +#define USB_VIDEO_VS_FRAME_UNCOMPRESSED 0x05 +#define USB_VIDEO_VS_FORMAT_MJPEG 0x06 +#define USB_VIDEO_VS_FRAME_MJPEG 0x07 +#define USB_VIDEO_VS_FORMAT_MPEG1 0x08 +#define USB_VIDEO_VS_FORMAT_MPEG2PS 0x09 +#define USB_VIDEO_VS_FORMAT_MPEG2TS 0x0A +#define USB_VIDEO_VS_FORMAT_MPEG4SL 0x0B +#define USB_VIDEO_VS_FORMAT_DV 0x0C +#define USB_VIDEO_VS_COLORFORMAT 0x0D +#define USB_VIDEO_VS_FORMAT_VENDOR 0x0E +#define USB_VIDEO_VS_FRAME_VENDOR 0x0F + +// A.7 Video Class-Specific Endpoint Descriptor Subtypes +// +#define USB_VIDEO_EP_UNDEFINED 0x00 +#define USB_VIDEO_EP_GENERAL 0x01 +#define USB_VIDEO_EP_ENDPOINT 0x02 +#define USB_VIDEO_EP_INTERRUPT 0x03 + +// +// Below definitions only necessary if testing requests +// +// A.8 Video Class-Specific Request Codes +// +#define USB_VIDEO_RC_UNDEFINED 0x00 +#define USB_VIDEO_SET_CUR 0x01 +#define USB_VIDEO_GET_CUR 0x81 +#define USB_VIDEO_GET_MIN 0x82 +#define USB_VIDEO_GET_MAX 0x83 +#define USB_VIDEO_GET_RES 0x84 +#define USB_VIDEO_GET_LEN 0x85 +#define USB_VIDEO_GET_INFO 0x86 +#define USB_VIDEO_GET_DEF 0x87 + +// A.9 Control Selector Codes +// A.9.1 VideoControl Interface Control Selectors +#define USB_VIDEO_VC_UNDEFINED_CONTROL 0x00 +#define USB_VIDEO_VC_VIDEO_POWER_MODE_CONTROL 0x01 +#define USB_VIDEO_VC_REQUEST_ERROR_CODE_CONTROL 0x02 +#define USB_VIDEO_VC_INDICATE_HOST_CLOCK_CONTROL 0x03 + +//A.9.2 Terminal Control Selectors +// +#define USB_VIDEO_TE_CONTROL_UNDEFINED 0x00 + +//A.9.3 Selector Unit Control Selectors +// +#define USB_VIDEO_SU_CONTROL_UNDEFINED 0x00 +#define USB_VIDEO_SU_INPUT_SELECT_CONTROL 0x01 + +//A.9.4 Camera Terminal Control Selectors +// +#define USB_VIDEO_CT_CONTROL_UNDEFINED 0x00 +#define USB_VIDEO_CT_SCANNING_MODE_CONTROL 0x01 +#define USB_VIDEO_CT_AE_MODE_CONTROL 0x02 +#define USB_VIDEO_CT_AE_PRIORITY_CONTROL 0x03 +#define USB_VIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 +#define USB_VIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 +#define USB_VIDEO_CT_FOCUS_ABSOLUTE_CONTROL 0x06 +#define USB_VIDEO_CT_FOCUS_RELATIVE_CONTROL 0x07 +#define USB_VIDEO_CT_FOCUS_AUTO_CONTROL 0x08 +#define USB_VIDEO_CT_IRIS_ABSOLUTE_CONTROL 0x09 +#define USB_VIDEO_CT_IRIS_RELATIVE_CONTROL 0x0A +#define USB_VIDEO_CT_ZOOM_ABSOLUTE_CONTROL 0x0B +#define USB_VIDEO_CT_ZOOM_RELATIVE_CONTROL 0x0C +#define USB_VIDEO_CT_PANTILT_ABSOLUTE_CONTROL 0x0D +#define USB_VIDEO_CT_PANTILT_RELATIVE_CONTROL 0x0E +#define USB_VIDEO_CT_ROLL_ABSOLUTE_CONTROL 0x0F +#define USB_VIDEO_CT_ROLL_RELATIVE_CONTROL 0x10 + +//A.9.5 Processing Unit Control Selectors +// +#define USB_VIDEO_PU_CONTROL_UNDEFINED 0x04 +#define USB_VIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 +#define USB_VIDEO_PU_BRIGHTNESS_CONTROL 0x02 +#define USB_VIDEO_PU_CONTRAST_CONTROL 0x03 +#define USB_VIDEO_PU_GAIN_CONTROL 0x04 +#define USB_VIDEO_PU_POWER_LINE_FREQUENCY_CONTROL 0x05 +#define USB_VIDEO_PU_HUE_CONTROL 0x06 +#define USB_VIDEO_PU_SATURATION_CONTROL 0x07 +#define USB_VIDEO_PU_SHARPNESS_CONTROL 0x08 +#define USB_VIDEO_PU_GAMMA_CONTROL 0x09 +#define USB_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0A +#define USB_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B +#define USB_VIDEO_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0C +#define USB_VIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0D +#define USB_VIDEO_PU_DIGITAL_MULTIPLIER_CONTROL 0x0E +#define USB_VIDEO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0F +#define USB_VIDEO_PU_HUE_AUTO_CONTROL 0x10 + +//A.9.6 Extension Unit Control Selectors +// +#define USB_VIDEO_XU_CONTROL_UNDEFINED 0x00 + +//A.9.7 VideoStreaming Interface Control Selectors +// +#define USB_VIDEO_VS_CONTROL_UNDEFINED 0x00 +#define USB_VIDEO_VS_PROBE_CONTROL 0x01 +#define USB_VIDEO_VS_COMMIT_CONTROL 0x02 +#define USB_VIDEO_VS_STILL_PROBE_CONTROL 0x03 +#define USB_VIDEO_VS_STILL_COMMIT_CONTROL 0x04 +#define USB_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 +#define USB_VIDEO_VS_STREAM_ERROR_CODE_CONTROL 0x06 +#define USB_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL 0x07 +#define USB_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 +#define USB_VIDEO_VS_SYNCH_DELAY_CONTROL 0x09 + +#define TapeControls 0 +#define TransportModes 1 +#define CameraControls 2 +#define ProcessorControls 3 +#define InHeaderControls 4 + +/***************************************************************************** + T Y P E D E F S +*****************************************************************************/ + + +/***************************************************************************** + USB Device Class Definition for Video Devices v8.b +*****************************************************************************/ + +typedef struct _USB_VIDEO_COMMON_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; +} USB_VIDEO_COMMON_DESCRIPTOR, +*PUSB_VIDEO_COMMON_DESCRIPTOR; + +// 3.6.2 Class-Specific VC (Video Control) Interface Descriptor +// +typedef struct _USB_VIDEO_VC_INTERFACE_HEADER_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + USHORT bcdVDC; + USHORT wTotalLength; + ULONG32 dwClockFrequency; + UCHAR bInCollection; +// UCHAR baInterfaceNr; // variable length (0 minimum) +} USB_VIDEO_VC_INTERFACE_HEADER_DESCRIPTOR, +*PUSB_VIDEO_VC_INTERFACE_HEADER_DESCRIPTOR; + +// 3.6.2.1 Input Terminal Descriptor +// +typedef struct _USB_VIDEO_INPUT_TERMINAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR iTerminal; +} USB_VIDEO_INPUT_TERMINAL_DESCRIPTOR, +*PUSB_VIDEO_INPUT_TERMINAL_DESCRIPTOR; + +// 3.6.2.2 Output Terminal Descriptor +// +typedef struct _USB_VIDEO_OUTPUT_TERMINAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bSourceID; + UCHAR iTerminal; +} USB_VIDEO_OUTPUT_TERMINAL_DESCRIPTOR, +*PUSB_VIDEO_OUTPUT_TERMINAL_DESCRIPTOR; + +// 3.6.2.3 Camera Unit Descriptor +// +typedef struct _USB_VIDEO_CAMERA_TERMINAL_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR iTerminal; + USHORT wObjectiveFocalLengthMin; + USHORT wObjectiveFocalLengthMax; + USHORT wOcularFocalLength; + UCHAR bControlSize; +// UCHAR bmControls; // variable length (0 min, 3 max) +} USB_VIDEO_CAMERA_TERMINAL_DESCRIPTOR, +*PUSB_VIDEO_CAMERA_TERMINAL_DESCRIPTOR; + +// 3.6.2.4 Selector Unit Descriptor +// +typedef struct _USB_VIDEO_SELECTOR_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bNrInPins; + UCHAR baSourceID; // variable length (1 minimum) + UCHAR iSelector; +} USB_VIDEO_SELECTOR_UNIT_DESCRIPTOR, +*PUSB_VIDEO_SELECTOR_UNIT_DESCRIPTOR; + +// 3.6.2.5 Processing Unit Descriptor +// +typedef struct _USB_VIDEO_PROCESSING_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + UCHAR bSourceID; + USHORT wMaxMultiplier; + UCHAR bControlSize; +// UCHAR bmControls; // variable length (0 minimum) + UCHAR iProcessing; +} USB_VIDEO_PROCESSING_UNIT_DESCRIPTOR, +*PUSB_VIDEO_PROCESSING_UNIT_DESCRIPTOR; + +// 3.6.2.6 Extension Unit Descriptor +// +typedef struct _USB_VIDEO_EXTENSION_UNIT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bUnitID; + GUID guidExtensionCode; + UCHAR bNumControls; + UCHAR bNrInPins; + UCHAR baSourceID; // variable length (1 minimum) +// UCHAR bControlSize; +// UCHAR bmControls; // variable length (0 minimum) +// UCHAR iExtension; +} USB_VIDEO_EXTENSION_UNIT_DESCRIPTOR, +*PUSB_VIDEO_EXTENSION_UNIT_DESCRIPTOR; + +// 3.7.2.2 Class-Specific VC Interrupt EndPoint Descriptor +// +typedef struct _USB_VIDEO_VC_INTERRUPT_ENDPOINT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + USHORT wMaxTransferSize; +} USB_VIDEO_VC_INTERRUPT_ENDPOINT_DESCRIPTOR, +*PUSB_VIDEO_VC_INTERRUPT_ENDPOINT_DESCRIPTOR; +// 3.8.2.1 Class-Specific Input Header Descriptor +// +typedef struct _USB_VIDEO_INPUT_HEADER_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bNumFormats; + USHORT wTotalLength; + UCHAR bEndpointAddress; + UCHAR bmInfo; + UCHAR bTerminalLink; + UCHAR bStillCaptureMethod; + UCHAR bTriggerSupport; + UCHAR bTriggerUsage; + UCHAR bControlSize; +// UCHAR bmaControls; // variable length (0 minimum) +} USB_VIDEO_INPUT_HEADER_DESCRIPTOR, +*PUSB_VIDEO_INPUT_HEADER_DESCRIPTOR; + +// 3.8.2.2 Class-Specific Output Header Descriptor +// +typedef struct _USB_VIDEO_OUTPUT_HEADER_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bNumFormats; + USHORT wTotalLength; + UCHAR bEndpointAddress; + UCHAR bTerminalLink; +} USB_VIDEO_OUTPUT_HEADER_DESCRIPTOR, +*PUSB_VIDEO_OUTPUT_HEADER_DESCRIPTOR; + +// 3.8.2.3 Payload Format Descriptors +//Payload Format Descriptor Document +//Uncompressed Video DWGVideo Payload Uncompressed 0.xx.doc +//MJPEG Video DWGVideo Payload MJPEG Format Ver0.xx.doc +//MPEG1 System Stream DWGVideo Payload MPEG1 System Stream, MPEG2-PS Format Ver0.xx.doc +//MPEG2 PS DWGVideo Payload MPEG1 System Stream, MPEG2-PS Format Ver0.xx.doc +//MPEG-2 TS DWGVideo Payload MPEG2TS Format Ver0.xx.doc +//MPEG-4 SL DWGVideo Payload MPEG4 SL format Ver0.xx.doc +//DV DWGVideo Payload DV Format Ver0.xx.doc + +// 3.8.2.4 Video Frame Descriptor +// +//Video Frame Descriptor Document +//Uncompressed DWGVideo Payload Uncompressed 0.xx.doc +//MJPEG DWGVideo Payload MJPEG Format Ver0.xx.doc + +// 3.8.2.5 Still Image Frame Descriptor +// +typedef struct _VIDEO_STILL_IMAGE { + USHORT wWidth; + USHORT wHeight; +} VIDEO_STILL_IMAGE, +*PVIDEO_STILL_IMAGE; + +typedef struct _USB_VIDEO_STILL_IMAGE_FRAME_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bEndpointAddress; + UCHAR bNumImageSizePatterns; + VIDEO_STILL_IMAGE dwStillImage; // variable count + UCHAR bNumCompressionPattern; + UCHAR bCompression; // variable count +} USB_VIDEO_STILL_IMAGE_FRAME_DESCRIPTOR, +*PUSB_VIDEO_STILL_IMAGE_FRAME_DESCRIPTOR; + +// 3.8.2.6 Color Matching Descriptor +// +typedef struct _USB_VIDEO_COLOR_MATCHING_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bColorPrimaries; + UCHAR bTransferCharacteristics; + UCHAR bMatrixCoefficients; +} USB_VIDEO_COLOR_MATCHING_DESCRIPTOR, +*PUSB_VIDEO_COLOR_MATCHING_DESCRIPTOR; +/* +// 3.9.1 Class-specific VC Interrupt Endpoint Descriptor +typedef struct _USB_VIDEO_VS_ENDPOINT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubType; + USHORT wMaxTransferSize; +} USB_VIDEO_VS_ENDPOINT_DESCRIPTOR, +*PUSB_VIDEO_VS_ENDPOINT_DESCRIPTOR; +*/ +// +// USB Device Class Definition for Video Devices: Uncompressed Payload 0.8a Draft Revision +// + +// 3.1.1 Uncompressed Video Format Descriptor +// +typedef struct _USB_VIDEO_UNCOMPRESSED_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + GUID guidFormat; + UCHAR bBitsPerPixel; + UCHAR bDefaultFrameIndex; + UCHAR bAspectRatioX; + UCHAR bAspectRatioY; + UCHAR bmInterlaceFlags; + UCHAR bCopyProtect; +} USB_VIDEO_UNCOMPRESSED_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_UNCOMPRESSED_FORMAT_DESCRIPTOR; + +// 3.1.2 Uncompressed Video Frame Descriptor Common +// +typedef struct _USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_COMMON { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; +} USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_COMMON, +*PUSB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_COMMON; + +// 3.1.2 Uncompressed Video Frame Descriptor - Continuous +// +typedef struct _USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_CONTINUOUS { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwMinFrameInterval; + ULONG32 dwMaxFrameInterval; + ULONG32 dwFrameIntervalStep; +} USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_CONTINUOUS, +*PUSB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_CONTINUOUS; + +// 3.1.2 Uncompressed Video Frame Descriptor - Discrete +// +typedef struct _USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_DISCRETE { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwFrameInterval; // variable count +} USB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_DISCRETE, +*PUSB_VIDEO_UNCOMPRESSED_FRAME_DESCRIPTOR_DISCRETE; + +// +// USB Device Class Definition for Video Devices: Motion-JPEG Payload 0.8a Draft Revision +// 3.1.1 MJPEG Video Format Descriptor +// +typedef struct _USB_VIDEO_MJPEG_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + UCHAR bmFlags; + UCHAR bDefaultFrameIndex; + UCHAR bAspectRatioX; + UCHAR bAspectRatioY; + UCHAR bmInterlaceFlags; + UCHAR bCopyProtect; +} USB_VIDEO_MJPEG_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_MJPEG_FORMAT_DESCRIPTOR; + +// 3.1.2 MJPEG Video Frame Descriptors Common +// +typedef struct _USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_COMMON { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; +} USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_COMMON, +*PUSB_VIDEO_MJPEG_FRAME_DESCRIPTOR_COMMON; + +// 3.1.2 MJPEG Video Frame Descriptors - Continuous +// +typedef struct _USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_CONTINUOUS { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwMinFrameInterval; + ULONG32 dwMaxFrameInterval; + ULONG32 dwFrameIntervalStep; +} USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_CONTINUOUS, +*PUSB_VIDEO_MJPEG_FRAME_DESCRIPTOR_CONTINUOUS; + +// 3.1.2 MJPEG Video Frame Descriptors -Discrete +// +typedef struct _USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_DISCRETE { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwFrameInterval; // variable count +} USB_VIDEO_MJPEG_FRAME_DESCRIPTOR_DISCRETE, +*PUSB_VIDEO_MJPEG_FRAME_DESCRIPTOR_DISCRETE; + +// +// USB Device Class Definition for Video Devices: MPEG1-SS, MPEG2-PS Payload 0.8a Draft Revision +// 3.1.1 MPEG1 System Stream Format Descriptor +// +typedef struct _USB_VIDEO_MPEG1_SS_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + USHORT wPacketLength; + USHORT wPackLength; + UCHAR bPackdataType; +} USB_VIDEO_MPEG1_SS_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_MPEG1_SS_FORMAT_DESCRIPTOR; + +// 3.1.2 MPEG2 PS Format Descriptor +// +typedef struct _USB_VIDEO_MPEG2_PS_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + USHORT wPacketLength; + USHORT wPackLength; + UCHAR bPackdataType; +} USB_VIDEO_MPEG2_PS_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_MPEG2_PS_FORMAT_DESCRIPTOR; + +// +// USB Device Class Definition for Video Devices: MPEG-2 TS Payload 0.8a Draft Revision +// 3.1.1 MPEG-2 TS Format Descriptor +// +typedef struct _USB_VIDEO_MPEG2_TS_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bDataOffset; + UCHAR bPacketLength; + UCHAR bStrideLength; +} USB_VIDEO_MPEG2_TS_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_MPEG2_TS_FORMAT_DESCRIPTOR; + +// +// USB Device Class Definition for Video Devices: MPEG4 SL Payload 0.8a Draft Revision +// 3.1.1 MPEG4 SL Format Descriptor +// +typedef struct _USB_VIDEO_MPEG4_SL_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + USHORT wPacketLength; +} USB_VIDEO_MPEG4_SL_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_MPEG4_SL_FORMAT_DESCRIPTOR; + +// USB Device Class Definition for Video Devices: DV Payload 0.8a Draft Revision +// 3.1.1 DV Format Descriptor +typedef struct _USB_VIDEO_DV_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + ULONG32 dwMaxVideoFrameBufferSize; + UCHAR bFormatType; +} USB_VIDEO_DV_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_DV_FORMAT_DESCRIPTOR; + +// USB Device Class Definition for Video Devices: Vendor Payload 0.8c Draft Revision +// 3.1.1 Vendor Video Format Descriptor +typedef struct _USB_VIDEO_VENDOR_VIDEO_FORMAT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + GUID guidMajorFormat; + GUID guidSubFormat; + GUID guidSpecifier; + UCHAR bPayloadClass; + UCHAR bDefaultFrameIndex; + UCHAR bCopyProtect; +} USB_VIDEO_VENDOR_VIDEO_FORMAT_DESCRIPTOR, +*PUSB_VIDEO_VENDOR_VIDEO_FORMAT_DESCRIPTOR; + +// USB Device Class Definition for Video Devices: Vendor Payload 0.8c Draft Revision +// 3.1.2 Vendor Video Frame Descriptor +typedef struct _USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_COMMON { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; +} USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_COMMON, +*PUSB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_COMMON; + +typedef struct _USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_CONTINUOUS { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwMinFrameInterval; + ULONG32 dwMaxFrameInterval; + ULONG32 dwFrameIntervalStep; +} USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_CONTINUOUS, +*PUSB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_CONTINUOUS; + +typedef struct _USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_DISCRETE { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG32 dwMinBitRate; + ULONG32 dwMaxBitRate; + ULONG32 dwMaxVideoFrameBufferSize; + ULONG32 dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG32 dwFrameInterval; // variable count +} USB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_DISCRETE, +*PUSB_VIDEO_VENDOR_VIDEO_FRAME_DESCRIPTOR_DISCRETE; + +// USB Device Class Definition for Video Devices: Media Transport Terminal 0.8a Draft Revision +// 3.1 Media Transport Input Descriptor +typedef struct _USB_VIDEO_MEDIA_TRANSPORT_INPUT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR iTerminal; + UCHAR bControlSize; + UCHAR bmControls; // variable size (min 1) +// UCHAR bTransportModeSize; // variable count (min 0) +// UCHAR bmTransportModes; // variable count (min 0) +} USB_VIDEO_MEDIA_TRANSPORT_INPUT_DESCRIPTOR, +*PUSB_VIDEO_MEDIA_TRANSPORT_INPUT_DESCRIPTOR; + +// 3.2 Media Transport Output Descriptor +typedef struct _USB_VIDEO_MEDIA_TRANSPORT_OUTPUT_DESCRIPTOR { + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bTerminalID; + USHORT wTerminalType; + UCHAR bAssocTerminal; + UCHAR bSourceID; + UCHAR iTerminal; + UCHAR bControlSize; + UCHAR bmControls; // variable size (min 1) +// UCHAR bTransportModeSize; // variable count (min 0) +// UCHAR bmTransportModes; // variable count (min 0) +} USB_VIDEO_MEDIA_TRANSPORT_OUTPUT_DESCRIPTOR, +*PUSB_VIDEO_MEDIA_TRANSPORT_OUTPUT_DESCRIPTOR; + +#pragma pack(pop) diff --git a/usb/usbview/usbview.sln b/usb/usbview/usbview.sln new file mode 100644 index 00000000..114e5229 --- /dev/null +++ b/usb/usbview/usbview.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbview", "usbview.vcxproj", "{F4C245DD-C596-4498-8905-79FA40CCF7D5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Debug|Win32.ActiveCfg = Debug|Win32 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Debug|Win32.Build.0 = Debug|Win32 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Release|Win32.ActiveCfg = Release|Win32 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Release|Win32.Build.0 = Release|Win32 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Debug|x64.ActiveCfg = Debug|x64 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Debug|x64.Build.0 = Debug|x64 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Release|x64.ActiveCfg = Release|x64 + {F4C245DD-C596-4498-8905-79FA40CCF7D5}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/usb/usbview/usbview.vcxproj b/usb/usbview/usbview.vcxproj new file mode 100644 index 00000000..1c8a9c0e --- /dev/null +++ b/usb/usbview/usbview.vcxproj @@ -0,0 +1,182 @@ +<?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>{F4C245DD-C596-4498-8905-79FA40CCF7D5}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{26027F55-159C-4FAA-99FB-7CC0A0B74E75}</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 /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</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" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>usbview</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>usbview</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>usbview</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>usbview</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <BaseAddress Condition="'$(Platform)'=='x64'">0x101000000</BaseAddress> + <BaseAddress Condition="!('$(Platform)'=='x64')">0x1000000</BaseAddress> + <AdditionalDependencies>%(AdditionalDependencies);shell32.lib;kernel32.lib;user32.lib;gdi32.lib;comctl32.lib;cfgmgr32.lib;comdlg32.lib;ole32.lib;setupapi.lib;strsafe.lib;shlwapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <BaseAddress Condition="'$(Platform)'=='x64'">0x101000000</BaseAddress> + <BaseAddress Condition="!('$(Platform)'=='x64')">0x1000000</BaseAddress> + <AdditionalDependencies>%(AdditionalDependencies);shell32.lib;kernel32.lib;user32.lib;gdi32.lib;comctl32.lib;cfgmgr32.lib;comdlg32.lib;ole32.lib;setupapi.lib;strsafe.lib;shlwapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <BaseAddress Condition="'$(Platform)'=='x64'">0x101000000</BaseAddress> + <BaseAddress Condition="!('$(Platform)'=='x64')">0x1000000</BaseAddress> + <AdditionalDependencies>%(AdditionalDependencies);shell32.lib;kernel32.lib;user32.lib;gdi32.lib;comctl32.lib;cfgmgr32.lib;comdlg32.lib;ole32.lib;setupapi.lib;strsafe.lib;shlwapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeTypeInfo>true</RuntimeTypeInfo> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <BaseAddress Condition="'$(Platform)'=='x64'">0x101000000</BaseAddress> + <BaseAddress Condition="!('$(Platform)'=='x64')">0x1000000</BaseAddress> + <AdditionalDependencies>%(AdditionalDependencies);shell32.lib;kernel32.lib;user32.lib;gdi32.lib;comctl32.lib;cfgmgr32.lib;comdlg32.lib;ole32.lib;setupapi.lib;strsafe.lib;shlwapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="debug.c" /> + <ClCompile Include="devnode.c" /> + <ClCompile Include="dispaud.c" /> + <ClCompile Include="display.c" /> + <ClCompile Include="dispvid.c" /> + <ClCompile Include="enum.c" /> + <ClCompile Include="h264.c" /> + <ClCompile Include="uvcview.c" /> + <ClCompile Include="xmlhelper.cpp"> + <CompileAsManaged>true</CompileAsManaged> + <BasicRuntimeChecks Condition="'$(UseDebugLibraries)'=='true'"> + </BasicRuntimeChecks> + </ClCompile> + <ResourceCompile Include="uvcview.rc" /> + </ItemGroup> + <Target Name="Custom Build Target 1" BeforeTargets="BeforeClCompile"> + <ItemGroup> + <CustomBuildTarget1Input Include="app.config" /> + </ItemGroup> + <Exec Command="copy "%(CustomBuildTarget1Input.Identity)" ".\$(IntDir)\usbview.exe.config"" WorkingDirectory="$(MSBuildProjectDirectory)" /> + </Target> + <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/usbview/usbview.vcxproj.Filters b/usb/usbview/usbview.vcxproj.Filters new file mode 100644 index 00000000..b3275fc2 --- /dev/null +++ b/usb/usbview/usbview.vcxproj.Filters @@ -0,0 +1,51 @@ +<?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>{EEF5A053-6396-47A4-9251-77779C282049}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{0F82DB55-DA55-4FE8-ABE6-374C2635F9FC}</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>{A6755BEE-12BC-4A51-B26F-A0BD3DADC2FD}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="debug.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="devnode.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dispaud.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="display.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dispvid.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="enum.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="h264.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="uvcview.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="xmlhelper.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="uvcview.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/usbview/uvcdesc.h b/usb/usbview/uvcdesc.h new file mode 100644 index 00000000..b1d197aa --- /dev/null +++ b/usb/usbview/uvcdesc.h @@ -0,0 +1,1106 @@ +//+------------------------------------------------------------------------- +// +// Microsoft Windows +// +// Copyright (C) Microsoft Corporation, 1999 - 2008 +// +// File: uvcdesc.h +// +// This header is from the UVC 1.1 USBVideo driver +// +//-------------------------------------------------------------------------- + +#ifndef ___UVCDESC_H___ +#define ___UVCDESC_H___ + + +// USB Video Device Class Code +#define USB_DEVICE_CLASS_VIDEO 0x0E + +// Video sub-classes +#define SUBCLASS_UNDEFINED 0x00 +#define VIDEO_SUBCLASS_CONTROL 0x01 +#define VIDEO_SUBCLASS_STREAMING 0x02 + +// Video Class-Specific Descriptor Types +#define CS_UNDEFINED 0x20 +#define CS_DEVICE 0x21 +#define CS_CONFIGURATION 0x22 +#define CS_STRING 0x23 +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +// Video Class-Specific VC Interface Descriptor Subtypes +#define VC_HEADER 0x01 +#define INPUT_TERMINAL 0x02 +#define OUTPUT_TERMINAL 0x03 +#define SELECTOR_UNIT 0x04 +#define PROCESSING_UNIT 0x05 +#define EXTENSION_UNIT 0x06 +#define MAX_TYPE_UNIT 0x07 + +// Video Class-Specific VS Interface Descriptor Subtypes +#define VS_DESCRIPTOR_UNDEFINED 0x00 +#define VS_INPUT_HEADER 0x01 +#define VS_OUTPUT_HEADER 0x02 +#define VS_STILL_IMAGE_FRAME 0x03 +#define VS_FORMAT_UNCOMPRESSED 0x04 +#define VS_FRAME_UNCOMPRESSED 0x05 +#define VS_FORMAT_MJPEG 0x06 +#define VS_FRAME_MJPEG 0x07 +#define VS_FORMAT_MPEG1 0x08 +#define VS_FORMAT_MPEG2PS 0x09 +#define VS_FORMAT_MPEG2TS 0x0A +#define VS_FORMAT_MPEG4SL 0x0B +#define VS_FORMAT_DV 0x0C +#define VS_COLORFORMAT 0x0D +#define VS_FORMAT_VENDOR 0x0E +#define VS_FRAME_VENDOR 0x0F + +// Video Class-Specific Endpoint Descriptor Subtypes +#define EP_UNDEFINED 0x00 +#define EP_GENERAL 0x01 +#define EP_ENDPOINT 0x02 +#define EP_INTERRUPT 0x03 + +// Video Class-Specific Terminal Types +#define TERMINAL_TYPE_VENDOR_SPECIFIC 0x0100 +#define TERMINAL_TYPE_USB_STREAMING 0x0101 +#define TERMINAL_TYPE_INPUT_MASK 0x0200 +#define TERMINAL_TYPE_INPUT_VENDOR_SPECIFIC 0x0200 +#define TERMINAL_TYPE_INPUT_CAMERA 0x0201 +#define TERMINAL_TYPE_INPUT_MEDIA_TRANSPORT 0x0202 +#define TERMINAL_TYPE_OUTPUT_MASK 0x0300 +#define TERMINAL_TYPE_OUTPUT_VENDOR_SPECIFIC 0x0300 +#define TERMINAL_TYPE_OUTPUT_DISPLAY 0x0301 +#define TERMINAL_TYPE_OUTPUT_MEDIA_TRANSPORT 0x0302 +#define TERMINAL_TYPE_EXTERNAL_VENDOR_SPECIFIC 0x0400 +#define TERMINAL_TYPE_EXTERNAL_UNDEFINED 0x0400 +#define TERMINAL_TYPE_EXTERNAL_COMPOSITE 0x0401 +#define TERMINAL_TYPE_EXTERNAL_SVIDEO 0x0402 +#define TERMINAL_TYPE_EXTERNAL_COMPONENT 0x0403 + + +// Controls for error checking only +#define DEV_SPECIFIC_CONTROL 0x1001 + +// Map KSNODE_TYPE GUIDs to Indexes +#define NODE_TYPE_NONE 0 +#define NODE_TYPE_STREAMING 1 +#define NODE_TYPE_INPUT_TERMINAL 2 +#define NODE_TYPE_OUTPUT_TERMINAL 3 +#define NODE_TYPE_SELECTOR 4 +#define NODE_TYPE_PROCESSING 5 +#define NODE_TYPE_CAMERA_TERMINAL 6 +#define NODE_TYPE_INPUT_MTT 7 +#define NODE_TYPE_OUTPUT_MTT 8 +#define NODE_TYPE_DEV_SPEC 9 +#define NODE_TYPE_MAX 9 + +// USB bmRequestType values +#define USBVIDEO_INTERFACE_SET 0x21 +#define USBVIDEO_ENDPOINT_SET 0x22 +#define USBVIDEO_INTERFACE_GET 0xA1 +#define USBVIDEO_ENDPOINT_GET 0xA2 + +// Video Class-specific specific requests +#define CLASS_SPECIFIC_GET_MASK 0x80 + +#define RC_UNDEFINED 0x00 +#define SET_CUR 0x01 +#define GET_CUR 0x81 +#define GET_MIN 0x82 +#define GET_MAX 0x83 +#define GET_RES 0x84 +#define GET_LEN 0x85 +#define GET_INFO 0x86 +#define GET_DEF 0x87 + +// Power Mode Control constants +#define POWER_MODE_CONTROL_FULL 0x0 +#define POWER_MODE_CONTROL_DEV_DEPENDENT 0x1 + +// Video Class-specific Processing Unit Controls +#define PU_CONTROL_UNDEFINED 0x00 +#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 +#define PU_BRIGHTNESS_CONTROL 0x02 +#define PU_CONTRAST_CONTROL 0x03 +#define PU_GAIN_CONTROL 0x04 +#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 +#define PU_HUE_CONTROL 0x06 +#define PU_SATURATION_CONTROL 0x07 +#define PU_SHARPNESS_CONTROL 0x08 +#define PU_GAMMA_CONTROL 0x09 +#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0A +#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B +#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0C +#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0D +#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0E +#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0F +#define PU_HUE_AUTO_CONTROL 0x10 +#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 +#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 + +// Video Class-specific Camera Terminal Controls +#define CT_CONTROL_UNDEFINED 0x00 +#define CT_SCANNING_MODE_CONTROL 0x01 +#define CT_AE_MODE_CONTROL 0x02 +#define CT_AE_PRIORITY_CONTROL 0x03 +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 +#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 +#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 +#define CT_FOCUS_RELATIVE_CONTROL 0x07 +#define CT_FOCUS_AUTO_CONTROL 0x08 +#define CT_IRIS_ABSOLUTE_CONTROL 0x09 +#define CT_IRIS_RELATIVE_CONTROL 0x0A +#define CT_ZOOM_ABSOLUTE_CONTROL 0x0B +#define CT_ZOOM_RELATIVE_CONTROL 0x0C +#define CT_PANTILT_ABSOLUTE_CONTROL 0x0D +#define CT_PANTILT_RELATIVE_CONTROL 0x0E +#define CT_ROLL_ABSOLUTE_CONTROL 0x0F +#define CT_ROLL_RELATIVE_CONTROL 0x10 +#define CT_PRIVACY_CONTROL 0x11 + +#define CT_RELATIVE_INCREASE 0x01 +#define CT_RELATIVE_DECREASE 0xff +#define CT_RELATIVE_STOP 0x00 + +// Selector Unit Control Selector +#define SU_INPUT_SELECT_CONTROL 0x01 + +// Media Tape Transport Control Selector +#define MTT_CONTROL_UNDEFINED 0x00 +#define MTT_TRANSPORT_CONTROL 0x01 +#define MTT_ATN_INFORMATION_CONTROL 0x02 +#define MTT_MEDIA_INFORMATION_CONTROL 0x03 +#define MTT_TIME_CODE_INFORMATION_CONTROL 0x04 + +// Media Transport Terminal States +#define MTT_STATE_PLAY_NEXT_FRAME 0x00 +#define MTT_STATE_PLAY_FWD_SLOWEST 0x01 +#define MTT_STATE_PLAY_SLOW_FWD_4 0x02 +#define MTT_STATE_PLAY_SLOW_FWD_3 0x03 +#define MTT_STATE_PLAY_SLOW_FWD_2 0x04 +#define MTT_STATE_PLAY_SLOW_FWD_1 0x05 +#define MTT_STATE_PLAY_X1 0x06 +#define MTT_STATE_PLAY_FAST_FWD_1 0x07 +#define MTT_STATE_PLAY_FAST_FWD_2 0x08 +#define MTT_STATE_PLAY_FAST_FWD_3 0x09 +#define MTT_STATE_PLAY_FAST_FWD_4 0x0A +#define MTT_STATE_PLAY_FASTEST_FWD 0x0B +#define MTT_STATE_PLAY_PREV_FRAME 0x0C +#define MTT_STATE_PLAY_SLOWEST_REV 0x0D +#define MTT_STATE_PLAY_SLOW_REV_4 0x0E +#define MTT_STATE_PLAY_SLOW_REV_3 0x0F +#define MTT_STATE_PLAY_SLOW_REV_2 0x10 +#define MTT_STATE_PLAY_SLOW_REV_1 0x11 +#define MTT_STATE_PLAY_REV 0x12 +#define MTT_STATE_PLAY_FAST_REV_1 0x13 +#define MTT_STATE_PLAY_FAST_REV_2 0x14 +#define MTT_STATE_PLAY_FAST_REV_3 0x15 +#define MTT_STATE_PLAY_FAST_REV_4 0x16 +#define MTT_STATE_PLAY_FASTEST_REV 0x17 +#define MTT_STATE_PLAY 0x18 +#define MTT_STATE_PAUSE 0x19 +#define MTT_STATE_PLAY_REVERSE_PAUSE 0x1A + + +#define MTT_STATE_STOP 0x40 +#define MTT_STATE_FAST_FORWARD 0x41 +#define MTT_STATE_REWIND 0x42 +#define MTT_STATE_HIGH_SPEED_REWIND 0x43 + +#define MTT_STATE_RECORD_START 0x50 +#define MTT_STATE_RECORD_PAUSE 0x51 + +#define MTT_STATE_EJECT 0x60 + +#define MTT_STATE_PLAY_SLOW_FWD_X 0x70 +#define MTT_STATE_PLAY_FAST_FWD_X 0x71 +#define MTT_STATE_PLAY_SLOW_REV_X 0x72 +#define MTT_STATE_PLAY_FAST_REV_X 0x73 +#define MTT_STATE_STOP_START 0x74 +#define MTT_STATE_STOP_END 0x75 +#define MTT_STATE_STOP_EMERGENCY 0x76 +#define MTT_STATE_STOP_CONDENSATION 0x77 +#define MTT_STATE_UNSPECIFIED 0x7F + +// Video Control Interface Control Selectors +#define VC_UNDEFINED_CONTROL 0x00 +#define VC_VIDEO_POWER_MODE_CONTROL 0x01 +#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 + +// VideoStreaming Interface Control Selectors +#define VS_CONTROL_UNDEFINED 0x00 +#define VS_PROBE_CONTROL 0x01 +#define VS_COMMIT_CONTROL 0x02 +#define VS_STILL_PROBE_CONTROL 0x03 +#define VS_STILL_COMMIT_CONTROL 0x04 +#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 +#define VS_STREAM_ERROR_CODE_CONTROL 0x06 +#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 +#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 +#define VS_SYNC_DELAY_CONTROL 0x09 + +// Probe commit bitmap framing info +#define VS_PROBE_COMMIT_BIT_FID 0x01 +#define VS_PROBE_COMMIT_BIT_EOF 0x02 + +// Stream payload header Bit Field Header bits +#define BFH_FID 0x01 // Frame ID bit +#define BFH_EOF 0x02 // End of Frame bit +#define BFH_PTS 0x04 // Presentation Time Stamp bit +#define BFH_SCR 0x08 // Source Clock Reference bit +#define BFH_RES 0x10 // Reserved bit +#define BFH_STI 0x20 // Still image bit +#define BFH_ERR 0x40 // Error bit +#define BFH_EOH 0x80 // End of header bit + +#define HDR_LENGTH 1 // Length of header length field in bytes +#define BFH_LENGTH 1 // Length of BFH field in bytes +#define PTS_LENGTH 4 // Length of PTS field in bytes +#define SCR_LENGTH 6 // Length of SCR field in bytes + +// USB Video Status Codes (Request Error Code Control) +#define USBVIDEO_RE_STATUS_NOERROR 0x00 +#define USBVIDEO_RE_STATUS_NOT_READY 0x01 +#define USBVIDEO_RE_STATUS_WRONG_STATE 0x02 +#define USBVIDEO_RE_STATUS_POWER 0x03 +#define USBVIDEO_RE_STATUS_OUT_OF_RANGE 0x04 +#define USBVIDEO_RE_STATUS_INVALID_UNIT 0x05 +#define USBVIDEO_RE_STATUS_INVALID_CONTROL 0x06 +#define USBVIDEO_RE_STATUS_UNKNOWN 0x07 + +// USB Video Device Status Codes (Stream Error Code Control) +#define USBVIDEO_SE_STATUS_NOERROR 0x00 +#define USBVIDEO_SE_STATUS_PROTECTED_CONTENT 0x01 +#define USBVIDEO_SE_STATUS_INPUT_BUFFER_UNDERRUN 0x02 +#define USBVIDEO_SE_STATUS_DATA_DICONTINUITY 0x03 +#define USBVIDEO_SE_STATUS_OUTPUT_BUFFER_UNDERRUN 0x04 +#define USBVIDEO_SE_STATUS_OUTPUT_BUFFER_OVERRUN 0x05 +#define USBVIDEO_SE_STATUS_FORMAT_CHANGE 0x06 +#define USBVIDEO_SE_STATUS_STILL_IMAGE_ERROR 0x07 +#define USBVIDEO_SE_STATUS_UNKNOWN 0x08 + +// Status Interrupt Types +#define STATUS_INTERRUPT_VC 1 +#define STATUS_INTERRUPT_VS 2 + +// Status Interrupt Attributes +#define STATUS_INTERRUPT_ATTRIBUTE_VALUE 0x00 +#define STATUS_INTERRUPT_ATTRIBUTE_INFO 0x01 +#define STATUS_INTERRUPT_ATTRIBUTE_FAILURE 0x02 + +// VideoStreaming interface interrupt types +#define VS_INTERRUPT_EVENT_BUTTON_PRESS 0x00 +#define VS_INTERRUPT_VALUE_BUTTON_RELEASE 0x00 +#define VS_INTERRUPT_VALUE_BUTTON_PRESS 0x01 + +// Get Info Values +#define USBVIDEO_ASYNC_CONTROL 0x10 +#define USBVIDEO_SETTABLE_CONTROL 0x2 + +#define MAX_INTERRUPT_PACKET_VALUE_SIZE 8 + +// Frame descriptor frame interval array offsets +#define MIN_FRAME_INTERVAL_OFFSET 0 +#define MAX_FRAME_INTERVAL_OFFSET 1 +#define FRAME_INTERVAL_STEP_OFFSET 2 + +// Still image capture methods +#define STILL_CAPTURE_METHOD_NONE 0 +#define STILL_CAPTURE_METHOD_1 1 +#define STILL_CAPTURE_METHOD_2 2 +#define STILL_CAPTURE_METHOD_3 3 + +// Still image trigger control states +#define STILL_IMAGE_TRIGGER_NORMAL 0 +#define STILL_IMAGE_TRIGGER_TRANSMIT 1 +#define STILL_IMAGE_TRIGGER_TRANSMIT_BULK 2 +#define STILL_IMAGE_TRIGGER_TRANSMIT_ABORT 3 + +// Endpoint descriptor masks +#define EP_DESCRIPTOR_TRANSACTION_SIZE_MASK 0x07ff +#define EP_DESCRIPTOR_NUM_TRANSACTION_MASK 0x1800 +#define EP_DESCRIPTOR_NUM_TRANSACTION_OFFSET 11 + + +// Copy protection flag defined in the Uncompressed Payload Spec +#define USB_VIDEO_UNCOMPRESSED_RESTRICT_DUPLICATION 1 + +// Interlace flags +#define INTERLACE_FLAGS_SUPPORTED_MASK 0x01 +#define INTERLACE_FLAGS_FIELDS_PER_FRAME_MASK 0x02 +#define INTERLACE_FLAGS_FIELDS_PER_FRAME_2 0x00 +#define INTERLACE_FLAGS_FIELDS_PER_FRAME_1 0x02 +#define INTERLACE_FLAGS_FIELD_1_FIRST_MASK 0x04 +#define INTERLACE_FLAGS_FIELD_PATTERN_MASK 0x30 +#define INTERLACE_FLAGS_FIELD_PATTERN_FIELD1 0x00 +#define INTERLACE_FLAGS_FIELD_PATTERN_FIELD2 0x10 +#define INTERLACE_FLAGS_FIELD_PATTERN_REGULAR 0x20 +#define INTERLACE_FLAGS_FIELD_PATTERN_RANDOM 0x30 +#define INTERLACE_FLAGS_DISPLAY_MODE_MASK 0xC0 +#define INTERLACE_FLAGS_DISPLAY_MODE_BOB 0x00 +#define INTERLACE_FLAGS_DISPLAY_MODE_WEAVE 0x40 +#define INTERLACE_FLAGS_DISPLAY_MODE_BOB_WEAVE 0x80 + +// Color Matching Flags +#define UVC_PRIMARIES_UNKNOWN 0x0 +#define UVC_PRIMARIES_BT709 0x1 +#define UVC_PRIMARIES_BT470_2M 0x2 +#define UVC_PRIMARIES_BT470_2BG 0x3 +#define UVC_PRIMARIES_SMPTE_170M 0x4 +#define UVC_PRIMARIES_SMPTE_240M 0x5 + +#define UVC_GAMMA_UNKNOWN 0x0 +#define UVC_GAMMA_BT709 0x1 +#define UVC_GAMMA_BT470_2M 0x2 +#define UVC_GAMMA_BT470_2BG 0x3 +#define UVC_GAMMA_SMPTE_170M 0x4 +#define UVC_GAMMA_SMPTE_240M 0x5 +#define UVC_GAMMA_LINEAR 0x6 +#define UVC_GAMMA_sRGB 0x7 + +#define UVC_TRANSFER_MATRIX_UNKNOWN 0x0 +#define UVC_TRANSFER_MATRIX_BT709 0x1 +#define UVC_TRANSFER_MATRIX_FCC 0x2 +#define UVC_TRANSFER_MATRIX_BT470_2BG 0x3 +#define UVC_TRANSFER_MATRIX_BT601 0x4 +#define UVC_TRANSFER_MATRIX_SMPTE_240M 0x5 + +// +// BEGIN - VDC Descriptor and Control Structures +// +#pragma warning( disable : 4200 ) // Allow zero-sized arrays at end of structs +#pragma pack( push, vdc_descriptor_structs, 1) + +// Video Specific Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // descriptor subtype +} VIDEO_SPECIFIC, *PVIDEO_SPECIFIC; + +#define SIZEOF_VIDEO_SPECIFIC(pDesc) sizeof(VIDEO_SPECIFIC) + + +// Video Unit Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // descriptor subtype + UCHAR bUnitID; // Constant uniquely identifying the Unit +} VIDEO_UNIT, *PVIDEO_UNIT; + +#define SIZEOF_VIDEO_UNIT(pDesc) sizeof(VIDEO_UNIT) + +// VideoControl Header Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // VC_HEADER descriptor subtype + USHORT bcdVideoSpec; // USB video class spec revision number + USHORT wTotalLength; // Total length, including all units and terminals + ULONG dwClockFreq; // Device clock frequency in Hz + UCHAR bInCollection; // number of video streaming interfaces + UCHAR baInterfaceNr[]; // interface number array +} VIDEO_CONTROL_HEADER_UNIT, *PVIDEO_CONTROL_HEADER_UNIT; + +#define SIZEOF_VIDEO_CONTROL_HEADER_UNIT(pDesc) \ + ((sizeof(VIDEO_CONTROL_HEADER_UNIT) + (pDesc)->bInCollection)) + + +// VideoControl Input Terminal Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // INPUT_TERMINAL descriptor subtype + UCHAR bTerminalID; // Constant uniquely identifying the Terminal + USHORT wTerminalType; // Constant characterizing the terminal type + UCHAR bAssocTerminal; // ID of associated output terminal + UCHAR iTerminal; // Index of string descriptor +} VIDEO_INPUT_TERMINAL, *PVIDEO_INPUT_TERMINAL; + +#define SIZEOF_VIDEO_INPUT_TERMINAL(pDesc) sizeof(VIDEO_INPUT_TERMINAL) + + +// VideoControl Output Terminal Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // OUTPUT_TERMINAL descriptor subtype + UCHAR bTerminalID; // Constant uniquely identifying the Terminal + USHORT wTerminalType; // Constant characterizing the terminal type + UCHAR bAssocTerminal; // ID of associated input terminal + UCHAR bSourceID; // ID of source unit/terminal + UCHAR iTerminal; // Index of string descriptor +} VIDEO_OUTPUT_TERMINAL, *PVIDEO_OUTPUT_TERMINAL; + +#define SIZEOF_VIDEO_OUTPUT_TERMINAL(pDesc) sizeof(VIDEO_OUTPUT_TERMINAL) + + +// VideoControl Camera Terminal Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // INPUT_TERMINAL descriptor subtype + UCHAR bTerminalID; // Constant uniquely identifying the Terminal + USHORT wTerminalType; // Sensor type + UCHAR bAssocTerminal; // ID of associated output terminal + UCHAR iTerminal; // Index of string descriptor + USHORT wObjectiveFocalLengthMin; // Min focal length for zoom + USHORT wObjectiveFocalLengthMax; // Max focal length for zoom + USHORT wOcularFocalLength; // Ocular focal length for zoom + UCHAR bControlSize; // Size of bmControls field + UCHAR bmControls[]; // Bitmap of controls supported +} VIDEO_CAMERA_TERMINAL, *PVIDEO_CAMERA_TERMINAL; + +#define SIZEOF_VIDEO_CAMERA_TERMINAL(pDesc) \ + (sizeof(VIDEO_CAMERA_TERMINAL) + (pDesc)->bControlSize) + + +// Media Transport Input Terminal Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // INPUT_TERMINAL descriptor subtype + UCHAR bTerminalID; // Constant uniquely identifying the Terminal + USHORT wTerminalType; // Media Transport type + UCHAR bAssocTerminal; // ID of associated output terminal + UCHAR iTerminal; // Index of string descriptor + UCHAR bControlSize; // Size of bmControls field + UCHAR bmControls[]; // Bitmap of controls supported +} VIDEO_INPUT_MTT, *PVIDEO_INPUT_MTT; + + +__inline size_t SizeOfVideoInputMTT(_In_ PVIDEO_INPUT_MTT pDesc) +{ + UCHAR bTransportModeSize; + PUCHAR pbCurr; + + pbCurr = pDesc->bmControls + pDesc->bControlSize; + bTransportModeSize = *pbCurr; + + return sizeof(VIDEO_INPUT_MTT) + pDesc->bControlSize + 1 + bTransportModeSize; +} + +#define SIZEOF_VIDEO_INPUT_MTT(pDesc) SizeOfVideoInputMTT(pDesc) + + +// Media Transport Output Terminal Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // OUTPUT_TERMINAL descriptor subtype + UCHAR bTerminalID; // Constant uniquely identifying the Terminal + USHORT wTerminalType; // Media Transport type + UCHAR bAssocTerminal; // ID of associated output terminal + UCHAR bSourceID; // ID of source unit/terminal + UCHAR iTerminal; // Index of string descriptor + UCHAR bControlSize; // Size of bmControls field + UCHAR bmControls[]; // Bitmap of controls supported +} VIDEO_OUTPUT_MTT, *PVIDEO_OUTPUT_MTT; + + +__inline size_t SizeOfVideoOutputMTT(_In_ PVIDEO_OUTPUT_MTT pDesc) +{ + UCHAR bTransportModeSize; + PUCHAR pbCurr; + + pbCurr = pDesc->bmControls + pDesc->bControlSize; + bTransportModeSize = *pbCurr; + + return sizeof(VIDEO_OUTPUT_MTT) + pDesc->bControlSize + 1+ bTransportModeSize; +} + +#define SIZEOF_VIDEO_OUTPUT_MTT(pDesc) SizeOfVideoOutputMTT(pDesc) + + +// VideoControl Selector Unit Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // SELECTOR_UNIT descriptor subtype + UCHAR bUnitID; // Constant uniquely identifying the Unit + UCHAR bNrInPins; // Number of input pins + UCHAR baSourceID[]; // IDs of connected units/terminals +} VIDEO_SELECTOR_UNIT, *PVIDEO_SELECTOR_UNIT; + +#define SIZEOF_VIDEO_SELECTOR_UNIT(pDesc) \ + (sizeof(VIDEO_SELECTOR_UNIT) + (pDesc)->bNrInPins + 1) + + +// VideoControl Processing Unit Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // PROCESSING_UNIT descriptor subtype + UCHAR bUnitID; // Constant uniquely identifying the Unit + UCHAR bSourceID; // ID of connected unit/terminal + USHORT wMaxMultiplier; // Maximum digital magnification + UCHAR bControlSize; // Size of bmControls field + UCHAR bmControls[]; // Bitmap of controls supported +} VIDEO_PROCESSING_UNIT, *PVIDEO_PROCESSING_UNIT; + +#define SIZEOF_VIDEO_PROCESSING_UNIT(pDesc) \ + (sizeof(VIDEO_PROCESSING_UNIT) + 1 + (pDesc)->bControlSize) + + +// VideoControl Extension Unit Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // EXTENSION_UNIT descriptor subtype + UCHAR bUnitID; // Constant uniquely identifying the Unit + GUID guidExtensionCode; // Vendor-specific code identifying extension unit + UCHAR bNumControls; // Number of controls in Extension Unit + UCHAR bNrInPins; // Number of input pins + UCHAR baSourceID[]; // IDs of connected units/terminals +} VIDEO_EXTENSION_UNIT, *PVIDEO_EXTENSION_UNIT; +// this is followed by bControlSize, bmControls and iExtension (1 byte) + +__inline size_t SizeOfVideoExtensionUnit(PVIDEO_EXTENSION_UNIT pDesc) +{ + UCHAR bControlSize; + PUCHAR pbCurr; + + // baSourceID is an array, and hence understood to be an address + pbCurr = pDesc->baSourceID + pDesc->bNrInPins; + if (((ULONG_PTR) pbCurr < (ULONG_PTR) pDesc->baSourceID) || + (ULONG_PTR) pbCurr >= (ULONG_PTR)((UCHAR *) pDesc + pDesc->bLength)) + return 0; + + bControlSize = *pbCurr; + return 24 + pDesc->bNrInPins + bControlSize; +} + +#define SIZEOF_VIDEO_EXTENSION_UNIT(pDesc) SizeOfVideoExtensionUnit(pDesc) + + +// Class-specific Interrupt Endpoint Descriptor +typedef struct { + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_ENDPOINT descriptor type + UCHAR bDescriptorSubtype; // EP_INTERRUPT descriptor subtype + USHORT wMaxTransferSize; // Max interrupt payload size +} VIDEO_CS_INTERRUPT, *PVIDEO_CS_INTERRUPT; + +#define SIZEOF_VIDEO_CS_INTERRUPT(pDesc) sizeof(VIDEO_CS_INTERRUPT) + + +// VideoStreaming Input Header Descriptor +typedef struct _VIDEO_STREAMING_INPUT_HEADER +{ + UCHAR bLength; // Size of this descriptor in bytes + UCHAR bDescriptorType; // CS_INTERFACE descriptor type + UCHAR bDescriptorSubtype; // VS_INPUT_HEADER descriptor subtype + UCHAR bNumFormats; + USHORT wTotalLength; + UCHAR bEndpointAddress; + UCHAR bmInfo; + UCHAR bTerminalLink; + UCHAR bStillCaptureMethod; + UCHAR bTriggerSupport; + UCHAR bTriggerUsage; + UCHAR bControlSize; + UCHAR bmaControls[]; +} VIDEO_STREAMING_INPUT_HEADER, *PVIDEO_STREAMING_INPUT_HEADER; + +#define SIZEOF_VIDEO_STREAMING_INPUT_HEADER(pDesc) \ + (sizeof(VIDEO_STREAMING_INPUT_HEADER) + (pDesc->bNumFormats * pDesc->bControlSize)) + + +// VideoStreaming Output Header Descriptor +typedef struct _VIDEO_STREAMING_OUTPUT_HEADER +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bNumFormats; + USHORT wTotalLength; + UCHAR bEndpointAddress; + UCHAR bTerminalLink; +} VIDEO_STREAMING_OUTPUT_HEADER, *PVIDEO_STREAMING_OUTPUT_HEADER; + +#define SIZEOF_VIDEO_STREAMING_OUTPUT_HEADER(pDesc) sizeof(VIDEO_STREAMING_OUTPUT_HEADER) + + +typedef struct _VIDEO_STILL_IMAGE_RECT +{ + USHORT wWidth; + USHORT wHeight; +} VIDEO_STILL_IMAGE_RECT; + +// VideoStreaming Still Image Frame Descriptor +typedef struct _VIDEO_STILL_IMAGE_FRAME +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bEndpointAddress; + UCHAR bNumImageSizePatterns; + VIDEO_STILL_IMAGE_RECT aStillRect[]; +} VIDEO_STILL_IMAGE_FRAME, *PVIDEO_STILL_IMAGE_FRAME; + +__inline size_t SizeOfVideoStillImageFrame(PVIDEO_STILL_IMAGE_FRAME pDesc) +{ + UCHAR bNumCompressionPatterns; + PUCHAR pbCurr; + + pbCurr = (PUCHAR) pDesc->aStillRect + (sizeof(VIDEO_STILL_IMAGE_RECT) * pDesc->bNumImageSizePatterns); + bNumCompressionPatterns = *pbCurr; + + return (sizeof(VIDEO_STILL_IMAGE_FRAME) + + (sizeof(VIDEO_STILL_IMAGE_RECT) * pDesc->bNumImageSizePatterns) + + 1 + bNumCompressionPatterns); +} + +#define SIZEOF_VIDEO_STILL_IMAGE_FRAME(pDesc) SizeOfVideoStillImageFrame(pDesc) + + +// VideoStreaming Color Matching Descriptor +typedef struct _VIDEO_COLORFORMAT +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bColorPrimaries; + UCHAR bTransferCharacteristics; + UCHAR bMatrixCoefficients; +} VIDEO_COLORFORMAT, *PVIDEO_COLORFORMAT; + +#define SIZEOF_VIDEO_COLORFORMAT(pDesc) sizeof(VIDEO_COLORFORMAT) + + +// VideoStreaming Uncompressed Format Descriptor +typedef struct _VIDEO_FORMAT_UNCOMPRESSED +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + GUID guidFormat; + UCHAR bBitsPerPixel; + UCHAR bDefaultFrameIndex; + UCHAR bAspectRatioX; + UCHAR bAspectRatioY; + UCHAR bmInterlaceFlags; + UCHAR bCopyProtect; +} VIDEO_FORMAT_UNCOMPRESSED, *PVIDEO_FORMAT_UNCOMPRESSED; + +#define SIZEOF_VIDEO_FORMAT_UNCOMPRESSED(pDesc) sizeof(VIDEO_FORMAT_UNCOMPRESSED) + + +// VideoStreaming Uncompressed Frame Descriptor +typedef struct _VIDEO_FRAME_UNCOMPRESSED +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG dwMinBitRate; + ULONG dwMaxBitRate; + ULONG dwMaxVideoFrameBufferSize; + ULONG dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG adwFrameInterval[]; +} VIDEO_FRAME_UNCOMPRESSED, *PVIDEO_FRAME_UNCOMPRESSED; + + +__inline size_t SizeOfVideoFrameUncompressed(_In_ PVIDEO_FRAME_UNCOMPRESSED pDesc) +{ + if (pDesc->bFrameIntervalType == 0) { // Continuous + return sizeof(VIDEO_FRAME_UNCOMPRESSED) + (3 * sizeof(ULONG)); + } + else { // Discrete + return sizeof(VIDEO_FRAME_UNCOMPRESSED) + (pDesc->bFrameIntervalType * sizeof(ULONG)); + } +} + +#define SIZEOF_VIDEO_FRAME_UNCOMPRESSED(pDesc) SizeOfVideoFrameUncompressed(pDesc) + + +// VideoStreaming MJPEG Format Descriptor +typedef struct _VIDEO_FORMAT_MJPEG +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + UCHAR bmFlags; + UCHAR bDefaultFrameIndex; + UCHAR bAspectRatioX; + UCHAR bAspectRatioY; + UCHAR bmInterlaceFlags; + UCHAR bCopyProtect; +} VIDEO_FORMAT_MJPEG, *PVIDEO_FORMAT_MJPEG; + +#define SIZEOF_VIDEO_FORMAT_MJPEG(pDesc) sizeof(VIDEO_FORMAT_MJPEG) + + +// VideoStreaming MJPEG Frame Descriptor +typedef struct _VIDEO_FRAME_MJPEG +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG dwMinBitRate; + ULONG dwMaxBitRate; + ULONG dwMaxVideoFrameBufferSize; + ULONG dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG adwFrameInterval[]; +} VIDEO_FRAME_MJPEG, *PVIDEO_FRAME_MJPEG; + + +__inline size_t SizeOfVideoFrameMjpeg(_In_ PVIDEO_FRAME_MJPEG pDesc) +{ + if (pDesc->bFrameIntervalType == 0) { // Continuous + return sizeof(VIDEO_FRAME_MJPEG) + (3 * sizeof(ULONG)); + } + else { // Discrete + return sizeof(VIDEO_FRAME_MJPEG) + (pDesc->bFrameIntervalType * sizeof(ULONG)); + } +} + +#define SIZEOF_VIDEO_FRAME_MJPEG(pDesc) SizeOfVideoFrameMjpeg(pDesc) + + +// VideoStreaming Vendor Format Descriptor +typedef struct _VIDEO_FORMAT_VENDOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + GUID guidMajorFormat; + GUID guidSubFormat; + GUID guidSpecifier; + UCHAR bPayloadClass; + UCHAR bDefaultFrameIndex; + UCHAR bCopyProtect; +} VIDEO_FORMAT_VENDOR, *PVIDEO_FORMAT_VENDOR; + +#define SIZEOF_VIDEO_FORMAT_VENDOR(pDesc) sizeof(VIDEO_FORMAT_VENDOR) + + +// VideoStreaming Vendor Frame Descriptor +typedef struct _VIDEO_FRAME_VENDOR +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG dwMinBitRate; + ULONG dwMaxBitRate; + ULONG dwMaxVideoFrameBufferSize; + ULONG dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + DWORD adwFrameInterval[]; +} VIDEO_FRAME_VENDOR, *PVIDEO_FRAME_VENDOR; + +__inline size_t SizeOfVideoFrameVendor(_In_ PVIDEO_FRAME_VENDOR pDesc) +{ + if (pDesc->bFrameIntervalType == 0) { // Continuous + return sizeof(VIDEO_FRAME_VENDOR) + (3 * sizeof(ULONG)); + } + else { // Discrete + return sizeof(VIDEO_FRAME_VENDOR) + (pDesc->bFrameIntervalType * sizeof(ULONG)); + } +} + +#define SIZEOF_VIDEO_FRAME_VENDOR(pDesc) SizeOfVideoFrameVendor(pDesc) + + +// VideoStreaming DV Format Descriptor +typedef struct _VIDEO_FORMAT_DV +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + ULONG dwMaxVideoFrameBufferSize; + UCHAR bFormatType; +} VIDEO_FORMAT_DV, *PVIDEO_FORMAT_DV; + +#define SIZEOF_VIDEO_FORMAT_DV(pDesc) sizeof(VIDEO_FORMAT_DV) + + +// VideoStreaming MPEG2-TS Format Descriptor +typedef struct _VIDEO_FORMAT_MPEG2TS +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bDataOffset; + UCHAR bPacketLength; + UCHAR bStrideLength; +} VIDEO_FORMAT_MPEG2TS, *PVIDEO_FORMAT_MPEG2TS; + +#define SIZEOF_VIDEO_FORMAT_MPEG2TS(pDesc) sizeof(VIDEO_FORMAT_MPEG2TS) + + +// VideoStreaming MPEG1 System Stream Format Descriptor +typedef struct _VIDEO_FORMAT_MPEG1SS +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bPacketLength; + UCHAR bPackLength; + UCHAR bPackDataType; +} VIDEO_FORMAT_MPEG1SS, *PVIDEO_FORMAT_MPEG1SS; + +#define SIZEOF_VIDEO_FORMAT_MPEG1SS(pDesc) sizeof(VIDEO_FORMAT_MPEG1SS) + + +// VideoStreaming MPEG2-PS Format Descriptor +typedef struct _VIDEO_FORMAT_MPEG2PS +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bPacketLength; + UCHAR bPackLength; + UCHAR bPackDataType; +} VIDEO_FORMAT_MPEG2PS, *PVIDEO_FORMAT_MPEG2PS; + +#define SIZEOF_VIDEO_FORMAT_MPEG2PS(pDesc) sizeof(VIDEO_FORMAT_MPEG2PS) + + +// VideoStreaming MPEG4-SL Format Descriptor +typedef struct _VIDEO_FORMAT_MPEG4SL +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bPacketLength; +} VIDEO_FORMAT_MPEG4SL, *PVIDEO_FORMAT_MPEG4SL; + +#define SIZEOF_VIDEO_FORMAT_MPEG4SL(pDesc) sizeof(VIDEO_FORMAT_MPEG4SL) + +// VideoStreaming Probe/Commit Control +typedef struct _VS_PROBE_COMMIT_CONTROL +{ + USHORT bmHint; + UCHAR bFormatIndex; + UCHAR bFrameIndex; + ULONG dwFrameInterval; + USHORT wKeyFrameRate; + USHORT wPFrameRate; + USHORT wCompQuality; + USHORT wCompWindowSize; + USHORT wDelay; + ULONG dwMaxVideoFrameSize; + ULONG dwMaxPayloadTransferSize; +} VS_PROBE_COMMIT_CONTROL, *PVS_PROBE_COMMIT_CONTROL; + +// VideoStreaming Still Probe/Commit Control +typedef struct _VS_STILL_PROBE_COMMIT_CONTROL +{ + UCHAR bFormatIndex; + UCHAR bFrameIndex; + UCHAR bCompressionIndex; + ULONG dwMaxVideoFrameSize; + ULONG dwMaxPayloadTransferSize; +} VS_STILL_PROBE_COMMIT_CONTROL, *PVS_STILL_PROBE_COMMIT_CONTROL; + + +// Status Interrupt Packet (Video Control) +typedef struct _VC_INTERRUPT_PACKET +{ + UCHAR bStatusType; + UCHAR bOriginator; + UCHAR bEvent; + UCHAR bSelector; + UCHAR bAttribute; + UCHAR bValue[1]; +} VC_INTERRUPT_PACKET, *PVC_INTERRUPT_PACKET; + +// Status Interrupt Packet (Video Control) +typedef struct _VC_INTERRUPT_PACKET_EX +{ + UCHAR bStatusType; + UCHAR bOriginator; + UCHAR bEvent; + UCHAR bSelector; + UCHAR bAttribute; + UCHAR bValue[MAX_INTERRUPT_PACKET_VALUE_SIZE]; +} VC_INTERRUPT_PACKET_EX, *PVC_INTERRUPT_PACKET_EX; + +// Status Interrupt Packet (Video Streaming) +typedef struct _VS_INTERRUPT_PACKET +{ + UCHAR bStatusType; + UCHAR bOriginator; + UCHAR bEvent; + UCHAR bValue[1]; +} VS_INTERRUPT_PACKET, *PVS_INTERRUPT_PACKET; + +// Status Interrupt Packet (Generic) +typedef struct _VIDEO_INTERRUPT_PACKET +{ + UCHAR bStatusType; + UCHAR bOriginator; +} VIDEO_INTERRUPT_PACKET, *PVIDEO_INTERRUPT_PACKET; + + +// Relative property struct +typedef struct _VIDEO_RELATIVE_PROPERTY +{ + UCHAR bValue; + UCHAR bSpeed; +} VIDEO_RELATIVE_PROPERTY, *PVIDEO_RELATIVE_PROPERTY; + +// Relative Zoom control struct +typedef struct _ZOOM_RELATIVE_PROPERTY +{ + UCHAR bZoom; + UCHAR bDigitalZoom; + UCHAR bSpeed; +} ZOOM_RELATIVE_PROPERTY, *PZOOM_RELATIVE_PROPERTY; + +// Relative pan-tilt struct +typedef struct _PANTILT_RELATIVE_PROPERTY +{ + UCHAR bPanRelative; + UCHAR bPanSpeed; + UCHAR bTiltRelative; + UCHAR bTiltSpeed; +} PANTILT_RELATIVE_PROPERTY, *PPANTILT_RELATIVE_PROPERTY; + +typedef struct _MEDIA_INFORMATION_CONTROL +{ + UCHAR bmMediaType; + UCHAR bmWriteProtect; +} MEDIA_INFORMATION_CONTROL, *PMEDIA_INFORMATION_CONTROL; + +typedef struct _TIME_CODE_INFORMATION_CONTROL +{ + UCHAR bcdFrame; + UCHAR bcdSecond; + UCHAR bcdMinute; + UCHAR bcdHour; +} TIME_CODE_INFORMATION_CONTROL, *PTIME_CODE_INFORMATION_CONTROL; + +typedef struct _ATN_INFORMATION_CONTROL +{ + UCHAR bmMediaType; + DWORD dwATN_Data; +} ATN_INFORMATION_CONTROL, *PATN_INFORMATION_CONTROL; + +#define VS_FORMAT_FRAME_BASED 0x10 +#define VS_FRAME_FRAME_BASED 0x11 +#define VS_FORMAT_STREAM_BASED 0x12 + +// Format Descriptor for UVC 1.1 frame based format +typedef struct _VIDEO_FORMAT_FRAME +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + UCHAR bNumFrameDescriptors; + GUID guidFormat; + UCHAR bBitsPerPixel; + UCHAR bDefaultFrameIndex; + UCHAR bAspectRatioX; + UCHAR bAspectRatioY; + UCHAR bmInterlaceFlags; + UCHAR bCopyProtect; + UCHAR bVariableSize; +} VIDEO_FORMAT_FRAME, *PVIDEO_FORMAT_FRAME; + +#define SIZEOF_VIDEO_FORMAT_FRAME(pDesc) sizeof(VIDEO_FORMAT_FRAME) + + +// Frame Descriptor for UVC 1.1 frame based format +typedef struct _VIDEO_FRAME_FRAME +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFrameIndex; + UCHAR bmCapabilities; + USHORT wWidth; + USHORT wHeight; + ULONG dwMinBitRate; + ULONG dwMaxBitRate; + ULONG dwDefaultFrameInterval; + UCHAR bFrameIntervalType; + ULONG dwBytesPerLine; + ULONG adwFrameInterval[]; +} VIDEO_FRAME_FRAME, *PVIDEO_FRAME_FRAME; + +__inline size_t SizeOfVideoFrameFrame(_In_ PVIDEO_FRAME_FRAME pDesc) +{ + if (pDesc->bFrameIntervalType == 0) { // Continuous + return sizeof(VIDEO_FRAME_FRAME) + (3 * sizeof(ULONG)); + } + else { // Discrete + return sizeof(VIDEO_FRAME_FRAME) + (pDesc->bFrameIntervalType * sizeof(ULONG)); + } +} + +#define SIZEOF_VIDEO_FRAME_FRAME(pDesc) SizeOfVideoFrameFrame(pDesc) + +// VideoStreaming Stream Based Format Descriptor +typedef struct _VIDEO_FORMAT_STREAM +{ + UCHAR bLength; + UCHAR bDescriptorType; + UCHAR bDescriptorSubtype; + UCHAR bFormatIndex; + GUID guidFormat; + ULONG dwPacketLength; +} VIDEO_FORMAT_STREAM, *PVIDEO_FORMAT_STREAM; + +#define SIZEOF_VIDEO_FORMAT_STREAM(pDesc) sizeof(VIDEO_FORMAT_STREAM) + +// VideoStreaming Probe/Commit Control +typedef struct _VS_PROBE_COMMIT_CONTROL2 +{ + USHORT bmHint; + UCHAR bFormatIndex; + UCHAR bFrameIndex; + ULONG dwFrameInterval; + USHORT wKeyFrameRate; + USHORT wPFrameRate; + USHORT wCompQuality; + USHORT wCompWindowSize; + USHORT wDelay; + ULONG dwMaxVideoFrameSize; + ULONG dwMaxPayloadTransferSize; + ULONG dwClockFrequency; + UCHAR bmFramingInfo; + UCHAR bPreferredVersion; + UCHAR bMinVersion; + UCHAR bMaxVersion; +} VS_PROBE_COMMIT_CONTROL2, *PVS_PROBE_COMMIT_CONTROL2; + +#pragma pack( pop, vdc_descriptor_structs ) +#pragma warning( default : 4200 ) + + +// +// END - VDC Descriptor and Control Structures +// + +#endif // ___UVCDESC_H___ diff --git a/usb/usbview/uvcview.c b/usb/usbview/uvcview.c new file mode 100644 index 00000000..f5600175 --- /dev/null +++ b/usb/usbview/uvcview.c @@ -0,0 +1,2153 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + +USBVIEW.C + +Abstract: + +This is the GUI goop for the USBVIEW application. + +Environment: + +user mode + +Revision History: + +04-25-97 : created +11-20-02 : minor changes to support more reporting options +04/13/2005 : major bug fixing +07/01/2008 : add UVC 1.1 support and move to Dev branch + +--*/ + +/***************************************************************************** +I N C L U D E S +*****************************************************************************/ + +#include "resource.h" +#include "uvcview.h" +#include "h264.h" +#include "xmlhelper.h" + +#include <commdlg.h> + + +/***************************************************************************** +D E F I N E S +*****************************************************************************/ + +// window control defines +// +#define SIZEBAR 0 +#define WINDOWSCALEFACTOR 15 + +/***************************************************************************** + L O C A L T Y P E D E F S +*****************************************************************************/ +typedef struct _TREEITEMINFO +{ + struct _TREEITEMINFO *Next; + USHORT Depth; + PCHAR Name; + +} TREEITEMINFO, *PTREEITEMINFO; + + +/***************************************************************************** +L O C A L E N U M S +*****************************************************************************/ + +typedef enum _USBVIEW_SAVE_FILE_TYPE +{ + UsbViewNone = 0, + UsbViewXmlFile, + UsbViewTxtFile +} USBVIEW_SAVE_FILE_TYPE; + +/***************************************************************************** +L O C A L F U N C T I O N P R O T O T Y P E S +*****************************************************************************/ + +int WINAPI +WinMain ( + _In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPSTR lpszCmdLine, + _In_ int nCmdShow + ); + +BOOL +CreateMainWindow ( + int nCmdShow + ); + +VOID +ResizeWindows ( + BOOL bSizeBar, + int BarLocation + ); + +LRESULT CALLBACK +MainDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ); + +BOOL +USBView_OnInitDialog ( + HWND hWnd, + HWND hWndFocus, + LPARAM lParam + ); + +VOID +USBView_OnClose ( + HWND hWnd + ); + +VOID +USBView_OnCommand ( + HWND hWnd, + int id, + HWND hwndCtl, + UINT codeNotify + ); + +VOID +USBView_OnLButtonDown ( + HWND hWnd, + BOOL fDoubleClick, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnLButtonUp ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnMouseMove ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnSize ( + HWND hWnd, + UINT state, + int cx, + int cy + ); + +LRESULT +USBView_OnNotify ( + HWND hWnd, + int DlgItem, + LPNMHDR lpNMHdr + ); + +BOOL +USBView_OnDeviceChange ( + HWND hwnd, + UINT uEvent, + DWORD dwEventData + ); + +VOID DestroyTree (VOID); + +VOID RefreshTree (VOID); + +LRESULT CALLBACK +AboutDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ); + +VOID +WalkTree ( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext + ); + +VOID +ExpandItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); + +VOID +AddItemInformationToFile( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); + +DWORD +DisplayLastError( + _Inout_updates_bytes_(count) char *szString, + int count); + +VOID AddItemInformationToXmlView( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); +HRESULT InitializeConsole(); +VOID UnInitializeConsole(); +BOOL IsStdOutFile(); +VOID DisplayMessage(DWORD dwMsgId, ...); +VOID PrintString(LPTSTR lpszString); +LPTSTR WStringToAnsiString(LPWSTR lpwszString); +VOID WaitForKeyPress(); +BOOL ProcessCommandLine(); +HRESULT ProcessCommandSaveFile(LPTSTR szFileName, DWORD dwCreationDisposition, USBVIEW_SAVE_FILE_TYPE fileType); +HRESULT SaveAllInformationAsText(LPTSTR lpstrTextFileName, DWORD dwCreationDisposition); +HRESULT SaveAllInformationAsXml(LPTSTR lpstrTextFileName , DWORD dwCreationDisposition); + +/***************************************************************************** +G L O B A L S +*****************************************************************************/ +BOOL gDoConfigDesc = TRUE; +BOOL gDoAnnotation = TRUE; +BOOL gLogDebug = FALSE; +int TotalHubs = 0; + +extern DEVICE_GUID_LIST gHubList; +extern DEVICE_GUID_LIST gDeviceList; + +/***************************************************************************** +G L O B A L S P R I V A T E T O T H I S F I L E +*****************************************************************************/ + +HINSTANCE ghInstance = NULL; +HWND ghMainWnd = NULL; +HWND ghTreeWnd = NULL; +HWND ghEditWnd = NULL; +HWND ghStatusWnd = NULL; +HMENU ghMainMenu = NULL; +HTREEITEM ghTreeRoot = NULL; +HCURSOR ghSplitCursor = NULL; +HDEVNOTIFY gNotifyDevHandle = NULL; +HDEVNOTIFY gNotifyHubHandle = NULL; +HANDLE ghStdOut = NULL; + +BOOL gbConsoleFile = FALSE; +BOOL gbConsoleInitialized = FALSE; +BOOL gbButtonDown = FALSE; +BOOL gDoAutoRefresh = TRUE; + +int gBarLocation = 0; +int giGoodDevice = 0; +int giBadDevice = 0; +int giComputer = 0; +int giHub = 0; +int giNoDevice = 0; +int giGoodSsDevice = 0; +int giNoSsDevice = 0; + + +/***************************************************************************** + +WinMain() + +*****************************************************************************/ + +int WINAPI +WinMain ( + _In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPSTR lpszCmdLine, + _In_ int nCmdShow + ) +{ + MSG msg; + HACCEL hAccel; + int retStatus = 0; + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpszCmdLine); + + InitXmlHelper(); + + ghInstance = hInstance; + + ghSplitCursor = LoadCursor(ghInstance, + MAKEINTRESOURCE(IDC_SPLIT)); + + if (!ghSplitCursor) + { + OOPS(); + return retStatus; + } + + hAccel = LoadAccelerators(ghInstance, + MAKEINTRESOURCE(IDACCEL)); + + if (!hAccel) + { + OOPS(); + return retStatus; + } + + if (!CreateTextBuffer()) + { + return retStatus; + } + + if (!ProcessCommandLine()) + { + // There were no command line flags, open GUI + if (CreateMainWindow(nCmdShow)) + { + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(ghMainWnd, + hAccel, + &msg) && + !IsDialogMessage(ghMainWnd, + &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + retStatus = 1; + } + } + + DestroyTextBuffer(); + + ReleaseXmlWriter(); + + CHECKFORLEAKS(); + + return retStatus; +} + + +/***************************************************************************** + +ProcessCommandLine() + +Parses the command line and takes appropriate actions. Returns FALSE If there is no action to +perform +*****************************************************************************/ +BOOL ProcessCommandLine() +{ + LPWSTR *szArgList = NULL; + LPTSTR szArg = NULL; + LPTSTR szAnsiArg= NULL; + BOOL quietMode = FALSE; + + HRESULT hr = S_OK; + DWORD dwCreationDisposition = CREATE_NEW; + USBVIEW_SAVE_FILE_TYPE fileType = UsbViewNone; + + int nArgs = 0; + int i = 0; + BOOL bStatus = FALSE; + BOOL bStopArgProcessing = FALSE; + + szArgList = CommandLineToArgvW(GetCommandLineW(), &nArgs); + + // If there are no arguments we return false + bStatus = (nArgs > 1)? TRUE:FALSE; + + if (NULL != szArgList) + { + if (nArgs > 1) + { + // If there are arguments, initialize console for ouput + InitializeConsole(); + } + + for (i = 1; (i < nArgs) && (bStopArgProcessing == FALSE); i++) + { + // Convert argument to ANSI string for futher processing + + szAnsiArg = WStringToAnsiString(szArgList[i]); + + if(NULL == szAnsiArg) + { + DisplayMessage(IDS_USBVIEW_INVALIDARG, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + break; + } + + if (0 == _stricmp(szAnsiArg, "/?")) + { + DisplayMessage(IDS_USBVIEW_USAGE); + break; + } + else if (NULL != StrStrI(szAnsiArg, "/saveall:")) + { + fileType = UsbViewTxtFile; + } + else if (NULL != StrStrI(szAnsiArg, "/savexml:")) + { + fileType = UsbViewXmlFile; + } + else if (0 == _stricmp(szAnsiArg, "/f")) + { + dwCreationDisposition = CREATE_ALWAYS; + } + else if (0 == _stricmp(szAnsiArg, "/q")) + { + quietMode = TRUE; + } + else + { + DisplayMessage(IDS_USBVIEW_INVALIDARG, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + bStopArgProcessing = TRUE; + } + + if (fileType != UsbViewNone) + { + // Save view information as to file + szArg = strchr(szAnsiArg, ':'); + + if (NULL == szArg || strlen(szArg) == 1) + { + // No ':' or just a ':' + DisplayMessage(IDS_USBVIEW_INVALID_FILENAME, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + bStopArgProcessing = TRUE; + } + else + { + hr = ProcessCommandSaveFile(szArg + 1, dwCreationDisposition, fileType); + + if (FAILED(hr)) + { + // No more processing + bStopArgProcessing = TRUE; + } + + fileType = UsbViewNone; + } + } + + if (NULL != szAnsiArg) + { + LocalFree(szAnsiArg); + } + } + + if(!quietMode) + { + WaitForKeyPress(); + } + + if (gbConsoleInitialized) + { + UnInitializeConsole(); + } + + LocalFree(szArgList); + } + return bStatus; +} + + +/***************************************************************************** + +ProcessCommandSaveFile() + +Process the save file command line + +*****************************************************************************/ +HRESULT ProcessCommandSaveFile(LPTSTR szFileName, DWORD dwCreationDisposition, USBVIEW_SAVE_FILE_TYPE fileType) +{ + HRESULT hr = S_OK; + LPTSTR szErrorBuffer = NULL; + + if (UsbViewNone == fileType || NULL == szFileName) + { + hr = E_INVALIDARG; + // Invalid arguments, return + return (hr); + } + + // The UI is not created yet, open the UI, but HIDE it + CreateMainWindow(SW_HIDE); + + if (UsbViewXmlFile == fileType) + { + hr = SaveAllInformationAsXml(szFileName, dwCreationDisposition); + } + + if (UsbViewTxtFile == fileType) + { + hr = SaveAllInformationAsText(szFileName, dwCreationDisposition); + } + + if (FAILED(hr)) + { + if (GetLastError() == ERROR_FILE_EXISTS || hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)) + { + // The operation failed because the file we tried to write to already existed and '/f' option + // was not present. Display error message to user describing '/f' option + switch(fileType) + { + case UsbViewXmlFile: + DisplayMessage(IDS_USBVIEW_FILE_EXISTS_XML, szFileName); + break; + case UsbViewTxtFile: + DisplayMessage(IDS_USBVIEW_FILE_EXISTS_TXT, szFileName); + break; + default: + DisplayMessage(IDS_USBVIEW_INTERNAL_ERROR); + break; + } + } + else + { + // Try to obtain system error message + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &szErrorBuffer, // FormatMessage expects this buffer to be cast as LPTSTR + 0, + NULL); + PrintString("Unable to save file.\n"); + PrintString(szErrorBuffer); + LocalFree(szErrorBuffer); + } + } + else + { + // Display file saved to message in console + DisplayMessage(IDS_USBVIEW_SAVED_TO, szFileName); + } + + return (hr); +} + +/***************************************************************************** + +InitializeConsole() + +Initializes the std output in console + +*****************************************************************************/ +HRESULT InitializeConsole() +{ + HRESULT hr = S_OK; + + SetLastError(0); + + // Find if STD_OUTPUT is a console or has been redirected to a File + gbConsoleFile = IsStdOutFile(); + + if (!gbConsoleFile) + { + // Output is not redirected and GUI application do not have console by default, create a console + if(AllocConsole()) + { +#pragma warning(disable:4996) // We don' need the FILE * returned by freopen + // Reopen STDOUT , STDIN and STDERR + if((freopen("conout$", "w", stdout) != NULL) && + (freopen("conin$", "r", stdin) != NULL) && + (freopen("conout$","w", stderr) != NULL)) + { + gbConsoleInitialized = TRUE; + ghStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + } +#pragma warning(default:4996) + } + } + + if (INVALID_HANDLE_VALUE == ghStdOut || FALSE == gbConsoleInitialized) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + return hr; +} + +/***************************************************************************** + +UnInitializeConsole() + +UnInitializes the console + +*****************************************************************************/ +VOID UnInitializeConsole() +{ + gbConsoleInitialized = FALSE; + FreeConsole(); +} + +/***************************************************************************** + +IsStdOutFile() + +Finds if the STD_OUTPUT has been redirected to a file +*****************************************************************************/ +BOOL IsStdOutFile() +{ + unsigned htype; + HANDLE hFile; + + // 1 = STDOUT + hFile = (HANDLE) _get_osfhandle(1); + htype = GetFileType(hFile); + htype &= ~FILE_TYPE_REMOTE; + + + // Check if file type is character file + if (FILE_TYPE_DISK == htype) + { + return TRUE; + } + + return FALSE; +} + + +/***************************************************************************** + +DisplayMessage() + +Displays a message to standard output +*****************************************************************************/ +VOID DisplayMessage(DWORD dwResId, ...) +{ + CHAR szFormat[4096]; + HRESULT hr = S_OK; + LPTSTR lpszMessage = NULL; + DWORD dwLen = 0; + va_list ap; + + va_start(ap, dwResId); + + // Initialize console if needed + if (!gbConsoleInitialized) + { + hr = InitializeConsole(); + if (FAILED(hr)) + { + OOPS(); + return; + } + } + + // Load the string resource + dwLen = LoadString(GetModuleHandle(NULL), + dwResId, + szFormat, + ARRAYSIZE(szFormat) + ); + + if(0 == dwLen) + { + PrintString("Unable to find message for given resource ID"); + + // Return if resource ID could not be found + return; + } + + dwLen = FormatMessage( + FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, + szFormat, + dwResId, + 0, + (LPTSTR) &lpszMessage, + ARRAYSIZE(szFormat), + &ap); + + if (dwLen > 0) + { + PrintString(lpszMessage); + LocalFree(lpszMessage); + } + else + { + PrintString("Unable to find message for given ID"); + } + + va_end(ap); + return; +} + +/***************************************************************************** + +WStringToAnsiString() + +Converts the Wide char string to ANSI string and returns the allocated ANSI string. +*****************************************************************************/ +LPTSTR WStringToAnsiString(LPWSTR lpwszString) +{ + int strLen = 0; + LPTSTR szAnsiBuffer = NULL; + + szAnsiBuffer = LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(CHAR)); + + // Convert string from from WCHAR to ANSI + if (NULL != szAnsiBuffer) + { + strLen = WideCharToMultiByte( + CP_ACP, + 0, + lpwszString, + -1, + szAnsiBuffer, + MAX_PATH + 1, + NULL, + NULL); + + if (strLen > 0) + { + return szAnsiBuffer; + } + } + return NULL; +} + +/***************************************************************************** + +PrintString() + +Displays a string to standard output +*****************************************************************************/ +VOID PrintString(LPTSTR lpszString) +{ + DWORD dwBytesWritten = 0; + size_t Len = 0; + LPSTR lpOemString = NULL; + + if (INVALID_HANDLE_VALUE == ghStdOut || NULL == lpszString) + { + OOPS(); + // Return if invalid inputs + return; + } + + if (FAILED(StringCchLength(lpszString, OUTPUT_MESSAGE_MAX_LENGTH, &Len))) + { + OOPS(); + // Return if string is too long + return; + } + + if (gbConsoleFile) + { + // Console has been redirected to a file, ex: `usbview /savexml:xx > test.txt`. We need to use WriteFile instead of + // WriteConsole for text output. + lpOemString = (LPSTR) LocalAlloc(LPTR, (Len + 1) * sizeof(CHAR)); + if (lpOemString != NULL) + { + if (CharToOemBuff(lpszString, lpOemString, (DWORD) Len)) + { + WriteFile(ghStdOut, (LPVOID) lpOemString, (DWORD) Len, &dwBytesWritten, NULL); + } + else + { + OOPS(); + } + } + } + else + { + // Write to std out in console + WriteConsole(ghStdOut, (LPVOID) lpszString, (DWORD) Len, &dwBytesWritten, NULL); + } + + return; +} + +/***************************************************************************** + +WaitForKeyPress() + +Waits for key press in case of console +*****************************************************************************/ +VOID WaitForKeyPress() +{ + // Wait for key press if console + if (!gbConsoleFile && gbConsoleInitialized) + { + DisplayMessage(IDS_USBVIEW_PRESSKEY); + (VOID) _getch(); + } + return; +} + +/***************************************************************************** + +CreateMainWindow() + +*****************************************************************************/ + +BOOL +CreateMainWindow ( + int nCmdShow + ) +{ + RECT rc; + + InitCommonControls(); + + ghMainWnd = CreateDialog(ghInstance, + MAKEINTRESOURCE(IDD_MAINDIALOG), + NULL, + (DLGPROC) MainDlgProc); + + if (ghMainWnd == NULL) + { + OOPS(); + return FALSE; + } + + GetWindowRect(ghMainWnd, &rc); + + gBarLocation = (rc.right - rc.left) / 3; + + ResizeWindows(FALSE, 0); + + ShowWindow(ghMainWnd, nCmdShow); + + UpdateWindow(ghMainWnd); + + return TRUE; +} + + +/***************************************************************************** + +ResizeWindows() + +Handles resizing the two child windows of the main window. If +bSizeBar is true, then the sizing is happening because the user is +moving the bar. If bSizeBar is false, the sizing is happening +because of the WM_SIZE or something like that. + +*****************************************************************************/ + +VOID +ResizeWindows ( + BOOL bSizeBar, + int BarLocation + ) +{ + RECT MainClientRect; + RECT MainWindowRect; + RECT TreeWindowRect; + RECT StatusWindowRect; + int right; + + // Is the user moving the bar? + // + if (!bSizeBar) + { + BarLocation = gBarLocation; + } + + GetClientRect(ghMainWnd, &MainClientRect); + + GetWindowRect(ghStatusWnd, &StatusWindowRect); + + // Make sure the bar is in a OK location + // + if (bSizeBar) + { + if (BarLocation < + GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + { + return; + } + + if ((MainClientRect.right - BarLocation) < + GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + { + return; + } + } + + // Save the bar location + // + gBarLocation = BarLocation; + + // Move the tree window + // + MoveWindow(ghTreeWnd, + 0, + 0, + BarLocation, + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + TRUE); + + // Get the size of the window (in case move window failed + // + GetWindowRect(ghTreeWnd, &TreeWindowRect); + GetWindowRect(ghMainWnd, &MainWindowRect); + + right = TreeWindowRect.right - MainWindowRect.left; + + // Move the edit window with respect to the tree window + // + MoveWindow(ghEditWnd, + right+SIZEBAR, + 0, + MainClientRect.right-(right+SIZEBAR), + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + TRUE); + + // Move the Status window with respect to the tree window + // + MoveWindow(ghStatusWnd, + 0, + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + MainClientRect.right, + StatusWindowRect.bottom - StatusWindowRect.top, + TRUE); +} + + +/***************************************************************************** + +MainWndProc() + +*****************************************************************************/ + +LRESULT CALLBACK +MainDlgProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ) +{ + + switch (uMsg) + { + + HANDLE_MSG(hWnd, WM_INITDIALOG, USBView_OnInitDialog); + HANDLE_MSG(hWnd, WM_CLOSE, USBView_OnClose); + HANDLE_MSG(hWnd, WM_COMMAND, USBView_OnCommand); + HANDLE_MSG(hWnd, WM_LBUTTONDOWN, USBView_OnLButtonDown); + HANDLE_MSG(hWnd, WM_LBUTTONUP, USBView_OnLButtonUp); + HANDLE_MSG(hWnd, WM_MOUSEMOVE, USBView_OnMouseMove); + HANDLE_MSG(hWnd, WM_SIZE, USBView_OnSize); + HANDLE_MSG(hWnd, WM_NOTIFY, USBView_OnNotify); + HANDLE_MSG(hWnd, WM_DEVICECHANGE, USBView_OnDeviceChange); + } + + return 0; +} + +/***************************************************************************** + +USBView_OnInitDialog() + +*****************************************************************************/ + +BOOL +USBView_OnInitDialog ( + HWND hWnd, + HWND hWndFocus, + LPARAM lParam + ) +{ + HFONT hFont; + HIMAGELIST himl; + HICON hicon; + DEV_BROADCAST_DEVICEINTERFACE broadcastInterface; + + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(hWndFocus); + + // Register to receive notification when a USB device is plugged in. + broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + + memcpy( &(broadcastInterface.dbcc_classguid), + &(GUID_DEVINTERFACE_USB_DEVICE), + sizeof(struct _GUID)); + + gNotifyDevHandle = RegisterDeviceNotification(hWnd, + &broadcastInterface, + DEVICE_NOTIFY_WINDOW_HANDLE); + + // Now register for Hub notifications. + memcpy( &(broadcastInterface.dbcc_classguid), + &(GUID_CLASS_USBHUB), + sizeof(struct _GUID)); + + gNotifyHubHandle = RegisterDeviceNotification(hWnd, + &broadcastInterface, + DEVICE_NOTIFY_WINDOW_HANDLE); + + gHubList.DeviceInfo = INVALID_HANDLE_VALUE; + InitializeListHead(&gHubList.ListHead); + gDeviceList.DeviceInfo = INVALID_HANDLE_VALUE; + InitializeListHead(&gDeviceList.ListHead); + + //end add + + ghTreeWnd = GetDlgItem(hWnd, IDC_TREE); + + //added + if ((himl = ImageList_Create(15, 15, + FALSE, 2, 0)) == NULL) + { + OOPS(); + } + + if(himl != NULL) + { + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON)); + giGoodDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_BADICON)); + giBadDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_COMPUTER)); + giComputer = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_HUB)); + giHub = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_NODEVICE)); + giNoDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_SSICON)); + giGoodSsDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_NOSSDEVICE)); + giNoSsDevice = ImageList_AddIcon(himl, hicon); + + TreeView_SetImageList(ghTreeWnd, himl, TVSIL_NORMAL); + // end add + } + + ghEditWnd = GetDlgItem(hWnd, IDC_EDIT); + +#ifdef H264_SUPPORT + // set the edit control to have a max text limit size + SendMessage(ghEditWnd, EM_LIMITTEXT, 0 /* USE DEFAULT MAX*/, 0); +#endif + + ghStatusWnd = GetDlgItem(hWnd, IDC_STATUS); + ghMainMenu = GetMenu(hWnd); + if (ghMainMenu == NULL) + { + OOPS(); + } + { + CHAR pszFont[256]; + CHAR pszHeight[8]; + + memset(pszFont, 0, sizeof(pszFont)); + LoadString(ghInstance, IDS_STANDARD_FONT, pszFont, sizeof(pszFont) - 1); + memset(pszHeight, 0, sizeof(pszHeight)); + LoadString(ghInstance, IDS_STANDARD_FONT_HEIGHT, pszHeight, sizeof(pszHeight) - 1); + + hFont = CreateFont((int) pszHeight[0], 0, 0, 0, + 400, 0, 0, 0, + 0, 1, 2, 1, + 49, pszFont); + } + SendMessage(ghEditWnd, + WM_SETFONT, + (WPARAM) hFont, + 0); + + RefreshTree(); + + return FALSE; +} + +/***************************************************************************** + +USBView_OnClose() + +*****************************************************************************/ + +VOID +USBView_OnClose ( + HWND hWnd + ) +{ + + UNREFERENCED_PARAMETER(hWnd); + + DestroyTree(); + + PostQuitMessage(0); +} + + +/***************************************************************************** + +AddItemInformationToFile() + +Saves the information about the current item to the list +*****************************************************************************/ +VOID +AddItemInformationToFile( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + HRESULT hr = S_OK; + HANDLE hf = NULL; + DWORD dwBytesWritten = 0; + + hf = *((PHANDLE) pContext); + + ResetTextBuffer(); + + hr = UpdateTreeItemDeviceInfo(hTreeWnd, hTreeItem); + + if (FAILED(hr)) + { + OOPS(); + } + else + { + WriteFile(hf, GetTextBuffer(), GetTextBufferPos()*sizeof(CHAR), &dwBytesWritten, NULL); + } + + ResetTextBuffer(); +} + + + +/***************************************************************************** + +SaveAllInformationAsText() + +Saves the entire USB tree as a text file +*****************************************************************************/ +HRESULT +SaveAllInformationAsText( + LPTSTR lpstrTextFileName, + DWORD dwCreationDisposition + ) +{ + HRESULT hr = S_OK; + HANDLE hf = NULL; + + hf = CreateFile(lpstrTextFileName, + GENERIC_WRITE, + 0, + NULL, + dwCreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hf == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + else + { + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + // CreateFile() sets this error if we are overwriting an existing file + // Reset this error to avoid false alarms + SetLastError(0); + } + + if (ghTreeRoot == NULL) + { + // If tree has not been populated yet, try a refresh + RefreshTree(); + } + + if (ghTreeRoot) + { + + LockFile(hf, 0, 0, 0, 0); + WalkTreeTopDown(ghTreeRoot, AddItemInformationToFile, &hf, NULL); + UnlockFile(hf, 0, 0, 0, 0); + CloseHandle(hf); + + hr = S_OK; + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + } + + ResetTextBuffer(); + return hr; +} + + +/***************************************************************************** + +USBView_OnCommand() + +*****************************************************************************/ + +VOID +USBView_OnCommand ( + HWND hWnd, + int id, + HWND hwndCtl, + UINT codeNotify + ) +{ + MENUITEMINFO menuInfo; + char szFile[MAX_PATH + 1]; + OPENFILENAME ofn; + HANDLE hf = NULL; + DWORD dwBytesWritten = 0; + int nTextLength = 0; + size_t lengthToNull = 0; + HRESULT hr = S_OK; + + UNREFERENCED_PARAMETER(hwndCtl); + UNREFERENCED_PARAMETER(codeNotify); + + //initialize save dialog variables + memset(szFile, 0, sizeof(szFile)); + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = 0; + ofn.lpstrTitle = NULL; + ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + + + switch (id) + { + case ID_AUTO_REFRESH: + gDoAutoRefresh = !gDoAutoRefresh; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoAutoRefresh ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_SAVE: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBView.txt"); + ofn.lpstrFilter = "Text\0*.TXT\0\0"; + ofn.lpstrDefExt = "txt"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + //create new file + hf = CreateFile((LPTSTR)ofn.lpstrFile, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hf == INVALID_HANDLE_VALUE) + { + OOPS(); + } + else + { + char *szText = NULL; + + //get data from display window to transfer to file + nTextLength = GetWindowTextLength(ghEditWnd); + nTextLength++; + + szText = ALLOC((DWORD)nTextLength); + if (NULL != szText) + { + GetWindowText(ghEditWnd, (LPSTR) szText, nTextLength); + + // + // Constrain length to the first null, which should be at + // the end of the window text. This prevents writing extra + // null characters. + // + if (StringCchLength(szText, nTextLength, &lengthToNull) == S_OK) + { + nTextLength = (int) lengthToNull; + + //lock the file, write to the file, unlock file + LockFile(hf, 0, 0, 0, 0); + + WriteFile(hf, szText, nTextLength, &dwBytesWritten, NULL); + + UnlockFile(hf, 0, 0, 0, 0); + } + else + { + OOPS(); + } + CloseHandle(hf); + FREE(szText); + } + else + { + OOPS(); + } + } + + break; + } + + case ID_SAVEALL: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBViewAll.txt"); + ofn.lpstrFilter = "Text\0*.txt\0\0"; + ofn.lpstrDefExt = "txt"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + // Save the file, overwrite in case of UI since UI gives popup for confirmation + hr = SaveAllInformationAsText(ofn.lpstrFile, CREATE_ALWAYS); + if (FAILED(hr)) + { + OOPS(); + } + + break; + } + + case ID_SAVEXML: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBViewAll.xml"); + ofn.lpstrFilter = "Xml\0*.xml\0\0"; + ofn.lpstrDefExt = "xml"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + // Save the file, overwrite in case of UI since UI gives popup for confirmation + hr = SaveAllInformationAsXml(ofn.lpstrFile, CREATE_ALWAYS); + if (FAILED(hr)) + { + OOPS(); + } + + break; + } + + case ID_CONFIG_DESCRIPTORS: + gDoConfigDesc = !gDoConfigDesc; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoConfigDesc ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_ANNOTATION: + gDoAnnotation = !gDoAnnotation; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoAnnotation ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_LOG_DEBUG: + gLogDebug = !gLogDebug; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gLogDebug ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_ABOUT: + DialogBox(ghInstance, + MAKEINTRESOURCE(IDD_ABOUT), + ghMainWnd, + (DLGPROC) AboutDlgProc); + break; + + case ID_EXIT: + UnregisterDeviceNotification(gNotifyDevHandle); + UnregisterDeviceNotification(gNotifyHubHandle); + DestroyTree(); + PostQuitMessage(0); + break; + + case ID_REFRESH: + RefreshTree(); + break; + } +} + +/***************************************************************************** + +USBView_OnLButtonDown() + +*****************************************************************************/ + +VOID +USBView_OnLButtonDown ( + HWND hWnd, + BOOL fDoubleClick, + int x, + int y, + UINT keyFlags + ) +{ + + UNREFERENCED_PARAMETER(fDoubleClick); + UNREFERENCED_PARAMETER(x); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + gbButtonDown = TRUE; + SetCapture(hWnd); +} + +/***************************************************************************** + +USBView_OnLButtonUp() + +*****************************************************************************/ + +VOID +USBView_OnLButtonUp ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ) +{ + + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(x); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + gbButtonDown = FALSE; + ReleaseCapture(); +} + +/***************************************************************************** + +USBView_OnMouseMove() + +*****************************************************************************/ + +VOID +USBView_OnMouseMove ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + SetCursor(ghSplitCursor); + + if (gbButtonDown) + { + ResizeWindows(TRUE, x); + } +} + +/***************************************************************************** + +USBView_OnSize(); + +*****************************************************************************/ + +VOID +USBView_OnSize ( + HWND hWnd, + UINT state, + int cx, + int cy + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(state); + UNREFERENCED_PARAMETER(cx); + UNREFERENCED_PARAMETER(cy); + + ResizeWindows(FALSE, 0); +} + +/***************************************************************************** + +USBView_OnNotify() + +*****************************************************************************/ + +LRESULT +USBView_OnNotify ( + HWND hWnd, + int DlgItem, + LPNMHDR lpNMHdr + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(DlgItem); + + if (lpNMHdr->code == TVN_SELCHANGED) + { + HTREEITEM hTreeItem; + + hTreeItem = ((NM_TREEVIEW *)lpNMHdr)->itemNew.hItem; + + if (hTreeItem) + { + UpdateEditControl(ghEditWnd, + ghTreeWnd, + hTreeItem); + } + } + + return 0; +} + + +/***************************************************************************** + +USBView_OnDeviceChange() + +*****************************************************************************/ + +BOOL +USBView_OnDeviceChange ( + HWND hwnd, + UINT uEvent, + DWORD dwEventData + ) +{ + UNREFERENCED_PARAMETER(hwnd); + UNREFERENCED_PARAMETER(dwEventData); + + if (gDoAutoRefresh) + { + switch (uEvent) + { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + RefreshTree(); + break; + } + } + + return TRUE; +} + + + +/***************************************************************************** + +DestroyTree() + +*****************************************************************************/ + +VOID DestroyTree (VOID) +{ + // Clear the selection of the TreeView, so that when the tree is + // destroyed, the control won't try to constantly "shift" the + // selection to another item. + // + TreeView_SelectItem(ghTreeWnd, NULL); + + // Destroy the current contents of the TreeView + // + if (ghTreeRoot) + { + WalkTree(ghTreeRoot, CleanupItem, NULL); + + TreeView_DeleteAllItems(ghTreeWnd); + + ghTreeRoot = NULL; + } + + ClearDeviceList(&gDeviceList); + ClearDeviceList(&gHubList); +} + +/***************************************************************************** + +RefreshTree() + +*****************************************************************************/ + +VOID RefreshTree (VOID) +{ + CHAR statusText[128]; + ULONG devicesConnected; + + // Clear the edit control + // + SetWindowText(ghEditWnd, ""); + + // Destroy the current contents of the TreeView + // + DestroyTree(); + + // Create the root tree node + // + ghTreeRoot = AddLeaf(TVI_ROOT, 0, "My Computer", ComputerIcon); + + if (ghTreeRoot != NULL) + { + // Enumerate all USB buses and populate the tree + // + EnumerateHostControllers(ghTreeRoot, &devicesConnected); + + // + // Expand all tree nodes + // + WalkTree(ghTreeRoot, ExpandItem, NULL); + + // Update Status Line with number of devices connected + // + memset(statusText, 0, sizeof(statusText)); + StringCchPrintf(statusText, sizeof(statusText), +#ifdef H264_SUPPORT + "UVC Spec Version: %d.%d Version: %d.%d Devices Connected: %d Hubs Connected: %d", + UVC_SPEC_MAJOR_VERSION, UVC_SPEC_MINOR_VERSION, USBVIEW_MAJOR_VERSION, USBVIEW_MINOR_VERSION, + devicesConnected, TotalHubs); +#else + "Devices Connected: %d Hubs Connected: %d", + devicesConnected, TotalHubs); +#endif + + SetWindowText(ghStatusWnd, statusText); + } + else + { + OOPS(); + } + +} + +/***************************************************************************** + +AboutDlgProc() + +*****************************************************************************/ + +LRESULT CALLBACK +AboutDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HRESULT hr; + char TextBuffer[TEXT_ITEM_LENGTH]; + HWND hItem; + + hItem = GetDlgItem(hwnd, IDC_VERSION); + + if (hItem != NULL) + { + hr = StringCbPrintfA(TextBuffer, + sizeof(TextBuffer), + "USBView version: %d.%d", + USBVIEW_MAJOR_VERSION, + USBVIEW_MINOR_VERSION); + if (SUCCEEDED(hr)) + { + SetWindowText(hItem,TextBuffer); + } + } + + hItem = GetDlgItem(hwnd, IDC_UVCVERSION); + + if (hItem != NULL) + { + hr = StringCbPrintfA(TextBuffer, + sizeof(TextBuffer), + "USB Video Class Spec version: %d.%d", + UVC_SPEC_MAJOR_VERSION, + UVC_SPEC_MINOR_VERSION); + if (SUCCEEDED(hr)) + { + SetWindowText(hItem,TextBuffer); + } + } + } + break; + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + + EndDialog (hwnd, 0); + break; + } + break; + + } + + return FALSE; +} + + +/***************************************************************************** + +AddLeaf() + +*****************************************************************************/ + +HTREEITEM +AddLeaf ( + HTREEITEM hTreeParent, + LPARAM lParam, + _In_ LPTSTR lpszText, + TREEICON TreeIcon + ) +{ + TV_INSERTSTRUCT tvins; + HTREEITEM hti; + + memset(&tvins, 0, sizeof(tvins)); + + // Set the parent item + // + tvins.hParent = hTreeParent; + + tvins.hInsertAfter = TVI_LAST; + + // pszText and lParam members are valid + // + tvins.item.mask = TVIF_TEXT | TVIF_PARAM; + + // Set the text of the item. + // + tvins.item.pszText = lpszText; + + // Set the user context item + // + tvins.item.lParam = lParam; + + // Add the item to the tree-view control. + // + hti = TreeView_InsertItem(ghTreeWnd, &tvins); + + // added + tvins.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvins.item.hItem = hti; + + // Determine which icon to display for the device + // + switch (TreeIcon) + { + case ComputerIcon: + tvins.item.iImage = giComputer; + tvins.item.iSelectedImage = giComputer; + break; + + case HubIcon: + tvins.item.iImage = giHub; + tvins.item.iSelectedImage = giHub; + break; + + case NoDeviceIcon: + tvins.item.iImage = giNoDevice; + tvins.item.iSelectedImage = giNoDevice; + break; + + case GoodDeviceIcon: + tvins.item.iImage = giGoodDevice; + tvins.item.iSelectedImage = giGoodDevice; + break; + + case GoodSsDeviceIcon: + tvins.item.iImage = giGoodSsDevice; + tvins.item.iSelectedImage = giGoodSsDevice; + break; + + case NoSsDeviceIcon: + tvins.item.iImage = giNoSsDevice; + tvins.item.iSelectedImage = giNoSsDevice; + break; + + case BadDeviceIcon: + default: + tvins.item.iImage = giBadDevice; + tvins.item.iSelectedImage = giBadDevice; + break; + } + TreeView_SetItem(ghTreeWnd, &tvins.item); + + return hti; +} + + +/***************************************************************************** + +WalkTreeTopDown() + +*****************************************************************************/ + +VOID +WalkTreeTopDown( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext, + _In_opt_ LPFNTREENOTIFYCALLBACK lpfnTreeNotifyCallback + ) +{ + if (hTreeItem) + { + HTREEITEM hTreeChild = TreeView_GetChild(ghTreeWnd, hTreeItem); + HTREEITEM hTreeSibling = TreeView_GetNextSibling(ghTreeWnd, hTreeItem); + + // + // Call the lpfnCallBack on the node itself. + // + (*lpfnTreeCallback)(ghTreeWnd, hTreeItem, pContext); + + // + // Recursively call WalkTree on the node's first child. + // + + if (hTreeChild) + { + WalkTreeTopDown(hTreeChild, + lpfnTreeCallback, + pContext, + lpfnTreeNotifyCallback); + } + + // + // Recursively call WalkTree on the node's first sibling. + // + if (hTreeSibling) + { + WalkTreeTopDown(hTreeSibling, + lpfnTreeCallback, + pContext, + lpfnTreeNotifyCallback); + } + else + { + // If there are no more siblings, we have reached the end of + // list of child nodes. Call notify function + if (lpfnTreeNotifyCallback != NULL) + { + (*lpfnTreeNotifyCallback)(pContext); + } + } + } +} + +/***************************************************************************** + +WalkTree() + +*****************************************************************************/ + +VOID +WalkTree ( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext + ) +{ + if (hTreeItem) + { + // Recursively call WalkTree on the node's first child. + // + WalkTree(TreeView_GetChild(ghTreeWnd, hTreeItem), + lpfnTreeCallback, + pContext); + + // + // Call the lpfnCallBack on the node itself. + // + (*lpfnTreeCallback)(ghTreeWnd, hTreeItem, pContext); + + // + // + // Recursively call WalkTree on the node's first sibling. + // + WalkTree(TreeView_GetNextSibling(ghTreeWnd, hTreeItem), + lpfnTreeCallback, + pContext); + } +} + +/***************************************************************************** + +ExpandItem() + +*****************************************************************************/ + +VOID +ExpandItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + // + // Make this node visible. + // + UNREFERENCED_PARAMETER(pContext); + + TreeView_Expand(hTreeWnd, hTreeItem, TVE_EXPAND); +} + +/***************************************************************************** + +SaveAllInformationAsXML() + +Saves the entire USB tree as an XML file +*****************************************************************************/ +HRESULT +SaveAllInformationAsXml( + LPTSTR lpstrTextFileName, + DWORD dwCreationDisposition + ) +{ + HRESULT hr = S_OK; + + if (ghTreeRoot == NULL) + { + // If tree has not been populated yet, try a refresh + RefreshTree(); + } + if (ghTreeRoot) + { + WalkTreeTopDown(ghTreeRoot, AddItemInformationToXmlView, NULL, XmlNotifyEndOfNodeList); + + hr = SaveXml(lpstrTextFileName, dwCreationDisposition); + } + else + { + hr = E_FAIL; + OOPS(); + } + ResetTextBuffer(); + return hr; +} + +//***************************************************************************** +// +// AddItemInformationToXmlView +// +// hTreeItem - Handle of selected TreeView item for which information should +// be added to the XML View +// +//***************************************************************************** +VOID +AddItemInformationToXmlView( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + TV_ITEM tvi; + PVOID info; + PCHAR tviName = NULL; + + UNREFERENCED_PARAMETER(pContext); + +#ifdef H264_SUPPORT + ResetErrorCounts(); +#endif + + tviName = (PCHAR) ALLOC(256); + + if (NULL == tviName) + { + return; + } + + // + // Get the name of the TreeView item, along with the a pointer to the + // info we stored about the item in the item's lParam. + // + + tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM; + tvi.hItem = hTreeItem; + tvi.pszText = (LPSTR) tviName; + tvi.cchTextMax = 256; + + TreeView_GetItem(hTreeWnd, + &tvi); + + info = (PVOID)tvi.lParam; + + if (NULL != info) + { + // + // Add Item to XML object + // + switch (*(PUSBDEVICEINFOTYPE)info) + { + case HostControllerInfo: + XmlAddHostController(tviName, (PUSBHOSTCONTROLLERINFO) info); + break; + + case RootHubInfo: + XmlAddRootHub(tviName, (PUSBROOTHUBINFO) info); + break; + + case ExternalHubInfo: + XmlAddExternalHub(tviName, (PUSBEXTERNALHUBINFO) info); + break; + + case DeviceInfo: + XmlAddUsbDevice(tviName, (PUSBDEVICEINFO) info); + break; + } + + } + return; +} + +/***************************************************************************** + +DisplayLastError() + +*****************************************************************************/ + +DWORD +DisplayLastError( + _Inout_updates_bytes_(count) char *szString, + int count) +{ + LPVOID lpMsgBuf; + + // get the last error code + DWORD dwError = GetLastError(); + + // get the system message for this error code + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + StringCchPrintf(szString, count, "Error: %s", (LPTSTR)lpMsgBuf ); + } + + // Free the local buffer + LocalFree( lpMsgBuf ); + + // return the error + return dwError; +} + +#if DBG + +/***************************************************************************** + +Oops() + +*****************************************************************************/ + +VOID +Oops +( + _In_ PCHAR File, + ULONG Line + ) +{ + char szBuf[1024]; + LPTSTR lpMsgBuf; + DWORD dwGLE = GetLastError(); + + memset(szBuf, 0, sizeof(szBuf)); + + // get the system message for this error code + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwGLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL)) + { + StringCchPrintf(szBuf, sizeof(szBuf), + "File: %s, Line %d\r\nGetLastError 0x%x %u %s\n", + File, Line, dwGLE, dwGLE, lpMsgBuf); + } + else + { + StringCchPrintf(szBuf, sizeof(szBuf), + "File: %s, Line %d\r\nGetLastError 0x%x %u\r\n", + File, Line, dwGLE, dwGLE); + } + OutputDebugString(szBuf); + + // Free the system allocated local buffer + LocalFree(lpMsgBuf); + + return; +} + +#endif diff --git a/usb/usbview/uvcview.h b/usb/usbview/uvcview.h new file mode 100644 index 00000000..eeb28eca --- /dev/null +++ b/usb/usbview/uvcview.h @@ -0,0 +1,675 @@ +/*++ + +Copyright (c) 1997-2008 Microsoft Corporation + +Module Name: + + UVCVIEW.H + +Abstract: + + This is the header file for UVCVIEW + +Environment: + + user mode + +Revision History: + + 04-25-97 : created + 04/13/2005 : major bug fixing + +--*/ + +/***************************************************************************** + I N C L U D E S +*****************************************************************************/ +#include <windows.h> +#include <windowsx.h> +#include <initguid.h> +#include <devioctl.h> +#include <dbt.h> +#include <stdio.h> +#include <commctrl.h> +#include <usbioctl.h> +#include <usbiodef.h> +#include <intsafe.h> +#include <strsafe.h> +#include <specstrings.h> +#include <usb.h> +#include <usbuser.h> +#include <basetyps.h> +#include <wtypes.h> +#include <objbase.h> +#include <io.h> +#include <conio.h> +#include <shellapi.h> +#include <cfgmgr32.h> +#include <shlwapi.h> +#include <setupapi.h> +#include <winioctl.h> +#include <devpkey.h> +#include <math.h> + +// This is mostly a private USB Audio descriptor header +#include "usbdesc.h" + +// This is the inbox USBVideo driver descriptor header (copied locally) +#include "uvcdesc.h" + +/***************************************************************************** + P R A G M A S +*****************************************************************************/ + +#pragma once + +/***************************************************************************** + D E F I N E S +*****************************************************************************/ + +// define H264_SUPPORT to add H.264 support to uvcview.exe +#define H264_SUPPORT + +#define TEXT_ITEM_LENGTH 64 + +#ifdef DEBUG +#undef DBG +#define DBG 1 +#endif + +#if DBG +#define OOPS() Oops(__FILE__, __LINE__) +#else +#define OOPS() +#endif + +#if DBG + +#define ALLOC(dwBytes) MyAlloc(__FILE__, __LINE__, (dwBytes)) + +#define REALLOC(hMem, dwBytes) MyReAlloc((hMem), (dwBytes)) + +#define FREE(hMem) MyFree((hMem)) + +#define CHECKFORLEAKS() MyCheckForLeaks() + +#else + +#define ALLOC(dwBytes) GlobalAlloc(GPTR,(dwBytes)) + +#define REALLOC(hMem, dwBytes) GlobalReAlloc((hMem), (dwBytes), (GMEM_MOVEABLE|GMEM_ZEROINIT)) + +#define FREE(hMem) GlobalFree((hMem)) + +#define CHECKFORLEAKS() + +#endif + +#define DEVICE_CONFIGURATION_TEXT_LENGTH 10240 + +#define STR_INVALID_POWER_STATE "(invalid state) " +#define STR_UNKNOWN_CONTROLLER_FLAVOR "Unknown" + +FORCEINLINE +VOID +InitializeListHead( + _Out_ PLIST_ENTRY ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +// +// BOOLEAN +// IsListEmpty( +// PLIST_ENTRY ListHead +// ); +// + +#define IsListEmpty(ListHead) \ + ((ListHead)->Flink == (ListHead)) + +// +// PLIST_ENTRY +// RemoveHeadList( +// PLIST_ENTRY ListHead +// ); +// + +#define RemoveHeadList(ListHead) \ + (ListHead)->Flink;\ + {RemoveEntryList((ListHead)->Flink)} + +// +// VOID +// RemoveEntryList( +// PLIST_ENTRY Entry +// ); +// + +#define RemoveEntryList(Entry) {\ + PLIST_ENTRY _EX_Blink;\ + PLIST_ENTRY _EX_Flink;\ + _EX_Flink = (Entry)->Flink;\ + _EX_Blink = (Entry)->Blink;\ + _EX_Blink->Flink = _EX_Flink;\ + _EX_Flink->Blink = _EX_Blink;\ + } + +// +// VOID +// InsertTailList( +// PLIST_ENTRY ListHead, +// PLIST_ENTRY Entry +// ); +// + +#define InsertTailList(ListHead,Entry) {\ + PLIST_ENTRY _EX_Blink;\ + PLIST_ENTRY _EX_ListHead;\ + _EX_ListHead = (ListHead);\ + _EX_Blink = _EX_ListHead->Blink;\ + (Entry)->Flink = _EX_ListHead;\ + (Entry)->Blink = _EX_Blink;\ + _EX_Blink->Flink = (Entry);\ + _EX_ListHead->Blink = (Entry);\ + } + +// global version for USB Video Class spec version (pre-release) +#define BCDVDC 0x0083 + +// A.2 Video Interface Subclass Codes +#define SC_VIDEO_INTERFACE_COLLECTION 0x03 + +// A.3 Video Interface Protocol Codes +#define PC_PROTOCOL_UNDEFINED 0x00 + +// USB Video Class spec version +#define NOT_UVC 0x0 +#define UVC10 0x100 +#define UVC11 0x110 + +#ifdef H264_SUPPORT +#define UVC15 0x150 +#endif + +#define OUTPUT_MESSAGE_MAX_LENGTH 1024 +#define MAX_DEVICE_PROP 200 +#define MAX_DRIVER_KEY_NAME 256 + +/***************************************************************************** + T Y P E D E F S +*****************************************************************************/ + +typedef enum _TREEICON +{ + ComputerIcon, + HubIcon, + NoDeviceIcon, + GoodDeviceIcon, + BadDeviceIcon, + GoodSsDeviceIcon, + NoSsDeviceIcon +} TREEICON; + +// Callback function for walking TreeView items +// +typedef VOID +(*LPFNTREECALLBACK)( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext +); + + +// Callback notification function called at end of every tree depth +typedef VOID +(*LPFNTREENOTIFYCALLBACK)(PVOID pContext); + +// +// Structure used to build a linked list of String Descriptors +// retrieved from a device. +// + +typedef struct _STRING_DESCRIPTOR_NODE +{ + struct _STRING_DESCRIPTOR_NODE *Next; + UCHAR DescriptorIndex; + USHORT LanguageID; + USB_STRING_DESCRIPTOR StringDescriptor[1]; +} STRING_DESCRIPTOR_NODE, *PSTRING_DESCRIPTOR_NODE; + +// +// A collection of device properties. The device can be hub, host controller or usb device +// +typedef struct _USB_DEVICE_PNP_STRINGS +{ + PCHAR DeviceId; + PCHAR DeviceDesc; + PCHAR HwId; + PCHAR Service; + PCHAR DeviceClass; + PCHAR PowerState; +} USB_DEVICE_PNP_STRINGS, *PUSB_DEVICE_PNP_STRINGS; + +typedef struct _DEVICE_INFO_NODE { + HDEVINFO DeviceInfo; + LIST_ENTRY ListEntry; + SP_DEVINFO_DATA DeviceInfoData; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceDetailData; + PSTR DeviceDescName; + ULONG DeviceDescNameLength; + PSTR DeviceDriverName; + ULONG DeviceDriverNameLength; + DEVICE_POWER_STATE LatestDevicePowerState; +} DEVICE_INFO_NODE, *PDEVICE_INFO_NODE; + +// +// Structures assocated with TreeView items through the lParam. When an item +// is selected, the lParam is retrieved and the structure it which it points +// is used to display information in the edit control. +// + +typedef enum _USBDEVICEINFOTYPE +{ + HostControllerInfo, + RootHubInfo, + ExternalHubInfo, + DeviceInfo +} USBDEVICEINFOTYPE, *PUSBDEVICEINFOTYPE; + +typedef struct _USBHOSTCONTROLLERINFO +{ + USBDEVICEINFOTYPE DeviceInfoType; + LIST_ENTRY ListEntry; + PCHAR DriverKey; + ULONG VendorID; + ULONG DeviceID; + ULONG SubSysID; + ULONG Revision; + USB_POWER_INFO USBPowerInfo[6]; + BOOL BusDeviceFunctionValid; + ULONG BusNumber; + USHORT BusDevice; + USHORT BusFunction; + PUSB_CONTROLLER_INFO_0 ControllerInfo; + PUSB_DEVICE_PNP_STRINGS UsbDeviceProperties; +} USBHOSTCONTROLLERINFO, *PUSBHOSTCONTROLLERINFO; + +typedef struct _USBROOTHUBINFO +{ + USBDEVICEINFOTYPE DeviceInfoType; + PUSB_NODE_INFORMATION HubInfo; + PUSB_HUB_INFORMATION_EX HubInfoEx; + PCHAR HubName; + PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps; + PUSB_DEVICE_PNP_STRINGS UsbDeviceProperties; + PDEVICE_INFO_NODE DeviceInfoNode; + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx; + +} USBROOTHUBINFO, *PUSBROOTHUBINFO; + +typedef struct _USBEXTERNALHUBINFO +{ + USBDEVICEINFOTYPE DeviceInfoType; + PUSB_NODE_INFORMATION HubInfo; + PUSB_HUB_INFORMATION_EX HubInfoEx; + PCHAR HubName; + PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo; + PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps; + PUSB_DESCRIPTOR_REQUEST ConfigDesc; + PUSB_DESCRIPTOR_REQUEST BosDesc; + PSTRING_DESCRIPTOR_NODE StringDescs; + PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2; // NULL if root HUB + PUSB_DEVICE_PNP_STRINGS UsbDeviceProperties; + PDEVICE_INFO_NODE DeviceInfoNode; + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx; +} USBEXTERNALHUBINFO, *PUSBEXTERNALHUBINFO; + + +// HubInfo, HubName may be in USBDEVICEINFOTYPE, so they can be removed +typedef struct +{ + USBDEVICEINFOTYPE DeviceInfoType; + PUSB_NODE_INFORMATION HubInfo; // NULL if not a HUB + PUSB_HUB_INFORMATION_EX HubInfoEx; // NULL if not a HUB + PCHAR HubName; // NULL if not a HUB + PUSB_NODE_CONNECTION_INFORMATION_EX ConnectionInfo; // NULL if root HUB + PUSB_PORT_CONNECTOR_PROPERTIES PortConnectorProps; + PUSB_DESCRIPTOR_REQUEST ConfigDesc; // NULL if root HUB + PUSB_DESCRIPTOR_REQUEST BosDesc; // NULL if root HUB + PSTRING_DESCRIPTOR_NODE StringDescs; + PUSB_NODE_CONNECTION_INFORMATION_EX_V2 ConnectionInfoV2; // NULL if root HUB + PUSB_DEVICE_PNP_STRINGS UsbDeviceProperties; + PDEVICE_INFO_NODE DeviceInfoNode; + PUSB_HUB_CAPABILITIES_EX HubCapabilityEx; // NULL if not a HUB +} USBDEVICEINFO, *PUSBDEVICEINFO; + +typedef struct _STRINGLIST +{ +#ifdef H264_SUPPORT + ULONGLONG ulFlag; +#else + ULONG ulFlag; +#endif + PCHAR pszString; + PCHAR pszModifier; + +} STRINGLIST, * PSTRINGLIST; + +typedef struct _DEVICE_GUID_LIST { + HDEVINFO DeviceInfo; + LIST_ENTRY ListHead; +} DEVICE_GUID_LIST, *PDEVICE_GUID_LIST; + + +/***************************************************************************** + G L O B A L S +*****************************************************************************/ + +// +// USBVIEW.C +// + +BOOL gDoConfigDesc; +BOOL gDoAnnotation; +BOOL gLogDebug; +int TotalHubs; + +// +// ENUM.C +// + +PCHAR ConnectionStatuses[]; + +// +// DISPVID.C +// +DEFINE_GUID(YUY2_Format,0x32595559L,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); +DEFINE_GUID(NV12_Format,0x3231564EL,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); + +#ifdef H264_SUPPORT +DEFINE_GUID(H264_Format,0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); +#endif + +// The following flags/variables are all initialized in Display.c InitializePerDeviceSettings() +// +// Save the default frame from the MJPEG, Uncompressed, Vendor and Frame Based Format descriptor +// Check for this when processing the individual Frame descriptors +UCHAR g_chMJPEGFrameDefault; +UCHAR g_chUNCFrameDefault; +UCHAR g_chVendorFrameDefault; +UCHAR g_chFrameBasedFrameDefault; + +// Spec version of UVC device +UINT g_chUVCversion; + +// Base address of the USBDEVICEINFO for device we're parsing +PUSBDEVICEINFO CurrentUSBDeviceInfo; + +// Base address of the Configuration descriptor we're parsing +PUSB_CONFIGURATION_DESCRIPTOR CurrentConfigDesc; + +// Length of the current configuration descriptor +DWORD dwConfigLength; +// Our current position from the beginning of the config descriptor +DWORD dwConfigIndex; + +// +// DISPLAY.C +// +int gDeviceSpeed; + +// Save the current Configuration starting and ending addresses +// Used in ValidateDescAddress() +// +PUSB_CONFIGURATION_DESCRIPTOR g_pConfigDesc; +PSTRING_DESCRIPTOR_NODE g_pStringDescs; +PUCHAR g_descEnd; + +/***************************************************************************** + F U N C T I O N P R O T O T Y P E S +*****************************************************************************/ + +// +// USBVIEW.C +// + +HTREEITEM +AddLeaf ( + HTREEITEM hTreeParent, + LPARAM lParam, + _In_ LPTSTR lpszText, + TREEICON TreeIcon +); + +VOID +Oops +( + _In_ PCHAR File, + ULONG Line +); + +// +// DISPLAY.C +// + +EXTERN_C UINT IsIADDevice (PUSBDEVICEINFO info); +EXTERN_C UINT IsUVCDevice (PUSBDEVICEINFO info); +EXTERN_C PCHAR GetVendorString(USHORT idVendor); +EXTERN_C PCHAR GetLangIDString(USHORT idLang); +EXTERN_C UINT GetConfigurationSize (PUSBDEVICEINFO info); +EXTERN_C PUSB_COMMON_DESCRIPTOR +GetNextDescriptor( + _In_reads_bytes_(TotalLength) + PUSB_COMMON_DESCRIPTOR FirstDescriptor, + _In_ + ULONG TotalLength, + _In_ + PUSB_COMMON_DESCRIPTOR StartDescriptor, + _In_ long + DescriptorType + ); + +HRESULT +UpdateTreeItemDeviceInfo( + HWND hTreeWnd, + HTREEITEM hTreeItem + ); + +PCHAR +GetTextBuffer( +); + +BOOL +ResetTextBuffer( +); + +BOOL +CreateTextBuffer ( +); + +VOID +DestroyTextBuffer ( +); + +UINT +GetTextBufferPos ( +); + +VOID +UpdateEditControl ( + HWND hEditWnd, + HWND hTreeWnd, + HTREEITEM hTreeItem +); + + +VOID __cdecl +AppendBuffer ( + LPCTSTR lpFormat, + ... +); + +VOID __cdecl +AppendTextBuffer ( + LPCTSTR lpFormat, + ... +); + +VOID +DisplayStringDescriptor ( + UCHAR Index, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState +); + +PCHAR +GetStringFromList( + PSTRINGLIST slPowerState, + ULONG ulNumElements, + +#ifdef H264_SUPPORT + ULONGLONG ulFlag, +#else + ULONG ulFlag, +#endif + _In_ PCHAR szDefault + ); + +EXTERN_C PCHAR GetPowerStateString( + WDMUSB_POWER_STATE powerState + ); + +EXTERN_C PCHAR GetControllerFlavorString( + USB_CONTROLLER_FLAVOR flavor + ); + +EXTERN_C ULONG GetEhciDebugPort( + ULONG vendorId, + ULONG deviceId + ); + +VOID +WalkTreeTopDown( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext, + _In_opt_ LPFNTREENOTIFYCALLBACK lpfnTreeNotifyCallback + ); + +VOID RefreshTree (VOID); + +// +// ENUM.C +// + +VOID +EnumerateHostControllers ( + HTREEITEM hTreeParent, + ULONG *DevicesConnected + ); + + +VOID +CleanupItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); + +DEVICE_POWER_STATE +AcquireDevicePowerState( + _Inout_ PDEVICE_INFO_NODE pNode + ); + +_Success_(return == TRUE) +BOOL +GetDeviceProperty( + _In_ HDEVINFO DeviceInfoSet, + _In_ PSP_DEVINFO_DATA DeviceInfoData, + _In_ DWORD Property, + _Outptr_ LPTSTR *ppBuffer + ); + +void +ClearDeviceList( + PDEVICE_GUID_LIST DeviceList + ); + +// +// DEBUG.C +// + +_Success_(return != NULL) +_Post_writable_byte_size_(dwBytes) +HGLOBAL +MyAlloc ( + _In_ PCHAR File, + ULONG Line, + DWORD dwBytes + ); + +_Success_(return != NULL) +_Post_writable_byte_size_(dwBytes) +HGLOBAL +MyReAlloc ( + HGLOBAL hMem, + DWORD dwBytes + ); + +HGLOBAL +MyFree ( + HGLOBAL hMem + ); + +VOID +MyCheckForLeaks ( + VOID + ); + +// +// DEVNODE.C +// + + +PUSB_DEVICE_PNP_STRINGS +DriverNameToDeviceProperties( + _In_reads_bytes_(cbDriverName) PCHAR DriverName, + _In_ size_t cbDriverName + ); + +VOID FreeDeviceProperties( + _In_ PUSB_DEVICE_PNP_STRINGS *ppDevProps + ); +// +// DISPAUD.C +// + +BOOL +DisplayAudioDescriptor ( + PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc, + UCHAR bInterfaceSubClass + ); + +// +// DISPVID.C +// + +BOOL +DisplayVideoDescriptor ( + PVIDEO_SPECIFIC VidCommonDesc, + UCHAR bInterfaceSubClass, + PSTRING_DESCRIPTOR_NODE StringDescs, + DEVICE_POWER_STATE LatestDevicePowerState + ); + +// +// DISPLAY.C +// + +BOOL +ValidateDescAddress ( + PUSB_COMMON_DESCRIPTOR commonDesc + ); diff --git a/usb/usbview/uvcview.rc b/usb/usbview/uvcview.rc new file mode 100644 index 00000000..ab9756b9 --- /dev/null +++ b/usb/usbview/uvcview.rc @@ -0,0 +1,152 @@ +#include <windows.h> +#include <commctrl.h> +#include "resource.h" +#include <ntverp.h> + +////////////////////////////////////////////////////////////////////////////// +// +// VERSION +// +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) USB device viewer" +#define VER_INTERNALNAME_STR "USBView" +#define VER_ORIGINALFILENAME_STR VER_INTERNALNAME_STR +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1996-2011 All Rights Reserved." + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + + +////////////////////////////////////////////////////////////////////////////// +// +// ICON +// +IDI_ICON ICON DISCARDABLE "USB.ICO" +IDI_BADICON ICON DISCARDABLE "BANG.ICO" +IDI_COMPUTER ICON DISCARDABLE "MONITOR.ICO" +IDI_HUB ICON DISCARDABLE "HUB.ICO" +IDI_NODEVICE ICON DISCARDABLE "PORT.ICO" +IDI_NOSSDEVICE ICON DISCARDABLE "SSPORT.ICO" +IDI_SSICON ICON DISCARDABLE "SSUSB.ICO" + +////////////////////////////////////////////////////////////////////////////// +// +// Cursor +// +IDC_SPLIT CURSOR DISCARDABLE "SPLIT.CUR" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAINDIALOG DIALOGEX 0, 0, 415, 243 +STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +CAPTION "USB Device Viewer" +MENU IDR_MENU +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Tree1",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, + 0,0,120,234,WS_EX_CLIENTEDGE + EDITTEXT IDC_EDIT,120,0,295,234,ES_MULTILINE | ES_READONLY | + WS_VSCROLL | WS_HSCROLL + CONTROL "Devices Connected: 0",IDC_STATUS,"msctls_statusbar32", + SBARS_SIZEGRIP, + 0,235,415,8 +END + + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 230, 117 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About USBView" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,90,100,50,14 + LTEXT "USB Device Viewer",IDC_STATIC,54,15,104,8 + LTEXT VER_LEGALCOPYRIGHT_STR,IDC_STATIC,54,45,145,8 + EDITTEXT IDC_VERSION,54,60,110,8,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + EDITTEXT IDC_UVCVERSION,54,75,110,8,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + ICON IDI_ICON,IDC_STATIC,15,15,21,20 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Refresh\tF5", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "Save Current &View ..." ID_SAVE + MENUITEM "Save As (&txt) ...", ID_SAVEALL + MENUITEM "Save As (&xml) ...\tF2", ID_SAVEXML + MENUITEM SEPARATOR + + MENUITEM "E&xit", ID_EXIT + END + POPUP "&Options" + BEGIN + MENUITEM "&Auto Refresh", ID_AUTO_REFRESH, CHECKED + MENUITEM "Show &Config Descriptors", ID_CONFIG_DESCRIPTORS, CHECKED + MENUITEM SEPARATOR +// MENUITEM "&Show Description Annotations", ID_ANNOTATION, CHECKED + MENUITEM "&Log to debugger", ID_LOG_DEBUG + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_ABOUT + END +END + +////////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDACCEL ACCELERATORS DISCARDABLE +BEGIN + VK_F5, ID_REFRESH, VIRTKEY,NOINVERT + VK_F2, ID_SAVEXML, VIRTKEY,NOINVERT +END + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_STRINGBASE "Base string" +END + +STRINGTABLE +BEGIN + IDS_STANDARD_FONT "Courier" + IDS_STANDARD_FONT_HEIGHT "\13" + IDS_STANDARD_FONT_WIDTH "\8" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USBVIEW_USAGE "usbview usage:\nusbview [/?]\n\t/? - this usage message.\ + \n\t/q quiet mode, does not display 'Press any key to continue ...\n\t\ + \nusbview [/q] [/f] /saveall:<filename.txt>\ + \n\tsaveall - saves the USB tree view as a text file\ + \n\t/f - overwrite file if it already exists\n\nusbview [/q] [/f] /savexml:<filename.xml>\ + \n\tsavexml - saves the USB tree view as a xml file\n\t/f - overwrite file if it already exists\n\n" + IDS_USBVIEW_PRESSKEY "Press any key to continue ...\n" + IDS_USBVIEW_INVALIDARG "Invalid argument: [%1]\n" + IDS_USBVIEW_FILE_EXISTS_TXT "File: [%1] already exists, try `usbview /f /saveall:[%1]` to force overwrite\n" + IDS_USBVIEW_FILE_EXISTS_XML "File: [%1] already exists, try `usbview /f /savexml:[%1]` to force overwrite\n" + IDS_USBVIEW_INTERNAL_ERROR "An internal error occured, please report this as a bug\n" + IDS_USBVIEW_SAVED_TO "Usbview information saved to file : [%1]\n" + IDS_USBVIEW_INVALID_FILENAME "The argument : [%1] is invalid or incomplete.\n" +END + diff --git a/usb/usbview/vndrlist.h b/usb/usbview/vndrlist.h new file mode 100644 index 00000000..0b10d22e --- /dev/null +++ b/usb/usbview/vndrlist.h @@ -0,0 +1,8930 @@ +/*++ + +Copyright (c) 1997-2008 Microsoft Corporation + +Module Name: + + VNDRLIST.H + +Abstract: + + This header file contains a list of all currently known USB Vendor IDs + and the vendor name associated with each Vendor ID. + +Source: + + http://www.usb.org usb.if + +Environment: + + Kernel & user mode + +Revision History: + + 04-25-97 : created + 03-28-03 : refreshed with latest list from usb.org + 05-04-05 : refreshed with latest list from usb.org + 05-02-07 : refreshed with latest list from usb.org + 03-19-08 : refreshed with latest list from usb.org + +--*/ + +#ifndef __VNDRLIST_H__ +#define __VNDRLIST_H__ + +// +// Vendor ID structure +// +typedef struct { + USHORT usVendorID; + PCHAR szVendor; +} USBVENDORID, *PUSBVENDORID; + +// +// This list built from information obtained on February-15-2012 from +// http://www.usb.org/developers/tools/ +// or +// http://www.usb.org/developers/tools/comp_dump +// +// This information has not been independently verified and no claims +// are made here as to its accuracy. +// +// 765 total +// +USBVENDORID USBVendorIDs[] = +{ + { 0x0079, "Shenzhen Longshengwei Technology, Co., Ltd." }, + { 0x013A, "Aimgene Technology Co., Ltd" }, + { 0x03CC, "GN OTOMETRIC" }, + { 0x03E8, "EndPoints Inc." }, + { 0x03E9, "Thesys Microelectronics" }, + { 0x03EA, "Data Broadcasting Corp." }, + { 0x03EB, "Atmel Corporation" }, + { 0x03EC, "Iwatsu America Inc." }, + { 0x03ED, "Mitel Corporation" }, + { 0x03EE, "Mitsumi" }, + { 0x03F0, "Hewlett Packard" }, + { 0x03F1, "Genoa Technology" }, + { 0x03F2, "Oak Technology, Inc" }, + { 0x03F3, "Adaptec, Inc." }, + { 0x03F4, "Diebold, Inc." }, + { 0x03F5, "Siemens Electromechanical" }, + { 0x03F7, "Tulip Computers International" }, + { 0x03F8, "Epson Imaging Technology Center" }, + { 0x03F9, "KeyTronic Corp." }, + { 0x03FB, "OPTi Inc." }, + { 0x03FC, "Elitegroup Computer Systems" }, + { 0x03FD, "Xilinx Inc." }, + { 0x03FE, "Farallon Comunications" }, + { 0x03FF, "Weitek Corporation" }, + { 0x0400, "National Semiconductor" }, + { 0x0401, "National Registry Inc." }, + { 0x0402, "ALi Corporation" }, + { 0x0403, "Future Technology Devices International Limited" }, + { 0x0404, "NCR Corporation" }, + { 0x0405, "inSilicon" }, + { 0x0406, "Fujitsu-ICL Computers" }, + { 0x0407, "Fujitsu Personal Systems, Inc." }, + { 0x0408, "Quanta Computer Inc." }, + { 0x0409, "NEC Corporation" }, + { 0x040A, "Eastman Kodak Company" }, + { 0x040B, "Weltrend Semiconductor" }, + { 0x040C, "VTech Computers Ltd" }, + { 0x040D, "VIA Technologies, Inc." }, + { 0x040E, "MCCI Corporation" }, + { 0x040F, "Echo Speech Corporation" }, + { 0x0410, "Isis Distributed Systems, Inc." }, + { 0x0411, "BUFFALO INC." }, + { 0x0412, "Award Software International" }, + { 0x0413, "Leadtek Research Inc." }, + { 0x0414, "Giga-Byte Technology Co., Ltd." }, + { 0x0416, "Nuvoton Technology Corp." }, + { 0x0417, "Symbios, Inc." }, + { 0x0418, "AST Research" }, + { 0x0419, "Samsung Info. Systems America Inc." }, + { 0x041A, "Phoenix Technologies Ltd." }, + { 0x041B, "d'TV" }, + { 0x041D, "S3 Incorporated" }, + { 0x041E, "Creative Labs" }, + { 0x041F, "LCS Telegraphics" }, + { 0x0420, "Chips and Technologies" }, + { 0x0421, "Nokia Corporation" }, + { 0x0422, "ADI Systems Inc." }, + { 0x0423, "CATC" }, + { 0x0424, "SMSC" }, + { 0x0425, "Freescale Semiconductor Hong Kong Limited" }, + { 0x0426, "Integrated Device Technology" }, + { 0x0427, "Motorola Electronics Taiwan Ltd." }, + { 0x0428, "Advanced Gravis Computer Ltd." }, + { 0x0429, "Cirrus Logic Inc." }, + { 0x042A, "Ericsson Austrian, AG" }, + { 0x042C, "Innovative Semiconductors, Inc." }, + { 0x042D, "Micronics" }, + { 0x042E, "Acer, Inc.(2)" }, + { 0x042F, "Molex Inc." }, + { 0x0430, "Fujitsu Component Limited" }, + { 0x0431, "ITAC Systems, Inc." }, + { 0x0432, "Unisys Corp." }, + { 0x0433, "Alps Electric Inc." }, + { 0x0434, "Samsung Info. Systems America Inc.(2)" }, + { 0x0435, "Hyundai Electronics America" }, + { 0x0436, "Taugagreining HF" }, + { 0x0437, "Framatome Connectors USA" }, + { 0x0438, "Advanced Micro Devices" }, + { 0x0439, "Voice Technologies Group" }, + { 0x043C, "Lucid Designs" }, + { 0x043D, "Lexmark International Inc." }, + { 0x043E, "LG Electronics USA Inc." }, + { 0x043F, "RadiSys Corporation" }, + { 0x0440, "EIZO NANAO CORPORATION" }, + { 0x0441, "Winbond Systems Lab." }, + { 0x0442, "Cygnion Corp." }, + { 0x0443, "Gateway 2000" }, + { 0x0445, "Agere Systems" }, + { 0x0446, "NMB Technologies Corporation" }, + { 0x0447, "Momentum Microsystems" }, + { 0x0449, "Eldim" }, + { 0x044A, "Shamrock Technology Co., Ltd." }, + { 0x044B, "WSI" }, + { 0x044C, "CCL/ITRI" }, + { 0x044D, "Siemens Nixdorf AG" }, + { 0x044E, "Alps Electric Co., Ltd." }, + { 0x044F, "ThrustMaster, Inc." }, + { 0x0450, "DFI Inc." }, + { 0x0451, "Texas Instruments" }, + { 0x0452, "Mitsubishi Electric & Electronics US, Inc." }, + { 0x0453, "CMD Technology" }, + { 0x0454, "Vobis Microcomputer AGO" }, + { 0x0455, "Telematics International, Inc." }, + { 0x0456, "Analog Devices, Inc." }, + { 0x0457, "Silicon Integrated Systems Corp." }, + { 0x0458, "KYE Systems Corp." }, + { 0x0459, "Adobe Systems, Inc." }, + { 0x045A, "SONICblue Incorporated" }, + { 0x045B, "Renesas Electronics Corp." }, + { 0x045D, "Nortel Networks" }, + { 0x045E, "Microsoft Corporation" }, + { 0x0460, "Ace Cad Enterprise Co., Ltd." }, + { 0x0461, "Primax Electronics" }, + { 0x0463, "EATON" }, + { 0x0464, "AMP/Tycoelectronics" }, + { 0x0465, "Pacific Micro Computing" }, + { 0x0467, "AT&T Paradyne" }, + { 0x0468, "Wieson Technologies Co., Ltd." }, + { 0x046A, "CHERRY" }, + { 0x046B, "American Megatrends" }, + { 0x046C, "Toshiba Corporation, Digital Media Network Company" }, + { 0x046D, "Logitech Inc." }, + { 0x046E, "Behavior Tech Computer Corporation" }, + { 0x046F, "Crystal Semiconductor" }, + { 0x0471, "Philips Consumer Lifestyle BV" }, + { 0x0472, "Sun Microsystems" }, + { 0x0473, "Sanyo Information Business Co., Ltd." }, + { 0x0474, "Sanyo Electric Co. Ltd." }, + { 0x0475, "TECO Electric & Machinery Co., Ltd." }, + { 0x0476, "AESP" }, + { 0x0477, "Seagate Technology" }, + { 0x0478, "Connectix Corp." }, + { 0x0479, "Advanced Peripheral Laboratories" }, + { 0x047A, "Semtech Corporation" }, + { 0x047B, "Silitek Corp." }, + { 0x047D, "Kensington" }, + { 0x047E, "LSI Corporation" }, + { 0x047F, "Plantronics, Inc." }, + { 0x0480, "Toshiba America Info. Systems, Inc." }, + { 0x0481, "Zenith Data Systems" }, + { 0x0482, "Kyocera Corporation" }, + { 0x0483, "STMicroelectronics" }, + { 0x0484, "Specialix" }, + { 0x0485, "Nokia Monitors" }, + { 0x0486, "ASUS Computers Inc." }, + { 0x0487, "Stewart Connector" }, + { 0x0488, "Cirque Corporation" }, + { 0x0489, "Foxconn / Hon Hai" }, + { 0x048A, "S-MOS Systems, Inc." }, + { 0x048C, "Alps Electric Ireland Ltd." }, + { 0x048D, "ITE Tech Inc." }, + { 0x048F, "Eicon Tech." }, + { 0x0490, "United Microelectronic Corporation (UMC)" }, + { 0x0491, "Capetronic Kaohsiung Corp." }, + { 0x0492, "Samsung Semiconductor, Inc." }, + { 0x0493, "MAG Technology Co., Ltd." }, + { 0x0495, "ESS Technology, Inc." }, + { 0x0496, "Micron Electronics" }, + { 0x0497, "Smile International, Inc." }, + { 0x0498, "Capetronic (Kaohsiung) Corp." }, + { 0x0499, "Yamaha Corporation" }, + { 0x049A, "Gandalf Technologies Ltd." }, + { 0x049B, "Curtis Computer Products" }, + { 0x049C, "Acer Advanced Labs, Inc." }, + { 0x049D, "VLSI Technology, Inc." }, + { 0x049F, "Compaq Computer Corporation" }, + { 0x04A0, "Digital Equipment Corp." }, + { 0x04A1, "SystemSoft Corporation" }, + { 0x04A2, "FirePower Systems" }, + { 0x04A3, "Trident Microsystems Inc." }, + { 0x04A4, "Hitachi, Ltd." }, + { 0x04A5, "BenQ Corporation" }, + { 0x04A6, "Nokia Display Products" }, + { 0x04A7, "Visioneer" }, + { 0x04A8, "Multivideo Labs, Inc." }, + { 0x04A9, "Canon Inc." }, + { 0x04AA, "Daewoo Teletech Co., Ltd." }, + { 0x04AB, "Chromatic Research" }, + { 0x04AC, "Micro Audiometrics Corp." }, + { 0x04AD, "Dooin Electronics" }, + { 0x04AE, "Brooktree Corporation" }, + { 0x04AF, "Winnov L.P." }, + { 0x04B0, "Nikon Corporation" }, + { 0x04B1, "Pan International" }, + { 0x04B3, "IBM Corporation" }, + { 0x04B4, "Cypress Semiconductor" }, + { 0x04B5, "ROHM Co., Ltd." }, + { 0x04B6, "Hint Corporation" }, + { 0x04B7, "Compal Electronics, Inc." }, + { 0x04B8, "Seiko Epson Corp." }, + { 0x04B9, "SafeNet, Inc." }, + { 0x04BA, "Toucan Systems Limited" }, + { 0x04BB, "I-O Data Device, Inc." }, + { 0x04BC, "Digital Systems Associates" }, + { 0x04BD, "Toshiba Electronics Taiwan Corp." }, + { 0x04BE, "Telia Research AB" }, + { 0x04BF, "TDK Corporation" }, + { 0x04C2, "Methode Electronics Far East Pte Ltd." }, + { 0x04C3, "Maxi Switch, Inc." }, + { 0x04C4, "Lockheed Martin Energy Research" }, + { 0x04C5, "Fujitsu Ltd." }, + { 0x04C6, "Toshiba America Electronic Components" }, + { 0x04C7, "Micro Macro Technologies" }, + { 0x04C8, "Konica Corporation" }, + { 0x04CA, "Lite-On Technology Corp." }, + { 0x04CB, "FUJIFILM Corporation" }, + { 0x04CC, "ST-Ericsson" }, + { 0x04CD, "Tatung Company of America, Inc." }, + { 0x04CE, "ScanLogic Corporation" }, + { 0x04CF, "Myson Century, Inc." }, + { 0x04D0, "Digi International" }, + { 0x04D1, "ITT Cannon" }, + { 0x04D2, "Altec Lansing Technologies, Inc." }, + { 0x04D3, "VidUS, Inc." }, + { 0x04D4, "LSI Logic Inc." }, + { 0x04D5, "Forte Technologies, Inc." }, + { 0x04D6, "Mentor Graphics" }, + { 0x04D7, "Oki Semiconductor" }, + { 0x04D8, "Microchip Technology Inc." }, + { 0x04D9, "Holtek Semiconductor, Inc." }, + { 0x04DA, "Panasonic Corporation" }, + { 0x04DB, "Hypertec Pty Ltd." }, + { 0x04DC, "Huan Hsin Holdings Ltd." }, + { 0x04DD, "Sharp Corporation" }, + { 0x04DE, "MindShare, Inc." }, + { 0x04DF, "ePadLink" }, + { 0x04E1, "Iiyama Corporation" }, + { 0x04E2, "Exar Corporation" }, + { 0x04E3, "Zilog" }, + { 0x04E4, "ACC Microelectronics" }, + { 0x04E5, "Promise Technology" }, + { 0x04E6, "Identive Group Inc." }, + { 0x04E7, "Elo TouchSystems" }, + { 0x04E8, "Samsung Electronics Co., Ltd." }, + { 0x04E9, "PC-Tel, Inc." }, + { 0x04EA, "Sipex Corporation" }, + { 0x04EB, "Northstar Systems Corp." }, + { 0x04EC, "Tokyo Electron Device Limited" }, + { 0x04ED, "Annabooks" }, + { 0x04EF, "Pacific Electronic International, Inc." }, + { 0x04F0, "Daewoo Electronics Co., Ltd." }, + { 0x04F1, "Victor Company of Japan, Limited" }, + { 0x04F2, "Chicony Electronics Co., Ltd." }, + { 0x04F3, "ELAN Microelectronics Corportation" }, + { 0x04F4, "Harting Elektronik Inc." }, + { 0x04F5, "Fujitsu-ICL Systems, Inc." }, + { 0x04F6, "Norand Corporation" }, + { 0x04F7, "Newnex Technology Corp." }, + { 0x04F8, "FuturePlus Systems" }, + { 0x04F9, "Brother Industries, Ltd." }, + { 0x04FA, "Dallas Semiconductor" }, + { 0x04FB, "Biostar Microtech Int'l Corp." }, + { 0x04FC, "SUNPLUS TECHNOLOGY CO., LTD." }, + { 0x04FD, "Soliton Systems K.K." }, + { 0x04FE, "PFU Limited" }, + { 0x04FF, "E-CMOS Corp." }, + { 0x0500, "Siam United Hi-Tech" }, + { 0x0501, "Fujikura/DDK" }, + { 0x0502, "Acer, Inc." }, + { 0x0503, "Hitachi America Ltd." }, + { 0x0504, "Hayes Microcomputer Products" }, + { 0x0505, "Digital Home Corporation" }, + { 0x0506, "3Com Corporation" }, + { 0x0507, "Hosiden Corporation" }, + { 0x0508, "Clarion Co., Ltd." }, + { 0x0509, "Aztech Systems Ltd" }, + { 0x050A, "Cinch Connectors" }, + { 0x050B, "Cable System International" }, + { 0x050C, "InnoMedia, Inc." }, + { 0x050D, "Belkin Corporation" }, + { 0x050E, "Neon Technology, Inc." }, + { 0x050F, "KC Technology Inc." }, + { 0x0510, "Sejin Electron Inc." }, + { 0x0511, "N*ABLE Technologies, Inc (Data Book)" }, + { 0x0512, "Hualon Microelectronics Corp." }, + { 0x0513, "digital-X, Inc." }, + { 0x0514, "FCI Electronics" }, + { 0x0515, "ACTC" }, + { 0x0516, "Longwell Electronics/Longwell Company" }, + { 0x0517, "Butterfly Communications" }, + { 0x0518, "EzKEY Corp." }, + { 0x0519, "Star Micronics Co., LTD" }, + { 0x051A, "WYSE Technology" }, + { 0x051C, "Shuttle Inc." }, + { 0x051D, "American Power Conversion" }, + { 0x051E, "Scientific Atlanta, Inc." }, + { 0x051F, "IO Systems Inc." }, + { 0x0520, "Taiwan Semiconductor Manufacturing Co." }, + { 0x0521, "Airborn Connectors" }, + { 0x0522, "ACON, Advanced-Connectek, Inc." }, + { 0x0523, "ATEN GMBH" }, + { 0x0524, "Sola Electronics" }, + { 0x0525, "PLX Technology, Inc." }, + { 0x0526, "Temic MHS S.A." }, + { 0x0527, "ALTRA" }, + { 0x0528, "ATI Technologies, Inc." }, + { 0x0529, "Aladdin Knowledge Systems" }, + { 0x052A, "Crescent Heart Software" }, + { 0x052B, "Tekom Technologies, Inc" }, + { 0x052C, "Canon Development Americas" }, + { 0x052D, "Avid Electronics Corp." }, + { 0x052E, "Standard Microsystems Corp. (1)" }, + { 0x052F, "Unicore Software, Inc." }, + { 0x0530, "American Microsystems Inc." }, + { 0x0531, "Wacom Technology Corp." }, + { 0x0532, "Systech Corporation" }, + { 0x0533, "Alcatel Mobile Phones" }, + { 0x0534, "Motorola" }, + { 0x0535, "LIH TZU Electric Co., Ltd." }, + { 0x0536, "Hand Held Products (Honeywell International Inc.)" }, + { 0x0537, "Inventec Corporation" }, + { 0x0538, "The SCO Group" }, + { 0x0539, "Shyh Shiun Terminals Co. LTD" }, + { 0x053A, "Preh KeyTec GmbH" }, + { 0x053B, "Global Village Communication" }, + { 0x053C, "Institut of Microelectronic & Mechatronic Systems" }, + { 0x053D, "Silicon Architect" }, + { 0x053E, "Mobility Electronics" }, + { 0x053F, "Synopsys, Inc." }, + { 0x0540, "UniAccess AB" }, + { 0x0541, "Sirf Technology, Inc" }, + { 0x0542, "MICOM Communications Corp." }, + { 0x0543, "ViewSonic Corporation" }, + { 0x0544, "Cristie Electronics Ltd." }, + { 0x0545, "Veo" }, + { 0x0546, "Polaroid Corporation" }, + { 0x0547, "Anchor Chips Inc." }, + { 0x0548, "Tyan Computer Corp." }, + { 0x0549, "Pixera Corporation" }, + { 0x054A, "Fujitsu Microelectronics, Inc." }, + { 0x054B, "New Media Corporation" }, + { 0x054C, "Sony Corporation" }, + { 0x054D, "Try Corporation" }, + { 0x054E, "Proside Corporation" }, + { 0x054F, "WYSE Technology Taiwan" }, + { 0x0550, "Fuji Xerox Co., Ltd." }, + { 0x0551, "CompuTrend Systems, Inc." }, + { 0x0552, "Philips Monitors" }, + { 0x0553, "STMicroelectronics Imaging Division" }, + { 0x0554, "Dictaphone Corp." }, + { 0x0555, "ANAM S&T Co., Ltd." }, + { 0x0556, "Asahi Kasei Microdevices Corporation" }, + { 0x0557, "ATEN International Co. Ltd." }, + { 0x0558, "Truevision, Inc." }, + { 0x0559, "Cadence Design Systems, Inc." }, + { 0x055A, "Kenwood USA" }, + { 0x055B, "KnowledgeTek, Inc." }, + { 0x055C, "Proton Electronic Ind." }, + { 0x055D, "Samsung Electro-Mechanics Co." }, + { 0x055E, "Optoma Corporation" }, + { 0x055F, "Mustek Systems Inc." }, + { 0x0560, "Interface Corporation" }, + { 0x0561, "Oasis Design, Inc." }, + { 0x0562, "Telex Communications Inc." }, + { 0x0563, "Immersion Corporation" }, + { 0x0564, "Kodak Digital Product Center, Japan Ltd." }, + { 0x0565, "Peracom Networks, Inc." }, + { 0x0566, "Monterey International Corp." }, + { 0x0567, "Xyratex" }, + { 0x0568, "Quartz Ingenierie" }, + { 0x0569, "SegaSoft" }, + { 0x056A, "WACOM Co., Ltd." }, + { 0x056B, "Decicon Incorporated" }, + { 0x056C, "Belkin Research & Development" }, + { 0x056D, "EIZO Corporation" }, + { 0x056E, "Elecom Co., Ltd." }, + { 0x056F, "Korea Data Systems Co., Ltd." }, + { 0x0570, "Epson America" }, + { 0x0571, "XLR8, Inc." }, + { 0x0572, "Conexant Systems, Inc." }, + { 0x0573, "Zoran Corporation" }, + { 0x0574, "City University of Hong Kong" }, + { 0x0575, "Philips Creative Display Solutions" }, + { 0x0576, "BAFO/Quality Computer Accessories" }, + { 0x0577, "ELSA" }, + { 0x0578, "Intrinsix Corp." }, + { 0x0579, "GVC Corporation" }, + { 0x057A, "Samsung Electronics America" }, + { 0x057B, "Y-E Data, Inc." }, + { 0x057C, "AVM GmbH" }, + { 0x057D, "Shark Multimedia Inc." }, + { 0x057E, "Nintendo Co., Ltd." }, + { 0x057F, "QuickShot Limited" }, + { 0x0580, "Denron Inc." }, + { 0x0581, "Racal Data Group" }, + { 0x0582, "Roland Corporation" }, + { 0x0583, "Padix Co., Ltd." }, + { 0x0584, "RATOC Systems, Inc." }, + { 0x0585, "FlashPoint Technology, Inc." }, + { 0x0586, "ZyXEL Communications Corp." }, + { 0x0587, "Matsushita Kotobuki Electronics Industries America" }, + { 0x0588, "Sapien Design" }, + { 0x0589, "Victron" }, + { 0x058A, "Nohau Corporation" }, + { 0x058B, "Infineon Technologies" }, + { 0x058C, "In Focus Systems" }, + { 0x058D, "Micrel Semiconductor" }, + { 0x058E, "Tripath Technology Inc." }, + { 0x058F, "Alcor Micro, Corp." }, + { 0x0590, "OMRON Corporation" }, + { 0x0591, "Questra Consulting" }, + { 0x0592, "Powerware Corporation" }, + { 0x0593, "Incite" }, + { 0x0594, "Princeton Graphic Systems" }, + { 0x0595, "Zoran Microelectronics Ltd." }, + { 0x0596, "3M Touch Systems" }, + { 0x0597, "Trisignal Communications" }, + { 0x0598, "Niigata Canotec Co., Inc." }, + { 0x0599, "Brilliance Semiconductor Inc." }, + { 0x059A, "Spectrum Signal Processing Inc." }, + { 0x059B, "Iomega Corporation" }, + { 0x059C, "A-Trend Technology Co., Ltd." }, + { 0x059D, "Advanced Input Devices" }, + { 0x059E, "Intelligent Instrumentation" }, + { 0x059F, "LaCie" }, + { 0x05A0, "Vetronix Corporation" }, + { 0x05A1, "USC Corporation" }, + { 0x05A2, "Fuji Film Microdevices Co. Ltd." }, + { 0x05A3, "TransDimension-NH LLC" }, + { 0x05A4, "Ortek Technology, Inc." }, + { 0x05A5, "Sampo Technology Corp." }, + { 0x05A6, "Cisco Systems, Inc." }, + { 0x05A7, "Bose Corporation" }, + { 0x05A8, "Spacetec IMC Corporation" }, + { 0x05A9, "OmniVision Technologies, Inc." }, + { 0x05AA, "Utilux South China Ltd." }, + { 0x05AB, "In-System Design" }, + { 0x05AC, "Apple" }, + { 0x05AD, "Y.C. Cable U.S.A., Inc" }, + { 0x05AE, "Synopsys, Inc.(2)" }, + { 0x05AF, "Sunrex Technology Corp." }, + { 0x05B0, "Fountain Technologies, Inc" }, + { 0x05B1, "First International Computer, Inc." }, + { 0x05B2, "Focus Electronics" }, + { 0x05B4, "HYUNDAI Electronics Industries Co., Ltd." }, + { 0x05B5, "Dialogic Corp" }, + { 0x05B6, "Proxima Corporation" }, + { 0x05B7, "Medianix Semiconductor, Inc." }, + { 0x05B8, "Sysgration" }, + { 0x05B9, "Philips Research Laboratories" }, + { 0x05BA, "DigitalPersona, Inc." }, + { 0x05BB, "Grey Cell Systems" }, + { 0x05BD, "RAFI GmbH & Co. KG" }, + { 0x05BE, "Tyco Electronics" }, + { 0x05BF, "S & S Research" }, + { 0x05C0, "Keil Software" }, + { 0x05C1, "Kawasaki Microelectronics, Inc." }, + { 0x05C2, "Media Phonics (Suisse) S.A." }, + { 0x05C3, "VME Microsystems" }, + { 0x05C5, "Digi International Inc." }, + { 0x05C6, "Qualcomm, Inc" }, + { 0x05C7, "Qtronix Corp" }, + { 0x05C8, "Foxlink/Cheng Uei Precision Industry Co., Ltd." }, + { 0x05C9, "Semtech" }, + { 0x05CA, "Ricoh Company Ltd." }, + { 0x05CB, "PowerVision Technologies Inc." }, + { 0x05CC, "Neue ELSA GmbH" }, + { 0x05CD, "Silicom LTD." }, + { 0x05CE, "sci-worx GmbH" }, + { 0x05CF, "Sung Forn Co. LTD." }, + { 0x05D0, "GE Medical Systems Lunar" }, + { 0x05D1, "Brainboxes Limited" }, + { 0x05D2, "Wave Systems Corp." }, + { 0x05D3, "Tohoku Ricoh Co., Ltd." }, + { 0x05D5, "Super Gate Technology Co., LTD" }, + { 0x05D6, "Philips Semiconductors, CICT" }, + { 0x05D7, "Thomas & Betts" }, + { 0x05D8, "Ultima Electronics Corp." }, + { 0x05D9, "TPG IPB, Inc." }, + { 0x05DA, "Microtek International Inc." }, + { 0x05DB, "Sun Corporation" }, + { 0x05DC, "Lexar Media, Inc." }, + { 0x05DD, "Delta Electronics Inc." }, + { 0x05DE, "Crucial Technology" }, + { 0x05DF, "Silicon Vision Inc." }, + { 0x05E0, "Symbol Technologies" }, + { 0x05E1, "Syntek Semiconductor Co., Ltd." }, + { 0x05E2, "ElecVision Inc." }, + { 0x05E3, "Genesys Logic, Inc." }, + { 0x05E4, "Red Wing Corporation" }, + { 0x05E5, "Fuji Electric Co., Ltd." }, + { 0x05E6, "Keithley Instruments" }, + { 0x05E7, "EIZO Nanoa Technologies Inc." }, + { 0x05E8, "ICC, Inc." }, + { 0x05E9, "Kawasaki Microelectronics America, Inc." }, + { 0x05EA, "Evergreen Systems International" }, + { 0x05EB, "FFC Limited" }, + { 0x05EC, "COM21, Inc." }, + { 0x05EE, "Cytechinfo Inc." }, + { 0x05EF, "Anko Electronic Co., Ltd." }, + { 0x05F0, "Canopus Co., Ltd." }, + { 0x05F2, "Dexin Corporation, Ltd." }, + { 0x05F3, "PI Engineering, Inc." }, + { 0x05F4, "Davis AS" }, + { 0x05F5, "Unixtar Technology Inc." }, + { 0x05F6, "Envision Peripherals, Inc." }, + { 0x05F7, "Silicon Portals Inc." }, + { 0x05F8, "Phase Metrics" }, + { 0x05F9, "Datalogic Scanning, Inc." }, + { 0x05FA, "Siemens Telecommunications Systems Limited" }, + { 0x05FC, "Harman Multimedia" }, + { 0x05FD, "STD Manufacturing Ltd." }, + { 0x05FE, "CHIC TECHNOLOGY CORP" }, + { 0x05FF, "LeCroy Corporation" }, + { 0x0600, "Barco Display Systems" }, + { 0x0601, "Jazz Hipster Corporation" }, + { 0x0602, "Vista Imaging Inc." }, + { 0x0603, "Novatek Microelectronics Corp." }, + { 0x0604, "Jean Co, Ltd." }, + { 0x0605, "Anchor C&C Co., Ltd." }, + { 0x0606, "Royal Information Electronics Co., Ltd." }, + { 0x0607, "Bridge Information Co., Ltd." }, + { 0x0608, "Genrad Ads" }, + { 0x0609, "SMK Manufacturing Inc." }, + { 0x060A, "Worth Data, Inc." }, + { 0x060B, "Solid Year Co., LTD." }, + { 0x060C, "EEH Datalink Gmbh" }, + { 0x060D, "Auctor Corporation" }, + { 0x060E, "Transmonde Technologies, Inc." }, + { 0x060F, "Joinsoon Electronics Mfg. Co., Ltd." }, + { 0x0610, "Costar Electronics Inc." }, + { 0x0611, "Totoku Electric Co., LTD." }, + { 0x0612, "TV Interactive Corp." }, + { 0x0613, "TransAct Technologies Incorporated" }, + { 0x0614, "Bio-Rad Laboratories" }, + { 0x0615, "Quabbin Wire & Cable Co., INC." }, + { 0x0616, "Future Techno Designs PVT. LTD." }, + { 0x0617, "Swiss Federal Institute of Technology" }, + { 0x0618, "Chia Shin Technology Corp." }, + { 0x0619, "Seiko Instruments Inc." }, + { 0x061A, "Veridicom2" }, + { 0x061B, "Promptus Communications, Inc." }, + { 0x061C, "Act Labs, Ltd." }, + { 0x061D, "Quatech, Inc." }, + { 0x061E, "Nissei Electric Co." }, + { 0x0620, "Alaris, Inc." }, + { 0x0621, "ODU-Steckverbindungssysteme GmbH & Co. KG" }, + { 0x0622, "Iotech, Inc." }, + { 0x0623, "Littelfuse, Inc." }, + { 0x0624, "Avocent Corporation" }, + { 0x0625, "TiMedia Technology Co., Ltd." }, + { 0x0626, "Nippon Systems Development Co., Ltd." }, + { 0x0627, "Adomax Technology Co., Ltd." }, + { 0x0628, "Tasking Software Inc." }, + { 0x0629, "Zida Technologies Limited" }, + { 0x062A, "MosArt Semiconductor Corp." }, + { 0x062B, "Greatlink Electronics Taiwan Ltd." }, + { 0x062C, "Institute for Information Industry" }, + { 0x062D, "Taiwan Tai-Hao Enterprises Co. Ltd." }, + { 0x062E, "MAIN SUPER ENTERPRISES CO.,LTD." }, + { 0x062F, "Sin Sheng Terminal & Machine Inc." }, + { 0x0630, "ORL" }, + { 0x0631, "JUJO Electronics Corporation" }, + { 0x0632, "Marquette Medical Systems, Inc." }, + { 0x0633, "Cyrix Corporation" }, + { 0x0634, "Micron Technology, Inc." }, + { 0x0635, "Methode Electronics, Inc." }, + { 0x0636, "Sierra Imaging, Inc." }, + { 0x0637, "Gunz Limited" }, + { 0x0638, "Avision, Inc." }, + { 0x0639, "Chrontel, Inc." }, + { 0x063A, "Techwin Corporation" }, + { 0x063B, "Taugagreining HF (2)" }, + { 0x063C, "Yamaichi Electronics Co., Ltd. (Sakura)" }, + { 0x063D, "Fong Kai Industrial Co., Ltd." }, + { 0x063E, "RealMedia Technology, Inc." }, + { 0x063F, "New Technology Cable Ltd." }, + { 0x0640, "Hitex Development Tools" }, + { 0x0641, "Woods Industries, Inc." }, + { 0x0642, "VIA Medical Corporation" }, + { 0x0643, "NOVATUS, Inc." }, + { 0x0644, "TEAC Corporation" }, + { 0x0645, "Ethentica Inc." }, + { 0x0647, "Acton Research Corporation" }, + { 0x0649, "Weli Science Co., Ltd" }, + { 0x064A, "Technical Corp." }, + { 0x064B, "Analog Devices, Inc. Development Tools" }, + { 0x064C, "Ji-Haw Industrial Co., Ltd" }, + { 0x064D, "TriTech Microelectronics Ltd" }, + { 0x064E, "Suyin Corporation" }, + { 0x064F, "WIBU-Systems AG" }, + { 0x0650, "Dynapro Systems" }, + { 0x0651, "Likom Technology Sdn. Bhd." }, + { 0x0652, "Stargate Solutions, Inc." }, + { 0x0653, "CNF Inc." }, + { 0x0654, "Granite Microsystems, Inc." }, + { 0x0655, "Space Shuttle Hi-Tech Co.,Ltd." }, + { 0x0656, "Glory Mark Electronic Ltd." }, + { 0x0657, "Tekcon Electronics Corp." }, + { 0x0658, "Sigma Designs, Inc." }, + { 0x0659, "AETHRA" }, + { 0x065A, "Optoelectronics Co., Ltd." }, + { 0x065B, "Tracewell Systems" }, + { 0x065C, "Brentwood Medical Technology Corp." }, + { 0x065D, "ATTO Technology, Inc." }, + { 0x065E, "Silicon Graphics" }, + { 0x065F, "Good Way Technology Co., Ltd. & GWC technology Inc" }, + { 0x0660, "TSAY-E (BVI) International Inc." }, + { 0x0661, "Hamamatsu Photonics K.K." }, + { 0x0662, "Kansai Electric Co., Ltd." }, + { 0x0663, "Topmax Electronic Co., Ltd." }, + { 0x0664, "ET&T" }, + { 0x0665, "WayTech Development, Inc." }, + { 0x0667, "Antona Corporation" }, + { 0x0668, "WordWand" }, + { 0x0669, "Oce' Printing Systems GmbH" }, + { 0x066A, "Total Technologies, Ltd." }, + { 0x066B, "SCM Microsystems Japan, Inc." }, + { 0x066C, "ASK ASA" }, + { 0x066D, "Entrega Technologies Inc." }, + { 0x066E, "Acer Semiconductor America, Inc." }, + { 0x066F, "Freescale Semiconductor, Inc. - Sigmatel" }, + { 0x0670, "Sequel Imaging, Inc." }, + { 0x0671, "Keisoku Giken Co., Ltd." }, + { 0x0672, "Labtec Inc." }, + { 0x0673, "HCL Peripherals Limited" }, + { 0x0674, "Key Mouse Electronic Enterprise Co., Ltd." }, + { 0x0675, "DrayTek Corp." }, + { 0x0676, "Teles AG" }, + { 0x0677, "Aiwa Co., Ltd." }, + { 0x0678, "ACARD Technology Corp." }, + { 0x0679, "WaterGate Software, Inc." }, + { 0x067A, "ADS ANKER GmbH" }, + { 0x067B, "Prolific Technology, Inc." }, + { 0x067C, "Efficient Networks, Inc." }, + { 0x067D, "Hohner Corp." }, + { 0x067E, "Intermec Technologies (S) Pte Ltd." }, + { 0x067F, "Virata Ltd." }, + { 0x0680, "Realtek Semiconductor Corp., CPP Div." }, + { 0x0681, "Siemens Information and Communication Products" }, + { 0x0683, "Dataq Instruments, Inc." }, + { 0x0684, "Cytec Corporation" }, + { 0x0685, "ISDN*tek" }, + { 0x0686, "KONICA MINOLTA TECHNOLOGY CENTER, INC." }, + { 0x0687, "Sycard Technology" }, + { 0x0688, "Microprocess Ingenierie" }, + { 0x0689, "Elesys Inc." }, + { 0x068A, "Pertech Inc." }, + { 0x068B, "Potrans International, Inc." }, + { 0x068C, "Tokin Corporation, Card Media Systems Department" }, + { 0x068D, "Medical Measurement Systems B.V." }, + { 0x068E, "CH Products" }, + { 0x068F, "Nihon Kohden Corporation" }, + { 0x0690, "Golden Bridge Electech Inc." }, + { 0x0691, "Denter System Co., Ltd." }, + { 0x0692, "Klippel GmbH" }, + { 0x0693, "Hagiwara Solutions Co., Ltd." }, + { 0x0694, "The LEGO Company" }, + { 0x0695, "ODU-USA, Inc." }, + { 0x0696, "Carroll Touch" }, + { 0x0697, "Oxford Instruments (Medical Systems Division)" }, + { 0x0698, "Chuntex (CTX)" }, + { 0x0699, "Tektronix, Inc." }, + { 0x069A, "Askey Computer Corporation" }, + { 0x069B, "Thomson Inc." }, + { 0x069C, "HST High Soft Tech GmbH" }, + { 0x069D, "Hughes Network Systems (HNS)" }, + { 0x069E, "Welcat Inc." }, + { 0x069F, "Tron b.v." }, + { 0x06A0, "USB Systems Design" }, + { 0x06A1, "Alexon Co., Ltd." }, + { 0x06A2, "Topro Technology Inc." }, + { 0x06A3, "MadCatz Europe Ltd." }, + { 0x06A4, "Xiamen Doowell Electron Co., Ltd." }, + { 0x06A5, "Divio" }, + { 0x06A7, "MicroStore, Inc." }, + { 0x06A8, "Topaz Systems, Inc." }, + { 0x06A9, "Westell" }, + { 0x06AA, "Sysgration Ltd." }, + { 0x06AB, "Johnathon Freeman Technologies" }, + { 0x06AC, "Fujitsu Laboratories of America, Inc." }, + { 0x06AD, "Greatland Electronics Taiwan Ltd." }, + { 0x06AE, "Testronic Labs" }, + { 0x06AF, "Harting, Inc. of North America" }, + { 0x06B0, "Alva B.V." }, + { 0x06B1, "Signtech USA, Ltd." }, + { 0x06B2, "N*ABLE Technologies, Inc." }, + { 0x06B3, "Galil Motion Control" }, + { 0x06B4, "Citron GmbH" }, + { 0x06B5, "Stanford Research Systems" }, + { 0x06B6, "Leda Media Products" }, + { 0x06B8, "Pixela Corporation" }, + { 0x06B9, "Thomson Telecom" }, + { 0x06BA, "Smooth Cord & Connector Co., Ltd." }, + { 0x06BB, "EDA Inc." }, + { 0x06BC, "Oki Data Corporation" }, + { 0x06BD, "AGFA-Gevaert NV" }, + { 0x06BE, "AME Optimedia Technology Co. Ltd." }, + { 0x06BF, "Leoco Corporation" }, + { 0x06C0, "AllSpirit Co., Ltd." }, + { 0x06C2, "Microlynx Systems Ltd." }, + { 0x06C3, "Foss Tecator AB" }, + { 0x06C4, "Bizlink Technology, Inc." }, + { 0x06C5, "Hagenuk, GmbH" }, + { 0x06C6, "Infowave Software Inc." }, + { 0x06C7, "Storm Technology Inc." }, + { 0x06C8, "SIIG, Inc." }, + { 0x06C9, "Taxan (Europe) Ltd." }, + { 0x06CA, "Newer Technology, Inc." }, + { 0x06CB, "Synaptics Inc." }, + { 0x06CC, "Terayon Communication Systems" }, + { 0x06CD, "Keyspan" }, + { 0x06CE, "Contec Co., Ltd." }, + { 0x06CF, "Spheron VR- Bonnet und Steuerwald GdbR" }, + { 0x06D0, "LapLink, Inc." }, + { 0x06D1, "Daewoo Electronics Co Ltd" }, + { 0x06D2, "Pioneer Microsystems" }, + { 0x06D3, "Mitsubishi Electric Corporation" }, + { 0x06D4, "Cisco Systems(2)" }, + { 0x06D5, "Toshiba America Electronic Components, Inc." }, + { 0x06D6, "Aashima Technology B.V." }, + { 0x06D7, "Network Computing Devices (NCD)" }, + { 0x06D8, "Technical Marketing Research, Inc." }, + { 0x06D9, "Atmel-TEMIC Semiconductor GmbH" }, + { 0x06DA, "Phoenixtec Power Co., Ltd." }, + { 0x06DB, "Paradyne" }, + { 0x06DC, "Foxlink Image Technology Co., Ltd." }, + { 0x06DD, "Impact Technologies" }, + { 0x06DE, "Heisei Electronics Co. Ltd." }, + { 0x06E0, "Multi-Tech Systems, Inc." }, + { 0x06E1, "ADS Technologies, Inc." }, + { 0x06E2, "Trio Motion Technology Limited" }, + { 0x06E4, "Alcatel Microelectronics" }, + { 0x06E5, "Lusher Technologies" }, + { 0x06E6, "Tiger Jet Network, Inc." }, + { 0x06E7, "Universal Electronics Inc." }, + { 0x06E8, "Braemar Inc." }, + { 0x06E9, "Nippon Electric Industry Co., Ltd." }, + { 0x06EA, "Sirius Technologies Limited" }, + { 0x06EB, "PC Expert Tech. Co., Ltd." }, + { 0x06EC, "ADInstruments Ltd." }, + { 0x06ED, "Datastor Technology" }, + { 0x06EF, "I.A.C. Geometrische Ingenieurs B.V." }, + { 0x06F0, "T.N.C Industrial Co., Ltd." }, + { 0x06F1, "Opcode Systems Inc." }, + { 0x06F2, "Emine Technology Company" }, + { 0x06F3, "Flexion Systems Ltd." }, + { 0x06F4, "First Person Gaming" }, + { 0x06F5, "Midian Production Distribution" }, + { 0x06F6, "Wintrend Technology Co., Ltd." }, + { 0x06F7, "Wish Technologies" }, + { 0x06F8, "Guillemot Corporation" }, + { 0x06F9, "Asyst Electronic" }, + { 0x06FA, "HSD S.r.L" }, + { 0x06FB, "Hitachi Device Engineering Ltd." }, + { 0x06FC, "Motorola Semiconductor Products Sector/US" }, + { 0x06FD, "Boston Acoustics" }, + { 0x06FE, "Gallant Computer, Inc." }, + { 0x06FF, "Mediacom Technologies Pte Ltd." }, + { 0x0701, "Supercomal Wire & Cable SDN. BHD." }, + { 0x0702, "PixStream Incorporated" }, + { 0x0703, "Bvtech Industry Inc." }, + { 0x0704, "Vorum Research Corporation" }, + { 0x0705, "NKK Corporation" }, + { 0x0706, "Ariel Corporation" }, + { 0x0707, "SMC Networks, Inc." }, + { 0x0708, "Putercom Co., Ltd." }, + { 0x0709, "Parthus Technologies" }, + { 0x070A, "Oki Electric Industry Co., Ltd." }, + { 0x070B, "Hasco Int., Inc." }, + { 0x070C, "Titan Electronics Inc." }, + { 0x070D, "Comoss Electronic Co., Ltd." }, + { 0x070E, "Excel Cell Electronic Co., Ltd." }, + { 0x070F, "Oce' -Technologies B.V." }, + { 0x0710, "Connect Tech Inc." }, + { 0x0711, "Magic Control Technology Corp." }, + { 0x0712, "Verity Instruments, Inc." }, + { 0x0713, "Interval Research Corp." }, + { 0x0714, "New Motion International Co., Ltd" }, + { 0x0715, "Liang Tei Co., Ltd." }, + { 0x0716, "Oxus Research S.A." }, + { 0x0717, "ZNK Corporation" }, + { 0x0718, "Imation Corp." }, + { 0x0719, "Tremon Enterprises Co., Ltd." }, + { 0x071A, "FLIR Explosives" }, + { 0x071B, "Domain Technologies, Inc." }, + { 0x071C, "Xionics Document Technologies, Inc." }, + { 0x071D, "Dialogic Corporation" }, + { 0x071E, "Ariston Technologies" }, + { 0x071F, "ARS Technologies Ltd." }, + { 0x0720, "Keyence Corporation" }, + { 0x0721, "HMedia Technology Inc." }, + { 0x0722, "Consero" }, + { 0x0723, "Centillium Communications Corporation" }, + { 0x0724, "Lawson Labs, Inc." }, + { 0x0725, "Applied Precision Inc." }, + { 0x0726, "Vanguard International Semiconductor-America" }, + { 0x0727, "C&H Technologies, Inc." }, + { 0x0728, "Avermedia" }, + { 0x0729, "CY&S Industrial Co., Ltd." }, + { 0x072A, "Luminex Corporation" }, + { 0x072B, "Dnova Corporation" }, + { 0x072C, "OTSO" }, + { 0x072D, "Able Communications, Inc." }, + { 0x072E, "Sunix Co., Ltd." }, + { 0x072F, "Advanced Card Systems Ltd." }, + { 0x0730, "Indus Instruments" }, + { 0x0731, "Susteen, Inc." }, + { 0x0732, "Goldfull Electronics & Telecommunications Corp." }, + { 0x0733, "ViewQuest Technologies, Inc." }, + { 0x0734, "LASAT Communications A/S" }, + { 0x0735, "Asuscom Network, Inc." }, + { 0x0736, "Lorom Industrial Co., Ltd." }, + { 0x0737, "Snap-on Diagnostics" }, + { 0x0738, "Mad Catz, Inc." }, + { 0x0739, "Cue Network Corporation" }, + { 0x073A, "Chaplet Systems, Inc." }, + { 0x073B, "Suncom Technologies" }, + { 0x073C, "Industrial Electronic Engineers, Inc." }, + { 0x073D, "Eutronsec Spa" }, + { 0x073E, "Sigma Itec, Inc." }, + { 0x073F, "Data Electronics (Aust) Pty, Ltd." }, + { 0x0740, "Full Enterprise Corp." }, + { 0x0741, "Momentum US Inc." }, + { 0x0742, "Stollmann EtV GmbH" }, + { 0x0743, "Bonig und Kallenback oHG" }, + { 0x0744, "GMK Electronic Design GmbH" }, + { 0x0745, "Syntech Information Co., Ltd." }, + { 0x0746, "ONKYO Corporation" }, + { 0x0747, "Labway Corporation" }, + { 0x0748, "Strong Man Enterprise Co., Ltd." }, + { 0x0749, "EVer Electronics Corp." }, + { 0x074A, "Ming Fortune Industry Co., Ltd." }, + { 0x074B, "Polestar Tech. Corp." }, + { 0x074C, "C-C-C Group PLC" }, + { 0x074D, "Micronas GmbH" }, + { 0x074E, "Digital Stream Corporation" }, + { 0x074F, "Microflip, Inc" }, + { 0x0750, "Innovative Integration" }, + { 0x0751, "Info Network Systems" }, + { 0x0752, "Non-Standard, TSG" }, + { 0x0753, "Mocom Softeare GmbH & Co. KG" }, + { 0x0754, "SyQuest Technology" }, + { 0x0755, "Aureal Semiconductor" }, + { 0x0756, "RSI Systems" }, + { 0x0757, "Network Technologies, Inc." }, + { 0x0758, "Carl Zeiss Jena GmbH" }, + { 0x0759, "Cellvision Systems, Inc." }, + { 0x075A, "SEL Inc." }, + { 0x075B, "Sophisticated Circuits, Inc." }, + { 0x075C, "Ulan Co., Ltd." }, + { 0x075D, "Microdowell SRL" }, + { 0x075E, "ABIT Corporation" }, + { 0x075F, "CITEL Technologies, Ltd." }, + { 0x0760, "JL Cooper Electronics" }, + { 0x0761, "MasTech, Inc." }, + { 0x0762, "Coretex Corporation" }, + { 0x0763, "M-Audio" }, + { 0x0764, "Cyber Power Systems, Inc." }, + { 0x0765, "X-Rite Incorporated" }, + { 0x0766, "Jess-Link Products Co., Ltd. (JPC)" }, + { 0x0767, "Tokheim Corporation" }, + { 0x0768, "Camtel Technology Corp." }, + { 0x0769, "SURECOM Technology Corp." }, + { 0x076A, "Conceptual Systems" }, + { 0x076B, "HID Global GmbH" }, + { 0x076C, "Partner Tech" }, + { 0x076D, "Denso Corporation" }, + { 0x076E, "Kuan Tech Enterprise Co., Ltd." }, + { 0x076F, "Jhen Vei Electronic Co., Ltd." }, + { 0x0770, "Welch Allyn, Inc - Medical Division" }, + { 0x0771, "MicroCraft" }, + { 0x0772, "TFL LAN, Inc" }, + { 0x0773, "Spital Sangyo Co., Ltd." }, + { 0x0774, "AmTRAN Technology Co., Ltd." }, + { 0x0775, "Longshine Electronics Corp." }, + { 0x0776, "Inalways Corporation" }, + { 0x0777, "Comda Advanced Technology Corporation" }, + { 0x0778, "Volex, Inc." }, + { 0x0779, "Fairchild Semiconductor" }, + { 0x077A, "NIDEC SANKYO CORPORATION" }, + { 0x077B, "Linksys" }, + { 0x077C, "Forward Electronics Co., Ltd." }, + { 0x077D, "Griffin Technology" }, + { 0x077E, "Softing GmbH" }, + { 0x077F, "Well Excellent & Most Corp." }, + { 0x0780, "ORGA Kartensysteme GmbH" }, + { 0x0781, "SanDisk Corporation" }, + { 0x0782, "Trackerball" }, + { 0x0783, "C3PO, S.L." }, + { 0x0784, "Pretec Corporation" }, + { 0x0785, "Willnet Inc." }, + { 0x0786, "Jeil Data Systems Co., Ltd." }, + { 0x0787, "Abera System Corp" }, + { 0x0788, "3Cam Technology, Inc" }, + { 0x0789, "Logitec Corporation" }, + { 0x078A, "Tandy Electronics (China) Ltd." }, + { 0x078B, "Happ Controls" }, + { 0x078C, "CalComp" }, + { 0x078D, "Presto Technologies Inc." }, + { 0x078E, "San Shih Electrical Enterprise Co. Ltd." }, + { 0x078F, "Troy XCD, Inc." }, + { 0x0790, "Pro-Image Manufacturing Co., Ltd" }, + { 0x0791, "Copartner Technology Corporation" }, + { 0x0792, "Axis Communications AB" }, + { 0x0793, "Wha Yu Industrial Co., Ltd." }, + { 0x0794, "ABL Electronics Corporation" }, + { 0x0795, "RealChip Inc." }, + { 0x0796, "Certicom Corp." }, + { 0x0797, "Grandtech Semiconductor Corporation" }, + { 0x0798, "F.J. Tieman BV" }, + { 0x0799, "Boulder Creek Engineering" }, + { 0x079A, "Aptec Instruments" }, + { 0x079B, "Sagem SA" }, + { 0x079C, "Sun Communications Inc." }, + { 0x079D, "Alfadata Computer Corp." }, + { 0x079E, "Tokin Corporation" }, + { 0x079F, "VMETRO asa" }, + { 0x07A0, "Leiderdorp Instruments" }, + { 0x07A1, "Digicom Spa" }, + { 0x07A2, "National Technical Systems" }, + { 0x07A3, "ONNTO Corp." }, + { 0x07A4, "Be Incorporated" }, + { 0x07A5, "Tietech Co., Ltd." }, + { 0x07A6, "Infineon-ADMtek Co., Ltd." }, + { 0x07A7, "Mediatronix BV" }, + { 0x07A8, "Home Office PSDB" }, + { 0x07A9, "Sandmartin Company Ltd." }, + { 0x07AA, "Allied Telesis K.K. corega division" }, + { 0x07AB, "Freecom Technologies" }, + { 0x07AC, "Fortress U&T Ltd." }, + { 0x07AD, "ECO Chemie" }, + { 0x07AE, "C&C Technic Taiwan Co., Ltd." }, + { 0x07AF, "Microtech International, Inc." }, + { 0x07B0, "Billion Electric Co., Ltd" }, + { 0x07B1, "IMP, Inc." }, + { 0x07B2, "Motorola BCS" }, + { 0x07B3, "Plustek, Inc." }, + { 0x07B4, "OLYMPUS CORPORATION" }, + { 0x07B5, "Mega World International Ltd." }, + { 0x07B6, "Marubun Corp." }, + { 0x07B7, "TIME Interconnect Ltd." }, + { 0x07B8, "AboCom Systems, Inc." }, + { 0x07B9, "Reynolds Medical" }, + { 0x07BA, "Accurate Technologies, Inc." }, + { 0x07BB, "Intelogis Inc" }, + { 0x07BC, "Canon Computer Systems, Inc." }, + { 0x07BD, "Webgear Inc." }, + { 0x07BE, "Veridicom" }, + { 0x07BF, "TestQuest, Inc." }, + { 0x07C0, "Code Mercenaries" }, + { 0x07C1, "Keisokugiken Corporation" }, + { 0x07C2, "Varatouch Technology Inc." }, + { 0x07C3, "J-Works, Inc." }, + { 0x07C4, "Datafab Systems Inc." }, + { 0x07C5, "APG Cash Drawer" }, + { 0x07C6, "ShareWave, Inc." }, + { 0x07C7, "Powertech Industrial Co., Ltd." }, + { 0x07C8, "B.U.G., Inc." }, + { 0x07C9, "Allied Telesyn International" }, + { 0x07CA, "AVerMedia Technologies, Inc." }, + { 0x07CB, "Kingmax Technology Inc." }, + { 0x07CC, "Carry Technology Co., Ltd." }, + { 0x07CD, "Hteck Corp." }, + { 0x07CE, "Nidec-Shimpo Corp." }, + { 0x07CF, "Casio Computer Co., Ltd." }, + { 0x07D0, "Dazzle Multimedia" }, + { 0x07D2, "Aptio Products Inc." }, + { 0x07D3, "Cyberdata Corp." }, + { 0x07D4, "Aloka Co., Ltd." }, + { 0x07D5, "Radiant Systems, Inc." }, + { 0x07D6, "MENICX International Co., Ltd." }, + { 0x07D7, "GCC Technologies, Inc." }, + { 0x07D8, "Network Suginami Kokoto" }, + { 0x07D9, "Compuapps" }, + { 0x07DA, "Arasan Chip Systems Inc." }, + { 0x07DB, "Mental Models, Inc." }, + { 0x07DC, "OCTAL-Engenharia de Sistemas S.A." }, + { 0x07DD, "Hampshire Company, Inc." }, + { 0x07DE, "Best Data Products" }, + { 0x07DF, "David Electronics Company, Ltd." }, + { 0x07E0, "NCP Engineering" }, + { 0x07E1, "Acer Netxus Incorporated" }, + { 0x07E2, "Elmeg GmbH & Co., Ltd." }, + { 0x07E3, "Planex Communications, Inc." }, + { 0x07E4, "Movado Enterprise Co., Ltd." }, + { 0x07E5, "QPS, Inc." }, + { 0x07E6, "Allied Cable Corporation" }, + { 0x07E7, "Mirvo Toys, Inc." }, + { 0x07E8, "Labsystems" }, + { 0x07E9, "Sanyo Technosound Co., Ltd." }, + { 0x07EA, "Iwatsu Electric Co., Ltd." }, + { 0x07EB, "Double-H Technology Co., Ltd." }, + { 0x07EC, "Taiyo Electric Wire & Cable Co., Ltd." }, + { 0x07ED, "Precision MicroDynamics, Inc." }, + { 0x07EE, "Logware GmbH" }, + { 0x07EF, "Suite Technology Systems" }, + { 0x07F0, "PS Communications Ltd." }, + { 0x07F1, "Picostar, Inc." }, + { 0x07F2, "BPT Enterprises" }, + { 0x07F3, "L3 Systems" }, + { 0x07F4, "Joritel International B.V." }, + { 0x07F5, "Amiable Technologies, Inc." }, + { 0x07F6, "Circuit Assembly Corp." }, + { 0x07F7, "Century Corporation" }, + { 0x07F8, "Eskape Labs" }, + { 0x07F9, "Dotop Technology, Inc." }, + { 0x07FA, "FHLP" }, + { 0x07FB, "Digi-Tek, Inc." }, + { 0x07FC, "Protec Microsystems" }, + { 0x07FD, "Mark of the Unicorn, Inc." }, + { 0x07FE, "Net Eyes, Inc." }, + { 0x07FF, "Sectra AB" }, + { 0x0800, "Kortex International" }, + { 0x0801, "Mag-Tek" }, + { 0x0802, "Mako Technologies, LLC" }, + { 0x0803, "Zoom Telephonics, Inc." }, + { 0x0804, "Neuron Corporation" }, + { 0x0805, "Iruma Soft Co., Ltd." }, + { 0x0806, "Clinton Electronics Corp." }, + { 0x0807, "SIIX Corporation" }, + { 0x0808, "InfiMed, Inc." }, + { 0x0809, "Genicom LP" }, + { 0x080A, "Evermuch Technology Co., Ltd." }, + { 0x080B, "Cross Match Technologies, Inc." }, + { 0x080C, "Datalogic S.p.A." }, + { 0x080D, "TECO Image Systems Co., Ltd." }, + { 0x080E, "Sound Technology, Inc." }, + { 0x080F, "Deschutes Corporation" }, + { 0x0810, "Personal Communication Systems, Inc." }, + { 0x0811, "Fimet" }, + { 0x0812, "E-Tech, Inc." }, + { 0x0813, "Mattel, Inc." }, + { 0x0814, "EBI Systems, Inc." }, + { 0x0815, "Scintrex" }, + { 0x0816, "ABB Automation Products AB" }, + { 0x0817, "Interzeag Medical Technology" }, + { 0x0818, "NTT Electronics Corporation" }, + { 0x0819, "Syncrosoft GMBH" }, + { 0x081A, "MG Logic Pte Ltd." }, + { 0x081B, "Indigita Corporation" }, + { 0x081C, "MIPSYS" }, + { 0x081D, "VlerZwo Software GbR" }, + { 0x081E, "AlphaSmart, Inc." }, + { 0x081F, "Totsu Engineering, Inc." }, + { 0x0820, "Verax Engineering" }, + { 0x0821, "A.T. Cross" }, + { 0x0822, "REUDO Corporation" }, + { 0x0823, "Tactex Controls, Inc." }, + { 0x0824, "M.S.E. GmbH" }, + { 0x0825, "GC Protronics" }, + { 0x0826, "Data Transit" }, + { 0x0827, "BroadLogic, Inc." }, + { 0x0828, "Sato Corporation" }, + { 0x0829, "DirecTV Broadband" }, + { 0x082A, "Object Co., Ltd." }, + { 0x082B, "TrophyTrex" }, + { 0x082C, "Japan Digital Laboratory Co., Ltd." }, + { 0x082D, "Handspring, Inc." }, + { 0x082E, "Suni Imaging Microsystems, Inc." }, + { 0x082F, "ACACIA" }, + { 0x0830, "Palm Inc." }, + { 0x0831, "Chong Tsi Su Enterprise Co., Ltd" }, + { 0x0832, "Kouwell Electronics Corp." }, + { 0x0833, "Sourcenext Corporation" }, + { 0x0834, "Ciponic Technology Co., Ltd." }, + { 0x0835, "Action Star Enterprise Co., Ltd." }, + { 0x0836, "Evertz Microsystems Ltd." }, + { 0x0837, "Renishaw PLC" }, + { 0x0838, "Precision MicroControl Corporation" }, + { 0x0839, "Samsung Techwin" }, + { 0x083A, "Accton Technology Corporation" }, + { 0x083B, "Dr. Neuhaus Telekommunikation GmbH" }, + { 0x083C, "Jaeger Messtechnik GmbH" }, + { 0x083D, "Nakayo Telecommunication, Inc." }, + { 0x083E, "2-Tel B.V." }, + { 0x083F, "Boca Global, Inc." }, + { 0x0840, "Argosy Research Inc." }, + { 0x0841, "Rioport.com Inc." }, + { 0x0842, "ESA MESSTECHNIK GMBH" }, + { 0x0843, "Mcom As" }, + { 0x0844, "Welland Industrial Co., Ltd." }, + { 0x0845, "EES Technik fur Musik" }, + { 0x0846, "NETGEAR, Inc." }, + { 0x0847, "Interack Communications Inc." }, + { 0x0848, "Accton Technology Co., Ltd." }, + { 0x0849, "SC&T International, Inc." }, + { 0x084A, "Wipro Limited" }, + { 0x084B, "Castlewood Systems" }, + { 0x084C, "The Japan Steel Works, Ltd." }, + { 0x084D, "Minton Optic Industry Co., Ltd." }, + { 0x084E, "KidBoard, Inc. dba KBGear Interactive" }, + { 0x084F, "EMPEG Ltd" }, + { 0x0850, "FastPoint Technologies, Inc." }, + { 0x0851, "Macronix International Co., Ltd." }, + { 0x0852, "CSEM" }, + { 0x0853, "Topre Corporation" }, + { 0x0854, "Active Wire, Inc." }, + { 0x0855, "JMBS Developpements" }, + { 0x0856, "B&B Electronics" }, + { 0x0857, "Gerber Scientific Products, Inc." }, + { 0x0858, "Hitachi Maxell Ltd." }, + { 0x0859, "Minolta Systems Laboratory, Inc." }, + { 0x085A, "Xircom" }, + { 0x085B, "Kurt Manufacturing" }, + { 0x085C, "Color Vision Inc." }, + { 0x085D, "Ambient Technologies, Inc." }, + { 0x085E, "NaftEL Technologies LTD." }, + { 0x085F, "Canberra Industries" }, + { 0x0860, "Momentum Data System" }, + { 0x0861, "Cambridge Research Systems Ltd." }, + { 0x0862, "Teletrol Systems, Inc." }, + { 0x0863, "Filanet Corporation" }, + { 0x0864, "Roper International Ltd." }, + { 0x0865, "MICROLAB" }, + { 0x0866, "PEI Electronics, Inc." }, + { 0x0867, "Data Translation, Inc." }, + { 0x0868, "Electrical Geodesics, Inc." }, + { 0x0869, "Visual Interaction" }, + { 0x086A, "Emagic Soft-und Hardware Gmbh" }, + { 0x086B, "ROHM Co. Ltd." }, + { 0x086C, "DeTeWe" }, + { 0x086D, "ICE Technology" }, + { 0x086E, "System TALKS Inc." }, + { 0x086F, "MEC IMEX INC/HPT" }, + { 0x0870, "Metricom, Inc." }, + { 0x0871, "Merge Technologies Inc." }, + { 0x0872, "Broadxent, Inc." }, + { 0x0873, "Xpeed Inc." }, + { 0x0874, "A-Tec Subsystem, Inc." }, + { 0x0875, "Mecel AB" }, + { 0x0876, "3M Home Health Systems" }, + { 0x0877, "Lew Engineering" }, + { 0x0878, "SYSTEC Computer Gmbh." }, + { 0x0879, "Comtrol Corporation" }, + { 0x087A, "Getemed GmbH" }, + { 0x087B, "Cornerstone Peripherals Technology" }, + { 0x087C, "ADESSO/Kbtek America Inc." }, + { 0x087D, "JATON Corporation" }, + { 0x087E, "Fujitsu Computer Products of America" }, + { 0x087F, "QualCore Logic Inc" }, + { 0x0880, "APT Technologies Inc." }, + { 0x0881, "Sistemas Y Redes Telematicas, Sire S.L." }, + { 0x0882, "Rightec Research" }, + { 0x0883, "Recording Industry Association of America (RIAA)" }, + { 0x0884, "USB Systems" }, + { 0x0885, "Boca Research, Inc." }, + { 0x0887, "Hannstar Electronics Corp." }, + { 0x0889, "Current Works, Inc." }, + { 0x088A, "TechTools" }, + { 0x088B, "MassWorks" }, + { 0x088C, "Swecoin AB" }, + { 0x088D, "Engineering Spirit" }, + { 0x088E, "Pace Anti-Piracy, Inc." }, + { 0x088F, "Husky Computers Limited" }, + { 0x0890, "Consultronics Ltd." }, + { 0x0891, "Drager Medizintechnik Gmbh." }, + { 0x0892, "DioGraphy Inc." }, + { 0x0893, "Bartec" }, + { 0x0894, "TSI Incorporated" }, + { 0x0895, "Kanitech A/S" }, + { 0x0896, "Starseed Enterprises AG" }, + { 0x0897, "Lauterbach GmbH" }, + { 0x0898, "3M Canada" }, + { 0x0899, "Grieshaber & Co. AG" }, + { 0x089A, "Koepruelue Engineering" }, + { 0x089B, "Digital-3, LLC." }, + { 0x089C, "United Technologies Research Cntr." }, + { 0x089D, "Icron Technologies Corporation" }, + { 0x089E, "NST Co., Ltd." }, + { 0x089F, "Primex Aerospace Co." }, + { 0x08A0, "Logic Meca Co., Ltd." }, + { 0x08A1, "Studio Zee" }, + { 0x08A2, "Millennia Systems, Inc." }, + { 0x08A3, "Hyowon Software" }, + { 0x08A4, "YTG Smartech Inc." }, + { 0x08A5, "e9 Inc." }, + { 0x08A6, "Toshiba Tec Corporation" }, + { 0x08A7, "General Cybernetics Inc." }, + { 0x08A8, "Andrea Electronics" }, + { 0x08A9, "CWAV" }, + { 0x08AA, "Kernel Productions, Inc." }, + { 0x08AB, "Innolab Pte. Ltd." }, + { 0x08AC, "Macraigor Systems LLC" }, + { 0x08AD, "Toyota Technical Development Corporation (TTDC)" }, + { 0x08AE, "Macally (Mace Group, Inc.)" }, + { 0x08AF, "Hamilton Co." }, + { 0x08B0, "Metrohm Ltd." }, + { 0x08B1, "High Technology Laboratory s.r.l" }, + { 0x08B2, "BIOTRONIK GmbH & Co." }, + { 0x08B3, "Voice It Worldwide, Inc." }, + { 0x08B4, "Sorenson Communications" }, + { 0x08B5, "Correlator.com" }, + { 0x08B6, "Imagek, Inc." }, + { 0x08B7, "NATSU Corporation Limited" }, + { 0x08B8, "J. Gordon Electronic Design, Inc." }, + { 0x08B9, "RadioShack Corporation" }, + { 0x08BA, "Fujitsu General Limited" }, + { 0x08BB, "Texas Instruments Japan" }, + { 0x08BC, "Dr. G. Schuhfried GmbH" }, + { 0x08BD, "Citizen Watch Co., Ltd." }, + { 0x08BE, "Meilenstein GmbH" }, + { 0x08BF, "Nova Engineering, Inc." }, + { 0x08C0, "Braintronics B.V." }, + { 0x08C1, "Timestep Electronics Ltd." }, + { 0x08C2, "ArgoCraft Co., Ltd." }, + { 0x08C3, "Precise Biometrics" }, + { 0x08C4, "Proxim CBU" }, + { 0x08C5, "Moreton Bay" }, + { 0x08C6, "Scalex Corporation" }, + { 0x08C7, "TAI TWUN ENTERPRISE CO., LTD." }, + { 0x08C8, "2Wire, Inc" }, + { 0x08C9, "Nippon Telegraph and Telephone Corp." }, + { 0x08CA, "AIPTEK International Inc." }, + { 0x08CB, "Cyber Innovate, Inc." }, + { 0x08CC, "ifak system GmbH" }, + { 0x08CD, "Jue Hsun Ind. Corp." }, + { 0x08CE, "Long Well Electronics Corp." }, + { 0x08CF, "Productivity Enhancement Products" }, + { 0x08D0, "Tasco Electronics Co., Inc." }, + { 0x08D1, "Smartbridges Pte. Ltd." }, + { 0x08D2, "Dialog4 System Engineering Gmbh." }, + { 0x08D3, "Virtual Ink" }, + { 0x08D4, "Siemens PC Systeme GmbH" }, + { 0x08D5, "Cambridge Heart, Inc." }, + { 0x08D6, "Itautec Philco S.A." }, + { 0x08D7, "Opticon, Inc." }, + { 0x08D8, "Huntsville Microsystems, Inc." }, + { 0x08D9, "Increment P Corporation" }, + { 0x08DA, "A W Electronics, Inc." }, + { 0x08DB, "IXXAT Automation GmbH" }, + { 0x08DC, "Animo Limited" }, + { 0x08DD, "Billionton Systems, Inc." }, + { 0x08DE, "Touchstone Software" }, + { 0x08DF, "Spyrus Inc." }, + { 0x08E0, "Geodesic Designs, Inc." }, + { 0x08E1, "LSI JAPAN Co., Ltd" }, + { 0x08E2, "Beijing Goldensoft Company Ltd." }, + { 0x08E3, "OLITEC" }, + { 0x08E4, "Pioneer Corporation" }, + { 0x08E5, "LITRONIC" }, + { 0x08E6, "Gemalto SA" }, + { 0x08E7, "PAN-INTERNATIONAL WIRE & CABLE (M) SDN BHD" }, + { 0x08E8, "Integrated Memory Logic" }, + { 0x08E9, "Extended Systems, Inc." }, + { 0x08EA, "Ericsson Inc." }, + { 0x08EB, "Asulab SA" }, + { 0x08EC, "M-Systems Flash Disk Pioneers" }, + { 0x08ED, "Instrumentation Metrics, Inc." }, + { 0x08EE, "CCSI/HESSO" }, + { 0x08EF, "PixelVision" }, + { 0x08F0, "CardScan Inc." }, + { 0x08F1, "CTI Electronics Corporation" }, + { 0x08F2, "Constance Technology Co., Ltd." }, + { 0x08F3, "Wintime Electronics Corp." }, + { 0x08F4, "Telia ProSoft AB" }, + { 0x08F5, "SYSTEC Co., Ltd." }, + { 0x08F6, "Logic 3 International Limited" }, + { 0x08F7, "Vernier Software" }, + { 0x08F8, "Keen Top International Enterprise Co., Ltd." }, + { 0x08F9, "Wipro Technologies" }, + { 0x08FA, "CAERE" }, + { 0x08FB, "Socket Mobile, Inc." }, + { 0x08FC, "Sicon International" }, + { 0x08FD, "Digianswer A/S" }, + { 0x08FE, "GDSYSTEMS" }, + { 0x08FF, "AuthenTec, Inc." }, + { 0x0901, "VST Technologies" }, + { 0x0902, "iDream Technologies Pte Ltd" }, + { 0x0903, "Infolibria" }, + { 0x0904, "Frank Audiodata" }, + { 0x0905, "ISDG" }, + { 0x0906, "FARADAY Technology Corp." }, + { 0x0907, "Addison Technology Europe B.V." }, + { 0x0908, "Siemens Automation & Drives" }, + { 0x0909, "Audio-Technica Corp." }, + { 0x090A, "Trumpion Microelectronics Inc" }, + { 0x090B, "Neurosmith" }, + { 0x090C, "Silicon Motion, Inc. - Taiwan" }, + { 0x090D, "MULTIPORT Computer Vertriebs GmbH" }, + { 0x090E, "Shining Technology, Inc." }, + { 0x090F, "Fujitsu Devices Inc." }, + { 0x0910, "Alation Systems, Inc." }, + { 0x0911, "Philips Speech Processing" }, + { 0x0912, "Voquette, Inc." }, + { 0x0913, "Asante' Technologies, Inc." }, + { 0x0914, "Bally Gaming, Inc." }, + { 0x0915, "GlobespanVirata, Inc." }, + { 0x0916, "DH electronics GmbH" }, + { 0x0917, "SmartDisk Corporation" }, + { 0x0918, "Planet Portal.com" }, + { 0x0919, "Sound Vision Inc." }, + { 0x091A, "Inter-Cable Systems, Inc." }, + { 0x091B, "Raleigh Technology Corporation" }, + { 0x091C, "Bormann EDV + Zubehoer GmbH" }, + { 0x091D, "A. K. Barns Ltd." }, + { 0x091E, "Garmin International" }, + { 0x091F, "U-JIN Mesco Co., Ltd." }, + { 0x0920, "Echelon Corporation" }, + { 0x0921, "GoHubs, inc." }, + { 0x0922, "Dymo Corporation" }, + { 0x0923, "IC Media Corporation" }, + { 0x0924, "Xerox Corporation" }, + { 0x0925, "Lakeview Research" }, + { 0x0926, "Sound Devices, LLC" }, + { 0x0927, "Summus, Ltd." }, + { 0x0928, "Oxford Semiconductor Ltd." }, + { 0x0929, "American Biometric Company" }, + { 0x092A, "Toshiba Information & Industrial Sys. And Services" }, + { 0x092B, "Sena Technologies, Inc." }, + { 0x092C, "Shanghai Bell Company Limited" }, + { 0x092D, "OYO Instruments" }, + { 0x092E, "Markpoint AB" }, + { 0x092F, "Northern Embedded Science" }, + { 0x0930, "Toshiba Corporation" }, + { 0x0931, "Harmonic Data Systems Ltd." }, + { 0x0932, "Crescentec Corporation" }, + { 0x0933, "Quantum Corp." }, + { 0x0934, "Spirent Communications" }, + { 0x0935, "Accurite Technologies, Inc." }, + { 0x0936, "DynamicNakedAudio Inc." }, + { 0x0937, "Scania CV AB" }, + { 0x0938, "Virtual DSP Corporation" }, + { 0x0939, "Lumberg, Inc." }, + { 0x093A, "Pixart Imaging, Inc." }, + { 0x093B, "Plextor LLC" }, + { 0x093C, "Intrepid Control Systems, Inc." }, + { 0x093D, "InnoSync, Inc." }, + { 0x093E, "J.S.T. Mfg. Co., Ltd." }, + { 0x093F, "OLYMPIA Telecom Vertriebs GmbH" }, + { 0x0940, "Japan Storage Battery Co., Ltd." }, + { 0x0941, "Photobit Corporation" }, + { 0x0942, "i2Go.com, LLC" }, + { 0x0943, "HCL Technologies Ltd." }, + { 0x0944, "KORG, Inc." }, + { 0x0945, "PASCO Scientific" }, + { 0x0946, "GEMSTAR TECHOLOGY DEVELOPMENT LIMITED" }, + { 0x0947, "Videonics, Inc." }, + { 0x0948, "Kronauer Music In Digital" }, + { 0x0949, "Hitachi Kokusai Electric Inc." }, + { 0x094A, "Luckytech Technology Co., Ltd" }, + { 0x094B, "Linkup Systems Corporation" }, + { 0x094C, "Metanetics Corporation" }, + { 0x094D, "Cable Television Laboratories" }, + { 0x094E, "Head Acoustics" }, + { 0x094F, "Yano Electric Co., Ltd." }, + { 0x0950, "TechniSat Sateliltenfernsehprodukte Gmbh" }, + { 0x0951, "Kingston Technology Company" }, + { 0x0952, "DCOM Enterprise Co., Ltd." }, + { 0x0953, "PLG" }, + { 0x0954, "RPM Systems Corporation" }, + { 0x0955, "NVIDIA" }, + { 0x0956, "BSquare Corporation" }, + { 0x0957, "Agilent Technologies, Inc." }, + { 0x0958, "BioLink Technologies International, Inc." }, + { 0x0959, "Cologne Chip AG" }, + { 0x095A, "Portsmith" }, + { 0x095B, "Medialogic Corporation" }, + { 0x095C, "K-Tec Electronics" }, + { 0x095D, "Polycom, Inc." }, + { 0x095E, "USB Design Labs" }, + { 0x095F, "TTO Engineering" }, + { 0x0960, "Bcom Electronics, Inc." }, + { 0x0961, "Portatec Corporation" }, + { 0x0962, "SAMx" }, + { 0x0963, "Instrument Solutions" }, + { 0x0964, "Bitran Corporation" }, + { 0x0965, "PAR Technologies, Inc." }, + { 0x0966, "HanGo Electronics Co., Ltd." }, + { 0x0967, "Acer NeWeb Corporation" }, + { 0x0969, "Magellan Corp." }, + { 0x096A, "Koizumi Computer, Inc." }, + { 0x096B, "ML Electronics Ltd." }, + { 0x096C, "GOPEL electronic GmbH" }, + { 0x096D, "PennyLan" }, + { 0x096E, "Feitian New Technology Co." }, + { 0x096F, "Memory Link" }, + { 0x0970, "K.S. Vector Co., Ltd." }, + { 0x0971, "GretagMacbeth AG" }, + { 0x0972, "Musicbird" }, + { 0x0973, "Axalto" }, + { 0x0974, "Eye Communication Systems, Inc" }, + { 0x0975, "OL'E Communications, Inc." }, + { 0x0976, "Adirondack Wire & Cable" }, + { 0x0977, "Lightsurf Technologies" }, + { 0x0978, "Beckhoff Gmbh" }, + { 0x0979, "Jeilin Technology Corp., Ltd." }, + { 0x097A, "Minds At Work LLC" }, + { 0x097B, "Knudsen Engineering Limited" }, + { 0x097C, "Marunix Co., Ltd." }, + { 0x097D, "Rosun Technologies, Inc." }, + { 0x097E, "Biopac Systems Inc." }, + { 0x097F, "Barun Electronics Co. Ltd." }, + { 0x0980, "Posh Mfg. Ltd." }, + { 0x0981, "Oak Technology Ltd." }, + { 0x0982, "Covadis S.A." }, + { 0x0983, "Nissha Printing Co., Ltd." }, + { 0x0984, "Apricorn" }, + { 0x0985, "Cab Produkttechnik" }, + { 0x0986, "Panasonic Electric Works Co., Ltd." }, + { 0x0987, "MicroSpeed Inc" }, + { 0x0988, "Teraoka Seiko Co. Ltd" }, + { 0x0989, "Digitel Co. LTD" }, + { 0x098A, "Neopost" }, + { 0x098B, "Kingtel Telecommunication Corp." }, + { 0x098C, "Vitana Corporation" }, + { 0x098D, "INDesign" }, + { 0x098E, "Integrated Intellectual Property Inc." }, + { 0x098F, "TEXIO CORPORATION" }, + { 0x0990, "General Instrument Corp." }, + { 0x0992, "Bandai Co., Ltd." }, + { 0x0993, "NuvoMedia, Inc." }, + { 0x0994, "Dionex Softron GmbH" }, + { 0x0995, "Simple Jet Technology Co., Ltd." }, + { 0x0996, "Integrated Telecom Express, Inc." }, + { 0x0997, "Xerox Corporation/Non-Networked Products" }, + { 0x0998, "Atech Totalsolution Co., Ltd." }, + { 0x0999, "Ocean Optics, Inc." }, + { 0x099A, "ZIPPY TECHNOLOGY CORP." }, + { 0x099B, "HIROTA SEISAKUSHO LTD." }, + { 0x099C, "Florida Probe, Inc." }, + { 0x099D, "NEC San-ei Instruments, Ltd." }, + { 0x099E, "Trimble" }, + { 0x099F, "Summa N.V." }, + { 0x09A0, "Altec Computersysteme GmbH" }, + { 0x09A1, "ELMO COMPANY, LIMITED" }, + { 0x09A2, "Telemann Co., Ltd." }, + { 0x09A3, "PairGain Technologies" }, + { 0x09A4, "Contech Research, Inc." }, + { 0x09A5, "VCON Telecommunications" }, + { 0x09A6, "Poinchips" }, + { 0x09A7, "Data Transmission Network Corp." }, + { 0x09A8, "Lin Shiung Enterprise Co., Ltd." }, + { 0x09A9, "Smart Card Technologies Co., Ltd." }, + { 0x09AA, "Intersil Corporation" }, + { 0x09AB, "Japan Cash Machine Co., Ltd." }, + { 0x09AC, "DIGIGRAM" }, + { 0x09AD, "The MITRE Corporation" }, + { 0x09AE, "Tripp Lite" }, + { 0x09AF, "G.i.N. mbH" }, + { 0x09B0, "Fargo Electronics, Inc." }, + { 0x09B1, "Ositech Communications Incorporated" }, + { 0x09B2, "Franklin Electronic Publishers" }, + { 0x09B3, "Simplex Solution Inc." }, + { 0x09B4, "MDS Gateways" }, + { 0x09B5, "Celltrix Technology Co., Ltd." }, + { 0x09B6, "SmithMyers Communications Limited" }, + { 0x09B7, "FAIRLIGHT ESP" }, + { 0x09B8, "PhoeniX . Incorporated" }, + { 0x09B9, "CentLand inc." }, + { 0x09BA, "Chumtronix N.V." }, + { 0x09BB, "Eule Industrie- & Datentechnik GmbH & Co. KG" }, + { 0x09BC, "Audivo GmbH" }, + { 0x09BD, "Haptix Creation Pte Ltd" }, + { 0x09BE, "Prosisa Overseas LLC" }, + { 0x09BF, "Auerswald GmbH & Co. KG" }, + { 0x09C0, "Axon Instruments" }, + { 0x09C1, "ARRIS International" }, + { 0x09C2, "NISCA Corporation" }, + { 0x09C3, "ACTIVCARD, INC." }, + { 0x09C4, "ACTiSYS Corporation" }, + { 0x09C5, "Memory Corporation" }, + { 0x09C6, "Inovatec S.p.A." }, + { 0x09C7, "PUBCOMPANY s.r.l." }, + { 0x09C8, "Carrot Systems Inc." }, + { 0x09C9, "U.S. Digital Corp." }, + { 0x09CA, "BMC Messsysteme GmbH" }, + { 0x09CB, "Flir Systems" }, + { 0x09CC, "Workbit Corporation" }, + { 0x09CD, "Psion Connect Ltd." }, + { 0x09CE, "City Electronics Ltd." }, + { 0x09CF, "Electronics Testing Center, Taiwan" }, + { 0x09D1, "NeoMagic Inc." }, + { 0x09D2, "Vreelin Engineering Inc." }, + { 0x09D3, "COM ONE" }, + { 0x09D4, "Asahi Engineering Co., Ltd." }, + { 0x09D5, "DigiTech" }, + { 0x09D6, "Berkeley Varitronics Systems" }, + { 0x09D7, "NovAtel Inc." }, + { 0x09D8, "Elatec Vertriebs GmbH" }, + { 0x09D9, "Jungo" }, + { 0x09DA, "A-FOUR TECH CO., LTD." }, + { 0x09DB, "Measurement Computing Corporation" }, + { 0x09DC, "AIMEX Corporation" }, + { 0x09DD, "Fellowes Inc." }, + { 0x09DE, "ViQuest Technology" }, + { 0x09DF, "Addonics Technologies Corp." }, + { 0x09E0, "Johnson Matthey PLC, Trading as Tracerco" }, + { 0x09E1, "Intellon Corporation" }, + { 0x09E2, "Surface Imaging Systems (S.I.S.)" }, + { 0x09E3, "WIZnet" }, + { 0x09E4, "Unidata" }, + { 0x09E5, "Jo-Dan International, Inc." }, + { 0x09E6, "Silutia, Inc." }, + { 0x09E7, "Real 3D, Inc." }, + { 0x09E8, "AKAI professional M.I. Corp." }, + { 0x09E9, "CHEN-SOURCE INC." }, + { 0x09EA, "ShareCall Technologies" }, + { 0x09EB, "Sonicbox, Inc." }, + { 0x09EC, "COINT Multimedia Systems" }, + { 0x09ED, "Viking Sewing Machines AB" }, + { 0x09EE, "Jesmay Electronics Co., Ltd." }, + { 0x09EF, "XITEL PTY Limited" }, + { 0x09F0, "Perpetual Technologies, LLC" }, + { 0x09F1, "Eshed Robotec" }, + { 0x09F2, "hema Elektronik GmbH" }, + { 0x09F3, "GoFlight, Inc." }, + { 0x09F4, "Microlink Corporation" }, + { 0x09F5, "ARESCOM" }, + { 0x09F6, "RocketChips, Inc." }, + { 0x09F7, "EDU-SCIENCE (H.K.) LIMITED" }, + { 0x09F8, "SoftConnex Technologies, Inc." }, + { 0x09F9, "Bay Associates" }, + { 0x09FA, "Mtek Vision" }, + { 0x09FB, "Altera" }, + { 0x09FC, "Silicon Mountain Design" }, + { 0x09FD, "MM - Manager Memory" }, + { 0x09FE, "Goldteck International Inc." }, + { 0x09FF, "Gain Technology Corp." }, + { 0x0A00, "Liquid Audio" }, + { 0x0A01, "ViA, Inc." }, + { 0x0A02, "DIATECNIC" }, + { 0x0A03, "Globe Wireless, Inc." }, + { 0x0A04, "Star, Inc." }, + { 0x0A05, "University of Kansas" }, + { 0x0A06, "BSQUARE Slicon Valley" }, + { 0x0A07, "Ontrak Control Systems Inc." }, + { 0x0A08, "Lorenz GmbH" }, + { 0x0A09, "Datadesk Technologies Inc." }, + { 0x0A0A, "LIEWENTHAL ELECTRONICS LTD." }, + { 0x0A0B, "Cybex Computer Products Corporation" }, + { 0x0A0C, "MIRAD" }, + { 0x0A0D, "VIPS France" }, + { 0x0A0E, "AGFEO" }, + { 0x0A0F, "Liesegang" }, + { 0x0A10, "Combinova AB" }, + { 0x0A11, "Xentec Incorporated" }, + { 0x0A12, "Cambridge Silicon Radio Ltd." }, + { 0x0A13, "Telebyte Inc." }, + { 0x0A14, "Spacelabs Healthcare" }, + { 0x0A15, "Scalar Corporation" }, + { 0x0A16, "Trek Technology (S) Pte Ltd" }, + { 0x0A17, "HOYA Corporation" }, + { 0x0A18, "Heidelberger Druckmaschinen AG" }, + { 0x0A19, "Hua Geng Technologies Inc." }, + { 0x0A1A, "Astro-Med, Inc." }, + { 0x0A1B, "Wolfvision GmbH" }, + { 0x0A1C, "Micro Systemation AB" }, + { 0x0A1D, "T-Nova Deutsche Telekom Innovationsgesellschaft" }, + { 0x0A1E, "Netcraft (Pty) Ltd." }, + { 0x0A1F, "Tesco Co." }, + { 0x0A20, "SystemBase Co., Ltd." }, + { 0x0A21, "Physio-Control, Inc." }, + { 0x0A22, "Century Semiconductor USA, Inc." }, + { 0x0A23, "NDS Technologies Israel Ltd." }, + { 0x0A24, "Boca Design, Inc." }, + { 0x0A25, "3M Germany" }, + { 0x0A26, "Cyberware" }, + { 0x0A27, "Datacard Group" }, + { 0x0A28, "Ensure Technologies, Inc." }, + { 0x0A29, "Marketcast" }, + { 0x0A2A, "Fortune Electronics & Plastic (International) Ltd." }, + { 0x0A2B, "Muller & Sebastiani Elektronik GmbH" }, + { 0x0A2C, "Ak Modul Bus Computer GmbH" }, + { 0x0A2D, "Advanced Measurement Technology" }, + { 0x0A2E, "ONE-O-ONE iSOLUTIONS" }, + { 0x0A2F, "Prime Systems, Inc." }, + { 0x0A30, "WAW-Tronics" }, + { 0x0A31, "Data System Co., Ltd." }, + { 0x0A32, "Addatel ApS" }, + { 0x0A33, "Intermind Inc." }, + { 0x0A34, "TG3 Electronics, Inc." }, + { 0x0A35, "Radikal Technologies" }, + { 0x0A36, "GS Technical Support Center" }, + { 0x0A37, "Concept Development" }, + { 0x0A38, "I.R.I.S." }, + { 0x0A39, "Gilat Satellite Networks Ltd." }, + { 0x0A3A, "PentaMedia Co., Ltd." }, + { 0x0A3B, "Hitachi Information Technology Co., Ltd." }, + { 0x0A3C, "NTT DoCoMo,Inc." }, + { 0x0A3D, "Varo Vision" }, + { 0x0A3E, "REINHARDT System- und Messelectronic GmbH" }, + { 0x0A3F, "Swissonic AG" }, + { 0x0A40, "PaloDEx Group Oy" }, + { 0x0A41, "SEKONIC corporation" }, + { 0x0A42, "Medtronic Functional Diagnostics" }, + { 0x0A43, "Boca Systems Inc." }, + { 0x0A44, "TurboLinux" }, + { 0x0A45, "Look&Say co., Ltd." }, + { 0x0A46, "Davicom Semiconductor, Inc." }, + { 0x0A47, "Hirose Electric Co., Ltd." }, + { 0x0A48, "I/O Interconnect" }, + { 0x0A4A, "propagamma kommunikation" }, + { 0x0A4B, "Fujitsu Media Devices Limited" }, + { 0x0A4C, "COMPUTEX Co., Ltd." }, + { 0x0A4D, "Evolution Electronics Ltd." }, + { 0x0A4E, "Steinberg Soft-und Hardware GmbH" }, + { 0x0A4F, "Litton Systems Inc." }, + { 0x0A50, "Mimaki Engineering Co., Ltd." }, + { 0x0A51, "Sony Electronics Inc." }, + { 0x0A52, "JEBSEE ELECTRONICS CO., LTD." }, + { 0x0A53, "Portable Peripheral Co., Ltd." }, + { 0x0A54, "Applied Signal Technology, Inc." }, + { 0x0A55, "ThermoQuest Corporation" }, + { 0x0A56, "EAE electronics GmbH" }, + { 0x0A57, "Joachim Koopmann Software" }, + { 0x0A58, "DIGIDENT LTD." }, + { 0x0A59, "Convergence Instruments" }, + { 0x0A5B, "EASICS NV" }, + { 0x0A5C, "Broadcom Corp." }, + { 0x0A5D, "Diatrend Corporation" }, + { 0x0A5E, "Spinnaker Systems Inc." }, + { 0x0A5F, "Eltron Card Printer Products" }, + { 0x0A60, "Future Networks, Inc." }, + { 0x0A61, "DTI sa" }, + { 0x0A62, "MPMan.com, Inc." }, + { 0x0A63, "Prism Media Products Ltd." }, + { 0x0A64, "Padcom Inc." }, + { 0x0A65, "FullAudio, Inc." }, + { 0x0A66, "ClearCube Technology" }, + { 0x0A67, "Medeli Electronics Co, Ltd." }, + { 0x0A68, "COMAIDE Corporation" }, + { 0x0A69, "Chroma ate Inc." }, + { 0x0A6A, "Newcom Inc." }, + { 0x0A6B, "Green House Co., Ltd." }, + { 0x0A6C, "Integrated Circuit Systems Inc." }, + { 0x0A6D, "UPS Manufacturing" }, + { 0x0A6E, "Benwin" }, + { 0x0A6F, "Core Technology, Inc." }, + { 0x0A70, "International Game Technology" }, + { 0x0A71, "VIPColor Technologies USA, Inc." }, + { 0x0A72, "Sanwa Denshi" }, + { 0x0A73, "SYDEC N.V." }, + { 0x0A74, "Adaptive Networks, Inc." }, + { 0x0A75, "Jeol USA, Inc." }, + { 0x0A76, "I-Jam Multi-Media, LLC" }, + { 0x0A77, "Janome Sewing Machine Co., Ltd." }, + { 0x0A78, "GREATSUN" }, + { 0x0A79, "Geocast Network Systems, Inc." }, + { 0x0A7A, "Towitoko AG" }, + { 0x0A7B, "R & D Co., Ltd." }, + { 0x0A7C, "QUANCOM Informationssysteme GmbH" }, + { 0x0A7D, "Intertek NSTL" }, + { 0x0A7E, "Octagon Systems Corporation" }, + { 0x0A7F, "AVerMedia MicroSystems" }, + { 0x0A80, "Rexon Technology Corp., Ltd" }, + { 0x0A81, "CHESEN ELECTRONICS CORP." }, + { 0x0A82, "SYSCAN" }, + { 0x0A83, "NextComm, Inc." }, + { 0x0A84, "Maui Innovative Peripherals" }, + { 0x0A85, "IDEXX LABS" }, + { 0x0A86, "NITGen Co., Ltd." }, + { 0x0A87, "Tucker-Davis Technologies, Inc." }, + { 0x0A88, "PAH-RAN TECH., INC." }, + { 0x0A89, "Active Company" }, + { 0x0A8A, "American Magnetics" }, + { 0x0A8B, "Intelliworxx Inc." }, + { 0x0A8C, "Tecmar" }, + { 0x0A8D, "Picturetel" }, + { 0x0A8E, "Japan Aviation Electronics Industry Ltd. (JAE)" }, + { 0x0A8F, "Young Chang Co. Ltd." }, + { 0x0A90, "Candy Technology Co., Ltd." }, + { 0x0A91, "Globlink Technology Inc." }, + { 0x0A92, "EGO SYStems Inc." }, + { 0x0A93, "C Technologies AB (publ)" }, + { 0x0A94, "Intersense" }, + { 0x0A95, "Origin Instruments Corporation" }, + { 0x0A96, "Evation.com" }, + { 0x0A97, "Guardware Systems Ltd." }, + { 0x0A98, "TECHNO ART CO., LTD" }, + { 0x0A99, "Talon Technology" }, + { 0x0A9A, "Business Navigator" }, + { 0x0A9B, "Input/Output Inc." }, + { 0x0A9C, "Applied Cytometry Systems" }, + { 0x0A9D, "Jung & Dusch GmbH" }, + { 0x0A9E, "Performance Concepts, Inc." }, + { 0x0A9F, "Sim-Addicts Design Group" }, + { 0x0AA0, "Vtech Communications Ltd." }, + { 0x0AA1, "Amer.com" }, + { 0x0AA2, "Delta Tau Data Systems, Inc." }, + { 0x0AA3, "Lava Computer Mfg. Inc." }, + { 0x0AA4, "Develco Elektronik" }, + { 0x0AA5, "First International Digital" }, + { 0x0AA6, "Perception Digital Limited" }, + { 0x0AA7, "Wincor Nixdorf GmbH & Co KG" }, + { 0x0AA8, "TriGem Computer, Inc." }, + { 0x0AA9, "Baromtec Co." }, + { 0x0AAA, "Japan CBM Corporation" }, + { 0x0AAB, "Vision Shape Europe SA." }, + { 0x0AAC, "iCompression Inc." }, + { 0x0AAD, "Rohde & Schwarz GmbH & Co. KG" }, + { 0x0AAE, "NEC infrontia Corporation" }, + { 0x0AAF, "digitalway co., ltd." }, + { 0x0AB0, "Arrow Strong Electronics CO. LTD" }, + { 0x0AB1, "Feig Electronic GmbH" }, + { 0x0AB2, "Sintefex Audio LDA" }, + { 0x0AB3, "CANON FINETECH INC." }, + { 0x0AB4, "esd electronic system design gmbh" }, + { 0x0AB5, "Beckman Coulter, Inc." }, + { 0x0AB6, "Labsystems Oy" }, + { 0x0AB7, "Cross electronics, inc." }, + { 0x0AB8, "TelePhotogenics, Inc." }, + { 0x0AB9, "Identcode Ltd." }, + { 0x0ABA, "University of Geneva" }, + { 0x0ABB, "Travsys BV" }, + { 0x0ABC, "Life-Tech, Inc." }, + { 0x0ABD, "Wako Rubber Industries Co., Ltd." }, + { 0x0ABE, "STEREOLINK.COM" }, + { 0x0ABF, "DeVaSys" }, + { 0x0AC0, "Nidek Co., Ltd." }, + { 0x0AC1, "MicroDatec GmbH" }, + { 0x0AC2, "BrainMaster Technologies, Inc." }, + { 0x0AC3, "SANYO Semiconductor Company Micro" }, + { 0x0AC4, "LECO CORPORATION" }, + { 0x0AC5, "I & C Corporation" }, + { 0x0AC6, "Singing Electrons, Inc." }, + { 0x0AC7, "Panwest Corporation" }, + { 0x0AC8, "Vimicro Corporation" }, + { 0x0AC9, "Micro Solutions, Inc." }, + { 0x0ACA, "The Open Group" }, + { 0x0ACB, "DEICY CORPORATION" }, + { 0x0ACC, "Koga Electronics Co." }, + { 0x0ACD, "ID Tech" }, + { 0x0ACE, "ZyDAS Technology Corporation" }, + { 0x0ACF, "Intoto, Inc." }, + { 0x0AD0, "Intellix Corp." }, + { 0x0AD1, "Remotec Technology Ltd." }, + { 0x0AD2, "Service & Quality Technology Co., Ltd." }, + { 0x0AD3, "Bolton Engineering, Inc." }, + { 0x0AD4, "TIGEREX ENTERPRISE CO., LTD." }, + { 0x0AD5, "kuwatec, Inc." }, + { 0x0AD6, "Vir A/S" }, + { 0x0AD7, "Lynium L.L.C." }, + { 0x0AD8, "Aidonic Corporation" }, + { 0x0AD9, "Avolites Ltd." }, + { 0x0ADA, "Data Encryption Systems Ltd" }, + { 0x0ADB, "T.A.M. Co., Ltd." }, + { 0x0ADC, "KE Knestel Elektronik GmbH" }, + { 0x0ADD, "Alliance Distribution" }, + { 0x0ADE, "Microft Co., Ltd." }, + { 0x0ADF, "Arial Phone L.L.C." }, + { 0x0AE0, "Collins Medical" }, + { 0x0AE1, "Protein Solutions, Inc." }, + { 0x0AE2, "NERA SATCOM ASA" }, + { 0x0AE3, "Allion Test Labs, Inc." }, + { 0x0AE4, "Taito Corporation" }, + { 0x0AE5, "MacroSystem Digital Video AG" }, + { 0x0AE6, "EVI, Inc." }, + { 0x0AE7, "Neodym Systems Inc." }, + { 0x0AE8, "System Support Co., Ltd." }, + { 0x0AE9, "North Shore Circuit Design L.L.P." }, + { 0x0AEA, "SciEssence, LLC" }, + { 0x0AEB, "TTP Communications Ltd." }, + { 0x0AEC, "Neodio Technologies Corporation" }, + { 0x0AED, "ScottCare Corporation" }, + { 0x0AEE, "Max Co., Ltd." }, + { 0x0AEF, "Simple Systems, Ltd." }, + { 0x0AF0, "Option NV" }, + { 0x0AF1, "KYOEI Co., Ltd." }, + { 0x0AF2, "CARTS, LLC" }, + { 0x0AF3, "Scale Master Technology, LLC." }, + { 0x0AF4, "ARTRONICS CO. LTD" }, + { 0x0AF5, "Nakamichi" }, + { 0x0AF6, "SILVER I CO., LTD." }, + { 0x0AF7, "B2C2, Inc." }, + { 0x0AF8, "Taiwan Regular Electronics Co., Ltd." }, + { 0x0AF9, "NEW AFA TECHNOLOGY CO., LTD" }, + { 0x0AFA, "DMC Co., Ltd." }, + { 0x0AFB, "OO-ALC/TISMD-CAPRE" }, + { 0x0AFC, "Zaptronix Ltd" }, + { 0x0AFD, "Tateno Dennou, Inc." }, + { 0x0AFE, "Cummins Engine Company" }, + { 0x0AFF, "Jump Zone Network Products, Inc." }, + { 0x0B00, "INGENICO" }, + { 0x0B01, "Techno-Holon Corporation" }, + { 0x0B02, "Avery Weigh-Tronix" }, + { 0x0B03, "ARCA TECHNOLOGIES, LTD." }, + { 0x0B04, "EURESYS S.A." }, + { 0x0B05, "ASUSTek Computer Inc." }, + { 0x0B06, "Digital Ink, Inc." }, + { 0x0B07, "Telebau GmbH" }, + { 0x0B08, "Lightwell Co., Ltd ZAX Division" }, + { 0x0B09, "Allophonic Electronics L.t.d." }, + { 0x0B0A, "FARO Technologies INC." }, + { 0x0B0B, "Datamax Corporation" }, + { 0x0B0C, "Todos Data System AB" }, + { 0x0B0D, "Project Lab" }, + { 0x0B0E, "GN Netcom" }, + { 0x0B0F, "AVID Technology" }, + { 0x0B10, "Pcally" }, + { 0x0B11, "I Tech Solutions Co., Ltd." }, + { 0x0B12, "T-Metrics, Inc." }, + { 0x0B13, "Practical Micro Design, Inc." }, + { 0x0B14, "Real Sport, Inc." }, + { 0x0B15, "Actia Do Brasil Ind. E. Com. Ltda." }, + { 0x0B16, "onscreen24" }, + { 0x0B17, "Scantron Corporation" }, + { 0x0B18, "Shimizu Works, Hitachi Air Conditioning Systems Co" }, + { 0x0B19, "Color Kinetics Inc." }, + { 0x0B1B, "Bematech Ind. Com. Equip. Elect. S.A." }, + { 0x0B1C, "York Electronics Centre" }, + { 0x0B1D, "Erich Jaeger GmbH" }, + { 0x0B1E, "Electronic Warfare Associates, Inc. (EWA)" }, + { 0x0B1F, "Insyde Software Corp." }, + { 0x0B20, "TransDimension Inc." }, + { 0x0B21, "Yokogawa Electric Corporation" }, + { 0x0B22, "Japan System Development Co. Ltd." }, + { 0x0B23, "Pan-Asia Electronics Co., Ltd." }, + { 0x0B24, "ITX E-Globaledge Corporation" }, + { 0x0B25, "Advanced Programming Concepts, Inc." }, + { 0x0B26, "Applied Scientific Instrumentation Inc." }, + { 0x0B27, "Ritek Corporation" }, + { 0x0B28, "Kenwood Corporation" }, + { 0x0B29, "Intertex Data AB" }, + { 0x0B2A, "Glotrex Co., Ltd." }, + { 0x0B2C, "Village Center, Inc." }, + { 0x0B2D, "Akatsuki Electronic work & study Corp." }, + { 0x0B2E, "CTL Inc." }, + { 0x0B2F, "Clarkspur Design, Inc." }, + { 0x0B30, "NewHeights Software" }, + { 0x0B31, "Kyowa Electronic Instruments Co., Ltd." }, + { 0x0B32, "Utrecht University MBF" }, + { 0x0B33, "Contour Design, Inc." }, + { 0x0B34, "KNP Technologies" }, + { 0x0B35, "Solutions Cubed" }, + { 0x0B36, "Iizuna Signal Processing Lab Inc." }, + { 0x0B37, "Hitachi ULSI Systems Co., Ltd." }, + { 0x0B39, "Omnidirectional Control Technology Inc." }, + { 0x0B3A, "IPaxess" }, + { 0x0B3B, "Bromax Communications, Inc." }, + { 0x0B3C, "Olivetti S.p.A" }, + { 0x0B3E, "Kikusui Electronics Corporation" }, + { 0x0B3F, "Mitec Systems, Inc." }, + { 0x0B40, "RF Solutions Ltd." }, + { 0x0B41, "Hal Corporation" }, + { 0x0B42, "LENZE GmbH & Co KG" }, + { 0x0B43, "Sixth Avenue Designs" }, + { 0x0B44, "Programa Tools, Inc." }, + { 0x0B45, "Event Electronics, LLC" }, + { 0x0B46, "Nuark Co., Ltd." }, + { 0x0B47, "Sportbug.com, Inc" }, + { 0x0B48, "TechnoTrend AG" }, + { 0x0B49, "ASCII Corporation" }, + { 0x0B4A, "Pocket Pyro, Inc." }, + { 0x0B4B, "XFX Creation Inc." }, + { 0x0B4C, "Comvurgent" }, + { 0x0B4D, "Graphtec" }, + { 0x0B4E, "Musical Electronics Ltd." }, + { 0x0B4F, "Neuralog, Inc." }, + { 0x0B50, "Starlight Marketing (H.K.) Ltd." }, + { 0x0B51, "USB KITS" }, + { 0x0B52, "Zight Corporation" }, + { 0x0B54, "Sinbon Electronics Co., Ltd." }, + { 0x0B55, "Sendtek Corporation" }, + { 0x0B56, "TYI Systems Ltd." }, + { 0x0B57, "Hanwang Technology Co. Ltd." }, + { 0x0B59, "Lake Communications Ltd." }, + { 0x0B5A, "Corel Corporation" }, + { 0x0B5B, "Anritsu Corporation" }, + { 0x0B5C, "IDEAL Industries Inc." }, + { 0x0B5D, "Music Playground Inc." }, + { 0x0B5E, "Luciol Instruments" }, + { 0x0B5F, "Green Electronics Co., Ltd." }, + { 0x0B60, "SiConnect Ltd." }, + { 0x0B61, "NEC Display Solutions, Ltd." }, + { 0x0B62, "Orange Micro, Inc." }, + { 0x0B63, "ADLink Technology Inc." }, + { 0x0B64, "Wonderful Wire Cable Co., Ltd" }, + { 0x0B65, "Expert Magnetics Corp." }, + { 0x0B66, "Cybiko Inc." }, + { 0x0B67, "Fairbanks Scales" }, + { 0x0B68, "SenDEC Corporation" }, + { 0x0B69, "CacheVision" }, + { 0x0B6A, "Maxim Integrated Products" }, + { 0x0B6B, "Ashling Microsystems Ltd." }, + { 0x0B6C, "FreeSystems Pte Ltd" }, + { 0x0B6D, "The Graphics Network Limited" }, + { 0x0B6E, "Neurosoft, Inc." }, + { 0x0B6F, "Nagano Japan Radio Co., Ltd" }, + { 0x0B70, "PortalPlayer, Inc." }, + { 0x0B71, "SHIN-EI Sangyo Co., Ltd." }, + { 0x0B72, "Embedded Wireless Technology Co. Ltd." }, + { 0x0B73, "Computone Corp." }, + { 0x0B75, "Roland DG Corporation" }, + { 0x0B76, "Pro-Tech Services Inc." }, + { 0x0B77, "RJS, Inc." }, + { 0x0B78, "ATSKY" }, + { 0x0B79, "Sunrise Telecom, Inc." }, + { 0x0B7A, "Zeevo, Inc." }, + { 0x0B7B, "Taiko Denki Co., Ltd." }, + { 0x0B7C, "ITRAN Communications Ltd." }, + { 0x0B7D, "Astrodesign, Inc." }, + { 0x0B7E, "Kurusugawa Electronics Incorporate" }, + { 0x0B7F, "Scantech BV" }, + { 0x0B80, "Omtronix Engineering Corp." }, + { 0x0B81, "id3 Semiconductors" }, + { 0x0B82, "TravRoute, a division of ALK Associates, Inc." }, + { 0x0B83, "OCTAX Microscience" }, + { 0x0B84, "Rextron Technology, Inc." }, + { 0x0B85, "Elkat Electronics (M) SDN. BHD." }, + { 0x0B86, "Exputer Systems, Inc." }, + { 0x0B87, "Plus-One I & T Inc." }, + { 0x0B88, "Sigma Koki Co., Ltd. Technology Center" }, + { 0x0B89, "Advanced Digital Broadcast Ltd." }, + { 0x0B8A, "YARC Systems Corporation" }, + { 0x0B8B, "American Microsystems, Ltd." }, + { 0x0B8C, "SMART Technologies Inc." }, + { 0x0B8D, "Microsystems Development Technologies, Inc." }, + { 0x0B8E, "Dartcom" }, + { 0x0B8F, "Visual Environment" }, + { 0x0B90, "DACTRON INC." }, + { 0x0B91, "DesignTech International, Inc." }, + { 0x0B92, "SINAR AG" }, + { 0x0B93, "Marantz Japan, Inc." }, + { 0x0B94, "NEOREX Co., Ltd." }, + { 0x0B95, "ASIX Electronics Corporation" }, + { 0x0B96, "SEWON TELECOM" }, + { 0x0B97, "O2Micro, Inc." }, + { 0x0B98, "Playmates Toys Inc." }, + { 0x0B99, "Audio International, Inc." }, + { 0x0B9A, "Namco Limited" }, + { 0x0B9B, "Dipl.-Ing. Stefan Kunde" }, + { 0x0B9C, "Melco Embroidery Systems" }, + { 0x0B9D, "Softprotec Co." }, + { 0x0B9E, "Asylum Research" }, + { 0x0B9F, "Chippo Technologies" }, + { 0x0BA0, "Turtle Industry Co., Ltd." }, + { 0x0BA1, "Jowit Company Limited" }, + { 0x0BA2, "Line Media Research CO., LTD." }, + { 0x0BA3, "Taiko Electric Works, Ltd." }, + { 0x0BA4, "Nagano Oki Electric Co., Ltd." }, + { 0x0BA5, "Clemex Technologies Inc." }, + { 0x0BA6, "3DM Devices Inc" }, + { 0x0BA7, "CVC Networks Co., Ltd." }, + { 0x0BA8, "CastleNet Technology Inc." }, + { 0x0BA9, "Misawa Homes Co., Ltd." }, + { 0x0BAA, "Dr. Gerhard Schmidt GmbH" }, + { 0x0BAB, "House Ear Institute" }, + { 0x0BAC, "Biometric Access Corporation" }, + { 0x0BAD, "Lab-Volt Itee" }, + { 0x0BAE, "IGEN International, Inc." }, + { 0x0BAF, "U.S. Robotics" }, + { 0x0BB0, "Concord Camera Corp." }, + { 0x0BB1, "Infinilink Corporation" }, + { 0x0BB2, "Ambit Microsystems Corporation" }, + { 0x0BB3, "Ofuji Technology" }, + { 0x0BB4, "HTC Corporation" }, + { 0x0BB5, "Murata Manufacturing Co., Ltd." }, + { 0x0BB6, "Network Alchemy" }, + { 0x0BB7, "Joytech Computer Company Limited" }, + { 0x0BB8, "Renesas Technology Sales Co., Ltd." }, + { 0x0BB9, "Eiger M & C CO., LTD." }, + { 0x0BBA, "ZACCESS Systems" }, + { 0x0BBB, "General Meters Corporation" }, + { 0x0BBC, "Assistive Technology, Inc." }, + { 0x0BBD, "System Connection, Inc" }, + { 0x0BBE, "ShibaSoku Co., Ltd." }, + { 0x0BBF, "Algo Communication Products Ltd." }, + { 0x0BC0, "Knilink Technology Inc." }, + { 0x0BC1, "FUW YNG ELECTRONICS COMPANY LTD" }, + { 0x0BC2, "Seagate Technology LLC" }, + { 0x0BC3, "IPWireless, Inc." }, + { 0x0BC4, "Microcube Corp." }, + { 0x0BC5, "JCN Co., Ltd." }, + { 0x0BC6, "ExWAY Inc." }, + { 0x0BC7, "X10 Wireless Technology, Inc." }, + { 0x0BC8, "Telmax Communications" }, + { 0x0BC9, "ECI Telecom Ltd" }, + { 0x0BCA, "Startek Engineering Incorporated" }, + { 0x0BCB, "Perfect Technic Enterprise Co. LTD" }, + { 0x0BCC, "Dolphin Interactive" }, + { 0x0BCD, "Mbeware Inc." }, + { 0x0BCE, "I-TEC hanshin Incorporated Company" }, + { 0x0BCF, "Chuo-Engineering Ltd." }, + { 0x0BD0, "Trenz Electronic" }, + { 0x0BD1, "Blue Sky Labs, Inc." }, + { 0x0BD2, "Union Biometrica" }, + { 0x0BD3, "OPHIR OPTRONICS LTD" }, + { 0x0BD4, "NISSIN INC." }, + { 0x0BD5, "Rabbit House Corporation" }, + { 0x0BD6, "Renaissance Learning Inc." }, + { 0x0BD7, "Andrew Pargeter & Associates" }, + { 0x0BD8, "Gamry Instruments, Inc." }, + { 0x0BD9, "Liberty Instruments, Inc." }, + { 0x0BDA, "Realtek Semiconductor Corp." }, + { 0x0BDB, "Ericsson AB" }, + { 0x0BDC, "Y Media Corporation" }, + { 0x0BDD, "Orange PCS" }, + { 0x0BDE, "Thuris Corporation" }, + { 0x0BDF, "PopcomNet Co., Ltd" }, + { 0x0BE0, "Silicon Magic Co., LTD" }, + { 0x0BE1, "COM DEV Wireless" }, + { 0x0BE2, "Kanda Tsushin Kogyo Co., LTD" }, + { 0x0BE3, "TOYO Corporation" }, + { 0x0BE4, "Elka International Ltd." }, + { 0x0BE5, "DOME Imaging Systems, Inc" }, + { 0x0BE6, "Wonderful Photoelectricity (DongGuan), Co., Ltd." }, + { 0x0BE7, "Zanthic Technologies Inc." }, + { 0x0BE8, "M@inNet Communication" }, + { 0x0BE9, "Realistic Interactive, Inc." }, + { 0x0BEA, "Bryce Office Systems" }, + { 0x0BEB, "RPA Electronics Design, LLC" }, + { 0x0BEC, "Idaho Technology" }, + { 0x0BED, "MEI, Inc." }, + { 0x0BEE, "LTK International Limited" }, + { 0x0BEF, "Way2Call Communications" }, + { 0x0BF0, "Pace Micro Technology PLC" }, + { 0x0BF1, "Intracom S.A." }, + { 0x0BF2, "Konexx" }, + { 0x0BF3, "CTI Co., Ltd." }, + { 0x0BF4, "Kuraya-Sanseido Co., Ltd." }, + { 0x0BF5, "Xactex Corporation" }, + { 0x0BF6, "Addonics Technologies, Inc." }, + { 0x0BF7, "Sunny Giken Inc." }, + { 0x0BF8, "Fujitsu Technology Solutions GmbH" }, + { 0x0BF9, "QPICT, Inc." }, + { 0x0BFA, "NKE Corporation" }, + { 0x0BFB, "Grass Valley Group" }, + { 0x0BFC, "Zero Mass Products Inc." }, + { 0x0BFD, "KVASER AB" }, + { 0x0BFE, "Morphy Planning & Co., Ltd" }, + { 0x0BFF, "Damotech Inc." }, + { 0x0C00, "ATM Computer" }, + { 0x0C01, "K-One Telecom Co., Ltd." }, + { 0x0C02, "Shinko Seisakusho Co., LTD" }, + { 0x0C03, "SAXA Inc." }, + { 0x0C04, "MOTO Development Group, Inc." }, + { 0x0C05, "Appian Graphics" }, + { 0x0C06, "Hasbro, Inc." }, + { 0x0C07, "Infinite Data Storage LTD" }, + { 0x0C08, "ei Corporation" }, + { 0x0C09, "Comjet Information System" }, + { 0x0C0A, "Highpoint Technologies, Inc." }, + { 0x0C0B, "Dura Micro, Inc." }, + { 0x0C0C, "OPTIKON 2000 S.P.A." }, + { 0x0C0D, "Callify Communications & Software Ltd." }, + { 0x0C0E, "Korea eBook Inc." }, + { 0x0C0F, "IDS Innomic GmbH" }, + { 0x0C10, "Silicon Wave" }, + { 0x0C11, "Multigon Industries" }, + { 0x0C12, "Zeroplus Technology Co; LTD" }, + { 0x0C13, "Orion Electronics International" }, + { 0x0C14, "Parallel Technologies, Inc." }, + { 0x0C15, "Iris Graphics" }, + { 0x0C16, "Gyration, Inc." }, + { 0x0C17, "Cyberboard A/S" }, + { 0x0C18, "SynerTek Korea, Inc." }, + { 0x0C19, "cyberPIXIE, Inc." }, + { 0x0C1A, "Silicon Motion, Inc." }, + { 0x0C1B, "MIPS TECHNOLOGIES" }, + { 0x0C1C, "Hang Zhou Silan Microelectronics Co. Ltd" }, + { 0x0C1D, "Digital Audio Corporation" }, + { 0x0C1E, "TAKAYA CORP." }, + { 0x0C1F, "Ultra Electronics Ltd (Ocean Systems)" }, + { 0x0C20, "Viditec Inc." }, + { 0x0C21, "Lunatronic" }, + { 0x0C22, "TallyGenicom LP" }, + { 0x0C23, "Lernout + Hauspie (L + H)" }, + { 0x0C24, "Taiyo Yuden Co., Ltd." }, + { 0x0C25, "Sampo Corporation" }, + { 0x0C26, "Icom Inc." }, + { 0x0C27, "RF Ideas" }, + { 0x0C28, "ICCC" }, + { 0x0C29, "Clairis Technologies" }, + { 0x0C2A, "AFP Imaging Corp." }, + { 0x0C2B, "AT system" }, + { 0x0C2C, "Controller Technologies Corporation" }, + { 0x0C2D, "Scientific Data Systems, Inc." }, + { 0x0C2E, "Honeywell Scanning & Mobility" }, + { 0x0C2F, "Starcover GmbH" }, + { 0x0C30, "MUTOH EUROPE N.V." }, + { 0x0C31, "Cosmo Techs Co., Ltd." }, + { 0x0C32, "Weibel Scientific A/S" }, + { 0x0C33, "GN Otometrics A/S" }, + { 0x0C34, "Interisa Electronica" }, + { 0x0C35, "Eagletron Inc." }, + { 0x0C36, "E INK CORPORATION" }, + { 0x0C37, "e.Digital" }, + { 0x0C38, "Der An Electric Wire & Cable Co. Ltd." }, + { 0x0C39, "Aeroflex" }, + { 0x0C3A, "Furui Precise Component (Kunshan) Co., Ltd" }, + { 0x0C3B, "Komatsu Ltd." }, + { 0x0C3C, "Radius Co., Ltd." }, + { 0x0C3D, "Innocom, Inc." }, + { 0x0C3E, "NEXTCELL INC." }, + { 0x0C3F, "Street Smart Security" }, + { 0x0C40, "Navini Networks, Inc" }, + { 0x0C41, "findtheDOT" }, + { 0x0C42, "OMAX Corporation" }, + { 0x0C43, "BIOMETRIKA" }, + { 0x0C44, "Motorola iDEN" }, + { 0x0C45, "Sonix Technology Co., Ltd." }, + { 0x0C46, "WaveRider Communications, Inc" }, + { 0x0C47, "TECAN Group AG" }, + { 0x0C48, "MARPOSS S.p.A." }, + { 0x0C49, "Gigahertz-Optik GmbH" }, + { 0x0C4A, "ALGE-TIMING GmbH & Co" }, + { 0x0C4B, "REINER Kartengeraete GmbH & Co.KG" }, + { 0x0C4C, "Needham's Electronics Inc" }, + { 0x0C4D, "ICHIRO.ORG" }, + { 0x0C4E, "Sonic Innovations, Inc." }, + { 0x0C4F, "01dB-Stell" }, + { 0x0C50, "Forvus Research Inc." }, + { 0x0C51, "Trax Softworks, Inc." }, + { 0x0C52, "Sealevel Systems, Inc." }, + { 0x0C53, "ViewPLUS Inc." }, + { 0x0C54, "GLORY LTD." }, + { 0x0C55, "Spectrum Digital Inc." }, + { 0x0C56, "Billion Bright Limited" }, + { 0x0C57, "Imaginative Design Operation Co. Ltd." }, + { 0x0C58, "Vidar Systems Corporation" }, + { 0x0C59, "Dong Guan Shinko Wire Co., Ltd." }, + { 0x0C5A, "TRS International Mfg., Inc." }, + { 0x0C5B, "EDEC Co., Ltd." }, + { 0x0C5C, "Obbligato Objectives" }, + { 0x0C5D, "Musitronics GmbH" }, + { 0x0C5E, "Xytronix Research & Design" }, + { 0x0C5F, "WAVESYSTEMS" }, + { 0x0C60, "Apogee Electronics Corporation" }, + { 0x0C61, "Network Security Technology Co." }, + { 0x0C62, "Chant Sincere Co., Ltd" }, + { 0x0C63, "Toko, Inc." }, + { 0x0C64, "Signality System Engineering Co., Ltd." }, + { 0x0C65, "Eminence Enterprise Co., Ltd." }, + { 0x0C66, "REXON ELECTRONICS CORP." }, + { 0x0C67, "Concept Telecom Ltd" }, + { 0x0C68, "Whanam Electronics Co., Ltd." }, + { 0x0C69, "COMPUTechnic AG" }, + { 0x0C6A, "Ackerman Computer Sciences" }, + { 0x0C6B, "Spectrum Techniques, Inc" }, + { 0x0C6C, "JETI Technische Instrumente GmbH" }, + { 0x0C6D, "Aardvark" }, + { 0x0C6E, "Zaxus Limited" }, + { 0x0C6F, "SCC Research" }, + { 0x0C70, "MCT Elektronikladen" }, + { 0x0C71, "Fa. Hydrotechnik" }, + { 0x0C72, "PEAK-System-Technik" }, + { 0x0C73, "Canada Tech" }, + { 0x0C74, "Optronic Laboratories, Inc." }, + { 0x0C75, "Ripmax Plc" }, + { 0x0C76, "Solid State System Co., Ltd." }, + { 0x0C77, "SIPIX GROUP LIMITED" }, + { 0x0C78, "Detto Corporation" }, + { 0x0C79, "NuConnex Technologies PTE LTD" }, + { 0x0C7A, "Wing-Span Enterprise Co., Ltd." }, + { 0x0C7B, "Link Instruments, Inc." }, + { 0x0C7C, "TMS International BV" }, + { 0x0C7E, "KIRK telecom" }, + { 0x0C7F, "SoftBaugh, Inc." }, + { 0x0C80, "Optim Electronics" }, + { 0x0C81, "Dragon State Ltd." }, + { 0x0C82, "Impeccable Instruments, LLC" }, + { 0x0C83, "Cylink" }, + { 0x0C84, "Howell Instruments, Inc." }, + { 0x0C85, "Lectra Systemes" }, + { 0x0C86, "NDA Technologies, Inc." }, + { 0x0C87, "Aubit, Ltd." }, + { 0x0C88, "Kyocera Wireless Inc." }, + { 0x0C89, "Honda Tsushin Kogyo Co., Ltd" }, + { 0x0C8A, "Cast Lighting Limited" }, + { 0x0C8B, "Wavefly Corporation" }, + { 0x0C8C, "Coactive Networks" }, + { 0x0C8D, "Greenlee Textron, Inc." }, + { 0x0C8E, "Cesscom Co., Ltd." }, + { 0x0C8F, "Applied Microsystems" }, + { 0x0C90, "American Arium" }, + { 0x0C91, "FPGA Information" }, + { 0x0C92, "Nixvue Systems PTE LTD" }, + { 0x0C93, "Alara Inc." }, + { 0x0C94, "SAGEM Denmark" }, + { 0x0C95, "Kyushu-Kyohan Co., Ltd." }, + { 0x0C96, "TOPCON Positioning Systems" }, + { 0x0C97, "GRE America, Inc." }, + { 0x0C98, "Berkshire Products, Inc." }, + { 0x0C99, "Innochips Co., Ltd." }, + { 0x0C9A, "Hanool Robotics Corp" }, + { 0x0C9B, "Jobin Yvon, Inc." }, + { 0x0C9C, "Brand Innovators" }, + { 0x0C9D, "Semtek IP Incorporated" }, + { 0x0C9E, "PLEXUS MULTIMEDIA PTE LTD" }, + { 0x0C9F, "Extenex Corporation" }, + { 0x0CA0, "Robert Bosch GmbH - Automotive Aftermarket" }, + { 0x0CA1, "Mentor Engineering, Inc." }, + { 0x0CA2, "Zyfer" }, + { 0x0CA3, "SEGA CORPORATION" }, + { 0x0CA4, "ST&T INSTRUMENT CORP." }, + { 0x0CA5, "BAE SYSTEMS CANADA INC." }, + { 0x0CA6, "Castles Technology Co. Ltd." }, + { 0x0CA7, "Information Systems Laboratories" }, + { 0x0CA8, "Digital Audio Labs, Inc." }, + { 0x0CA9, "Institut fuer Rundfunktechnik" }, + { 0x0CAA, "Allied Telesis K.K." }, + { 0x0CAB, "Melon Technos Co., Ltd." }, + { 0x0CAC, "NEC Electronics (Europe) GmbH" }, + { 0x0CAD, "Motorola Solutions" }, + { 0x0CAE, "swissvoice ag" }, + { 0x0CAF, "Buslink" }, + { 0x0CB0, "Flying Pig Systems" }, + { 0x0CB1, "Innovonics, Inc." }, + { 0x0CB2, "Softmark" }, + { 0x0CB3, "FitzSimons Automation" }, + { 0x0CB4, "PalmMicro Communications, Inc." }, + { 0x0CB5, "Esel International Company Ltd." }, + { 0x0CB6, "Celestix Networks PTE LTD" }, + { 0x0CB7, "Singatron Enterprise Co. Ltd." }, + { 0x0CB8, "Opticis Co., Ltd." }, + { 0x0CB9, "VTECH INFORMATIONS LTD." }, + { 0x0CBA, "Trust Electronic (Shanghai) Co., Ltd." }, + { 0x0CBB, "Shanghai Darong Electronics Co., Ltd." }, + { 0x0CBC, "PALMAX Technology Co., Ltd." }, + { 0x0CBD, "Pentel Co., Ltd. (Electronics Equipment Div.)" }, + { 0x0CBE, "Keryx Technologies, Inc." }, + { 0x0CBF, "Union Genius Computer Co., Ltd" }, + { 0x0CC0, "Kuon Yi Industrial Corp." }, + { 0x0CC2, "Timex Corporation" }, + { 0x0CC3, "Rimage Corporation" }, + { 0x0CC4, "emsys Embedded Systems GmbH" }, + { 0x0CC5, "SENDO" }, + { 0x0CC6, "INTERMAGIC CORP." }, + { 0x0CC7, "Kontron Medical AG" }, + { 0x0CC8, "Technotools Corporation" }, + { 0x0CC9, "BroadMAX Technologies, Inc." }, + { 0x0CCA, "AMPHENOL" }, + { 0x0CCB, "SKNET CORPORATION LTD." }, + { 0x0CCC, "DOMEX TECHNOLOGY CORPORATION" }, + { 0x0CCD, "TerraTec Electronic GmbH" }, + { 0x0CCE, "Optical Imaging Inc." }, + { 0x0CCF, "T&D CORPORATION" }, + { 0x0CD0, "Art Haven 9 Co., Ltd" }, + { 0x0CD1, "Premier Technologies, Inc." }, + { 0x0CD2, "C-MAP SRL" }, + { 0x0CD3, "Pretorian Manufacturing Ltd" }, + { 0x0CD4, "Amplex" }, + { 0x0CD5, "Colorado Circuitworks, Inc." }, + { 0x0CD6, "Scheldt & Bachmann GmbH" }, + { 0x0CD7, "NEWCHIP S.r.l." }, + { 0x0CD8, "JS Digitech, Inc." }, + { 0x0CD9, "Shin Din Cable Ltd." }, + { 0x0CDA, "INTERFACE K.K." }, + { 0x0CDB, "OSMOOZE S.A." }, + { 0x0CDC, "HIJI HIGH-TECH CO., LTD." }, + { 0x0CDD, "Fidelica Microsystems, Inc." }, + { 0x0CDE, "Z-Com INC." }, + { 0x0CDF, "BUZZ-VC" }, + { 0x0CE0, "ZAPEX Research Ltd." }, + { 0x0CE1, "Pepperoni Light" }, + { 0x0CE2, "Eltech Solutions Inc." }, + { 0x0CE3, "MaxVision Corporation" }, + { 0x0CE4, "JOOHONG" }, + { 0x0CE5, "Hemisphere West" }, + { 0x0CE6, "First Silicon Solutions, Inc." }, + { 0x0CE7, "Bakker IT Services BV" }, + { 0x0CE8, "Interflex Datensysteme GmbH" }, + { 0x0CE9, "Pico Technology Limited" }, + { 0x0CEA, "PRO TECH COMMUNICATIONS INC." }, + { 0x0CEB, "Sophia Systems Co., Ltd." }, + { 0x0CEC, "Cyverse Corp." }, + { 0x0CED, "MAYCOM Audio Systems b.v." }, + { 0x0CEE, "Gaitmat II" }, + { 0x0CEF, "Contex A/S" }, + { 0x0CF0, "Cadac Electronics plc." }, + { 0x0CF1, "e-CONN ELECTRONIC CO., LTD." }, + { 0x0CF2, "ENE Technology Inc." }, + { 0x0CF3, "Qualcomm Atheros, Inc." }, + { 0x0CF4, "Fomtex Corporation" }, + { 0x0CF5, "Cellink Co., Ltd." }, + { 0x0CF6, "Compucable Corporation" }, + { 0x0CF7, "ishoni Networks" }, + { 0x0CF8, "Clarisys Incorporated" }, + { 0x0CF9, "Central System Research Co., Ltd." }, + { 0x0CFA, "Inviso, Inc." }, + { 0x0CFB, "SEnergy Corporation" }, + { 0x0CFC, "Konica-Minolta" }, + { 0x0CFD, "Hitex UK Ltd." }, + { 0x0CFE, "L.J. Technical Systems Ltd." }, + { 0x0CFF, "SAFA MEDIA CO., LTD." }, + { 0x0D00, "Polar Instruments Ltd" }, + { 0x0D01, "Red Bird LLC" }, + { 0x0D02, "Vestibular Technolgies" }, + { 0x0D03, "Triad Spectrum Ltd." }, + { 0x0D04, "Addmaster Corporation" }, + { 0x0D05, "Chung Nam Electronics Co. Ltd." }, + { 0x0D06, "telos EDV Systementwicklung GmbH" }, + { 0x0D07, "TAUREUS s.r.o." }, + { 0x0D08, "UTStarcom (Hangzhou) Telecom Co., Ltd" }, + { 0x0D09, "MMELECTRONICS" }, + { 0x0D0A, "Colourfull Creations" }, + { 0x0D0B, "Contemporary Controls" }, + { 0x0D0C, "Astron Electronics Co., Ltd." }, + { 0x0D0D, "MKNet Corporation" }, + { 0x0D0E, "Hybrid Networks, Inc" }, + { 0x0D0F, "Feng Shin Cable Co. Ltd." }, + { 0x0D10, "Elastic Networks" }, + { 0x0D11, "Maspro Denkoh Corp." }, + { 0x0D12, "Hansol Electronics Inc." }, + { 0x0D13, "BMF CORPORATION" }, + { 0x0D14, "Array Comm, Inc." }, + { 0x0D15, "OnStream b.v." }, + { 0x0D16, "Hi-Touch Imaging Technologies Co., Ltd." }, + { 0x0D17, "NALTEC, Inc." }, + { 0x0D18, "coaXmedia" }, + { 0x0D19, "Shanghai Hank Connection Co., Ltd." }, + { 0x0D1A, "COMTECH SYSTEMS, INC" }, + { 0x0D1B, "EC Engineering, LLC" }, + { 0x0D1C, "MACSEMA, INC" }, + { 0x0D1D, "GEMAC mbH" }, + { 0x0D1E, "Eone Inc." }, + { 0x0D1F, "imc MessSysteme GmbH" }, + { 0x0D20, "Malcom Co., Ltd." }, + { 0x0D22, "Rojone Pty Ltd" }, + { 0x0D23, "SATAKE USA INC." }, + { 0x0D24, "Trapper Data AB" }, + { 0x0D25, "PENTTECH Engineering Systems AB" }, + { 0x0D26, "Micro-Vu" }, + { 0x0D27, "CLEARJET GmbH" }, + { 0x0D28, "ARM Ltd" }, + { 0x0D29, "Eng Resource Inc" }, + { 0x0D2A, "FIELDSERVER TECHNOLOGIES" }, + { 0x0D2B, "DAINIPPON SCREEN" }, + { 0x0D2C, "3M Library Systems" }, + { 0x0D2D, "GigaSysNet" }, + { 0x0D2E, "Feedback Instruments Ltd" }, + { 0x0D2F, "Andamiro Co., Ltd." }, + { 0x0D30, "Vision Electronics Co., Ltd." }, + { 0x0D31, "Arizona Cooperative Power" }, + { 0x0D32, "Leo Hui Electric Wire & Cable Co., Ltd." }, + { 0x0D33, "AirSpeak Inc." }, + { 0x0D34, "Moxi Digital, Inc." }, + { 0x0D35, "Dah Kun Co., Ltd." }, + { 0x0D36, "Tellabs" }, + { 0x0D37, "PRISM" }, + { 0x0D38, "Nihon Culture-soft Service Co., Ltd." }, + { 0x0D3A, "Posiflex Technologies, Inc." }, + { 0x0D3B, "SANYO TECNICA Co., Ltd." }, + { 0x0D3C, "SRI CABLE TECHNOLOGY LTD." }, + { 0x0D3D, "TANGTOP TECHNOLOGY CO., LTD." }, + { 0x0D3E, "Fitcom, inc." }, + { 0x0D3F, "MTS Systems Corporation" }, + { 0x0D40, "Ascor Inc." }, + { 0x0D41, "Ta Yun Electronic Technology Co., Ltd." }, + { 0x0D42, "FULL DER CO., LTD." }, + { 0x0D43, "iCableSystem Co., Ltd." }, + { 0x0D44, "AFG Elektronik GmbH" }, + { 0x0D45, "Union Data Corporation" }, + { 0x0D46, "KOBIL Systems GmbH" }, + { 0x0D47, "KOPEK PACIFIC LTD." }, + { 0x0D48, "PROMETHEAN" }, + { 0x0D49, "Maxtor" }, + { 0x0D4A, "NF Corporation" }, + { 0x0D4B, "Grape Systems Inc." }, + { 0x0D4C, "TEDAS AG" }, + { 0x0D4D, "Coherent Inc." }, + { 0x0D4E, "Agere Systems Netherland BV" }, + { 0x0D4F, "EADS AIRBUS FRANCE" }, + { 0x0D50, "Cleware GmbH" }, + { 0x0D51, "Volex (Asia) Pte Ltd" }, + { 0x0D52, "YAMAHA Motor Co., Ltd" }, + { 0x0D53, "HMI Co., Ltd." }, + { 0x0D54, "HOLON Corporation" }, + { 0x0D55, "ASKA Technologies Inc." }, + { 0x0D56, "AVLAB Technology, Inc." }, + { 0x0D57, "SOLOMON Microtech Ltd." }, + { 0x0D59, "CDS electronics bv" }, + { 0x0D5A, "Hoshino Metal Industries, Ltd." }, + { 0x0D5B, "LOGIC CORPORATION" }, + { 0x0D5C, "Eumitcom Technology Inc." }, + { 0x0D5D, "Telesis Technologies, Inc." }, + { 0x0D5E, "MYACOM LTD" }, + { 0x0D5F, "CSI, Inc." }, + { 0x0D60, "IVL Technologies Ltd." }, + { 0x0D61, "MEILU ELECTRONICS (SHENZHEN) CO., LTD." }, + { 0x0D62, "Darfon Electronics Corp." }, + { 0x0D63, "Fritz Gegauf AG" }, + { 0x0D64, "DXG Technology Corp." }, + { 0x0D65, "KMJP CO., LTD." }, + { 0x0D66, "TMT" }, + { 0x0D67, "Advanet Inc." }, + { 0x0D68, "Super Link Electronics Co., Ltd." }, + { 0x0D69, "NSI" }, + { 0x0D6A, "eMegaTech International Corp." }, + { 0x0D6B, "And-Or Logic" }, + { 0x0D6C, "CANMAX Technology Ltd." }, + { 0x0D6D, "Mitsubishi Elec. Micro-Computer App. Software Co." }, + { 0x0D6E, "Forum Trading Ltd. (UK)" }, + { 0x0D70, "Try Computer Co. LTD." }, + { 0x0D71, "Hirakawa Hewtech Corp." }, + { 0x0D72, "Winmate Communication Inc." }, + { 0x0D73, "Hit's Communications INC." }, + { 0x0D74, "Dreams Come True Co., Ltd." }, + { 0x0D75, "LET'S Corporation, Ltd." }, + { 0x0D76, "MFP Korea, Inc." }, + { 0x0D77, "Power Sentry/Newpoint" }, + { 0x0D78, "Japan Distributor Corporation" }, + { 0x0D79, "Assistive Technology Engineering Lab" }, + { 0x0D7A, "MARX CryptoTech LP" }, + { 0x0D7B, "Wellco Technology Co., Ltd." }, + { 0x0D7C, "Taiwan Line Tek Electronic Co., Ltd." }, + { 0x0D7D, "Add-On Technology Co., Ltd." }, + { 0x0D7E, "American Computer & Digital Components" }, + { 0x0D7F, "Essential Reality LLC" }, + { 0x0D80, "H.R. Silvine Electronics Inc." }, + { 0x0D81, "TechnoVision" }, + { 0x0D83, "Think Outside, Inc." }, + { 0x0D84, "ELECTRO-SYSTEM Co., Ltd." }, + { 0x0D85, "Identix Incorporated" }, + { 0x0D86, "Marconi" }, + { 0x0D87, "Dolby Laboratories Inc." }, + { 0x0D88, "Miyoshi Corp." }, + { 0x0D89, "Oz Software" }, + { 0x0D8A, "KING JIM CO., LTD." }, + { 0x0D8B, "Ascom Telecommunications Ltd." }, + { 0x0D8C, "C-MEDIA ELECTRONICS INC." }, + { 0x0D8D, "Promotion & Display Technology Ltd." }, + { 0x0D8E, "Global Sun Technology Inc." }, + { 0x0D8F, "Pitney Bowes" }, + { 0x0D90, "Sure-Fire Electrical Corporation" }, + { 0x0D91, "ALPHA PROJECT Co., Ltd." }, + { 0x0D92, "Mega & Game" }, + { 0x0D93, "Nishitomo Co., Ltd." }, + { 0x0D94, "Advanced Logic Technology (ALT)" }, + { 0x0D95, "Numonics Corp." }, + { 0x0D96, "Skanhex Technology Inc." }, + { 0x0D97, "Santa Barbara Instrument Group (SBIG)" }, + { 0x0D98, "Mars Semiconductor Corp." }, + { 0x0D99, "Trazer Technologies Inc." }, + { 0x0D9A, "RTX Telecom A/S" }, + { 0x0D9B, "Tat Shing Electrical Co." }, + { 0x0D9C, "Chee Chen Hi-Technology Co., Ltd." }, + { 0x0D9D, "Sanwa Supply Inc" }, + { 0x0D9E, "Avaya" }, + { 0x0D9F, "Powercom Co., Ltd." }, + { 0x0DA0, "Danger Research" }, + { 0x0DA1, "Suzhou Peter's Precise Industrial Co., Ltd." }, + { 0x0DA2, "Land Instruments International Ltd." }, + { 0x0DA3, "Nippon Electro-Sensory Devices Corporation" }, + { 0x0DA4, "POLAR ELECTRO OY" }, + { 0x0DA5, "TOKYO MAGNETIC PRINTING CO., LTD." }, + { 0x0DA6, "Aimtron Technology Corp." }, + { 0x0DA7, "IOGEAR, Inc." }, + { 0x0DA8, "softDSP Co., Ltd." }, + { 0x0DA9, "DigiLife Technology Inc." }, + { 0x0DAA, "Derelek" }, + { 0x0DAB, "Diasonic Technology Co., Ltd." }, + { 0x0DAC, "Smart Card Technology, Inc." }, + { 0x0DAD, "Westover Scientific" }, + { 0x0DAE, "SERIAL SYSTEM LTD" }, + { 0x0DAF, "NXTV, Inc." }, + { 0x0DB0, "Micro-Star International Co., Ltd." }, + { 0x0DB1, "Wen Te Electronics Co., Ltd." }, + { 0x0DB2, "Shian Hwi Plug Parts, Plastic Factory" }, + { 0x0DB3, "Tekram Technology Co. Ltd." }, + { 0x0DB4, "Chung Fu Chen Yeh Enterprise Corporation" }, + { 0x0DB5, "Azio Ltd." }, + { 0x0DB6, "SIMS Valley Co., Ltd." }, + { 0x0DB7, "ELCON Systemtechnik GmbH" }, + { 0x0DB8, "Garear Taiwan Co., Ltd." }, + { 0x0DB9, "EMKAY" }, + { 0x0DBA, "DIGIDESIGN" }, + { 0x0DBB, "Luna Analytics, Inc." }, + { 0x0DBC, "A&D Company, Limited" }, + { 0x0DBD, "Bruker Biospin" }, + { 0x0DBE, "Jiuh Shiuh Precision Industry Co., Ltd." }, + { 0x0DBF, "Jess-Link International" }, + { 0x0DC0, "G7 Solutions" }, + { 0x0DC1, "Tamagawa Seiki Co., Ltd." }, + { 0x0DC3, "Athena Smartcard Solutions Inc." }, + { 0x0DC4, "inXtron, Inc." }, + { 0x0DC5, "SDK Co, Ltd." }, + { 0x0DC6, "Precision Squared Technology Corporation" }, + { 0x0DC7, "First Cable Line, Inc." }, + { 0x0DC8, "WINTEC Corporation" }, + { 0x0DC9, "Arvel Corp." }, + { 0x0DCA, "SMaL Camera Technologies, Inc." }, + { 0x0DCB, "RocketPod, Inc." }, + { 0x0DCC, "Largan Digital" }, + { 0x0DCD, "NetworkFab Corporation" }, + { 0x0DCE, "E-MU Systems, Inc., d.b.a. E-MU/ENSONIQ" }, + { 0x0DCF, "Analytik Jena AG" }, + { 0x0DD0, "Access Solutions" }, + { 0x0DD1, "Contek Electronics Co., Ltd." }, + { 0x0DD2, "Power Quotient International Co., Ltd." }, + { 0x0DD3, "MediaQ" }, + { 0x0DD4, "Custom Engineering SPA" }, + { 0x0DD5, "California Micro Devices" }, + { 0x0DD6, "TECHKON GmbH" }, + { 0x0DD7, "KOCOM CO., LTD" }, + { 0x0DD8, "Netac Technology Co., Ltd." }, + { 0x0DD9, "HighSpeed Surfing" }, + { 0x0DDA, "Integrated Silicon Solution, Inc" }, + { 0x0DDB, "Tamarack Inc." }, + { 0x0DDC, "Takaotec" }, + { 0x0DDD, "Datelink Technology Co., Ltd." }, + { 0x0DDE, "UBICOM, INC" }, + { 0x0DDF, "DriveCam Video Systems" }, + { 0x0DE1, "Vidicode Datacommunicatie BV" }, + { 0x0DE2, "Acom Data" }, + { 0x0DE3, "RFTECH CO., LTD." }, + { 0x0DE4, "Aron Digital Inc." }, + { 0x0DE5, "Secure2Net, Inc. USA" }, + { 0x0DE6, "Dentsply Int'l - Gendex Dental Division" }, + { 0x0DE7, "USBmicro" }, + { 0x0DE8, "Delsy Electronic Components AG" }, + { 0x0DE9, "Technische Industrie TACX BV" }, + { 0x0DEA, "UTECH Electronic (D.G.) Co., Ltd." }, + { 0x0DEB, "Lean Horn Co." }, + { 0x0DEC, "Callserve Communications Ltd." }, + { 0x0DED, "Novasonics" }, + { 0x0DEE, "Lifetime Memory Products" }, + { 0x0DEF, "Full Rise Electronic Co., Ltd." }, + { 0x0DF0, "GE Yokogawa Medical Systems, Ltd." }, + { 0x0DF1, "Envoy Medical Corporation" }, + { 0x0DF2, "Nisshin Electronics Co., Ltd." }, + { 0x0DF3, "VeriTek Co., Ltd." }, + { 0x0DF4, "Net & Sys Co., Ltd." }, + { 0x0DF5, "Yamatake Corporation" }, + { 0x0DF6, "Sitecom Europe B.V." }, + { 0x0DF7, "Mobile Action Technology Inc." }, + { 0x0DF8, "Hoya Computer Co., Ltd." }, + { 0x0DF9, "Nice Fountain Industrial Co., Ltd." }, + { 0x0DFA, "Toyo Networks & System Integration Co., Ltd." }, + { 0x0DFB, "Daisy Technology" }, + { 0x0DFC, "General Touch Technology Co., Ltd." }, + { 0x0DFD, "Suruga Seiki Co., Ltd." }, + { 0x0DFE, "Interactive Metronome" }, + { 0x0DFF, "Deodeo Corporation" }, + { 0x0E00, "Novar GmbH" }, + { 0x0E01, "Sheng Xiang Investment Ltd." }, + { 0x0E02, "Doowon Co., LTD" }, + { 0x0E03, "Nippon Systemware Co., Ltd." }, + { 0x0E04, "PowerCom Technology Co., Ltd." }, + { 0x0E05, "Nordic ID" }, + { 0x0E06, "Personal Telecom, Inc." }, + { 0x0E07, "Viewtek Co., Ltd" }, + { 0x0E08, "Winbest Technology Co., Ltd." }, + { 0x0E09, "Winskon Cabling Specialist Co., Ltd." }, + { 0x0E0A, "JAEIK Information & Communication Co., Ltd." }, + { 0x0E0B, "Fujitsu Denso Ltd." }, + { 0x0E0C, "Gesytec GmbH" }, + { 0x0E0D, "Picoquant GmbH" }, + { 0x0E0E, "Fuji Data System Co., Ltd." }, + { 0x0E0F, "VMWare, Inc." }, + { 0x0E10, "TERUMO Corporation (Suruga Factory)" }, + { 0x0E11, "Neurotec" }, + { 0x0E12, "Danam Communications Inc." }, + { 0x0E13, "Lugh Networks, Inc." }, + { 0x0E14, "Hunter Engineering Co." }, + { 0x0E15, "Tellert Elektronik GmbH" }, + { 0x0E16, "JMTEK, LLC" }, + { 0x0E17, "Walex Electronic Ltd." }, + { 0x0E18, "UNIWIDE Technologies" }, + { 0x0E19, "OeRSTED, Inc." }, + { 0x0E1A, "RDM Corporation" }, + { 0x0E1B, "Crewave Co., Ltd." }, + { 0x0E1C, "Beijing Hi-tech Wealth Software Technology Co." }, + { 0x0E1D, "International Parts & Information Co., Ltd." }, + { 0x0E1E, "Green Hills Software, Inc." }, + { 0x0E1F, "Cabin Industrial Co., Ltd." }, + { 0x0E20, "Pegasus Technologies Ltd." }, + { 0x0E21, "Cowon Systems, Inc." }, + { 0x0E22, "Symbian Ltd." }, + { 0x0E23, "Liou Yuane International Ltd." }, + { 0x0E24, "Samson Electric Wire Co., Ltd." }, + { 0x0E25, "VinChip Systems, Inc." }, + { 0x0E26, "J-Phone East Co., Ltd." }, + { 0x0E27, "Thunder Island Limited" }, + { 0x0E28, "Industrial Control Systems" }, + { 0x0E29, "CB Sciences, Inc." }, + { 0x0E2A, "Flight Link Inc." }, + { 0x0E2B, "Kumamoto Techno Corporation" }, + { 0x0E2C, "Intersoft Electronics N.V." }, + { 0x0E2D, "SKF Condition Monitoring" }, + { 0x0E2E, "Brady Corporation" }, + { 0x0E2F, "Daisen Electronic Industrial Co., Ltd." }, + { 0x0E30, "HeartMath LLC" }, + { 0x0E31, "Biosign" }, + { 0x0E32, "ICONAG - Intelligent Control AG" }, + { 0x0E33, "Luna Innovations, Inc." }, + { 0x0E34, "Micro Computer Control Corp." }, + { 0x0E35, "3Pea Technologies, Inc." }, + { 0x0E36, "TiePie engineering" }, + { 0x0E37, "Alpha Data Corp." }, + { 0x0E38, "Stratitec, Inc." }, + { 0x0E39, "Smart Modular Technologies, Inc." }, + { 0x0E3A, "Neostar Technology Co., Ltd." }, + { 0x0E3B, "Mansella Ltd." }, + { 0x0E3C, "Raytec Electronic Co., Ltd." }, + { 0x0E3D, "Metex Corporation" }, + { 0x0E3E, "Good Technology, Inc." }, + { 0x0E3F, "AM Group Corp." }, + { 0x0E40, "Proteq LTDA" }, + { 0x0E41, "Line 6" }, + { 0x0E42, "Puretek Industrial Co., Ltd." }, + { 0x0E43, "Holly Lin International Technology Inc." }, + { 0x0E44, "Sun-Riseful Technology Co., Ltd." }, + { 0x0E45, "SafeNet B.V." }, + { 0x0E46, "Delphi Corporation" }, + { 0x0E47, "AMANO Corporation" }, + { 0x0E48, "Julia Corporation Limited" }, + { 0x0E49, "Ingenieurbuero Chanda AG" }, + { 0x0E4A, "Shenzhen Bao Hing Electric Wire & Cable Mfr. Co." }, + { 0x0E4B, "System General Corp." }, + { 0x0E4C, "Radica Games Ltd." }, + { 0x0E4D, "Hong Shi Precision Corp." }, + { 0x0E4E, "Lih Duo Intl. Co., Ltd." }, + { 0x0E4F, "Data Ray Corp." }, + { 0x0E50, "TDi GmbH TechnoData Interware" }, + { 0x0E51, "Therapy Information & Communication System Inc." }, + { 0x0E52, "Mindready Solutions (NI) Ltd." }, + { 0x0E53, "King Tester Corporation" }, + { 0x0E54, "KDE, Inc." }, + { 0x0E55, "Speed Dragon Multimedia Ltd." }, + { 0x0E56, "Cenix Digicom Co., Ltd." }, + { 0x0E57, "Loas Co., Ltd" }, + { 0x0E58, "Technology For Energy Corp." }, + { 0x0E59, "Bourns, Inc." }, + { 0x0E5A, "ACTIVE CO., LTD." }, + { 0x0E5B, "Union Power Information Industrial Co., Ltd." }, + { 0x0E5C, "Shenzhen Bitland Information Technology Co., Ltd." }, + { 0x0E5D, "Neltron Industrial Co., Ltd." }, + { 0x0E5E, "Conwise Technology Co., Ltd." }, + { 0x0E5F, "Entone Technologies" }, + { 0x0E60, "XAVi Technologies Corp." }, + { 0x0E61, "E-Pen InMotion Inc." }, + { 0x0E62, "Shandong CVIC Software Engineering Co., Ltd." }, + { 0x0E63, "SECUREPIA Inc." }, + { 0x0E64, "Nida Corporation" }, + { 0x0E65, "Skycom Tek Co., Ltd" }, + { 0x0E66, "Hawking Technologies, Inc." }, + { 0x0E67, "Fossil" }, + { 0x0E68, "Artec" }, + { 0x0E69, "A Global Partner Corporation" }, + { 0x0E6A, "Megawin Technology Co., Ltd." }, + { 0x0E6B, "DMA Korea Co., Ltd" }, + { 0x0E6C, "E & D Co., Ltd." }, + { 0x0E6D, "Tenovis Business Communication" }, + { 0x0E6E, "Volvo Car Corporation" }, + { 0x0E6F, "Electro Source, LLC" }, + { 0x0E70, "Tokyo Electronic Industry Co, LTD." }, + { 0x0E71, "Schwarzer GmbH" }, + { 0x0E72, "Hsi-Chin Electronics Co., Ltd." }, + { 0x0E73, "MCK Communications, Inc." }, + { 0x0E74, "Accu-Automation Corp." }, + { 0x0E75, "TVS Electronics Limited" }, + { 0x0E76, "Seiko S-Yard Co., Ltd" }, + { 0x0E77, "Weinzierl Engineering GmbH" }, + { 0x0E78, "Ascom Powerline Communications Ltd." }, + { 0x0E79, "ARCHOS SA" }, + { 0x0E7A, "Indocomp Systems Inc." }, + { 0x0E7B, "On-Tech Industry Co., Ltd." }, + { 0x0E7C, "Legend Holdings Limited" }, + { 0x0E7D, "Eutectics Inc." }, + { 0x0E7E, "G.Mate, Inc." }, + { 0x0E7F, "Molecular Imaging" }, + { 0x0E80, "GateHouse A/S" }, + { 0x0E81, "System Consultants Co., Ltd." }, + { 0x0E82, "Ching Tai Electric Wire & Cable Co., Ltd." }, + { 0x0E83, "Shin An Wire & Cable Co." }, + { 0x0E84, "Elelux International Ltd." }, + { 0x0E85, "Dynavox Systems LLC" }, + { 0x0E86, "Watthour Engineering Co., Inc." }, + { 0x0E87, "Internet Security Co., Ltd" }, + { 0x0E88, "ELBIO" }, + { 0x0E89, "PRT Manufacturing Ltd." }, + { 0x0E8A, "FinePoint Innovations, Inc." }, + { 0x0E8B, "KAO SHIN PRECISION INDUSTRY CO., LTD." }, + { 0x0E8C, "Well Force Electronic Co., Ltd" }, + { 0x0E8D, "MediaTek Inc." }, + { 0x0E8E, "Stuart Tyrrell Developments" }, + { 0x0E8F, "Pansignal Technology Inc." }, + { 0x0E90, "WiebeTech LLC" }, + { 0x0E91, "VTech Engineering Canada Ltd." }, + { 0x0E92, "C'S GLORY ENTERPRISE CO., LTD." }, + { 0x0E93, "eM Technics Co., Ltd." }, + { 0x0E94, "Sirona Dental Systems GmbH" }, + { 0x0E95, "Future Technology Co., Ltd" }, + { 0x0E96, "APLUX Communications Ltd." }, + { 0x0E97, "Fingerworks, Inc." }, + { 0x0E98, "Advanced Analogic Technologies, Inc." }, + { 0x0E99, "Parallel Dice Co., Ltd." }, + { 0x0E9A, "TA HSING INDUSTRIES LTD." }, + { 0x0E9B, "ADTEC CORPORATION" }, + { 0x0E9C, "StreamZap, Inc." }, + { 0x0E9D, "Hitron Technologies, Inc." }, + { 0x0E9E, "Japan System Design Co." }, + { 0x0E9F, "TAMURA CORPORATION" }, + { 0x0EA0, "Ours Technology Inc." }, + { 0x0EA1, "Infinite Communication Terminals Ltd." }, + { 0x0EA2, "Triumph Technology Corp." }, + { 0x0EA3, "Rion Co., Ltd." }, + { 0x0EA4, "Intelligent Hearing Systems" }, + { 0x0EA5, "DATA SYSTEM TECHNOLOGY CO., LTD." }, + { 0x0EA6, "Nihon Computer Co., Ltd." }, + { 0x0EA7, "MSL Enterprises Corp." }, + { 0x0EA8, "CenDyne, Inc." }, + { 0x0EA9, "J&J ENGINEERING INC." }, + { 0x0EAA, "TOKYO SOKKI KENKYUJO CO., LTD." }, + { 0x0EAB, "Yiso Telecom" }, + { 0x0EAC, "ALCATech GmbH" }, + { 0x0EAD, "HUMAX Co., Ltd." }, + { 0x0EAE, "Alcon Labs" }, + { 0x0EAF, "Grandex International Corporation" }, + { 0x0EB0, "Amigo Technology Co., Ltd." }, + { 0x0EB1, "WIS Technologies, Inc." }, + { 0x0EB2, "Y-S ELECTRONIC CO., LTD." }, + { 0x0EB3, "Saint Technology Corp." }, + { 0x0EB4, "IPLAN Inc." }, + { 0x0EB5, "@pos.com" }, + { 0x0EB6, "GAMEPARK, Inc." }, + { 0x0EB7, "Endor AG" }, + { 0x0EB8, "Mettler-Toledo (Albstadt) GmbH" }, + { 0x0EB9, "SKY Electronics" }, + { 0x0EBA, "iWOW Connections Pte Ltd" }, + { 0x0EBB, "Thermo Nicolet Corp." }, + { 0x0EBC, "CHOIS Technology" }, + { 0x0EBD, "Kyowa Electronics Co., Ltd." }, + { 0x0EBE, "VWEB Corporation" }, + { 0x0EBF, "Omega Technology Inc." }, + { 0x0EC0, "LHI Technology (China) Co., Ltd." }, + { 0x0EC1, "ABIT Computer Corporation" }, + { 0x0EC2, "Sweetray Industrial Ltd." }, + { 0x0EC3, "Axell Corporation" }, + { 0x0EC4, "Ballracing Developments Ltd." }, + { 0x0EC5, "GT Information System Co., Ltd." }, + { 0x0EC6, "InnoVISION Multimedia Limited" }, + { 0x0EC7, "Theta Link Corporation" }, + { 0x0EC8, "Mitechno Co., Ltd." }, + { 0x0EC9, "HemoCue AB" }, + { 0x0ECA, "Mit System Co., Ltd." }, + { 0x0ECB, "Harman Kardon" }, + { 0x0ECC, "Samsung SDS" }, + { 0x0ECD, "Lite-On IT Corp." }, + { 0x0ECE, "TaiSol Electronics Co., Ltd." }, + { 0x0ECF, "Phogenix Imaging, LLC" }, + { 0x0ED0, "LANergy Limited" }, + { 0x0ED1, "Tai Guen Enterprise Co., Ltd." }, + { 0x0ED2, "Kyoto Micro Computer Co., LTD." }, + { 0x0ED3, "Wing-Tech Enterprise Co., Ltd." }, + { 0x0ED4, "Ross Video" }, + { 0x0ED5, "ChronoLogic Pty. Ltd." }, + { 0x0ED6, "TECHNOS JAPAN Co., LTD." }, + { 0x0ED7, "COSMODOG, LTD." }, + { 0x0ED8, "ASAHI SPECTRA CO., LTD." }, + { 0x0ED9, "Holy Stone Enterprise Co., Ltd." }, + { 0x0EDA, "NORITAKE ITRON CORPORATION" }, + { 0x0EDB, "AboveTech, Inc." }, + { 0x0EDC, "GALTRONICS" }, + { 0x0EDD, "KOWA COMPANY, LTD." }, + { 0x0EDE, "TOD Co., Ltd." }, + { 0x0EDF, "e-MDT Co., Ltd." }, + { 0x0EE0, "SHIMA SEIKI MFG., LTD." }, + { 0x0EE1, "Sarotech Co., Ltd." }, + { 0x0EE2, "AMI Semiconductor Inc." }, + { 0x0EE3, "ComTrue Technology Corporation (Taiwan)" }, + { 0x0EE4, "Sunrich Technology (H.K.) Ltd." }, + { 0x0EE5, "Medical Graphics Corporation" }, + { 0x0EE6, "Takacom Corporation" }, + { 0x0EE7, "Furuno Electric Co., Ltd." }, + { 0x0EE8, "Triz Communications Group" }, + { 0x0EE9, "JPK Systems Limited" }, + { 0x0EEA, "William Demant Holding A/S" }, + { 0x0EEB, "Design Of Systems On Silicon, S.A. (DS2)" }, + { 0x0EEC, "Tritek Co., Ltd." }, + { 0x0EED, "CCP Co., Ltd." }, + { 0x0EEE, "Digital STREAM Technology, Inc." }, + { 0x0EEF, "eGalax Inc." }, + { 0x0EF0, "Hitachi Cable, Ltd." }, + { 0x0EF1, "Aichi Micro Intelligent Corporation" }, + { 0x0EF2, "I/OMAGIC CORPORATION" }, + { 0x0EF3, "Lynn Products, Inc." }, + { 0x0EF4, "DSI Datotech" }, + { 0x0EF5, "PointChips" }, + { 0x0EF6, "Yield Microelectronics Corp." }, + { 0x0EF7, "SM Tech Co., Ltd." }, + { 0x0EF8, "ECT Inc." }, + { 0x0EF9, "eHome TV, Inc. DBA Fuze3 Technologies" }, + { 0x0EFA, "Corepro Entertainment" }, + { 0x0EFB, "ARKRAY, Inc." }, + { 0x0EFC, "ELMEX COMPANY Ltd." }, + { 0x0EFD, "Oasis Semiconductor" }, + { 0x0EFE, "WEM TECHNOLOGY INC." }, + { 0x0EFF, "CSIRO-TIP" }, + { 0x0F00, "ndd Medizintechnik AG" }, + { 0x0F01, "EXPAN Electronics Co., Ltd." }, + { 0x0F02, "MobileAria" }, + { 0x0F03, "Jet Power Technology Co., Ltd." }, + { 0x0F04, "Softlok International Limited" }, + { 0x0F05, "Quanta Network Systems Inc." }, + { 0x0F06, "Visual Frontier Precision Corp." }, + { 0x0F07, "Pakon" }, + { 0x0F08, "CSL Wire & Plug (Shen Zhen) Company" }, + { 0x0F09, "Sandel Arionics Inc." }, + { 0x0F0B, "Great Computer Corporation" }, + { 0x0F0C, "CAS Corporation" }, + { 0x0F0D, "HORI CO., LTD." }, + { 0x0F0E, "Energyfull & Hi-Top International Ltd." }, + { 0x0F0F, "NANOPTIX INC." }, + { 0x0F10, "Personal Information Systems Co., Ltd." }, + { 0x0F11, "Leybold Didactic GMBH" }, + { 0x0F12, "MARS ENGINEERING CORPORATION" }, + { 0x0F13, "Acetek Technology Co., Ltd." }, + { 0x0F14, "XIRING" }, + { 0x0F15, "PlayMore Corporation" }, + { 0x0F16, "GLOBAL VIEW CO. LTD." }, + { 0x0F17, "Correlant Communications" }, + { 0x0F18, "Finger Lakes Instrumentation, LLC" }, + { 0x0F19, "ORACOM CO., Ltd." }, + { 0x0F1A, "General Information Systems Ltd." }, + { 0x0F1B, "Onset Computer Corporation" }, + { 0x0F1C, "Funai Electric Co., Ltd." }, + { 0x0F1D, "Iwill Corporation" }, + { 0x0F1E, "INVAIR Technologies AG" }, + { 0x0F1F, "Laxtha" }, + { 0x0F20, "GENNUM CORPORATION" }, + { 0x0F21, "IOI Technology Corporation" }, + { 0x0F22, "SENIOR INDUSTRIES, INC." }, + { 0x0F23, "Leader Tech Manufacturer Co., Ltd" }, + { 0x0F24, "FLEX-P INDUSTRIES SDN.BHD." }, + { 0x0F25, "Primera Technology Inc." }, + { 0x0F26, "B.G. Technologies, Inc." }, + { 0x0F27, "Alpes DEIS" }, + { 0x0F28, "ESEC SA" }, + { 0x0F29, "TIPTEL AG" }, + { 0x0F2A, "Marconi Data Systems" }, + { 0x0F2B, "XEMICS SA" }, + { 0x0F2D, "ViPower, Inc." }, + { 0x0F2E, "Good Man Corporation" }, + { 0x0F2F, "Priva Design Services" }, + { 0x0F30, "Jess Technology Co., Ltd." }, + { 0x0F31, "Chrysalis Development" }, + { 0x0F32, "YFC-BonEagle Electric Co., Ltd." }, + { 0x0F33, "Futek Electronics, Co., Ltd." }, + { 0x0F34, "Hokuto Denshi Co., Ltd." }, + { 0x0F35, "Kinpo Electronics, Inc." }, + { 0x0F36, "Philips Medical Systems Ultrasound" }, + { 0x0F37, "Kokuyo Co., Ltd." }, + { 0x0F38, "Nien-Yi Industrial Corp." }, + { 0x0F39, "Heng Yu Technology (HK) Ltd." }, + { 0x0F3A, "Aidensi Giken" }, + { 0x0F3B, "IR-LINK" }, + { 0x0F3C, "Numesa, Inc." }, + { 0x0F3D, "AirPrime Inc." }, + { 0x0F3E, "Aastra Broadband" }, + { 0x0F3F, "FEI Electron Optics B.V." }, + { 0x0F40, "Denver Instrument Company" }, + { 0x0F41, "RDC Semiconductor Co., Ltd." }, + { 0x0F42, "Nital Consulting Services, Inc." }, + { 0x0F43, "LiteON Semiconductor Corp." }, + { 0x0F44, "Polhemus Incorporated" }, + { 0x0F45, "International Road Dynamics" }, + { 0x0F46, "KIHOKU Electronic Co., Ltd." }, + { 0x0F47, "SN Systems Ltd." }, + { 0x0F48, "Durand Interstellar, Inc." }, + { 0x0F49, "Evolis" }, + { 0x0F4A, "Planmeca Oy" }, + { 0x0F4B, "St. John Technology Co., Ltd." }, + { 0x0F4C, "WORLDWIDE CABLE OPTO CORP." }, + { 0x0F4D, "Microtune, Inc." }, + { 0x0F4E, "Freedom Scientific" }, + { 0x0F4F, "INVENTEL" }, + { 0x0F50, "LeadingSpect Corporation" }, + { 0x0F51, "Zeta Broadband Inc." }, + { 0x0F52, "Wing Kei Electrical Production Ltd." }, + { 0x0F53, "Taiyo Cable (Dongguan) Co. Ltd." }, + { 0x0F54, "Kawai Musical Instruments Mfg. Co., Ltd." }, + { 0x0F55, "AmbiCom, Inc." }, + { 0x0F56, "SecureTech Corp." }, + { 0x0F57, "WavePlus Tech. Co., Ltd." }, + { 0x0F58, "JASCO Corporation" }, + { 0x0F59, "NCI/Newcomb Company, Inc." }, + { 0x0F5A, "Cogency Semiconductor Inc." }, + { 0x0F5B, "Ritech International Ltd." }, + { 0x0F5C, "PRAIRIECOMM, INC." }, + { 0x0F5D, "NewAge International, LLC" }, + { 0x0F5E, "LEADER ELECTRONICS CORP." }, + { 0x0F5F, "Key Technology Corporation" }, + { 0x0F60, "GuangZhou Chief Tech Electronic Technology Co. Ltd." }, + { 0x0F61, "Varian Inc." }, + { 0x0F62, "Acrox Technologies Co., Ltd." }, + { 0x0F63, "Leapfrog Enterprises" }, + { 0x0F64, "ZAE Research, Inc." }, + { 0x0F65, "Dataflex Design Communications Limited" }, + { 0x0F66, "Productivity Solutions Inc." }, + { 0x0F67, "Quantum3D, Inc." }, + { 0x0F68, "TEPCO UQUEST, LTD." }, + { 0x0F69, "DIONEX CORPORATION" }, + { 0x0F6A, "Vibren Technologies Inc." }, + { 0x0F6B, "OHM ELECTRIC CO., LTD." }, + { 0x0F6C, "DnC Tech., Inc." }, + { 0x0F6D, "WillPoD Co., Ltd." }, + { 0x0F6E, "INTELLIGENT SYSTEMS CO., LTD." }, + { 0x0F6F, "Samtec GmbH" }, + { 0x0F70, "YOZAN Inc." }, + { 0x0F71, "Systems Integration Solutions Inc." }, + { 0x0F72, "Robert Bosch GmbH CS-AS/EMT" }, + { 0x0F73, "DFI" }, + { 0x0F74, "KOSUGI GIKEN Co, Ltd." }, + { 0x0F75, "Future Internet" }, + { 0x0F76, "Vacon Plc" }, + { 0x0F77, "Fasstech" }, + { 0x0F78, "Guntermann & Drunck GmbH" }, + { 0x0F79, "Transonic Systems, Inc." }, + { 0x0F7A, "EE Tools, Inc." }, + { 0x0F7B, "Hivertec Inc." }, + { 0x0F7C, "DQ Technology, Inc." }, + { 0x0F7D, "NetBotz, Inc." }, + { 0x0F7E, "Fluke" }, + { 0x0F7F, "Lansmont Corporation" }, + { 0x0F80, "OCULUS Optikgeraete GmbH" }, + { 0x0F81, "DP Computers Pte. Ltd." }, + { 0x0F82, "IMedia Semiconductor Corporation" }, + { 0x0F83, "Ernst Reiner GmbH & Co. KG" }, + { 0x0F84, "A.E.B. S.R.L." }, + { 0x0F85, "IDX Company, Ltd." }, + { 0x0F86, "Cedar Audio Limited" }, + { 0x0F87, "HUMANDATA LTD." }, + { 0x0F88, "VTech Holdings Ltd." }, + { 0x0F89, "Leading Edge Co., Ltd." }, + { 0x0F8A, "Centro De Tecnologia de las Comunicaciones, S.A." }, + { 0x0F8B, "Yazaki Corporation" }, + { 0x0F8C, "Young Generation International Corp." }, + { 0x0F8D, "Uniwill Computer Corp." }, + { 0x0F8E, "Kingnet Technology Co., Ltd." }, + { 0x0F8F, "SOMA NETWORKS" }, + { 0x0F90, "Quad Engineering Solutions LLC" }, + { 0x0F91, "UNIPULSE Corporation" }, + { 0x0F92, "JASTEC CO., LTD." }, + { 0x0F93, "Sondex Limited" }, + { 0x0F94, "FALCOM GmbH" }, + { 0x0F95, "TOKYO SOKUSHIN CO., LTD." }, + { 0x0F96, "NEC-Mitsubishi Electric Visual Systems Corp." }, + { 0x0F97, "CviLux Corporation" }, + { 0x0F98, "CYBERBANK CORP." }, + { 0x0F99, "Biopia Co., Ltd." }, + { 0x0F9A, "Sistel S.R.L." }, + { 0x0F9B, "G-Card Technology Co., Ltd." }, + { 0x0F9C, "HYUN WON INC." }, + { 0x0F9D, "Opteon Corporation" }, + { 0x0F9E, "Lucent Technologies" }, + { 0x0F9F, "Racewood Technology Co., Ltd." }, + { 0x0FA0, "TRITTON TECHNOLOGIES" }, + { 0x0FA1, "AIJI System Co., Ltd." }, + { 0x0FA2, "TAG Systems Racing Products, Inc." }, + { 0x0FA3, "STARCONN Electronic Co., Ltd." }, + { 0x0FA4, "ATL Technology" }, + { 0x0FA5, "SOTEC CO., LTD." }, + { 0x0FA6, "CMD AG" }, + { 0x0FA7, "EPOX COMPUTER CO., LTD." }, + { 0x0FA8, "Logic Controls, Inc." }, + { 0x0FA9, "Shenzhen Motion Control Technology Co., Ltd." }, + { 0x0FAA, "Changrime Telecom Co., Ltd." }, + { 0x0FAB, "ISZ" }, + { 0x0FAC, "Current Stone Co., Ltd." }, + { 0x0FAD, "Ultravision Ltd." }, + { 0x0FAE, "Redsun Technology Corp." }, + { 0x0FAF, "Winpoint Electronic Corp." }, + { 0x0FB0, "Haurtian Wire & Cable Co., Ltd." }, + { 0x0FB1, "SuperGate Technologies" }, + { 0x0FB2, "Conteck Co., Ltd." }, + { 0x0FB3, "SYMAGERY MICROSYSTEMS INC." }, + { 0x0FB4, "Smiths Detection" }, + { 0x0FB5, "NIHON DENJI SOKKI CO., LTD." }, + { 0x0FB6, "Heber Ltd." }, + { 0x0FB7, "East Press Co., Ltd." }, + { 0x0FB8, "Wistron Corporation" }, + { 0x0FB9, "AACOM CORPORATION" }, + { 0x0FBA, "SAN SHING ELECTRONICS CO., LTD.." }, + { 0x0FBB, "Bitwise Systems, Inc." }, + { 0x0FBC, "Schick Technologies" }, + { 0x0FBD, "Siblings Investment Inc. (dba vantecusa)" }, + { 0x0FBE, "Applied Diabetes Research, Inc." }, + { 0x0FBF, "Certifiable Innovations" }, + { 0x0FC0, "NUDIAN ELECTRON CO., LTD." }, + { 0x0FC1, "MITAC INTERNATIONAL CORP." }, + { 0x0FC2, "PLUG AND JACK INDUSTRIAL INC." }, + { 0x0FC3, "BRAINTREE COMMUNICATIONS" }, + { 0x0FC4, "Yamato Electric Industry Co., Ltd." }, + { 0x0FC5, "Delcom Engineering" }, + { 0x0FC6, "Dataplus Supplies, Inc." }, + { 0x0FC7, "BES Technology Group" }, + { 0x0FC8, "Phoenix Co., Ltd." }, + { 0x0FC9, "Tecom Co., Ltd." }, + { 0x0FCA, "Research in Motion Ltd." }, + { 0x0FCB, "Suzuken Co., Ltd." }, + { 0x0FCC, "Marushin-Denshi Co., Ltd." }, + { 0x0FCD, "Centurion, Inc." }, + { 0x0FCE, "Sony Ericsson Mobile Communications AB" }, + { 0x0FCF, "Dynastream Innovations Inc." }, + { 0x0FD0, "2L international B.V." }, + { 0x0FD1, "Giant Electronics Ltd." }, + { 0x0FD2, "SEAC BANCHE S.P.A." }, + { 0x0FD3, "Marconi Applied Technologies Ltd." }, + { 0x0FD4, "Tenovis GmbH & Co., KG" }, + { 0x0FD5, "Direct Access Technology, Inc." }, + { 0x0FD6, "Mexmal Mayorista S.A. de C.V." }, + { 0x0FD7, "Jeulin S.A." }, + { 0x0FD8, "LARSEN & BRUSGAARD" }, + { 0x0FD9, "El Gato Software LLC" }, + { 0x0FDA, "Quantec Networks GmbH" }, + { 0x0FDB, "Comtech EF Data" }, + { 0x0FDC, "Micro Plus" }, + { 0x0FDD, "Yuyama Mfg. Co., Ltd." }, + { 0x0FDE, "IDT DATA SYSTEM LIMITED" }, + { 0x0FDF, "Foveon Inc." }, + { 0x0FE0, "AONEPROTECH Co., Ltd." }, + { 0x0FE1, "MADWAVES ApS" }, + { 0x0FE2, "Air Techniques, Inc." }, + { 0x0FE3, "ACCEL CORP." }, + { 0x0FE4, "IN-TECH ELECTRONICS LIMITED" }, + { 0x0FE5, "TC&C ELECTRONIC CO.,LTD (SUNTECC, INC.)" }, + { 0x0FE6, "Sospita ASA" }, + { 0x0FE7, "Mitutoyo Corporation" }, + { 0x0FE8, "TurboComm Tech. Inc." }, + { 0x0FE9, "DVICO Inc." }, + { 0x0FEA, "United Computer Accessories" }, + { 0x0FEB, "CRS ELECTRONIC CO., LTD." }, + { 0x0FEC, "UMC Electronics Co., Ltd." }, + { 0x0FED, "ACCESS CO., LTD." }, + { 0x0FEE, "Xsido Corporation" }, + { 0x0FEF, "MJ RESEARCH, INC." }, + { 0x0FF0, "Physical Electronics" }, + { 0x0FF1, "Minato Electronics, Inc." }, + { 0x0FF2, "EZMAX CO., LTD." }, + { 0x0FF3, "Dimentor" }, + { 0x0FF4, "POLYMATECH CO., LTD." }, + { 0x0FF5, "OYO-ELECTRIC CO., LTD." }, + { 0x0FF6, "Core Valley Co., Ltd." }, + { 0x0FF7, "CHI SHING COMPUTER ACCESSORIES CO., LTD." }, + { 0x0FF8, "iXs Research Corporation" }, + { 0x0FF9, "FHC., Inc. Frederick Haer & Co." }, + { 0x0FFA, "ELENTEC CO., LTD." }, + { 0x0FFB, "Avail Corporation" }, + { 0x0FFC, "Clavia Digital Musical Instruments AB" }, + { 0x0FFD, "AKATSUKI ELECTRIC MFG. CO., LTD." }, + { 0x0FFE, "ASKA Corporation" }, + { 0x0FFF, "Aopen Inc." }, + { 0x1000, "Speed Tech Corp." }, + { 0x1001, "Ritronics Components (S) Pte. Ltd." }, + { 0x1002, "Spa Design Ltd." }, + { 0x1003, "SIGMA CORPORATION" }, + { 0x1004, "LG Electronics Inc." }, + { 0x1005, "Apacer Technology Inc." }, + { 0x1006, "Reign Com Ltd." }, + { 0x1007, "Samphone Electronic Co., Ltd." }, + { 0x1008, "Futaba Corporation" }, + { 0x1009, "Lumanate, Inc." }, + { 0x100A, "AVC Technology" }, + { 0x100B, "Chou Chin Industrial Co., Ltd." }, + { 0x100C, "eMachines, inc" }, + { 0x100D, "NETOPIA, INC." }, + { 0x100E, "North American Pacific Industries, Corp." }, + { 0x100F, "Trek Inc." }, + { 0x1010, "FUKUDA DENSHI CO., LTD." }, + { 0x1011, "Mobile Media Tech." }, + { 0x1012, "SDKM Fibres, Wires & Cables Berhad" }, + { 0x1013, "TST-Touchless Sensor Technology AG" }, + { 0x1014, "Densitron Technologies PLC" }, + { 0x1015, "Softronics Pty. Ltd." }, + { 0x1016, "Xiamen Hung's Enterprise Co., Ltd." }, + { 0x1017, "SPEEDY INDUSTRIAL SUPPLIES PTE. LTD." }, + { 0x1018, "Mindtell Inc." }, + { 0x1019, "Fostex Corporation" }, + { 0x101A, "Annecy Electronique" }, + { 0x101B, "Digital Innovations" }, + { 0x101C, "Teradyne Diagnostic Solutions Ltd." }, + { 0x101D, "Aerospace Information Corporation Limited" }, + { 0x101E, "Fronius International GmbH" }, + { 0x101F, "Pocketec" }, + { 0x1020, "Paten Wireless Technology Inc." }, + { 0x1021, "Time Management, Inc." }, + { 0x1022, "Shinko Shoji Co., Ltd." }, + { 0x1023, "CHRONIX Inc." }, + { 0x1024, "ASEC CO., LTD." }, + { 0x1025, "Technology Testing Lab" }, + { 0x1026, "Newly Corporation" }, + { 0x1027, "Time Domain" }, + { 0x1028, "Inovys Corporation" }, + { 0x1029, "Atlantic Coast Telesys" }, + { 0x102A, "RAMOS Technology Co., Ltd." }, + { 0x102B, "Infotronic America, Inc." }, + { 0x102C, "Etoms Electronics Corp." }, + { 0x102D, "Winic Corporation" }, + { 0x102E, "Binstead Systems Ltd." }, + { 0x102F, "WENZHOU YIHUA COMMUNICATED CONNECTOR CO., LTD." }, + { 0x1030, "Asoka USA Corporation" }, + { 0x1031, "Comax Technology Inc." }, + { 0x1032, "C-One Technology Corp." }, + { 0x1033, "Nucam Corporation" }, + { 0x1034, "Teramecs Co., Ltd." }, + { 0x1035, "Cyber Solid Laboratory" }, + { 0x1036, "ELLAB A/S" }, + { 0x1037, "Red Lion Controls LP" }, + { 0x1038, "SteelSeries ApS" }, + { 0x1039, "devolo AG" }, + { 0x103A, "I+ME ACTIA GmbH" }, + { 0x103B, "Quatographic AG" }, + { 0x103C, "AMX Corp." }, + { 0x103D, "Stanton Magnetics, Inc." }, + { 0x103E, "Thurlby-Thandar Instruments Ltd." }, + { 0x103F, "Tectech inc." }, + { 0x1040, "Valiant Technology Ltd." }, + { 0x1041, "Kongsberg Defence Communications AS" }, + { 0x1042, "CARDIO SISTEMAS COML. INDL. LTDA." }, + { 0x1043, "iCreate Technologies Corporation" }, + { 0x1044, "Chu Yuen Enterprise Co., Ltd." }, + { 0x1045, "Transiciel Technologies" }, + { 0x1046, "Hitachi Asahi Electronics Co., Ltd." }, + { 0x1047, "HOYA CORPORATION Vision Care Company" }, + { 0x1048, "Targus Group International" }, + { 0x1049, "Studio Technologies, Inc." }, + { 0x104A, "WACOH Corporation" }, + { 0x104B, "CSM GmbH" }, + { 0x104C, "AMCO TEC International Inc." }, + { 0x104D, "Newport Corporation" }, + { 0x104E, "Halliburton Energy Services" }, + { 0x104F, "W B Electronics" }, + { 0x1050, "Cypak AB" }, + { 0x1051, "Nippon Printer Engineering Inc." }, + { 0x1052, "U-Medica Inc." }, + { 0x1053, "Immanuel Electronics Co., Ltd." }, + { 0x1054, "BMS International Beheer N.V." }, + { 0x1055, "Complex Micro Interconnection Co., Ltd." }, + { 0x1056, "Hsin Chen Ent Co., Ltd." }, + { 0x1057, "ON Semiconductor" }, + { 0x1058, "Western Digital Technologies, Inc." }, + { 0x1059, "Giesecke & Devrient GmbH" }, + { 0x105A, "DDS, Inc." }, + { 0x105B, "TOKIWA WEST Co., Ltd." }, + { 0x105C, "Freeway Electronic Wire & Cable (Dongguan) Co., Ltd." }, + { 0x105D, "Delkin Devices, Inc." }, + { 0x105E, "Valence Semiconductor Design Limited" }, + { 0x105F, "Chin Shong Enterprise Co., Ltd." }, + { 0x1060, "Easthome Industrial Co., Ltd." }, + { 0x1061, "Cardinal Components Inc." }, + { 0x1062, "Sumitomo Electric Industries, Ltd." }, + { 0x1063, "LPKF Motion & Control GmbH" }, + { 0x1064, "INNOPLUS Co., Ltd." }, + { 0x1065, "ImageQuest Co., Ltd." }, + { 0x1066, "Eten Information Systems Co., Ltd." }, + { 0x1067, "L-3 Communications" }, + { 0x1068, "Micropi Elettronica" }, + { 0x1069, "Easy Digital Concept" }, + { 0x106A, "Loyal Legend Limited" }, + { 0x106B, "MED Associates Inc. , [email protected]" }, + { 0x106C, "Curitel Communications, Inc." }, + { 0x106D, "San Chieh Manufacturing Ltd." }, + { 0x106E, "ConectL" }, + { 0x106F, "Money Controls" }, + { 0x1070, "TAKAMISAWA CYBERNETICS CO., LTD." }, + { 0x1071, "Paxton Access Ltd." }, + { 0x1072, "FDI Matelec" }, + { 0x1073, "Lifetron Co., Ltd." }, + { 0x1074, "TECHNO SOFT SYSTEMNICS INC." }, + { 0x1075, "TOKYO KEIKI INC." }, + { 0x1076, "GCT Semiconductor, Inc." }, + { 0x1077, "VoiceBox Technologies Inc." }, + { 0x1078, "Maycom Co., Ltd." }, + { 0x1079, "Suisei Electronics System Co., Ltd." }, + { 0x107A, "Optionexist Limited" }, + { 0x107B, "X E Systems Inc." }, + { 0x107C, "Whelen Engineering Company Inc." }, + { 0x107D, "Arlec Australia Limited" }, + { 0x107E, "MIDORIYA ELECTRIC CO., LTD." }, + { 0x107F, "KidzMouse, Inc." }, + { 0x1080, "Musetel Co., Ltd." }, + { 0x1081, "VG Electracon, Inc." }, + { 0x1082, "Shin-Etsukaken Co., Ltd." }, + { 0x1083, "CANON ELECTRONICS INC." }, + { 0x1084, "PANTECH CO., LTD." }, + { 0x1085, "Datalaster" }, + { 0x1086, "Smart System Inc." }, + { 0x1087, "Shanghai Ewaytek Co., Ltd." }, + { 0x1088, "Archtek Telecom Co." }, + { 0x1089, "On Track Innovations Ltd." }, + { 0x108A, "Chloride Power Protection" }, + { 0x108B, "Grand-tek Technology Co., Ltd." }, + { 0x108C, "Robert Bosch GmbH" }, + { 0x108D, "Mitsui Zosen Systems Research Inc." }, + { 0x108E, "Lotes Co., Ltd." }, + { 0x108F, "HIOKI E.E. CORPORATION" }, + { 0x1090, "DSP Research Inc." }, + { 0x1091, "DR. JOHANNES HEIDENHAIN GmbH" }, + { 0x1092, "TOPDEK Semiconductor Inc." }, + { 0x1093, "SongPro, Inc." }, + { 0x1094, "NextEngine, Inc." }, + { 0x1095, "Good Work Systems" }, + { 0x1096, "NIO Corporation" }, + { 0x1097, "Computational Systems Incorporated" }, + { 0x1098, "Raytek Corp." }, + { 0x1099, "Surface Optics Corporation" }, + { 0x109A, "DATASOFT Systems GmbH" }, + { 0x109B, "Qingdao Hisense Communication Co., Ltd." }, + { 0x109C, "Electronic Trade Solutions Ltd." }, + { 0x109D, "NAVIUS CO., LTD." }, + { 0x109E, "Finger System Inc." }, + { 0x109F, "eSOL Co., Ltd." }, + { 0x10A0, "HIROTECH, INC." }, + { 0x10A1, "target-systemelectronic gmbh" }, + { 0x10A2, "HYUNDAI NETWORKS, INC." }, + { 0x10A3, "MITSUBISHI MATERIALS CORPORATION" }, + { 0x10A4, "Frontier Silicon Ltd." }, + { 0x10A5, "FINGERPRINT CARDS AB" }, + { 0x10A6, "SKYUP TECHNOLOGY CORPORATION" }, + { 0x10A7, "3i techs Development Corp" }, + { 0x10A8, "Imaging Devices, Inc." }, + { 0x10A9, "SK Teletech Co., Ltd." }, + { 0x10AA, "Cables To Go" }, + { 0x10AB, "Universal Global Scientific Industrial Co., Ltd." }, + { 0x10AC, "Honeywell, Inc." }, + { 0x10AD, "Impact Instrumentation Inc." }, + { 0x10AE, "Princeton Technology Corp." }, + { 0x10AF, "Liebert Corporation" }, + { 0x10B0, "IPmental Inc." }, + { 0x10B1, "Safe Valley Inc." }, + { 0x10B2, "Data East Corporation" }, + { 0x10B3, "Roke Manor Research Limited" }, + { 0x10B4, "Guardtec, Inc." }, + { 0x10B5, "Comodo" }, + { 0x10B6, "Dynojet Research, Inc." }, + { 0x10B7, "VSM Medtech Ltd." }, + { 0x10B8, "DIBCOM" }, + { 0x10B9, "Prime Electronics & Satellitics, Inc." }, + { 0x10BA, "Dong-Guan Sintai Optical Co., Ltd." }, + { 0x10BB, "TM Technology Inc." }, + { 0x10BC, "Dinging Technology Co., Ltd." }, + { 0x10BD, "TMT TECHNOLOGY, INC." }, + { 0x10BE, "KBM Electronic System Design" }, + { 0x10BF, "Smarthome" }, + { 0x10C0, "SougaSoft Co., Ltd." }, + { 0x10C1, "Kyokuto Electric Co., Ltd." }, + { 0x10C2, "Phasespace, Inc." }, + { 0x10C3, "Universal Laser Systems" }, + { 0x10C4, "Silicon Laboratories, Inc." }, + { 0x10C5, "Sanei Electric Inc." }, + { 0x10C6, "Intec, Inc." }, + { 0x10C7, "Touchstone Technology Co., Ltd." }, + { 0x10C8, "SIGMACOM CO., LTD." }, + { 0x10C9, "ZUKEN Inc." }, + { 0x10CA, "Xrosstech, Inc." }, + { 0x10CB, "eratech" }, + { 0x10CC, "GBM Connector Co., Ltd." }, + { 0x10CD, "Kycon Inc." }, + { 0x10CE, "Shinko Electric Co., Ltd." }, + { 0x10CF, "Velleman Components" }, + { 0x10D0, "Tokai University Educational System" }, + { 0x10D1, "HBM GmbH" }, + { 0x10D2, "Adams IT Services" }, + { 0x10D3, "Trimos SA" }, + { 0x10D4, "Man Boon Manufactory Ltd." }, + { 0x10D5, "Uni Class Technology Co., Ltd." }, + { 0x10D6, "Actions Semiconductor Co., Ltd." }, + { 0x10D7, "Array Corporation" }, + { 0x10D8, "ACTIKEY S.A." }, + { 0x10D9, "Tecnova Corporation" }, + { 0x10DA, "HOWTEL CO., LTD." }, + { 0x10DB, "Prior Scientific Instruments Ltd." }, + { 0x10DC, "Evolve Communications" }, + { 0x10DD, "VerNova, Inc." }, + { 0x10DE, "Authenex, Inc." }, + { 0x10DF, "In-Win Development Inc." }, + { 0x10E0, "Bella Corporation" }, + { 0x10E1, "CABLEPLUS LTD." }, + { 0x10E2, "Nada Electronics, Ltd." }, + { 0x10E3, "tec5 AG" }, + { 0x10E4, "Trans-Lux Corporation & Subsidiaries" }, + { 0x10E5, "MACTek" }, + { 0x10E6, "Altotec Hard- und Software GmbH" }, + { 0x10E7, "dSPACE GmbH" }, + { 0x10E8, "Kumahira Co., Ltd." }, + { 0x10E9, "XIA LLC" }, + { 0x10EA, "ELITRONIC s.r.o." }, + { 0x10EB, "FREEBOX SA" }, + { 0x10EC, "Vast Technologies Inc." }, + { 0x10ED, "KDS USA, Inc." }, + { 0x10EE, "Compuprint" }, + { 0x10EF, "Integrity Instruments Inc." }, + { 0x10F0, "Etronics Corp." }, + { 0x10F1, "Inventec Multimedia & Telecom Corp." }, + { 0x10F2, "Autonics Co., Ltd." }, + { 0x10F3, "Vercel Development Inc." }, + { 0x10F4, "INcoder Technology CO., Ltd." }, + { 0x10F5, "Voyetra Turtle Beach, Inc." }, + { 0x10F6, "IMAGENICS Co., Ltd." }, + { 0x10F7, "Hando Computer Co., Ltd" }, + { 0x10F8, "CESYS GmbH" }, + { 0x10F9, "NSD Corporation" }, + { 0x10FA, "CHINO Corporation" }, + { 0x10FB, "Pictos Technologies, Inc." }, + { 0x10FC, "MICRELEC" }, + { 0x10FD, "Animation Technologies Inc." }, + { 0x10FE, "Thrane & Thrane A/S" }, + { 0x10FF, "Bellwave" }, + { 0x1100, "VirTouch Ltd." }, + { 0x1101, "EASYPASS INDUSTRIAL CO., LTD." }, + { 0x1102, "Instrument Systems GmbH" }, + { 0x1103, "Brain Products GmbH" }, + { 0x1104, "TOA Corporation" }, + { 0x1105, "MAP Medizin-Technologie GmbH" }, + { 0x1106, "OrangeHouse Co., Ltd." }, + { 0x1107, "CreamWare GmbH" }, + { 0x1108, "BRIGHTCOM TECHNOLOGIES LTD." }, + { 0x1109, "LG Industrial Systems Co., Ltd." }, + { 0x110A, "Moxa Inc." }, + { 0x110B, "NAKI INTERNATIONAL" }, + { 0x110C, "Computer Network Technology" }, + { 0x110D, "Hitachi Car Engineering Co., Ltd." }, + { 0x110E, "Innotrac Diagnostics OY" }, + { 0x110F, "OneVision Corporation" }, + { 0x1110, "Analog Devices Canada Ltd." }, + { 0x1111, "Dade Behring, Inc." }, + { 0x1112, "Golden Bright (Sichuan) Electronic Technology Co Ltd" }, + { 0x1113, "Medion AG" }, + { 0x1114, "Psion Teklogix Inc." }, + { 0x1115, "Data Link Co., Ltd." }, + { 0x1116, "Compro Technology Inc." }, + { 0x1117, "11 WAVE TECHNOLOGY, INC." }, + { 0x1118, "MotoSAT" }, + { 0x1119, "GCS General Control Systems GmbH" }, + { 0x111A, "The Nippon Signal Co., Ltd." }, + { 0x111B, "Kyusyu Ten Ltd." }, + { 0x111C, "point electronic GmbH" }, + { 0x111D, "Centon Electronics" }, + { 0x111E, "VSO ELECTRONICS CO., LTD." }, + { 0x111F, "BANCOR S.R.L." }, + { 0x1120, "Voipac, s.r.o." }, + { 0x1121, "Kore Technology Limited" }, + { 0x1122, "Klein & Melgert Developments B.V." }, + { 0x1123, "Hi-Tech Instruments, Inc." }, + { 0x1124, "REnex Technology Limited" }, + { 0x1125, "Industrial Computing Ltd." }, + { 0x1126, "Protonic - Holland" }, + { 0x1127, "BANK25 Co., Ltd." }, + { 0x1128, "STEAG ETA-Optik GmbH" }, + { 0x1129, "Jung Myung Telecom Co., Ltd." }, + { 0x112A, "RedRat Ltd." }, + { 0x112B, "Stenograph L.L.C." }, + { 0x112C, "Ethics Organization of Computer Software" }, + { 0x112D, "SYSMEX CORPORATION" }, + { 0x112E, "Master Hill Electric Wire and Cable Co., Ltd." }, + { 0x112F, "Cellon International" }, + { 0x1130, "Tenx Technology, Inc." }, + { 0x1131, "Integrated System Solution Corp." }, + { 0x1132, "Visoduck discount GmbH" }, + { 0x1133, "Sanei Electric Co., Ltd." }, + { 0x1134, "Tri-L Data Systems, Inc." }, + { 0x1135, "imo-elektronik GmbH" }, + { 0x1136, "CTS ELECTRONICS" }, + { 0x1137, "Beyond LSI, Inc." }, + { 0x1138, "Greenwood Engineering A/S" }, + { 0x1139, "Wavetrend" }, + { 0x113B, "Hana Micron, Inc." }, + { 0x113C, "Arintech Co., Ltd." }, + { 0x113D, "Mapower Electronics Co. Ltd." }, + { 0x113E, "KDK Electric Wire (H.K.) Co., Ltd." }, + { 0x113F, "Integrated Biometrics" }, + { 0x1140, "Ultra-Scan Corporation" }, + { 0x1141, "V ONE MULTIMEDIA PTE LTD" }, + { 0x1142, "CYBERSCAN TECH. INC." }, + { 0x1143, "Wako Pure Chemical Industries, Ltd.." }, + { 0x1144, "MURATA MACHINERY, LTD." }, + { 0x1145, "Japan Radio Co., Ltd." }, + { 0x1146, "Shimane SANYO Electric Co., Ltd." }, + { 0x1147, "Ever Great Electric Wire and Cable Co., Ltd." }, + { 0x1148, "KGS Corporation" }, + { 0x1149, "TAMA TECH LAB CORP." }, + { 0x114A, "TANITA Corporation (1)" }, + { 0x114B, "Sphairon Technologies GmbH" }, + { 0x114C, "Tinius Olsen Testing Machine Co., Inc." }, + { 0x114D, "Alpha Imaging Technology Corp." }, + { 0x114E, "Digital Electronics Corporation" }, + { 0x114F, "WAVECOM" }, + { 0x1150, "Don Alan Pty. Ltd." }, + { 0x1151, "World Wide Licenses Limited" }, + { 0x1152, "Codonics, Inc." }, + { 0x1153, "Tritec Co., Ltd." }, + { 0x1154, "BEB Industrie-Elektronik AG" }, + { 0x1155, "DICESVA S.L." }, + { 0x1156, "Cybertech bv" }, + { 0x1157, "EKS Oy" }, + { 0x1158, "Syn-Tech Systems Inc." }, + { 0x1159, "Micro Application Laboratory Corp." }, + { 0x115A, "Extreme Speed" }, + { 0x115B, "Salix Technology Co., Ltd." }, + { 0x115C, "CORESMA" }, + { 0x115D, "ADTEK SYSTEM SCIENCE CO., LTD." }, + { 0x115E, "Group Sense Ltd." }, + { 0x115F, "Dataring Systems" }, + { 0x1160, "Invocon, Inc." }, + { 0x1161, "Port Denshi Co., Ltd." }, + { 0x1162, "Secugen Corporation" }, + { 0x1163, "DeLorme Publishing Inc." }, + { 0x1164, "YUAN High-Tech Development Co., Ltd." }, + { 0x1165, "Telson Electronics Co., Ltd." }, + { 0x1166, "Bantam Interactive Technologies" }, + { 0x1167, "Salient Systems Corporation" }, + { 0x1168, "BizConn International Corp." }, + { 0x1169, "Adirondack Optics" }, + { 0x116A, "JJL Technologies, LLC" }, + { 0x116B, "Pigeon Point Systems" }, + { 0x116C, "SecureEye, Inc." }, + { 0x116D, "Filmetrics, Inc." }, + { 0x116E, "Gigastorage Corp." }, + { 0x116F, "Silicon 10 Technology Corp." }, + { 0x1170, "Tadiran Com. Ltd." }, + { 0x1171, "CRE Technology Co., Ltd." }, + { 0x1172, "Telegate Co., Ltd." }, + { 0x1173, "Esko-Graphics" }, + { 0x1174, "Techno-One Co., Ltd." }, + { 0x1175, "Sheng Yih Technologies Co., Ltd." }, + { 0x1176, "Japan Touchscreen Distributions, Inc." }, + { 0x1177, "Hitachi Communication Technologies, Ltd." }, + { 0x1178, "Kamaya Electric Co., Ltd." }, + { 0x1179, "Bio-logic Systems Corp." }, + { 0x117A, "Ishikawa Seisakusho, Ltd." }, + { 0x117B, "Primetech Engineering Corporation" }, + { 0x117C, "SOFTIDEA s.r.o." }, + { 0x117D, "Santa Electronic Inc." }, + { 0x117E, "JNC, Inc." }, + { 0x117F, "Princeton Technology, Ltd." }, + { 0x1180, "Spectra-Physics" }, + { 0x1181, "USB NET" }, + { 0x1182, "Venture Corporation Limited" }, + { 0x1183, "Digital Dream Co. Europe Ltd." }, + { 0x1184, "Kyocera Elco Corporation" }, + { 0x1185, "Projectiondesign AS" }, + { 0x1186, "Scientec System" }, + { 0x1187, "Techno Valley Co., Ltd." }, + { 0x1188, "Bloomberg L.P." }, + { 0x1189, "Trisat Industrial Co., Ltd." }, + { 0x118A, "KEBA AG" }, + { 0x118B, "AXIOMTEK Co., Ltd." }, + { 0x118C, "INFINIT GmbH" }, + { 0x118D, "Gould Instrument Systems" }, + { 0x118E, "Hermstedt AG" }, + { 0x118F, "You Yang Technology Co., Ltd." }, + { 0x1190, "Tripace" }, + { 0x1191, "Loyalty Founder Enterprise Co., Ltd." }, + { 0x1192, "Matsusada Precision Inc." }, + { 0x1193, "H2I TECHNOLOGIES" }, + { 0x1194, "GLORY AZ System Co., Ltd." }, + { 0x1195, "ELECTROLINE" }, + { 0x1196, "Yankee Robotics, LLC" }, + { 0x1197, "Technoimagia Co., Ltd." }, + { 0x1198, "StarShine Technology Corp." }, + { 0x1199, "Sierra Wireless Inc." }, + { 0x119A, "DONG GUAN JALINK ELECTRONICES CO.,LTD" }, + { 0x119B, "ruwido austria GmbH" }, + { 0x119C, "SK MEDICAL ELECTRONICS CO.,LTD" }, + { 0x119D, "Saka-Techno Science Co., Ltd." }, + { 0x119E, "Engineered Audio, LLC." }, + { 0x119F, "TECNOS CO., LTD." }, + { 0x11A0, "Chipcon" }, + { 0x11A1, "Mikrap AG" }, + { 0x11A2, "SitecSoft Co., Ltd." }, + { 0x11A3, "Technovas Co., Ltd." }, + { 0x11A4, "THE FURUKAWA ELECTRIC CO., LTD." }, + { 0x11A5, "TOKYO RIKAKIKAI CO., LTD." }, + { 0x11A6, "VRmagic GmbH" }, + { 0x11A7, "SNAPSHIELD LTD." }, + { 0x11A8, "Hoeft & Wessel AG" }, + { 0x11A9, "Parker Hannifin" }, + { 0x11AA, "GlobalMedia Group, LLC" }, + { 0x11AB, "Exito Electronics Co., Ltd." }, + { 0x11AC, "Nike, Inc." }, + { 0x11AD, "SANWA ELECTRIC INSTRUMENT CO., LTD." }, + { 0x11AE, "Stoelting Co." }, + { 0x11AF, "Valence Semiconductor" }, + { 0x11B0, "ATECH FLASH TECHNOLOGY" }, + { 0x11B1, "New Motion Tec. Corp." }, + { 0x11B2, "Bizerba GmbH & Co. KG" }, + { 0x11B3, "MONYA Corporation" }, + { 0x11B4, "SPIELO" }, + { 0x11B5, "ADVANTECH EQUIPMENT CORP." }, + { 0x11B6, "Diskware Co., Ltd." }, + { 0x11B7, "Embla" }, + { 0x11B8, "CROSS S&T Inc." }, + { 0x11B9, "IST Electronics, Inc." }, + { 0x11BA, "Sasem Co., Ltd." }, + { 0x11BB, "YaMu Solutions" }, + { 0x11BC, "Taipei EELY-ECW Co., Ltd." }, + { 0x11BD, "UBINETICS LIMITED" }, + { 0x11BE, "Martin Professional A/S" }, + { 0x11BF, "SonoSite, Inc." }, + { 0x11C0, "Sanmos Microelectronics Corp." }, + { 0x11C1, "Wako Giken Kogyo Co., Ltd." }, + { 0x11C2, "EYESPYFX" }, + { 0x11C3, "Kaizen Frogpad, LLC" }, + { 0x11C4, "DALLANTBANK, INC." }, + { 0x11C5, "INMAX TECHNOLOGY CORP." }, + { 0x11C6, "Guzik Technical Enterprises" }, + { 0x11C7, "Reliance Electric Limited" }, + { 0x11C8, "Fullcom Technology Corp." }, + { 0x11C9, "Monster Cable Products, Inc." }, + { 0x11CA, "VeriFone" }, + { 0x11CB, "Magni Systems, Inc." }, + { 0x11CC, "AIM SRL" }, + { 0x11CD, "KTEK Co., Ltd." }, + { 0x11CE, "Argolis BV" }, + { 0x11CF, "Nemoto Kyorindo Co., Ltd." }, + { 0x11D0, "TOPCON CORPORATION, Opthalmic & Medical Instrument Dept" }, + { 0x11D1, "Far Touch Inc." }, + { 0x11D2, "BW Technologies Ltd." }, + { 0x11D3, "Elias Technology, Inc." }, + { 0x11D4, "Unitac Co., Ltd." }, + { 0x11D5, "Polyvision Corporation" }, + { 0x11D6, "FUJIFILM AXIA CO., LTD." }, + { 0x11D7, "Kokusai Electric Alpha Co., Ltd." }, + { 0x11D8, "Zybertek" }, + { 0x11D9, "Itronix Corporation" }, + { 0x11DA, "Tekscan, Inc." }, + { 0x11DB, "Topfield Co., Ltd." }, + { 0x11DC, "STELECTRIC A/S" }, + { 0x11DD, "DRAGONCHIP LTD." }, + { 0x11DE, "La Generale Multimedia" }, + { 0x11DF, "ROI Computer AG" }, + { 0x11E0, "SUNX Limited" }, + { 0x11E1, "Encentuate Pte. Ltd." }, + { 0x11E2, "SPECSOFT CONSULTING INC" }, + { 0x11E3, "GfS-Hofheim" }, + { 0x11E4, "STANDARD ELECTRONICS TELECOM INC." }, + { 0x11E5, "CHUFON Technology Co., Ltd." }, + { 0x11E6, "K.I. Technology Co. Ltd." }, + { 0x11E7, "Rockford Corporation" }, + { 0x11E8, "NAAT Technology Corp." }, + { 0x11E9, "Wincan Technology Co., Ltd." }, + { 0x11EA, "PAN RAM International Corp." }, + { 0x11EB, "VTech Innovation L.P. dba Advanced American Telephones" }, + { 0x11EC, "Hitachi Computer Peripherals Co., Ltd." }, + { 0x11ED, "Shimizu Technology Inc." }, + { 0x11EE, "ASAHI ELECTRIC CO., LTD." }, + { 0x11EF, "Cableplus Industrial Co., Ltd." }, + { 0x11F0, "Matthew Ward Solutions" }, + { 0x11F1, "Cal-Comp Electronics (Thailand) Public Co., Ltd." }, + { 0x11F2, "Chain Tay Technology Co., Ltd." }, + { 0x11F3, "ROUND Co., Ltd." }, + { 0x11F4, "Kyoritsu Electric Corporation" }, + { 0x11F5, "Siemens Mobile Phones" }, + { 0x11F6, "NetIndex Inc." }, + { 0x11F7, "ALCATEL BUSINESS SYSTEMS" }, + { 0x11F8, "BodyMedia, Inc." }, + { 0x11F9, "Cryptocard Corporation" }, + { 0x11FA, "Code Corporation" }, + { 0x11FB, "HORIBA, Ltd." }, + { 0x11FC, "ANCOT CORPORATION" }, + { 0x11FD, "EKE-Electronics Ltd." }, + { 0x11FE, "SHENZHEN CHANGXUNXING ELECTRONIC CO., LTD." }, + { 0x11FF, "LITE STAR ELECTRONICS TECHNOLOGIES, CO. LTD." }, + { 0x1200, "Spellman High Voltage Electronics Corp." }, + { 0x1201, "Practical Automation, Inc." }, + { 0x1202, "KUK JE TONG SHIN CO., LTD." }, + { 0x1203, "Taiwan Semiconductor Co., Ltd." }, + { 0x1204, "SATEC" }, + { 0x1205, "NV ADB TTV TECHNOLOGIES SA" }, + { 0x1206, "Synnix Technology Co." }, + { 0x1207, "Cardinal Health UK 232 Ltd." }, + { 0x1208, "Seiko Epson Corp.- System Device" }, + { 0x1209, "Interbiometrics Zugangssysteme GmbH" }, + { 0x120A, "Wintest Corp." }, + { 0x120B, "Dension Audio Systems Ltd." }, + { 0x120C, "ALF, Inc." }, + { 0x120D, "(AVL) DiTEST Fahrzeugdiagnose GmbH" }, + { 0x120E, "HUDSON SOFT CO., LTD." }, + { 0x120F, "Magellan Navigation, Inc." }, + { 0x1210, "Harman" }, + { 0x1211, "COSMED S.r.l." }, + { 0x1212, "D'Crypt Pte Ltd." }, + { 0x1213, "Fukko System Co., Ltd." }, + { 0x1214, "Dr. Bott KG" }, + { 0x1215, "Towa Engineering Corporation" }, + { 0x1216, "ProMinent Dosiertechnik GmbH" }, + { 0x1217, "Goyatek Technology Inc." }, + { 0x1218, "Geutebrueck GmbH" }, + { 0x1219, "COMPAL COMMUNICATIONS, INC." }, + { 0x121A, "TimeKeeping Systems, Inc." }, + { 0x121B, "FEC Inc." }, + { 0x121C, "Raysis Co., Ltd." }, + { 0x121D, "Intelligent Computer Solutions" }, + { 0x121E, "Jungsoft Co., Ltd." }, + { 0x121F, "Panini S.P.A." }, + { 0x1220, "TC Group A/S" }, + { 0x1221, "Averatec, Inc." }, + { 0x1222, "Tipro Keyboards D.O.O." }, + { 0x1223, "SKYCABLE ENTERPRISE. CO., LTD." }, + { 0x1224, "SCATT, ZAO" }, + { 0x1225, "HI-P Tech Corporation" }, + { 0x1226, "Keihin Corporation" }, + { 0x1227, "T-RAC INTERNATIONAL, INC." }, + { 0x1228, "DATAPAQ" }, + { 0x1229, "EPO Science & Technology Inc." }, + { 0x122A, "WABCO GmbH & Co., OHG" }, + { 0x122B, "Midas Lab Inc." }, + { 0x122C, "Qbtech AB" }, + { 0x122D, "Hitachi Information & Control Solutions, Ltd." }, + { 0x122E, "IOLINE" }, + { 0x122F, "Takimaging" }, + { 0x1230, "MIPSABG Chipidea, Lda." }, + { 0x1231, "CHI MEI COMMUNICATION SYSTEMS, INC." }, + { 0x1232, "SolitonWave Co., Ltd." }, + { 0x1233, "Targa Systems Div. L-3 Communications" }, + { 0x1234, "Micro Science Co., Ltd." }, + { 0x1235, "Focusrite Audio Engineering Ltd" }, + { 0x1236, "Nozaki Insatsu Shigyo Co., Ltd." }, + { 0x1237, "Technowave Ltd." }, + { 0x1238, "Bridgekey Corp." }, + { 0x1239, "Antex Electronics" }, + { 0x123A, "Spectra Technologies Holdings Co., Ltd." }, + { 0x123B, "De La Rue Systems Automatizacao" }, + { 0x123C, "K-Won C & C Co., Ltd." }, + { 0x123D, "Microplex Printware AG" }, + { 0x123E, "A.T. WORKS, Inc." }, + { 0x123F, "DURAPOWER TECHNOLOGY LTD." }, + { 0x1240, "HUMUS MOG CO., LTD." }, + { 0x1241, "OTSUKA ELECTRONICS CO., LTD." }, + { 0x1242, "MAC SYSTEM CO., LTD." }, + { 0x1243, "Fujikura Ltd., Fiber Optic System Division" }, + { 0x1244, "DResearch Digital Media Systems GmbH" }, + { 0x1245, "R/D Tech Inc." }, + { 0x1246, "CTO S.p.A." }, + { 0x1247, "JAPAN PRECISION INSTRUMENTS, INC." }, + { 0x1248, "Vector Informatik GmbH" }, + { 0x1249, "TRACESPAN Communications Ltd." }, + { 0x124A, "AirVast Technology Inc." }, + { 0x124B, "NYKO Technologies, Inc." }, + { 0x124C, "MEMORY EXPERTS International Inc." }, + { 0x124D, "Just Rams PLC" }, + { 0x124E, "YEM Inc." }, + { 0x124F, "Beijing JingHuiJiaDe Tech. Co., Ltd." }, + { 0x1250, "TECMAG" }, + { 0x1251, "Iwaya Corporation" }, + { 0x1252, "Nextway Co., Ltd." }, + { 0x1253, "Erebus Limited" }, + { 0x1254, "Empirical Systems" }, + { 0x1255, "ASCII Solutions, Inc." }, + { 0x1256, "Spectronic Denmark A/S" }, + { 0x1257, "AudioScience" }, + { 0x1258, "Autodiagnos Ltd." }, + { 0x1259, "Deutsche Montan Technologie GmbH" }, + { 0x125A, "Shintake Sangyo Co., Ltd." }, + { 0x125B, "VIDEX" }, + { 0x125C, "Apogee Instruments, Inc." }, + { 0x125D, "Advanced Technology (UK) PLC" }, + { 0x125E, "SPX Corporation" }, + { 0x125F, "ADATA Technology Co., Ltd." }, + { 0x1260, "Cores Inc." }, + { 0x1261, "All Ring Tech Co., Ltd." }, + { 0x1262, "MICRO VISION CO., LTD." }, + { 0x1263, "Opti Japan Corporation" }, + { 0x1264, "Covidien Energy-based Devices" }, + { 0x1265, "Good Mind Industries Co., Ltd." }, + { 0x1266, "Pirelli Cavi e Sistemi Telecom S.p.A." }, + { 0x1267, "SILCOR" }, + { 0x1268, "icube Corp." }, + { 0x1269, "Sequoia Voting Systems Inc." }, + { 0x126A, "CHH Electronics Ltd." }, + { 0x126B, "Veridian Systems" }, + { 0x126C, "Aristocrat Technologies" }, + { 0x126D, "Bel Stewart" }, + { 0x126E, "Strobe Data, Inc." }, + { 0x126F, "TwinMOS Technologies ME FZE" }, + { 0x1270, "Procomp Informatics Ltd." }, + { 0x1271, "Foxda Technology Industrial (Shenzhen) Co., Ltd." }, + { 0x1272, "Linear Technology Corporation" }, + { 0x1273, "HANEX Co., Ltd." }, + { 0x1274, "Matin, Inc." }, + { 0x1275, "Xaxero Marine Software Engineering Ltd." }, + { 0x1276, "QVS" }, + { 0x1277, "Silicon Media Inc." }, + { 0x1278, "Starlight Xpress Ltd." }, + { 0x1279, "Cheesecote Mountain Camac" }, + { 0x127A, "Electrophysics Corp." }, + { 0x127B, "The Technology Partnership (TTP)" }, + { 0x127C, "Comarco Wireless" }, + { 0x127D, "RAiO Technology Inc." }, + { 0x127E, "Hugelent Telecommunication (SuZhou) Co., Ltd." }, + { 0x127F, "IPACS Hans-Borchers-Gruentjens GbR (IPACS)" }, + { 0x1280, "Animeta Systems Inc." }, + { 0x1281, "Gean Sen Electronic Co., Ltd." }, + { 0x1282, "Falco Electronics Mexico" }, + { 0x1283, "zebris Medizintechnik GmbH" }, + { 0x1284, "YEC Co., Ltd." }, + { 0x1285, "Schindler Aufzuge AG" }, + { 0x1286, "MARVELL SEMICONDUCTOR, INC." }, + { 0x1287, "Infomove Co., Ltd." }, + { 0x1288, "Micro Advantage Inc." }, + { 0x1289, "Nippon Telesoft Co., Ltd." }, + { 0x128A, "Asia Vital Components Co., Ltd." }, + { 0x128B, "Medicapture, Inc." }, + { 0x128C, "ITW Food Equipment Group, LLC dba Hobart Corporation" }, + { 0x128D, "Testo AG" }, + { 0x128E, "Stormblue Co., Ltd." }, + { 0x128F, "Guidant Corporation" }, + { 0x1290, "Musicus GmbH" }, + { 0x1291, "Flarion Technologies" }, + { 0x1292, "Fire International Ltd." }, + { 0x1293, "Mitsubishi Electric Engineering Co., Ltd." }, + { 0x1294, "RISO KAGAKU CORP." }, + { 0x1295, "A & G Souzioni Digitali" }, + { 0x1296, "RadioScape" }, + { 0x1297, "DEKTEC Digital Video B.V." }, + { 0x1298, "Genlyte Controls" }, + { 0x1299, "DGStation Co., Ltd." }, + { 0x129A, "PULSTEC INDUSTRIAL CO., LTD." }, + { 0x129B, "CyberTAN Technology Inc." }, + { 0x129C, "Min Aik Technology Co., Ltd." }, + { 0x129D, "Yueqing Longhua Electronics Factory" }, + { 0x129E, "Aceeca Limited" }, + { 0x129F, "Howtek Devices Corp." }, + { 0x12A0, "CDC Point S.p.A." }, + { 0x12A1, "Tohken Co., Ltd." }, + { 0x12A2, "E28 (Shanghai) Ltd." }, + { 0x12A3, "KENT WORLD CO., LTD." }, + { 0x12A4, "Guangdong Matsunichi Communications Technology Co., Ltd" }, + { 0x12A5, "Sola/Hevi-Duty" }, + { 0x12A6, "ULVAC-PHI, Inc." }, + { 0x12A7, "Trendchip Technologies Corp." }, + { 0x12A8, "Clovertech Inc." }, + { 0x12A9, "Sunwave Technology Corp." }, + { 0x12AA, "Bustec Production Ltd." }, + { 0x12AB, "Honey Bee Electronic International Ltd." }, + { 0x12AC, "Compact Light System Norway A/S" }, + { 0x12AD, "Asahi Seiko Co., Ltd." }, + { 0x12AE, "Matsunichi Communication Holdings Limited" }, + { 0x12AF, "Baldor UK Ltd." }, + { 0x12B0, "Axciton Systems, Inc." }, + { 0x12B1, "HIMECS CO., LTD." }, + { 0x12B2, "DICKSON Company" }, + { 0x12B3, "Megaforce Company Ltd." }, + { 0x12B4, "Hanchang System Corporation" }, + { 0x12B5, "World Touch Gaming , Inc." }, + { 0x12B6, "Naito Densei Machida Mfg. Co., Ltd." }, + { 0x12B7, "Genesis Microchip Inc." }, + { 0x12B8, "Zhejiang Xinya Electronic Technology Co., Ltd." }, + { 0x12B9, "Freehand Systems, Inc." }, + { 0x12BA, "Sony Computer Entertainment America" }, + { 0x12BB, "Paltronics, Inc." }, + { 0x12BC, "Hakusan Corporation" }, + { 0x12BD, "Sun Light Application Co., Ltd." }, + { 0x12BE, "Dynex Technologies" }, + { 0x12BF, "Matrix Multimedia Ltd." }, + { 0x12C0, "Sencore, Inc." }, + { 0x12C1, "ARTRAY CO., LTD." }, + { 0x12C2, "HHB Communications Ltd." }, + { 0x12C3, "Fiso Technologies, Inc." }, + { 0x12C4, "Autocue Ltd." }, + { 0x12C5, "XN Technologies, Inc." }, + { 0x12C6, "Bosch Security Systems" }, + { 0x12C7, "Hismartech Co., Ltd." }, + { 0x12C8, "XiMeta Inc." }, + { 0x12C9, "Newmen Technology Corp. Ltd." }, + { 0x12CA, "Cables To Go International Manufacturing Co., Ltd." }, + { 0x12CB, "Dallmeier electronic GmbH" }, + { 0x12CC, "Printherm" }, + { 0x12CD, "Cables Unlimited" }, + { 0x12CE, "Hakko Electronics Co., Ltd." }, + { 0x12CF, "Dexin Corporation" }, + { 0x12D0, "ITG Research & Development Center" }, + { 0x12D1, "Huawei Technologies Co., Ltd." }, + { 0x12D2, "LINE TECH INDUSTRIAL CO., LTD." }, + { 0x12D3, "Linak A/S" }, + { 0x12D4, "Infonics Pty. Limited" }, + { 0x12D5, "Strategic Vista Corp." }, + { 0x12D6, "EMS Dr. Thomas Wuensche" }, + { 0x12D7, "Better Holdings (HK) Limited" }, + { 0x12D8, "Araneus Information Systems Oy" }, + { 0x12D9, "DIGITFAB INTERNATIONAL CO., LTD." }, + { 0x12DA, "Simavionics, Inc." }, + { 0x12DB, "Planar Systems, Inc." }, + { 0x12DC, "MMGEAR Co., Ltd." }, + { 0x12DD, "Alec Electronics Co.,Ltd." }, + { 0x12DE, "National Display Systems" }, + { 0x12DF, "Sumitomo 3M Limited" }, + { 0x12E0, "Electronica Mecanica Y Control S.A." }, + { 0x12E1, "FDK CORPORATION" }, + { 0x12E2, "Bonso Electronic Ltd." }, + { 0x12E3, "1417188 Ontario Ltd." }, + { 0x12E4, "Bruel & Kjaer Sound & Vibration Meas. A/S" }, + { 0x12E5, "Interactive Computer Products, Inc." }, + { 0x12E6, "Waldorf-Music AG" }, + { 0x12E7, "Sugiyama Electron Co., Ltd." }, + { 0x12E8, "ZAN Messgeraete" }, + { 0x12E9, "Mindspeed Technologies" }, + { 0x12EA, "Microlink Systems" }, + { 0x12EB, "MITSUI & CO., LTD." }, + { 0x12EC, "KYORITSU ELECTRICAL INSTRUMENTS WORKS, LTD. (R&D Center" }, + { 0x12ED, "Techno Kit Corporation" }, + { 0x12EE, "Avery Dennison Deutschland GmbH" }, + { 0x12EF, "Tapwave, Inc." }, + { 0x12F0, "KROHNE" }, + { 0x12F1, "OHIRA GIKEN, IND. CO., LTD." }, + { 0x12F2, "VIEWPLUS TECHNOLOGIES, INC." }, + { 0x12F3, "FORMOSA TELETEK CORPORATION" }, + { 0x12F4, "Glovic Electronics Corp." }, + { 0x12F5, "Dynamic System Electronics Corp." }, + { 0x12F6, "Aichi Tokei Denki Co., Ltd." }, + { 0x12F7, "Memorex Products, Inc." }, + { 0x12F8, "Evolution Technologies, Inc." }, + { 0x12F9, "RF-LINK SYSTEMS, INC." }, + { 0x12FA, "RF Micro Devices" }, + { 0x12FB, "SSD JAPAN CO., Ltd" }, + { 0x12FC, "eGenium S.r.l." }, + { 0x12FD, "AIN COMM. TECHNOLOGY CO., LTD." }, + { 0x12FE, "E.U CONNECTOR(M) SDN BHD." }, + { 0x12FF, "Fascinating Electronics, Inc." }, + { 0x1300, "Muscle Corporation" }, + { 0x1301, "Woehler Messgeraete Kehrgeraete GmbH" }, + { 0x1302, "Wildseed Ltd." }, + { 0x1303, "Lloyd Research Ltd." }, + { 0x1304, "MEDIALINK-I, Inc." }, + { 0x1305, "ELSE Ltd." }, + { 0x1306, "Torcon Instruments Inc." }, + { 0x1307, "USBest Technology Inc." }, + { 0x1308, "Precision Photonics Corp." }, + { 0x1309, "Sabine, Inc." }, + { 0x130A, "SIBATA SCIENTIFIC TECHNOLOGY, LTD." }, + { 0x130B, "MPC Products" }, + { 0x130C, "Quest Technologies" }, + { 0x130D, "Loyal Technology Corporation" }, + { 0x130E, "Microlink Communications Inc." }, + { 0x130F, "AGFA NDT, Krautkramer Ultrasonic Systems" }, + { 0x1310, "Air2U Inc." }, + { 0x1311, "EDX Epi-Scan Corp" }, + { 0x1312, "ICS Electronics" }, + { 0x1313, "THORLABS, INC" }, + { 0x1314, "Ryoko Electric Co., Ltd." }, + { 0x1315, "Prairie Systems & Equip. Ltd. O/A Massload Technologies" }, + { 0x1316, "JUNGLE Inc" }, + { 0x1317, "PC-CRAFT Co., Ltd." }, + { 0x1318, "O'RITE TECHNOLOGY Co., Ltd." }, + { 0x1319, "Peekel Instruments B.V." }, + { 0x131A, "VERYWELL CO., LTD." }, + { 0x131B, "Rowley Associates Ltd." }, + { 0x131C, "Staples, Inc." }, + { 0x131D, "Natural Point" }, + { 0x131E, "Duerr Dental GmbH & Co., KG" }, + { 0x131F, "Ayuttha Technology Corp." }, + { 0x1320, "Jaguar International Corporation" }, + { 0x1321, "Lectrosonics, Inc." }, + { 0x1322, "Z/I Imaging" }, + { 0x1323, "Zeustech Company Limited" }, + { 0x1324, "H-Mod, Inc." }, + { 0x1325, "Austriamicrosystems AG" }, + { 0x1326, "Force Control Industries Inc." }, + { 0x1327, "Avtec, Inc." }, + { 0x1328, "Iris Power Engineering" }, + { 0x1329, "Appairent Technologies, Inc." }, + { 0x132A, "Envara" }, + { 0x132B, "Konica Minolta Holdings, Inc." }, + { 0x132C, "Le Prestique International (H.K.) Ltd." }, + { 0x132D, "GE Healthcare Life Sciences" }, + { 0x132E, "Kwang Jang Corporation" }, + { 0x132F, "ViALUX GmbH" }, + { 0x1330, "ALFANUCLEAR S.A." }, + { 0x1331, "Panic Inc." }, + { 0x1332, "Moral Follow System Co., Ltd." }, + { 0x1333, "Ultra Electronics Electrics Division" }, + { 0x1334, "ADC Corporation" }, + { 0x1335, "PLUS Corporation" }, + { 0x1336, "IMM-Gruppe" }, + { 0x1337, "Radiant Networks Plc" }, + { 0x1338, "IT CONCEPTS LLC" }, + { 0x1339, "Akashi Corporation" }, + { 0x133A, "Vyyo Inc." }, + { 0x133B, "FLASH SUPPORT GROUP, INC." }, + { 0x133C, "G-Design Technology" }, + { 0x133D, "Jasco Products Company" }, + { 0x133E, "Kemper Digital GmbH" }, + { 0x133F, "Hwayoung RF Solution Inc." }, + { 0x1340, "Escherlogic Inc." }, + { 0x1341, "Lavry Engineering" }, + { 0x1342, "Sutter Instrument Company" }, + { 0x1343, "Heiwa Tokei Mfg. Co., Ltd" }, + { 0x1344, "TCI, Inc. d/b/a TCI Medical" }, + { 0x1345, "Sino Lite Technology Corp." }, + { 0x1346, "Mediatek Corp." }, + { 0x1347, "Moravian Instruments, Inc." }, + { 0x1348, "Katsuragawa Electric Co., Ltd." }, + { 0x1349, "Esaote/Pie Medical Equipment" }, + { 0x134A, "iX Group" }, + { 0x134B, "El Pusk Co., Ltd." }, + { 0x134C, "Panjit International Inc." }, + { 0x134D, "Danfoss Drives A/S" }, + { 0x134E, "Digby's Bitpile, Inc. D.B.A. D Bit" }, + { 0x134F, "Addvalue Communications Pte Ltd." }, + { 0x1350, "UniqueICs, LLC" }, + { 0x1351, "Crossware Associates" }, + { 0x1352, "Km2Net" }, + { 0x1353, "Shenzhen Coship Software Co., Ltd." }, + { 0x1354, "FACTS Engineering LLC" }, + { 0x1355, "Ethicon Endo-Surgery, Inc." }, + { 0x1356, "Techpoint Electric Wire & Cable Co., Ltd." }, + { 0x1357, "P & E Microcomputer Systems, Inc." }, + { 0x1358, "SKYLIGHT DIGITAL INC." }, + { 0x1359, "RKC INSTRUMENT INC." }, + { 0x135A, "URMET TLC S.p.A. - Servizio Amministrativo" }, + { 0x135B, "M-System Co., Ltd." }, + { 0x135C, "Real-Time Essentials, Inc." }, + { 0x135D, "ALGOTEX SRL" }, + { 0x135E, "Insta Elektro GmbH" }, + { 0x135F, "Control Development, Inc." }, + { 0x1360, "FREETRON COM LTD." }, + { 0x1361, "Thinktel Korea Co., Ltd." }, + { 0x1362, "IMAGICA Corp." }, + { 0x1363, "Axsun Technologies, Inc." }, + { 0x1364, "SHARP TAKAYA ELECTRONICS INDUSTRY CO., LTD." }, + { 0x1365, "TOYO JIKI INDUSTRY CO., LTD." }, + { 0x1366, "SEGGER Microcontroller Systems GmbH" }, + { 0x1367, "The Soundbeam Project" }, + { 0x1368, "TelePaq Technology Inc." }, + { 0x1369, "FASL LLC." }, + { 0x136A, "Pelco" }, + { 0x136B, "STEC" }, + { 0x136C, "Datastor Technology Co., Ltd." }, + { 0x136D, "Brainchild" }, + { 0x136E, "Andor Technology" }, + { 0x136F, "Nielsen Media Research" }, + { 0x1370, "Swissbit AG" }, + { 0x1371, "Micro Technology Co., Ltd." }, + { 0x1372, "AMAC Tek Co., Ltd." }, + { 0x1373, "Radical Research, Inc." }, + { 0x1374, "American Anko Co." }, + { 0x1375, "TCL MOBILE COMMUNICATION CO., LTD." }, + { 0x1376, "Vimtron Electronics Co., Ltd." }, + { 0x1377, "Sennheiser Electronic" }, + { 0x1378, "HIRATA Corporation" }, + { 0x1379, "Inprocomm, Inc." }, + { 0x137A, "Weldon Technologies, Inc." }, + { 0x137B, "SCAPS GmbH" }, + { 0x137C, "Yaskawa Electric Corporation" }, + { 0x137D, "Pericom Semiconductor Corp." }, + { 0x137E, "XL Microwave, Inc." }, + { 0x137F, "Sata Hi Tech Services" }, + { 0x1380, "Staveley Instruments" }, + { 0x1381, "N-LINE SYSTEM CO., LTD." }, + { 0x1382, "Systemware Inc." }, + { 0x1383, "Application Corporation" }, + { 0x1384, "Device Drivers Limited" }, + { 0x1385, "Variscite Ltd." }, + { 0x1386, "SCD Tech Inc." }, + { 0x1387, "Advanced Technical Group" }, + { 0x1388, "Southern Vision Systems, Inc." }, + { 0x1389, "Coolnection Technology Co., Ltd." }, + { 0x138A, "Validity Inc." }, + { 0x138B, "AMS Limited, Integrated Systems" }, + { 0x138C, "Fortemedia, Inc." }, + { 0x138D, "CPI GmbH" }, + { 0x138E, "RAISONANCE" }, + { 0x138F, "Saia-Burgess Controls Ltd." }, + { 0x1390, "TomTom International B.V." }, + { 0x1391, "IdealTEK" }, + { 0x1392, "SAGE INSTRUMENTS" }, + { 0x1393, "ELNEC s.r.o." }, + { 0x1394, "Gemini 2000 Ltd." }, + { 0x1395, "Sennheiser Communications A/S" }, + { 0x1396, "Greenliant Systems, Inc." }, + { 0x1397, "Behringer Spezielle Studiotechnik GmbH" }, + { 0x1398, "Nintendo of America" }, + { 0x1399, "Thai Wonderful Wire Cable Co., Ltd." }, + { 0x139A, "Infinitec Co., Ltd." }, + { 0x139B, "Thomas Enterprises, Inc." }, + { 0x139C, "Deltronics" }, + { 0x139D, "Digisafe Pte. Ltd." }, + { 0x139E, "Valueplus Inc." }, + { 0x139F, "NAGRAVISION SA" }, + { 0x13A0, "Essilor International" }, + { 0x13A1, "Canas Co., Ltd." }, + { 0x13A2, "Pesa Switching Systems, Inc." }, + { 0x13A3, "Dynon Instruments" }, + { 0x13A4, "Equipment Systems & Devices" }, + { 0x13A5, "Sammy Corporation" }, + { 0x13A6, "Jeppesen Sanderson Inc." }, + { 0x13A7, "Circuit Design, Inc." }, + { 0x13A8, "Grandtec Electronic Corp" }, + { 0x13A9, "YAMAMOTO-MS CO., LTD." }, + { 0x13AA, "Sinar Electronics Limited" }, + { 0x13AB, "MicroMade Galka i Drozdz sp.j" }, + { 0x13AC, "DAQ Systems" }, + { 0x13AD, "Baltech AG" }, + { 0x13AE, "CIM-USA Inc." }, + { 0x13AF, "Handheld Entertainment" }, + { 0x13B0, "PerkinElmer Optoelectronics" }, + { 0x13B1, "Cisco-Linksys, LLC" }, + { 0x13B2, "ALESIS" }, + { 0x13B3, "Nippon Dics Co., Ltd." }, + { 0x13B4, "Dolch Computer Systems" }, + { 0x13B5, "INVENTECH, INC." }, + { 0x13B6, "ISABELLENHUETTE Heusler GmbH KG" }, + { 0x13B7, "Keymark Technology Co., Ltd." }, + { 0x13B8, "PDM Electronic Co., Ltd." }, + { 0x13B9, "Cimcore" }, + { 0x13BA, "Yung Ray Technology Co., Ltd." }, + { 0x13BB, "Covidien Respiratory and Monitoring Solutions" }, + { 0x13BC, "Imaging Supersonic Laboratories Co., Ltd." }, + { 0x13BD, "Remote Technologies, Inc." }, + { 0x13BE, "Ricoh Printing Systems, Ltd." }, + { 0x13BF, "Accusys, Inc." }, + { 0x13C0, "Stream Labs" }, + { 0x13C1, "Vivitar Corporation" }, + { 0x13C2, "SATO KEIRYOKI MFG. CO., LTD." }, + { 0x13C3, "SCT Performance, LLC" }, + { 0x13C4, "StationZ Inc." }, + { 0x13C5, "MELFAS, INC." }, + { 0x13C6, "Hasointech Co., Ltd." }, + { 0x13C7, "ANDO ELECTRIC CO., LTD." }, + { 0x13C8, "Togami Electric Mfg. Co., Ltd." }, + { 0x13C9, "LinearX Systems Inc." }, + { 0x13CA, "JyeTai Precision Industrial Co., Ltd." }, + { 0x13CB, "JTEK Technology Corporation" }, + { 0x13CC, "Cellvic Corporation" }, + { 0x13CD, "ABCD Aging Biorhythms and Computer Diagnostics GmbH" }, + { 0x13CE, "Cypherix (Pty) Ltd." }, + { 0x13CF, "Wisair Ltd." }, + { 0x13D0, "Swedect AB" }, + { 0x13D1, "A-Max Technology Macao Commercial Offshore Co. Ltd." }, + { 0x13D2, "Intelligraphics, Inc." }, + { 0x13D3, "AzureWave Technologies, Inc." }, + { 0x13D4, "IWATSU TEST INSTRUMENTS CORPORATION" }, + { 0x13D5, "International Electronics Inc." }, + { 0x13D6, "Appside" }, + { 0x13D7, "Tableau, LLC" }, + { 0x13D8, "University of Stirling" }, + { 0x13D9, "Blazepoint Limited" }, + { 0x13DA, "OPTEX CO., LTD." }, + { 0x13DB, "Zastron Electronic (Shenzhen) Co. Ltd." }, + { 0x13DC, "ALEREON, INC." }, + { 0x13DD, "i.Tech Dynamic Limited" }, + { 0x13DE, "LANKOM ELECTRONICS CO., LTD." }, + { 0x13DF, "Good Fancy Enterprise Co., Ltd." }, + { 0x13E0, "Taiwan Silicon Electronics Corp." }, + { 0x13E1, "Kaibo Wire & Cable (Shenzhen) Co., Ltd." }, + { 0x13E2, "Parallax, Inc." }, + { 0x13E3, "SoniqCast, LLC" }, + { 0x13E4, "Audio Precision" }, + { 0x13E5, "Sigma Audio Research Ltd." }, + { 0x13E6, "TechnoScope Co., Ltd." }, + { 0x13E7, "Gantner Pigeon Systems GmbH" }, + { 0x13E8, "PalmSource Inc." }, + { 0x13E9, "Ununpentium, LLC" }, + { 0x13EA, "I/F - COM A/S" }, + { 0x13EB, "PILZ GMBH & CO. KG" }, + { 0x13EC, "Chyau Yuan Technology Co., Ltd." }, + { 0x13ED, "Wooju Communications Co., Ltd." }, + { 0x13EE, "ATLab Inc." }, + { 0x13EF, "Turner Technology" }, + { 0x13F0, "DIGENT CO., Ltd." }, + { 0x13F1, "AP Instruments" }, + { 0x13F2, "Tech Micro Corporation" }, + { 0x13F3, "Amulet Hotkey" }, + { 0x13F4, "Verisity Design Inc." }, + { 0x13F5, "X-TEL Communications, Inc." }, + { 0x13F6, "Aspen Touch Solutions, Inc." }, + { 0x13F7, "Corevalley Co., Ltd." }, + { 0x13F8, "EZPnP Technologies Corp." }, + { 0x13F9, "Impsys Digital Security AB" }, + { 0x13FA, "Radiantech, Inc." }, + { 0x13FB, "Noritsu Koki Co., Ltd." }, + { 0x13FC, "Compucat Research Pty Limited" }, + { 0x13FD, "Initio Corporation" }, + { 0x13FE, "Phison Electronics Corp." }, + { 0x13FF, "VIEWCON ELECTRONIC LTD." }, + { 0x1400, "Axxion Group Corp." }, + { 0x1401, "Fulhua Microelectronics Corp." }, + { 0x1402, "Bowe Bell & Howell" }, + { 0x1403, "Sitronix Technology Corp." }, + { 0x1404, "Fundamental Software Incorporated" }, + { 0x1405, "Cooper Security Ltd." }, + { 0x1406, "Systemneeds, Inc." }, + { 0x1407, "Coin Mechanisms Inc." }, + { 0x1408, "Comark Ltd." }, + { 0x1409, "IDS Imaging Development Systems GmbH" }, + { 0x140A, "Koyo Electronics Industries Co., Ltd." }, + { 0x140B, "Vertex Standard Co., Ltd." }, + { 0x140C, "MITS Electronics" }, + { 0x140D, "Japan Novel Corporation" }, + { 0x140E, "Telechips, Inc." }, + { 0x140F, "i-WAVER" }, + { 0x1410, "Novatel Wireless, Inc." }, + { 0x1411, "SKIDATA AG" }, + { 0x1412, "IMADA CO., LTD." }, + { 0x1413, "Telsey S.p.A." }, + { 0x1415, "Sony Computer Entertainment Europe" }, + { 0x1416, "Axeon Limited" }, + { 0x1417, "Butterfly Media" }, + { 0x1418, "MediaPower Technology Corporation" }, + { 0x1419, "ABILITY ENTERPRISE CO., LTD." }, + { 0x141A, "Realm Systems Inc." }, + { 0x141B, "METRAWARE" }, + { 0x141C, "Leviton Manufacturing" }, + { 0x141D, "J.FIT Co., Ltd." }, + { 0x141E, "Ikegami Tsushinki Co., Ltd." }, + { 0x141F, "SHIMADZU CORPORATION" }, + { 0x1420, "Lyrtech Inc." }, + { 0x1421, "Sensor Technologies America, Inc." }, + { 0x1422, "Bird Electronic Corporation" }, + { 0x1423, "ANCA Pty. Ltd." }, + { 0x1424, "Posnet Polska S.A." }, + { 0x1425, "IBEX Technology Co., Ltd." }, + { 0x1426, "NADEX Co., Ltd." }, + { 0x1427, "Global Display Solutions S.P.A." }, + { 0x1428, "Improvision Ltd." }, + { 0x1429, "Vega Technologies Industrial (Austria) Co." }, + { 0x142A, "Thales-e-Transactions" }, + { 0x142B, "Arbiter Systems, Inc." }, + { 0x142C, "SOMA OPTICS, LTD." }, + { 0x142D, "Sanblaze Technology, Inc." }, + { 0x142E, "TAMS Inc." }, + { 0x142F, "IO Display Systems" }, + { 0x1430, "RedOctane" }, + { 0x1431, "Pertech Resources, Inc." }, + { 0x1432, "Beijing Watertek Information Technology Co., Ltd." }, + { 0x1433, "TRANWO TECHNOLOGY CORP." }, + { 0x1434, "Comart System Co., Ltd." }, + { 0x1435, "Wistron NeWeb Corp." }, + { 0x1436, "Denali Software, Inc." }, + { 0x1437, "Carl Zeiss" }, + { 0x1438, "My3ia (Beijing) Technology Ltd." }, + { 0x1439, "Wind River Systems Inc." }, + { 0x143A, "CP Technologies" }, + { 0x143B, "RHESCA Company Limited" }, + { 0x143C, "Altek Corporation" }, + { 0x143D, "FUKOKU INDUSTRY CO., LTD." }, + { 0x143E, "IAV GmbH" }, + { 0x143F, "IDEC IZUMI CORPORATION" }, + { 0x1440, "Jaalaa, Inc." }, + { 0x1441, "MARIAN GbR" }, + { 0x1442, "Canadian Bank Note Company, Limited" }, + { 0x1443, "Digilent Inc." }, + { 0x1444, "H & S Instruments Inc." }, + { 0x1445, "JUSTER CO., LTD." }, + { 0x1446, "X.J. Group Ltd." }, + { 0x1447, "Cognex Corporation" }, + { 0x1448, "Biosystems LLC" }, + { 0x1449, "SHIMADEN CO., LTD." }, + { 0x144A, "Megger" }, + { 0x144B, "MADENTEC LTD." }, + { 0x144C, "Always On UPS Systems Inc." }, + { 0x144D, "K-SUN Corporation" }, + { 0x144E, "Westar Corporation" }, + { 0x144F, "K-jump Health Co., Ltd." }, + { 0x1450, "Melec Inc." }, + { 0x1451, "Force Dimension LLC" }, + { 0x1452, "DAI NIPPON PRINTING CO., LTD." }, + { 0x1453, "Epilog Corporation" }, + { 0x1454, "China IWNCOMM Co., Ltd." }, + { 0x1455, "Georgia Technology Corp." }, + { 0x1456, "Extending Wire & Cable Co., Ltd." }, + { 0x1457, "DAE-A Mediatech Co., Ltd." }, + { 0x1458, "Rauland-Borg Corporation" }, + { 0x1459, "Shanghai Simax Micro-electronics Co., Ltd." }, + { 0x145A, "All-Systems Electronics Pty. Ltd." }, + { 0x145B, "Lead-Type Precision Electronics Co., Ltd." }, + { 0x145C, "Busch-Jaeger-Elektro GmbH" }, + { 0x145D, "Sopac Ltd." }, + { 0x145E, "Forschungszentrum Karlsruhe GmbH" }, + { 0x145F, "Trust International BV" }, + { 0x1460, "TATUNG Company" }, + { 0x1461, "Staccato Communications" }, + { 0x1462, "Bright Computech Co., Ltd." }, + { 0x1463, "BBWM Corp." }, + { 0x1464, "Asiamajor Inc." }, + { 0x1465, "Michilin Prosperity Co., Ltd." }, + { 0x1466, "H2 Developer Group" }, + { 0x1467, "Clearly Superior Technologies" }, + { 0x1468, "CSE Co., Ltd." }, + { 0x1469, "ELECTRIM CORPORATION" }, + { 0x146A, "Knobloch GmbH" }, + { 0x146B, "BigBen Interactive Limited" }, + { 0x146C, "HETEC Datensysteme GmbH" }, + { 0x146D, "Progeny Inc." }, + { 0x146E, "ClearOne Communications" }, + { 0x146F, "Unity Electrical Ind. Ltd." }, + { 0x1470, "STARRIVER TECHNOLOGY CO., LTD." }, + { 0x1471, "Open Labs, Inc." }, + { 0x1472, "Hangzhou H3C Technologies Co., Ltd." }, + { 0x1473, "Dingo Incorporated" }, + { 0x1474, "Lamp Express USA, Inc." }, + { 0x1475, "NAC Image Technology Incorporated" }, + { 0x1476, "Westech Korea Inc." }, + { 0x1477, "XIROKU INC." }, + { 0x1478, "Link World Electric Inc." }, + { 0x1479, "Datalux Corporation" }, + { 0x147A, "Formosa21 Inc." }, + { 0x147B, "ABB STOTZ-KONTAKT GmbH" }, + { 0x147C, "KeyGhost Ltd." }, + { 0x147D, "Tosoh Corporation" }, + { 0x147E, "UPEK Inc." }, + { 0x147F, "Hama GmbH & Co., KG" }, + { 0x1480, "SITEK S.p.a." }, + { 0x1481, "MHT S.p.A." }, + { 0x1482, "Vaillant GmbH" }, + { 0x1483, "Shenzhen MingWah Aohan High Technology Co., Ltd." }, + { 0x1484, "Triad Semiconductor, Inc." }, + { 0x1485, "OrangeWare Corp." }, + { 0x1486, "SCM PC-CARD GmbH" }, + { 0x1487, "DSP Group, Ltd." }, + { 0x1488, "Orion Technology Corp." }, + { 0x1489, "Sakura Finetek USA, Inc." }, + { 0x148A, "MICROVISION" }, + { 0x148B, "HandEra, Inc." }, + { 0x148C, "Colortrac Ltd." }, + { 0x148D, "DESMA Co., Ltd." }, + { 0x148E, "EVATRONIX SA" }, + { 0x148F, "Ralink Technology, Corp." }, + { 0x1490, "Digitek Spa" }, + { 0x1491, "Futronic Technology Co., Ltd." }, + { 0x1492, "Farsharp Imaging Technology Corp." }, + { 0x1493, "Suunto" }, + { 0x1495, "Elprotronic Inc." }, + { 0x1496, "Tunturi Oy Ltd." }, + { 0x1497, "Panstrong Company Ltd." }, + { 0x1498, "ULi Electronics Inc." }, + { 0x1499, "G-STAR Communications, Ltd." }, + { 0x149A, "Imagination Technologies" }, + { 0x149B, "Ivoclar Vivadent AG" }, + { 0x149C, "TonerHead.com" }, + { 0x149D, "QMotions Inc." }, + { 0x149E, "Amkor Technology" }, + { 0x149F, "Wits Technologies Pte. Ltd." }, + { 0x14A0, "WAVE Corporation" }, + { 0x14A1, "Sunhayato Corp." }, + { 0x14A2, "Big Dutchman (Skandinavien) A/S" }, + { 0x14A3, "Wipotec GmbH" }, + { 0x14A4, "Kyerim Industrial Co." }, + { 0x14A5, "I-ROCKS TECHNOLOGY CO., LTD." }, + { 0x14A6, "Interface Masters, Inc." }, + { 0x14A7, "LanReady Technologies, Inc." }, + { 0x14A8, "1C Company" }, + { 0x14A9, "Smar Research Corp." }, + { 0x14AA, "WideView Technology Inc." }, + { 0x14AB, "Technisches Buero Koenig" }, + { 0x14AC, "Coolstf.com" }, + { 0x14AD, "CTK Corporation" }, + { 0x14AE, "Printronix Inc." }, + { 0x14AF, "ATP Electronics Inc." }, + { 0x14B0, "StarTech.com Ltd." }, + { 0x14B1, "I.E. Gesellschaft fuer Industrieelektronik mbH" }, + { 0x14B2, "Alpha Networks Inc." }, + { 0x14B3, "CHUO ELECTRIC WORKS CO., LTD." }, + { 0x14B4, "Appliances Corp." }, + { 0x14B5, "NTS Telecom" }, + { 0x14B6, "Mimic Technologies Inc." }, + { 0x14B7, "In2Games Limited" }, + { 0x14B8, "UNITEK TECHNOLOGY CORPORATION" }, + { 0x14B9, "BP Microsystems" }, + { 0x14BA, "FLOVEL CO., LTD." }, + { 0x14BB, "Assembly Tech. Co., Ltd." }, + { 0x14BC, "NordNav Technologies AB" }, + { 0x14BD, "Eintech Co., Ltd." }, + { 0x14BE, "Crestron Electronics, Inc." }, + { 0x14BF, "Everbee Networks" }, + { 0x14C0, "Rockwell Automation, Inc." }, + { 0x14C1, "SOHYA TECHNOLOGY CO., LTD." }, + { 0x14C2, "Gemlight Computer Ltd." }, + { 0x14C3, "VOXELLE LTD." }, + { 0x14C4, "CLOVER Electronics Co., Ltd." }, + { 0x14C5, "AudioControl" }, + { 0x14C6, "Trigon Components, Inc." }, + { 0x14C7, "Hartmann GmbH" }, + { 0x14C8, "Zytronic Displays Limited" }, + { 0x14C9, "IXOS Ltd. Bvi" }, + { 0x14CA, "Technol Seven Co., Ltd." }, + { 0x14CB, "Dynapoint, Inc." }, + { 0x14CC, "WIN TONG ELECTRONICS CO., LTD." }, + { 0x14CD, "MOAI ELECTRONICS CORPORATION" }, + { 0x14CE, "Spectra, Inc." }, + { 0x14CF, "Measurement Systems Inc." }, + { 0x14D0, "Dentrix Dental Systems, Inc." }, + { 0x14D1, "Maximo Products LLC" }, + { 0x14D2, "BITS CO., LTD." }, + { 0x14D3, "Y2 Corporation" }, + { 0x14D4, "Telequip Corporation" }, + { 0x14D5, "Electronic Theatre Controls" }, + { 0x14D6, "Beijing Zhijiu Technology Co., Ltd." }, + { 0x14D7, "Toppan Printing Co., Ltd." }, + { 0x14D8, "JAMER INDUSTRIES CO., LTD." }, + { 0x14D9, "Advanced Flash Memory Card Technology Ltd." }, + { 0x14DA, "Horng Technical Enterprise Co., Ltd." }, + { 0x14DB, "TOA Musendenki Co., Ltd." }, + { 0x14DC, "Ftech Co., Ltd." }, + { 0x14DD, "Raritan Computer, Inc." }, + { 0x14DE, "Jetway Information Co., Ltd." }, + { 0x14DF, "COMPRION GmbH" }, + { 0x14E0, "Winradio Communications" }, + { 0x14E1, "Dialogue Technology Corp." }, + { 0x14E2, "Avistar Communications Corporation" }, + { 0x14E3, "Medmont Pty Ltd." }, + { 0x14E4, "S.CAM Co., Ltd." }, + { 0x14E5, "SAIN Information & Communications Co., Ltd." }, + { 0x14E6, "Micromed Biotecnologia Ltda." }, + { 0x14E7, "ISS Incorporated" }, + { 0x14E8, "Animated Lighting LC" }, + { 0x14E9, "Lifetouch, Inc." }, + { 0x14EA, "Kosaka Laboratory Ltd." }, + { 0x14EB, "Pendulum Instruments AB" }, + { 0x14EC, "Vansco Electronics Ltd." }, + { 0x14ED, "Shure Inc." }, + { 0x14EE, "INFORAD Ltd." }, + { 0x14EF, "AVICLink Corporation" }, + { 0x14F0, "GE" }, + { 0x14F1, "America Hears, LLC." }, + { 0x14F2, "Axess AG" }, + { 0x14F3, "BAP IMAGE SYSTEMS" }, + { 0x14F4, "Accell Corporation" }, + { 0x14F5, "SourceQuest, Inc." }, + { 0x14F6, "Symbium Corporation" }, + { 0x14F7, "TechniSat Digital GmbH" }, + { 0x14F8, "Chenrol Electric Wire & Cable Co., Ltd." }, + { 0x14F9, "Full Conductor Electric Appliance Manufacturer" }, + { 0x14FA, "The Wild Divine Project" }, + { 0x14FB, "JAI" }, + { 0x14FC, "Signami LLC" }, + { 0x14FD, "IPC Information Systems" }, + { 0x14FE, "Madrics Media GmbH Europe" }, + { 0x14FF, "Twinhead International Corp." }, + { 0x1500, "Ellisys" }, + { 0x1501, "Pine-Tum Enterprise Co., Ltd." }, + { 0x1502, "Peavey Electronics" }, + { 0x1503, "Stretch Inc." }, + { 0x1504, "KOREA PRINTING SYSTEMS CO., LTD." }, + { 0x1505, "Extraordinary Technologies Pty. Ltd.-Trading as Halcro" }, + { 0x1506, "T.D. Technecon Ltd." }, + { 0x1507, "APIM INFORMATIQUE" }, + { 0x1508, "MAATEL" }, + { 0x1509, "LI-COR Biosciences, Inc." }, + { 0x150A, "TiVo Inc." }, + { 0x150B, "COLLEX COMMUNICATION CORP." }, + { 0x150C, "Brightwell Dispenses Ltd." }, + { 0x150D, "PR Electronics A/S" }, + { 0x150E, "Ono Sokki Co., Ltd." }, + { 0x150F, "Nidec Nemicon Corporation" }, + { 0x1510, "RACEWOOD TELECOM CO., LTD." }, + { 0x1511, "BridgeCo, AG" }, + { 0x1512, "Software Technologies Group, Inc." }, + { 0x1513, "Hypercom" }, + { 0x1514, "ACTEL CORPORATION" }, + { 0x1515, "Hexon Media Pte Ltd" }, + { 0x1516, "Skymedi Corporation" }, + { 0x1517, "Precisa Instruments AG" }, + { 0x1518, "Cheshire Engineering Corporation" }, + { 0x1519, "Comneon GmbH Co., Ohg." }, + { 0x151A, "RoyalTek Company Ltd." }, + { 0x151B, "HOSTNET CO." }, + { 0x151C, "VeriSilicon Holdings Co., Ltd." }, + { 0x151D, "P W Allen & Co." }, + { 0x151E, "Circad Design Ltd." }, + { 0x151F, "Opal Kelly Incorporated" }, + { 0x1520, "Bitwire Corp." }, + { 0x1521, "S++ Simulation Services" }, + { 0x1522, "Educational Insights" }, + { 0x1523, "SII NanoTechnology Inc." }, + { 0x1524, "SCIENTEX Inc." }, + { 0x1525, "Newson Engineering NV" }, + { 0x1526, "ARDUC Co., Ltd." }, + { 0x1527, "iQue Ltd." }, + { 0x1528, "HighAndes Limited" }, + { 0x1529, "UBIQUAM CO., LTD." }, + { 0x152A, "Thesycon Systemsoftware & Consulting GmbH" }, + { 0x152B, "MIR-Medical International Research" }, + { 0x152C, "titel++" }, + { 0x152D, "JMicron Technology Corp." }, + { 0x152E, "HLDS (Hitachi-LG Data Storage, Inc.)" }, + { 0x152F, "PRO-MECH CORPORATION" }, + { 0x1530, "Martsoft Corp." }, + { 0x1531, "MICRODIA Ltd." }, + { 0x1532, "Razer (Asia-Pacific) Pte Ltd." }, + { 0x1533, "AEPTEC Microsystems, Inc." }, + { 0x1534, "Advanced Research Corporation" }, + { 0x1535, "Practical Engineering Incorporated" }, + { 0x1536, "NEONODE AB" }, + { 0x1537, "Power Up Manufacturing" }, + { 0x1538, "IES Elektronikentwicklung" }, + { 0x1539, "AFG-Engineering GmbH" }, + { 0x153A, "WMS Gaming Inc." }, + { 0x153B, "ERCO Leuchten GmbH" }, + { 0x153C, "Guger Technologies OEG" }, + { 0x153D, "Adam Technologies" }, + { 0x153E, "abKey ptd ltd." }, + { 0x153F, "UNIBRAIN S.A." }, + { 0x1540, "Phihong Technology Co., Ltd." }, + { 0x1541, "Better Light, Inc." }, + { 0x1542, "Gemini Industries, Inc." }, + { 0x1543, "Buxco Research Systems" }, + { 0x1544, "Alphamosaic Ltd." }, + { 0x1545, "Kistler Instrumente AG" }, + { 0x1546, "u-blox AG" }, + { 0x1547, "S. Goers IT-Solutions" }, + { 0x1548, "Centrepoint Technologies" }, + { 0x1549, "Beamex Oy Ab" }, + { 0x154A, "ID Innovations Incorporated" }, + { 0x154B, "PNY Technologies Inc." }, + { 0x154C, "AutoXray Inc." }, + { 0x154D, "Rapid Conn, Connect County Holdings Bhd" }, + { 0x154E, "D & M Holdings, Inc." }, + { 0x154F, "Shandong New Beiyang Information Technology Co., Ltd." }, + { 0x1550, "Cardinal Health, Inc." }, + { 0x1551, "SAIC/IISBU" }, + { 0x1552, "DALLAB (M) SDN BHD (587734-A)" }, + { 0x1553, "Raytheon Commercial Infrared" }, + { 0x1554, "Prolink Microsystems Corporation" }, + { 0x1555, "OWEN Ltd." }, + { 0x1556, "CERN" }, + { 0x1557, "OQO" }, + { 0x1558, "Microbus Designs Ltd." }, + { 0x1559, "The Toro Company" }, + { 0x155A, "ELDAT GmbH" }, + { 0x155B, "Shanghai Huahong Integrated Circuit Co., Ltd." }, + { 0x155C, "Meyers Technology" }, + { 0x155D, "National Rejectors, Inc. GmbH" }, + { 0x155E, "DUPLO SEIKO CORPORATION" }, + { 0x155F, "Cobra Electronics Corporation" }, + { 0x1560, "Supra, A UTC Fire & Security Company" }, + { 0x1561, "LaunchPadOffice Inc." }, + { 0x1562, "Infowize Technologies Corporation" }, + { 0x1563, "Micronet Corporation" }, + { 0x1564, "Gizmondo Europe Ltd." }, + { 0x1565, "Advance Modules" }, + { 0x1566, "WIN ACCORD LTD." }, + { 0x1567, "MUTOH Industries Ltd." }, + { 0x1568, "Sunf Pu Technology Co., Ltd" }, + { 0x1569, "Mad City Labs, Inc." }, + { 0x156A, "Logical Solutions, Inc." }, + { 0x156B, "Cairn Research Ltd." }, + { 0x156C, "Meade Instruments Corp." }, + { 0x156D, "OMICRON electronics GmbH" }, + { 0x156E, "MVox Electronics" }, + { 0x156F, "Quantum Corporation" }, + { 0x1570, "ALLTOP TECHNOLOGY CO., LTD." }, + { 0x1571, "NIKON-TRIMBLE CO., LTD." }, + { 0x1572, "Ricreations, Inc." }, + { 0x1573, "Gradiente Eletronica S.A." }, + { 0x1574, "HKW-Elektronik GmbH" }, + { 0x1575, "Video Associates Labs, Inc." }, + { 0x1576, "Maretron" }, + { 0x1577, "MIYUKI ELEX CO., LTD." }, + { 0x1578, "Beijing Huaqi Information Digital Technology Co., Ltd." }, + { 0x1579, "Reputed Industrial Company Limited" }, + { 0x157A, "Lowrance Electronics, Inc." }, + { 0x157B, "Ketron SRL" }, + { 0x157C, "Eurosoft (UK) Ltd." }, + { 0x157D, "Tokyo Sokuteikizai Co., Ltd." }, + { 0x157E, "U-MEDIA Communications, Inc." }, + { 0x157F, "Levon Limited" }, + { 0x1580, "Real Time Logic, Inc." }, + { 0x1581, "IGB Communication Co., Ltd." }, + { 0x1582, "Asia Pacifc Microsystems, Inc." }, + { 0x1583, "EUCHNER GmbH & Co. KG" }, + { 0x1584, "Prueftechnik AG" }, + { 0x1585, "IKeyInfinity Inc." }, + { 0x1586, "Palconn Technology Co., Ltd." }, + { 0x1587, "SMA Solar Technology AG" }, + { 0x1588, "Fine Instruments Corporation" }, + { 0x1589, "Arcus Technology Inc." }, + { 0x158A, "BOBE Industrie-Elektronik" }, + { 0x158B, "Righttag Inc." }, + { 0x158C, "LINFOS CO., LTD." }, + { 0x158D, "Oakley Inc." }, + { 0x158E, "Acterna Germany GmbH" }, + { 0x158F, "Tai Yip Electrical Co., Ltd." }, + { 0x1590, "Onsu Data Telecommunication Technology (Shenzhen) Fty." }, + { 0x1591, "Advanced Product Design & Mfg. Inc." }, + { 0x1592, "Tokyo Drawing Ltd." }, + { 0x1593, "Vector International bvba" }, + { 0x1594, "Lockheed Martin Missiles & Fire Control" }, + { 0x1595, "Flexiworld Technologies, Inc." }, + { 0x1596, "Kilodyne LLC" }, + { 0x1597, "KCodes Corporation" }, + { 0x1598, "Kunshan Guoji Electronics Co., Ltd." }, + { 0x1599, "ANRITSU METER CO., LTD." }, + { 0x159A, "SkuTek Instrumentation" }, + { 0x159B, "Zitte Corporation" }, + { 0x159C, "Binary Acoustic Technology" }, + { 0x159D, "Boone Cable Works & Electronics" }, + { 0x159E, "SmartSwing, Inc." }, + { 0x159F, "Beijer Electronics AB" }, + { 0x15A0, "Zarlink Semiconductor" }, + { 0x15A1, "Nicety Technologies Inc." }, + { 0x15A2, "Freescale Semiconductor, Inc." }, + { 0x15A3, "Larson Davis, Inc." }, + { 0x15A4, "Afa Technologies, Inc." }, + { 0x15A5, "CIT Engineering NV" }, + { 0x15A6, "Unicos Corporation" }, + { 0x15A7, "APPSware Wireless LLC dba Apriva" }, + { 0x15A8, "Shen Zhen Teamspower Electronics Co., Ltd." }, + { 0x15A9, "Gemtek Technology Co., Ltd." }, + { 0x15AA, "Hong Kong Gearway Electronics Co., Ltd." }, + { 0x15AB, "Virgin HealthMiles, Inc." }, + { 0x15AC, "Smartware" }, + { 0x15AD, "Bleile Datentechnik GmbH" }, + { 0x15AE, "KAYSER-THREDE GMBH" }, + { 0x15AF, "Jenaer Antriebstechnik GmbH" }, + { 0x15B0, "Pacific Instruments, Inc." }, + { 0x15B1, "MiTAC Technology Corporation" }, + { 0x15B2, "Audio Dev AB" }, + { 0x15B3, "GL Sciences Inc." }, + { 0x15B4, "Orient Power Multimedia Ltd." }, + { 0x15B5, "ANUBIS ELECTRONIC GmbH" }, + { 0x15B6, "Dialog Semiconductor GmbH" }, + { 0x15B7, "Hyper Stimulator International Pty Ltd." }, + { 0x15B8, "Serome Electronics, Inc." }, + { 0x15B9, "USD Corporation" }, + { 0x15BA, "Olimex Ltd." }, + { 0x15BB, "CopyPro , Inc." }, + { 0x15BC, "Daktronics Inc." }, + { 0x15BD, "Sigmaelectronics Co., Ltd." }, + { 0x15BE, "EssNet Interactive AB" }, + { 0x15BF, "ESA, Inc." }, + { 0x15C0, "CJM" }, + { 0x15C1, "Amirix Systems Inc." }, + { 0x15C2, "SoundGraph, Inc." }, + { 0x15C3, "m.u.t - GmbH" }, + { 0x15C4, "Global Marketing Alliance, Inc." }, + { 0x15C5, "Pressure Profile Systems, Inc." }, + { 0x15C6, "Laboratoires MXM" }, + { 0x15C7, "IRI-Ubiteq, Inc." }, + { 0x15C8, "KTF Technologies" }, + { 0x15C9, "D-Box Technologies" }, + { 0x15CA, "TEXTECH INTERNATIONAL LTD." }, + { 0x15CB, "Activis Polska" }, + { 0x15CC, "GL Communications Inc." }, + { 0x15CD, "DeFelsko Corporation" }, + { 0x15CE, "Oriental R&D Co., Ltd." }, + { 0x15CF, "AVTOR Ltd.." }, + { 0x15D0, "AIRSTAR Inc." }, + { 0x15D1, "Hokuyo Automatic Co., Ltd." }, + { 0x15D2, "REA Elektronik GmbH" }, + { 0x15D3, "Symmetric Research" }, + { 0x15D4, "Opinionmeter International, Ltd." }, + { 0x15D5, "Coulomb Electronics Ltd." }, + { 0x15D6, "Fitness Expert" }, + { 0x15D7, "amaxa GmbH" }, + { 0x15D8, "Grundig Business Systems GmbH" }, + { 0x15D9, "Apexone Microelectronics Inc." }, + { 0x15DA, "Cooper - Atkins Corporation" }, + { 0x15DB, "Philip Harris Education" }, + { 0x15DC, "Hynix Semiconductor Inc." }, + { 0x15DD, "Axona Limited" }, + { 0x15DE, "Spatial Freedom, Inc." }, + { 0x15DF, "Helmut Fischer GmbH + Co. KG" }, + { 0x15E0, "Seong Ji Industrial Co., Ltd." }, + { 0x15E1, "RSA Security Inc." }, + { 0x15E2, "Bionopoly LLC" }, + { 0x15E3, "NEURICAM SPA" }, + { 0x15E4, "Numark Industries" }, + { 0x15E5, "Micro Systems Inc." }, + { 0x15E6, "Turnkey Ltd." }, + { 0x15E7, "Media Systems Ltd." }, + { 0x15E8, "Micro Tools Inc." }, + { 0x15E9, "Pacific Digital Corp." }, + { 0x15EA, "C-guys Inc." }, + { 0x15EB, "VIA Telecom" }, + { 0x15EC, "Belcarra Technologies Corp." }, + { 0x15ED, "UCA Technology Inc." }, + { 0x15EE, "Quorum Communications, Inc." }, + { 0x15EF, "MSilicon Electronics, Inc." }, + { 0x15F0, "Technex Lab Co., Ltd." }, + { 0x15F1, "Mortara Instrument, Inc." }, + { 0x15F2, "Chyron Corp." }, + { 0x15F3, "AquaCube Inc." }, + { 0x15F4, "Computer & Entertainment, Inc." }, + { 0x15F5, "Mobitek Communication Corp." }, + { 0x15F6, "ASICS World Services Ltd." }, + { 0x15F7, "HANTEL CO., LTD." }, + { 0x15F8, "Vianet, Inc." }, + { 0x15F9, "SunCorp Industrial Limited" }, + { 0x15FA, "Department of Defense" }, + { 0x15FB, "R-Quest Technologies , LLC" }, + { 0x15FC, "Humen Xintai Electrical Wires Factory" }, + { 0x15FD, "XEMAX Co., Ltd." }, + { 0x15FE, "Bio-Rad Laboratories Deeside" }, + { 0x15FF, "Heartsine Technologies Ltd." }, + { 0x1600, "Monisys Limited" }, + { 0x1601, "Avenues in Leather" }, + { 0x1602, "CompUSA Inc." }, + { 0x1603, "ERGODEX Corp." }, + { 0x1604, "Kyokko Seiko Co., Ltd." }, + { 0x1605, "Acces I/O Products, Inc." }, + { 0x1606, "UMAX Data Systems Inc." }, + { 0x1607, "ESE Corporate" }, + { 0x1608, "Inside Out Networks, a division of Digi International" }, + { 0x1609, "K-byte (ACI Group)" }, + { 0x160A, "VIA Networking Technologies, Inc." }, + { 0x160B, "CSI Wireless Inc." }, + { 0x160C, "Shanghai Tiananxin Information & Tech., Co., Ltd." }, + { 0x160D, "Samtec" }, + { 0x160E, "INRO Consultants Inc." }, + { 0x160F, "Strand Lighting Limited" }, + { 0x1610, "Q-Sense AB" }, + { 0x1611, "Vita-Mix Corporation" }, + { 0x1612, "Soft DB Inc." }, + { 0x1613, "Airconnect Solutions (Asia) Ltd." }, + { 0x1614, "Amoi Electronics Co., Ltd." }, + { 0x1615, "Rock Data Services Ltd." }, + { 0x1616, "Cute Mobile Corp." }, + { 0x1617, "Navman" }, + { 0x1618, "Redpine Signals, Inc." }, + { 0x1619, "L & K Precision Technology Co., Ltd." }, + { 0x161A, "Celeraise Investments Ltd." }, + { 0x161B, "MYCOM, INC." }, + { 0x161C, "DigiTech Systems Co., Ltd." }, + { 0x161D, "Delfin Technologies Ltd." }, + { 0x161E, "Aerotech Inc." }, + { 0x161F, "Prosisa International LLC" }, + { 0x1620, "Accesstek Inc." }, + { 0x1621, "Wionics Research" }, + { 0x1622, "California Instruments" }, + { 0x1623, "Mindtech Limited" }, + { 0x1624, "AIOI Systems, USA Corp." }, + { 0x1625, "Stonewood" }, + { 0x1626, "Advance Data Technology Corporation" }, + { 0x1627, "IPextreme, Inc." }, + { 0x1628, "Stonestreet One, Inc." }, + { 0x1629, "Erae Electronics" }, + { 0x162A, "Airgo Networks Inc." }, + { 0x162B, "Acksys" }, + { 0x162C, "Ecler Laboratorio de Electroacustica S.A." }, + { 0x162D, "Control Instruments Development (Pty) Ltd." }, + { 0x162E, "Joytech Europe Ltd." }, + { 0x162F, "WiQuest Communications, Inc." }, + { 0x1630, "QformX" }, + { 0x1631, "Focus Enhancements" }, + { 0x1632, "Data Ray Inc." }, + { 0x1633, "AIM GmbH" }, + { 0x1634, "ABB Switzerland Ltd." }, + { 0x1635, "Doble Engineering Co." }, + { 0x1636, "Kobe-Addtech Co., Ltd." }, + { 0x1637, "LZAE LUMEL SA" }, + { 0x1638, "Skyworks Solutions" }, + { 0x1639, "BeRiver Electronics Co., Ltd." }, + { 0x163A, "Traficon N.V." }, + { 0x163B, "Controlled Speed Engineering Ltd." }, + { 0x163C, "Watchdata System Co., Ltd." }, + { 0x163D, "Million Tech Dev. Ltd." }, + { 0x163E, "HongLin Electronics Co., Ltd." }, + { 0x163F, "AVEX Technologies, Inc." }, + { 0x1640, "M3 Electronics, Inc." }, + { 0x1641, "eMagin Corporation" }, + { 0x1642, "AquaSensors LLC" }, + { 0x1643, "Sanwa Newtec Co., Ltd." }, + { 0x1644, "Active Technologies SRL" }, + { 0x1645, "Smiths Heimann Biometrics GmbH" }, + { 0x1646, "Altronic, Inc." }, + { 0x1647, "Horizon Navigation, Inc." }, + { 0x1648, "Wood Head Software & Electronics" }, + { 0x1649, "Softec Microsystems" }, + { 0x164A, "ChipX" }, + { 0x164B, "Lytech Technology Inc." }, + { 0x164C, "Matrix Vision GmbH" }, + { 0x164D, "DASAN Networks, Inc." }, + { 0x164E, "Picotest Corp." }, + { 0x164F, "Kinkei System Co., Ltd." }, + { 0x1650, "Remopro Technology Inc." }, + { 0x1651, "PACOMP" }, + { 0x1652, "EFull Tech. Corp. Ltd." }, + { 0x1653, "Nissho Electronics Co., Ltd." }, + { 0x1654, "Stamer Musikanlagen GmbH" }, + { 0x1655, "Dtron Co., Ltd." }, + { 0x1656, "QSC Audio Products, Inc." }, + { 0x1657, "Struck Innovative Systeme GmbH" }, + { 0x1658, "Grayhill Inc." }, + { 0x1659, "Lathem Time Corp." }, + { 0x165A, "E.D.P. SRL" }, + { 0x165B, "Frontier Design Group" }, + { 0x165C, "Kondo Kagaku Co., Ltd." }, + { 0x165D, "Orange Tree Technologies Ltd." }, + { 0x165E, "Pangolin" }, + { 0x165F, "Ansync Inc." }, + { 0x1660, "Creatix Polymedia GmbH" }, + { 0x1661, "DVS Korea Co., Ltd." }, + { 0x1662, "Positivo Informatica LTDA" }, + { 0x1663, "Sercel, Inc." }, + { 0x1664, "ARGOX INFORMATION CO., LTD." }, + { 0x1665, "General Dynamics Canada" }, + { 0x1666, "Vanguard Instruments Co., Inc." }, + { 0x1667, "GIGA-TMS, INC." }, + { 0x1668, "Actiontec Electronics, Inc." }, + { 0x1669, "PiKRON s.r.o." }, + { 0x166A, "Clipsal Integrated Systems" }, + { 0x166B, "PedalPax Corporation" }, + { 0x166C, "Technology Driven Solutions Ltd" }, + { 0x166D, "MCS Logic Inc." }, + { 0x166E, "SerComm Corporation" }, + { 0x166F, "Idetech Europe S.A." }, + { 0x1670, "Hach Company" }, + { 0x1671, "Telular Corporation" }, + { 0x1672, "MBS GmbH" }, + { 0x1673, "ROBOTIKER" }, + { 0x1674, "Pantone, Inc." }, + { 0x1675, "SE-IR Corporation" }, + { 0x1676, "I-Ware Laboratory Co., Ltd." }, + { 0x1677, "China Integrated Circuit Design Corp., Ltd." }, + { 0x1678, "Matsunichi Information Technology (Shenzhen) Co., Ltd." }, + { 0x1679, "Total Phase" }, + { 0x167A, "USBWARE" }, + { 0x167B, "Pure Digital Technologies" }, + { 0x167C, "Vionics" }, + { 0x167D, "SIM Security & Electronic System GmbH" }, + { 0x167E, "Videa Technology Inc." }, + { 0x167F, "Actigraph, LLC" }, + { 0x1680, "KaVo Dental GmbH" }, + { 0x1681, "Prevo Technologies, Inc." }, + { 0x1682, "Maxwise Production Enterprise Ltd." }, + { 0x1683, "DualCor Technologies, Inc." }, + { 0x1684, "Godspeed Computer Corp." }, + { 0x1685, "Tanic Electroics Ltd." }, + { 0x1686, "ZOOM Corporation" }, + { 0x1687, "Kingmax Digital Inc." }, + { 0x1688, "AerotechTelub AB" }, + { 0x1689, "Griffin International Companies, Inc." }, + { 0x168A, "Veeco Instruments" }, + { 0x168B, "BTC Secu Co., Ltd." }, + { 0x168C, "Tabor Electroics Ltd." }, + { 0x168D, "YSI, Inc." }, + { 0x168E, "iMetrikus Inc." }, + { 0x168F, "ETA S.A. Manufacture Horlogere Suisse" }, + { 0x1690, "Simple Solutions" }, + { 0x1691, "Landers Instruments" }, + { 0x1692, "Weatherford" }, + { 0x1693, "Zultys Technologies" }, + { 0x1694, "Cassidian Communications" }, + { 0x1695, "FATAR, S.r.l." }, + { 0x1696, "Hitachi Advanced Digital, Inc." }, + { 0x1697, "VTEC TEST, INC." }, + { 0x1698, "Eurosmart" }, + { 0x1699, "United RadioTek Inc." }, + { 0x169A, "Ten X Technology Inc." }, + { 0x169B, "aitronic GmbH" }, + { 0x169C, "DMS" }, + { 0x169E, "Groupics.com, Inc." }, + { 0x169F, "Monolith Inc." }, + { 0x16A0, "Real Thoughts GmbH" }, + { 0x16A1, "Trilithic, Inc." }, + { 0x16A2, "Sypris Test and Measurement (FW Bell)" }, + { 0x16A3, "B & W Tek Inc." }, + { 0x16A4, "Sagutech Microsystems" }, + { 0x16A5, "Shenzhen Zhengerya Technology Co., Ltd." }, + { 0x16A6, "UNIGRAF OY" }, + { 0x16A7, "Sauer-Danfoss" }, + { 0x16A8, "Nice Systems" }, + { 0x16A9, "Worth-Pfaff Innovations, Inc." }, + { 0x16AA, "Symtx Inc." }, + { 0x16AB, "InnoWireless Co. Ltd." }, + { 0x16AC, "Dongguan ChingLung Wire & Cable Co., Ltd." }, + { 0x16AD, "Siemens VDO Trading GmbH" }, + { 0x16AE, "ELSA Japan Inc." }, + { 0x16AF, "Intelligent Mechatronic Systems" }, + { 0x16B0, "Infosight Corp." }, + { 0x16B1, "Cami Research Inc." }, + { 0x16B2, "Bruxton Corporation" }, + { 0x16B3, "Eizoken Inc." }, + { 0x16B4, "Digital Cube" }, + { 0x16B5, "PerSen Technologies, Inc." }, + { 0x16B6, "Nexus Technology Inc." }, + { 0x16B7, "Pulsafeeder Inc." }, + { 0x16B8, "Honeywell Life Safety" }, + { 0x16B9, "Origin Technologies Limited" }, + { 0x16BA, "SmarTec" }, + { 0x16BB, "Tomra Systems ASA" }, + { 0x16BC, "JOBO AG" }, + { 0x16BD, "Leica Geosystems AG" }, + { 0x16BE, "RyuSyo Industrial Co., Ltd." }, + { 0x16BF, "CAST, INC." }, + { 0x16C0, "Van Ooijen Technische Informatica" }, + { 0x16C1, "Lucas-Nuelle GmbH" }, + { 0x16C2, "Amphenol-Data Telecom" }, + { 0x16C3, "Nihon Kaiheiki Ind. Co., Ltd." }, + { 0x16C4, "SavaJe Technologies, Inc." }, + { 0x16C5, "Cryptek Inc." }, + { 0x16C6, "NDS Surgical Imaging, LLC" }, + { 0x16C7, "Crystal Technology, Inc." }, + { 0x16C8, "Technische Universiteit Eindhoven" }, + { 0x16C9, "OCT Co., Ltd." }, + { 0x16CA, "Wireless Cables Inc." }, + { 0x16CB, "Highwater Designs Limited" }, + { 0x16CC, "silex technology, Inc." }, + { 0x16CD, "Brian Moore Guitars, Inc." }, + { 0x16CE, "IPFlex Inc." }, + { 0x16CF, "YAZAKI PARTS CO., LTD." }, + { 0x16D1, "SUPREMA, INC." }, + { 0x16D2, "TOMEY" }, + { 0x16D3, "Frontline Test Equipment, Inc." }, + { 0x16D4, "SRTechnologies" }, + { 0x16D5, "AnyDATA Corporation" }, + { 0x16D6, "Jablotron" }, + { 0x16D7, "Aprilis, Inc." }, + { 0x16D8, "CMOTECH CO., LTD." }, + { 0x16D9, "A7 Engineering, Inc." }, + { 0x16DA, "Linkam Scientific Instruments Ltd." }, + { 0x16DB, "Eridon Corporation" }, + { 0x16DC, "W-IE-NE-R, Plein & Baus GmbH" }, + { 0x16DD, "YOSHIDA SEIKI CO., LTD." }, + { 0x16DE, "Schneider Electric" }, + { 0x16DF, "King Billion Electronics Co., Ltd." }, + { 0x16E0, "Lumex Ltd." }, + { 0x16E1, "Bed Check Corporation" }, + { 0x16E2, "Hitachi I E Systems Co., Ltd." }, + { 0x16E3, "ITM Inc." }, + { 0x16E4, "Franklin Electric Co., Inc." }, + { 0x16E5, "TOKYO KEIKI RAIL TECHNO INC." }, + { 0x16E6, "Diginfo Technology Corporation" }, + { 0x16E7, "United Keys, Inc." }, + { 0x16E8, "Frontier Information Enterprise, Inc." }, + { 0x16E9, "Dr. Gal Ben-David" }, + { 0x16EA, "Avionica, Inc." }, + { 0x16EB, "Helvar" }, + { 0x16EC, "ASAHI GLASS CO., LTD." }, + { 0x16ED, "Parker Vision Inc." }, + { 0x16EE, "Ryvor Corp." }, + { 0x16EF, "Global Safety & Security Solutions OY" }, + { 0x16F0, "GN ReSound" }, + { 0x16F1, "Versus Technology, Inc." }, + { 0x16F2, "St. Jude Medical AB" }, + { 0x16F3, "Hammer Storage/Bell Microproducts" }, + { 0x16F4, "Lineeye Co., Ltd." }, + { 0x16F5, "Futurelogic Inc." }, + { 0x16F6, "Shin Tek Inc." }, + { 0x16F7, "Japan Gals Co., Ltd." }, + { 0x16F8, "Ever Bright Wire Factory" }, + { 0x16F9, "Astrosys International Limited" }, + { 0x16FA, "Shachihata Inc." }, + { 0x16FB, "MICRONIX CORPORATION" }, + { 0x16FC, "TRICOM TECHNOLOGIES, INC." }, + { 0x16FD, "Reakin Technology Corporation" }, + { 0x16FE, "Su Zhou Song Qing Electronical Co., Ltd." }, + { 0x16FF, "Ultimate Technology Corp." }, + { 0x1700, "Hunt Engineering (UK) Ltd." }, + { 0x1701, "Peyroutet Telecom" }, + { 0x1702, "Softcare Ltd." }, + { 0x1703, "NormSoft, Inc." }, + { 0x1704, "ANIMATICS CORP." }, + { 0x1705, "Aerosonic Corporation" }, + { 0x1706, "BlueView Technologies, Inc." }, + { 0x1707, "ARTIMI" }, + { 0x1708, "Mibudenki Industrial Co., Ltd." }, + { 0x1709, "Sanmina-SCI" }, + { 0x170A, "MAXTEK, INC." }, + { 0x170B, "Phonic Corp." }, + { 0x170C, "BlueTree Wireless Data" }, + { 0x170D, "Avnera" }, + { 0x170E, "Iris Corporation Berhad" }, + { 0x170F, "UbiBro Technolgies Inc." }, + { 0x1710, "AZIO Corporation" }, + { 0x1711, "Leica Microsystems CMS GmbH" }, + { 0x1712, "Fujitsu LSI Technology Ltd." }, + { 0x1713, "Enter Tech Co., Ltd" }, + { 0x1714, "iCRco" }, + { 0x1715, "NL Technology" }, + { 0x1716, "LHR Technologies" }, + { 0x1717, "Formats Unlimited, Inc." }, + { 0x1718, "Mobile Doctor Co., Ltd." }, + { 0x1719, "American Technology Corp." }, + { 0x171A, "PSi Printer Systems international GmbH" }, + { 0x171B, "NT Ware Systemprogrammierung GmbH" }, + { 0x171C, "IER" }, + { 0x171E, "PACIFIC CORPORATION" }, + { 0x171F, "CHIPNUTS TECHNOLOGY INC." }, + { 0x1720, "Innova Electronics Corp." }, + { 0x1721, "ELAD SRL" }, + { 0x1722, "Axicon Auto ID LTD" }, + { 0x1723, "Datatronics Technology, Inc" }, + { 0x1724, "Lumenera Corporation" }, + { 0x1725, "HI-TECH Software" }, + { 0x1726, "Axesstel, Inc." }, + { 0x1727, "RiCHIP Incorporated" }, + { 0x1728, "BYTE TOOLS INC." }, + { 0x1729, "CONSULTRONICS EUROPE LTD." }, + { 0x172A, "wenglor sensoric gmbh" }, + { 0x172B, "CompuSoft A/S" }, + { 0x172C, "Silicon Optix" }, + { 0x172D, "AccFast Technology Corp." }, + { 0x172E, "ELECTION SYSTEMS & Software" }, + { 0x172F, "WALTOP International Corporation" }, + { 0x1730, "MERCURY" }, + { 0x1731, "DATA DISPLAY AG" }, + { 0x1732, "NETENRICH INC." }, + { 0x1733, "NUBYTECH INC." }, + { 0x1734, "IPdrum AB" }, + { 0x1735, "Satloc LLC (CSI Wireless)" }, + { 0x1736, "CANON IMAGING SYSTEMS INC." }, + { 0x1737, "Hong Kong Applied Science and Technology Research Inst." }, + { 0x1738, "Asicen Technology Corp." }, + { 0x1739, "Radiant Technologies Inc." }, + { 0x173A, "Roche Diagnostics" }, + { 0x173B, "Cadillac Jack Inc." }, + { 0x173C, "Signalcraft Technologies Inc." }, + { 0x173D, "Great Pleasure Electronics Co. LTD." }, + { 0x173E, "Devlin Electronics Ltd." }, + { 0x173F, "Peyer Engineering" }, + { 0x1740, "Senao International Co., Ltd." }, + { 0x1741, "Techino Science Co., Ltd." }, + { 0x1742, "Nippon Chemi-Con Corp." }, + { 0x1743, "General Atomics" }, + { 0x1744, "Sanwa Electronic Instrument Co. Ltd." }, + { 0x1745, "Video Simplex, Inc." }, + { 0x1746, "Edge Products" }, + { 0x1747, "CML MICROCIRCUITS (UK) LTD" }, + { 0x1748, "MQP Electronics Ltd." }, + { 0x1749, "MAGO MOBILE LTD" }, + { 0x174A, "Endress + Hauser" }, + { 0x174B, "BARACODA" }, + { 0x174C, "ASMedia Technology Inc." }, + { 0x174D, "Broadcast System & Design ApS" }, + { 0x174E, "Xi'an Tongshi Data Co., Ltd." }, + { 0x174F, "D-MAX Technology Co., Ltd." }, + { 0x1750, "Hirschmann Automation and Control GmbH" }, + { 0x1751, "EMPIRISOFT CORPORATION" }, + { 0x1752, "Liyitec Incorporated" }, + { 0x1753, "Tecvan Informatica LTDA" }, + { 0x1754, "GERSTEL GmbH & Co. KG" }, + { 0x1755, "Electronics and Telecommunication Research Institute" }, + { 0x1756, "ENENSYS Technologies" }, + { 0x1757, "ST-MICHAEL STRATEGIES" }, + { 0x1758, "FUTURECOM SYSTEMS GROUP INC." }, + { 0x1759, "LucidPort Technology, Inc." }, + { 0x175A, "Lantronix" }, + { 0x175B, "Dongguan Init Technology Co., Ltd." }, + { 0x175C, "Isolcell Italia SpA" }, + { 0x175D, "Caterpillar Inc." }, + { 0x175E, "AT KidSystems Inc." }, + { 0x175F, "I-BIT Corporation" }, + { 0x1760, "RAYLASE AG" }, + { 0x1761, "RC GROUP (Holdings) Limited" }, + { 0x1763, "USAF" }, + { 0x1764, "KANOMAX JAPAN INC." }, + { 0x1765, "VK Corporation" }, + { 0x1766, "Hip Interactive Inc." }, + { 0x1767, "KIS Photo Mc Group" }, + { 0x1769, "ARTEK Inc." }, + { 0x176A, "GLOBALSAT TECHNOLOGY CORPORATION" }, + { 0x176B, "ATOP ELECTRONICS CO., LTD." }, + { 0x176C, "Advanced Electronic Designs" }, + { 0x176D, "Mbridge Systems, Inc." }, + { 0x176E, "UD electronic corp." }, + { 0x176F, "Astralink Technology Pte Ltd" }, + { 0x1770, "precisionWave Corporation" }, + { 0x1771, "Shenzhen Alex Connector Co., Ltd." }, + { 0x1772, "System Level Solutions, Inc." }, + { 0x1773, "InSync Speech Technologies, Inc." }, + { 0x1774, "Strawberry Linux Co., Ltd." }, + { 0x1775, "RADAR-TRONIC KFT." }, + { 0x1776, "HYPERLABS, Inc." }, + { 0x1777, "Microscan Systems, Inc." }, + { 0x1778, "PChome Online Inc." }, + { 0x1779, "Optek Electronics Co., Ltd." }, + { 0x177A, "Explore Semiconductor, Inc." }, + { 0x177B, "Cetus Engineering" }, + { 0x177C, "AD Information & Communications Co., Ltd" }, + { 0x177D, "Delta Industrie Service" }, + { 0x177E, "mils electronic GmbH & Co Kg" }, + { 0x177F, "Sweex Europe B.V." }, + { 0x1780, "TENDYRON CORPORATION" }, + { 0x1781, "MECANIQUE" }, + { 0x1782, "Spreadtrum Communications Inc." }, + { 0x1783, "Foster Flight, Inc." }, + { 0x1784, "TopSeed Technology Corp." }, + { 0x1785, "CARALLON LIMITED" }, + { 0x1786, "Xeltek Inc." }, + { 0x1787, "TRIDENT SYSTEMS, INC." }, + { 0x1788, "ShenZhen Litkconn Technology Co., Ltd." }, + { 0x1789, "Ascom (Schweiz) AG" }, + { 0x178A, "Prentke Romich Company" }, + { 0x178B, "Panduit Corp." }, + { 0x178C, "URTEK TECHNOLOGIES INC." }, + { 0x178D, "CEIVA Logic, Inc." }, + { 0x178E, "Movimento Group AB" }, + { 0x1790, "Ueda Japan Radio Co., Ltd." }, + { 0x1791, "SYNTHETIC PLANNING INDUSTRY CO., LTD." }, + { 0x1792, "LINK GmbH" }, + { 0x1793, "Heim Systems GmbH" }, + { 0x1794, "MA'AGALIM COMPUTER SYSTEMS Ltd." }, + { 0x1795, "INTEGRATION ASSOCIATES INCORPORATED" }, + { 0x1796, "Printrex, Inc." }, + { 0x1797, "JALCO CO., LTD." }, + { 0x1798, "TYPE TECHNOLOGY INC." }, + { 0x1799, "Thales Norway AS" }, + { 0x179A, "Conrad Electronic GmbH" }, + { 0x179B, "HANDSFULL TECHNOLOGY CORP." }, + { 0x179C, "Net-2Com Corporation" }, + { 0x179D, "Ricavision International Inc." }, + { 0x179E, "Silicon Engines" }, + { 0x179F, "CLIQ LIMITED" }, + { 0x17A0, "Samson Technologies Corp." }, + { 0x17A1, "Taiwan Advanced Sensors Corporation" }, + { 0x17A2, "Vantage Controls, Inc." }, + { 0x17A3, "OnTime tek Inc." }, + { 0x17A4, "Concept 2" }, + { 0x17A5, "Advanced Connection Technology Inc." }, + { 0x17A6, "Astron Clinica Ltd." }, + { 0x17A7, "MICOMSOFT CO., LTD." }, + { 0x17A8, "Kamstrup A/S" }, + { 0x17A9, "MULTIMEDIA GAMES, INC." }, + { 0x17AA, "SETEK Elektronik AB" }, + { 0x17AB, "i-Bulldog Co., Ltd." }, + { 0x17AC, "Dengen Automation Co., Ltd." }, + { 0x17AD, "TRIOC AB" }, + { 0x17AE, "NAD Electronics International/A Div. of Lenbrook Ind." }, + { 0x17AF, "GIGABYTE Communications Inc." }, + { 0x17B0, "Weinmann Geraete fuer Medizen GmbH+Co. KG" }, + { 0x17B1, "ViaSat, Inc." }, + { 0x17B2, "Metec GmbH" }, + { 0x17B3, "Grey Innovation Pty., Ltd." }, + { 0x17B4, "Apres Health & Fitness" }, + { 0x17B5, "Lunatone Industrielle Elektronik GmbH" }, + { 0x17B6, "Hydronix Limited" }, + { 0x17B7, "Sinter Information Corp." }, + { 0x17B8, "Trojan Technologies Private Limited" }, + { 0x17B9, "Green Bit S.p.A." }, + { 0x17BA, "Sauris GmbH" }, + { 0x17BB, "Weihai Dongxing Electronics Co., Ltd." }, + { 0x17BC, "Advanced Peripherals Technologies, Inc." }, + { 0x17BD, "Citron Electronic Co., Ltd." }, + { 0x17BE, "Dongguan Yangming Precision of Plastic Metal Elec.Co.Lt" }, + { 0x17BF, "Ampere Inc." }, + { 0x17C0, "ED Co., Ltd." }, + { 0x17C1, "Sirius XM Radio" }, + { 0x17C2, "Ingenient Technologies" }, + { 0x17C3, "SGB Group Ltd." }, + { 0x17C4, "VISIOWAVE SA" }, + { 0x17C5, "Hantle System Co., Ltd." }, + { 0x17C6, "Magnetox" }, + { 0x17C7, "AIM Infrarot-Module GmbH" }, + { 0x17C8, "Ringway Tech (JiangSu) Co., Ltd." }, + { 0x17C9, "Andros Incorporated" }, + { 0x17CA, "CyberPak Co." }, + { 0x17CB, "CHINA HUAXU GOLDEN CARD CO., LTD." }, + { 0x17CC, "Native Instruments Software Synthesis GmbH" }, + { 0x17CD, "Basler Electric" }, + { 0x17CE, "Keymile AG" }, + { 0x17CF, "Hip Hing Cable & Plug Mfy. Ltd." }, + { 0x17D0, "Sanford L.P." }, + { 0x17D1, "ViDisys GmbH" }, + { 0x17D2, "Radiometer Medical ApS" }, + { 0x17D3, "Korea Techtron Co., Ltd." }, + { 0x17D4, "Kenetics Innovations Pte. Ltd., Singapore" }, + { 0x17D5, "ImageMap Inc." }, + { 0x17D6, "Samsung Electronics Research Institute" }, + { 0x17D7, "Copley Controls Corp." }, + { 0x17D8, "Rapattoni Corporation" }, + { 0x17D9, "Rasteme Systems Co., Ltd." }, + { 0x17DA, "GEMIT GmbH" }, + { 0x17DB, "CYNOVE" }, + { 0x17DC, "Thermoteknix Systems Ltd." }, + { 0x17DD, "Simply Automated, Incorporated" }, + { 0x17DE, "Grant Instruments" }, + { 0x17DF, "SOUTHWING" }, + { 0x17E0, "Big Sky Laser" }, + { 0x17E1, "ORTHOFIX" }, + { 0x17E2, "PIKAONE" }, + { 0x17E3, "Beck IPC GmbH" }, + { 0x17E4, "OKB SAPR" }, + { 0x17E5, "Memcorp Inc." }, + { 0x17E6, "Quantel Medical" }, + { 0x17E7, "Sirah Laser-und Plasmatechnik GmbH" }, + { 0x17E8, "Visionee S.R.L." }, + { 0x17E9, "DisplayLink (UK) Ltd." }, + { 0x17EA, "Web Technology Corp" }, + { 0x17EB, "Cornice, Inc." }, + { 0x17EC, "Telsource" }, + { 0x17ED, "Sumita Optical Glass, Inc." }, + { 0x17EE, "Personal Media Corporation" }, + { 0x17EF, "Lenovo" }, + { 0x17F0, "Bestronic Industry Co., Ltd." }, + { 0x17F1, "Microjet Technology Co., Ltd." }, + { 0x17F2, "Xmultiple Technologies Inc." }, + { 0x17F3, "Terascala, Inc." }, + { 0x17F4, "AgaMatrix, Inc." }, + { 0x17F5, "K.K. Rocky" }, + { 0x17F6, "Unicomp, Inc" }, + { 0x17F7, "Metroptic Technologies Ltd." }, + { 0x17F8, "Enustech, Inc." }, + { 0x17F9, "GIE Sesam-Vitale" }, + { 0x17FA, "DOSHISHA CORPORATION" }, + { 0x17FB, "Emutec Inc." }, + { 0x17FC, "Vitesse Semiconductor Corp." }, + { 0x17FD, "Formac GmbH" }, + { 0x17FE, "NIPPON PULSE MOTOR CO., LTD." }, + { 0x17FF, "Unication Co., Ltd" }, + { 0x1800, "Shandong Yuanda Net & Multimedia Co., Ltd." }, + { 0x1801, "Southern Data Comm, Inc." }, + { 0x1802, "SYN-TEK Technologies Inc." }, + { 0x1803, "Secutronix" }, + { 0x1804, "Clemens GmbH" }, + { 0x1805, "Digital Peripheral Solutions Inc." }, + { 0x1806, "New Index AS" }, + { 0x1807, "Par-Tech Inc." }, + { 0x1808, "Multiplex Engineering Inc." }, + { 0x1809, "Advantech Co., Ltd." }, + { 0x180A, "Technosystem Co., Ltd." }, + { 0x180B, "Photo Research, Inc." }, + { 0x180C, "Power Digital Card Co., Ltd." }, + { 0x180D, "U3, LLC" }, + { 0x180E, "Audisoft Technologies" }, + { 0x180F, "Phonak Communications AG" }, + { 0x1810, "Wanshih Electronic Co., Ltd." }, + { 0x1811, "Blackspot Interactive Ltd." }, + { 0x1812, "GEWI GmbH" }, + { 0x1813, "HAGIWARA ELECTRIC Co., Ltd." }, + { 0x1814, "Fashionow Co. Ltd." }, + { 0x1815, "Horizon Semiconductors Ltd." }, + { 0x1816, "Directed Electronics" }, + { 0x1817, "Digital Authentication Technologies, Inc." }, + { 0x1818, "Osteosys Co., Ltd." }, + { 0x1819, "Quality Vision International, Inc." }, + { 0x181A, "Fotonation" }, + { 0x181B, "Current Designs, Inc." }, + { 0x181C, "Rensselaer Polytechnic Institute" }, + { 0x181D, "Axon Systems Inc." }, + { 0x181E, "Advanced Tracking Technologies, Inc." }, + { 0x181F, "NAKAJIMA ALL Co., Ltd." }, + { 0x1820, "DSM - Messtechnik GmbH" }, + { 0x1821, "INwireless Co., Ltd" }, + { 0x1822, "DIGIBIO TECHNOLOGY CORP." }, + { 0x1823, "CelleBrite Mobile Synchronization" }, + { 0x1824, "Aval Nagasaki Corp." }, + { 0x1825, "Star-Dundee Ltd." }, + { 0x1826, "Xitron Inc." }, + { 0x1827, "Sanko Electronics Co., Ltd." }, + { 0x1828, "TSR Silicon Resources, Inc." }, + { 0x1829, "Dongguan YuQiu Electronics Co., Ltd." }, + { 0x182A, "Signalion GmbH" }, + { 0x182B, "Chest M.I., Incorporated" }, + { 0x182C, "Caliper LifeSciences" }, + { 0x182D, "Accutron Limited" }, + { 0x182E, "System Instruments Co., Ltd." }, + { 0x182F, "Worldwide Productions Inc." }, + { 0x1830, "I CAP Technologies, Inc." }, + { 0x1831, "Gwo Jinn Industries Co., Ltd." }, + { 0x1832, "Huizhou Shenghua Industrial Co., Ltd." }, + { 0x1833, "Genuine Technologies Co., Ltd." }, + { 0x1834, "SONEL S.A." }, + { 0x1835, "Lust Drivetronics GmbH" }, + { 0x1836, "ePoint Technology" }, + { 0x1837, "Hokuto Denko Corporation" }, + { 0x1838, "Real Networks, Inc." }, + { 0x1839, "AnexTEK Global Inc." }, + { 0x183A, "Mediafour Corporation" }, + { 0x183B, "SIDACON Systemtechnik GmbH" }, + { 0x183C, "Saab AB" }, + { 0x183D, "F3 Inc." }, + { 0x183E, "Robonik India Pvt. Ltd." }, + { 0x183F, "i-BEAD Co., Ltd." }, + { 0x1840, "Cognitive Solutions, Inc." }, + { 0x1841, "SEIKO TIME SYSTEM INC." }, + { 0x1842, "Keen High Technologies (HK) Ltd." }, + { 0x1843, "Vaisala" }, + { 0x1844, "Radiotechnika Marketing Sp.zo.o" }, + { 0x1845, "Cion Technology Corporation" }, + { 0x1846, "microEngineering Labs, Inc." }, + { 0x1847, "Global Payment Technologies, Inc." }, + { 0x1848, "Eurochannels Holding B.V." }, + { 0x1849, "Centurion Systems (Pty) Ltd." }, + { 0x184A, "EB Neuro SPA" }, + { 0x184B, "ARION Technology Inc." }, + { 0x184C, "Centice" }, + { 0x184D, "Dansk Automat Expert A/S" }, + { 0x184E, "SyGade Solutions (Pty) Ltd." }, + { 0x184F, "K2L GmbH" }, + { 0x1850, "Andigilog, Inc." }, + { 0x1851, "ULTRASONIC ENGINEERING CO., LTD." }, + { 0x1852, "TENOR ELECTRONICS CORP." }, + { 0x1853, "MITSUBISHI PRECISION CO., LTD." }, + { 0x1854, "Memory Devices Ltd." }, + { 0x1855, "Redpay Secure Payments" }, + { 0x1856, "Imaginova" }, + { 0x1857, "Picosecond Pulse Labs" }, + { 0x1858, "CELLSYSTEM CO., LTD" }, + { 0x1859, "Speech Technology Center, Ltd." }, + { 0x185A, "WinProbe Corporation" }, + { 0x185B, "IG-Development" }, + { 0x185C, "Omnisec AG" }, + { 0x185D, "Origgio Limited" }, + { 0x185E, "Meritech Co., Ltd." }, + { 0x185F, "Stinger Systems Inc." }, + { 0x1860, "HYUPJIN I & C CO, LTD." }, + { 0x1861, "Tech Technology Industrial Company" }, + { 0x1862, "Teridian Semiconductor Corp." }, + { 0x1863, "Wave Technology Co., Ltd." }, + { 0x1864, "Digital Art System" }, + { 0x1865, "Europlex Technologies" }, + { 0x1866, "Union Community Co., Ltd." }, + { 0x1867, "Control Microsystems" }, + { 0x1868, "Index Braille AB" }, + { 0x1869, "RTS Automation GmbH" }, + { 0x186A, "Pivot International, Inc." }, + { 0x186B, "Holophase Incorporated" }, + { 0x186C, "Miyachi Corporation" }, + { 0x186D, "Evermore Innovations" }, + { 0x186E, "Reel Stream LLC" }, + { 0x186F, "Motion Lingo, LLC" }, + { 0x1870, "Nexio Co., Ltd." }, + { 0x1871, "Aveo Technology Corp." }, + { 0x1872, "Cobalt Technologies Co., Ltd." }, + { 0x1873, "Etrovision Technology" }, + { 0x1874, "Nexilion Inc." }, + { 0x1875, "Humo Laboratory, Ltd." }, + { 0x1876, "MG Industrieelektronik GmbH" }, + { 0x1877, "SANEI HYTECHS Co., Ltd." }, + { 0x1878, "Sumitomo Heavy Industries, Ltd." }, + { 0x1879, "Spin Semiconductor Inc." }, + { 0x187A, "Mediachorus Inc." }, + { 0x187B, "Dent Instruments, Inc." }, + { 0x187C, "Alienware Corporation" }, + { 0x187D, "Ardware Ltd." }, + { 0x187E, "Sentelic Corporation" }, + { 0x187F, "Siano Mobile Silicon Ltd." }, + { 0x1880, "Vericon Co., Ltd./Jinn Shyang Precision Industrial Co.," }, + { 0x1881, "Interactive Learning Technologies" }, + { 0x1882, "TransChip Israel Ltd." }, + { 0x1883, "Tanaka S/S Ltd." }, + { 0x1884, "Liyuh Technology Ltd." }, + { 0x1885, "Ascalade Communications Inc." }, + { 0x1886, "Metalink Ltd." }, + { 0x1887, "Fishcamp Engineering" }, + { 0x1888, "Livingston Products, Inc." }, + { 0x1889, "DME Corporation" }, + { 0x188A, "Moeller" }, + { 0x188B, "Showa Electric Laboratory Co., Ltd." }, + { 0x188C, "Epos Development Ltd." }, + { 0x188D, "Across Techno, Inc." }, + { 0x188E, "Neopost Technologies" }, + { 0x188F, "Zefatek Co., Ltd." }, + { 0x1890, "MEDIAN Inc." }, + { 0x1891, "XSENSOR Technology Corp." }, + { 0x1892, "Accuri Instruments, Inc." }, + { 0x1893, "Ginga Software, Inc." }, + { 0x1894, "SyntheSys Research, Inc." }, + { 0x1895, "tesa scribos GmbH" }, + { 0x1896, "Legacy Electronics, Inc." }, + { 0x1897, "Evertop Wire Cable Co." }, + { 0x1898, "Summit Microelectronics" }, + { 0x1899, "Linkiss Co., Ltd." }, + { 0x189A, "Earth Computer Technologies, Inc." }, + { 0x189B, "Trimax Electronics Co., Ltd." }, + { 0x189C, "Walletex Microelectronics Ltd." }, + { 0x189D, "Navionics Inc." }, + { 0x189E, "Net Insight AB" }, + { 0x189F, "3Shape A/S" }, + { 0x18A0, "Kongsberg Maritime AS" }, + { 0x18A1, "Ionwerks, Inc." }, + { 0x18A2, "PSIA Corp." }, + { 0x18A3, "DIGIFRIENDS CO., LTD." }, + { 0x18A4, "CSSN, Inc. dba Card Scanning Solutions" }, + { 0x18A5, "Verbatim Americas LLC" }, + { 0x18A6, "Peripheral Dynamics Inc." }, + { 0x18A7, "Omniprint Inc." }, + { 0x18A8, "Smiths Medical MD" }, + { 0x18A9, "Veri-Tek International" }, + { 0x18AA, "MedRx Inc." }, + { 0x18AB, "Applied Data Systems, Inc." }, + { 0x18AC, "STRATEC Biomedical Systems AG" }, + { 0x18AD, "Invisible Technologies, Inc." }, + { 0x18AE, "MTT Corporation" }, + { 0x18AF, "LN Systems Limited" }, + { 0x18B0, "Mikrodidakt AB" }, + { 0x18B1, "Elmak Ltd." }, + { 0x18B2, "CINTEL FRANCE" }, + { 0x18B3, "RAYDON Corporation" }, + { 0x18B4, "e3C Inc." }, + { 0x18B5, "Klipsch Audio" }, + { 0x18B6, "Mikkon Technology Limited" }, + { 0x18B7, "Zotek Electronic Co., Ltd." }, + { 0x18B8, "Securewave SA" }, + { 0x18B9, "Clixxun GmbH" }, + { 0x18BA, "Bell Fruit Games" }, + { 0x18BB, "G7 Productivity Systems" }, + { 0x18BC, "Muro Co., Ltd" }, + { 0x18BD, "MNBT Co., Ltd." }, + { 0x18BE, "Kingfisher International" }, + { 0x18BF, "Ensyc Technologies" }, + { 0x18C0, "Gatekeeper Systems Inc." }, + { 0x18C1, "Shenzhen SDMC Microelectronics Co., Ltd." }, + { 0x18C2, "AccuSport International, Inc." }, + { 0x18C3, "Elite Semiconductor Memory Technology Inc. (ESMT)" }, + { 0x18C4, "ServerEngines LLC" }, + { 0x18C5, "Corega Taiwan, Inc." }, + { 0x18C6, "Aurora Photonics" }, + { 0x18C7, "Nagano Tectron Co., Ltd" }, + { 0x18C8, "Computerprox Corp." }, + { 0x18C9, "Exfo Electro-Optical Engineering Inc." }, + { 0x18CA, "Canon Korea Business Solutions Inc." }, + { 0x18CB, "Fr. Sauter AG" }, + { 0x18CC, "Osaki Electric Co., Ltd." }, + { 0x18CD, "Pico Instruments LLC" }, + { 0x18CE, "DTC Communications, Inc" }, + { 0x18CF, "Tung Shu Mei Industrial Co., Ltd." }, + { 0x18D0, "Uniform Industrial Corp." }, + { 0x18D1, "Google Inc." }, + { 0x18D2, "Raptor Gaming Technology GmbH" }, + { 0x18D3, "L&V Design" }, + { 0x18D4, "ABI Electronics Ltd." }, + { 0x18D5, "Starline International Group Limited" }, + { 0x18D6, "Ruetz Technologies" }, + { 0x18D7, "New Scale Technologies" }, + { 0x18D8, "Individual Computers" }, + { 0x18D9, "Kaba" }, + { 0x18DA, "Phonol Inc." }, + { 0x18DB, "Compix Incorporated" }, + { 0x18DC, "LKC Technologies, Inc." }, + { 0x18DD, "Docuport WC" }, + { 0x18DE, "Cyto Pulse Sciences, Inc" }, + { 0x18DF, "Cinea Inc." }, + { 0x18E0, "Source Technologies, LLC" }, + { 0x18E1, "Drew Technologies Inc." }, + { 0x18E2, "S.J. Electronics Co., Ltd" }, + { 0x18E3, "Fitilink Integrated Technology, Inc." }, + { 0x18E4, "SB Solutions, Inc" }, + { 0x18E5, "Ablaze Systems LLC" }, + { 0x18E6, "Gobex AS" }, + { 0x18E7, "Truscott Designs" }, + { 0x18E8, "Mondo Systems" }, + { 0x18E9, "Numsite Corporation" }, + { 0x18EA, "Matrox Electronic Systems" }, + { 0x18EB, "nDezign, Inc." }, + { 0x18EC, "Arkmicro Technologies Inc." }, + { 0x18ED, "Tyco Safety Products" }, + { 0x18EE, "Holm Acoustics" }, + { 0x18EF, "ELV Elektronik AG" }, + { 0x18F0, "AVAL DATA CORPORATION" }, + { 0x18F1, "AL Tech, Inc." }, + { 0x18F2, "Rasotto S.N.C." }, + { 0x18F3, "Miglia Technology Ltd." }, + { 0x18F4, "Vtech Engineering Corporation" }, + { 0x18F5, "Esterline Mason" }, + { 0x18F6, "Zermatt Systems Inc" }, + { 0x18F7, "ImageStream Internet Solutions Inc.." }, + { 0x18F8, "Teitsu Denshi Kenkyusho Co., Ltd." }, + { 0x18F9, "EX COMPANY LIMITED" }, + { 0x18FA, "Kuang Ying Computer Equipment Co., Ltd." }, + { 0x18FB, "Scriptel Corporation" }, + { 0x18FC, "Kinyo Co., Ltd." }, + { 0x18FD, "FineArch Inc." }, + { 0x18FE, "SecuriMetrics, Inc." }, + { 0x18FF, "HYUNDAI Digital Technology Co., Ltd." }, + { 0x1900, "Future Wave, Inc." }, + { 0x1901, "GE Healthcare" }, + { 0x1902, "CSIRO Marine & Atmospheric Research" }, + { 0x1903, "ANEX SYSTEM LTD." }, + { 0x1904, "LVI Low Vision International AB" }, + { 0x1905, "EGEMEN Bilgisayar Muh ve San LTD STI" }, + { 0x1906, "Seoro Tech Co., Ltd." }, + { 0x1907, "Elcoteq Design Center Oy" }, + { 0x1908, "APPOTECH LIMITED" }, + { 0x1909, "ABB Inc. Totalflow Division" }, + { 0x190A, "Freewide Inc." }, + { 0x190B, "Metasoft S.C." }, + { 0x190C, "ierise Inc." }, + { 0x190D, "Motorola GSG" }, + { 0x190E, "YAMASA Tokei-Keiki Co, Ltd" }, + { 0x190F, "YA HORNG ELECTRONIC CO., LTD." }, + { 0x1910, "Seriprint-Ziprip UK Limited" }, + { 0x1911, "Nihon Dengyo Kosaku Co., Ltd." }, + { 0x1912, "Yukyung Technologies Co, Ltd" }, + { 0x1913, "Atomynet, Inc." }, + { 0x1914, "Alco Digital Devices Limited" }, + { 0x1915, "Nordic Semiconductor ASA" }, + { 0x1916, "Juniper Systems, Inc." }, + { 0x1917, "Imagetech Corporation" }, + { 0x1918, "NanoSystem Solutions, Inc." }, + { 0x1919, "Pixelworks" }, + { 0x191A, "PATLITE Corporation" }, + { 0x191B, "PICOCEL Co., Ltd." }, + { 0x191C, "Innovative Technology Limited" }, + { 0x191D, "Midtronics, Inc." }, + { 0x191E, "Monsoon Multimedia Inc." }, + { 0x191F, "Venetex Co., Ltd." }, + { 0x1920, "U.S. Digital Television, LLC" }, + { 0x1921, "Interson Corporation" }, + { 0x1922, "Power 7 Technologies Corp." }, + { 0x1923, "FitSense Technology, Inc." }, + { 0x1924, "QnAp iT" }, + { 0x1925, "InnoFaith beauty sciences B.V." }, + { 0x1926, "NextWindow Limited" }, + { 0x1927, "Vulcan Portals Inc." }, + { 0x1928, "PROCEQ SA" }, + { 0x1929, "Wagner Owen Corporation" }, + { 0x192A, "Intek" }, + { 0x192B, "KVH Industries, Inc." }, + { 0x192C, "Twig Com Oy" }, + { 0x192D, "AgileTV" }, + { 0x192E, "Bioanalytical Systems" }, + { 0x192F, "Avago Technologies, Pte." }, + { 0x1930, "Shenzhen Xianhe Technology Co., Ltd." }, + { 0x1931, "Ningbo Broad Telecommunication Co., Ltd." }, + { 0x1932, "Daniels Electronics Ltd." }, + { 0x1933, "TASER INTERNATIONAL INC." }, + { 0x1934, "SAKAI Medical Co., Ltd." }, + { 0x1935, "Elektron Music Machines AB" }, + { 0x1936, "Asaka Riken Co., Ltd" }, + { 0x1937, "Dynjab Technologies Pty. Ltd." }, + { 0x1938, "Meinberg Funkuhren GmbH & Co. KG" }, + { 0x1939, "Hilscher GmbH" }, + { 0x193A, "Lipman Electronic Engineering Ltd." }, + { 0x193B, "Power Monitors, Inc." }, + { 0x193C, "COGELEC" }, + { 0x193D, "MAXIAN Co., Ltd." }, + { 0x193E, "Chestnut Hill Sound Inc." }, + { 0x193F, "OPDICOM PTY LTD" }, + { 0x1940, "U.S. Music Corporation" }, + { 0x1941, "Top Eight Industrial Corp." }, + { 0x1942, "GAMING PARTNERS INTERNATIONAL" }, + { 0x1943, "Sensoray" }, + { 0x1944, "Wegener Communications" }, + { 0x1945, "O-Pen" }, + { 0x1946, "Irisguard UK Ltd" }, + { 0x1947, "Harris Corporation" }, + { 0x1948, "Darlitech International Co., Ltd." }, + { 0x1949, "Lab126" }, + { 0x194A, "Secure Design Institute Co., Ltd." }, + { 0x194B, "Yanago Design Inc." }, + { 0x194C, "Scanivalve Corp." }, + { 0x194D, "Kern AG" }, + { 0x194E, "acam-messelectronic GmbH" }, + { 0x194F, "PreSonus Audio Electronics" }, + { 0x1950, "FUJINON CORPORATION" }, + { 0x1951, "Hyperstone AG" }, + { 0x1952, "X-TEMPO DESIGNS LLC" }, + { 0x1953, "Ironkey Inc." }, + { 0x1954, "Radiient Technologies" }, + { 0x1955, "4G Systems GmbH" }, + { 0x1956, "The SmartPill Corporation" }, + { 0x1957, "BIOS Corporation" }, + { 0x1958, "Office Depot, Inc." }, + { 0x1959, "DRS Signal Solutions Inc." }, + { 0x195A, "Technology Link Corporation" }, + { 0x195B, "Huge China Industrial Ltd." }, + { 0x195C, "NewSight" }, + { 0x195D, "Itron Technology Inc." }, + { 0x195E, "Datakey Electronics" }, + { 0x195F, "GODEX INTERNATIONAL CO., LTD." }, + { 0x1960, "Brains Corporation" }, + { 0x1961, "Grupo CD World S.L." }, + { 0x1962, "Vstone Corp." }, + { 0x1963, "IK MULTIMEDIA PRODUCTION srl" }, + { 0x1964, "ID Technica Sales Co., Ltd." }, + { 0x1965, "Uniden Corporation" }, + { 0x1966, "ELESTA GmbH" }, + { 0x1967, "CASIO HITACHI Mobile Communications Co., Ltd." }, + { 0x1968, "Global Silicon Ltd." }, + { 0x1969, "TM-Research, Inc." }, + { 0x196A, "SmartCom" }, + { 0x196B, "Wispro Technology Inc." }, + { 0x196C, "EMKA Technologies" }, + { 0x196D, "InnoDisk Corporation" }, + { 0x196E, "SEI" }, + { 0x196F, "Otoichi Corporation" }, + { 0x1970, "Dane-Elec Corp. USA" }, + { 0x1971, "Real ID Technology Co., Ltd." }, + { 0x1972, "Diagnostic Instruments, Inc." }, + { 0x1973, "SpectraLink Corporation" }, + { 0x1974, "LOSTEAKA, Inc." }, + { 0x1975, "Dongguan Guneetal Wire & Cable Co., Ltd." }, + { 0x1976, "Chipsbrand Microelectronics (HK) Co., Ltd." }, + { 0x1977, "Thales" }, + { 0x1978, "Lismore Instruments Limited" }, + { 0x1979, "Suga Digital Technology Limited" }, + { 0x197A, "Kellendonk Elektronik GmbH" }, + { 0x197B, "Way Systems Inc." }, + { 0x197C, "JSC Videofon MV" }, + { 0x197D, "Leuze electronic GmbH & Co. KG" }, + { 0x197E, "scemtec Transponder Technology GmbH" }, + { 0x197F, "Triton" }, + { 0x1980, "Storage Appliance Corp." }, + { 0x1981, "Matrix Audio Designs Inc." }, + { 0x1982, "Hitel Italia S.P.A." }, + { 0x1983, "Icera Inc." }, + { 0x1984, "Targetti Sankey S.P.A." }, + { 0x1985, "Elmos Co., Ltd." }, + { 0x1986, "Qioptiq Imaging Solutions" }, + { 0x1987, "Camille Bauer AG" }, + { 0x1988, "Novar Controls" }, + { 0x1989, "Nuconn Technology Corp." }, + { 0x198A, "MODMEN Co., Ltd." }, + { 0x198B, "Fluid Imaging Technologies, Inc" }, + { 0x198C, "c-scape" }, + { 0x198D, "Fairchild Imaging" }, + { 0x198E, "Ingrid, Inc." }, + { 0x198F, "Beceem Communications Inc." }, + { 0x1990, "Acron Precision Industrial Co., Ltd." }, + { 0x1991, "AAI Corporation" }, + { 0x1992, "Avantes B.V." }, + { 0x1993, "Bluetop Technology Co., Ltd." }, + { 0x1994, "ZMM Ltd." }, + { 0x1995, "Trillium Technology PTY LTD." }, + { 0x1996, "PixeLINK" }, + { 0x1997, "CEFLA S.C.R.L." }, + { 0x1998, "JENOPTIK Laser, Optik, Systeme GmbH" }, + { 0x1999, "iba AG" }, + { 0x199A, "DNA-Technology" }, + { 0x199B, "MicroStrain, Inc." }, + { 0x199C, "Richnex Microelectronics Corporation" }, + { 0x199D, "Dexxon" }, + { 0x199E, "The Imaging Source Europe GmbH" }, + { 0x199F, "Benica Corporation" }, + { 0x19A0, "Krautkramer Japan Co., Ltd." }, + { 0x19A1, "Zeecraft Tech." }, + { 0x19A2, "SICK AG" }, + { 0x19A3, "ASmobile Communication Inc." }, + { 0x19A4, "Unique Medical Co., Ltd." }, + { 0x19A5, "Harris RF Communication" }, + { 0x19A6, "UBISYS TECHNOLOGIES" }, + { 0x19A7, "SuperTop International Corp." }, + { 0x19A8, "Biforst Technology Inc." }, + { 0x19A9, "Musashi Co., Ltd." }, + { 0x19AA, "musicobo" }, + { 0x19AB, "Bodelin Technologies" }, + { 0x19AC, "Hardworks, Inc." }, + { 0x19AD, "RiTTO GmbH & Co. KG" }, + { 0x19AE, "KeeLog" }, + { 0x19AF, "Innomax Technology Ltd." }, + { 0x19B0, "Sobal Corporation" }, + { 0x19B1, "Kyoritsu Radio Co., Ltd." }, + { 0x19B2, "Batronix Elektronik" }, + { 0x19B3, "SPOTWAVE WIRELESS" }, + { 0x19B4, "CELESTRON" }, + { 0x19B5, "B & W Group" }, + { 0x19B6, "Infotech Logistic, LLC" }, + { 0x19B7, "SK-Electronics Co. Ltd." }, + { 0x19B8, "Control Technology Inc." }, + { 0x19B9, "Data Robotics, Inc." }, + { 0x19BA, "ebro Electronic GmbH & Co. KG" }, + { 0x19BB, "Informtest" }, + { 0x19BC, "ioLab Systems Inc." }, + { 0x19BD, "Celluon, Inc." }, + { 0x19BE, "Guidance Software, Inc." }, + { 0x19BF, "HASHIMOTO Electronic Industry Co., Ltd." }, + { 0x19C0, "TeraTron GmbH" }, + { 0x19C1, "Digital Info Technology Pte. Ltd." }, + { 0x19C2, "TARGA GmbH" }, + { 0x19C3, "Riskema Informatica e Automacao Ltda." }, + { 0x19C4, "Control Gaging, Inc." }, + { 0x19C5, "Danaher Sensors and Controls" }, + { 0x19C6, "Harmony Microelectronic Inc." }, + { 0x19C7, "WEG Equipamentos El�tricos S.A. - Automa��o" }, + { 0x19C8, "Secure Key LLC" }, + { 0x19C9, "Electronic Sports" }, + { 0x19CA, "Sandio Technology Corp." }, + { 0x19CB, "EMS (European) LTD." }, + { 0x19CC, "SCIEN Co." }, + { 0x19CD, "D. O. Tel Co., Ltd." }, + { 0x19CE, "SINUS Messtechnik GmbH" }, + { 0x19CF, "Parrot SA" }, + { 0x19D0, "Pan Pacific Enterprise Co., Inc." }, + { 0x19D1, "Channaa" }, + { 0x19D2, "ZTE Corporation" }, + { 0x19D3, "Zucchetti Centro Sistemi SPA" }, + { 0x19D4, "I Bee, K.K." }, + { 0x19D5, "CNB Technology Inc." }, + { 0x19D6, "WIDE Corporation" }, + { 0x19D7, "Unitop New Technology Co., Ltd." }, + { 0x19D8, "Smart Point SA" }, + { 0x19D9, "Fujitsu Ten Limited" }, + { 0x19DA, "MUSE Inc." }, + { 0x19DB, "GeBE Elektronik und Feinwerktechnik GmbH" }, + { 0x19DC, "Communications & Power Industries" }, + { 0x19DD, "NEXVU TECHNOLOGIES, Inc." }, + { 0x19DE, "MITEQ Inc." }, + { 0x19DF, "AlpnaCom" }, + { 0x19E0, "Micro-Nits Co., Ltd." }, + { 0x19E1, "WeiDuan Electronic Accessory (S.Z.) Co., Ltd." }, + { 0x19E2, "Solomon Systech Limited" }, + { 0x19E3, "Bae Systems IEWS" }, + { 0x19E4, "In-Situ Inc." }, + { 0x19E5, "Jetmobile" }, + { 0x19E6, "Apex Digital Inc." }, + { 0x19E7, "Charismathics GmbH" }, + { 0x19E8, "Industrial Technology Research Institute" }, + { 0x19E9, "Bartec Auto ID Ltd." }, + { 0x19EA, "Lung Hwa Electronics Co., Ltd." }, + { 0x19EB, "ACE Antenna, Advanced Technology R&D Team." }, + { 0x19EC, "Forth Dimension Displays Ltd." }, + { 0x19ED, "Plastic Logic Ltd." }, + { 0x19EE, "Modern Marketing Concepts Inc." }, + { 0x19EF, "Pak Heng Technology (Shenzhen) Co., Ltd." }, + { 0x19F0, "Jyh Woei Industrial Co., Ltd." }, + { 0x19F1, "SindoRicoh Co., LTD." }, + { 0x19F2, "INFOMARK Co., Ltd." }, + { 0x19F3, "JAPAN Kyastem Co., Ltd." }, + { 0x19F4, "Malvern Instruments Ltd" }, + { 0x19F5, "Nationz Technologies Inc." }, + { 0x19F6, "J. A. Woollam Co. Inc." }, + { 0x19F7, "Rode Microphones" }, + { 0x19F8, "RoboTech srl" }, + { 0x19F9, "Megadata (Europe) PLC" }, + { 0x19FA, "SHENZHEN GAMEWARE ELECTRONIC CO., LTD." }, + { 0x19FB, "VLSI Solution Oy" }, + { 0x19FC, "BioControl A/S" }, + { 0x19FD, "MTI Instruments" }, + { 0x19FE, "Micromap Corporation" }, + { 0x19FF, "Best Buy" }, + { 0x1A00, "Polymax Precision Industry Co., Ltd." }, + { 0x1A01, "Siemens Power Transmission & Dist. Energy Automation" }, + { 0x1A02, "DLoG GmbH" }, + { 0x1A03, "HORIBA ITECH Co., Ltd." }, + { 0x1A04, "ASTRO MACHINE CORP." }, + { 0x1A05, "Media Lab., Inc" }, + { 0x1A06, "Beijing Deng Hong Technology Co., Ltd." }, + { 0x1A07, "HID" }, + { 0x1A08, "Bellwood International, Inc." }, + { 0x1A09, "DILANO GmbH" }, + { 0x1A0B, "Teleste OYJ" }, + { 0x1A0C, "Sunkorea Electronics Co., Ltd." }, + { 0x1A0D, "Ladybug Technologies LLC" }, + { 0x1A0E, "Sasse Elektronik GmbH" }, + { 0x1A0F, "HT-ITALIA" }, + { 0x1A10, "KWANG SUNG ELECTRONICS H.K. Co., Ltd." }, + { 0x1A11, "eMDee Technology, Inc." }, + { 0x1A12, "KES Co., Ltd." }, + { 0x1A13, "Plasmon" }, + { 0x1A14, "Brainvision Inc." }, + { 0x1A15, "Amphenol-Tuchel Electronics GmbH" }, + { 0x1A16, "General Dynamics" }, + { 0x1A17, "Oticon A/S" }, + { 0x1A18, "Quadzilla Performance Technologies, Inc." }, + { 0x1A19, "DDTIC Corporation Ltd." }, + { 0x1A1A, "ASIACORP INTERNATIONAL LTD." }, + { 0x1A1B, "Fischer-Zoth GmbH" }, + { 0x1A1C, "Mercury Computer Systems AG" }, + { 0x1A1D, "Syncomm Technology Corp." }, + { 0x1A1E, "Dekart s.r.l." }, + { 0x1A1F, "Ikanos Communications Inc." }, + { 0x1A20, "Mind Logic Co., Ltd." }, + { 0x1A21, "ASITEQ Co., Ltd." }, + { 0x1A22, "Kenwin Industrial (HK) Ltd." }, + { 0x1A23, "Hangzhou YiHeng Technologies Co., Ltd." }, + { 0x1A24, "Beyondwiz Co., Ltd." }, + { 0x1A25, "Amphenol East Asia Ltd." }, + { 0x1A26, "APSI (Asia Pacific Satellite Industry)" }, + { 0x1A27, "Senior Technologies" }, + { 0x1A28, "NOVITUS SA" }, + { 0x1A29, "ABOV Semiconductor Co., Ltd." }, + { 0x1A2A, "Seagate Branded Solutions" }, + { 0x1A2B, "NTI Corporation" }, + { 0x1A2C, "Wuxi China Resources Semico Co., Ltd." }, + { 0x1A2D, "WEBSYNC Co., Ltd." }, + { 0x1A2E, "Lanner Electronics Inc." }, + { 0x1A2F, "Tetradyne Software Inc." }, + { 0x1A30, "New Media Life" }, + { 0x1A31, "SPEX SamplePrep, LLC" }, + { 0x1A32, "Verint Video Technology GmbH" }, + { 0x1A33, "Schmid & Partner Engineering AG" }, + { 0x1A34, "King Chuang Tech & Electronic Co., Ltd." }, + { 0x1A35, "Astec Power, a division of Emerson Network Power" }, + { 0x1A36, "Biwin Technology Ltd." }, + { 0x1A37, "Stayhealthy Inc." }, + { 0x1A38, "Nemo-Q International AB" }, + { 0x1A39, "GBC Scientific Equipment" }, + { 0x1A3A, "Laerdal Medical AS" }, + { 0x1A3B, "South Mountain Technologies, Ltd." }, + { 0x1A3C, "New Image Co., Ltd." }, + { 0x1A3D, "ELGA LabWater (VWS UK LTD)" }, + { 0x1A3E, "INTEVAC" }, + { 0x1A3F, "Hokkei Industries Co., Ltd." }, + { 0x1A40, "TERMINUS TECHNOLOGY INC." }, + { 0x1A41, "Action Electronics Co., Ltd." }, + { 0x1A42, "CROSSLINK GmbH" }, + { 0x1A43, "JTEKT CORPORATION" }, + { 0x1A44, "VASCO Data Security NV" }, + { 0x1A45, "Wavelength Electronics Inc." }, + { 0x1A46, "JAVAD GNSS, Inc." }, + { 0x1A47, "iQBio, Inc." }, + { 0x1A48, "KYOHRITSU ELECTRONIC INDUSTRY Co., Ltd." }, + { 0x1A49, "TOKYO SEIMITSU CO., LTD." }, + { 0x1A4A, "Silicon Image" }, + { 0x1A4B, "SafeBoot International B.V." }, + { 0x1A4C, "PMC" }, + { 0x1A4D, "N-CRYPT, Inc." }, + { 0x1A4E, "SIMS Corp." }, + { 0x1A4F, "Haliplex PTY Ltd." }, + { 0x1A50, "Mechatro Inc." }, + { 0x1A51, "FRWD Technologies Ltd." }, + { 0x1A52, "MediaPhy Corporation" }, + { 0x1A53, "SANDBOX Co., Ltd" }, + { 0x1A54, "Oestling Markiersysteme GmbH" }, + { 0x1A55, "Raytheon Systems Limited" }, + { 0x1A56, "East Port Technology Co., Ltd." }, + { 0x1A57, "ARESIS d.o.o." }, + { 0x1A58, "Miranda Technologies Inc." }, + { 0x1A59, "HAAG-STREIT AG" }, + { 0x1A5A, "Tandberg Data" }, + { 0x1A5B, "Entner Electronics KEG" }, + { 0x1A5C, "Arkino Corporation Limited" }, + { 0x1A5D, "Daikin Denshi Kogyo Co., Ltd." }, + { 0x1A5E, "Edixia" }, + { 0x1A5F, "Sonatest Limited" }, + { 0x1A60, "Joytoto Co., Ltd." }, + { 0x1A61, "Abbott Diabetes Care" }, + { 0x1A62, "DAT H.K. LIMITED" }, + { 0x1A63, "Canfield Scientific, Inc." }, + { 0x1A64, "MASTERVOLT INTERNATIONAL" }, + { 0x1A65, "ELEKTRINA d.o.o., podjetje za razvoj elektronike" }, + { 0x1A66, "Andatek Technology, Ltd." }, + { 0x1A67, "Privaris" }, + { 0x1A68, "Double Top Technology Ltd." }, + { 0x1A69, "Kalon Semiconductor, Inc." }, + { 0x1A6A, "Spansion Inc." }, + { 0x1A6B, "Taiwin Electronics Co., Ltd." }, + { 0x1A6C, "Hivion Co., Ltd." }, + { 0x1A6D, "SamYoung Electronics Co., Ltd" }, + { 0x1A6E, "Global Unichip Corp." }, + { 0x1A6F, "Sagem Orga GmbH" }, + { 0x1A70, "Items Technology Co., Ltd." }, + { 0x1A71, "SEIDEL Elektronik GmbH Nfg. KG" }, + { 0x1A72, "Physik Instrumente (PI) GmbH & Co. KG" }, + { 0x1A73, "Huntron Inc." }, + { 0x1A74, "Oberthur Technologies" }, + { 0x1A75, "Nautilus Hyosung" }, + { 0x1A76, "JADAK Technologies, Inc." }, + { 0x1A77, "American Master Import 26, Inc." }, + { 0x1A78, "AirLink Communications, Inc." }, + { 0x1A79, "Bayer Health Care LLC" }, + { 0x1A7A, "Softron Co., Ltd." }, + { 0x1A7B, "Lumberg Connect GmbH" }, + { 0x1A7C, "Evoluent LLC" }, + { 0x1A7D, "Systex Corporation" }, + { 0x1A7E, "MELTEC Systementwicklung" }, + { 0x1A7F, "SSD COMPANY LIMITED" }, + { 0x1A80, "Zhong Ming Wire Cable Technology (Xiamen) Co., Ltd." }, + { 0x1A81, "G.Tech Technology Ltd." }, + { 0x1A82, "Proconn Technology Co., Ltd." }, + { 0x1A83, "Socle Technology Corp." }, + { 0x1A84, "COBB Tuning, Inc." }, + { 0x1A85, "Southwest Research Institute" }, + { 0x1A86, "Nanjing Qinherg Electronics Co., Ltd." }, + { 0x1A87, "TechLab 2000 Ltd. Co., Sp Zo.o." }, + { 0x1A88, "WowWee Limited" }, + { 0x1A89, "Dynalith Systems Co., Ltd." }, + { 0x1A8A, "Simula Technology Inc." }, + { 0x1A8B, "SGS Taiwan Ltd." }, + { 0x1A8C, "MagicEyes Digital Co., Ltd" }, + { 0x1A8D, "BandRich Inc." }, + { 0x1A8E, "XiTRON Technologies" }, + { 0x1A8F, "Harman Becker Automotive Systems, GmbH" }, + { 0x1A90, "Resource Data Management" }, + { 0x1A91, "GEOMC Co., Ltd." }, + { 0x1A92, "Berkash Enterprise" }, + { 0x1A93, "Promotional Technologies International Corp." }, + { 0x1A94, "STWTECH Co., Ltd." }, + { 0x1A95, "Sextant Labs, Inc." }, + { 0x1A96, "Harman Becker Automotive Systems, Inc." }, + { 0x1A97, "XM Satellite Radio Inc." }, + { 0x1A98, "Leica Camera AG" }, + { 0x1A99, "Asia Tai Technology (Dongguan) Co., Ltd." }, + { 0x1A9A, "Verari Systems, Inc." }, + { 0x1A9B, "Balboa Instruments" }, + { 0x1A9C, "Inomed Medizintechnik GmbH" }, + { 0x1A9D, "TrafficSim Co., Ltd." }, + { 0x1A9E, "Epicenter, Inc." }, + { 0x1A9F, "Hysitron Incorporated" }, + { 0x1AA0, "Auto Enginuity, L.L.C." }, + { 0x1AA1, "Vestax Corporation" }, + { 0x1AA2, "ORIENTAL MOTOR CO., LTD." }, + { 0x1AA3, "ZOLL Medical Corporation" }, + { 0x1AA4, "Data Drive Thru, Inc." }, + { 0x1AA5, "UBeacon Technologies, Inc." }, + { 0x1AA6, "eFortune Technology Corp." }, + { 0x1AA7, "SiliconSystems, Inc." }, + { 0x1AA8, "Waves Audio Ltd." }, + { 0x1AA9, "Home Phone Tunes Inc." }, + { 0x1AAA, "Taylor Associates/Communications, Inc." }, + { 0x1AAB, "SilverCreations Software AG" }, + { 0x1AAC, "Witschi Electronic AG" }, + { 0x1AAD, "KeeTouch Electronic Co., Ltd." }, + { 0x1AAE, "Johnson Component & Equipments Co., Ltd." }, + { 0x1AAF, "Intellectual Property Library Company" }, + { 0x1AB0, "DAEWOO ELECTRONIC COMPONENTS CO., LTD." }, + { 0x1AB1, "Rigol Technologies, Inc." }, + { 0x1AB2, "Allied Vision Technologies GmbH" }, + { 0x1AB3, "M and C System" }, + { 0x1AB4, "Japan Remote Control Co., Ltd." }, + { 0x1AB5, "Hamamatsu TOA Electronics, Inc." }, + { 0x1AB6, "Integrated Technology Corp." }, + { 0x1AB7, "GLOBAL VR, Inc." }, + { 0x1AB8, "Pen Laboratory Inc." }, + { 0x1AB9, "Nomadio Inc." }, + { 0x1ABA, "Kenton Electronics Limited" }, + { 0x1ABB, "Airo Wireless Media Inc." }, + { 0x1ABC, "Fuji Photo Film USA" }, + { 0x1ABD, "PERTO S.A." }, + { 0x1ABE, "MP3Car.com Inc" }, + { 0x1ABF, "ANIMA Corporation" }, + { 0x1AC0, "SOKKIA Co., Ltd." }, + { 0x1AC1, "LIANHE TECHNOLOGIES, INC." }, + { 0x1AC2, "DESKO GmbH" }, + { 0x1AC3, "DISK KING Technology Co., Ltd." }, + { 0x1AC4, "CAO Group, Inc." }, + { 0x1AC5, "Electronic Engineering Solutions S.L." }, + { 0x1AC6, "JAPAN ADE LTD." }, + { 0x1AC7, "Modular Communication Systems, Inc." }, + { 0x1AC8, "Toyota Industries Corporation" }, + { 0x1AC9, "Broadxent Pte. Ltd." }, + { 0x1ACA, "Bluebird Soft Inc." }, + { 0x1ACB, "Salcomp Plc" }, + { 0x1ACC, "Ta Horng Musical Instrument Co., Ltd." }, + { 0x1ACD, "MKS Instruments" }, + { 0x1ACE, "Temento Systems" }, + { 0x1ACF, "International Manufacturing & Engineering Services Co." }, + { 0x1AD0, "Cygnetron, Inc." }, + { 0x1AD1, "Desan Wire Co., Ltd." }, + { 0x1AD2, "Mesa Imaging AG" }, + { 0x1AD3, "Advanced Technetix, Inc." }, + { 0x1AD4, "Advanced Printing Systems" }, + { 0x1AD5, "Gentec-EO" }, + { 0x1AD6, "General Dynamics SATCOM Technologies, State College Fac" }, + { 0x1AD7, "A.B.O. Co., Ltd." }, + { 0x1AD8, "Motion Control i V�ster�s AB" }, + { 0x1AD9, "Rocket Gaming Systems" }, + { 0x1ADA, "VEGA Grieshaber KG" }, + { 0x1ADB, "Schweitzer Engineering Laboratories" }, + { 0x1ADC, "Turbolinux, Inc." }, + { 0x1ADD, "Marshall Electronics, Inc." }, + { 0x1ADE, "SpinMaster Ltd." }, + { 0x1ADF, "digital design GmbH" }, + { 0x1AE0, "Axiomatic Technologies Corp." }, + { 0x1AE1, "Hoffman Engineering" }, + { 0x1AE2, "A-JET Technology Co., LTD." }, + { 0x1AE3, "Chung Young Digital Corp., Ltd." }, + { 0x1AE4, "ic-design Reinhard Gottinger GmbH" }, + { 0x1AE5, "Jianduan Technology (Shenzhen) Co., Ltd" }, + { 0x1AE6, "JOA Telecom Co., Ltd." }, + { 0x1AE7, "Joellenbeck GmbH" }, + { 0x1AE8, "Myway Labs Co., Ltd." }, + { 0x1AE9, "arnotec GmbH" }, + { 0x1AEA, "Mobilygen Corporation" }, + { 0x1AEB, "NIHON UNICA CORPORATION" }, + { 0x1AEC, "PORTEK TECHNOLOGY CORPORATION" }, + { 0x1AED, "High Top Precision Electronic Co., Ltd." }, + { 0x1AEE, "SHEN ZHEN REX TECHNOLOGY CO., LTD." }, + { 0x1AEF, "Octekconn Incorporation" }, + { 0x1AF0, "SuperPix Micro Technology Limited" }, + { 0x1AF1, "Connect One, Ltd." }, + { 0x1AF2, "AXSionics AG" }, + { 0x1AF3, "Smarthome Technology Limited" }, + { 0x1AF4, "NCS Pearson, Inc." }, + { 0x1AF5, "Arima Communications Corp." }, + { 0x1AF6, "SL International Ltd." }, + { 0x1AF7, "GRAPHIN CO., LTD." }, + { 0x1AF8, "JS-ROBOTICS" }, + { 0x1AF9, "Alvarion Ltd." }, + { 0x1AFA, "Mobinnova Corp." }, + { 0x1AFB, "Kirche Jesu Christi der Heiligen der Letzten Tage" }, + { 0x1AFC, "Blue Orb" }, + { 0x1AFD, "FarSite Communications Limited" }, + { 0x1AFE, "A. Eberle GmbH & Co. KG" }, + { 0x1AFF, "Defibtech, LLC" }, + { 0x1B00, "Uster Technologies, Inc." }, + { 0x1B01, "ETA Chips, Co." }, + { 0x1B02, "MEN Mikro Elektronik GmbH" }, + { 0x1B03, "Moog Japan Ltd." }, + { 0x1B04, "MEILHAUS Electronic GmbH" }, + { 0x1B05, "Cracol Developments Ltd." }, + { 0x1B06, "OPGAL" }, + { 0x1B07, "WEY Elektronik AG" }, + { 0x1B08, "Actimo Inc." }, + { 0x1B09, "MISUZU INDUSTRIES CORPORATION" }, + { 0x1B0A, "Sense Technology Inc." }, + { 0x1B0B, "Lambda Systems Inc." }, + { 0x1B0C, "MYTECS Co., Ltd." }, + { 0x1B0D, "SmarDTV" }, + { 0x1B0E, "BLUTRONICS S.R.L." }, + { 0x1B0F, "EKS-ELEKTRONIKSERVICE GmbH" }, + { 0x1B10, "KAGA COMPONENTS CO., LTD." }, + { 0x1B11, "OneClick Technologies Ltd." }, + { 0x1B12, "Eventide, Inc." }, + { 0x1B13, "Neuf Cegetel" }, + { 0x1B14, "Ergotron, Inc." }, + { 0x1B15, "i3micro technology ab" }, + { 0x1B16, "LinTech GmbH Berlin" }, + { 0x1B17, "SHENZHEN e-loam Technology Co., Ltd." }, + { 0x1B18, "Mikrolab Entwicklungsgesellschaft fur Elektroniksysteme" }, + { 0x1B19, "RADA Electronic Industries Ltd." }, + { 0x1B1A, "Tianjin China-Silicon Microelectronics Co., Ltd." }, + { 0x1B1B, "Shenzhen MD Electric Co., Ltd." }, + { 0x1B1C, "CORSAIR MEMORY INC." }, + { 0x1B1D, "Torian Wireless Ltd." }, + { 0x1B1E, "General Imaging Company" }, + { 0x1B1F, "eQ-3 Entwicklung GmbH" }, + { 0x1B20, "MStar Semiconductor, Inc." }, + { 0x1B21, "XenICs nv" }, + { 0x1B22, "WiLinx Corp." }, + { 0x1B23, "Skyray Instrument Co., Ltd." }, + { 0x1B24, "Telegent Systems Inc." }, + { 0x1B25, "ALE" }, + { 0x1B26, "Plug Power" }, + { 0x1B27, "Current Electronics Inc." }, + { 0x1B28, "NAVIsis Inc." }, + { 0x1B29, "Industrie Dial Face S.p.A." }, + { 0x1B2A, "MICRO EMISSION CO., LTD." }, + { 0x1B2B, "Neural Image Co., Ltd." }, + { 0x1B2C, "Advanced Thermal Solutions, Inc." }, + { 0x1B2D, "Photon Inc." }, + { 0x1B2E, "ETANI ELECTRONICS CO., LTD." }, + { 0x1B2F, "Ihara Electronic Industries Co.,Ltd." }, + { 0x1B30, "STZ QSBV Ilmenau" }, + { 0x1B31, "Renu Electronics Pvt. Ltd." }, + { 0x1B32, "Ugobe, Inc." }, + { 0x1B33, "3DV Systems Ltd." }, + { 0x1B34, "EyeTalk Systems, Inc." }, + { 0x1B35, "Paradigm Electronics Inc." }, + { 0x1B36, "ViXS Systems, Inc." }, + { 0x1B37, "Savant Systems, LLC" }, + { 0x1B38, "ALBAHITH TECHNOLOGIES" }, + { 0x1B39, "ViaMichelin SAS" }, + { 0x1B3A, "JUMO GmbH & Co. KG" }, + { 0x1B3B, "iPassion Technology Inc." }, + { 0x1B3C, "DEVI A/S" }, + { 0x1B3D, "Matrix Orbital" }, + { 0x1B3E, "STIL SA" }, + { 0x1B3F, "Generalplus Technology Inc." }, + { 0x1B40, "AISIN SEIKI CO., LTD." }, + { 0x1B41, "Fujitsu Australia Limited" }, + { 0x1B42, "Cardinal Scale Manufacturing Company" }, + { 0x1B43, "Extron Design Services" }, + { 0x1B44, "Elite Co., Ltd." }, + { 0x1B45, "Cyan Technology Ltd." }, + { 0x1B46, "Holylite Microelectronics Corp." }, + { 0x1B47, "Energizer Holdings, Inc." }, + { 0x1B48, "Plastron Precision Co., Ltd." }, + { 0x1B49, "Applied Printed Electronics Research, LLC" }, + { 0x1B4A, "Gem-Med, S.L." }, + { 0x1B4B, "Watson Marlow Ltd." }, + { 0x1B4C, "Unitron Group" }, + { 0x1B4D, "Objet Geometries Ltd." }, + { 0x1B4E, "ELPRO-BUCHS AG" }, + { 0x1B4F, "Spark Fun Electronics" }, + { 0x1B50, "DictaNet Software AG" }, + { 0x1B51, "Kundisch GmbH & Co. KG" }, + { 0x1B52, "A.R. Hungary, Inc." }, + { 0x1B53, "DANI Instruments S.p.A." }, + { 0x1B54, "COMMIT Incorporated" }, + { 0x1B55, "ZKSoftware Inc." }, + { 0x1B56, "V.I.O., Inc." }, + { 0x1B57, "ATREE Inc." }, + { 0x1B58, "Sumitomo Elec Ind Ltd. Lightwave Network Products Div." }, + { 0x1B59, "K.S. Terminals Inc." }, + { 0x1B5A, "Chao Zhou Kai Yuan Electric Co., Ltd." }, + { 0x1B5B, "Homoth Medizinelektronik" }, + { 0x1B5C, "ICP DAS Co., Ltd." }, + { 0x1B5D, "MV Circuit Design, Inc." }, + { 0x1B5E, "General Engine Management Systems Ltd." }, + { 0x1B5F, "Wayne Dalton Corp." }, + { 0x1B60, "NanoDrop Technologies, Inc." }, + { 0x1B61, "n-Trance Security Ltd." }, + { 0x1B62, "Shenzhen Aoni Electronic Industry Co., Ltd." }, + { 0x1B63, "Seedsware Corporation" }, + { 0x1B64, "C.G. Development Ltd." }, + { 0x1B65, "The Hong Kong Standards and Testing Centre Ltd." }, + { 0x1B66, "Bontempi-Farfisa Sigma S.p.A." }, + { 0x1B67, "Toradex AG" }, + { 0x1B68, "ZAFENA AB" }, + { 0x1B69, "KLA-Tencor" }, + { 0x1B6A, "HIKARI Co., Ltd." }, + { 0x1B6B, "Modiotek Co., Ltd." }, + { 0x1B6C, "Techno Veins Co., Ltd." }, + { 0x1B6D, "IDpendant GmbH" }, + { 0x1B6E, "HS Automatic ApS" }, + { 0x1B6F, "Federal Signal Vama S.A." }, + { 0x1B70, "Minicom Advanced Systems" }, + { 0x1B71, "Huizhou 10Moons Technology Development Co., Ltd." }, + { 0x1B72, "ATERGI TECHNOLOGY CO., LTD." }, + { 0x1B73, "Vehicle Camera Systems Ltd" }, + { 0x1B74, "MODAFUN, Inc." }, + { 0x1B75, "OvisLink Corp." }, + { 0x1B76, "Legend Silicon Corp." }, + { 0x1B77, "Protec, Inc." }, + { 0x1B78, "LOGICPACK CO., LTD." }, + { 0x1B79, "WingsTek, Inc." }, + { 0x1B7A, "Electrox" }, + { 0x1B7B, "Ingersoll Rand Co." }, + { 0x1B7C, "io Corporation" }, + { 0x1B7D, "SUNGIL TELECOM" }, + { 0x1B7E, "Lutron Electronics Inc." }, + { 0x1B7F, "EMC Corporation" }, + { 0x1B80, "KWorld Computer Co., Ltd." }, + { 0x1B81, "Kratos Analytical Ltd." }, + { 0x1B82, "Mcube Technology Co., Ltd." }, + { 0x1B83, "Megatone systems and Technologies LTD." }, + { 0x1B84, "WALTHER Data GmbH Scan-Solutions" }, + { 0x1B85, "INNOVA S.A." }, + { 0x1B86, "Dongguan Guanshang Electronics Co., Ltd." }, + { 0x1B87, "Davis Instruments" }, + { 0x1B88, "ShenMing Electron (Dong Guan) Co., Ltd." }, + { 0x1B89, "iCache, Incorporated" }, + { 0x1B8A, "Quellan, Inc." }, + { 0x1B8B, "PROCES-DATA A/S" }, + { 0x1B8C, "Altium Limited" }, + { 0x1B8D, "e-MOVE Technology Co., Ltd." }, + { 0x1B8E, "Amlogic, Inc." }, + { 0x1B8F, "Super Talent Technology, Inc." }, + { 0x1B90, "Deep Sea Electronics Plc" }, + { 0x1B91, "Zicplay SA" }, + { 0x1B92, "Trysys Co., Ltd." }, + { 0x1B93, "Phoenix Contact GmbH & Co. KG" }, + { 0x1B94, "Yoggie Security Systems" }, + { 0x1B95, "EVC electronic GmbH" }, + { 0x1B96, "N-Trig" }, + { 0x1B97, "Metronix GmbH" }, + { 0x1B98, "YMax Communications Corp." }, + { 0x1B99, "Shenzhen Yuanchuan Electronic" }, + { 0x1B9A, "Applied Vision Systems Corporation" }, + { 0x1B9B, "Microtrac, Inc." }, + { 0x1B9C, "Maki Manufacturing Co., Ltd." }, + { 0x1B9D, "Sigma Instruments, Inc." }, + { 0x1B9E, "ARCoptix S.A" }, + { 0x1B9F, "GHI Electronics, LLC" }, + { 0x1BA0, "Jiangmen Kong Yue Jolimark Information Technology Ltd." }, + { 0x1BA1, "JINQ CHERN ENTERPRISE CO., LTD." }, + { 0x1BA2, "Lite Metals & Plastic (Shenzhen) Co., Ltd." }, + { 0x1BA3, "EmbeddedFusion Ltd." }, + { 0x1BA4, "Ember Corporation" }, + { 0x1BA5, "Futiro" }, + { 0x1BA6, "Abilis Systems" }, + { 0x1BA7, "Xantech Corporation" }, + { 0x1BA8, "China Telecommunication Technology Labs" }, + { 0x1BA9, "Renau Electronic Laboratories" }, + { 0x1BAA, "Transcell Technology, Inc." }, + { 0x1BAB, "MATT R.P.Traczynscy Sp.J." }, + { 0x1BAC, "Bernecker + Rainer Industrie-Elektronik Ges.m.b.H." }, + { 0x1BAD, "Harmonix Music Systems, Inc." }, + { 0x1BAE, "Icuiti Corporation" }, + { 0x1BAF, "NIIGATA SEIMITSU CO., LTD." }, + { 0x1BB0, "LBS PLUS Co., Ltd." }, + { 0x1BB1, "Commodore International Corporation" }, + { 0x1BB2, "G.T. trading Srl" }, + { 0x1BB3, "Holzworth Instrumentation LLC" }, + { 0x1BB4, "Satmap Systems Ltd." }, + { 0x1BB5, "SEF Roboter GmbH" }, + { 0x1BB6, "PdMA Corporation" }, + { 0x1BB7, "DGT Sp. z o.o." }, + { 0x1BB8, "MIZOUE PROJECT JAPAN Corporation" }, + { 0x1BB9, "Qpixel Technology, Inc." }, + { 0x1BBA, "Medicomp, Inc." }, + { 0x1BBB, "TCT Mobile Limited" }, + { 0x1BBC, "KATHREIN-Werke KG" }, + { 0x1BBD, "Videology Imaging Solutions, Inc." }, + { 0x1BBE, "CE+T s.a." }, + { 0x1BBF, "Littfinski DatenTechnik (LDT)" }, + { 0x1BC0, "Senselock Software Technology Co.,Ltd" }, + { 0x1BC1, "ACE ELECTRONIQUE" }, + { 0x1BC2, "SEW-EURODRIVE GmbH & Co. KG" }, + { 0x1BC3, "Fujian START Computer Equipment Co., Ltd." }, + { 0x1BC4, "Ford Motor Co." }, + { 0x1BC5, "AVIXE Technology (China) Ltd." }, + { 0x1BC6, "Yurex, Inc." }, + { 0x1BC7, "Telit Wireless Solutions" }, + { 0x1BC8, "MDS Technology Co., Ltd." }, + { 0x1BC9, "Alti-2 Inc." }, + { 0x1BCA, "Ishii Hyoki Co., Ltd." }, + { 0x1BCB, "Cubic Defence NZ Limited" }, + { 0x1BCC, "TopScan Ltd." }, + { 0x1BCD, "AZKOYEN" }, + { 0x1BCE, "Contac Cable Industrial Limited" }, + { 0x1BCF, "Sunplus Innovation Technology Inc." }, + { 0x1BD0, "Hangzhou Riyue Electronic Co., Ltd." }, + { 0x1BD1, "Companion Worlds, Inc." }, + { 0x1BD2, "Beijing G & D Card Systems Co., Ltd." }, + { 0x1BD3, "3layer Engineering" }, + { 0x1BD4, "FastVDO Inc." }, + { 0x1BD5, "BG Systems, Inc." }, + { 0x1BD6, "Lodam electronics" }, + { 0x1BD7, "TouchNetworks, Inc." }, + { 0x1BD8, "Image Computer Systems Limited" }, + { 0x1BD9, "Control Products, Inc." }, + { 0x1BDA, "University of Southampton" }, + { 0x1BDB, "Spectral Applied Research" }, + { 0x1BDC, "Slacker" }, + { 0x1BDD, "QiGO Inc" }, + { 0x1BDE, "P-TWO INDUSTRIES, INC." }, + { 0x1BDF, "Electrone Americas Ltd., Co." }, + { 0x1BE0, "Analog Devices, Inc. - Test Technology Group" }, + { 0x1BE1, "LG-Ericsson Co., Ltd" }, + { 0x1BE2, "Shenzhen Fametech Electronic Co., Ltd." }, + { 0x1BE3, "WAGO Kontakttechnik GmbH & Co. KG" }, + { 0x1BE4, "Integrated Digital Technologies, Inc. (IDTI)" }, + { 0x1BE5, "NetLogic Microsystems" }, + { 0x1BE6, "NAVENTO TECHNOLOGIES" }, + { 0x1BE7, "CPR Tools, Inc." }, + { 0x1BE8, "MEDAV GmbH" }, + { 0x1BE9, "CONCH ELECTRONIC CO., LTD." }, + { 0x1BEA, "ATTO Corporation" }, + { 0x1BEB, "HOYA CANDEO OPTRONICS CORPORATION" }, + { 0x1BEC, "isMedia Co., Ltd." }, + { 0x1BED, "OPT Corporation" }, + { 0x1BEE, "KCI Medical Products (UK) Ltd." }, + { 0x1BEF, "Shenzhen Tongyuan Network-Communication Cables Co., Ltd" }, + { 0x1BF0, "RealVision Inc." }, + { 0x1BF1, "HENGSTLER" }, + { 0x1BF2, "Newport Media, Inc." }, + { 0x1BF3, "WAVES SYSTEM / SONAMIX" }, + { 0x1BF4, "ABB / Drives" }, + { 0x1BF5, "Extranet Systems Inc." }, + { 0x1BF6, "Orient Semiconductor Electronics, Ltd." }, + { 0x1BF7, "Axiotron, Inc." }, + { 0x1BF8, "Game Mechanisms LLC" }, + { 0x1BF9, "TRACTEL SAS" }, + { 0x1BFA, "METROLAB TECHNOLOGY SA" }, + { 0x1BFB, "ALLIED PANELS" }, + { 0x1BFC, "Guidance Interactive Healthcare" }, + { 0x1BFD, "RISINTECH INC." }, + { 0x1BFE, "SEOHWA TELECOM Co., LTD." }, + { 0x1BFF, "IonOptix Corp." }, + { 0x1C00, "prodaSafe GmbH" }, + { 0x1C01, "No Climb Products Ltd." }, + { 0x1C02, "Kreton Corporation" }, + { 0x1C03, "DDL CO., LTD." }, + { 0x1C04, "QNAP System Inc." }, + { 0x1C05, "Rockwell Collins" }, + { 0x1C06, "SeekTech, Inc." }, + { 0x1C07, "CEntrance, Inc." }, + { 0x1C08, "Arcus-EDS GmbH" }, + { 0x1C09, "RAMTEX Engineering ApS" }, + { 0x1C0A, "MaxRise Inc." }, + { 0x1C0B, "Kato Tech Co., Ltd." }, + { 0x1C0C, "Ionics EMS Inc." }, + { 0x1C0D, "Relm Wireless" }, + { 0x1C0E, "Qstik plc" }, + { 0x1C0F, "NEOTECHKNO" }, + { 0x1C10, "Lanterra Industrial Co., Ltd." }, + { 0x1C11, "UNIMTEC Co., Ltd." }, + { 0x1C12, "CONITEC DATENSYSTEME GmbH" }, + { 0x1C13, "ALECTRONIC LIMITED" }, + { 0x1C14, "SENSITIVE OBJECT" }, + { 0x1C15, "TeleWell Oy" }, + { 0x1C16, "Afit Corporation" }, + { 0x1C17, "LAB REHAB PTE LTD." }, + { 0x1C18, "Apria Technology" }, + { 0x1C19, "Charder Electronic Co., Ltd." }, + { 0x1C1A, "Datel Electronics Ltd." }, + { 0x1C1B, "Volkswagen of America, Inc." }, + { 0x1C1C, "Schmartz Inc." }, + { 0x1C1D, "GASTEC CORPORATION" }, + { 0x1C1E, "Focused Test, Inc." }, + { 0x1C1F, "Goldvish S.A." }, + { 0x1C20, "Fuji Electric Device Technology Co., Ltd." }, + { 0x1C21, "ADDMM LLC" }, + { 0x1C22, "ZHONGSHAN CHIANG YU ELECTRIC CO., LTD." }, + { 0x1C23, "Enzytek Technology Inc." }, + { 0x1C24, "DIGITAL IMAGING SYSTEMS GmbH" }, + { 0x1C25, "Sunwell Electronics Ltd." }, + { 0x1C26, "Shanghai Haiying Electronics Co., Ltd." }, + { 0x1C27, "SHENZHEN D&S INDUSTRIES LIMITED" }, + { 0x1C28, "PMDTechnologies" }, + { 0x1C29, "Elster Group" }, + { 0x1C2A, "NAVIGON AG" }, + { 0x1C2B, "SIEB & MEYER AG" }, + { 0x1C2C, "QUANTEL LTD." }, + { 0x1C2D, "Barloworld Scientific Limited" }, + { 0x1C2E, "LiveWire Test Labs, Inc." }, + { 0x1C2F, "Wessex Advanced Switching Products Ltd." }, + { 0x1C30, "Li Creative Technologies, Inc." }, + { 0x1C31, "LS Mtron" }, + { 0x1C32, "INTELBANQ" }, + { 0x1C33, "EK-TEAM GmbH" }, + { 0x1C34, "Pro-Active" }, + { 0x1C35, "Superna Inc." }, + { 0x1C36, "Axiom Manufacturing" }, + { 0x1C37, "Sonavation, Inc." }, + { 0x1C38, "Kirin Techno-System Company, Limited" }, + { 0x1C39, "Quantronix, Inc." }, + { 0x1C3A, "CCV Deutschland GmbH" }, + { 0x1C3B, "Nivis, LLC" }, + { 0x1C3C, "INFOTURE, INC." }, + { 0x1C3D, "NONIN MEDICAL INC." }, + { 0x1C3E, "Wep Peripherals" }, + { 0x1C3F, "Amfit, Inc." }, + { 0x1C40, "EZ PROTOTYPES" }, + { 0x1C41, "CompX Fort" }, + { 0x1C42, "VERCET LLC" }, + { 0x1C43, "PeCon GmbH" }, + { 0x1C44, "Fukasawa Co." }, + { 0x1C45, "NavCom Technology Inc." }, + { 0x1C46, "SEILLAC Co., Ltd." }, + { 0x1C47, "Andrew Telecommunication Product SRL" }, + { 0x1C48, "International Truck and Engine Corporation" }, + { 0x1C49, "Cherng Weei Technology Corp." }, + { 0x1C4A, "Cathay Tri-Tech., Inc." }, + { 0x1C4B, "Geratherm Respiratory GmbH" }, + { 0x1C4C, "SYSTECH" }, + { 0x1C4D, "Everest Display Inc." }, + { 0x1C4E, "Koninklijke Gazelle N.V." }, + { 0x1C4F, "Beijing Sigmachip Co., Ltd." }, + { 0x1C50, "Chatsworth Data Corporation" }, + { 0x1C51, "Wisecube Co., Ltd." }, + { 0x1C52, "FLEETWOOD ELECTRONICS LTD." }, + { 0x1C53, "Heartland Data Co." }, + { 0x1C54, "NU-LEC INDUSTRIES" }, + { 0x1C55, "LGS" }, + { 0x1C56, "RED DIGITAL CINEMA" }, + { 0x1C57, "Zalman Tech Co., Ltd." }, + { 0x1C58, "IVA Corporation" }, + { 0x1C59, "SIXNET, LLC" }, + { 0x1C5A, "Fisher and Paykel Healthcare Limited" }, + { 0x1C5B, "FUTURE WAVES PTE Ltd." }, + { 0x1C5C, "CELLMETRIC LTD." }, + { 0x1C5D, "KB Kommutatcionnoy apparatury LTD." }, + { 0x1C5E, "Fueltech Ind. & Com. Prod. Elet. Ltda." }, + { 0x1C5F, "Watec Co., Ltd." }, + { 0x1C60, "Vision & Control GmbH" }, + { 0x1C61, "ASI DataMyte, Inc." }, + { 0x1C62, "LITEPOINT CORP." }, + { 0x1C63, "DLP Design, Inc." }, + { 0x1C64, "QSI Corporation" }, + { 0x1C65, "PROCENTEC" }, + { 0x1C66, "The Trane Company" }, + { 0x1C67, "Sugar Creek Solutions LLC" }, + { 0x1C68, "Trace Systems, Inc." }, + { 0x1C69, "MPB Communications" }, + { 0x1C6A, "Regula Ltd." }, + { 0x1C6B, "Philips & Lite-ON Digital Solutions Corporation" }, + { 0x1C6C, "Skydigital Inc." }, + { 0x1C6D, "Bioptigen Inc." }, + { 0x1C6E, "MINELAB ELECTRONICS PTY LTD." }, + { 0x1C6F, "SUN-A CORPORATION" }, + { 0x1C70, "Wessa Engineering" }, + { 0x1C71, "HUMANWARE LTD." }, + { 0x1C72, "EMTEC Elektronische Messtechnik GmbH" }, + { 0x1C73, "AMT Co., Ltd." }, + { 0x1C74, "PHOTOVOX srl" }, + { 0x1C75, "ARTURIA" }, + { 0x1C76, "Sun-Light Electronic Technologies Inc." }, + { 0x1C77, "Kaetat Industrial Co., Ltd." }, + { 0x1C78, "Mindray DS USA, Inc." }, + { 0x1C79, "Unigen Corporation" }, + { 0x1C7A, "Egis Technology, Inc." }, + { 0x1C7B, "Shenzhen Luxshare Precision Industry Co., Ltd." }, + { 0x1C7C, "DELCOP LLC" }, + { 0x1C7D, "STARKEY LABORATORIES INC." }, + { 0x1C7E, "Hydrometer GmbH" }, + { 0x1C7F, "FILTRONIC DEFENCE LIMITED" }, + { 0x1C80, "Hoffmann + Krippner GmbH" }, + { 0x1C81, "MOTOSOFT b.v." }, + { 0x1C82, "Atracsys LLC" }, + { 0x1C83, "BEKA Elektronik" }, + { 0x1C84, "DRS Tactical Systems" }, + { 0x1C85, "Audyssey Laboratories, Inc." }, + { 0x1C86, "Tallahassee Technologies, Inc." }, + { 0x1C87, "2N TELEKOMUNIKACE a.s." }, + { 0x1C88, "Somagic, Inc." }, + { 0x1C89, "HONGKONG WEIDIDA ELECTRON LIMITED" }, + { 0x1C8A, "SHIN HEUNG PRECISION CO., LTD." }, + { 0x1C8B, "Bridgestone Cycle Co., Ltd." }, + { 0x1C8C, "noax Technologies AG" }, + { 0x1C8D, "Payter BV" }, + { 0x1C8E, "ASTRON INTERNATIONAL CORP." }, + { 0x1C8F, "Scolis Technologies (India) Pvt. Ltd." }, + { 0x1C90, "Pixela (Shanghai) Co., Ltd." }, + { 0x1C91, "Hutchinson Technology Incorporated" }, + { 0x1C92, "JDD Enterprises" }, + { 0x1C93, "Airspan Networks" }, + { 0x1C94, "Maerzhaeuser Wetzlar GmbH & Co. KG." }, + { 0x1C95, "OVATION SYSTEMS LIMITED" }, + { 0x1C96, "Tesselon, LLC" }, + { 0x1C97, "PEBBLE ENTERTAINMENT GmbH" }, + { 0x1C98, "ALPINE ELECTRONICS, INC." }, + { 0x1C99, "KETEREX, Inc." }, + { 0x1C9A, "Simple Step LLC" }, + { 0x1C9B, "Ohden Co., Ltd." }, + { 0x1C9C, "Technological Solutions Laboratory" }, + { 0x1C9D, "Descuentos y Electronicos AVA" }, + { 0x1C9E, "Shanghai Longcheer 3G Technology Co., Ltd." }, + { 0x1C9F, "SISS Technology Inc." }, + { 0x1CA0, "ACCARIO Inc." }, + { 0x1CA1, "Symwave, Inc." }, + { 0x1CA2, "G-coder Systems AB" }, + { 0x1CA3, "CAPAZ GmbH" }, + { 0x1CA4, "METRICO WIRELESS INC." }, + { 0x1CA5, "HASLER RAIL AG" }, + { 0x1CA6, "TECHNO-AP Limited Company" }, + { 0x1CA7, "BAE SYSTEMS AUSTRALIA LIMITED" }, + { 0x1CA8, "ROCCAT STUDIO GmbH" }, + { 0x1CA9, "THE TINTOMETER LTD." }, + { 0x1CAA, "Accel Semiconductor Corp." }, + { 0x1CAB, "SCS Engineering, Inc." }, + { 0x1CAC, "SHENZHEN KINSTONE D&T DEVELOP CO., LTD." }, + { 0x1CAD, "ONE-TOO" }, + { 0x1CAE, "MPMAN" }, + { 0x1CAF, "2WCOM GmbH" }, + { 0x1CB0, "LEGRAND FRANCE" }, + { 0x1CB1, "Enforce Device Inc." }, + { 0x1CB2, "PCO AG" }, + { 0x1CB3, "Aces Electronics Co., Ltd." }, + { 0x1CB4, "OPEX CORPORATION" }, + { 0x1CB5, "Boonton Electronics" }, + { 0x1CB6, "IDEACOM TECHNOLOGY INC." }, + { 0x1CB7, "EASTERN TIMES TECHNOLOGY CO., LTD." }, + { 0x1CB8, "Ferguson Beauregard" }, + { 0x1CB9, "DIVERSIFIED TECHNICAL SYSTEMS, INC." }, + { 0x1CBA, "MERIDIAN AUDIO LTD." }, + { 0x1CBB, "DATATEC CO., LTD." }, + { 0x1CBC, "Zizzle, LLC" }, + { 0x1CBD, "Wha Shin Co., Ltd." }, + { 0x1CBE, "Texas Instruments - Stellaris" }, + { 0x1CBF, "FORTAT SKYMARK INDUSTRIAL COMPANY" }, + { 0x1CC0, "PlantSense" }, + { 0x1CC1, "EXAKTIME INC." }, + { 0x1CC2, "CC Systems AB" }, + { 0x1CC3, "Biocomfort Diagnostics GmbH & Co. KG" }, + { 0x1CC4, "Byte Paradigm sprl" }, + { 0x1CC5, "Rane Corporation" }, + { 0x1CC6, "Digital Force Technologies" }, + { 0x1CC7, "GELOGIC" }, + { 0x1CC8, "Iofy Corporation" }, + { 0x1CC9, "COMAP, spol. s r. o." }, + { 0x1CCA, "NextWave Broadband Inc." }, + { 0x1CCB, "Lattebox Co., Ltd." }, + { 0x1CCC, "DA-DESIGN OY" }, + { 0x1CCD, "Bodatong Technology (Shenzhen) Co., Ltd." }, + { 0x1CCE, "DATA MODUL" }, + { 0x1CCF, "Konami Digital Entertainment Co., Ltd." }, + { 0x1CD0, "VEGATECH CO., LTD." }, + { 0x1CD1, "ARTAFLEX" }, + { 0x1CD2, "Christ Elektronik GmbH" }, + { 0x1CD3, "ATSUMI ELECTRIC CO., LTD." }, + { 0x1CD4, "adp corporation" }, + { 0x1CD5, "Firecomms Ltd." }, + { 0x1CD6, "Antonio Precise Products Manufactory Ltd." }, + { 0x1CD7, "GMC-I Gossen-Metrawatt GmbH" }, + { 0x1CD8, "Dash Navigation, Inc." }, + { 0x1CD9, "TL Industries" }, + { 0x1CDA, "NAVICO" }, + { 0x1CDB, "Cat Technologies Ltd." }, + { 0x1CDC, "Advanced Medical Electronics Corp." }, + { 0x1CDD, "YOOSAMFLUTE CO., LTD." }, + { 0x1CDE, "Telecommunications Technology Association (TTA)" }, + { 0x1CDF, "WonTen Technology Co., Ltd." }, + { 0x1CE0, "EDIMAX TECHNOLOGY CO., LTD." }, + { 0x1CE1, "Amphenol KAE" }, + { 0x1CE2, "Extron Electronics" }, + { 0x1CE3, "Australian Simulation Control Systems Pty., Ltd." }, + { 0x1CE4, "High Leah Electronics, Inc." }, + { 0x1CE5, "SimPhonics, Inc." }, + { 0x1CE6, "SOPRO" }, + { 0x1CE7, "FASY SPA" }, + { 0x1CE8, "Alcorn McBride, Inc." }, + { 0x1CE9, "Cadmus Payment Solutions Ltd." }, + { 0x1CEA, "MESTEK, INC." }, + { 0x1CEB, "SMARTWI" }, + { 0x1CEC, "Siemens AG I & S Postal Automation" }, + { 0x1CED, "DEWESOFT d.o.o." }, + { 0x1CEE, "Production Technology Center Kyushuu" }, + { 0x1CEF, "Siemens LD-A" }, + { 0x1CF0, "SA VALIDY" }, + { 0x1CF1, "dresden elektronik ingenieurtechnik gmbh" }, + { 0x1CF2, "TrellisWare Technologies, Inc." }, + { 0x1CF3, "Lion Power Co., Ltd." }, + { 0x1CF4, "SK INTERFACES LTD." }, + { 0x1CF5, "Swirlnet A/S" }, + { 0x1CF6, "Atlantic Zeiser GmbH" }, + { 0x1CF7, "Electric-Spin" }, + { 0x1CF8, "Biometric Associates" }, + { 0x1CF9, "Aipermon GmbH & Co. KG" }, + { 0x1CFA, "Daco Scientific Limited" }, + { 0x1CFB, "Livescribe Inc." }, + { 0x1CFC, "ANDES TECHNOLOGY CORPORATION" }, + { 0x1CFD, "Flextronics Digital Design Japan, LTD." }, + { 0x1CFE, "Cryptsoft Pty. Ltd." }, + { 0x1CFF, "Tad Radio of Canada Inc." }, + { 0x1D00, "MicroStone Corporation" }, + { 0x1D01, "SNIF Labs" }, + { 0x1D02, "DevGuru" }, + { 0x1D03, "ICON INTERNATIONAL DIGITAL LIMITED" }, + { 0x1D04, "Itronics" }, + { 0x1D05, "DESTURA S.R.L." }, + { 0x1D06, "BBK ELECTRONICS CORPORATION LIMITED" }, + { 0x1D07, "Solid-Motion" }, + { 0x1D08, "NINGBO HENTEK DRAGON ELECTRONICS CO., LTD." }, + { 0x1D09, "TechFaith Wireless Technology Limited" }, + { 0x1D0A, "Johnson Controls, Inc." }, + { 0x1D0B, "HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD." }, + { 0x1D0C, "LAKS GmbH" }, + { 0x1D0D, "TDK Marketing Europe GmbH" }, + { 0x1D0E, "deister electronic GmbH" }, + { 0x1D0F, "NEO ELECTRONICS (HK) CO., LIMITED" }, + { 0x1D10, "Jiangsu Shinco Digital Technology Co., Ltd." }, + { 0x1D11, "Xtend Technologies Pvt. Ltd." }, + { 0x1D12, "UAB TELTONIKA" }, + { 0x1D13, "L3 Communications - Telemetry West" }, + { 0x1D14, "ALPHA-SAT TECHNOLOGY LIMITED" }, + { 0x1D15, "FUJIFILM RECORDING MEDIA GmbH" }, + { 0x1D16, "KABA MAS CORPORATION" }, + { 0x1D17, "C-THRU MUSIC Ltd." }, + { 0x1D18, "APICAL INSTRUMENTS, INC." }, + { 0x1D19, "Dexatek Technology Ltd." }, + { 0x1D1A, "Boeckeler Instruments, Inc." }, + { 0x1D1B, "HumanBeams Inc." }, + { 0x1D1C, "Novatron Oy" }, + { 0x1D1D, "SYNESTHESIA CORPORATION" }, + { 0x1D1E, "OFFCODE" }, + { 0x1D1F, "Diostech Co., Ltd." }, + { 0x1D20, "SAMTACK INC." }, + { 0x1D21, "COMPUSULT LIMITED" }, + { 0x1D22, "ELCOM s.r.o." }, + { 0x1D23, "Netsushin Co., Ltd." }, + { 0x1D24, "PHOTON KINETICS" }, + { 0x1D25, "Trinity Security Systems, Inc." }, + { 0x1D26, "ADVANCED ELECTRONICS LTD." }, + { 0x1D27, "Prime Sense Ltd." }, + { 0x1D28, "JORDAN VALLEY SEMICONDUCTORS LTD." }, + { 0x1D29, "Horng Tong Enterprise Co., Ltd." }, + { 0x1D2A, "LyconSys GmbH & Co. KG" }, + { 0x1D2B, "BEN-RI ELECTRONICA S.A." }, + { 0x1D2C, "equinux AG" }, + { 0x1D2D, "Fraunhofer IBMT" }, + { 0x1D2E, "I.S.V. Co., Ltd." }, + { 0x1D2F, "JACO, INC." }, + { 0x1D30, "Sinosun Technology Ltd." }, + { 0x1D31, "XINTRONIX LIMITED" }, + { 0x1D32, "ELECTRONICA MECHATRONIC SYSTEMS (I) PVT. LTD." }, + { 0x1D33, "Lockheed Martin - Maritime Systems & Sensors" }, + { 0x1D34, "DREAM LINK LTD." }, + { 0x1D35, "ISS Manufacturing Limited" }, + { 0x1D36, "Volucris, Inc." }, + { 0x1D37, "Phoenix Microelectronics (China) Co., Ltd." }, + { 0x1D38, "Ergowerx Int'l LLC/Smartfish Technologies" }, + { 0x1D39, "XECURENEXUS Co., LTD." }, + { 0x1D3A, "P. R. Glassel & Associates, Inc." }, + { 0x1D3B, "J & C Technology Co., Ltd." }, + { 0x1D3C, "Tomei Tsushin Kogyo Co., Ltd." }, + { 0x1D3D, "R&D Center of Biometric Technology-BMSTU" }, + { 0x1D3E, "EMCON Emanation Control Limited" }, + { 0x1D3F, "Photon Control Inc." }, + { 0x1D40, "EDANIS Elektronik AG" }, + { 0x1D41, "Teletronic Rossendorf GmbH" }, + { 0x1D42, "DRAGON JOY LIMITED" }, + { 0x1D43, "Montage Technology, Inc." }, + { 0x1D44, "Adirondack Digital Imaging Systems, Inc." }, + { 0x1D45, "Qisda Corporation" }, + { 0x1D46, "nSys Design Systems" }, + { 0x1D47, "ATAUCE" }, + { 0x1D48, "Shenzhen XinYonghui Precise Technology Co., Ltd." }, + { 0x1D49, "SHENZHEN LINKCONN ELECTRONICS CO., LTD." }, + { 0x1D4A, "HKS Co., Ltd." }, + { 0x1D4B, "DARIM VISION CO." }, + { 0x1D4C, "ARK-DESIGN Co., Ltd." }, + { 0x1D4D, "Pegatron Corporation" }, + { 0x1D4E, "INPHI CORPORATION" }, + { 0x1D4F, "ADVANCED CHIP EXPRESS INC." }, + { 0x1D50, "OPENMOKO, Inc." }, + { 0x1D51, "Sengital Limited" }, + { 0x1D52, "ELECTROBYTE di GARAVAGLIA MATTIA" }, + { 0x1D53, "Innofidei Inc." }, + { 0x1D54, "ZARAM TECHNOLOGY, Inc." }, + { 0x1D55, "XRONet Corporation" }, + { 0x1D56, "Verico International Co., Ltd." }, + { 0x1D57, "Feeling Technology Corp." }, + { 0x1D58, "SUZUKI Engineering" }, + { 0x1D59, "3DSP" }, + { 0x1D5A, "Hillcrest Laboratories, Inc." }, + { 0x1D5B, "Smartronix, Inc." }, + { 0x1D5C, "Fresco Logic Inc." }, + { 0x1D5D, "QIXING INDUSTRIAL (HK) CO." }, + { 0x1D5E, "Tonium AB" }, + { 0x1D5F, "ViVOtech, Inc." }, + { 0x1D60, "ASAP International Co., Ltd." }, + { 0x1D61, "ACCEMIC GmbH & CO. KG" }, + { 0x1D62, "KYORITSU ELECTRIC CO., LTD." }, + { 0x1D63, "Nippon Seiki Co., Ltd." }, + { 0x1D64, "MobilMAX Technology Inc." }, + { 0x1D65, "Moteurs LEROY SOMER" }, + { 0x1D66, "StreamBuster" }, + { 0x1D67, "DYNAMIC INNOVATIONS LIMITED" }, + { 0x1D68, "SEMA ELECTRONICS (H.K.) CO., Ltd." }, + { 0x1D69, "Walta Electronic Co., Ltd." }, + { 0x1D6A, "ARICENT TECHNOLOGIES (HOLDINGS) LTD." }, + { 0x1D6B, "The Linux Foundation" }, + { 0x1D6C, "Man & Machine, Inc." }, + { 0x1D6D, "VARISYS LIMITED" }, + { 0x1D6E, "EUROTECH" }, + { 0x1D6F, "Seluxit" }, + { 0x1D70, "MULTIPLE ACCESS COMMUNICATIONS LTD." }, + { 0x1D71, "Finisar Corporation" }, + { 0x1D72, "Mobiltex Data Ltd." }, + { 0x1D73, "Signal Processing Devices Sweden AB" }, + { 0x1D74, "LG Innotek Co., Ltd." }, + { 0x1D75, "DICOM, spol. s r.o." }, + { 0x1D76, "LongCheng Electronic & Communication CO., LTD." }, + { 0x1D77, "Yueqing Changling Electronic Instrument Corp., Ltd." }, + { 0x1D78, "CAMBRIDGE SEMICONDUCTOR LTD." }, + { 0x1D79, "Shenzhen My-Power Technology Co., Ltd." }, + { 0x1D7A, "SHINWA INTERNATIONAL HOLDINGS LTD." }, + { 0x1D7B, "Single Strand Co., Ltd." }, + { 0x1D7C, "KarmelSonix" }, + { 0x1D7D, "Seoul Commtech Co., Ltd." }, + { 0x1D7E, "WAVESAT" }, + { 0x1D7F, "MoBeam, Inc." }, + { 0x1D80, "PLDA" }, + { 0x1D81, "YongXin Plastic & Hardware Co., Ltd." }, + { 0x1D82, "HERTZ SYSTEMTECHNIK GmbH" }, + { 0x1D83, "Mantech International" }, + { 0x1D84, "Kechenda Plastic Electronic Factory" }, + { 0x1D85, "NINGBO SHUNSHENG COMMUNICATION APPARATUS CO., LTD." }, + { 0x1D86, "C.D.N. CORPORATION" }, + { 0x1D87, "RHK TECHNOLOGY, INC." }, + { 0x1D88, "Mahr GmbH" }, + { 0x1D89, "Hunter Associates" }, + { 0x1D8A, "OSASI Technos Inc. (Tokyo Headquarters)" }, + { 0x1D8B, "MEDTRONIC" }, + { 0x1D8C, "Wuxi AlphaScale IC Systems, Inc." }, + { 0x1D8D, "EXEO SYSTEMS" }, + { 0x1D8E, "Capistrano Labs, Inc." }, + { 0x1D8F, "Viprinet GmbH" }, + { 0x1D90, "CITIZEN SYSTEMS JAPAN CO., LTD." }, + { 0x1D91, "BYD COMPANY LIMITED" }, + { 0x1D92, "SPECTRONIC DEVICES LTD." }, + { 0x1D93, "Tokyo System Development Co., Ltd." }, + { 0x1D94, "ENCIRIS TECHNOLOGIES" }, + { 0x1D95, "SYSTRONIK Elektronik und Systemtechnik GmbH" }, + { 0x1D96, "CHIRSON LTD." }, + { 0x1D97, "Telonics" }, + { 0x1D98, "OUTLINE ELECTRONICS LTD." }, + { 0x1D99, "Shanghai HSIC Application System Co., Ltd." }, + { 0x1D9A, "Vubiq, Inc." }, + { 0x1D9B, "Techno Source" }, + { 0x1D9C, "SONIM TECHNOLOGIES, INC." }, + { 0x1D9D, "Sigma Elektro GmbH" }, + { 0x1D9E, "CSR, Inc." }, + { 0x1D9F, "KUNMING ELECTRONICS CO., LTD." }, + { 0x1DA0, "Parade Technologies, Inc." }, + { 0x1DA1, "COVIDENCE A/S" }, + { 0x1DA2, "LAMBDA, INC." }, + { 0x1DA3, "bebro electronic GmbH" }, + { 0x1DA4, "BTICINO" }, + { 0x1DA5, "CATHEXIS INNOVATIONS INC." }, + { 0x1DA6, "Inepro BV" }, + { 0x1DA7, "ENDRA Inc." }, + { 0x1DA8, "VIOLET" }, + { 0x1DA9, "In-Circuit GmbH" }, + { 0x1DAA, "Alcatel-Lucent" }, + { 0x1DAB, "MAGELLAN GPS" }, + { 0x1DAC, "MOBOTIX AG" }, + { 0x1DAD, "DATNET KFT" }, + { 0x1DAE, "ellipsis INC." }, + { 0x1DAF, "Breas Medical AB" }, + { 0x1DB0, "GreenPeak Technologies NV" }, + { 0x1DB1, "Reliable Controls Corporation" }, + { 0x1DB2, "Duali Inc." }, + { 0x1DB3, "Arcelik A.S." }, + { 0x1DB4, "Montalvo Systems" }, + { 0x1DB5, "BRYSTON LTD." }, + { 0x1DB6, "eDimensional, Inc." }, + { 0x1DB7, "SMedia Technology Corporation" }, + { 0x1DB8, "HD MEDICAL INC." }, + { 0x1DB9, "LITEN UP TECHNOLOGIES INC." }, + { 0x1DBA, "BancTec, Inc." }, + { 0x1DBB, "Condalo GmbH" }, + { 0x1DBC, "Shenzhen HOJY Technology Co., Ltd." }, + { 0x1DBD, "Terawins" }, + { 0x1DBE, "S.R.N. Corporation" }, + { 0x1DBF, "Signostics Pty. Ltd." }, + { 0x1DC0, "DATAFIELD INDIA PVT.LTD." }, + { 0x1DC1, "Laser Drive" }, + { 0x1DC2, "Datalogic Mobile Inc." }, + { 0x1DC3, "PoLabs" }, + { 0x1DC4, "TRANSICS" }, + { 0x1DC5, "Pixim Inc." }, + { 0x1DC6, "Miyama, Inc." }, + { 0x1DC7, "Leroy Automatique Industrielle" }, + { 0x1DC8, "GC Corporation" }, + { 0x1DC9, "Hitachi Koki Co., Ltd." }, + { 0x1DCA, "The IVOXX Corp." }, + { 0x1DCB, "IFTEST AG" }, + { 0x1DCC, "Document Capture Technologies, Inc." }, + { 0x1DCD, "HIN KUI MACHINE & METAL INDUSTRIAL CO., LTD." }, + { 0x1DCE, "SIMTEC Elektronik GmbH" }, + { 0x1DCF, "INVIX Co., Ltd." }, + { 0x1DD0, "ABB AS, Division Automation Products" }, + { 0x1DD1, "EFJohnson" }, + { 0x1DD2, "LEO BODNAR" }, + { 0x1DD3, "Dajac, Inc." }, + { 0x1DD4, "ARMELIN WIDGET CORPORATION" }, + { 0x1DD5, "MetaGeek, LLC" }, + { 0x1DD6, "Solomon Technology Corp." }, + { 0x1DD7, "REDMERE TECHNOLOGY" }, + { 0x1DD8, "BUFFALO KOKUYO SUPPLY INC." }, + { 0x1DD9, "EFFICERE TECHNOLOGIES" }, + { 0x1DDA, "TA Instruments" }, + { 0x1DDB, "Abon Touchsystems Inc." }, + { 0x1DDC, "id Quantique" }, + { 0x1DDD, "DOKING ELECTRONIC TECHNOLOGY CO., LTD." }, + { 0x1DDE, "TridonicAtco" }, + { 0x1DDF, "GDA Technologies, Inc." }, + { 0x1DE0, "Shenzhen Excelstor Technology Ltd." }, + { 0x1DE1, "Actions Microelectronics Co., Ltd." }, + { 0x1DE2, "ENTERY INDUSTRIAL CO., LTD." }, + { 0x1DE3, "SHENZHEN REX ELECTRONICS CO., LTD." }, + { 0x1DE4, "DAEWOO ELECTRONICS CORPORATION" }, + { 0x1DE5, "AMONTEC" }, + { 0x1DE6, "MICRORISC S.R.O." }, + { 0x1DE7, "MIDAS TECHNOLOGY" }, + { 0x1DE8, "Applied Systems Engineering, Inc." }, + { 0x1DE9, "Seco Technology Co., Ltd." }, + { 0x1DEA, "Yesin Electronics Technology Co., Ltd." }, + { 0x1DEB, "SHIUH CHI PRECISION INDUSTRY CO., LTD." }, + { 0x1DEC, "HAGER CONTROLS SAS" }, + { 0x1DED, "COOLIT SYSTEMS, INC." }, + { 0x1DEE, "JCM II, Inc." }, + { 0x1DEF, "KYOTO KAGAKU CO., LTD." }, + { 0x1DF0, "TRICKLESTAR LIMITED" }, + { 0x1DF1, "HUATIANYUAN ELECTRONIC INDUSTRY CO., LTD." }, + { 0x1DF2, "Telecommunication Metrology Center of MII" }, + { 0x1DF3, "CRESYN CO., LTD." }, + { 0x1DF4, "SHEN ZHEN FORMAN PRECISION INDUSTRY CO., LTD." }, + { 0x1DF5, "Universal Remote Control, Inc." }, + { 0x1DF6, "TakeMS International AG" }, + { 0x1DF7, "Mirics Semiconductor Ltd." }, + { 0x1DF8, "The Charles Machine Works, Inc." }, + { 0x1DF9, "Komax AG" }, + { 0x1DFA, "BLOCKMASTER AB" }, + { 0x1DFB, "marco Systemanalyse und Entwicklung GmbH" }, + { 0x1DFC, "YUNNAN NANTIAN ELECTRONICS INFORMATION CO., LTD." }, + { 0x1DFD, "Quality Thermistor, Inc." }, + { 0x1DFE, "BEDA Precision" }, + { 0x1DFF, "InfraRed Integrated Systems Ltd." }, + { 0x1E00, "Jupiter Systems" }, + { 0x1E01, "Dynalloy, Inc." }, + { 0x1E02, "GLOBEMASTER TECHNOLOGIES CO., LTD." }, + { 0x1E03, "OXFORD INSTRUMENTS ANALYTICAL OY" }, + { 0x1E04, "Coolsand Technologies (Hong Kong) Ltd." }, + { 0x1E05, "Microtronic AG" }, + { 0x1E06, "Moore Industries International" }, + { 0x1E07, "GETA ELECTRONICS (DONG GUAN) CO., LTD." }, + { 0x1E08, "Inventure, Inc." }, + { 0x1E09, "Baldwin Boxall Communication Ltd." }, + { 0x1E0A, "NOX Medical" }, + { 0x1E0B, "TUBITAK UEKAE" }, + { 0x1E0C, "NATIONAL HYBRID, INC." }, + { 0x1E0D, "NEOWAVE" }, + { 0x1E0E, "SHANGHAI BASECOM LTD." }, + { 0x1E0F, "mSilica Inc." }, + { 0x1E10, "Point Grey Research Inc." }, + { 0x1E11, "Hoya Xponent" }, + { 0x1E12, "OCTRIAN" }, + { 0x1E13, "Burgundy Electric, LLC" }, + { 0x1E14, "YANtide Corporation" }, + { 0x1E15, "mStation" }, + { 0x1E16, "SMARTIO" }, + { 0x1E17, "Mirion Technologies Inc." }, + { 0x1E18, "MIGHT Co., Ltd." }, + { 0x1E19, "Torus Networks Co., Ltd." }, + { 0x1E1A, "HITEC RCD KOREA" }, + { 0x1E1B, "e-Practical Solutions" }, + { 0x1E1C, "CMS PRODUCTS" }, + { 0x1E1D, "Kanguru Solutions" }, + { 0x1E1E, "Trans New Technology, Inc." }, + { 0x1E1F, "INVIA" }, + { 0x1E20, "JDSU" }, + { 0x1E21, "NEONUMERIC" }, + { 0x1E22, "LEDCO" }, + { 0x1E23, "Aeronix, Inc." }, + { 0x1E24, "Cine-tal Systems, Inc." }, + { 0x1E25, "3M Cogent, Inc." }, + { 0x1E26, "Multi Channel Systems MCS GmbH" }, + { 0x1E27, "NASA / Johnson Space Center / EV2" }, + { 0x1E28, "Raptor Innovations International" }, + { 0x1E29, "Festo AG & Co. KG" }, + { 0x1E2A, "NANOFORTI INC." }, + { 0x1E2B, "3M CMD (Communication Markets Division)" }, + { 0x1E2C, "KRONIK ELEKTRONIK SANAYI VETICARET LIMITED SIRKETI" }, + { 0x1E2D, "Cinterion Wireless Modules GmbH" }, + { 0x1E2E, "Syrinx Industrial Electronics b.v." }, + { 0x1E2F, "Celrun Co., Ltd." }, + { 0x1E30, "Kohler Co." }, + { 0x1E31, "Greatbatch" }, + { 0x1E32, "Opti-Sciences, Inc." }, + { 0x1E33, "KOBIAN CANADA INC." }, + { 0x1E34, "Sensory, Inc." }, + { 0x1E35, "BELLING Co., Ltd." }, + { 0x1E36, "Insulet Corporation" }, + { 0x1E37, "Rehoboth Tech. Co., Ltd." }, + { 0x1E38, "QRS Music Technologies Inc." }, + { 0x1E39, "YIS Corporation" }, + { 0x1E3A, "Continental Automotive Systems Inc." }, + { 0x1E3B, "MICROBIT 2.0 AB" }, + { 0x1E3C, "Vapor Bus Int'l Div of Westinghouse Air Brake Tech Corp" }, + { 0x1E3D, "Chipsbrand Technologies (HK) Co., Limited" }, + { 0x1E3E, "EMS Aviation" }, + { 0x1E3F, "JJ Keller & Associates Inc." }, + { 0x1E40, "SciLog, Inc." }, + { 0x1E41, "Cleverscope Ltd." }, + { 0x1E42, "SSE GmbH" }, + { 0x1E43, "Sagem Mobiles" }, + { 0x1E44, "SHIMANO INC." }, + { 0x1E45, "TADANO LTD." }, + { 0x1E46, "Danfoss A/S" }, + { 0x1E47, "HUNG TA H.T.ENTERPRISE CO., LTD." }, + { 0x1E48, "LABAU Technology" }, + { 0x1E49, "FES LLC" }, + { 0x1E4A, "CHIRON TECHNOLOGY LTD." }, + { 0x1E4B, "exxact GmbH" }, + { 0x1E4C, "Stereotaxis, Inc." }, + { 0x1E4D, "BST International GmbH" }, + { 0x1E4E, "Etron Technology, Inc." }, + { 0x1E4F, "SECOM Co., Ltd." }, + { 0x1E50, "VILTECHMEDA UAB" }, + { 0x1E51, "DiMoto" }, + { 0x1E52, "SZ TELSTAR CO., LTD." }, + { 0x1E53, "WYPLAY" }, + { 0x1E54, "TypeMatrix Inc." }, + { 0x1E55, "Memorysolution GmbH" }, + { 0x1E56, "EURINTEL" }, + { 0x1E57, "Bundesdruckerei GmbH" }, + { 0x1E58, "Horner APG" }, + { 0x1E59, "inTera Tecnologia" }, + { 0x1E5A, "VOXTRONIC TECHNOLOGY" }, + { 0x1E5B, "APRICO A/S" }, + { 0x1E5C, "Enova Technology Corp." }, + { 0x1E5D, "SAT Corporation" }, + { 0x1E5E, "Touch International" }, + { 0x1E5F, "Relpol SA" }, + { 0x1E60, "SEA Signalisation" }, + { 0x1E61, "Anoto AB" }, + { 0x1E62, "Uriver Inc." }, + { 0x1E63, "DRAEGER MEDICAL" }, + { 0x1E64, "IMSTORAGE CO., LTD." }, + { 0x1E65, "BOEING INTEGRATED DEFENSE SYSTEMS" }, + { 0x1E66, "KAPSYS" }, + { 0x1E67, "Orban/CRL Systems, Inc." }, + { 0x1E68, "TrekStor GmbH & Co. KG" }, + { 0x1E69, "Hormann Funkwerk Kolleda GmbH" }, + { 0x1E6A, "RGB Spectrum" }, + { 0x1E6B, "iRex Technologies B.V." }, + { 0x1E6C, "Sureshotgps Pty. Ltd." }, + { 0x1E6D, "WAN SHIH ELECTRONIC (H.K.) CO., LTD." }, + { 0x1E6E, "F&D Feinwerk-Und Drucktechnik GmbH" }, + { 0x1E6F, "Images Scientific Instruments Inc." }, + { 0x1E70, "POSBRO Inc." }, + { 0x1E71, "NZXT Corporation" }, + { 0x1E72, "Federal Signal Corporation" }, + { 0x1E73, "COMLINK ELECTRONICS CO., LTD." }, + { 0x1E74, "COBY COMMUNICATIONS, LIMITED" }, + { 0x1E75, "TLS Communication GmbH" }, + { 0x1E76, "Proview Technology (Shenzhen) Co., Ltd." }, + { 0x1E77, "Core Micro Technology Inc." }, + { 0x1E78, "Flextronics R & D (Shenzhen) Co., Ltd." }, + { 0x1E79, "ISA Co., Ltd." }, + { 0x1E7A, "The Tsurumi-Seiki Company, Limited" }, + { 0x1E7B, "Zurich Instruments AG" }, + { 0x1E7C, "biostep GmbH" }, + { 0x1E7D, "ROCCAT GmbH" }, + { 0x1E7E, "Bright Star Engineering Inc." }, + { 0x1E7F, "NEXS ELECTRONIC CORP." }, + { 0x1E80, "InterDigital Communications LLC" }, + { 0x1E81, "KIDS PREFERRED, LLC." }, + { 0x1E82, "Nortech Systems" }, + { 0x1E83, "AMICUS WIRELESS" }, + { 0x1E84, "VIVAX CORPORATION" }, + { 0x1E85, "Gigaset Communications GmbH" }, + { 0x1E86, "Japan Meditech Co., Ltd." }, + { 0x1E87, "W&W Communications Inc." }, + { 0x1E88, "GBS Laboratories, LLC" }, + { 0x1E89, "Vtion Information Technology (Fujian) Co., Ltd." }, + { 0x1E8A, "HIBEST Electronic (DongGuan) Co., Ltd." }, + { 0x1E8B, "ImTech, Inc." }, + { 0x1E8C, "Data Conversion Systems Ltd." }, + { 0x1E8D, "HIGHVOLT Prueftechnik Dresden GmbH" }, + { 0x1E8E, "EADS Secure Networks" }, + { 0x1E8F, "PublicSolution GmbH" }, + { 0x1E90, "Mego Afek" }, + { 0x1E91, "New Concepts Dev Corp. dba Other World Computing (OWC)" }, + { 0x1E92, "Beyond Question Learning Technologies, Inc." }, + { 0x1E93, "GSI Group" }, + { 0x1E94, "RealD" }, + { 0x1E95, "DIRECTV, Inc." }, + { 0x1E96, "BlueAnt Wireless" }, + { 0x1E97, "TOMMYCA HONG KONG LIMITED" }, + { 0x1E98, "COMPASS SYSTEMS CORP." }, + { 0x1E99, "General Dynamics C4 Systems" }, + { 0x1E9A, "MANTHAN SEMICONDUCTOR PVT. LTD." }, + { 0x1E9B, "Netcom Sicherheitstechnik GmbH" }, + { 0x1E9C, "FirstPaper, LLC" }, + { 0x1E9D, "GEOTEST AG" }, + { 0x1E9E, "InnoSys Inc." }, + { 0x1E9F, "Chase Peabody and Associates, Inc." }, + { 0x1EA0, "DiabloSport, Inc." }, + { 0x1EA1, "NANOBASE" }, + { 0x1EA2, "N.V. Nederlandsche Apparatenfabriek Nedap" }, + { 0x1EA3, "Concraft Holding Co., Ltd." }, + { 0x1EA4, "MOBILE SYSTEM TECHNOLOGIES INC." }, + { 0x1EA5, "CEN LINK CO., LTD." }, + { 0x1EA6, "novero GmbH" }, + { 0x1EA7, "SEMITEK INTERNATIONAL (HK) HOLDING LTD." }, + { 0x1EA8, "Shenzhen Excelsecu Data Technology Co., Ltd." }, + { 0x1EA9, "ANDERS ELECTRONICS PLC" }, + { 0x1EAA, "Zeebo, Inc." }, + { 0x1EAB, "Fujian Newland Auto-ID Tech. Co., Ltd." }, + { 0x1EAC, "Thinkware Systems" }, + { 0x1EAD, "Industrial Control Communications, Inc." }, + { 0x1EAE, "YESCNC CO., LTD." }, + { 0x1EAF, "Continental Trading GmbH" }, + { 0x1EB0, "Centers for Disease Control & Prevention (CDC)" }, + { 0x1EB1, "Kramer Electronics Ltd." }, + { 0x1EB2, "IWAKI CO., LTD." }, + { 0x1EB3, "SAE MAGNETICS (HK) LTD." }, + { 0x1EB4, "YuhDing Precision Industry (KunShan) Co., Ltd." }, + { 0x1EB5, "Diablo Technologies Inc." }, + { 0x1EB6, "PHYLINKS LIMITED" }, + { 0x1EB7, "WIN WIN PRECISION INDUSTRIAL CO., LTD." }, + { 0x1EB8, "MODACOM CO., LTD." }, + { 0x1EB9, "Campbell Scientific Inc." }, + { 0x1EBA, "HITTITE MICROWAVE CORP." }, + { 0x1EBB, "NuCORE Technology, Inc." }, + { 0x1EBC, "Beijing Novel-Super Media Investment Co., Ltd." }, + { 0x1EBD, "Wireless Matrix Corp." }, + { 0x1EBE, "Qwizdom, Inc." }, + { 0x1EBF, "Yulong Computer Telecommunication Scientific" }, + { 0x1EC0, "VIGORHOOD PHOTOELECTRIC SHENZHEN CO., LTD." }, + { 0x1EC1, "PROTEK DEVICES" }, + { 0x1EC2, "CHUO ELECTRONICS CO., LTD." }, + { 0x1EC3, "ANDREAS STIHL AG & Co. KG" }, + { 0x1EC4, "ELTRONIC SOLUTION A/S" }, + { 0x1EC5, "SIDSA" }, + { 0x1EC6, "PHYWORKS LTD." }, + { 0x1EC7, "Gefen Inc." }, + { 0x1EC8, "TelePath Technologies Co., Ltd." }, + { 0x1EC9, "MOSER BAER INDIA LIMITED" }, + { 0x1ECA, "Mintpass Co., Ltd." }, + { 0x1ECB, "Advanced Mobile Telecom Co., Ltd." }, + { 0x1ECC, "Enfora, Inc." }, + { 0x1ECD, "Alverix Inc." }, + { 0x1ECE, "MyungMin Systems, Inc." }, + { 0x1ECF, "MDR Grup S.R.L." }, + { 0x1ED0, "Hirschmann Car Communication GmbH" }, + { 0x1ED1, "DIGITAL CHINA NETWORKS (BEIJING) LIMITED" }, + { 0x1ED2, "Crevis Co., Ltd." }, + { 0x1ED3, "Forsis GmbH" }, + { 0x1ED4, "Transwitch (Israel) Ltd." }, + { 0x1ED5, "LLC GlobalTest" }, + { 0x1ED6, "adidas International" }, + { 0x1ED7, "Headplay, Inc." }, + { 0x1ED8, "Fender Musical Instruments Corp." }, + { 0x1ED9, "ALBUMteam, Ltd." }, + { 0x1EDA, "AIRTIES WIRELESS NETWORKS" }, + { 0x1EDB, "BLACKMAGIC DESIGN PTY." }, + { 0x1EDC, "B-DeltaCom" }, + { 0x1EDD, "IRIDIUM SATELLITE LLC" }, + { 0x1EDE, "steute Schaltgerate GmbH & Co. KG" }, + { 0x1EDF, "Selectwireless Co., Ltd." }, + { 0x1EE0, "KYUDEN TECHNOSYSTEMS CORPORATION" }, + { 0x1EE1, "Matrix Key Inc." }, + { 0x1EE2, "NOVA GAMING" }, + { 0x1EE3, "3D INNOVATIONS, LLC" }, + { 0x1EE4, "Luff Technology Co., Ltd." }, + { 0x1EE5, "Spring Soft K.K." }, + { 0x1EE6, "SHENZHEN EVERWIN PRECISION TECHNOLOGY CO., LTD." }, + { 0x1EE7, "EPCOS" }, + { 0x1EE8, "ONDA COMMUNICATION S.p.a." }, + { 0x1EE9, "PC PARTNER LIMITED" }, + { 0x1EEA, "Yullin Technologies Co., Ltd." }, + { 0x1EEB, "GEOTATE" }, + { 0x1EEC, "CTC Analytics AG" }, + { 0x1EED, "Helo Oy / Helo Ltd." }, + { 0x1EEE, "RigiSystems AG" }, + { 0x1EEF, "I.C.Y. B.V." }, + { 0x1EF0, "Thunder Tiger Corp." }, + { 0x1EF1, "PQ Computing Ltd." }, + { 0x1EF2, "Vircion Inc." }, + { 0x1EF3, "JIANGXI SHIP ELECTRONICS CO., LTD." }, + { 0x1EF4, "TATA ELXSI LTD." }, + { 0x1EF5, "Impinj, Inc." }, + { 0x1EF6, "EADS Deutschland GmbH" }, + { 0x1EF7, "ZiiLABS Ltd." }, + { 0x1EF8, "CRITICAL LINK, LLC" }, + { 0x1EF9, "US Army Electronic Proving Ground" }, + { 0x1EFA, "SEIKO Precision Inc." }, + { 0x1EFB, "TOUR & ANDERSSON AB" }, + { 0x1EFC, "IMOGEN STUDIO" }, + { 0x1EFD, "ROFIN-SINAR LASER GMBH" }, + { 0x1EFE, "Sound Design Technologies" }, + { 0x1EFF, "Kinemetrics, Inc." }, + { 0x1F00, "YUEQING ZHONGLI COMPUTER ELECTRONICS CO., LTD." }, + { 0x1F01, "Geo Studio Technology" }, + { 0x1F02, "Australian National University" }, + { 0x1F03, "PTW Freiburg GmbH" }, + { 0x1F04, "Watlow" }, + { 0x1F05, "Kyosai Technos Co., Ltd." }, + { 0x1F06, "K.T.E.-Keter Technologies Europe" }, + { 0x1F07, "OPTOQUEST Co., Ltd." }, + { 0x1F08, "Digital Ally Inc." }, + { 0x1F09, "DURAG GmbH" }, + { 0x1F0A, "AUROX Ltd." }, + { 0x1F0B, "INTRONIX TEST INSTURMENTS, INC." }, + { 0x1F0C, "Fourier Systems Ltd." }, + { 0x1F0D, "NAMOS" }, + { 0x1F0E, "Inflexis Corporation" }, + { 0x1F0F, "Action Technology (SZ) Co., Ltd." }, + { 0x1F10, "LTW TECHNOLOGY CO., LTD." }, + { 0x1F11, "VIRAGE LOGIC" }, + { 0x1F12, "Photometrics" }, + { 0x1F13, "CENTURY SYSTEMS Co., Ltd." }, + { 0x1F14, "Astoria Networks GmbH" }, + { 0x1F15, "Schmitt Industries Inc." }, + { 0x1F16, "Olidata SpA" }, + { 0x1F17, "APIS Device, Inc." }, + { 0x1F18, "Teseq GmbH" }, + { 0x1F19, "POLATIS INC." }, + { 0x1F1A, "SANDEN CORPORATION" }, + { 0x1F1B, "NORTHROP GRUMMAN SPERRY MARINE" }, + { 0x1F1C, "LXE, INC." }, + { 0x1F1D, "How Weih Precision Technology (Shenzhen)Co., Ltd." }, + { 0x1F1E, "TSIEN (UK) LTD." }, + { 0x1F1F, "RaaX Co., Ltd." }, + { 0x1F20, "Shenzhen Tenwei Electronics Co., Ltd." }, + { 0x1F21, "Scosche Industries" }, + { 0x1F22, "STAr Technologies, Inc." }, + { 0x1F23, "KOUEI SYSTEM, LTD." }, + { 0x1F24, "EBTRON INC." }, + { 0x1F25, "Victron Energy B.V." }, + { 0x1F26, "INCAP GmbH" }, + { 0x1F27, "KEE Action Sports (Hater Paintball)" }, + { 0x1F28, "Cal-Comp Electronics & Communications" }, + { 0x1F29, "Analogix Semiconductor, Inc." }, + { 0x1F2A, "Scene Double Ltd." }, + { 0x1F2B, "JUKI CORPORATION" }, + { 0x1F2C, "SELESTA INGEGNERIA SPA" }, + { 0x1F2D, "Liteye Systems, Inc." }, + { 0x1F2E, "ARMOUR GROUP PLC." }, + { 0x1F2F, "UPOS SYSTEM SP. Z O.O." }, + { 0x1F30, "RENA GmbH" }, + { 0x1F31, "SASKEN COMMUNICATION TECH LTD." }, + { 0x1F32, "COCHLEAR TECHNOLOGY CENTRE BELGIUM" }, + { 0x1F33, "GrupoPIE Portugal, S.A." }, + { 0x1F34, "Dutronics" }, + { 0x1F35, "Amphenol Shouh Min Industry" }, + { 0x1F36, "ddm hopt + schuler GmbH & Co. KG" }, + { 0x1F37, "Next Step Solutions Limited" }, + { 0x1F38, "Kesumo, LLC" }, + { 0x1F39, "Sumitomo Electric Networks, Inc." }, + { 0x1F3A, "All Will Technology Co., Ltd." }, + { 0x1F3B, "Biocryptodisk Sdn Bhd" }, + { 0x1F3C, "Chang Yang Electronics Company Ltd." }, + { 0x1F3D, "Advanced Engineering Services Co., Ltd." }, + { 0x1F3E, "Telenot Electronic GmbH" }, + { 0x1F3F, "SECA GmbH & Co. KG" }, + { 0x1F40, "JiangSu Dongda Integrated Circuits Sys. Eng. Tech. Co." }, + { 0x1F41, "Nipro Diagnostics, Inc" }, + { 0x1F42, "ID2P TECHNOLOGIES, INC." }, + { 0x1F43, "RAPID BRIDGE LLC" }, + { 0x1F44, "Digital Business Process (dba: The Neat Company)" }, + { 0x1F45, "QUALCOMM ENTERPRISE SERVICES" }, + { 0x1F46, "Gener8, Inc." }, + { 0x1F47, "Orb Networks, Inc." }, + { 0x1F48, "H-TRONIC GmbH" }, + { 0x1F49, "Exelis, Inc." }, + { 0x1F4A, "Key Ingredient Corporation" }, + { 0x1F4B, "Precision System Science Co., Ltd." }, + { 0x1F4C, "Cyber Sport Pty., Ltd." }, + { 0x1F4D, "SHENZHEN GENIATECH INC., LTD." }, + { 0x1F4E, "OFF-NET SERVICE LIMITED" }, + { 0x1F4F, "EXAR CORPORATION - JAPAN" }, + { 0x1F50, "KEMPPI OY" }, + { 0x1F51, "Helmut Hund GmbH" }, + { 0x1F52, "Systems & Electronic Development FZCO (SEDCO)" }, + { 0x1F53, "SK telesys" }, + { 0x1F54, "Data Tech Systems, LLC" }, + { 0x1F55, "Fujitsu Semiconductor Europe GmbH" }, + { 0x1F56, "MUT" }, + { 0x1F57, "PIGNOLO S.P.A." }, + { 0x1F58, "Inmarsat" }, + { 0x1F59, "EL.MO. S.P.A." }, + { 0x1F5A, "Micronova srl." }, + { 0x1F5B, "KYODO COMMUNICATIONS & ELECTRONICS INC." }, + { 0x1F5C, "MIDORI ANZEN CO., LTD." }, + { 0x1F5D, "Mobii Systems (Pty) Ltd." }, + { 0x1F5E, "Techsonic Industries, a subsidiary of Johnson Outdoors" }, + { 0x1F5F, "NETCLEUS SYSTEMS Corporation" }, + { 0x1F60, "Young at Heart International Ltd." }, + { 0x1F61, "Flexocard GmbH" }, + { 0x1F62, "Elquest Corporation" }, + { 0x1F63, "IriTech, Inc." }, + { 0x1F64, "actionXL, Inc." }, + { 0x1F65, "Taylor Technologies, Co., Ltd." }, + { 0x1F66, "Hokkaido Electronics Corporation" }, + { 0x1F67, "MICRO INNOVATIONS CORP." }, + { 0x1F68, "General Dynamics UK Limited" }, + { 0x1F69, "NVIS, Inc." }, + { 0x1F6A, "AJA VIDEO SYSTEMS INC." }, + { 0x1F6B, "Muve, Inc." }, + { 0x1F6C, "Cadex Electronics Inc." }, + { 0x1F6D, "AMTI" }, + { 0x1F6E, "AccuVein LLC" }, + { 0x1F6F, "ALIPHCOM, INC." }, + { 0x1F70, "MKD Technology Inc." }, + { 0x1F71, "Huaya Microelectronics (HK) Ltd." }, + { 0x1F72, "GM INSTRUMENTS LTD." }, + { 0x1F73, "Record4Free.TV AG" }, + { 0x1F74, "UNISTO Ltd." }, + { 0x1F75, "Innostor Co., Ltd." }, + { 0x1F76, "CYBER-RAIN, INC." }, + { 0x1F77, "POSITRON PUBLIC SAFETY SYSTEMS" }, + { 0x1F78, "UNION TOOL CO." }, + { 0x1F79, "Rosen Technology and Research Center GmbH" }, + { 0x1F7A, "WhiteOak Controls Inc." }, + { 0x1F7B, "AVMAP SRL" }, + { 0x1F7C, "Voltopia e.U." }, + { 0x1F7D, "UNICARD S.A." }, + { 0x1F7E, "Canon India Private Limited" }, + { 0x1F7F, "NOVA Sensors" }, + { 0x1F80, "MagicPixel Inc." }, + { 0x1F81, "HYB D.O.O." }, + { 0x1F82, "TANDBERG TELECOM AS" }, + { 0x1F83, "Beauty Up Co., Ltd." }, + { 0x1F84, "Inverness Medical Innovations, Inc." }, + { 0x1F85, "Netronix Inc." }, + { 0x1F86, "Skyworth Multimedia (Shenzhen) Co., Ltd." }, + { 0x1F87, "STANTUM" }, + { 0x1F88, "Modu Ltd." }, + { 0x1F89, "Dongguan Goldconn Electronics Co., Ltd." }, + { 0x1F8A, "Morning Star Industrial Co., Ltd." }, + { 0x1F8B, "Rittal GmbH & Co. KG" }, + { 0x1F8C, "Reference, LLC." }, + { 0x1F8D, "DEVICE FUNCTIONS" }, + { 0x1F8E, "SENSE INSIDE GmbH" }, + { 0x1F8F, "Narda Safety Test Solutions GmbH" }, + { 0x1F90, "PURE TECHNOLOGIES" }, + { 0x1F91, "Wilhelm Mikroelektronik GmbH" }, + { 0x1F92, "INTERNATIONAL TECHNIDYNE CORP." }, + { 0x1F93, "Alcohol Monitoring Systems, Inc." }, + { 0x1F94, "Microhard Systems Inc." }, + { 0x1F95, "Art of Technology AG" }, + { 0x1F96, "Ascend Geo, LLC" }, + { 0x1F97, "OZMO, INC. DBA OZMO DEVICES" }, + { 0x1F98, "DSP Design Limited" }, + { 0x1F99, "TOKAI RIKEN CO., LTD." }, + { 0x1F9A, "Barron Associates, Inc." }, + { 0x1F9B, "UBIQUITI Networks, Inc." }, + { 0x1F9C, "ARVOO Engineering BV" }, + { 0x1F9D, "Tri Works" }, + { 0x1F9E, "MUTECH LIMITED" }, + { 0x1F9F, "CasaTools, LLC" }, + { 0x1FA0, "XLNT IDEA, INC." }, + { 0x1FA1, "Curtis Instruments, Inc." }, + { 0x1FA2, "AMETEK DENMARK A/S" }, + { 0x1FA3, "LAIRD TECHNOLOGIES" }, + { 0x1FA4, "BRIDGEPORT INSTRUMENTS, LLC" }, + { 0x1FA5, "DELTA DORE" }, + { 0x1FA6, "Daylight Solutions, Inc." }, + { 0x1FA7, "COSMOS WEB CO., LTD." }, + { 0x1FA8, "TCL Technoly Electronics (Hui Zhou) Co., Ltd." }, + { 0x1FA9, "Digital Information Technologies Corporation" }, + { 0x1FAA, "Zhong Shan City Li Tai Electronic Industrial Co., Ltd." }, + { 0x1FAB, "SAMSUNG DIGITAL IMAGING CO., LTD." }, + { 0x1FAC, "Franklin Technology Inc." }, + { 0x1FAD, "Cresta Technology Inc." }, + { 0x1FAE, "Lumidigm, Inc." }, + { 0x1FAF, "Weintek Labs, Inc." }, + { 0x1FB0, "Discera, Inc." }, + { 0x1FB1, "Weatronic GmbH" }, + { 0x1FB2, "WITHINGS" }, + { 0x1FB3, "Matchbeeper AB" }, + { 0x1FB4, "Owl Computing Technologies, Inc." }, + { 0x1FB5, "Siemens Enterprise Communications GmbH & Co. KG" }, + { 0x1FB6, "SheKel" }, + { 0x1FB7, "J & D Tech Co., Ltd." }, + { 0x1FB8, "DORMA TIME + ACCESS GmbH" }, + { 0x1FB9, "Lake Shore Cryotronics, Inc." }, + { 0x1FBA, "DERMALOG GmbH" }, + { 0x1FBB, "PC Worth Int'l Co., Ltd." }, + { 0x1FBC, "Kurzweil Education Systems, Inc." }, + { 0x1FBD, "STACK LTD." }, + { 0x1FBE, "CGS" }, + { 0x1FBF, "OVAL Corporation" }, + { 0x1FC0, "JUNE-ON Co., Ltd." }, + { 0x1FC1, "Blue Chip Technology Limited" }, + { 0x1FC2, "Poken SA" }, + { 0x1FC3, "ICOP Digital, Inc." }, + { 0x1FC4, "Alfons Haar Maschinenbau GmbH & Co. KG" }, + { 0x1FC5, "Adaxys Solutions AG" }, + { 0x1FC6, "LAUREL BANK MACHINES CO., LTD." }, + { 0x1FC7, "mrs GmbH" }, + { 0x1FC8, "Medis Technologies Ltd." }, + { 0x1FC9, "NXP Semiconductors" }, + { 0x1FCA, "ON TIM Technologies Ltd." }, + { 0x1FCB, "Thermo Process Instruments" }, + { 0x1FCC, "Hiro" }, + { 0x1FCD, "Aurora Scientific Inc." }, + { 0x1FCE, "WEBSCAN Inc." }, + { 0x1FCF, "ACK Co., Ltd." }, + { 0x1FD0, "GILSON S.A.S." }, + { 0x1FD1, "TEKWorx Limited" }, + { 0x1FD2, "LG Display Co., Ltd." }, + { 0x1FD3, "ASK SA" }, + { 0x1FD4, "FINSECUR" }, + { 0x1FD5, "Dream Multimedia GmbH" }, + { 0x1FD6, "Logitek Electronic Systems, Inc." }, + { 0x1FD7, "ASELSAN Elektronik Sanayi ve Ticaret. A.S." }, + { 0x1FD8, "Guangzhou Tianhe Changjiang Communication Industrial Co" }, + { 0x1FD9, "Knox Company" }, + { 0x1FDA, "Beckwith Electric Co., Inc." }, + { 0x1FDB, "Delphin Technology AG" }, + { 0x1FDC, "HOSA TECHNOLOGY, INC." }, + { 0x1FDD, "CHASE GLORY INDUSTRIAL LTD." }, + { 0x1FDE, "ILX Lightwave" }, + { 0x1FDF, "SEPURA PLC" }, + { 0x1FE0, "REALFLEET Co., Ltd." }, + { 0x1FE1, "Ubixum, Inc." }, + { 0x1FE2, "Aetas Systems Inc." }, + { 0x1FE3, "Amaranthine, LLC" }, + { 0x1FE4, "HANDY TECH ELEKTRONIK GmbH" }, + { 0x1FE5, "KUKA Roboter GmbH" }, + { 0x1FE6, "BOOKHAM INC." }, + { 0x1FE7, "VERTEX WIRELESS CO., LTD." }, + { 0x1FE8, "103mm Tech" }, + { 0x1FE9, "Harvard Bioscience" }, + { 0x1FEA, "SIMPLO TECHNOLOGY CO., LTD." }, + { 0x1FEB, "Tecella" }, + { 0x1FEC, "NIAN YEONG ENTERPRISE CO., LTD." }, + { 0x1FED, "SYSACOM R&D Plus Inc." }, + { 0x1FEE, "GALILEO ENGINEERING SRL" }, + { 0x1FEF, "RESOL - Elektronische Regelungen GmbH" }, + { 0x1FF0, "Kyoto Electronics Manufacturing Co., Ltd." }, + { 0x1FF1, "Remote Operations Solutions" }, + { 0x1FF2, "Carl Valentin GmbH" }, + { 0x1FF3, "SINTEF Energy Research" }, + { 0x1FF4, "HYUNDAI PETATEL INC." }, + { 0x1FF5, "Changzhou Wujin BEST Electronic Cables Co., Ltd." }, + { 0x1FF6, "ClickTech LLC" }, + { 0x1FF7, "Guangzhou Shi Rui Electronics Co., Ltd." }, + { 0x1FF8, "Infinite Memories" }, + { 0x1FF9, "Schulze Elektronik GmbH" }, + { 0x1FFA, "ARYGON Technologies AG" }, + { 0x1FFB, "Pololu Corporation" }, + { 0x1FFC, "Azimut Production Association JSC" }, + { 0x1FFD, "TESSERA, INC." }, + { 0x1FFE, "HOST ENGINEERING, INC." }, + { 0x1FFF, "Ideofy Inc." }, + { 0x2000, "RongTong Info & Tech Co., Ltd." }, + { 0x2001, "D-Link Corporation" }, + { 0x2002, "DAP Technologies Ltd." }, + { 0x2003, "detectomat GmbH" }, + { 0x2004, "Shanghai Bellmann Digital Source Co., Ltd." }, + { 0x2005, "Balluff GmbH" }, + { 0x2006, "Lenovo Mobile Communication Technology Ltd." }, + { 0x2007, "LEYIO" }, + { 0x2008, "ThingMagic, Inc." }, + { 0x2009, "MPEDIA" }, + { 0x200A, "ADVANCED RELAY CORP." }, + { 0x200B, "TRANSISTOR DEVICES INC." }, + { 0x200C, "HANPIN ELECTRON CO., LTD." }, + { 0x200D, "Belkin Electronic (Changzhou) Co., Ltd." }, + { 0x200E, "DAIICHI PARTS (HK) CO., LTD." }, + { 0x200F, "Progind Srl" }, + { 0x2010, "Tectonica Australia Pty. Ltd." }, + { 0x2011, "SHENZHEN HEXIN COM. TECH. CO., LTD." }, + { 0x2012, "Applied Radar, Inc." }, + { 0x2013, "PCTV Systems" }, + { 0x2014, "ONKEN CORPORATION" }, + { 0x2015, "Shenzhen Ephone Communication Technology Co., Ltd." }, + { 0x2016, "Norbit AS" }, + { 0x2017, "NAL Research Corporation" }, + { 0x2018, "SilverPAC, Inc." }, + { 0x2019, "Electronics Development Corp." }, + { 0x201A, "Vortran Laser Technology, Inc." }, + { 0x201B, "1064138 Ontario Ltd. O/A UNI-TEC ELECTRONICS" }, + { 0x201C, "Freeport Resources Enterprises Corp." }, + { 0x201D, "Dongguan Shunhui Electronic Co., Ltd." }, + { 0x201E, "Qingdao Haier Telecom Co., Ltd." }, + { 0x201F, "W.E.M. INC." }, + { 0x2020, "Shanghai BroadMobi Communication Technology Co., Ltd." }, + { 0x2021, "Smartd ltd" }, + { 0x2022, "AMICON Ltd." }, + { 0x2023, "BERTHOLD DETECTION SYSTEMS GmbH" }, + { 0x2024, "Shoto Technologies LLC" }, + { 0x2025, "NANOSENSE" }, + { 0x2026, "EASUN REYROLLE LIMITED" }, + { 0x2027, "LOAD SYSTEMS INTERNATIONAL, INC." }, + { 0x2028, "DETAS TECHNOLOGY LTD." }, + { 0x2029, "MYTRAK HEALTH SYSTEM INC." }, + { 0x202A, "Fast Forward Video, Inc." }, + { 0x202B, "Damalini AB" }, + { 0x202C, "Enhanced Vision" }, + { 0x202D, "Snowbush IP (a division of Gennum)" }, + { 0x202E, "Lumio Inc." }, + { 0x202F, "US ARMY RDECOM-ARDEC" }, + { 0x2030, "VITEC Multimedia" }, + { 0x2031, "Vistec AG" }, + { 0x2032, "GFMesstechnik GmbH" }, + { 0x2033, "WYMA Tecnologia Ltda." }, + { 0x2034, "iSoft Silicon, Inc." }, + { 0x2035, "seowonintech" }, + { 0x2036, "Eitech Co., Ltd." }, + { 0x2037, "Control Devices Australia Pty., Ltd." }, + { 0x2038, "Wescor Inc." }, + { 0x2039, "SE-Elektronic GmbH" }, + { 0x203A, "Parallels, Inc." }, + { 0x203B, "EIT, Inc." }, + { 0x203C, "Steptechnica Co., Ltd." }, + { 0x203D, "Encore Electronics" }, + { 0x203E, "Pascher Instruments AB" }, + { 0x203F, "WPG System Pte. Ltd." }, + { 0x2040, "Hauppauge Computer Works, Inc." }, + { 0x2041, "WILL BEST (ELECTRONICS) LTD." }, + { 0x2042, "Eberspaecher Electronics GmbH & Co. KG" }, + { 0x2043, "Mobius Microsystems" }, + { 0x2044, "NOVUS PRODUTOS ELETRONICOS LTDA." }, + { 0x2045, "EMH - Energie-Messtechnik GmbH" }, + { 0x2046, "AbleNet Inc." }, + { 0x2047, "Texas Instruments Incorporated (MSP430 Group)" }, + { 0x2048, "Hongtech Electronics Co., Ltd." }, + { 0x2049, "APACEWAVE TECHNOLOGIES" }, + { 0x204A, "Enclustra GmbH" }, + { 0x204B, "HANSHIN INFORMATION TECHNOLOGY INC." }, + { 0x204C, "M7Lab., Co., Ltd." }, + { 0x204D, "Orthodyne Electronics" }, + { 0x204E, "LINO MANFROTTO + CO. S.P.A." }, + { 0x204F, "VIDEOTEC SpA" }, + { 0x2050, "CBF Systems, Inc." }, + { 0x2051, "N.A.T. GmbH" }, + { 0x2052, "Movidius Ltd." }, + { 0x2053, "HANSHIN TERMINAL CO., LTD." }, + { 0x2054, "Source R & D Inc. (DBA WARPIA)" }, + { 0x2055, "Opti B. I. Communications, Ltd." }, + { 0x2056, "CliniComp International Inc." }, + { 0x2057, "DICE ELECTRONICS, LLC" }, + { 0x2058, "NANO RIVER TECHNOLOGIES" }, + { 0x2059, "SMART Temps LLC" }, + { 0x205A, "Hankook Tire" }, + { 0x205B, "TRUMPF Medizin Systeme GmbH" }, + { 0x205C, "Shenzhen Tronixin Electronics Co., Ltd." }, + { 0x205D, "RESMED LTD." }, + { 0x205E, "CTI PRODUCTS, Inc." }, + { 0x205F, "Capella Microsystems Inc." }, + { 0x2060, "U.S. Army Aviation & Missile R & D & Engineering Center" }, + { 0x2061, "FIGMENT DESIGN LABORATORIES" }, + { 0x2062, "Trulife" }, + { 0x2063, "AirMagnet Inc." }, + { 0x2064, "Shenzhen AnNet Technology Co., Ltd." }, + { 0x2065, "MEASUREMENT SPECIALTIES INC." }, + { 0x2066, "Unicorn Electronics Components Co., Ltd." }, + { 0x2067, "TSB LAO COMPANY LIMITED" }, + { 0x2068, "Seven 45 Studios" }, + { 0x2069, "Vanguard Rugged Storage, LLC" }, + { 0x206A, "Fujian Star-net Communication Co., Ltd." }, + { 0x206B, "CETIM" }, + { 0x206C, "Seeker Technology Corp." }, + { 0x206D, "Hunan GreatWall Information Financial Equipment Co.Ltd." }, + { 0x206E, "ZAO MIRCOM" }, + { 0x206F, "JTOUCH Corporation" }, + { 0x2070, "Infinite Response, Inc." }, + { 0x2071, "SYSTEM S.P.A." }, + { 0x2072, "GOOD YEAR ELECTRONIC MFG. CO., LTD." }, + { 0x2073, "Shenzhen R-Way Technology Co., Ltd." }, + { 0x2074, "UNIVERSAL CHAMPION ELECTROACOUSTIC TECHNOLOGY COMPANY" }, + { 0x2075, "SecureKey Technologies Inc." }, + { 0x2076, "SHINKAWA Sensor Technology, Inc." }, + { 0x2077, "Shenzhen Gongjin Electronics Co., Ltd." }, + { 0x2078, "Epsilon Electronics, Inc dba Power Acoustik Electronics" }, + { 0x2079, "New Concept Gaming Ltd." }, + { 0x207A, "CETWIN AB" }, + { 0x207B, "Technetix Group Ltd." }, + { 0x207C, "NESA International, Inc." }, + { 0x207D, "CESI Technology Co., Ltd." }, + { 0x207E, "ENHANCED VIDEO DEVICES, INC." }, + { 0x207F, "Profound BV" }, + { 0x2080, "Barnes and Noble" }, + { 0x2081, "UTRONIX Elektronikutreckling AB" }, + { 0x2082, "EKOMINI INC." }, + { 0x2083, "XEL SOLUTIONS LTD." }, + { 0x2084, "I Zone Technologies Co., Ltd." }, + { 0x2085, "SIXENSE ENTERTAINMENT INC." }, + { 0x2086, "SHENZHEN CATIC INFORMATION TECHNOLOGY INDUSTRY CO., LTD" }, + { 0x2087, "Cando Corporation" }, + { 0x2088, "WALTON CHAINTECH CORPORATION" }, + { 0x2089, "microdrones GmbH" }, + { 0x208A, "TECHNO ROAD Inc." }, + { 0x208B, "KONTRON EMBEDDED COMPUTERS GmbH" }, + { 0x208C, "Linkbit, Inc." }, + { 0x208D, "Attero Tech, LLC" }, + { 0x208E, "Luxshare-ICT" }, + { 0x208F, "Chi Mei Optoelectronics Corporation" }, + { 0x2090, "Transition Networks" }, + { 0x2091, "Callpod, Inc." }, + { 0x2092, "Logina" }, + { 0x2093, "Ambu A/S" }, + { 0x2094, "Yoostar Entertainment Group, Inc." }, + { 0x2095, "CE LINK LIMITED" }, + { 0x2096, "Microconn Electronic Co., Ltd." }, + { 0x2097, "USBPARTNER" }, + { 0x2098, "TouchTable, Inc." }, + { 0x2099, "Systematic Development Group, LLC" }, + { 0x209A, "Avedis Zildjian Company" }, + { 0x209B, "SATEL OY" }, + { 0x209C, "iPulse Systems" }, + { 0x209D, "Vector Co., Ltd." }, + { 0x209E, "GlideTV Inc." }, + { 0x209F, "Alcolizer Technology" }, + { 0x20A0, "Clay Logic" }, + { 0x20A1, "BRAINZSQUARE CO., LTD." }, + { 0x20A2, "SCANMATIK" }, + { 0x20A3, "Sterilucent" }, + { 0x20A4, "Itron Metering Solutions" }, + { 0x20A5, "Cardiorobotics, Inc." }, + { 0x20A6, "ZheJiang SEENSUN Communication&Electronic Equipment Co." }, + { 0x20A7, "GREAT LUSTRE (SPEEDY) CO., LTD." }, + { 0x20A8, "nLighten Technologies (Shanghai) Co., Ltd." }, + { 0x20A9, "Autotronic Controls Corp." }, + { 0x20AA, "ED-CONTRIVE Co., Ltd." }, + { 0x20AB, "Identification International, Inc." }, + { 0x20AC, "Wintek Corporation" }, + { 0x20AD, "Japan Probe Co., Ltd." }, + { 0x20AE, "SoCChip (Wuxi Youxin IC Design Co., Ltd.)" }, + { 0x20AF, "Shenzhen CARVE Electronics Co., Ltd." }, + { 0x20B0, "ICOMM TELE LIMITED" }, + { 0x20B1, "XMOS Ltd." }, + { 0x20B2, "Clubbhouse Inventions LLC" }, + { 0x20B3, "Hannstouch Solution Inc." }, + { 0x20B4, "SANDBRIDGE TECHNOLOGIES, INC." }, + { 0x20B5, "ACD Gruppe" }, + { 0x20B6, "Bohle AG" }, + { 0x20B7, "Qi Hardware, Inc." }, + { 0x20B8, "PARA INDUSTRIAL CO., LTD." }, + { 0x20B9, "TLAY Technologies Co., Ltd." }, + { 0x20BA, "jwin Electronics Corp." }, + { 0x20BB, "THALES TRANSPORTATION SYSTEMS" }, + { 0x20BC, "Guangzhou Pingzhong Electronic Technology Co., Ltd." }, + { 0x20BD, "KETEK" }, + { 0x20BE, "BURY GmbH & Co. KG" }, + { 0x20BF, "Dwyer Instruments, Inc." }, + { 0x20C0, "FENGHUA KINGSUN CO., LTD." }, + { 0x20C1, "HARWIN ASIA PTE. LTD." }, + { 0x20C2, "Sumitomo Electric Ind., Ltd., Optical Comm. R&D Lab" }, + { 0x20C3, "TECNOMOTOR ELETRONICA DO BRASIL S/A" }, + { 0x20C4, "Communications Laboratories, Inc. (Comlabs)" }, + { 0x20C5, "A.U. Physics Enterprises" }, + { 0x20C6, "Mutto Optronics Corporation" }, + { 0x20C7, "HMC INTERNATIONAL" }, + { 0x20C8, "CEC TELECOM CO., LTD." }, + { 0x20C9, "SYSTEMCORP Pty., Ltd." }, + { 0x20CA, "TRIPHOS Co., Ltd." }, + { 0x20CB, "Dave Smith Instruments" }, + { 0x20CC, "TAKARA" }, + { 0x20CD, "Schweers Informationstechnologie GmbH" }, + { 0x20CE, "Mini-Circuits" }, + { 0x20CF, "Gridmark Limited" }, + { 0x20D0, "FRESENIUS VIAL" }, + { 0x20D1, "Dascom Europe GmbH" }, + { 0x20D2, "ROBOTEQ INC." }, + { 0x20D3, "Provo Craft" }, + { 0x20D4, "SCDi" }, + { 0x20D5, "Lenexpo Inc. (dba: Atlona)" }, + { 0x20D6, "Bensussen Deutsch & Associates, Inc. (BDA)" }, + { 0x20D7, "SHENZHEN ZILI ELECTRONICS CO. LTD." }, + { 0x20D8, "Changzhou Xinchao Technologies, Inc." }, + { 0x20D9, "ZHEJIANG YONGCHENGGONG DIANSU.CO., LTD." }, + { 0x20DA, "LumaSense Technologies A/S" }, + { 0x20DB, "KTS GmbH" }, + { 0x20DC, "KCS Digital, Inc." }, + { 0x20DD, "FORTREND TAIWAN SCIENTIFIC CORP." }, + { 0x20DE, "OneSail HK Ltd." }, + { 0x20DF, "SIMTEC ELECTRONICS" }, + { 0x20E0, "Realway Electronics Technology Limited" }, + { 0x20E1, "Daiichi Co., Ltd." }, + { 0x20E2, "ASEQ INSTRUMENTS" }, + { 0x20E3, "LAUDA DR.R.WOBSER GMBH & CO. KG" }, + { 0x20E4, "Onecell Technologies" }, + { 0x20E5, "Cardreader, Inc." }, + { 0x20E6, "Brooks Automation, Inc." }, + { 0x20E7, "Scientific Digital Imaging plc" }, + { 0x20E8, "Jow Tong Technology Co., Ltd." }, + { 0x20E9, "adp Gauselmann GmbH" }, + { 0x20EA, "CACTUS TECHNOLOGIES, LIMITED" }, + { 0x20EB, "AOS Technologies AG" }, + { 0x20EC, "AMBIR TECHNOLOGY, INC." }, + { 0x20ED, "TRANZFINITY, INC." }, + { 0x20EE, "Emotiva Audio Corp." }, + { 0x20EF, "TIGRIS Elektronik GmbH" }, + { 0x20F0, "Insight Technology Incorporated" }, + { 0x20F1, "NET GmbH" }, + { 0x20F2, "Secured Mobility" }, + { 0x20F3, "Flexcore" }, + { 0x20F4, "TRENDnet" }, + { 0x20F5, "MKS Instruments - Technology for Productivity" }, + { 0x20F6, "EXMAN ELECTRIC" }, + { 0x20F7, "SOFTHARD Technology Ltd." }, + { 0x20F8, "Guangzhou Somic Digital & Electronic Technology Co, Ltd" }, + { 0x20F9, "Medical Computer Systems, Ltd." }, + { 0x20FA, "IC Intracom" }, + { 0x20FB, "Aptina Imaging Corporation" }, + { 0x20FC, "PIE SOFT LAB CORPORATION" }, + { 0x20FD, "NOVO NORDISK A/S" }, + { 0x20FE, "Elektrobit Inc." }, + { 0x20FF, "PNI Sensor Corp." }, + { 0x2100, "RT Systems Inc." }, + { 0x2101, "NAS Technologies Corp." }, + { 0x2102, "Vitalograph Ltd." }, + { 0x2103, "OHMORI ELECTRIC INDUSTRIES CO., LTD." }, + { 0x2104, "Tobii Technology AB" }, + { 0x2105, "Retail Innovation HTT AB" }, + { 0x2106, "Sharp Korea Corporation" }, + { 0x2107, "Amstore CD Production Ltd." }, + { 0x2108, "NEATO ROBOTICS" }, + { 0x2109, "VIA Labs, Inc." }, + { 0x210A, "PULSUS TECHNOLOGIES" }, + { 0x210B, "Work Microwave GmbH" }, + { 0x210C, "DOT HILL SYSTEMS" }, + { 0x210D, "Plastoform Industries Ltd." }, + { 0x210E, "Commscope" }, + { 0x210F, "Tyco / Scott Health & Safety" }, + { 0x2110, "carina system co., ltd." }, + { 0x2111, "alphaNUCLEAR Inc." }, + { 0x2112, "Point Of Pay Pty. Ltd." }, + { 0x2113, "Optrima N.V." }, + { 0x2114, "Innovision Technology Corporation Ltd." }, + { 0x2115, "Alliance Material Co., Ltd." }, + { 0x2116, "KT Tech Inc." }, + { 0x2117, "Frama AG" }, + { 0x2118, "RF WINDOW" }, + { 0x2119, "MoreDNA Technology Co., Ltd." }, + { 0x211A, "PILLKEY HOLDING BV" }, + { 0x211B, "MENTOR GmbH & Co. Praezisions-Bauteile KG" }, + { 0x211C, "SWENC Technology Co., Ltd." }, + { 0x211D, "Mutualink, Inc." }, + { 0x211E, "Dongbu HiTek" }, + { 0x211F, "XINETWORKS CO., LTD." }, + { 0x2120, "Odirrus Limited" }, + { 0x2121, "Escort Data Logging Systems Ltd." }, + { 0x2122, "ZEDEL" }, + { 0x2123, "SYNTEK DEVELOPMENT LTD." }, + { 0x2124, "ELSAGDATAMAT S.P.A." }, + { 0x2125, "FIBERPRO INC." }, + { 0x2126, "SUZA INTERNATIONAL FRANCE" }, + { 0x2127, "FutureDial, Inc." }, + { 0x2128, "Naval Research Laboratory" }, + { 0x2129, "Tokushu Denshi Kairo, Inc." }, + { 0x212A, "Kappa optronics GmbH" }, + { 0x212B, "GR Telecom Co., Ltd." }, + { 0x212C, "Shenzhen Linoya Electronic Co., Ltd." }, + { 0x212D, "Dong Guan City Marubeni Electronic Co., Ltd." }, + { 0x212E, "Amphenol AssembleTech (Xiamen) Co., Ltd." }, + { 0x212F, "SUZUKI MUSICAL INST. MFG. CO., LTD." }, + { 0x2130, "Sanmu Communication Technology (H.K.) Ltd." }, + { 0x2131, "IES Co., Ltd." }, + { 0x2132, "EDAS, Inc." }, + { 0x2133, "SIGNOTEC GmbH" }, + { 0x2134, "CANESTA, INC." }, + { 0x2135, "W.O.M. World of Medicine AG" }, + { 0x2136, "Compunow Trading Corp." }, + { 0x2137, "Beyonics Technology Limited" }, + { 0x2138, "iVina, Inc." }, + { 0x2139, "Eigenlabs Ltd." }, + { 0x213A, "Carlo Gavazzi" }, + { 0x213B, "UICO, Inc." }, + { 0x213C, "ICON Health & Fitness" }, + { 0x213D, "DRS Data & Imaging Systems, Inc." }, + { 0x213E, "Phase Matrix, Inc." }, + { 0x213F, "Digitron Instrumentation Ltd." }, + { 0x2140, "Sichuan Jiuzhou Electric Group Co., Ltd." }, + { 0x2141, "ZT Group Int'l, Inc." }, + { 0x2142, "Pulsecom" }, + { 0x2143, "InDevR Inc." }, + { 0x2144, "Sea Tel, Inc." }, + { 0x2145, "Ballard Technology" }, + { 0x2146, "Victorinox AG" }, + { 0x2147, "Chin-Ban Electronics (Hong Kong) Co." }, + { 0x2148, "Visteon Sistemas Automotives Ltda." }, + { 0x2149, "MasTouch Optoelectronics Technologies Co., Ltd." }, + { 0x214A, "Interlink Electronics" }, + { 0x214B, "AMECO TECHNOLOGIES (SHENZHEN) CO., LTD." }, + { 0x214C, "Y Soft Corporation" }, + { 0x214D, "SyTech Corporation" }, + { 0x214E, "Swiftpoint Limited" }, + { 0x214F, "Attainment Company, Inc." }, + { 0x2150, "AZOTEQ (PTY) LTD." }, + { 0x2151, "SeaSpace Corporation" }, + { 0x2152, "AD Semiconductor Co., Ltd." }, + { 0x2153, "Mastertouch Solutions Electronics Co., Ltd." }, + { 0x2154, "Trace Lighting Ltd." }, + { 0x2155, "Teledyne Controls" }, + { 0x2156, "Weistech Technology Co., Ltd." }, + { 0x2157, "Digital Imaging Technology" }, + { 0x2158, "TA WEI TECHNOLOGY CO., LTD." }, + { 0x2159, "TRIASX Pty Ltd." }, + { 0x215A, "Sling Media, Inc." }, + { 0x215B, "2D Debus & Diebold Messsysteme GmbH" }, + { 0x215C, "OTOVATION, LLC" }, + { 0x215D, "GeNUA mbH" }, + { 0x215E, "ST Embedded Engineering, LLC" }, + { 0x215F, "DECIMATOR DESIGN PTY LTD." }, + { 0x2160, "PULOON Technology Inc." }, + { 0x2161, "BEA SA" }, + { 0x2162, "Prime Audio Inc." }, + { 0x2163, "Digital Rapids Corp." }, + { 0x2164, "Witek System" }, + { 0x2165, "CONTROL SOLUTIONS, INC." }, + { 0x2166, "JVC KENWOOD Corporation" }, + { 0x2167, "Zhejiang Fousine Science & Technology Co., Ltd." }, + { 0x2168, "TZYR HWEY ENTERPRISE CO., LTD." }, + { 0x2169, "TIANJIN SHENNAN INFORMATION SECURITY CO., LTD." }, + { 0x216A, "Shenzhen San Jing Electronics Co., Ltd." }, + { 0x216B, "XceedID Corporation" }, + { 0x216C, "UniDisplay Inc." }, + { 0x216D, "BENSON MEDICAL INSTRUMENTS" }, + { 0x216E, "KHOMP INDUSTRIA E COMERCIO LTDA" }, + { 0x216F, "ALTAIR SEMICONDUCTOR" }, + { 0x2170, "Wurtec, Inc." }, + { 0x2171, "Bokam Engineering, Inc." }, + { 0x2172, "Torrey Pines Logic, Inc." }, + { 0x2173, "HUIZHOU HUANGJI PRECISIONS FLEX ELECTRONICAL CO., LTD." }, + { 0x2174, "Transcend Information, Inc." }, + { 0x2175, "Light Blue Optics, Inc." }, + { 0x2176, "TMC/Allion Test Labs" }, + { 0x2177, "CHAUVIN ARNOUX" }, + { 0x2178, "Ion Science" }, + { 0x2179, "UGtizer Corp." }, + { 0x217A, "Triple Eye" }, + { 0x217B, "BDP Semiconductors Ltd." }, + { 0x217C, "Sensitech Inc." }, + { 0x217D, "Bilcare Technologies Singapore Pte. Ltd." }, + { 0x217E, "TP RADIO" }, + { 0x217F, "REAL EAR A/S" }, + { 0x2180, "Icare Finland Oy" }, + { 0x2181, "GLOBAL TRAFFIC TECHNOLOGIES, LLC" }, + { 0x2182, "XAC Automation Corp." }, + { 0x2183, "Bonutti Research" }, + { 0x2184, "GOOD WILL Instrument Co., Ltd." }, + { 0x2185, "FUJIWORK Co., Ltd." }, + { 0x2186, "Home Server Technologies Inc." }, + { 0x2187, "ESPACE SERVICES MULTIMEDIAS" }, + { 0x2188, "CalDigit" }, + { 0x2189, "SEMNTECH" }, + { 0x218A, "EXELYS LLC" }, + { 0x218B, "Blackbird Technologies Inc." }, + { 0x218C, "Gammadata Instrument AB" }, + { 0x218D, "Adaptive I/O Technologies, Inc." }, + { 0x218E, "UNITRO-Fleischmann" }, + { 0x218F, "DHEF INC." }, + { 0x2190, "esonic Co., Ltd." }, + { 0x2191, "SecureAT Co., Ltd." }, + { 0x2192, "FlexRadio Systems" }, + { 0x2193, "Schnick-Schnack-Systems GmbH" }, + { 0x2194, "ROTH + WEBER GmbH" }, + { 0x2195, "Hans Eckes Hardware & Software" }, + { 0x2196, "XPMOBILE" }, + { 0x2197, "W & D, LLC" }, + { 0x2198, "Wonde Proud Technology Co., Ltd." }, + { 0x2199, "Image and Information Technology" }, + { 0x219A, "COSMO ELECTRONICS CO., LTD." }, + { 0x219B, "TPK Touch Solutions Inc." }, + { 0x219C, "SEAL ONE AG" }, + { 0x219D, "BDR Technologies Ltd." }, + { 0x219E, "VALKEE OY" }, + { 0x219F, "VENTIS" }, + { 0x21A0, "AXELSPACE Corporation" }, + { 0x21A1, "EMOTIV SYSTEMS INC." }, + { 0x21A2, "ABB Low Voltage Products" }, + { 0x21A3, "Optcom Co., Ltd." }, + { 0x21A4, "ELECTRONIC ARTS" }, + { 0x21A5, "Genesis Technology USA, Inc." }, + { 0x21A6, "YUPITERU CORPORATION" }, + { 0x21A7, "PAYPRINT SRL" }, + { 0x21A8, "GE Intelligent Platforms, Inc." }, + { 0x21A9, "Saleae LLC" }, + { 0x21AA, "TAKASAKI KYODO COMPUTING CENTER CO., LTD." }, + { 0x21AB, "Planeta Informatica Ltda." }, + { 0x21AC, "infoSense Technology Inc." }, + { 0x21AD, "Wobbegong Fitness and Therapy Products Pty. Ltd." }, + { 0x21AE, "Philips and Neusoft Medical System Co., Ltd." }, + { 0x21AF, "Euro-CB Phils. Inc." }, + { 0x21B0, "Grace Industries, Incorporated" }, + { 0x21B1, "TATA CONSULTANCY SERVICES" }, + { 0x21B2, "Felix Meier GmbH" }, + { 0x21B3, "Dongguan Teconn Electronics Technology Co., Ltd." }, + { 0x21B4, "Wavelength Audio, Ltd." }, + { 0x21B5, "SHENZHEN JASON ELECTRONICS CO., LTD." }, + { 0x21B6, "EUROAVIONICS GmbH & Co. KG" }, + { 0x21B7, "STAIB INSTRUMENTE GmbH" }, + { 0x21B8, "KONTRONIK GmbH" }, + { 0x21B9, "ZP ENGINEERING s.r.l." }, + { 0x21BA, "SI2 MICROSYSTEMS, Ltd." }, + { 0x21BB, "WWPass Corporation" }, + { 0x21BC, "Skyhawke Technologies, LLC" }, + { 0x21BD, "Code Red Technologies, Ltd." }, + { 0x21BE, "KEC Co., Ltd." }, + { 0x21BF, "Mayo Clinic" }, + { 0x21C0, "PIXTREE, Inc." }, + { 0x21C1, "Baumann Electronic Controls, LLC" }, + { 0x21C2, "Shenzhen V-Interface Technology Co., Ltd." }, + { 0x21C3, "MASIMO LABORATORIES INC." }, + { 0x21C4, "Netcom Technology (HK) Limited" }, + { 0x21C5, "Vukic Computer Instruments GmbH" }, + { 0x21C6, "PSS Hong Kong Limited" }, + { 0x21C7, "Unisoku Co., Ltd." }, + { 0x21C8, "IDONDEMAND INC." }, + { 0x21C9, "Innoteletek, Inc." }, + { 0x21CA, "RAE Systems Inc." }, + { 0x21CB, "Vodafone Ltd." }, + { 0x21CC, "ChipsWork Microelectronics Corp." }, + { 0x21CD, "Infoxelle Co., Ltd." }, + { 0x21CE, "Polostar Technology Corporation" }, + { 0x21CF, "HISATOMI ELECTRIC IND. CO., LTD." }, + { 0x21D0, "Red Rapids" }, + { 0x21D1, "ADDER TECHNOLOGY LTD." }, + { 0x21D2, "NeoLAB Convergence" }, + { 0x21D3, "Compupack Technology Co., Ltd." }, + { 0x21D4, "Eduplayer Co., Ltd." }, + { 0x21D5, "M.G.F." }, + { 0x21D6, "Agecodagis SARL" }, + { 0x21D7, "VINCIAMO, Inc." }, + { 0x21D8, "P & A Technologies, Inc." }, + { 0x21D9, "Verification Technology, Inc." }, + { 0x21DA, "Valor Auto Companion, Inc." }, + { 0x21DB, "G-Max Technology Co., Ltd." }, + { 0x21DC, "ABB S.p.A., Low Voltage Products Division" }, + { 0x21DD, "Looxcie, Inc." }, + { 0x21DE, "Cloud Engines, Inc." }, + { 0x21DF, "Quanser Consulting Inc." }, + { 0x21E0, "OpenPattern" }, + { 0x21E1, "CAEN S.P.A." }, + { 0x21E2, "Ascension Technology Corp." }, + { 0x21E3, "Crest Technology Inc." }, + { 0x21E4, "Xcellen Co., Ltd." }, + { 0x21E5, "Kruglov Evgeniy Vladimirovich" }, + { 0x21E6, "OCZ Technology Group" }, + { 0x21E7, "Sagem Communications SAS" }, + { 0x21E8, "BOEHNKE + PARTNER GmbH Steuerungssysteme" }, + { 0x21E9, "Jiafuh Metal & Plastic (ShenZhen) Co., Ltd." }, + { 0x21EA, "JUST MAKE ELECTRONICS CO., LTD." }, + { 0x21EB, "KOKORO CO., LTD." }, + { 0x21EC, "ApniCure, Inc." }, + { 0x21ED, "Accuphase Laboratories, Inc." }, + { 0x21EE, "MAVIN TECHNOLOGY INC." }, + { 0x21EF, "FEMTO Messtechnik GmbH" }, + { 0x21F0, "LivingLab Development Co., Ltd." }, + { 0x21F1, "ABS Group AB" }, + { 0x21F2, "Palmer Environmental Ltd." }, + { 0x21F3, "Inspired Instruments Inc." }, + { 0x21F4, "Minebea Technologies Taiwan Co., Ltd." }, + { 0x21F5, "Shenzhen Strong Rising Electronics Co., Ltd." }, + { 0x21F6, "QSR Automations, Inc." }, + { 0x21F7, "Wuerth-Elektronik eiSos GmbH & Co. KG" }, + { 0x21F8, "Goeasily Int'l Co., Ltd." }, + { 0x21F9, "American Thermal Instruments" }, + { 0x21FA, "Pitsco, Inc." }, + { 0x21FB, "HELIOS Electronic Design & Manufacture" }, + { 0x21FC, "Thum + Mahr GmbH" }, + { 0x21FD, "Associated Controls (Australia) Pty., Limited" }, + { 0x21FE, "ELAP S.p.A." }, + { 0x21FF, "DEIF A/S" }, + { 0x2200, "Nuribom" }, + { 0x2201, "Elan Digital Systems Ltd." }, + { 0x2202, "Walex Electronic (Wu Xi) Co., Ltd." }, + { 0x2203, "Shin Shin Co., Ltd." }, + { 0x2204, "Innov-X Systems Inc." }, + { 0x2205, "3eYamaichi Electronics Co., Ltd." }, + { 0x2206, "Wiretek International Investment Ltd." }, + { 0x2207, "Fuzhou Rockchip Electronics Co., Ltd." }, + { 0x2208, "CONNFLY ELECTRONIC CO., LTD." }, + { 0x2209, "SPoT LLC" }, + { 0x220A, "Anton Paar GmbH" }, + { 0x220B, "IKARIA Holdings, Inc." }, + { 0x220C, "Island Technology Co., Ltd." }, + { 0x220D, "Humanline Co., Ltd." }, + { 0x220E, "NetComm Ltd." }, + { 0x220F, "Italdata Ingegneria Dell'Idea s.p.a." }, + { 0x2210, "Klavis Technologies" }, + { 0x2211, "FLUID COMPONENTS INTERNATIONAL LLC" }, + { 0x2212, "Dev-Audio Pty. Ltd. (Dev-Audio)" }, + { 0x2213, "Ascon Co., Ltd." }, + { 0x2214, "Pollin Electronic GmbH" }, + { 0x2215, "InCOMM Technologies Co., Ltd." }, + { 0x2216, "Environmental Systems Corporation" }, + { 0x2217, "FTS Forest Technology Systems Ltd." }, + { 0x2218, "Listen Technologies Corp." }, + { 0x2219, "Hogahm Technology" }, + { 0x221A, "ZTEX" }, + { 0x221B, "Kyodo Denshi Engineering Co., Ltd." }, + { 0x221C, "CORTEX TECHNOLOGY APS" }, + { 0x221D, "fischertechnik GmbH" }, + { 0x221E, "Linktec Technologies Co., Ltd." }, + { 0x221F, "Resolution Audio" }, + { 0x2220, "FAMAS SYSTEM S.P.A." }, + { 0x2221, "EnovateIT Inc." }, + { 0x2222, "SOFTMECHA" }, + { 0x2223, "Ratioplast-Optoelectronics GmbH" }, + { 0x2224, "LM Technologies Ltd." }, + { 0x2225, "GETT Geratetechnik GmbH" }, + { 0x2226, "PLANAR LLC" }, + { 0x2227, "Northtronics Pty., Ltd." }, + { 0x2228, "Dantec Dynamics A/S" }, + { 0x2229, "Key Technologies, Inc." }, + { 0x222A, "ILI TECHNOLOGY CORP." }, + { 0x222B, "ALPHAMEDIA CO., LTD." }, + { 0x222C, "TOHAN DENSHI KIKI Co., Ltd." }, + { 0x222D, "LEIFHEIT AG" }, + { 0x222E, "OXYSEC s.r.l." }, + { 0x222F, "Tcom Technology Co., Ltd." }, + { 0x2230, "Plugable Technologies" }, + { 0x2231, "Coregate Inc." }, + { 0x2232, "NAMUGA Co., Ltd." }, + { 0x2233, "ARGtek Communication Inc." }, + { 0x2234, "T-CONN PRECISION CORPORATION" }, + { 0x2235, "WoundVision" }, + { 0x2236, "ACELLA" }, + { 0x2237, "Kobo Inc." }, + { 0x2238, "ELMO Motion Control Ltd." }, + { 0x2239, "PEIKER acustic GmbH & Co., KG" }, + { 0x223A, "BKtel Communications GmbH" }, + { 0x223B, "Crystalfontz America, Inc." }, + { 0x223C, "Audio Research Corp." }, + { 0x223D, "AlfaPlus Semiconductor, Inc." }, + { 0x223E, "Home Electronics" }, + { 0x223F, "Oga, Inc." }, + { 0x2240, "NETTALK.COM INC." }, + { 0x2241, "Envision Interface Engineering, LLC" }, + { 0x2242, "Zhihe Electronics Technology Co., Ltd." }, + { 0x2243, "EMIC CORPORATION" }, + { 0x2244, "Kronos" }, + { 0x2245, "ASPEED Technology Inc." }, + { 0x2246, "Nanjing Frentec Co., Ltd." }, + { 0x2247, "CHUNGHWA PICTURE TUBES, LTD." }, + { 0x2248, "KAISE CORPORATION" }, + { 0x2249, "Long Range Systems, Inc." }, + { 0x224A, "ORMEC SYSTEMS CORP." }, + { 0x224B, "Sirit Inc." }, + { 0x224C, "Datron World Communications, Inc." }, + { 0x224D, "Tescom Co., Ltd." }, + { 0x224E, "RDH2 Science" }, + { 0x224F, "APDM, INC." }, + { 0x2250, "Evernew Wire & Cable Co., Ltd." }, + { 0x2251, "QuieTek Corp." }, + { 0x2252, "TSANSUN TECH. CO., LTD." }, + { 0x2253, "Arpage AG" }, + { 0x2254, "RPO" }, + { 0x2255, "COOPER WIRELESS" }, + { 0x2256, "Mathias Fuchss Software - Entwicklung" }, + { 0x2257, "On the Go Video, Inc." }, + { 0x2258, "D+H Mechatronic AG" }, + { 0x2259, "Skypine Electronics (Shenzhen) Co., Ltd." }, + { 0x225A, "Vivanco AG" }, + { 0x225B, "Lineage Power" }, + { 0x225C, "Burroughs Payment Systems, Inc." }, + { 0x225D, "Sagem Securite" }, + { 0x225E, "Unholtz-Dickie Corp." }, + { 0x225F, "Ace Karaoke Corp." }, + { 0x2260, "Multigig, Inc." }, + { 0x2261, "DOM-Sicherheitstechnik GmbH & Co. KG" }, + { 0x2262, "VIETTEL GROUP" }, + { 0x2263, "Nuovations" }, + { 0x2264, "Entourage Systems, Inc." }, + { 0x2265, "DailyCare BioMedical Inc." }, + { 0x2266, "Psychology Software Tools, Inc." }, + { 0x2267, "Boreal Genomics" }, + { 0x2268, "EXSUSS, Inc." }, + { 0x2269, "Schlumberger Ltd." }, + { 0x226A, "Ooma, Inc." }, + { 0x226B, "Bruker Nano GmbH" }, + { 0x226C, "HAL Communications Corp." }, + { 0x226D, "Wrenchman, Inc." }, + { 0x226E, "DISPLAX" }, + { 0x226F, "Koyo Trading Co., Ltd." }, + { 0x2270, "XiaMen GaoLuChang Electronics Co. Ltd." }, + { 0x2271, "Karl Storz GmbH & Co. KG" }, + { 0x2272, "E.E.P.D." }, + { 0x2273, "IMAX Corporation" }, + { 0x2274, "Morgan Schaffer Inc." }, + { 0x2275, "ReliOn Inc." }, + { 0x2276, "Pioneer CBC" }, + { 0x2277, "Ortho Neuro Technologies, Inc." }, + { 0x2278, "Infratec Datentechnik GmbH" }, + { 0x2279, "Goossens Engineering" }, + { 0x227A, "FLOM Corporation" }, + { 0x227B, "CYBELEC SA" }, + { 0x227C, "S. & A.S. LTD." }, + { 0x227D, "Unitec Co., Ltd." }, + { 0x227E, "JSC <SATIS-TL-94>" }, + { 0x227F, "Granite River Labs" }, + { 0x2280, "Life Technologies Corp." }, + { 0x2281, "GI CORPORATION" }, + { 0x2282, "Mamiya Digital Imaging Co., Ltd." }, + { 0x2283, "NIHON DEMPA KOGYO Co., Ltd." }, + { 0x2284, "SuperSonic Inc." }, + { 0x2285, "IRIS ID" }, + { 0x2286, "Altierre Corporation" }, + { 0x2287, "Shenzhen Oversea Win Technology Co., Ltd." }, + { 0x2288, "Digital EMC Co., Ltd." }, + { 0x2289, "Sun Fair Electric Wire & Cable (HK) Co., Ltd." }, + { 0x228A, "Hotron Precision Electronic Ind. Corp." }, + { 0x228B, "Shenzhen DLK Electronics Technology Co., Ltd." }, + { 0x228C, "Analogic Corporation" }, + { 0x228D, "8D TECHNOLOGIES INC." }, + { 0x228E, "EKO Instruments Co., Ltd." }, + { 0x228F, "SIGMATEK GmbH & Co. KG" }, + { 0x2290, "Touchplus information Corp." }, + { 0x2291, "Vallen Systeme GmbH" }, + { 0x2292, "Global Industrial Services, Ltd." }, + { 0x2293, "Berger Elektronik GmbH" }, + { 0x2294, "KoCo Connector AG" }, + { 0x2295, "Sound ID" }, + { 0x2296, "Musashi Engineering Company Limited" }, + { 0x2297, "Grain Media Technology Corporation" }, + { 0x2298, "PULSION Medical Systems AG" }, + { 0x2299, "BRAIN VISION SYSTEMS (BVS)" }, + { 0x229A, "Control Express Finland OY" }, + { 0x229B, "SFC Smart Fuel Cell AG" }, + { 0x229C, "Raytheon Company" }, + { 0x229D, "Solacia Inc." }, + { 0x229E, "JV2R - MacWay" }, + { 0x229F, "RRC power solutions GmbH" }, + { 0x22A0, "Winpos System Co., Ltd." }, + { 0x22A1, "Shenzhen Jiuzhou Electric Co., Ltd." }, + { 0x22A2, "Disruptive Ltd." }, + { 0x22A3, "DexCom" }, + { 0x22A4, "InnoComm Mobile Technology Corp." }, + { 0x22A5, "Yu Jeong System Co., Ltd." }, + { 0x22A6, "Pie Digital, Inc." }, + { 0x22A7, "Fortinet, Inc." }, + { 0x22A8, "OTTO" }, + { 0x22A9, "Valor Communication, Inc." }, + { 0x22AA, "AppliedMicro" }, + { 0x22AB, "Trigence Semiconductor, Inc." }, + { 0x22AC, "Sensor Switch, Inc." }, + { 0x22AD, "DCP Microdevelopments Limited" }, + { 0x22AE, "Buerkert Werke GmbH" }, + { 0x22AF, "JW Fishers Mfg." }, + { 0x22B0, "Business Security OL AB" }, + { 0x22B1, "Secret Labs LLC" }, + { 0x22B2, "EDGE Tech Corp." }, + { 0x22B3, "SOMFY" }, + { 0x22B4, "NIPPON ANTENNA Co., Ltd." }, + { 0x22B5, "Thyracont Vacuum Instruments GmbH" }, + { 0x22B6, "IMTRADEX Hoer-/Sprechsysteme GmbH" }, + { 0x22B7, "Unjo AB" }, + { 0x22B8, "Motorola Mobility Inc." }, + { 0x22B9, "eTurboTouch Technology Inc." }, + { 0x22BA, "Technology Innovation Holdings Ltd." }, + { 0x22BB, "Saris Cycling Group" }, + { 0x22BC, "OPWILL Technologies (Beijing) Co., Ltd." }, + { 0x22BD, "Basis Software, Inc." }, + { 0x22BE, "Cheetah-Medical Ltd." }, + { 0x22BF, "Bit Cauldron Corporation" }, + { 0x22C0, "ReLia Diagnostic Systems, Inc." }, + { 0x22C1, "ATEK Products, LLC" }, + { 0x22C2, "Fast And Safe Technology Co., Ltd." }, + { 0x22C3, "Tsinghua Tongfang Co., Ltd." }, + { 0x22C4, "Fresenius Medical Care Deutschland GmbH" }, + { 0x22C5, "Himax Technologies, Inc." }, + { 0x22C6, "Baker Hughes Production Quest" }, + { 0x22C7, "MEMUP" }, + { 0x22C8, "Karming Electronic (Shenzhen) Co., Ltd." }, + { 0x22C9, "StepOver GmbH" }, + { 0x22CA, "Amimon Ltd." }, + { 0x22CB, "Forware Spain S.L." }, + { 0x22CC, "LAONEX CO., LTD." }, + { 0x22CD, "Kinova" }, + { 0x22CE, "Metters Industries" }, + { 0x22CF, "Marquess Co., Limited" }, + { 0x22D0, "Norsonic AS" }, + { 0x22D1, "ZeitControl GmbH" }, + { 0x22D2, "ZETT OPTICS GmbH" }, + { 0x22D3, "FAAC SpA" }, + { 0x22D4, "Laview Technology Ltd." }, + { 0x22D5, "Yellow Soft Co., Ltd." }, + { 0x22D6, "Numatic International Ltd." }, + { 0x22D7, "IntelliTech International, Inc." }, + { 0x22D8, "Shantery Co., Ltd." }, + { 0x22D9, "GuangDong OPPO Mobile Telecommunications Corp., Ltd." }, + { 0x22DA, "TXTR GmbH" }, + { 0x22DB, "Phase One A/S" }, + { 0x22DC, "TILERA CORPORATION" }, + { 0x22DD, "Kawasaki Heavy Industries, Ltd." }, + { 0x22DE, "WeTelecom" }, + { 0x22DF, "Medicom-MTD" }, + { 0x22E0, "Secunet Security Networks AG" }, + { 0x22E1, "TempoTec Corp" }, + { 0x22E2, "IDEA!" }, + { 0x22E3, "Escort, Inc." }, + { 0x22E4, "Shenyang Tongzhen Precision Electronic Technology Co." }, + { 0x22E5, "Mine Safety Appliances Co." }, + { 0x22E6, "Labo America, Inc." }, + { 0x22E7, "ZAFFER BVBA" }, + { 0x22E8, "Audio Partnership" }, + { 0x22E9, "Orion Diagnostica OY" }, + { 0x22EA, "Bit Trade One, Ltd." }, + { 0x22EB, "Vizimax Inc." }, + { 0x22EC, "Kozio, Inc." }, + { 0x22ED, "HannStar Display Corp." }, + { 0x22EE, "Struers A/S" }, + { 0x22EF, "Edutor Technologies India Private Limited" }, + { 0x22F0, "Allen + Heath Ltd." }, + { 0x22F1, "DATEQ BV" }, + { 0x22F2, "Quest Payment Systems" }, + { 0x22F3, "Zephyr Technology Corporation" }, + { 0x22F4, "Olive Global Holding Pvt. Ltd." }, + { 0x22F5, "oTHE Technology Inc." }, + { 0x22F6, "Clear Pulse Co., Ltd." }, + { 0x22F7, "Drivven, Inc." }, + { 0x22F8, "Universal Sats Ltd." }, + { 0x22F9, "Compass, s.r.l." }, + { 0x22FA, "Sifteo Inc." }, + { 0x22FB, "Beijing Chiplight IC Design Co., Ltd." }, + { 0x22FC, "ModusLink Global Solutions, Inc." }, + { 0x22FD, "Miltope Corp." }, + { 0x22FE, "Protium Technologies, Inc." }, + { 0x22FF, "Avnet" }, + { 0x2300, "Nanjing Magon Opto-Electrical Science & Technology Co." }, + { 0x2301, "Imaginant Inc." }, + { 0x2302, "Rafael Advanced Defense Systems Ltd." }, + { 0x2303, "Grosvenor Technology Ltd." }, + { 0x2304, "Pinnacle" }, + { 0x2305, "Lindemann Audiotechnik GmbH" }, + { 0x2306, "Syba Multimedia, Inc." }, + { 0x2307, "Madboy Audio International Oy" }, + { 0x2308, "UV Networks, Inc." }, + { 0x2309, "TimeLink Inc." }, + { 0x230A, "Data Locker Inc." }, + { 0x230B, "Shanda Interactive Entertainment Limited" }, + { 0x230C, "GarTech Enterprises, Inc." }, + { 0x230D, "Linktop Technology Co., Ltd." }, + { 0x230E, "eDAQ Pty., Ltd." }, + { 0x230F, "applause.elfmimi.jp" }, + { 0x2310, "WCE, Inc." }, + { 0x2311, "Francotyp-Postalia GmbH" }, + { 0x2312, "Learning Curve Brands, Inc." }, + { 0x2313, "Kunshan Jiahua Electronics Co., Ltd." }, + { 0x2314, "INQ Mobile Limited" }, + { 0x2315, "Avery Design Systems, Inc." }, + { 0x2316, "DongGuan Potec Electric Industrial Co., Ltd." }, + { 0x2317, "Huawei Device Co., Ltd." }, + { 0x2318, "Solar Components LLC" }, + { 0x2319, "Loewe Opta GmbH" }, + { 0x231A, "SANWA KAGAKU KENKYUSHO CO., LTD." }, + { 0x231B, "winner story Co., Ltd." }, + { 0x231C, "SONUUS LIMITED" }, + { 0x231D, "Fervian Technologies Limited" }, + { 0x231E, "Chongqing CYIT Communication Technologies Co., Ltd." }, + { 0x231F, "FandF Co., Ltd." }, + { 0x2320, "Redring AB" }, + { 0x2321, "iKingdom Corp. (d.b.a. iConnectivity)" }, + { 0x2322, "RichWave Technology Corp." }, + { 0x2323, "EFI TECHNOLOGY s.r.l." }, + { 0x2324, "Ubisense Limited" }, + { 0x2325, "Simbex" }, + { 0x2326, "CKM Electronics Co., Ltd." }, + { 0x2327, "DreamSecurity" }, + { 0x2328, "Radio Systems Corporation" }, + { 0x2329, "Infinite Technologies JLT" }, + { 0x232A, "Skalar Analytical b.v." }, + { 0x232B, "ZHUHAI SEINE Technology CO., LTD." }, + { 0x232C, "Digital Lumens" }, + { 0x232D, "Edinburgh Instruments Ltd." }, + { 0x232E, "EA, Elektro-Automatik GmbH & Co. KG" }, + { 0x232F, "Motic China Group Co., Ltd." }, + { 0x2330, "Tensorcom" }, + { 0x2331, "PUZZLE LOGIC INC." }, + { 0x2332, "Coges S.p.A." }, + { 0x2333, "Zamzee Co." }, + { 0x2334, "Opticos srl" }, + { 0x2335, "Personable Inc." }, + { 0x2336, "Vix Products Pty. Ltd." }, + { 0x2337, "linked IP GmbH" }, + { 0x2338, "RedE Innovations" }, + { 0x2339, "Sierra Nevada Corporation" }, + { 0x233A, "Telpar" }, + { 0x233B, "taberna pro medicum GmbH" }, + { 0x233C, "Julabo" }, + { 0x233D, "Microtech System" }, + { 0x233E, "Aastra Telecom Inc." }, + { 0x233F, "Stage Tec GmbH" }, + { 0x2340, "Teleepoch Limited" }, + { 0x2341, "Arduino, LLC" }, + { 0x2342, "nextEDGE Technology, K.K." }, + { 0x2343, "AquaScan A/S" }, + { 0x2344, "HAMBURG INDUSTRIES CO., LTD." }, + { 0x2345, "ZOWIE GEAR" }, + { 0x2346, "Data Transfer & Communications Ltd." }, + { 0x2347, "iControl Networks" }, + { 0x2348, "Ubisys Technology" }, + { 0x2349, "P2 Engineering Group, LLC" }, + { 0x234A, "Cypress Technology Co., Ltd." }, + { 0x234B, "Free Software Initiative of Japan" }, + { 0x234C, "Zenverge Inc." }, + { 0x234D, "Skype Inc." }, + { 0x234E, "Anewin" }, + { 0x234F, "VaniOs Consulting" }, + { 0x2350, "ZiiLABS Pte. Ltd." }, + { 0x2351, "EmbCodeAB" }, + { 0x2352, "SKYTEX Technology Inc." }, + { 0x2353, "PHiON Technology Inc." }, + { 0x2354, "BirdBrain Technologies LLC" }, + { 0x2355, "Pacific Northwest National Laboratory (PNNL)" }, + { 0x2356, "Grid Connect Inc." }, + { 0x2357, "TP-LINK Technologies Co., Ltd." }, + { 0x2358, "Greenconn Corporation" }, + { 0x2359, "Shenzhen Autone-Tronic Technology Co., Ltd." }, + { 0x235A, "Top Yang Technology Enterprise Co., Ltd." }, + { 0x235B, "KangXiang Electronic Co., Ltd." }, + { 0x235C, "Neuralieve" }, + { 0x235D, "Wavepod Technologies LLC" }, + { 0x235E, "Sage Electronic Engineering LLC" }, + { 0x235F, "Delux Technology Co., Ltd." }, + { 0x2360, "AudioProbe Inc." }, + { 0x2361, "Artiza Networks, Inc." }, + { 0x2362, "Intuity Medical" }, + { 0x2363, "SplitFish Ltd." }, + { 0x2364, "Friedrich Leutert GmbH & Co. KG" }, + { 0x2365, "Midwest Microwave Solutions" }, + { 0x2366, "Bitmanufaktur GmbH" }, + { 0x2367, "Teenage Engineering" }, + { 0x2368, "Peterson Electro-Musical Products, Inc." }, + { 0x2369, "JDA, LLC (dba JDA Systems)" }, + { 0x236A, "SiBEAM, Inc." }, + { 0x236B, "Era Optoelectronics Inc." }, + { 0x236C, "ZheJiang Chunsheng Electronics Co., Ltd." }, + { 0x236D, "e-supplies Co., Ltd." }, + { 0x236E, "Idex ASA" }, + { 0x236F, "Risun Electric Information Technology Co., Ltd." }, + { 0x2370, "Vlatacom d.o.o." }, + { 0x2371, "Zetron, Inc." }, + { 0x2372, "Shenzhen Techaser Technologies Co., Ltd." }, + { 0x2373, "Pumatronix Equipamentos Eletronicos Ltda." }, + { 0x2374, "Codan Limited" }, + { 0x2375, "Nexell Co., Ltd." }, + { 0x2376, "Realfiction Aps" }, + { 0x2377, "Musa srl" }, + { 0x2378, "OnLive, INC." }, + { 0x2379, "Geotechnical Instruments (UK) Ltd." }, + { 0x237A, "Danatronics, Corp." }, + { 0x237B, "YUKAI Engineering" }, + { 0x237C, "POWERVAR" }, + { 0x237D, "CradlePoint, Inc." }, + { 0x237E, "Ernie Ball, Inc." }, + { 0x237F, "He Shan World Fair Electronics Technology Ltd." }, + { 0x2380, "Law Enforcement Associates, Inc." }, + { 0x2381, "IPE Music" }, + { 0x2382, "Trigaudio, Inc." }, + { 0x2383, "Super Pioneer Co., Ltd." }, + { 0x2384, "Tamara Electronics Design" }, + { 0x2385, "Booyco Electronics (Pty) Ltd." }, + { 0x2386, "Raydium Semicondutor Corporation" }, + { 0x2387, "N&S Services, Inc. dba XIM Technologies" }, + { 0x2388, "High Density Devices" }, + { 0x2389, "ShenZhen Handin Tech Co., Ltd." }, + { 0x238A, "ASAHI SANGYO CO., LTD." }, + { 0x238B, "Hytera Communications Co., Ltd." }, + { 0x238C, "Japan Care Net Service Corporation" }, + { 0x238D, "OMNIO Corporation" }, + { 0x238E, "Xtralis" }, + { 0x238F, "TRS Star GmbH" }, + { 0x2390, "Triex Technologies, Inc." }, + { 0x2391, "FUKUDA CO., LTD." }, + { 0x2392, "Deltatee Enterprises Ltd." }, + { 0x2393, "WonATech Co., Ltd." }, + { 0x2394, "J.MORITA MFG. CORP." }, + { 0x2395, "CNOGA MEDICAL LTD." }, + { 0x2396, "Advanced Multi Tech Pte. Ltd." }, + { 0x2397, "Simaudio Ltd." }, + { 0x2398, "Bluetechnix" }, + { 0x2399, "Lightwares" }, + { 0x239A, "Adafruit Industries LLC" }, + { 0x239B, "TZ Medical, Inc." }, + { 0x239C, "Braebon Medical Corporation" }, + { 0x239D, "Memjet Labels, Inc." }, + { 0x239E, "Rubin Informatikai Zrt." }, + { 0x239F, "Nikola Engineering Inc." }, + { 0x23A0, "BIFIT" }, + { 0x23A1, "Pepperl+Fuchs GmbH" }, + { 0x23A2, "Mobile Peak Holdings, Ltd." }, + { 0x23A3, "Dongguan City ShengJing Electronics Co., Ltd." }, + { 0x23A4, "MINGTECH CHINA CO., LTD." }, + { 0x23A5, "Instytut Fotonowy Sp. Z o.o." }, + { 0x23A6, "Tronical Components GmbH" }, + { 0x23A7, "System In Frontier Inc." }, + { 0x23A8, "Sagio A/S" }, + { 0x23A9, "SiliconGo Microelectronics Co., Ltd." }, + { 0x23AA, "JS Karaoke LLC" }, + { 0x23AB, "Shenzhen Zhengtong Electronics Co., Ltd." }, + { 0x23AC, "Marunix Electron Limited" }, + { 0x23AD, "voxeljet technology GmbH" }, + { 0x23AE, "DIGITAL DEVICES UG" }, + { 0x23AF, "iOWA AB" }, + { 0x23B0, "Seniorsoft Development Co., Ltd." }, + { 0x23B1, "Riken Keiki Co., Ltd." }, + { 0x23B2, "SEER Technology, Inc." }, + { 0x23B3, "Straubtec GmbH & Co. KG" }, + { 0x23B4, "Dental Wings Inc." }, + { 0x23B5, "Crowcon Detection Instruments Limited" }, + { 0x23B6, "FULL ELECTRONIC system" }, + { 0x23B7, "Isca Networks" }, + { 0x23B8, "Daruma Telecomunicacoes e Informatica S/A" }, + { 0x23B9, "Green Energy Options Ltd." }, + { 0x23BA, "Playback Designs LLC" }, + { 0x23BB, "EMI STOP CORP." }, + { 0x23BC, "ARIDIAN TECHNOLOGY COMPANY INC." }, + { 0x23BD, "Musashi Engineering, Inc." }, + { 0x23BE, "Raynet Technologies Pte. Ltd." }, + { 0x23BF, "Environics Oy" }, + { 0x23C0, "Kotec" }, + { 0x23C1, "MakerBot Industries" }, + { 0x23C2, "CREALOGIX E-Banking AG" }, + { 0x23C3, "Cydle Corp." }, + { 0x23C4, "Media Engineering" }, + { 0x23C5, "Promega Corporation" }, + { 0x23C6, "plawa-feinwerktechnik GmbH & Co. KG" }, + { 0x23C7, "GCI Technologies Corp." }, + { 0x23C8, "IML Ltd." }, + { 0x23C9, "IRM Touch Inc." }, + { 0x23CA, "IHP GmbH Innovations for High Performance Microelectro" }, + { 0x23CB, "Point Core SARL" }, + { 0x23CC, "Avitech International Corp." }, + { 0x23CD, "Avconn Precise Connector Co., Ltd." }, + { 0x23CE, "Gembird Electronics Ltd." }, + { 0x23CF, "Admesy BV" }, + { 0x23D0, "Youjie" }, + { 0x23D1, "LUFFT Mess-und Regeltechnik GmbH" }, + { 0x23D2, "WEAVERSMIND Inc." }, + { 0x23D3, "RFTECH SRL" }, + { 0x23D4, "ALLTRAX, Inc." }, + { 0x23D5, "SerialTek" }, + { 0x23D6, "DONGGUAN LICHENG ELECTRONICS CO., LTD." }, + { 0x23D7, "PENNYWISE PERIPHERALS PTY. LTD." }, + { 0x23D8, "CREATOR (CHINA) TECH CO., LTD." }, + { 0x23D9, "SIGLEAD Inc." }, + { 0x23DA, "THK Co., Ltd." }, + { 0x23DB, "Sonicweld" }, + { 0x23DC, "Phonic Ear, Inc. Frontrow Division" }, + { 0x23DD, "Ningbo Sunny Opotech Co., Ltd." }, + { 0x23DE, "ZAO Papillon" }, + { 0x23DF, "WebAthletics BV" }, + { 0x23E0, "BitifEye Digital Test Solutions GmbH" }, + { 0x23E1, "Vidyo, Inc." }, + { 0x23E2, "Shape Medical Systems, Inc." }, + { 0x23E3, "Christie Digital Systems Canada Inc." }, + { 0x23E4, "General Microsystems Sdn Bhd" }, + { 0x23E5, "Antelope Audio" }, + { 0x23E6, "DIGIT MOBILE INC." }, + { 0x23E7, "ROGER Dariusz Wensker Grzegorz Wensker S.P.j." }, + { 0x23E8, "Propellerhead Software AB" }, + { 0x23E9, "Peregrine Technology Co., Ltd." }, + { 0x23EA, "Inputek" }, + { 0x23EB, "TOPPAN FORMS CO., LTD." }, + { 0x23EC, "Alacer Biomedica Industria Eletronica Ltda." }, + { 0x23ED, "Optomotive, mehatronika d.o.o." }, + { 0x23EE, "Sofird, Inc." }, + { 0x23EF, "PPHU AWEX RAFAL STANUCH" }, + { 0x23F0, "Ecotronics Limited" }, + { 0x23F1, "WIMM Labs" }, + { 0x23F2, "Northern Digital Inc." }, + { 0x23F3, "Funke Digital TV" }, + { 0x23F4, "NXT Plc" }, + { 0x23F5, "SpeedConn Co., Ltd." }, + { 0x23F6, "Gamesman Ltd." }, + { 0x23F7, "TechRhythm, Inc." }, + { 0x23F8, "Xiangde Electronic Technologies (Shenzhen) Co., Ltd." }, + { 0x23F9, "RT Systems (Pty) Ltd." }, + { 0x23FA, "DJO, LLC" }, + { 0x23FB, "Janich & Klass Computertechnik GmbH" }, + { 0x23FC, "SesKion GmbH" }, + { 0x23FD, "AWare, Inc." }, + { 0x23FE, "Express Way Limited" }, + { 0x23FF, "UIworks Electronics" }, + { 0x2400, "ChuangYi Hardware Precision Mould Com., Ltd." }, + { 0x2401, "Deltronic Labs" }, + { 0x2402, "DA FACT" }, + { 0x2403, "XTRAMUS TECHNOLOGIES" }, + { 0x2404, "GE MDS" }, + { 0x2405, "Custom Computer Services, Inc." }, + { 0x2406, "INSIDE Secure" }, + { 0x2407, "Incasolution Co., Ltd." }, + { 0x2408, "Catalyst Enterprises, Inc." }, + { 0x2409, "BCInet, Inc." }, + { 0x240A, "Infron Teknolojik Sistemleri San. Ve Tic. Ltd. STI" }, + { 0x240B, "Kawamura Electric, Inc." }, + { 0x240C, "Maples Micro System Corp" }, + { 0x240D, "Chinachip Technology Limited" }, + { 0x240E, "JEFF ROWLAND DESIGN GROUP, INC" }, + { 0x240F, "Trantek Electronics Co., Ltd." }, + { 0x2410, "Tenebraex Corp." }, + { 0x2411, "Industrial Scientific Oldham SAS" }, + { 0x2412, "Invision Biometrics Ltd." }, + { 0x2413, "Skyviia Corporation" }, + { 0x2414, "Leopold Kostal GmbH & Co. KG" }, + { 0x2415, "CipherLab Co., Ltd." }, + { 0x2416, "FUTURE DESIGNS, INC." }, + { 0x2417, "INIT GmbH" }, + { 0x2418, "Irphotonics" }, + { 0x2419, "Shenzhen Dnine Technology Co., Ltd." }, + { 0x241A, "The Silanna Group Pty. Ltd." }, + { 0x241B, "Dongguan City Qirui Electronics Co., Ltd." }, + { 0x241C, "ATMOS Medizin Technik GmbH & Co. KG" }, + { 0x241D, "Redbird Flight Simulations, Inc." }, + { 0x241E, "SHENZHEN FUNDUN TECHNOLOGY CO., LTD." }, + { 0x241F, "Global Geo Supplies, Inc." }, + { 0x2420, "M Seven System Limited" }, + { 0x2421, "Anasphere, Inc." }, + { 0x2422, "Tom Communication Industrial Co., Ltd." }, + { 0x2423, "Bio-Med Devices Inc." }, + { 0x2424, "CREATZ Inc." }, + { 0x2425, "PIQX Imaging Pte. Ltd." }, + { 0x2426, "Johnson Controls, Inc. - Building Efficiency Business" }, + { 0x2427, "Winkelmann UK Ltd." }, + { 0x2428, "SANTEC CORPORATION" }, + { 0x2429, "IWSCOPE Inc." }, + { 0x242A, "HUR OY" }, + { 0x242B, "Philips Healthcare" }, + { 0x242C, "ARMSTEL, Inc." }, + { 0x242D, "Flastar Technology Co., Ltd." }, + { 0x242E, "Vossloh-Schwabe Deutschland GmbH" }, + { 0x242F, "GPH Co., Ltd." }, + { 0x2430, "APE GmbH" }, + { 0x2431, "Yamazaki Co., Ltd." }, + { 0x2432, "Ceton Corp." }, + { 0x2433, "Asetek A/S" }, + { 0x2434, "NOVA electronics, Inc." }, + { 0x2435, "PAKSENSE, INC." }, + { 0x2436, "MediTECH Electronic GmbH" }, + { 0x2437, "NIKETECH ELECTRONICS GROUP LIMITED" }, + { 0x2438, "Innopower Technology Corporation" }, + { 0x2439, "Comex Electronics AB" }, + { 0x243A, "Mobile Devices Ingenierie" }, + { 0x243B, "OTAX Electronics (ShenZhen) Co., Ltd." }, + { 0x243C, "DiZiC Co., Ltd." }, + { 0x243D, "emz - Hanauer GmbH & Co KGaA" }, + { 0x243E, "Savi Elettronica srl" }, + { 0x243F, "Photonic GesmbH & Co. KG" }, + { 0x2440, "RB GeneralEkonomik" }, + { 0x2441, "TV One" }, + { 0x2442, "University of Central Florida" }, + { 0x2443, "Aessent Technology Ltd." }, + { 0x2444, "NetModule AG" }, + { 0x2445, "TOMY Company, Ltd." }, + { 0x2446, "Avionics Interface Technologies" }, + { 0x2447, "Knick Elektronische Messgerate GmbH & Co. KG" }, + { 0x2448, "Winterhalter GmbH" }, + { 0x2449, "SHAEFER GmbH" }, + { 0x244A, "Onzo Ltd." }, + { 0x244B, "Applied Technical Systems" }, + { 0x244C, "Minebea Co., Ltd." }, + { 0x244D, "Pantec Biosolutions AG" }, + { 0x244E, "ShopGuard Ltd." }, + { 0x244F, "iWall A/S" }, + { 0x2450, "Boule Medical AB" }, + { 0x2451, "AEM Performance Electronics" }, + { 0x2452, "Speeder Electronics Co., Ltd." }, + { 0x2453, "BAANTO" }, + { 0x2454, "Velosti Technology Limited" }, + { 0x2455, "Anton/Bauer, Inc." }, + { 0x2456, "Nikki Denso Co., Ltd." }, + { 0x2457, "Alcomp. Inc." }, + { 0x2458, "Bluegiga Technologies Oy" }, + { 0x2459, "Secure Holdings Limited" }, + { 0x245A, "KONDOH SEISAKUSHO Co., Ltd." }, + { 0x245B, "Zixsys Inc." }, + { 0x245C, "Steinbauer Electronics GmbH" }, + { 0x245D, "ID Technologies" }, + { 0x245E, "LNT - Automation GmbH" }, + { 0x245F, "Chord Electronics Limited" }, + { 0x2460, "NELS, Ltd." }, + { 0x2461, "Beam Communications" }, + { 0x2462, "IDENTICA S.A." }, + { 0x2463, "BAP Precision LLC" }, + { 0x2464, "Nestlabs" }, + { 0x2465, "Perceptive Pixel, Inc." }, + { 0x2466, "Fractal Audio Systems, LLC" }, + { 0x2467, "Nektar Technology, Inc." }, + { 0x2468, "New Cosmos Electric Co., Ltd." }, + { 0x2469, "Gloria Music Corp." }, + { 0x246A, "UNH Interoperability Laboratory" }, + { 0x246B, "Perfect Fortune Electric Wire & Cable (ShenZhen) Co Ltd" }, + { 0x246C, "Shanghai Fudan Microelectronics Co., Ltd." }, + { 0x246D, "TrackMan A/S" }, + { 0x246E, "Movinto Fun AB" }, + { 0x246F, "STORK PRINTS AUSTRIA GmbH" }, + { 0x2470, "Hale Microsystems" }, + { 0x2471, "Bloonn Srl" }, + { 0x2472, "Bossa Nova Robotics, Inc." }, + { 0x2473, "Trend Control Systems Limited" }, + { 0x2474, "Stamps.com" }, + { 0x2475, "JCM American Corporation" }, + { 0x2476, "Yost Engineering Inc." }, + { 0x2477, "UbiVelox" }, + { 0x2478, "Sonix Technology (Shenzhen) Co., Ltd." }, + { 0x2479, "visiosens GmbH" }, + { 0x247A, "WuJiang XinYa Electronics Co., Ltd." }, + { 0x247B, "Digibras Industria do Brasil S.A" }, + { 0x247C, "Fullconn Industry Inc." }, + { 0x247D, "JARGY CO. LTD." }, + { 0x247E, "GEWA music GmbH" }, + { 0x247F, "Lynx Studio Technology, Inc." }, + { 0x2480, "Omniware Inc." }, + { 0x2481, "Shenzhen SKY DRAGON Audio-Video Technology Co., Ltd." }, + { 0x2482, "SmartRoom LLC" }, + { 0x2483, "Valups Corp." }, + { 0x2484, "Unipolar Optics-Electrical Technology Co., Ltd." }, + { 0x2485, "Dream SAS" }, + { 0x2486, "DCG Systems, Inc." }, + { 0x2487, "SHANGHAI VEI SHENG AUTO PARTS MANUFACTURING CO., LTD." }, + { 0x2488, "SuperD Co., Ltd." }, + { 0x2489, "Irvine Sensors Corporation" }, + { 0x248A, "TeLink Semiconductor (Shanghai) Co., Ltd." }, + { 0x248B, "SYNCONN INTERCONNECT INC." }, + { 0x248C, "Avicenna Instruments, LLC" }, + { 0x248D, "Digital Matter Pty Ltd." }, + { 0x248E, "Pulsar Informatics, Inc." }, + { 0x248F, "HMS Industrial Networks AB" }, + { 0x2490, "Zealtek electronic Co. Ltd." }, + { 0x2491, "OBSERVATOR instruments b.v." }, + { 0x2492, "Mofiria Corporation" }, + { 0x2493, "Sensolutions Inc." }, + { 0x2494, "Invoxia" }, + { 0x2495, "Summit Semiconductor LLC" }, + { 0x2496, "Dongguan DaTang Industrial Investment Co., Ltd." }, + { 0x2497, "HyunWoo Electronics Co., Ltd." }, + { 0x2498, "Aurora SFC Systems, Inc." }, + { 0x2499, "Governors America Corp." }, + { 0x249A, "Anedio, LLC" }, + { 0x249B, "Miller Electric Mfg. Co." }, + { 0x249C, "M2TECH SRL" }, + { 0x249D, "Ken-A-Vision Manufacturing Company, Inc." }, + { 0x249E, "Tlab West Systems AB" }, + { 0x249F, "ABC PCB Sarl" }, + { 0x24A0, "VIMAR SPA" }, + { 0x24A1, "AUTONICS Corporation" }, + { 0x24A2, "SafeTech Ltd." }, + { 0x24A3, "BioTillion, LLC" }, + { 0x24A4, "Primare AB" }, + { 0x24A5, "OWANDY" }, + { 0x24A6, "Shenzhen Pangngai Industrial Co., Ltd." }, + { 0x24A7, "PROMAX ELECTRONICA S.A." }, + { 0x24A8, "Hermes electronic GmbH" }, + { 0x24A9, "ASolid Technology Co., Ltd." }, + { 0x24AA, "Wasatch Photonics" }, + { 0x24AB, "IMERJ LTD." }, + { 0x24AC, "ToMiTec GmbH" }, + { 0x24AD, "embedded brains GmbH" }, + { 0x24AE, "Shenzhen Rapoo Technology Co., Ltd." }, + { 0x24AF, "Integrated Corporation" }, + { 0x24B0, "Echometer Company" }, + { 0x24B1, "SCR Engineers Ltd." }, + { 0x24B2, "DelSys Inc." }, + { 0x24B3, "Simbionix Ltd." }, + { 0x24B4, "Leema Acoustics" }, + { 0x24B5, "3C TEK CORP." }, + { 0x24B6, "Shenzhen New-Conn International Co., Ltd." }, + { 0x24B7, "Medical Equipment Europe GmbH" }, + { 0x24B8, "DongGuan CJ TOUCH Electronic Co., Ltd." }, + { 0x24B9, "Hoshin Electronics Co., Ltd." }, + { 0x24BA, "PRADOTEC Corporation Sdn. Bhd." }, + { 0x24BB, "SHANGHAI LIGHTSURFING INFORMATION TECHNOLOGY CO., LTD." }, + { 0x24BC, "Sartorius AG" }, + { 0x24BD, "Smart Solution" }, + { 0x24BE, "Mutewatch AB" }, + { 0x24BF, "NBS Payment Solutions, Inc." }, + { 0x24C0, "Chaney Instrument Co." }, + { 0x24C1, "Maction Technologies, Inc." }, + { 0x24C2, "DiCon Fiberoptics, Inc." }, + { 0x24C3, "Covaris, Inc." }, + { 0x24C4, "CMITECH Co., Ltd." }, + { 0x24C5, "HUINTECH" }, + { 0x24C6, "Xbox 3rd Party Partners" }, + { 0x24C7, "Laser Technology, Inc." }, + { 0x24C8, "CHAPP INC." }, + { 0x24C9, "Pilot Electronic (China) Ltd." }, + { 0x24CA, "SMARTEH d.o.o." }, + { 0x24CB, "Servotronix Motion Control Ltd." }, + { 0x24CC, "JSB Tech Pte. Ltd." }, + { 0x24CD, "Viking360.com LLC" }, + { 0x24CE, "Shenzhen Deren Electronic Co., Ltd." }, + { 0x24CF, "Lytro, Inc." }, + { 0x24D0, "Smith Micro Software, Inc." }, + { 0x24D1, "POS & Solution Company" }, + { 0x24D2, "DADT Holdings, LLC" }, + { 0x24D3, "Lexking Technology Co., Ltd." }, + { 0x24D4, "KOMATSU ELECTRONIC CO., LTD." }, + { 0x24D5, "SATEL Ltd." }, + { 0x24D6, "Develer S.r.l." }, + { 0x24D7, "ACORDE TECHNOLOGIES" }, + { 0x24D8, "Pittway Tecnologica Srl" }, + { 0x24D9, "Unfors Instruments AB" }, + { 0x24DA, "KYOCERA ELCO Korea Co., Ltd." }, + { 0x24DB, "DDUSB Technology" }, + { 0x24DC, "Aladdin Software Security R.D." }, + { 0x24DD, "Kingspan Environmental Ltd." }, + { 0x24DE, "Navicron" }, + { 0x24DF, "ALGO System. Co" }, + { 0x24E0, "Yoctopuce Sarl" }, + { 0x24E1, "Paratronic S.A." }, + { 0x24E2, "Digital Information Technology Studies (Shenzhen) Ltd." }, + { 0x24E3, "Beijing TianYu Communication Equipment Co., Ltd." }, + { 0x24E4, "Bytec Group Limited" }, + { 0x24E5, "Lanmark Controls Inc." }, + { 0x24E6, "ACI Analytical Control Instruments GmbH" }, + { 0x24E7, "maxon motor ag" }, + { 0x24E8, "ivee" }, + { 0x24E9, "Microelectronics Technology Inc." }, + { 0x24EA, "ZEBEX INDUSTRIES INC." }, + { 0x24EB, "SHENZHEN PCTX TECHNOLOGY DEVELOPMENT CO., LTD." }, + { 0x24EC, "CE-Infosys GmbH" }, + { 0x24ED, "ZEN FACTORY GROUP (ASIA) LTD." }, + { 0x24EE, "A C S Co., Ltd." }, + { 0x24EF, "DATONG PLC" }, + { 0x24F0, "Das Keyboard - Metadot" }, + { 0x24F1, "Silicon Communication Technology" }, + { 0x24F2, "Secure Electrans LTD." }, + { 0x24F3, "MartinLogan Ltd." }, + { 0x24F4, "Mind Media BV" }, + { 0x24F5, "QRS Diagnostic" }, + { 0x24F6, "Zeemote Technology Inc." }, + { 0x24F7, "Seneye Ltd." }, + { 0x24F8, "Bang & Olufsen A/S" }, + { 0x24F9, "TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORP." }, + { 0x24FA, "Vectronix AG" }, + { 0x24FB, "GTECH Corporation" }, + { 0x24FC, "GPEG International" }, + { 0x24FD, "Nichiyu Giken Kogyo Co., Ltd." }, + { 0x24FE, "GOMETRICS, S.L." }, + { 0x24FF, "Acroname Inc." }, + { 0x2500, "Ettus Research LLC" }, + { 0x2501, "Bridge Publications, Inc." }, + { 0x2502, "Canadian Automotive Instruments Ltd." }, + { 0x2503, "Kurth Electronic GmbH" }, + { 0x2504, "Nemic Lambda Ltd." }, + { 0x2505, "Xiroku Accupoint Technology Inc." }, + { 0x2506, "Hind Technology Group" }, + { 0x2507, "Advion BioSystems" }, + { 0x2508, "Symplex Communications, Inc." }, + { 0x2509, "Chain-In Electronic Co., Ltd." }, + { 0x250A, "H-Squared" }, + { 0x250B, "Nautilus Lifeline Ltd." }, + { 0x250C, "PHX Inc." }, + { 0x250D, "Alstom Grid SAS" }, + { 0x250E, "Beijing MOPS Technology Co., Ltd." }, + { 0x250F, "itplants ltd." }, + { 0x2510, "SE Elektronische Systeme" }, + { 0x2511, "Morita Tech Co., Ltd." }, + { 0x2512, "RNDPLUS Co., Ltd." }, + { 0x2513, "RMI Laser, LLC" }, + { 0x2514, "Fullpower Technologies" }, + { 0x2515, "KOREA O/S TECHNOLOGIES" }, + { 0x2516, "Cooler Master Co., Ltd." }, + { 0x2517, "Marel EHF" }, + { 0x2518, "Anite Telecoms Inc." }, + { 0x2519, "n-gineric gmbh" }, + { 0x251A, "Daiichi Electronics" }, + { 0x251B, "Stable Imaging Solutions, LLC" }, + { 0x251C, "snom technology AG" }, + { 0x251D, "Fortebio Inc." }, + { 0x251E, "Polara Engineering, Inc." }, + { 0x251F, "Golden Emperor International Ltd." }, + { 0x2520, "ANA-U GmbH" }, + { 0x2521, "Fundacion Tekniker" }, + { 0x2522, "Light Harmonic" }, + { 0x2523, "Recon Instruments Inc." }, + { 0x2524, "CVRx" }, + { 0x2525, "Barron McCann Technology Ltd." }, + { 0x2526, "Weide Electronics Co., Ltd." }, + { 0x2527, "Software Bisque, Inc." }, + { 0x2528, "BittWare Inc." }, + { 0x2529, "SUZHOU XINYA ELECTRIC COMMUNICATION CO., LTD." }, + { 0x252A, "SUZHOU KELI TECHNOLOGY DEVELOPMENT CO., LTD." }, + { 0x252B, "TOP Exactitude Industry (ShenZhen) Co., Ltd." }, + { 0x252C, "VIGO System S.A." }, + { 0x252D, "Nokia Siemens Networks" }, + { 0x252E, "Heliox Technologies, Inc." }, + { 0x252F, "Pentronic AB" }, + { 0x2530, "STT Emtec AB" }, + { 0x2531, "Proteus Industries Inc." }, + { 0x2532, "C.R.D.E. (Cahors Group)" }, + { 0x2533, "Osaka Micro Computer, Inc." }, + { 0x2534, "Russia's Institute of Radionavigation and Time" }, + { 0x2535, "Shenzhen Hong Junde Precision Technology Co., Ltd." }, + { 0x2536, "Ubisys Technology Co., Ltd." }, + { 0x2537, "Norel Systems Ltd." }, + { 0x2538, "Cochlear Ltd." }, + { 0x2539, "Club Electronics" }, + { 0x253A, "System Sacom Industry Corporation" }, + { 0x253B, "RCF S.p.a." }, + { 0x253C, "Tri-Tech Manufacturing Inc." }, + { 0x253D, "Koss Corporation" }, + { 0x253E, "Creative Product Design Pty., Ltd." }, + { 0x253F, "ORANGE IT INC." }, + { 0x2540, "Applied Materials" }, + { 0x2541, "Shanghai AisinoChip Electronics Technology Co., Ltd." }, + { 0x2542, "Ditron S.R.L." }, + { 0x2543, "Spark Dental Technology Limited" }, + { 0x2544, "Energy Micro AS" }, + { 0x2545, "Digital Foci, Inc." }, + { 0x2546, "Ravensburger Spieleverlag GmbH" }, + { 0x2547, "YiDu Technology" }, + { 0x2548, "Pulse-Eight Limited" }, + { 0x2549, "Librestream Technologies" }, + { 0x254A, "Enegate Co., Ltd." }, + { 0x254B, "Toy Toy Toy Ltd." }, + { 0x254C, "X6D Limited" }, + { 0x254D, "ICAR VISION SYSTEMS S.L." }, + { 0x254E, "SHF Communication Technologies AG" }, + { 0x254F, "Jigeon Technologies Co., Ltd." }, + { 0x2550, "Teledyne" }, + { 0x2551, "A.E.B. Industriale S.r.l." }, + { 0x2552, "Striiv, Inc." }, + { 0x2553, "C8 MediSensor" }, + { 0x2554, "Securitron Magnalock Corporation" }, + { 0x2555, "Pulse Tracer, Inc." }, + { 0x2556, "United Radio-Electronic Technologies Co., Ltd." }, + { 0x2557, "Robatech AG" }, + { 0x2558, "INTECH ELECTRONICS CORP." }, + { 0x2559, "Jangus Music, Inc. (dba Wi Digital Systems)" }, + { 0x255A, "TaiDoc Technology Corp." }, + { 0x255B, "NDI Technologies, Inc." }, + { 0x255C, "HOSIWELL TECHNOLOGY CO., LTD." }, + { 0x255D, "ATEECS" }, + { 0x255E, "Beijing Bonxeon Technology Co., Ltd." }, + { 0x255F, "DORNIER-LTF GmbH" }, + { 0x2560, "e-con Systems India Private Limited" }, + { 0x2561, "Brookhaven Instruments Corp." }, + { 0x2562, "SHENGZHEN MAYA ELECTRONICS CREATION CO. LTD." }, + { 0x2563, "Shenzhen ShanWan Technology Co., Ltd." }, + { 0x2564, "TESSERA TECHNOLOGY INC." }, + { 0x2565, "Cyclone Industries Limited" }, + { 0x2566, "Cryptera A/S" }, + { 0x2567, "DongGuan LongTao Electronic Co., Ltd." }, + { 0x2568, "ALL LINK CONN. TECHNOLOGY CORP." }, + { 0x2569, "DongGuan City MingJi Electronics Co., Ltd." }, + { 0x256A, "TAIAN TECHNOLOGY (WUXI) Co., Ltd." }, + { 0x256B, "Perreaux Industries Ltd." }, + { 0x256C, "GRAPHICS TECHNOLOGY (HK) CO., LIMITED" }, + { 0x256D, "Compal Broadband Networks, Inc." }, + { 0x256E, "Valuest Co., Ltd." }, + { 0x256F, "3D CONNEXION SAM" }, + { 0x2570, "AVID Technologies, Inc." }, + { 0x2571, "CHIPMAST TECHNOLOGY CO., LTD." }, + { 0x2572, "Vmarker" }, + { 0x2573, "ESI Audiotechnik GmbH" }, + { 0x2574, "AVer Information Inc." }, + { 0x2575, "Weida Hi-Tech Co., Ltd." }, + { 0x2576, "AFO Co., Ltd." }, + { 0x2577, "LCDVF LLC" }, + { 0x2578, "MPEC Technology Limited" }, + { 0x2579, "Dongguan Kowell Electronic Co., Ltd." }, + { 0x257A, "Shanghai Yuga Information Technology Co., Ltd." }, + { 0x257B, "shenzhen dcard smart card tech. co., ltd." }, + { 0x257C, "Richard Woehr GmbH" }, + { 0x257D, "Panovel Technology Corporation" }, + { 0x257E, "RFL Electronics Inc." }, + { 0x257F, "8devices" }, + { 0x2580, "DJ Techtools (Golden Sol Music LLC. Is Holding Co.)" }, + { 0x2581, "Plug-up" }, + { 0x2582, "Systeme Helmholz GmbH" }, + { 0x2583, "VECTRUX DISTRIBUTORS LLC" }, + { 0x2584, "COSMO CO., LTD." }, + { 0x2585, "HomeChip Ltd." }, + { 0x2586, "PLANET Technology Corporation" }, + { 0x2587, "Ningbo Jiatang Electronic Co., Ltd." }, + { 0x2588, "Infinitegra, Inc." }, + { 0x2589, "Argon Technology Corporation" }, + { 0x258A, "Sino Wealth Electronic Ltd." }, + { 0x258B, "KORYO ELECTRONICS CO., LTD." }, + { 0x258C, "Fastec Imaging Corporation" }, + { 0x258D, "SEQUANS Communications" }, + { 0x258E, "ENJsoft Co., Ltd." }, + { 0x258F, "CME" }, + { 0x2590, "MuChip Co., Ltd." }, + { 0x2591, "Optimus Semiconductor Inc." }, + { 0x2592, "Quest International" }, + { 0x2593, "CELIZION, Inc." }, + { 0x2594, "Acsys Technologies Ltd." }, + { 0x2595, "SANYO DENKI CO., LTD." }, + { 0x2596, "Twisted Melon, Inc." }, + { 0x2597, "Diagnostic Systems Associates Inc." }, + { 0x2598, "Aerocrine" }, + { 0x2599, "Q-tag AG" }, + { 0x259A, "TriQuint Semiconductor" }, + { 0x259B, "INUVIO" }, + { 0x259C, "Immedia Semiconductor Inc." }, + { 0x259D, "RCA DA AMAZONIA LTDA" }, + { 0x259E, "American Messaging Services LLC" }, + { 0x259F, "THERMO KING" }, + { 0x25A0, "Ciegus Ltd." }, + { 0x25A1, "Suitable Technologies, Inc." }, + { 0x25A2, "LEMKE ENG." }, + { 0x25A3, "Nanoteq (Pty) Ltd." }, + { 0x25A4, "ALGOLTEK, INC." }, + { 0x25A5, "Yakel Enterprises LLC" }, + { 0x25A6, "AADI AS" }, + { 0x25A7, "Beken Corporation" }, + { 0x25A8, "Guangzhou Geoelectron Science & Technology Co., Ltd." }, + { 0x25A9, "Advanced Bionics" }, + { 0x25AA, "Top Victory Investments Ltd. (HK)" }, + { 0x25AB, "Carmanah Signs" }, + { 0x25AC, "PLIGG" }, + { 0x25AD, "Aurora Networks, Inc." }, + { 0x25AE, "OXIPULSE" }, + { 0x25AF, "C&A Marketing" }, + { 0x25B0, "Musical Fidelity" }, + { 0x25B1, "Disc Soft Ltd." }, + { 0x25B2, "DRS-RSTA, Inc." }, + { 0x25B3, "DongGuan Elinke Industrial Co., Ltd." }, + { 0x25B4, "Fairhaven Health" }, + { 0x25B5, "FlatFrog Laboratories AB" }, + { 0x25B6, "Fructel AB" }, + { 0x25B7, "Neomitic Technologies S.A. de C.V." }, + { 0x25B8, "Neutronics Inc." }, + { 0x25B9, "Nujira Ltd." }, + { 0x25BA, "WITec Wissenschaftliche Instrumente & Technologie GmbH" }, + { 0x25BB, "Brunner Elektronik AG" }, + { 0x25BC, "CETRTA POT" }, + { 0x25BD, "TECHEYE SYSTEMS INC." }, + { 0x25BE, "Infinite Z" }, + { 0x25BF, "Elegant Invention" }, + { 0x25C0, "Beyond Music Industrial Co., Ltd." }, + { 0x25C1, "Vaddio" }, + { 0x25C2, "Smith + Nephew Inc." }, + { 0x25C3, "Phorus" }, + { 0x25C4, "A & R Cambridge Ltd." }, + { 0x25C5, "Securetec Detektions Systeme AG" }, + { 0x25C6, "AVA Group A/S" }, + { 0x25C7, "MEGATRON Elektronik AG & Co." }, + { 0x25C8, "Visualplanet Ltd." }, + { 0x25C9, "Proximiant" }, + { 0x25CA, "Hovding Sverige AB" }, + { 0x25CB, "ELZET80 Mikrocomputer Giesler & Danne GmbH & Co. KG" }, + { 0x25CC, "NKC Co., Ltd." }, + { 0x25CD, "Edwards Ltd." }, + { 0x25CE, "MYTEK DIGITAL" }, + { 0x25CF, "Corning Incorporated" }, + { 0x25D0, "AeVee Laboratories LLC" }, + { 0x25D1, "TOKAI-DENSHI Inc." }, + { 0x25D2, "MRA Tek LLC" }, + { 0x25D3, "Zhe Jiang Huasheng Technology Co., Ltd." }, + { 0x25D4, "LOOPCOMM TECHNOLOGY, INC." }, + { 0x25D5, "DATATON AB" }, + { 0x25D6, "KOUZIRO Co., Ltd." }, + { 0x25D7, "Audiomatica srl" }, + { 0x25D8, "Serious Integrated, Inc." }, + { 0x25D9, "Monarch Innovative Technologies Pvt. Ltd." }, + { 0x25DA, "NETATMO" }, + { 0x25DB, "Merrick Industries, Inc." }, + { 0x25DC, "Cobolt AB" }, + { 0x25DD, "bit4id srl" }, + { 0x25DE, "Gasmet Technologies OY" }, + { 0x25DF, "TTE Systems Ltd." }, + { 0x25E0, "MULTIPLEX Modellsport GmbH & Co. KG" }, + { 0x25E1, "Daimler AG" }, + { 0x25E2, "Domain Surgical" }, + { 0x25E3, "SCI Innovations Ltd." }, + { 0x25E4, "AnaJet" }, + { 0x25E5, "ALLFLEX EUROPE" }, + { 0x25E6, "Digital Drilling Data Systems, LLC" }, + { 0x25E7, "EIFELWERK Butler Systeme GmbH" }, + { 0x25E8, "ATOLL Electronique" }, + { 0x25E9, "Leybold Vacuum" }, + { 0x25EA, "Aeroflex Weinschel" }, + { 0x25EB, "Medical Intubation Technology Corp." }, + { 0x25EC, "VELUX A/S" }, + { 0x25ED, "Logic PD" }, + { 0x25EE, "Mimoco" }, + { 0x25EF, "BLITZ Co., Ltd." }, + { 0x25F0, "GOODBETTERBEST Ltd." }, + { 0x25F1, "Eden Innovations" }, + { 0x25F2, "Dongguan Jinyue Electronics Co., Ltd." }, + { 0x25F3, "Kicker" }, + { 0x25F4, "ADVANSEE" }, + { 0x25F5, "Lucas Holding bv" }, + { 0x25F6, "SaferZone Co., Ltd." }, + { 0x25F7, "Engineea Remote Technologies S.L." }, + { 0x25F8, "Keypair Co., Ltd." }, + { 0x25F9, "Donbass Soft Ltd. & Co. KG" }, + { 0x25FA, "SoftEther Corporation" }, + { 0x25FB, "PENTAX RICOH IMAGING COMPANY, LTD." }, + { 0x25FC, "RWA (Hong Kong) Limited" }, + { 0x25FD, "Neuromonics Inc." }, + { 0x25FE, "Providence Enterprise Limited" }, + { 0x25FF, "Watermark Medical, Inc." }, + { 0x2600, "SMARTCORE Inc." }, + { 0x2601, "OFI Testing Equipment, Inc." }, + { 0x2602, "Magenta Research Ltd." }, + { 0x2603, "Swyx Solutions AG" }, + { 0x2604, "Shenzhen Tenda Technology, Ltd." }, + { 0x2605, "OSRAM SYLVANIA" }, + { 0x2606, "O-Network Engineering AB" }, + { 0x2607, "Prox Dynamics AS" }, + { 0x2608, "OLHO tronic GmbH" }, + { 0x2609, "FICOSA" }, + { 0x260A, "SPEMOT AG" }, + { 0x260B, "Schneider Electric Canada Inc. - Division of PCT" }, + { 0x260C, "Saiko Systems Ltd." }, + { 0x260D, "DongGuan Togran Electronic Co., Ltd." }, + { 0x260E, "DongGuan HYX Industrial Co., Ltd." }, + { 0x260F, "VITY" }, + { 0x2610, "Egan Teamboard Inc." }, + { 0x2611, "I.C.E. Co., Ltd." }, + { 0x2612, "Crave Innovations" }, + { 0x2613, "Gerd Bar GmbH" }, + { 0x2614, "VMC Consulting Corporation" }, + { 0x2615, "Gammaflux L.P." }, + { 0x2616, "PS Audio" }, + { 0x2617, "Front-End Technology, Inc." }, + { 0x2618, "MicroGate Systems Ltd." }, + { 0x2619, "Advanced Silicon SA" }, + { 0x261A, "Shandong Synthesis Electronic Technology Co., Ltd." }, + { 0x261B, "INTELLIGENT ENERGY, LTD." }, + { 0x261C, "EISST Limited" }, + { 0x261D, "Arkham Technology" }, + { 0x261E, "IFAM GmbH Erfurt" }, + { 0x261F, "Cooper Industries" }, + { 0x2620, "SUE unicon.uz Scientific, Engineering & Marketing RC" }, + { 0x2621, "CLIXUP LLC" }, + { 0x2622, "IAG Group Limited" }, + { 0x2623, "SGR Audio Pty Ltd." }, + { 0x2624, "L-3 Communications - Communications Systems West" }, + { 0x2625, "MilDef AB" }, + { 0x2626, "Aruba Networks" }, + { 0x2627, "Vectron Systems AG" }, + { 0x2628, "TEN-TEC, INC." }, + { 0x2629, "Winstars Technology Limited" }, + { 0x262A, "SAVITECH Corporation" }, + { 0x262B, "JXT Precision Electronics Technical Co., Ltd." }, + { 0x262C, "Scannx" }, + { 0x262D, "Fujian Witsi Microelectronics Technology Co., Ltd." }, + { 0x262E, "UNITEX Corporation" }, + { 0x262F, "MELAG Medizintechnik oHG" }, + { 0x2630, "ifm electronic gmbh" }, + { 0x2631, "NEOPROT TECNOLOGIA EM INFORMATICA LTDA." }, + { 0x2632, "ENSPERT Inc." }, + { 0x2633, "Inno Audio & Video (HK) Limited" }, + { 0x2634, "E.M.S. S.R.L." }, + { 0x2635, "uHDevice Technology Ltd." }, + { 0x2636, "MED-EL Medical Electronics" }, + { 0x2637, "TAEWOONG MEDICAL. CO., LTD." }, + { 0x2638, "Becker-Antriebe GmbH" }, + { 0x2639, "Xsens Technologies B.V." }, + { 0x263A, "Maury Microwave" }, + { 0x263B, "Time & Data Systems International Ltd." }, + { 0x263C, "Schultes Microcomputer-Vertriebs-GmbH & Co KG" }, + { 0x263D, "pls Programmierbare Logik & Systeme GmbH" }, + { 0x263E, "Odin TeleSystems Inc." }, + { 0x263F, "ES-Experts, Ltd." }, + { 0x2640, "Banner Engineering" }, + { 0x2641, "PRO TUNE ELECTRONIC SYSTEMS" }, + { 0x2642, "NPP ELIKS America Inc. DBA T&M Atlantic" }, + { 0x2643, "COMVOX AUDIO CO., LTD." }, + { 0x2644, "Sioux Electronics B.V." }, + { 0x2645, "Lead Data Inc." }, + { 0x2646, "Bel Canto Design, Ltd." }, + { 0x2647, "FORMER ENGINEERING SERVICE CO., LTD." }, + { 0x2648, "Telongo LLC" }, + { 0x2649, "BYOS Audio, Inc." }, + { 0x264A, "THERMALTAKE Technology Co., Ltd." }, + { 0x264B, "Industrial Indexing Systems" }, + { 0x264C, "Si14 SpA" }, + { 0x264D, "Wolfrum Elektronik & Avionik" }, + { 0x264E, "3i Corporation" }, + { 0x264F, "RF Controls, LLC" }, + { 0x2650, "Electronics For Imaging, Inc." }, + { 0x2651, "Otis Instruments Inc." }, + { 0x2652, "Fallbrook Technologies, Inc." }, + { 0x2653, "AutoHotBox" }, + { 0x2654, "DarklingX, LLC" }, + { 0x2655, "Moog Inc." }, + { 0x2656, "Ashcroft Inc." }, + { 0x2657, "Embedia Technologies Corporation" }, + { 0x2658, "Sintermask GmbH" }, + { 0x2659, "Sundtek" }, + { 0x265A, "3Brain GmbH" }, + { 0x265B, "D-tect Systems" }, + { 0x265C, "IDEX Health + Science LLC" }, + { 0x265D, "H. Schomaecker GmbH" }, + { 0x265E, "JSC Engineering Centre Energoservice" }, + { 0x265F, "Azatrax" }, + { 0x2660, "YEONG DER (SUM-EM) Enterprises Co., Ltd." }, + { 0x2661, "WorldCast Systems" }, + { 0x2662, "MOOG Music Inc." }, + { 0x2663, "JOMESA Messsysteme GmbH" }, + { 0x2664, "NOHMI BOSAI Ltd." }, + { 0x2665, "Yamaki Electric Corporation" }, + { 0x2666, "BLX IC Design Corp., Ltd." }, + { 0x2667, "SuZhou ZhongXingLian Precision Industrial Co., Ltd." }, + { 0x2668, "Shenzhen Yuwenfa Electronic Technology Co., Ltd." }, + { 0x2669, "ME4SURE, Inc." }, + { 0x266A, "Linear LLC" }, + { 0x266B, "ProSys Development Services" }, + { 0x266C, "Brightsight BV" }, + { 0x266D, "Ergotest Innovation A.S." }, + { 0x266F, "Shanghai Zhengyuan Technologies Co., Ltd." }, + { 0x2670, "Zhengzhou Xin Da Jie An Information Technology Co., Ltd" }, + { 0x2671, "Innovative Logic" }, + { 0x2672, "GoPro" }, + { 0x2673, "Wadia Digital" }, + { 0x2674, "Hoyt Monitor Technologies, LLC" }, + { 0x2675, "Peter Huber Kaeltemaschinenbau GmbH" }, + { 0x2676, "Basler AG" }, + { 0x2677, "Winegard Company" }, + { 0x2678, "Sky Deutschland GmbH & Co. KG" }, + { 0x2679, "BESTMEDIA CD-Recordable GmbH & Co. KG" }, + { 0x267A, "Xi'an YEP Telecommunication Technology Co., Ltd." }, + { 0x267B, "Palpilot International Corp." }, + { 0x267C, "OptiGene Limited" }, + { 0x267D, "KOHZU Precision Co., Ltd." }, + { 0x267E, "E.D. Bullard Company" }, + { 0x267F, "Acromag Inc." }, + { 0x2680, "DIGICO UK Limited" }, + { 0x2681, "MYLAPS B.V." }, + { 0x2682, "ROBOX S.P.A." }, + { 0x2683, "Gazogiken Co., Ltd." }, + { 0x2684, "Funkwerk Security Communications GmbH" }, + { 0x2685, "Cardo Systems Inc." }, + { 0x2686, "IP LABS Inc." }, + { 0x2687, "FITBIT" }, + { 0x2688, "Stratasys Inc." }, + { 0x2689, "StepOver Inc." }, + { 0x268A, "QEES" }, + { 0x268B, "Dimension Engineering LLC" }, + { 0x268C, "AMS-TAOS" }, + { 0x268D, "WEISS ENGINEERING LTD." }, + { 0x268E, "xyzmo Software GmbH" }, + { 0x268F, "LETech Co., Ltd." }, + { 0x2690, "K.K. Rabbit" }, + { 0x2691, "ZINK Imaging, Inc." }, + { 0x2692, "CELLIENT CO., LTD." }, + { 0x2693, "Silvershore Technology Partners" }, + { 0x2694, "RoboteX Inc." }, + { 0x2695, "DynaGen Technologies Inc." }, + { 0x2696, "Sensovation AG" }, + { 0x2697, "Anfatec Instruments" }, + { 0x2698, "EVTD Inc." }, + { 0x2699, "ECOUS Corp." }, + { 0x269A, "BETTER MANAGE INVESTMENTS LIMITED" }, + { 0x269B, "Novel Data Solutions (Suzhou) Coorporation" }, + { 0x269C, "ECTRON CORPORATION" }, + { 0x269D, "Accessible Technologies, Inc." }, + { 0x269E, "Astro Gaming" }, + { 0x269F, "DKL TECHNOLOGY (SHENZHEN) CO., LTD." }, + { 0x26A0, "MIDAS" }, + { 0x26A1, "Miris AB" }, + { 0x26A2, "Eppendorf AG" }, + { 0x26A3, "EMKO ELEKTRONIK SAN. VE TIC. AS" }, + { 0x26A4, "Blue Goji" }, + { 0x26A5, "CAL TEST ELECTRONICS, INC." }, + { 0x26A6, "Radio Design Group, Inc." }, + { 0x26A7, "LOG-IN, Inc." }, + { 0x26A8, "UNIREX CORPORATION" }, + { 0x26A9, "Research Industrial Systems IT-Engineering (RISE) GmbH" }, + { 0x26AA, "YAESU MUSEN CO., LTD." }, + { 0x26AB, "Motion Control Systems, Inc." }, + { 0x26AC, "3D Robotics Inc." }, + { 0x26AD, "Global Distribution GmbH" }, + { 0x26AE, "Oscium" }, + { 0x26AF, "Bombardier Transportation GmbH, TCMS Development Ctr 2" }, + { 0x26B0, "Zhejiang Senda Electronics Co., Ltd." }, + { 0x26B1, "Bassett Electronic Systems Limited" }, + { 0x2899, "Toptronic Industrial Co., Ltd. " }, + { 0x2FB2, "Fujitsu Limited " }, + { 0x3176, "WHANAM ELECTRONICS CO., Ltd. MS division " }, + { 0x3552, "BD Consumer Healthcare " }, + { 0x3636, "INVIBRO " }, + { 0x3884, "Nicolet Biomedical Inc., a Viasys Healthcare Co. " }, + { 0x3923, "National Instruments " }, + { 0x4102, "iRiver " }, + { 0x413C, "Dell Inc. " }, + { 0x4242, "USB Design By Example " }, + { 0x4317, "Broadcom WLAN " }, + { 0x4426, "TANITA Corporation " }, + { 0x4791, "HGST BRANDED BUSINESS " }, + { 0x4971, "HITACHI GLOBAL STORAGE TECHNOLOGIES " }, + { 0x4B53, "Key Soft Service " }, + { 0x4C46, "DSPecialists GmbH " }, + { 0x4DDC, "Data Device Corporation " }, + { 0x5058, "ProXense, LLC " }, + { 0x5245, "RESPIRONICS, INC. " }, + { 0x544D, "Transmeta Corporation " }, + { 0x5543, "UC-Logic Technology Corp. " }, + { 0x5555, "Number Five, Software " }, + { 0x55AA, "OnSpec Electronic Inc. " }, + { 0x5986, "BISON ELECTRONICS INC. " }, + { 0x6000, "TRIDENT MICROSYSTEMS (Far East) Ltd. " }, + { 0x630F, "Leapfrog Schoolhouse " }, + { 0x636C, "CoreLogic, Inc. " }, + { 0x6400, "Springer Design, Inc. " }, + { 0x6A75, "Shanghai Jujo Electronics Co., Ltd. " }, + { 0x735F, "Beijing Techshino Technology Co., Ltd. " }, + { 0x8020, "Trinity, Inc. " }, + { 0x8086, "Intel Corporation " }, + { 0x8087, "Intel " }, + { 0x8829, "Beijing Daming Wuzhou Science & Technology Co., Ltd. " }, + { 0x8873, "Dengineer Co., Ltd. " }, + { 0x9696, "Digital Arts, Inc. " }, + { 0x9710, "Moschip Semiconductor Technology " }, + { 0xA600, "ASIX s.r.o. " }, + { 0xA625, "Wuhan Tianyu Information Industry Co., Ltd. " }, + { 0xBEE5, "BEE SYSTEMS LLC " }, + { 0xC0B8, "Corbett Life Science " }, + { 0xC10C, "Given Imaging " }, + { 0xCACE, "CACE Technologies " }, + { 0xCC42, "Cardio Control NV " }, + { 0xEA01, "Eagle Technology " }, + { 0xEB1A, "Empia Technology, Inc. " }, + { 0x0000, "Vendor ID not listed with USB.org as of 02-15-2012"} +}; + +#endif /* __VNDRLIST_H__ */ + diff --git a/usb/usbview/xmlhelper.cpp b/usb/usbview/xmlhelper.cpp new file mode 100644 index 00000000..4221aeb0 --- /dev/null +++ b/usb/usbview/xmlhelper.cpp @@ -0,0 +1,3058 @@ +/*++ + + Copyright (c) 1997-2011 Microsoft Corporation + + Module Name: + + XMLHELPER.CPP + +Abstract: + +This source file contains helper APIs for reading writing XML + +Environment: + +user mode + +Revision History: + +05-05-11 : created + +--*/ + +/***************************************************************************** + I N C L U D E S + *****************************************************************************/ +#include "uvcview.h" +#include "h264.h" +#include "xmlhelper.h" + +// usbschema.hpp is autogenerated from schema during build PASS0 +#include "usbschema.hpp" + +// Include code analysis suppressions +#include "codeanalysis.h" + +/***************************************************************************** + D E F I N E S + *****************************************************************************/ +#define COBJMACROS + +#define PACHAR_TO_STRING(X) ((X != NULL)? gcnew String(Marshal::PtrToStringAnsi((IntPtr) X )):nullptr) +#define PWCHAR_TO_STRING(X) ((X != NULL)? gcnew String(Marshal::PtrToStringUni((IntPtr) X )):nullptr) + +#define MAX_STRING_DESCRIPTOR_LENGTH 512 +#define STRING_DESCRIPTOR_EN_LANGUAGE_ID 0x0409 +#define DEVICE_DESCRIPTOR_LENGTH 18 + +#define SERVICE_EHCI "usbehci" +#define SERVICE_XHCI "usbxhci" +#define SERVICE_OHCI "usbohci" +#define SERVICE_UHCI "usbuhci" + +#define USB_1_1 "USB 1.1" +#define USB_2_0 "USB 2.0" +#define USB_3_0 "USB 3.0" +#define USB_GENERIC "USB GENERIC (UNKNOWN)" + +/***************************************************************************** + N A M E S P A C E S + *****************************************************************************/ + +using namespace System; +using namespace System::IO; +using namespace System::Runtime::InteropServices; +using namespace System::Collections; +using namespace Microsoft::Kits::Samples::Usb; + + +/***************************************************************************** + G L O B A L S + *****************************************************************************/ + +namespace Microsoft +{ + namespace Kits + { + namespace Samples + { + namespace Usb + { + public ref class XmlGlobal sealed + { + private: + static XmlGlobal ^ pInstance = gcnew XmlGlobal(); + + // Empty private constructor + XmlGlobal() + { + } + + public: + // + // Globals for XML view + // + property UvcViewAll ^ ViewAll; + property bool XmlViewInitialized; + + // + // Stack of parents of a given node. This is used for finding + // where a given object should be added + // + +#if CODE_ANALYSIS + // ParentStack need not be constant since we will only have one instance of this object + [SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible")] +#endif + static Stack ^ ParentStack = gcnew Stack(); + + static XmlGlobal ^ Instance() + { + return pInstance; + } + }; + }; + }; + }; +}; + +#define gXmlView ((XmlGlobal::Instance())->ViewAll->UvcView) +#define gXmlViewInitialized ((XmlGlobal::Instance())->XmlViewInitialized) +#define gXmlStack ((XmlGlobal::Instance())->ParentStack) + +/***************************************************************************** + D E C L A R A T I O N S + *****************************************************************************/ + +String ^ XmlGetStringDescriptor(UCHAR index, PSTRING_DESCRIPTOR_NODE stringDesc, bool enOnly); +void XmlAddHostControllerPowerMapping( UsbHCPowerStateMappingType ^xmlPwrInfo, PUSB_POWER_INFO usbHCPowerInfo); +String ^ XmlGetDeviceClassString(UCHAR deviceClass); +void XmlAddHostControllerPowerMapping(UsbHCPowerStateMappingType ^xmlPwrInfo, PUSB_POWER_INFO usbHCPowerInfo); +void XmlAddHub30Descriptor(Hub30DescriptorType ^hub30Desc, PUSB_30_HUB_DESCRIPTOR hub30Descriptor); +void XmlAddHubDescriptor(HubDescriptorType ^hubDesc, PUSB_HUB_DESCRIPTOR hubDescriptor); +void XmlAddPortConnectorProps(PortConnectorType ^portXmlProps, PUSB_PORT_CONNECTOR_PROPERTIES portProps); +void XmlAddHubCharacteristics(HubInformationType ^hubI, WORD hubChar); +HRESULT XmlAddHubNodeInformation(HubNodeInformationType ^ni, PUSB_NODE_INFORMATION nodeInfo); +HRESULT XmlAddHubInformationEx(HubInformationExType ^ex, PUSB_HUB_INFORMATION_EX hubInfoEx); +HRESULT XmlAddHubCapabilitiesEx(HubCapabilitiesExType ^ex, USB_HUB_CAPABILITIES_EX hubCapEx); +ExternalHubType ^ AddExternalHub(Object ^parent); +NoDeviceType ^ AddDisconnectedPort(Object ^parent); +UsbDeviceType ^ AddUsbDevice(Object ^parent); +void XmlAddEndpointDescriptor( + EndpointDescriptorType ^usbXmlEndpointDescriptor, + PUSB_ENDPOINT_DESCRIPTOR endPointDescriptor, + UCHAR connectionSpeed); +void XmlAddPipeInformation( + array< UsbPipeInfoType ^> ^ usbXmlPipeInfoList, + PUSB_PIPE_INFO pipeInfo, + ULONG numPipes, + UCHAR connectionSpeed); +void XmlAddUsbDeviceDescriptor( + UsbDeviceDescriptorType ^usbXmlDeviceDescriptor, + PUSB_DEVICE_DESCRIPTOR usbDeviceDescriptor); +void XmlAddConfigurationDescriptor( + UsbConfigurationDescriptorType ^ confXmlDesc, + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDesc, + PSTRING_DESCRIPTOR_NODE stringDesc); +void XmlAddDeviceQualDescriptor( + UsbDeviceQualifierDescriptorType ^ qualXmlDesc, + PUSB_DEVICE_QUALIFIER_DESCRIPTOR qualDesc); +void XmlAddDeviceConfiguration( + UsbDeviceConfigurationType ^ confXmlDesc, + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDesc, + PSTRING_DESCRIPTOR_NODE stringDesc, + int numInterfaces); +void XmlAddConnectionInfoSt( + NodeConnectionInfoExStructType ^xmlConnectionInfoSt, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PDEVICE_INFO_NODE pNode); +String ^ XmlGetLangIdString(UCHAR index, PSTRING_DESCRIPTOR_NODE stringDesc); +String ^ XmlGetStringDescriptor(UCHAR index, PSTRING_DESCRIPTOR_NODE stringDesc, bool enOnly); +String ^ XmlGetDeviceClassString(UCHAR deviceClass); +bool XmlAddDeviceClassDetails( + UsbDeviceClassDetailsType ^ deviceDetails, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PUSBDEVICEINFO deviceInfo); +void XmlAddConnectionInfo( + NodeConnectionInfoExType ^xmlConnectionInfo, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PUSBDEVICEINFO deviceInfo, + PSTRING_DESCRIPTOR_NODE stringDesc, + PDEVICE_INFO_NODE pNode); +void XmlAddHidDescriptor( + UsbDeviceHidDescriptorType ^ hidXmlDesc, + PUSB_HID_DESCRIPTOR hidDesc); +void XmlAddDeviceInterfaceDescriptor( + UsbDeviceInterfaceDescriptorType ^ ifXmlDesc, + PUSB_INTERFACE_DESCRIPTOR ifDesc, + PSTRING_DESCRIPTOR_NODE stringDesc); +void XmlAddOTGDescriptor( + UsbDeviceOTGDescriptorType ^ otgXmlDesc, + PUSB_OTG_DESCRIPTOR otgDesc); +void XmlAddIADDescriptor( + UsbDeviceIADDescriptorType ^ iadXmlDesc, + PUSB_IAD_DESCRIPTOR iadDesc, + PSTRING_DESCRIPTOR_NODE stringDesc, + int nInterfaces); +array < UsbDeviceConfigurationType ^> ^ XmlGetConfigDescriptors( + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDescs, + PSTRING_DESCRIPTOR_NODE stringDesc); +UsbBosDescriptorType ^ XmlGetBosDescriptor(PUSB_BOS_DESCRIPTOR bosDesc); +UsbDeviceClassType ^ XmlGetDeviceClass(UCHAR deviceClass, UCHAR deviceSubClass, UCHAR deviceProtocol); +UsbDeviceUnknownDescriptorType ^ XmlGetUnknownDescriptor( + PUSB_COMMON_DESCRIPTOR unknownDesc + ); +UsbUsb20ExtensionDescriptorType ^ XmlGetUsb20CapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR capDesc + ); +UsbSuperSpeedExtensionDescriptorType ^ XmlGetSuperSpeedCapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR capDesc + ); +UsbDispContIdCapExtDescriptorType ^ XmlGetContainerIdCapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR capDesc + ); + +/***************************************************************************** + D E F I N I T I O N S + *****************************************************************************/ + +/***************************************************************************** + XmlNotifyEndOfNodeList + + This function is called back by WalkTreeTopDown() function to notify us + that there are no more children to add for the current parent + + *****************************************************************************/ +VOID XmlNotifyEndOfNodeList(PVOID pContext) +{ + UNREFERENCED_PARAMETER(pContext); + + if (gXmlStack != nullptr && gXmlStack->Count > 0) + { + // Remove the last parent on the stack + gXmlStack->Pop(); + } +} + +/***************************************************************************** + + XmlAddHostControllerPowerMapping() + + add power info to xml structure + *****************************************************************************/ +void XmlAddHostControllerPowerMapping(UsbHCPowerStateMappingType ^xmlPwrInfo, PUSB_POWER_INFO usbHCPowerInfo) +{ + int i, powerState; + PUSB_POWER_INFO pUPI = usbHCPowerInfo; + UsbHCPowerStateType ^ pwrState = nullptr; + + xmlPwrInfo->PowerMap = gcnew array<UsbHCPowerStateType ^> (WdmUsbPowerSystemShutdown); + + for(i = 0, powerState = WdmUsbPowerSystemWorking; powerState < WdmUsbPowerSystemShutdown; i++, powerState++, pUPI++) + { + xmlPwrInfo->PowerMap[i] = gcnew UsbHCPowerStateType(); + pwrState = xmlPwrInfo->PowerMap[i]; + pwrState->SystemState = PACHAR_TO_STRING(GetPowerStateString(pUPI->SystemState)); + pwrState->HostControllerState = PACHAR_TO_STRING(GetPowerStateString(pUPI->HcDevicePowerState)); + pwrState->HubState = PACHAR_TO_STRING(GetPowerStateString(pUPI->RhDevicePowerState)); + pwrState->CanWakeUp = pUPI->CanWakeup? true:false; + pwrState->IsPowered = pUPI->IsPowered? true:false; + } + + xmlPwrInfo->LastSleepState = PACHAR_TO_STRING(GetPowerStateString(pUPI->LastSystemSleepState)); + return; +} + +/***************************************************************************** + + XmlAddHostController() + + Add an host controller to XML view + *****************************************************************************/ + +HRESULT XmlAddHostController(PSTR hcName, PUSBHOSTCONTROLLERINFO hcInfo) +{ + HRESULT hr = S_OK; + + UNREFERENCED_PARAMETER(hcName); + + HostControllerType ^ hc = nullptr; + // + // Check if the USB Tree array has been initialized + // It would have been great if XSD had a way of generating a list instead of array, but it does not + // So we have to do array.Resize everytime + // + if (gXmlView->UsbTree == nullptr) + { + // This is the first time we are being called, initialize the array with 1 element + gXmlView->UsbTree = gcnew array<HostControllerType ^>(1); + gXmlView->UsbTree[0] = gcnew HostControllerType(); + hc = gXmlView->UsbTree[0]; + } + else + { + // Create a new array every time as Array.Resize does not seem to work in our case (CLI) + // We do this using ArrayList. + ArrayList ^hcList = gcnew ArrayList; + hcList->AddRange(gXmlView->UsbTree); + hc = gcnew HostControllerType(); + hcList->Add(hc); + gXmlView->UsbTree = reinterpret_cast<array<HostControllerType ^>^> (hcList->ToArray(HostControllerType::typeid)); + } + + if (hc != nullptr) + { + ULONG debugPort = 0; + + UsbHCDeviceInfoType ^ ci = nullptr; + UsbHCPowerStateMappingType ^ pm = nullptr; + + if (NULL != hcInfo->UsbDeviceProperties) + { + hc->HwId = PACHAR_TO_STRING(hcInfo->UsbDeviceProperties->HwId); + hc->DeviceId = PACHAR_TO_STRING(hcInfo->UsbDeviceProperties->DeviceId); + hc->ServiceName = PACHAR_TO_STRING(hcInfo->UsbDeviceProperties->Service); + hc->DeviceName = PACHAR_TO_STRING(hcInfo->UsbDeviceProperties->DeviceDesc); + hc->DeviceClass = PACHAR_TO_STRING(hcInfo->UsbDeviceProperties->DeviceClass); + + if (_stricmp(hcInfo->UsbDeviceProperties->Service, SERVICE_OHCI) == 0) + { + hc->UsbProtocol = gcnew String(USB_1_1); + } + else if(_stricmp(hcInfo->UsbDeviceProperties->Service, SERVICE_EHCI) == 0 || + _stricmp(hcInfo->UsbDeviceProperties->Service, SERVICE_UHCI) == 0) + { + hc->UsbProtocol = gcnew String(USB_2_0); + } + else if (_stricmp(hcInfo->UsbDeviceProperties->Service, SERVICE_XHCI) == 0) + { + hc->UsbProtocol = gcnew String(USB_3_0); + } + else + { + USB_CONTROLLER_FLAVOR flavor = hcInfo->ControllerInfo->ControllerFlavor; + + // If protocol lookup failed based on service name, try Controller flavor + if(NULL != hcInfo->ControllerInfo) + { + if(flavor == USB_HcGeneric) + { + hc->UsbProtocol = gcnew String(USB_GENERIC); + } + else if(flavor >= OHCI_Generic && flavor < UHCI_Generic) + { + hc->UsbProtocol = gcnew String(USB_1_1); + } + else if(flavor >= UHCI_Generic && flavor < EHCI_Generic) + { + hc->UsbProtocol = gcnew String(USB_2_0); + } + else if(flavor >= EHCI_Generic) + { + hc->UsbProtocol = gcnew String(USB_3_0); + } + } + } + } + + hc->ControllerInfo = gcnew UsbHCDeviceInfoType(); + hc->PowerMapping = gcnew UsbHCPowerStateMappingType(); + ci = hc->ControllerInfo; + pm = hc->PowerMapping; + + ci->VendorId = hcInfo->VendorID; + ci->DeviceId = hcInfo->DeviceID; + ci->DriverKey = PACHAR_TO_STRING(hcInfo->DriverKey); + ci->SubSysId = hcInfo->SubSysID; + ci->Revision = hcInfo->Revision; + + if(NULL != hcInfo->ControllerInfo) + { + ci->NumberOfRootPorts = hcInfo->ControllerInfo->NumberOfRootPorts; + ci->ControllerFlavor = hcInfo->ControllerInfo->ControllerFlavor; + ci->PortSwitchingEnabled = (hcInfo->ControllerInfo->HcFeatureFlags & USB_HC_FEATURE_FLAG_PORT_POWER_SWITCHING)? true: false; + ci->SelectiveSuspendEnabled = (hcInfo->ControllerInfo->HcFeatureFlags & USB_HC_FEATURE_FLAG_SEL_SUSPEND)? true: false; + ci->LegacyBios = (hcInfo->ControllerInfo->HcFeatureFlags & USB_HC_FEATURE_LEGACY_BIOS)? true: false; + ci->ControllerFlavorString = PACHAR_TO_STRING(GetControllerFlavorString(hcInfo->ControllerInfo->ControllerFlavor)); + } + + // Add power mappings + XmlAddHostControllerPowerMapping(pm, (PUSB_POWER_INFO) (&(hcInfo->USBPowerInfo[0]))); + + // Add debug port + debugPort = GetEhciDebugPort(hcInfo->VendorID, hcInfo->DeviceID); + if (debugPort > 0) + { + ci->DebugPort = debugPort; + } + + gXmlStack->Push(hc); + + } + else + { + hr = E_FAIL; + } + + return hr; +} + +/***************************************************************************** + + XmlAddHub30Descriptor() + + Adds the hub 3.0 descriptor to the given hub object + *****************************************************************************/ +void XmlAddHub30Descriptor(Hub30DescriptorType ^hub30Desc, PUSB_30_HUB_DESCRIPTOR hub30Descriptor) +{ + + if (nullptr != hub30Desc && NULL != hub30Descriptor) + { + hub30Desc->Length = hub30Descriptor->bLength; + hub30Desc->DescriptorType = hub30Descriptor->bDescriptorType; + hub30Desc->NumberOfPorts = hub30Descriptor->bNumberOfPorts; + hub30Desc->HubCharacteristics = hub30Descriptor->wHubCharacteristics; + hub30Desc->PowerOntoPowerGood = hub30Descriptor->bPowerOnToPowerGood; + hub30Desc->HubControlCurrent = hub30Descriptor->bHubControlCurrent; + hub30Desc->HubHdrDecLat = hub30Descriptor->bHubHdrDecLat; + hub30Desc->DeviceRemovable = hub30Descriptor->DeviceRemovable; + } +} + +/***************************************************************************** + + XmlAddHubDescriptor() + + Adds the hub descriptor to the given hub object + *****************************************************************************/ +void XmlAddHubDescriptor(HubDescriptorType ^hubDesc, PUSB_HUB_DESCRIPTOR hubDescriptor) +{ + if (nullptr != hubDesc && NULL != hubDescriptor) + { + hubDesc->DescriptorLength = hubDescriptor->bDescriptorLength; + hubDesc->DescriptorType = hubDescriptor->bDescriptorType; + hubDesc->NumberOfPorts = hubDescriptor->bNumberOfPorts; + hubDesc->PowerOntoPowerGood = hubDescriptor->bPowerOnToPowerGood; + hubDesc->HubControlCurrent = hubDescriptor->bHubControlCurrent; + } +} + +/***************************************************************************** + + XmlAddPortConnectorProps() + + Adds the port connector properties to XML file + *****************************************************************************/ +void XmlAddPortConnectorProps(PortConnectorType ^portXmlProps, PUSB_PORT_CONNECTOR_PROPERTIES portProps) +{ + if (NULL != portProps) + { + portXmlProps->UsbPortProperties = gcnew UsbPortPropertiesType(); + + portXmlProps->ConnectionIndex = portProps->ConnectionIndex; + portXmlProps->ActualLength = portProps->ActualLength; + portXmlProps->CompanionIndex = portProps->CompanionIndex; + portXmlProps->CompanionPortNumber = portProps->CompanionPortNumber; + portXmlProps->CompanionHubSymbolicLinkName = PWCHAR_TO_STRING(portProps->CompanionHubSymbolicLinkName); + + portXmlProps->UsbPortProperties->PortIsUserConnectable = portProps->UsbPortProperties.PortIsUserConnectable? true:false; + portXmlProps->UsbPortProperties->PortIsDebugCapable = portProps->UsbPortProperties.PortIsDebugCapable? true:false; + } + return; +} + +/***************************************************************************** + + XmlAddConnectionInfoV2() + + Adds the V2 connection info structure + *****************************************************************************/ +void XmlAddConnectionInfoV2(NodeConnectionInfoExV2Type ^ connectionXmlInfo, PUSB_NODE_CONNECTION_INFORMATION_EX_V2 connectionInfo) +{ + if (NULL != connectionInfo) + { + connectionXmlInfo->ConnectionIndex = connectionInfo->ConnectionIndex; + connectionXmlInfo->Length = connectionInfo->Length; + + connectionXmlInfo->Usb110Supported = connectionInfo->SupportedUsbProtocols.Usb110? true:false; + connectionXmlInfo->Usb200Supported = connectionInfo->SupportedUsbProtocols.Usb200? true:false; + connectionXmlInfo->Usb300Supported = connectionInfo->SupportedUsbProtocols.Usb300? true:false; + + connectionXmlInfo->DeviceIsOperatingAtSuperSpeedOrHigher = + connectionInfo->Flags.DeviceIsOperatingAtSuperSpeedOrHigher; + + connectionXmlInfo->DeviceIsSuperSpeedCapableOrHigher = + connectionInfo->Flags.DeviceIsSuperSpeedCapableOrHigher; + + connectionXmlInfo->DeviceIsOperatingAtSuperSpeedPlusOrHigher = + connectionInfo->Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher; + + connectionXmlInfo->DeviceIsSuperSpeedPlusCapableOrHigher = + connectionInfo->Flags.DeviceIsSuperSpeedPlusCapableOrHigher; + + } + return; +} + +/***************************************************************************** + + XmlAddHubCharacteristics() + + Adds the hub characteristics to the given hub object + *****************************************************************************/ +void XmlAddHubCharacteristics(HubInformationType ^hubI, WORD hubChar) +{ + HubCharacteristicsType ^hubC = nullptr; + + hubI->HubCharacteristics = gcnew HubCharacteristicsType(); + hubC = hubI->HubCharacteristics; + hubC->HubCharacteristicsValue = hubChar; + switch(hubChar & 0x3) + { + case 0x0: + hubC->PowerSwitching = gcnew String("Ganged"); + break; + case 0x1: + hubC->PowerSwitching = gcnew String("Individual"); + break; + case 0x2: + case 0x3: + hubC->PowerSwitching = gcnew String("None"); + break; + default: + hubC->PowerSwitching = gcnew String("Unknown"); + } + + hubC->CompoundDevice = (hubChar & 0x4)? true:false; + + switch(hubChar & 0x18) + { + case 0x0: + hubC->OverCurrentProtection = gcnew String("Global"); + break; + case 0x8: + hubC->OverCurrentProtection = gcnew String("Individual"); + break; + case 0x10: + case 0x18: + hubC->OverCurrentProtection = gcnew String("No protection, bus power only"); + break; + default: + hubC->OverCurrentProtection = gcnew String("Unknown"); + } +} + +/***************************************************************************** + + XmlAddHubNodeInformation() + + Adds the node information to the hub object + *****************************************************************************/ +HRESULT XmlAddHubNodeInformation(HubNodeInformationType ^ni, PUSB_NODE_INFORMATION nodeInfo) +{ + PUSB_HUB_INFORMATION hubInfo = NULL; + + if (NULL == nodeInfo) + { + return E_FAIL; + } + + hubInfo = &(nodeInfo->u.HubInformation); + ni->HubNode = static_cast<HubNodeType> (nodeInfo->NodeType); + + ni->HubInformation = gcnew HubInformationType(); + ni->HubInformation->IsRootHub = true; + ni->HubInformation->IsBusPowered = hubInfo->HubIsBusPowered? true:false; + + // Add hub characteristics + XmlAddHubCharacteristics(ni->HubInformation, hubInfo->HubDescriptor.wHubCharacteristics); + // Add descriptor + ni->HubInformation->HubDescriptor = gcnew HubDescriptorType(); + XmlAddHubDescriptor(ni->HubInformation->HubDescriptor, &(hubInfo->HubDescriptor)); + + return S_OK; +} + +/***************************************************************************** + + XmlAddHubInformation() + + Adds the node information to the hub object + *****************************************************************************/ +HRESULT XmlAddHubInformationEx(HubInformationExType ^ex, PUSB_HUB_INFORMATION_EX hubInfoEx) +{ + HubDescriptorType ^hubDesc = nullptr; + Hub30DescriptorType ^hub30Desc = nullptr; + + if (NULL == hubInfoEx) + { + return E_FAIL; + } + + ex->HubType = static_cast<HubTypeType> (hubInfoEx->HubType); + ex->HighestPortNumber = hubInfoEx->HighestPortNumber; + switch(hubInfoEx->HubType) + { + case UsbRootHub: + case Usb20Hub: + ex->HubDescriptor = hubDesc = gcnew HubDescriptorType(); + XmlAddHubDescriptor(hubDesc, &(hubInfoEx->u.UsbHubDescriptor)); + break; + case Usb30Hub: + ex->Hub30Descriptor = hub30Desc = gcnew Hub30DescriptorType(); + XmlAddHub30Descriptor(hub30Desc, &(hubInfoEx->u.Usb30HubDescriptor)); + break; + } + return S_OK; +} + +/***************************************************************************** + + XmlAddHubCapabilitiesEx() + + Adds the hub capabilities information to the hub object + *****************************************************************************/ +HRESULT XmlAddHubCapabilitiesEx(HubCapabilitiesExType ^ex, PUSB_HUB_CAPABILITIES_EX hubCapEx) +{ + if(NULL != hubCapEx) + { + ex->HubIsHighSpeedCapable = hubCapEx->CapabilityFlags.HubIsHighSpeedCapable?true:false; + ex->HubIsHighSpeed = hubCapEx->CapabilityFlags.HubIsHighSpeed?true:false; + ex->HubIsMultiTtCapable = hubCapEx->CapabilityFlags.HubIsMultiTtCapable?true:false; + ex->HubIsMultiTt = hubCapEx->CapabilityFlags.HubIsMultiTt?true:false; + ex->HubIsRoot = hubCapEx->CapabilityFlags.HubIsRoot?true:false; + ex->HubIsArmedWakeOnConnect = hubCapEx->CapabilityFlags.HubIsArmedWakeOnConnect?true:false; + ex->HubIsBusPowered = hubCapEx->CapabilityFlags.HubIsBusPowered?true:false; + } + return S_OK; +} + +/***************************************************************************** + + ExternalHubType ^ AddExternalHub(Object ^parent) + + This routine finds the type of the parent and adds an external hub object to the + parent's list of external hubs. The newly created object is returned + We are using arrays insted of better types of collections becaused the code generated + by xsd.exe does not support other types. + *****************************************************************************/ +ExternalHubType ^ AddExternalHub(Object ^parent) +{ + RootHubType ^ rhParent = nullptr; + ExternalHubType ^ ehParent = nullptr; + array<ExternalHubType ^> ^ exHubArray = nullptr; + ExternalHubType ^ exHub = nullptr; + boolean arrayCreated = false; + + // An external hub can be connected to a Root Hub or another External Hub + // We need to determine the type of the object. + + // Try root hub first + + rhParent = dynamic_cast<RootHubType ^> (parent); + if (rhParent == nullptr) + { + // RootHub cast was not successfult, try external hub + ehParent = dynamic_cast<ExternalHubType ^> (parent); + if (ehParent != nullptr) + { + // External hub parent + if (ehParent->ExternalHub == nullptr) + { + // First hub in the list of external hubs + ehParent->ExternalHub = gcnew array<ExternalHubType ^> (1); + arrayCreated = true; + } + exHubArray = ehParent->ExternalHub; + } + + } + else + { + // Parent is a root hub + if (rhParent->ExternalHub == nullptr) + { + // First hub in root hub list + rhParent->ExternalHub = gcnew array<ExternalHubType ^>(1); + arrayCreated = true; + } + exHubArray = rhParent->ExternalHub; + } + + if (exHubArray != nullptr) + { + if (arrayCreated) + { + // We created the array in this function, so we use offset 0 + exHubArray[0] = gcnew ExternalHubType(); + exHub = exHubArray[0]; + } + else + { + // The array was already present, we need to do elaborate things + // as array.resize does not work. + ArrayList ^exList = gcnew ArrayList(); + exList->AddRange(exHubArray); + exHub = gcnew ExternalHubType(); + exList->Add(exHub); + + if (rhParent != nullptr) + { + rhParent->ExternalHub = reinterpret_cast<array<ExternalHubType ^>^> (exList->ToArray(ExternalHubType::typeid)); + } + else + { + ehParent->ExternalHub = reinterpret_cast<array<ExternalHubType ^>^> (exList->ToArray(ExternalHubType::typeid)); + } + } + } + return exHub; +} +/***************************************************************************** + + NoDeviceType ^ AddDisconnectedPort(Object ^parent) + + This routine finds the type of the parent and adds a empty port connection object to the + parent's list of devices. The newly created object is returned + We are using arrays insted of better types of collections becaused the code generated + by xsd.exe does not support other types. + *****************************************************************************/ +NoDeviceType ^ AddDisconnectedPort(Object ^parent) +{ + RootHubType ^ rhParent = nullptr; + ExternalHubType ^ ehParent = nullptr; + array<NoDeviceType ^> ^ devicesArray = nullptr; + NoDeviceType ^ noD = nullptr; + boolean arrayCreated = false; + + // An external hub can be connected to a Root Hub or another External Hub + // We need to determine the type of the object. + + // Try RH first + + rhParent = dynamic_cast<RootHubType ^> (parent); + if (rhParent == nullptr) + { + // RootHub cast was not successfult, try external hub + ehParent = dynamic_cast<ExternalHubType ^> (parent); + if (ehParent != nullptr) + { + // External hub parent + if (ehParent->NoDevice == nullptr) + { + // First hub in the list of external hubs + ehParent->NoDevice = gcnew array<NoDeviceType ^> (1); + arrayCreated = true; + } + devicesArray = ehParent->NoDevice; + } + + } + else + { + // Parent is a root hub + if (rhParent->NoDevice == nullptr) + { + // First hub in root hub list + rhParent->NoDevice = gcnew array<NoDeviceType ^>(1); + arrayCreated = true; + } + devicesArray = rhParent->NoDevice; + } + + if (devicesArray != nullptr) + { + if (arrayCreated) + { + // We created the array in this function, so we use offset 0 + devicesArray[0] = gcnew NoDeviceType(); + noD = devicesArray[0]; + } + else + { + // The array was already present, we need to do elaborate things + // as array.resize does not work. + ArrayList ^exList = gcnew ArrayList(); + exList->AddRange(devicesArray); + noD = gcnew NoDeviceType(); + exList->Add(noD); + + if (rhParent != nullptr) + { + rhParent->NoDevice = reinterpret_cast<array<NoDeviceType ^>^> (exList->ToArray(NoDeviceType::typeid)); + } + else + { + ehParent->NoDevice = reinterpret_cast<array<NoDeviceType ^>^> (exList->ToArray(NoDeviceType::typeid)); + } + } + } + return noD; +} + +/***************************************************************************** + + UsbDeviceType ^ AddUsbDevice(Object ^parent) + + This routine finds the type of the parent and adds a port connection object to the + parent's list of port connectors. The newly created object is returned + We are using arrays insted of better types of collections becaused the code generated + by xsd.exe does not support other types. + *****************************************************************************/ +UsbDeviceType ^ AddUsbDevice(Object ^parent) +{ + RootHubType ^ rhParent = nullptr; + ExternalHubType ^ ehParent = nullptr; + array<UsbDeviceType ^> ^ devicesArray = nullptr; + UsbDeviceType ^ usbD = nullptr; + boolean arrayCreated = false; + + // An external hub can be connected to a Root Hub or another External Hub + // We need to determine the type of the object. + + // Try RH first + + rhParent = dynamic_cast<RootHubType ^> (parent); + if (rhParent == nullptr) + { + // RootHub cast was not successfult, try external hub + ehParent = dynamic_cast<ExternalHubType ^> (parent); + if (ehParent != nullptr) + { + // External hub parent + if (ehParent->UsbDevice == nullptr) + { + // First hub in the list of external hubs + ehParent->UsbDevice = gcnew array<UsbDeviceType ^> (1); + arrayCreated = true; + } + devicesArray = ehParent->UsbDevice; + } + + } + else + { + // Parent is a root hub + if (rhParent->UsbDevice == nullptr) + { + // First hub in root hub list + rhParent->UsbDevice = gcnew array<UsbDeviceType ^>(1); + arrayCreated = true; + } + devicesArray = rhParent->UsbDevice; + } + + if (devicesArray != nullptr) + { + if (arrayCreated) + { + // We created the array in this function, so we use offset 0 + devicesArray[0] = gcnew UsbDeviceType(); + usbD = devicesArray[0]; + } + else + { + // The array was already present, we need to do elaborate things + // as array.resize does not work. + ArrayList ^exList = gcnew ArrayList(); + exList->AddRange(devicesArray); + usbD = gcnew UsbDeviceType(); + exList->Add(usbD); + + if (rhParent != nullptr) + { + rhParent->UsbDevice = reinterpret_cast<array<UsbDeviceType ^>^> (exList->ToArray(UsbDeviceType::typeid)); + } + else + { + ehParent->UsbDevice = reinterpret_cast<array<UsbDeviceType ^>^> (exList->ToArray(UsbDeviceType::typeid)); + } + } + } + return usbD; +} + +/***************************************************************************** + + XmlAddIADDescriptor() + + This routine adds usb IAD descriptor + *****************************************************************************/ +void XmlAddIADDescriptor( + UsbDeviceIADDescriptorType ^ iadXmlDesc, + PUSB_IAD_DESCRIPTOR iadDesc, + PSTRING_DESCRIPTOR_NODE stringDesc, + int nInterfaces) +{ + if (NULL == iadDesc || NULL == stringDesc) + { + return; + } + + // Update structure fields + iadXmlDesc->BLength = iadDesc->bLength; + iadXmlDesc->BDescriptorType = iadDesc->bDescriptorType; + iadXmlDesc->BFirstInterface = iadDesc->bFirstInterface; + iadXmlDesc->BInterfaceCount = iadDesc->bInterfaceCount; + iadXmlDesc->BFunctionClass = iadDesc->bFunctionClass; + iadXmlDesc->BFunctionSubclass = iadDesc->bFunctionSubClass; + iadXmlDesc->BFunctionProtocol = iadDesc->bFunctionProtocol; + iadXmlDesc->IFunction = iadDesc->iFunction; + + // Validate fields + if (iadDesc->bInterfaceCount == 1) + { + iadXmlDesc->InterfaceError = gcnew String("ERROR: bInterfaceCount must be greater than 1"); + } + if (nInterfaces < iadDesc->bFirstInterface + iadDesc->bInterfaceCount) + { + iadXmlDesc->InterfaceError = gcnew String("ERROR: The total number of interfaces"); + iadXmlDesc->InterfaceError += nInterfaces; + iadXmlDesc->InterfaceError += " must be greater than or equal to the highest linked interface number (base "; + iadXmlDesc->InterfaceError += iadDesc->bFirstInterface; + iadXmlDesc->InterfaceError += " + count "; + iadXmlDesc->InterfaceError += iadDesc->bInterfaceCount; + iadXmlDesc->InterfaceError += " = "; + iadXmlDesc->InterfaceError += (iadDesc->bFirstInterface + iadDesc->bInterfaceCount); + iadXmlDesc->InterfaceError += " )"; + } + if (iadDesc->bFunctionClass == 0) + { + iadXmlDesc->FunctionClassError = gcnew String("ERROR: bFunctionClass contains an illegal value 0"); + } + + iadXmlDesc->FunctionDetails = XmlGetDeviceClass( + iadDesc->bFunctionClass, + iadDesc->bFunctionSubClass, + iadDesc->bFunctionProtocol); + + // Protocol check + if (iadDesc->bFunctionClass == USB_DEVICE_CLASS_VIDEO) + { + if (iadDesc->bFunctionProtocol != PC_PROTOCOL_UNDEFINED) + { + iadXmlDesc->Protocol= gcnew String("WARNING: Protocol must be set to PC_PROTOCOL_UNDEFINED"); + iadXmlDesc->Protocol+= " for this class but is set to: "; + iadXmlDesc->Protocol+= iadDesc->bFunctionProtocol; + } + else + { + iadXmlDesc->Protocol = gcnew String("PC_PROTOCOL_UNDEFINED protocol"); + } + } + + if (iadDesc->iFunction) + { + // Add String descriptor + iadXmlDesc->StringDesc = XmlGetStringDescriptor( + iadDesc->iFunction, + stringDesc, + false); + } + + return; +} + +/***************************************************************************** + + XmlAddOTGDescriptor() + + This routine adds usb OTG descriptor + *****************************************************************************/ +void XmlAddOTGDescriptor( + UsbDeviceOTGDescriptorType ^ otgXmlDesc, + PUSB_OTG_DESCRIPTOR otgDesc) +{ + if (NULL == otgDesc) + { + return; + } + + otgXmlDesc->BLength = otgDesc->bLength; + otgXmlDesc->BDescriptorType = otgDesc->bDescriptorType; + otgXmlDesc->BmAttributes = otgDesc->bmAttributes; + + // Add descriptive fields + switch (otgDesc->bmAttributes) + { + case 0: + break; + case 1: + otgXmlDesc->AttributesString = gcnew String("SRP support"); + break; + case 2: + otgXmlDesc->AttributesString = gcnew String("HNP support"); + break; + case 3: + otgXmlDesc->AttributesString = gcnew String("SRP and HNP support"); + break; + default: + otgXmlDesc->AttributesString = gcnew String("ERROR: bmAttributes bits 2-7 are reserved should be 0)"); + break; + } + return; +} + +/***************************************************************************** + + XmlAddHidDescriptor() + + This routine adds usb HID descriptor + *****************************************************************************/ +void XmlAddHidDescriptor( + UsbDeviceHidDescriptorType ^ hidXmlDesc, + PUSB_HID_DESCRIPTOR hidDesc + ) +{ + int i = 0; + + if (NULL == hidDesc) + { + return; + } + + hidXmlDesc->BLength = hidDesc->bLength; + hidXmlDesc->BDescriptorType = hidDesc->bDescriptorType; + hidXmlDesc->BcdHID = hidDesc->bcdHID; + hidXmlDesc->BCountryCode = hidDesc->bCountryCode; + hidXmlDesc->BNumDescriptors = hidDesc->bNumDescriptors; + + // Add optional descriptors + if (hidDesc->bNumDescriptors > 0) + { + hidXmlDesc->OptionalDescriptor = gcnew array <UsbDeviceHidOptionalDescriptorsType ^>(hidDesc->bNumDescriptors); + for(i=0; i < hidDesc->bNumDescriptors; i++) + { + hidXmlDesc->OptionalDescriptor[i] = gcnew UsbDeviceHidOptionalDescriptorsType(); + hidXmlDesc->OptionalDescriptor[i]->BDescriptorType = hidDesc->OptionalDescriptors[i].bDescriptorType; + hidXmlDesc->OptionalDescriptor[i]->WDescriptorLength = hidDesc->OptionalDescriptors[i].wDescriptorLength; + } + } + return; +} + +/***************************************************************************** + + XmlGetUnknownDescriptor() + + This routine gets a usb unknown descriptor object form unknown descriptor + *****************************************************************************/ +UsbDeviceUnknownDescriptorType ^ XmlGetUnknownDescriptor( + PUSB_COMMON_DESCRIPTOR unknownDesc + ) +{ + int i = 0; + UsbDeviceUnknownDescriptorType ^ unknownXmlDesc = nullptr; + + if (NULL == unknownDesc) + { + return nullptr; + } + + unknownXmlDesc = gcnew UsbDeviceUnknownDescriptorType(); + unknownXmlDesc->BLength = unknownDesc->bLength; + unknownXmlDesc->BDescriptorType = unknownDesc->bDescriptorType; + + // Add optional descriptors + if (unknownDesc->bLength > 0) + { + unknownXmlDesc->UnknownDescriptor = gcnew String("Unknown descriptor->"); + for(i=0; i < unknownDesc->bLength; i++) + { + unknownXmlDesc->UnknownDescriptor += String::Format("0x{0:X} ", ((PUCHAR) unknownDesc)[i]); + } + } + return unknownXmlDesc; +} + +/***************************************************************************** + + XmlAddEndpointDescriptor() + + This routine adds usb endpoint descriptor and verbose fields + *****************************************************************************/ +void XmlAddEndpointDescriptor( + EndpointDescriptorType ^usbXmlEndpointDescriptor, + PUSB_ENDPOINT_DESCRIPTOR endPointDescriptor, + UCHAR connectionSpeed + ) +{ + EndpointDescriptorType ^ue = usbXmlEndpointDescriptor; + ULONG maxBytes = endPointDescriptor->wMaxPacketSize & 0x7FF; + + // Add structure values + ue->Length = endPointDescriptor->bLength; + ue->DescriptorType = endPointDescriptor->bDescriptorType; + ue->EndpointAddress = endPointDescriptor->bEndpointAddress; + ue->Attributes = endPointDescriptor->bmAttributes; + ue->MaxPacketSize = endPointDescriptor->wMaxPacketSize; + + // Add verbose fields + ue->EndpointId = endPointDescriptor->bEndpointAddress & 0x0F; + + // Add endpoint direction + if (USB_ENDPOINT_DIRECTION_OUT(endPointDescriptor->bEndpointAddress)) + { + ue->EndpointDirection = gcnew String("Out"); + } + else if (USB_ENDPOINT_DIRECTION_IN(endPointDescriptor->bEndpointAddress)) + { + ue->EndpointDirection = gcnew String("In"); + } + + // Add endpoint type + switch (endPointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) + { + case USB_ENDPOINT_TYPE_CONTROL: + ue->EndpointType = gcnew String("Control Transfer Type"); + break; + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + switch (endPointDescriptor->bmAttributes & 0x0C) + { + case 0x00: + ue->EndpointType = gcnew String("Ischronous Transfer Type - No Synchronization"); + break; + + case 0x04: + ue->EndpointType = gcnew String("Ischronous Transfer Type - Asynchronous"); + break; + + case 0x08: + ue->EndpointType = gcnew String("Ischronous Transfer Type - Adaptive"); + break; + + case 0x0C: + ue->EndpointType = gcnew String("Ischronous Transfer Type - Synchronous"); + break; + } + break; + case USB_ENDPOINT_TYPE_BULK: + ue->EndpointType = gcnew String("Bulk Transfer Type"); + break; + + case USB_ENDPOINT_TYPE_INTERRUPT: + ue->EndpointType = gcnew String("Interrupt Transfer Type"); + break; + } + + // Add packet info + switch (connectionSpeed) + { + case UsbHighSpeed: + if (endPointDescriptor->bmAttributes & 1) { + ULONG transactions = ((endPointDescriptor->wMaxPacketSize & 0x1800) >> 11) + 1; + // Isoc or Interrupt endpoint + ue->EndpointPacketInfo = gcnew String( + transactions + " transactions per microframe, " + + maxBytes + " max bytes"); + } + else + { + // Bulk endpoint + ue->EndpointPacketInfo = gcnew String(maxBytes + " max bytes"); + } + break; + case UsbFullSpeed: + ue->EndpointPacketInfo = gcnew String(maxBytes + " max bytes"); + break; + default: + // Low or Invalid speed + ue->EndpointPacketInfo = gcnew String("Invalid bus speed"); + break; + } + + // Add validation + if (endPointDescriptor->wMaxPacketSize & 0xE000) + { + ue->EndpointPacketSizeValidation = gcnew String("ERROR: wMaxPacketSize bits 15-13 should be 0"); + } else if (connectionSpeed==UsbHighSpeed) + { + USHORT hsMux; + + hsMux = (endPointDescriptor->wMaxPacketSize >> 11) & 0x03; + + switch (endPointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) + { + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + case USB_ENDPOINT_TYPE_INTERRUPT: + switch (hsMux) { + case 0: + if ((maxBytes < 1) || (maxBytes > 1024)) + { + ue->EndpointPacketSizeValidation = gcnew String("ERROR: Invalid maximum packet size, should be between 1 and 1024"); + } + break; + + case 1: + if ((maxBytes < 513) || (maxBytes > 1024)) + { + ue->EndpointPacketSizeValidation = gcnew String("ERROR: Invalid maximum packet size, should be between 513 and 1024"); + } + break; + + case 2: + if ((maxBytes < 683) || (maxBytes > 1024)) + { + ue->EndpointPacketSizeValidation = gcnew String("ERROR: Invalid maximum packet size, should be between 683 and 1024"); + } + break; + + case 3: + ue->EndpointPacketSizeValidation = gcnew String("ERROR: Bits 12-11 set to reserved value\r\n"); + break; + } + } + } + + // Add interval + if (endPointDescriptor->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR)) + { + ue->Interval = endPointDescriptor->bInterval; + } + else + { + PUSB_ENDPOINT_DESCRIPTOR2 endpointDesc2 = (PUSB_ENDPOINT_DESCRIPTOR2) endPointDescriptor; + ue->WInterval = endpointDesc2->wInterval; + ue->SyncAddress = endpointDesc2->bSyncAddress; + } + return; +} + +/***************************************************************************** + + XmlAddPipeInformation() + + This routine adds all the pipe information for device + *****************************************************************************/ +void XmlAddPipeInformation( + array< UsbPipeInfoType ^> ^ usbXmlPipeInfoList, + PUSB_PIPE_INFO pipeInfo, + ULONG numPipes, + UCHAR connectionSpeed + ) +{ + ULONG i = 0; + + for(i = 0; i< numPipes; i++) + { + // Add all pipe in the list + usbXmlPipeInfoList[i] = gcnew UsbPipeInfoType(); + usbXmlPipeInfoList[i]->EndpointDescriptor = gcnew EndpointDescriptorType(); + XmlAddEndpointDescriptor( + usbXmlPipeInfoList[i]->EndpointDescriptor, + &pipeInfo[i].EndpointDescriptor, + connectionSpeed); + usbXmlPipeInfoList[i]->ScheduleOffset = pipeInfo->ScheduleOffset; + } + return; +} + +/***************************************************************************** + + XmlAddUsbDeviceDescriptor() + + This routine adds usb device descriptor + *****************************************************************************/ +void XmlAddUsbDeviceDescriptor( + UsbDeviceDescriptorType ^usbXmlDeviceDescriptor, + PUSB_DEVICE_DESCRIPTOR usbDeviceDescriptor) +{ + UsbDeviceDescriptorType ^ud = usbXmlDeviceDescriptor; + + // Map all fields explicitly + + ud->Length = usbDeviceDescriptor->bLength; + ud->DescriptorType = usbDeviceDescriptor->bDescriptorType; + ud->CdUSB= usbDeviceDescriptor->bcdUSB; + ud->DeviceClass = usbDeviceDescriptor->bDeviceClass; + ud->DeviceSubclass = usbDeviceDescriptor->bDeviceSubClass; + ud->DeviceProtocol = usbDeviceDescriptor->bDeviceProtocol; + ud->MaxPacketSize0 = usbDeviceDescriptor->bMaxPacketSize0; + ud->IdVendor = usbDeviceDescriptor->idVendor; + ud->IdProduct = usbDeviceDescriptor->idProduct ; + ud->CdDevice = usbDeviceDescriptor->bcdDevice; + ud->IManufacturer = usbDeviceDescriptor->iManufacturer; + ud->IProduct = usbDeviceDescriptor->iProduct; + ud->ISerialNumber = usbDeviceDescriptor->iSerialNumber; + ud->NumConfigurations = usbDeviceDescriptor->bNumConfigurations; + return; +} + +/***************************************************************************** + + XmlAddConfigurationDescriptor() + + This routine adds the configuration descriptor + *****************************************************************************/ +void XmlAddConfigurationDescriptor( + UsbConfigurationDescriptorType ^ confXmlDesc, + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDesc, + PSTRING_DESCRIPTOR_NODE stringDesc + ) + +{ + UINT uCount = 0; + BOOL isSuperSpeed = FALSE; + + if (NULL == configDesc || NULL == deviceInfo) + { + return; + } + + if(deviceInfo->ConnectionInfoV2 && + (deviceInfo->ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedOrHigher || + deviceInfo->ConnectionInfoV2->Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher)) + { + isSuperSpeed = TRUE; + } + + confXmlDesc->BLength = configDesc->bLength; + confXmlDesc->BDescriptorType = configDesc->bDescriptorType; + confXmlDesc->WTotalLength = configDesc->wTotalLength; + confXmlDesc->BNumInterfaces = configDesc->bNumInterfaces; + confXmlDesc->BConfigurationValue = configDesc->bConfigurationValue; + confXmlDesc->IConfiguration = configDesc->iConfiguration; + confXmlDesc->BmAttributes = configDesc->bmAttributes; + confXmlDesc->MaxPower = configDesc->MaxPower; + + uCount = GetConfigurationSize(deviceInfo); + + if (uCount != configDesc->wTotalLength) + { + confXmlDesc->ConfigDescError = gcnew String("ERROR: Invalid total configuration size " + + configDesc->wTotalLength + ", should be " + uCount); + } + + if (configDesc->bConfigurationValue != 1) + { + confXmlDesc->ConfValueError = gcnew String("CAUTION: Most host controllers will only work with one configuration per speed"); + } + + if (configDesc->iConfiguration) + { + confXmlDesc->ConfStringDesc = XmlGetStringDescriptor( + configDesc->iConfiguration, + stringDesc, + false); + } + + if (configDesc->bmAttributes & USB_CONFIG_BUS_POWERED) + { + confXmlDesc->AttributesStr = gcnew String("Bus Powered"); + } + else if (configDesc->bmAttributes & USB_CONFIG_SELF_POWERED) + { + confXmlDesc->AttributesStr = gcnew String("Self Powered"); + } + else if (configDesc->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) + { + confXmlDesc->AttributesStr = gcnew String("Remote Wakeup"); + } + else + { + confXmlDesc->AttributesStr = gcnew String("WARNING: bmAttributes is using reserved space"); + } + + confXmlDesc->MaxCurrent = gcnew String(""); + confXmlDesc->MaxCurrent += (isSuperSpeed?configDesc->MaxPower * 8:configDesc->MaxPower * 2); + confXmlDesc->MaxCurrent += " mA"; + + return; +} + +/***************************************************************************** + + XmlGetDeviceClass() + + This routine returns the interface class and subclass for given interface descriptor + *****************************************************************************/ +UsbDeviceClassType ^ XmlGetDeviceClass(UCHAR bInterfaceClass, UCHAR bInterfaceSubclass, UCHAR bInterfaceProtocol) +{ + String ^ deviceClass = nullptr; + String ^ deviceSubclass = nullptr; + UsbDeviceClassType ^ deviceDetails = gcnew UsbDeviceClassType(); + + switch (bInterfaceClass) + { + case USB_DEVICE_CLASS_AUDIO: + deviceClass = gcnew String("Audio Interface"); + + switch (bInterfaceSubclass) + { + case USB_AUDIO_SUBCLASS_AUDIOCONTROL: + deviceSubclass = gcnew String("Audio Control Interface"); + break; + + case USB_AUDIO_SUBCLASS_AUDIOSTREAMING: + deviceSubclass = gcnew String("Audio Streaming Interface"); + break; + + case USB_AUDIO_SUBCLASS_MIDISTREAMING: + deviceSubclass = gcnew String("MIDI Streaming Interface"); + break; + + default: + deviceSubclass = gcnew String("CAUTION: This appears to be an invalid bInterfaceSubclass : "); + deviceSubclass += bInterfaceSubclass; + break; + } + break; + + case USB_DEVICE_CLASS_VIDEO: + deviceClass = gcnew String("Video Interface"); + + switch(bInterfaceSubclass) + { + case VIDEO_SUBCLASS_CONTROL: + deviceSubclass = gcnew String("Video Control"); + break; + + case VIDEO_SUBCLASS_STREAMING: + deviceSubclass = gcnew String("Video Streaming"); + break; + + default: + deviceSubclass = gcnew String("CAUTION: This appears to be an invalid bInterfaceSubclass : "); + deviceSubclass += bInterfaceSubclass; + break; + } + break; + + case USB_DEVICE_CLASS_VENDOR_SPECIFIC: + deviceClass = gcnew String("Vendor Specific Device"); + break; + + case USB_DEVICE_CLASS_HUMAN_INTERFACE: + + deviceClass = gcnew String("HID Interface"); + break; + + case USB_DEVICE_CLASS_HUB: + deviceClass = gcnew String("HUB Interface"); + break; + + case USB_DEVICE_CLASS_RESERVED: + deviceClass = gcnew String("CAUTION: Reserved USB Device Interface Class"); + break; + + case USB_DEVICE_CLASS_COMMUNICATIONS: + deviceClass = gcnew String("Communications (CDC Control) USB Device\r\n"); + break; + + case USB_DEVICE_CLASS_MONITOR: + deviceClass = gcnew String("Monitor USB Device Interface Class*** (This may be obsolete)"); + break; + + case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: + deviceClass = gcnew String("Physical Interface USB Device"); + break; + + case USB_DEVICE_CLASS_POWER: + if (bInterfaceSubclass == 1 && bInterfaceProtocol == 1) + { + deviceClass = gcnew String("Image USB Device"); + } + else + { + deviceClass = gcnew String("Power USB Device (This may be obsolete)"); + } + break; + + case USB_DEVICE_CLASS_PRINTER: + deviceClass = gcnew String("Printer USB Device"); + break; + + case USB_DEVICE_CLASS_STORAGE: + deviceClass = gcnew String("Mass Storage USB Device"); + break; + + case USB_CDC_DATA_INTERFACE: + deviceClass = gcnew String("CDC Data USB Device"); + break; + + case USB_CHIP_SMART_CARD_INTERFACE: + deviceClass = gcnew String("Chip/Smart Card USB Device"); + break; + + case USB_CONTENT_SECURITY_INTERFACE: + deviceClass = gcnew String("Content Security USB Device"); + break; + + case USB_DIAGNOSTIC_DEVICE_INTERFACE: + if (bInterfaceSubclass == 1 && bInterfaceProtocol == 1) + { + deviceClass = gcnew String("Reprogrammable USB2 Compliance Diagnostic Device USB Device"); + } + else + { + deviceClass = gcnew String("CAUTION: This appears to be an invalid device class: "); + deviceClass += bInterfaceClass; + } + break; + + case USB_WIRELESS_CONTROLLER_INTERFACE: + if (bInterfaceSubclass == 1 && bInterfaceProtocol == 1) + { + deviceClass = gcnew String("Wireless RF Controller USB Device Interface Class with Bluetooth Programming Interface"); + } + else + { + deviceClass = gcnew String("CAUTION: This appears to be an invalid device class: "); + deviceClass += bInterfaceClass; + } + break; + + case USB_APPLICATION_SPECIFIC_INTERFACE: + deviceClass = gcnew String("Application Specific USB Device"); + + switch(bInterfaceSubclass) + { + case 1: + deviceSubclass = gcnew String("Device Firmware Application Specific USB Device"); + break; + case 2: + deviceSubclass = gcnew String("IrDA Bridge Application Specific USB Device"); + break; + case 3: + deviceSubclass = gcnew String("Test & Measurement Class (USBTMC) Application Specific USB Device"); + break; + default: + deviceSubclass = gcnew String("CAUTION: This appears to be an invalid bInterfaceSubclass : "); + deviceSubclass += bInterfaceSubclass; + } + break; + + default: + + deviceClass = gcnew String("Interface Class unknown : "); + deviceClass += bInterfaceClass; + break; + } + + // Return class and subclass + + deviceDetails->DeviceClass = deviceClass; + deviceDetails->DeviceSubclass = deviceSubclass; + + return deviceDetails; +} + +/***************************************************************************** + + XmlAddInterfaceDescriptor() + + This routine adds the device interface descriptor + *****************************************************************************/ +void XmlAddDeviceInterfaceDescriptor( + UsbDeviceInterfaceDescriptorType ^ ifXmlDesc, + PUSB_INTERFACE_DESCRIPTOR ifDesc, + PSTRING_DESCRIPTOR_NODE stringDesc) +{ + if (NULL == ifDesc || NULL == stringDesc) + { + return; + } + + // Update structure fields + ifXmlDesc->BLength = ifDesc->bLength; + ifXmlDesc->BDescriptorType = ifDesc->bDescriptorType; + ifXmlDesc->BInterfaceNumber = ifDesc->bInterfaceNumber; + ifXmlDesc->BAlternateSetting = ifDesc->bAlternateSetting; + ifXmlDesc->BNumEndpoints = ifDesc->bNumEndpoints; + ifXmlDesc->BInterfaceClass = ifDesc->bInterfaceClass; + ifXmlDesc->BInterfaceSubclass = ifDesc->bInterfaceSubClass; + ifXmlDesc->BInterfaceProtocol = ifDesc->bInterfaceProtocol; + ifXmlDesc->IInterface = ifDesc->iInterface; + + // Update class and sub class + ifXmlDesc->InterfaceDetails = XmlGetDeviceClass( + ifDesc->bInterfaceClass, + ifDesc->bInterfaceSubClass, + ifDesc->bInterfaceProtocol); + + //This is basically the check for PC_PROTOCOL_UNDEFINED + if ((ifDesc->bInterfaceClass == USB_DEVICE_CLASS_VIDEO) || + (ifDesc->bInterfaceClass == USB_DEVICE_CLASS_AUDIO)) + { + if (ifDesc->bInterfaceProtocol != PC_PROTOCOL_UNDEFINED) + { + ifXmlDesc->ProtocolError = gcnew String("WARNING: Protocol must be set to PC_PROTOCOL_UNDEFINED"); + ifXmlDesc->ProtocolError += " for this class but is set to: "; + ifXmlDesc->ProtocolError += ifDesc->bInterfaceProtocol; + } + } + + if (ifDesc->iInterface) + { + // Add String descriptor + ifXmlDesc->StringDesc = XmlGetStringDescriptor( + ifDesc->iInterface, + stringDesc, + false); + } + + if (ifDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR2)) + { + PUSB_INTERFACE_DESCRIPTOR2 interfaceDesc2; + + interfaceDesc2 = (PUSB_INTERFACE_DESCRIPTOR2)ifDesc; + + ifXmlDesc->WNumClasses = interfaceDesc2->wNumClasses; + } + return; +} + +/***************************************************************************** + + XmlAddDeviceQualDescriptor() + + This routine adds the device qualifier descriptor + *****************************************************************************/ + +void XmlAddDeviceQualDescriptor( + UsbDeviceQualifierDescriptorType ^ qualXmlDesc, + PUSB_DEVICE_QUALIFIER_DESCRIPTOR qualDesc) +{ + if (NULL == qualDesc) + { + return; + } + + // Add structure fields + qualXmlDesc->BLength = qualDesc->bLength; + qualXmlDesc->BDescriptorType = qualDesc->bDescriptorType; + qualXmlDesc->BcdUSB = qualDesc->bcdUSB; + qualXmlDesc->BDeviceClass = qualDesc->bDeviceClass; + qualXmlDesc->BDeviceSubclass = qualDesc->bDeviceSubClass; + qualXmlDesc->BDeviceProtocol = qualDesc->bDeviceProtocol; + qualXmlDesc->BMaxPacketSize0 = qualDesc->bMaxPacketSize0; + qualXmlDesc->NumConfigurations = qualDesc->bNumConfigurations; + + // Get device class string + qualXmlDesc->DeviceClass = XmlGetDeviceClassString(qualDesc->bDeviceClass); + + if (qualDesc->bDeviceSubClass > 0x00 && qualDesc->bDeviceSubClass < 0xFF) + { + qualXmlDesc->DeviceSubclassError = gcnew String("ERROR: bDeviceSubClass is invalid : "); + qualXmlDesc->DeviceSubclassError += qualDesc->bDeviceSubClass; + } + + if (qualDesc->bDeviceProtocol > 0x00 && qualDesc->bDeviceProtocol < 0xFF) + { + qualXmlDesc->DeviceProtocolError = gcnew String("ERROR: bDeviceProtocol is invalid : "); + qualXmlDesc->DeviceProtocolError += qualDesc->bDeviceProtocol; + } + + qualXmlDesc->MaxPacketSizeInBytes = qualDesc->bMaxPacketSize0; + + if (qualDesc->bNumConfigurations != 1) + { + qualXmlDesc->DeviceNumConfigError = gcnew String( + "CAUTION: Most host controllers will only work with one configuration per speed"); + } + + if (qualDesc->bReserved != 0) + { + qualXmlDesc->ReservedError = gcnew String("WARNING: bReserved needs to be set to 0 to be valid - " + + qualDesc->bReserved); + } + + return; +} + +/***************************************************************************** + + XmlAddAddConfigDescriptors() + + This routine adds the all the config descriptors + *****************************************************************************/ +array < UsbDeviceConfigurationType ^> ^ XmlGetConfigDescriptors( + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDescs, + PSTRING_DESCRIPTOR_NODE stringDesc + ) +{ + array < UsbDeviceConfigurationType ^> ^ confXmlDescs = nullptr; + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + PUCHAR descEnd = NULL; + ArrayList ^confList = gcnew ArrayList; + UsbDeviceConfigurationType ^ deviceConf = nullptr; + + commonDesc = (PUSB_COMMON_DESCRIPTOR) configDescs; + descEnd = (PUCHAR) configDescs + configDescs->wTotalLength; + + while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && + (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) + { + // Add the config descriptor + deviceConf = gcnew UsbDeviceConfigurationType(); + + XmlAddDeviceConfiguration( + deviceConf, + deviceInfo, + (PUSB_CONFIGURATION_DESCRIPTOR) commonDesc, + stringDesc, + configDescs->bNumInterfaces + ); + + confList->Add(deviceConf); + commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); + } + + confXmlDescs = reinterpret_cast<array<UsbDeviceConfigurationType ^>^> (confList->ToArray(UsbDeviceConfigurationType::typeid)); + return confXmlDescs; +} + +/***************************************************************************** + + XmlAddDeviceConfiguration() + + This routine adds the device configuration + *****************************************************************************/ +void XmlAddDeviceConfiguration( + UsbDeviceConfigurationType ^ confXmlDesc, + PUSBDEVICEINFO deviceInfo, + PUSB_CONFIGURATION_DESCRIPTOR configDesc, + PSTRING_DESCRIPTOR_NODE stringDesc, + int numInterfaces + ) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + UCHAR bInterfaceClass = 0; + UCHAR bInterfaceSubclass = 0; + UCHAR bInterfaceProtocol = 0; + BOOL displayUnknown = FALSE; + + if (NULL == deviceInfo || NULL == configDesc || NULL == stringDesc) + { + return; + } + + commonDesc = (PUSB_COMMON_DESCRIPTOR)configDesc; + displayUnknown = FALSE; + + switch (commonDesc->bDescriptorType) + { + case USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)) + { + // Validate descriptor + confXmlDesc->DeviceQualifierError = String::Format( + "ERROR: Device Qualifier bLength value incorrect Obtained: {0} Expected {1}", + commonDesc->bLength, + sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR)); + displayUnknown = TRUE; + break; + } + // Add device Qual descriptor + confXmlDesc->DeviceQualifierDescriptor = gcnew UsbDeviceQualifierDescriptorType(); + + XmlAddDeviceQualDescriptor( + confXmlDesc->DeviceQualifierDescriptor, + (PUSB_DEVICE_QUALIFIER_DESCRIPTOR) commonDesc); + break; + + case USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + // Validate descriptor + confXmlDesc->SpeedConfigurationError = String::Format( + "ERROR: Other speed configuration bLength value incorrect Obtained: {0} Expected {1}", + commonDesc->bLength, + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + displayUnknown = TRUE; + } + + // Add configuration desc + confXmlDesc->ConfigurationDescriptor = gcnew UsbConfigurationDescriptorType(); + + XmlAddConfigurationDescriptor( + confXmlDesc->ConfigurationDescriptor, + deviceInfo, + (PUSB_CONFIGURATION_DESCRIPTOR) commonDesc, + stringDesc); + break; + + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (commonDesc->bLength != sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + // Validate descriptor + confXmlDesc->SpeedConfigurationError = String::Format( + "ERROR: Configuration bLength value incorrect Obtained: {0} Expected {1}", + commonDesc->bLength, + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + displayUnknown = TRUE; + break; + } + + // Add configuration desc + confXmlDesc->ConfigurationDescriptor = gcnew UsbConfigurationDescriptorType(); + XmlAddConfigurationDescriptor( + confXmlDesc->ConfigurationDescriptor, + deviceInfo, + (PUSB_CONFIGURATION_DESCRIPTOR) commonDesc, + stringDesc); + break; + + case USB_INTERFACE_DESCRIPTOR_TYPE: + if ((commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR)) && + (commonDesc->bLength != sizeof(USB_INTERFACE_DESCRIPTOR2))) + { + // Validate descriptor + confXmlDesc->InterfaceError = String::Format( + "ERROR: Interface bLength value incorrect Obtained: {0} Expected: {1} or {2}", + commonDesc->bLength, + sizeof(USB_INTERFACE_DESCRIPTOR), + sizeof(USB_INTERFACE_DESCRIPTOR2)); + displayUnknown = TRUE; + break; + } + + // Add interface descriptor + bInterfaceClass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceClass; + bInterfaceSubclass = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceSubClass; + bInterfaceProtocol = ((PUSB_INTERFACE_DESCRIPTOR)commonDesc)->bInterfaceProtocol; + + confXmlDesc->InterfaceDescriptor = gcnew UsbDeviceInterfaceDescriptorType(); + XmlAddDeviceInterfaceDescriptor( + confXmlDesc->InterfaceDescriptor, + (PUSB_INTERFACE_DESCRIPTOR) commonDesc, + stringDesc + ); + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if ((commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR)) && + (commonDesc->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR2))) + { + // Validate endpoint descriptor + confXmlDesc->EndpointError = String::Format( + "ERROR: Endpoint bLength value incorrect Obtained: {0} Expected: {1} or {2}", + commonDesc->bLength, + sizeof(USB_ENDPOINT_DESCRIPTOR), + sizeof(USB_ENDPOINT_DESCRIPTOR2)); + displayUnknown = TRUE; + break; + } + + confXmlDesc->EndpointDescriptor = gcnew EndpointDescriptorType(); + + if (NULL != deviceInfo->ConnectionInfo) + { + // Add endpoint descriptor + XmlAddEndpointDescriptor( + confXmlDesc->EndpointDescriptor, + (PUSB_ENDPOINT_DESCRIPTOR) commonDesc, + deviceInfo->ConnectionInfo->Speed); + } + + break; + + case USB_HID_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_HID_DESCRIPTOR)) + { + // Validate HID + confXmlDesc->HidError = String::Format( + "ERROR: HID bLength value incorrect Obtained: {0} Expected: {1}", + commonDesc->bLength, + sizeof(USB_HID_DESCRIPTOR)); + displayUnknown = TRUE; + break; + } + + // Add HID descriptor + confXmlDesc->HidDescriptor = gcnew UsbDeviceHidDescriptorType(); + XmlAddHidDescriptor( + confXmlDesc->HidDescriptor, + (PUSB_HID_DESCRIPTOR) commonDesc + ); + break; + + case USB_OTG_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_OTG_DESCRIPTOR)) + { + // Validate length + confXmlDesc->HidError = String::Format( + "ERROR: OTG bLength value incorrect Obtained: {0} Expected: {1}", + commonDesc->bLength, + sizeof(USB_OTG_DESCRIPTOR)); + displayUnknown = TRUE; + break; + } + + // Add OTG descriptor + confXmlDesc->OtgDescriptor = gcnew UsbDeviceOTGDescriptorType(); + XmlAddOTGDescriptor( + confXmlDesc->OtgDescriptor, + (PUSB_OTG_DESCRIPTOR) commonDesc + ); + break; + + case USB_IAD_DESCRIPTOR_TYPE: + if (commonDesc->bLength < sizeof(USB_IAD_DESCRIPTOR)) + { + // Validate length + confXmlDesc->IadError = String::Format( + "ERROR: IAD bLength value incorrect", + commonDesc->bLength, + sizeof(USB_OTG_DESCRIPTOR)); + displayUnknown = TRUE; + } + + // Add IAD descriptor + confXmlDesc->IadDescriptor = gcnew UsbDeviceIADDescriptorType(); + XmlAddIADDescriptor( + confXmlDesc->IadDescriptor, + (PUSB_IAD_DESCRIPTOR) commonDesc, + stringDesc, + numInterfaces + ); + break; + + default: + // Interface class device (?) + confXmlDesc->DeviceDetails = XmlGetDeviceClass( + ((PUSB_INTERFACE_DESCRIPTOR) commonDesc)->bInterfaceClass, + ((PUSB_INTERFACE_DESCRIPTOR) commonDesc)->bInterfaceSubClass, + ((PUSB_INTERFACE_DESCRIPTOR) commonDesc)->bInterfaceProtocol + ); + break; + } + + if (displayUnknown) + { + // Add unknown descriptor + confXmlDesc->UnknownDescriptor = XmlGetUnknownDescriptor(commonDesc); + } + return; +} + +/***************************************************************************** + + XmlAddConnectionInfoSt() + + This routine adds connection information structures for the device + *****************************************************************************/ +void XmlAddConnectionInfoSt( + NodeConnectionInfoExStructType ^xmlConnectionInfoSt, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PDEVICE_INFO_NODE pNode) +{ + NodeConnectionInfoExStructType ^nS = xmlConnectionInfoSt; + + nS->ConnectionIndex = connectionInfo->ConnectionIndex; + + nS->DeviceDescriptor = gcnew UsbDeviceDescriptorType(); + + XmlAddUsbDeviceDescriptor(nS->DeviceDescriptor, &(connectionInfo->DeviceDescriptor)); + + nS->CurrentConfigurationValue = connectionInfo->CurrentConfigurationValue; + nS->Speed = connectionInfo->Speed; + nS->SpeedStr = static_cast<UsbConnectionSpeedType> (connectionInfo->Speed); + nS->DeviceIsHub = connectionInfo->DeviceIsHub? true: false; + nS->NumOfOpenPipes = connectionInfo->NumberOfOpenPipes; + nS->UsbConnectionStatus = static_cast<UsbConnectionStatusType> (connectionInfo->ConnectionStatus); + + if(NULL != pNode) + { + nS->DevicePowerState = static_cast<DevicePowerStateType>(pNode->LatestDevicePowerState); + } + else + { + nS->DevicePowerState = static_cast<DevicePowerStateType>(PowerDeviceUnspecified); + } + + // Add the pipe list + if (connectionInfo->NumberOfOpenPipes > 0) + { + nS->Pipe = gcnew array <UsbPipeInfoType ^>(connectionInfo->NumberOfOpenPipes); + XmlAddPipeInformation( + nS->Pipe, + connectionInfo->PipeList, + connectionInfo->NumberOfOpenPipes, + connectionInfo->Speed + ); + } + + return; +} + +/***************************************************************************** + + XmlGetLangIdString() + + Obtains the language string for given string descriptor index + *****************************************************************************/ +String ^ XmlGetLangIdString(UCHAR index, PSTRING_DESCRIPTOR_NODE stringDesc) +{ + String ^langIdStr = nullptr; + bool foundDescriptor = false; + + while(stringDesc) + { + if (stringDesc->DescriptorIndex == index) + { + langIdStr = PACHAR_TO_STRING(GetLangIDString(stringDesc->LanguageID)); + + if (langIdStr == nullptr) + { + langIdStr = gcnew String("WARNING: Invalid language ID: " + stringDesc->LanguageID); + } + foundDescriptor = true; + break; + } + stringDesc = stringDesc->Next; + } + + if (foundDescriptor == false) + { + // If no descriptor was found, return error message in field + langIdStr = gcnew String("ERROR: No String descriptor for index " + index); + } + + return langIdStr; +} + +/***************************************************************************** + + XmlGetStringDescriptor() + + Obtains the string descriptor for given string descriptor index + *****************************************************************************/ + +String ^ XmlGetStringDescriptor(UCHAR index, PSTRING_DESCRIPTOR_NODE stringDesc, bool enOnly) +{ + ULONG nBytes = 0; + + CHAR pString[MAX_STRING_DESCRIPTOR_LENGTH]; + String ^desc = nullptr; + bool foundDescriptor = false; + bool foundNonEnglishDescriptor = false; + + ZeroMemory(pString, MAX_STRING_DESCRIPTOR_LENGTH); + + while(stringDesc) + { + if (stringDesc->DescriptorIndex == index) + { + if (enOnly && stringDesc->LanguageID != STRING_DESCRIPTOR_EN_LANGUAGE_ID) + { + // If we are required to return only english descriptor, continue + foundNonEnglishDescriptor = true; + continue; + } + + nBytes = WideCharToMultiByte( + CP_ACP, + WC_NO_BEST_FIT_CHARS, + stringDesc->StringDescriptor->bString, + (stringDesc->StringDescriptor->bLength -2)/2, + pString, + MAX_STRING_DESCRIPTOR_LENGTH, + NULL, + NULL + ); + + if (nBytes) + { + foundDescriptor = true; + desc = PACHAR_TO_STRING(pString); + } + break; + } + stringDesc = stringDesc->Next; + } + + if ((foundDescriptor == false) && (foundNonEnglishDescriptor == false)) + { + // If no descriptor was found, return error message in field + desc = gcnew String("ERROR: No String descriptor for index " + + index); + } + else if ((foundDescriptor == false) && (foundNonEnglishDescriptor == true) && (enOnly)) + { + desc = gcnew String("ERROR: The index " + index + " does not support English(US)"); + } + + return desc; +} + +/***************************************************************************** + + XmlGetDeviceClassString() + + Returns the device class string for given device class ID + *****************************************************************************/ + +String ^ XmlGetDeviceClassString(UCHAR deviceClass) +{ + String ^ deviceClassStr = nullptr; + + // Not an IAD device + switch (deviceClass) + { + case USB_INTERFACE_CLASS_DEVICE: + deviceClassStr = gcnew String("Interface Class Defined Device"); + break; + + case USB_COMMUNICATION_DEVICE: + deviceClassStr = gcnew String("Communication Device"); + break; + + case USB_HUB_DEVICE: + deviceClassStr = gcnew String("Hub Device"); + break; + + case USB_DIAGNOSTIC_DEVICE: + deviceClassStr = gcnew String("Diagnostic Device"); + break; + + case USB_WIRELESS_CONTROLLER_DEVICE: + deviceClassStr = gcnew String("Wireless Controller(Bluetooth) Device"); + break; + + case USB_VENDOR_SPECIFIC_DEVICE: + deviceClassStr = gcnew String("Vendor specific device"); + break; + + default: + deviceClassStr= gcnew String("ERROR: unknown bDeviceClass" + deviceClass); + break; + } + return deviceClassStr; +} + + +/***************************************************************************** + + XmlAddDeviceClassDetails() + + This routine adds device class details + *****************************************************************************/ +bool XmlAddDeviceClassDetails( + UsbDeviceClassDetailsType ^ deviceDetails, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PUSBDEVICEINFO deviceInfo) +{ + UINT uIADcount = 0; + bool tog = true; + + uIADcount = IsIADDevice((PUSBDEVICEINFO) deviceInfo); + + if (uIADcount) + { + // IAD device, check validity of device class + if (connectionInfo->DeviceDescriptor.bDeviceClass == USB_MISCELLANEOUS_DEVICE) + { + tog = false; + deviceDetails->DeviceType = gcnew String("Multi-interface Function Code Device"); + } + else { + deviceDetails->DeviceTypeError = gcnew String("ERROR: device class should be Multi-interface Function " + + USB_MISCELLANEOUS_DEVICE + + "is used"); + } + deviceDetails->UvcVersion = IsUVCDevice((PUSBDEVICEINFO) deviceInfo); + + // This device configuration has 1 or more IAD descriptors + if (connectionInfo->DeviceDescriptor.bDeviceSubClass == USB_COMMON_SUB_CLASS) + { + deviceDetails->SubclassType = gcnew String("Common Class Sub Class"); + } + else + { + deviceDetails->SubclassTypeError = gcnew String("ERROR: device SubClass should be USB Common Sub Class" + + USB_COMMON_SUB_CLASS + + " when IAD descriptor is used"); + } + + // Check device protocol + if (connectionInfo->DeviceDescriptor.bDeviceProtocol == USB_IAD_PROTOCOL) + { + deviceDetails->DeviceProtocol = gcnew String("Interface Association Descriptor protocol"); + } + else + { + deviceDetails->DeviceProtocolError = gcnew String("ERROR: device Protocol should be USB IAD Protocol " + + USB_IAD_PROTOCOL + + " when IAD descriptor is used"); + } + + } + else + { + deviceDetails->DeviceType = XmlGetDeviceClassString(connectionInfo->DeviceDescriptor.bDeviceClass); + + if (connectionInfo->DeviceDescriptor.bDeviceClass == USB_MISCELLANEOUS_DEVICE) + { + deviceDetails->DeviceTypeError = gcnew String("ERROR: Multi-interface Function code " + + connectionInfo->DeviceDescriptor.bDeviceClass + + " used for device with no IAD descriptors"); + } + + if (connectionInfo->DeviceDescriptor.bDeviceClass == USB_COMMUNICATION_DEVICE || + connectionInfo->DeviceDescriptor.bDeviceClass == USB_HUB_DEVICE || + connectionInfo->DeviceDescriptor.bDeviceClass == USB_DIAGNOSTIC_DEVICE || + connectionInfo->DeviceDescriptor.bDeviceClass == USB_WIRELESS_CONTROLLER_DEVICE || + connectionInfo->DeviceDescriptor.bDeviceClass == USB_MISCELLANEOUS_DEVICE || + connectionInfo->DeviceDescriptor.bDeviceClass == USB_VENDOR_SPECIFIC_DEVICE) + { + tog = false; + } + + // Not an IAD device, so all subclass values are invalid + if (connectionInfo->DeviceDescriptor.bDeviceSubClass > 0x00 && + connectionInfo->DeviceDescriptor.bDeviceSubClass < 0xFF) + { + deviceDetails->SubclassTypeError = gcnew String("ERROR: bDeviceSubClass is invalid - " + + connectionInfo->DeviceDescriptor.bDeviceSubClass); + } + + // Not an IAD device, so all subclass values are invalid, check protocol + if (connectionInfo->DeviceDescriptor.bDeviceProtocol > 0x00 && + connectionInfo->DeviceDescriptor.bDeviceProtocol < 0xFF && tog==1) + { + deviceDetails->DeviceProtocolError = gcnew String("ERROR: bDeviceProtocol is invalid - " + + connectionInfo->DeviceDescriptor.bDeviceProtocol); + } + } + + return tog; +} + +/***************************************************************************** + + XmlAddConnectionInfo() + + This routine adds connection information for the device + *****************************************************************************/ +void XmlAddConnectionInfo( + NodeConnectionInfoExType ^xmlConnectionInfo, + PUSB_NODE_CONNECTION_INFORMATION_EX connectionInfo, + PUSBDEVICEINFO deviceInfo, + PSTRING_DESCRIPTOR_NODE stringDesc, + PDEVICE_INFO_NODE pNode) +{ + NodeConnectionInfoExType ^ nc = xmlConnectionInfo; + bool tog = true; + nc->ConnectionInfoStruct = gcnew NodeConnectionInfoExStructType(); + + // Update the structure + XmlAddConnectionInfoSt(nc->ConnectionInfoStruct, connectionInfo, pNode); + + // Add verbose fields + if (connectionInfo->ConnectionStatus == NoDeviceConnected) + { + // No device connected, nothing to do + return; + } + + if (connectionInfo->DeviceDescriptor.iProduct) + { + // Add EN version of string descriptor + + nc->IProductStringDescEn = XmlGetStringDescriptor( + connectionInfo->DeviceDescriptor.iProduct, + stringDesc, + true); + } + + // Check open pipes count + if (connectionInfo->NumberOfOpenPipes == 0) + { + nc->PipeInfoError = gcnew String("ERROR: No open pipes"); + } + + // Check device descriptor length + if (connectionInfo->DeviceDescriptor.bLength != DEVICE_DESCRIPTOR_LENGTH) + { + nc->LengthError = gcnew String("ERROR: bLength " + + connectionInfo->DeviceDescriptor.bLength + + " incorrect, should be " + + DEVICE_DESCRIPTOR_LENGTH + ); + } + + // Check for device error + if ((connectionInfo->ConnectionStatus == DeviceFailedEnumeration) || + (connectionInfo->ConnectionStatus == DeviceGeneralFailure)) + { + nc->DeviceError = gcnew String("ERROR: Device enumeration failure"); + } + else + { + nc->DeviceClassDetails = gcnew UsbDeviceClassDetailsType(); + + // Add device class details + tog = XmlAddDeviceClassDetails( + nc->DeviceClassDetails, + connectionInfo, + deviceInfo); + + nc->MaxPacketSizeInBytes = connectionInfo->DeviceDescriptor.bMaxPacketSize0; + + // Validate speed + switch (connectionInfo->Speed) + { + case UsbLowSpeed: + if (connectionInfo->DeviceDescriptor.bMaxPacketSize0 != 8) + { + nc->PacketSizeError = gcnew String("ERROR: Low Speed Devices require bMaxPacketSize0 = 8"); + } + break; + case UsbFullSpeed: + if (!(connectionInfo->DeviceDescriptor.bMaxPacketSize0 == 8 || + connectionInfo->DeviceDescriptor.bMaxPacketSize0 == 16 || + connectionInfo->DeviceDescriptor.bMaxPacketSize0 == 32 || + connectionInfo->DeviceDescriptor.bMaxPacketSize0 == 64)) + { + nc->PacketSizeError = gcnew String("ERROR: Full Speed Devices require bMaxPacketSize0 = 8, 16, 32, or 64"); + } + break; + case UsbHighSpeed: + if (connectionInfo->DeviceDescriptor.bMaxPacketSize0 != 64) + { + nc->PacketSizeError = gcnew String("ERROR: High Speed Devices require bMaxPacketSize0 = 64"); + } + break; + } + + // Get string descriptors + nc->VendorString = PACHAR_TO_STRING(GetVendorString(connectionInfo->DeviceDescriptor.idVendor)); + + nc->ManufacturerString = XmlGetStringDescriptor(connectionInfo->DeviceDescriptor.iManufacturer, stringDesc, false); + nc->ProductString = XmlGetStringDescriptor(connectionInfo->DeviceDescriptor.iProduct, stringDesc, false); + nc->LangIdString = XmlGetLangIdString(connectionInfo->DeviceDescriptor.iProduct, stringDesc); + nc->SerialString = XmlGetStringDescriptor(connectionInfo->DeviceDescriptor.iSerialNumber, stringDesc, false); + + // Validate configuration + if (connectionInfo->DeviceDescriptor.bNumConfigurations != 1) + { + nc->ConfigurationCountError = gcnew String("WARNING: Most host controllers will only work with "\ + "one configuration per speed"); + } + } + return; +} + + +/***************************************************************************** + + XmlAddExternalHub() + + Add a external to the parent Host Controller or hub. This is determined by the + last object pushed on the stack + *****************************************************************************/ +HRESULT XmlAddExternalHub(PSTR ehName, PUSBEXTERNALHUBINFO ehInfo) +{ + HRESULT hr = S_OK; + Object ^ parent = gXmlStack->Peek(); + ExternalHubType ^exHub = nullptr; + + UNREFERENCED_PARAMETER(ehName); + + if (NULL == ehInfo) + { + return E_FAIL; + } + + exHub = AddExternalHub(parent); + + if (exHub != nullptr) + { + exHub->HubName = PACHAR_TO_STRING(ehInfo->HubName); + + if (NULL != ehInfo->UsbDeviceProperties) + { + exHub->HwId = PACHAR_TO_STRING(ehInfo->UsbDeviceProperties->HwId); + exHub->DeviceId = PACHAR_TO_STRING(ehInfo->UsbDeviceProperties->DeviceId); + exHub->ServiceName = PACHAR_TO_STRING(ehInfo->UsbDeviceProperties->Service); + exHub->DeviceName = PACHAR_TO_STRING(ehInfo->UsbDeviceProperties->DeviceDesc); + exHub->DeviceClass = PACHAR_TO_STRING(ehInfo->UsbDeviceProperties->DeviceClass); + } + + exHub->HubNodeInformation = gcnew HubNodeInformationType(); + XmlAddHubNodeInformation(exHub->HubNodeInformation, ehInfo->HubInfo); + + exHub->HubInformationEx = gcnew HubInformationExType(); + XmlAddHubInformationEx(exHub->HubInformationEx, ehInfo->HubInfoEx); + + exHub->HubCapabilityEx = gcnew HubCapabilitiesExType(); + XmlAddHubCapabilitiesEx(exHub->HubCapabilityEx, ehInfo->HubCapabilityEx); + + exHub->ConnectionInfo = gcnew NodeConnectionInfoExType(); + + // Update protocol + if (NULL != ehInfo->ConnectionInfo) + { + switch(ehInfo->ConnectionInfo->Speed) + { + case UsbLowSpeed: + case UsbFullSpeed: + exHub->UsbProtocol = gcnew String(USB_1_1); + break; + case UsbHighSpeed: + exHub->UsbProtocol = gcnew String(USB_2_0); + break; + case UsbSuperSpeed: + exHub->UsbProtocol = gcnew String(USB_3_0); + break; + } + } + + // Add connection info + XmlAddConnectionInfo( + exHub->ConnectionInfo, + ehInfo->ConnectionInfo, + (PUSBDEVICEINFO) ehInfo, + ehInfo->StringDescs, + ehInfo->DeviceInfoNode + ); + + // Add port connectors + if (NULL != ehInfo->PortConnectorProps) + { + exHub->PortConnector = gcnew PortConnectorType(); + + XmlAddPortConnectorProps( + exHub->PortConnector, + ehInfo->PortConnectorProps + ); + } + // Add connection info V2 + exHub->ConnectionInfoV2 = gcnew NodeConnectionInfoExV2Type(); + + XmlAddConnectionInfoV2( + exHub->ConnectionInfoV2, + ehInfo->ConnectionInfoV2 + ); + + // Add configuration descriptor + if (NULL != ehInfo->ConfigDesc) + { + exHub->DeviceConfiguration = XmlGetConfigDescriptors( + (PUSBDEVICEINFO) ehInfo, + (PUSB_CONFIGURATION_DESCRIPTOR) (ehInfo->ConfigDesc + 1), + ehInfo->StringDescs + ); + } + + // Add BOS descriptor + if (NULL != ehInfo->BosDesc) + { + exHub->BosDescriptor = XmlGetBosDescriptor((PUSB_BOS_DESCRIPTOR) (ehInfo->BosDesc + 1)); + } + + gXmlStack->Push(exHub); + } + else + { + hr = E_FAIL; + } + return hr; +} + +/***************************************************************************** + + XmlGetBosDescriptor() + + Gets the Bos descriptor object for given BOS descriptor + *****************************************************************************/ +UsbBosDescriptorType ^ XmlGetBosDescriptor(PUSB_BOS_DESCRIPTOR bosDesc) +{ + PUSB_COMMON_DESCRIPTOR commonDesc = NULL; + PUSB_DEVICE_CAPABILITY_DESCRIPTOR capDesc = NULL; + UsbBosDescriptorType ^ bosXmlDesc = nullptr; + ArrayList ^usb20CapExtDescList = gcnew ArrayList(); + ArrayList ^usbSuperSpeedExtDescList = gcnew ArrayList(); + ArrayList ^usbContIdCapExtDescList = gcnew ArrayList(); + ArrayList ^usbUnknownDescList = gcnew ArrayList(); + + if(NULL == bosDesc) + { + return nullptr; + } + + // Initialize attributes + bosXmlDesc = gcnew UsbBosDescriptorType(); + bosXmlDesc->BLength = bosDesc->bLength; + bosXmlDesc->BDescriptorType = bosDesc->bDescriptorType; + bosXmlDesc->WTotalLength = bosDesc->wTotalLength; + bosXmlDesc->BNumDeviceCaps = bosDesc->bNumDeviceCaps; + + commonDesc = (PUSB_COMMON_DESCRIPTOR) bosDesc; + + while ((commonDesc = GetNextDescriptor((PUSB_COMMON_DESCRIPTOR) bosDesc, + bosDesc->wTotalLength, + commonDesc, + -1)) != NULL) + { + switch (commonDesc->bDescriptorType) + { + case USB_DEVICE_CAPABILITY_DESCRIPTOR_TYPE: + capDesc = (PUSB_DEVICE_CAPABILITY_DESCRIPTOR)commonDesc; + switch (capDesc->bDevCapabilityType) + { + case USB_DEVICE_CAPABILITY_USB20_EXTENSION: + usb20CapExtDescList->Add( + XmlGetUsb20CapabilityExtensionDescriptor( + (PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR)capDesc + ) + ); + break; + case USB_DEVICE_CAPABILITY_SUPERSPEED_USB: + usbSuperSpeedExtDescList->Add( + XmlGetSuperSpeedCapabilityExtensionDescriptor( + (PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR)capDesc + ) + ); + break; + case USB_DEVICE_CAPABILITY_CONTAINER_ID: + usbContIdCapExtDescList->Add( + XmlGetContainerIdCapabilityExtensionDescriptor( + (PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR)capDesc + ) + ); + break; + default: + usbUnknownDescList->Add( + XmlGetUnknownDescriptor( + (PUSB_COMMON_DESCRIPTOR) capDesc + ) + ); + break; + } + break; + default: + usbUnknownDescList->Add(XmlGetUnknownDescriptor(commonDesc)); + break; + } + } + + // Convert lists to arrays for and add to Bos Descriptor + bosXmlDesc->UnknownDescriptor = reinterpret_cast<array<UsbDeviceUnknownDescriptorType ^>^> ( + usbUnknownDescList->ToArray(UsbDeviceUnknownDescriptorType::typeid) + ); + bosXmlDesc->UsbSuperSpeedExtensionDescriptor = reinterpret_cast<array<UsbSuperSpeedExtensionDescriptorType ^>^> ( + usbSuperSpeedExtDescList->ToArray(UsbSuperSpeedExtensionDescriptorType::typeid) + ); + bosXmlDesc->UsbUsb20ExtensionDescriptor = reinterpret_cast<array<UsbUsb20ExtensionDescriptorType ^>^> ( + usb20CapExtDescList->ToArray(UsbUsb20ExtensionDescriptorType::typeid) + ); + bosXmlDesc->UsbDispContIdCapExtDescriptor = reinterpret_cast<array<UsbDispContIdCapExtDescriptorType ^>^> ( + usbContIdCapExtDescList->ToArray(UsbDispContIdCapExtDescriptorType::typeid) + ); + + return bosXmlDesc; +} + + +/***************************************************************************** + + XmlGetUsb20CapabilityExtensionDescriptor() + + Gets a Usb20Capability extension descriptor object from the given descriptor + *****************************************************************************/ +UsbUsb20ExtensionDescriptorType ^ XmlGetUsb20CapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR capDesc + ) +{ + UsbUsb20ExtensionDescriptorType ^ capXmlDesc = nullptr; + + if(NULL == capDesc) + { + return nullptr; + } + + capXmlDesc = gcnew UsbUsb20ExtensionDescriptorType(); + + capXmlDesc->BLength = capDesc->bLength; + capXmlDesc->BDescriptorType = capDesc->bDescriptorType; + capXmlDesc->BDevCapabilityType = capDesc->bDevCapabilityType; + capXmlDesc->BmAttributes = capDesc->bmAttributes.AsUlong; + + if (capDesc->bmAttributes.AsUlong & USB_DEVICE_CAPABILITY_USB20_EXTENSION_BMATTRIBUTES_RESERVED_MASK) + { + capXmlDesc->ReservedBitError = gcnew String("ERROR: bits 31..2 and bit 0 are reserved and must be 0"); + } + if (capDesc->bmAttributes.LPMCapable == 1) + { + capXmlDesc->SupportsLinkPowerManagement = true; + } + + return capXmlDesc; +} + +/***************************************************************************** + + XmlGetSuperSpeedCapabilityExtensionDescriptor() + + Gets a Super speed capability extension descriptor object from the given descriptor + *****************************************************************************/ +UsbSuperSpeedExtensionDescriptorType ^ XmlGetSuperSpeedCapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR capDesc + ) +{ + UsbSuperSpeedExtensionDescriptorType ^ capXmlDesc = nullptr; + + if(NULL == capDesc) + { + return nullptr; + } + + capXmlDesc = gcnew UsbSuperSpeedExtensionDescriptorType(); + + capXmlDesc->BLength = capDesc->bLength; + capXmlDesc->BDescriptorType = capDesc->bDescriptorType; + capXmlDesc->BDevCapabilityType = capDesc->bDevCapabilityType; + capXmlDesc->BmAttributes = capDesc->bmAttributes; + capXmlDesc->BU1DevExitLat = capDesc->bU1DevExitLat; + capXmlDesc->WSpeedsSupported = capDesc->wSpeedsSupported; + capXmlDesc->WU2DevExitLat = capDesc->wU2DevExitLat; + capXmlDesc->BFunctionalitySupport = capDesc->bFunctionalitySupport; + + // Add descriptive fields + if (capDesc->bmAttributes & USB_DEVICE_CAPABILITY_SUPERSPEED_BMATTRIBUTES_RESERVED_MASK) + { + capXmlDesc->ReservedAttributesBitError = gcnew String("ERROR: bits 7:2 and bit 0 are reserved"); + } + if (capDesc->bmAttributes & USB_DEVICE_CAPABILITY_SUPERSPEED_BMATTRIBUTES_LTM_CAPABLE) + { + capXmlDesc->LatencyToleranceMsgCapable = true; + } + if (capDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_LOW) + { + capXmlDesc->SupportsLowSpeed = true; + } + if (capDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_FULL) + { + capXmlDesc->SupportsFullSpeed = true; + } + if (capDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_HIGH) + { + capXmlDesc->SupportsHighSpeed = true; + } + if (capDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_SUPER) + { + capXmlDesc->SupportsSuperSpeed = true; + } + if (capDesc->wSpeedsSupported & USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_RESERVED_MASK) + { + capXmlDesc->ReservedSpeedError = gcnew String("ERROR: bits 15:4 are reserved"); + } + + + switch (capDesc->bFunctionalitySupport) + { + case UsbLowSpeed: + capXmlDesc->LowestSpeed = gcnew String("low-speed"); + break; + case UsbFullSpeed: + capXmlDesc->LowestSpeed = gcnew String("full-speed"); + break; + case UsbHighSpeed: + capXmlDesc->LowestSpeed = gcnew String("high-speed"); + break; + case UsbSuperSpeed: + capXmlDesc->LowestSpeed = gcnew String("SuperSpeed"); + break; + default: + capXmlDesc->LowestSpeed = gcnew String("ERROR: Invalid value"); + break; + } + + if (capDesc->bU1DevExitLat <= USB_DEVICE_CAPABILITY_SUPERSPEED_U1_DEVICE_EXIT_MAX_VALUE) + { + capXmlDesc->U1DevExitLatencyString = String::Format("Less than {0} micro-seconds", capDesc->bU1DevExitLat); + } + else + { + capXmlDesc->U1DevExitLatencyString = gcnew String("ERROR: Invalid value"); + } + + if (capDesc->wU2DevExitLat <= USB_DEVICE_CAPABILITY_SUPERSPEED_U2_DEVICE_EXIT_MAX_VALUE) + { + capXmlDesc->U2DevExitLatencyString = String::Format("Less than {0} micro-seconds", capDesc->wU2DevExitLat); + } + else + { + capXmlDesc->U2DevExitLatencyString = gcnew String("ERROR: Invalid value"); + } + + return capXmlDesc; +} + +/***************************************************************************** + + XmlGetContainerIdCapabilityExtensionDescriptor() + + Gets a Usb20Capability extension descriptor object from the given descriptor + *****************************************************************************/ +UsbDispContIdCapExtDescriptorType ^ XmlGetContainerIdCapabilityExtensionDescriptor( + PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR capDesc + ) +{ + UsbDispContIdCapExtDescriptorType ^ capXmlDesc = nullptr; + LPGUID pGuid = NULL; + + if(NULL == capDesc) + { + return nullptr; + } + + capXmlDesc = gcnew UsbDispContIdCapExtDescriptorType(); + + capXmlDesc->BLength = capDesc->bLength; + capXmlDesc->BDescriptorType = capDesc->bDescriptorType; + capXmlDesc->BDevCapabilityType = capDesc->bDevCapabilityType; + capXmlDesc->BReserved = capDesc->bReserved; + + if (capDesc->bReserved != 0) + { + capXmlDesc->ReservedBitError = gcnew String("ERROR: field is reserved and should be zero"); + } + + pGuid = (LPGUID) capDesc->ContainerID; + + capXmlDesc->ContainerIdStr = String::Format("{0:X}-{1:X}-{2:X}-{3:X}{4:X}-{5:X}{6:X}{7:X}{8:X}{9:X}{10:X}", + pGuid->Data1, + pGuid->Data2, + pGuid->Data3, + pGuid->Data4[0], + pGuid->Data4[1], + pGuid->Data4[2], + pGuid->Data4[3], + pGuid->Data4[4], + pGuid->Data4[5], + pGuid->Data4[6], + pGuid->Data4[7]); + + return capXmlDesc; +} + +/***************************************************************************** + + XmlAddUsbDevice() + + Add a external to the parent Host Controller or hub. This is determined by the + last object pushed on the stack + *****************************************************************************/ +HRESULT XmlAddUsbDevice(PSTR devName, PUSBDEVICEINFO deviceInfo) +{ + HRESULT hr = S_OK; + Object ^ parent = gXmlStack->Peek(); + UsbDeviceType ^usbDevice = nullptr; + NoDeviceType ^noDevice = nullptr; + + if (NULL == deviceInfo) + { + return E_FAIL; + } + + if (deviceInfo->ConfigDesc == NULL) + { + // There is no USB device on this port, add a NoDevice type here instead of USB device + noDevice = AddDisconnectedPort(parent); + + if (nullptr != noDevice) + { + noDevice->UsbPortNumber = gcnew String(""); + noDevice->UsbPortNumber += deviceInfo->ConnectionInfo->ConnectionIndex; + noDevice->Name = PACHAR_TO_STRING(devName); + } + else + { + hr = E_FAIL; + } + } + + else + { + usbDevice = AddUsbDevice(parent); + + if (nullptr != usbDevice) + { + // Update device information + if (NULL != deviceInfo->UsbDeviceProperties) + { + usbDevice->HwId = PACHAR_TO_STRING(deviceInfo->UsbDeviceProperties->HwId); + usbDevice->DeviceId = PACHAR_TO_STRING(deviceInfo->UsbDeviceProperties->DeviceId); + usbDevice->ServiceName = PACHAR_TO_STRING(deviceInfo->UsbDeviceProperties->Service); + usbDevice->DeviceName = PACHAR_TO_STRING(deviceInfo->UsbDeviceProperties->DeviceDesc); + usbDevice->DeviceClass = PACHAR_TO_STRING(deviceInfo->UsbDeviceProperties->DeviceClass); + } + + // Update port number + usbDevice->UsbPortNumber = gcnew String(""); + usbDevice->UsbPortNumber += deviceInfo->ConnectionInfo->ConnectionIndex; + usbDevice->ConnectionInfo = gcnew NodeConnectionInfoExType(); + + // Update protocol + if (NULL != deviceInfo->ConnectionInfo) + { + switch(deviceInfo->ConnectionInfo->Speed) + { + case UsbLowSpeed: + case UsbFullSpeed: + usbDevice->UsbProtocol = gcnew String(USB_1_1); + break; + case UsbHighSpeed: + usbDevice->UsbProtocol = gcnew String(USB_2_0); + break; + case UsbSuperSpeed: + usbDevice->UsbProtocol = gcnew String(USB_3_0); + break; + } + } + + // Add connection info + XmlAddConnectionInfo( + usbDevice->ConnectionInfo, + deviceInfo->ConnectionInfo, + (PUSBDEVICEINFO) deviceInfo, + deviceInfo->StringDescs, + deviceInfo->DeviceInfoNode + ); + + // Add port connector + if (NULL != deviceInfo->PortConnectorProps) + { + usbDevice->PortConnector = gcnew PortConnectorType(); + + XmlAddPortConnectorProps( + usbDevice->PortConnector, + deviceInfo->PortConnectorProps + ); + } + + // Add connectiontion info V2 + if (NULL != deviceInfo->ConnectionInfoV2) + { + usbDevice->ConnectionInfoV2 = gcnew NodeConnectionInfoExV2Type(); + XmlAddConnectionInfoV2( + usbDevice->ConnectionInfoV2, + deviceInfo->ConnectionInfoV2 + ); + } + + // Add configuration descriptor + if (NULL != deviceInfo->ConfigDesc) + { + // The device configuration is allocated by XmlGetConfigDescriptors() + usbDevice->DeviceConfiguration = XmlGetConfigDescriptors( + (PUSBDEVICEINFO) deviceInfo, + (PUSB_CONFIGURATION_DESCRIPTOR) (deviceInfo->ConfigDesc + 1), + deviceInfo->StringDescs + ); + } + + // Add BOS descriptor + if (NULL != deviceInfo->BosDesc) + { + usbDevice->BosDescriptor = XmlGetBosDescriptor((PUSB_BOS_DESCRIPTOR) (deviceInfo->BosDesc + 1)); + } + } + else + { + hr = E_FAIL; + } + } + return hr; +} + +/***************************************************************************** + + XmlAddRootHub() + + Add a root hub to the parent Host Controller + *****************************************************************************/ +HRESULT XmlAddRootHub(PSTR rhName, PUSBROOTHUBINFO rhInfo) +{ + HRESULT hr = S_OK; + Object ^ parent = gXmlStack->Peek(); + HostControllerType ^ hcParent = nullptr; + PSTR rootHubName = rhInfo->HubName; + + UNREFERENCED_PARAMETER(rhName); + + hcParent = dynamic_cast<HostControllerType ^> (parent); + + if (hcParent != nullptr) + { + RootHubType ^ rh = nullptr; + hcParent = (HostControllerType ^) parent; + hcParent->RootHub = gcnew RootHubType(); + + rh = hcParent->RootHub; + rh->HubName = PACHAR_TO_STRING(rootHubName); + + if (NULL != rhInfo->UsbDeviceProperties) + { + rh->HwId = PACHAR_TO_STRING(rhInfo->UsbDeviceProperties->HwId); + rh->DeviceId = PACHAR_TO_STRING(rhInfo->UsbDeviceProperties->DeviceId); + rh->ServiceName = PACHAR_TO_STRING(rhInfo->UsbDeviceProperties->Service); + rh->DeviceName = PACHAR_TO_STRING(rhInfo->UsbDeviceProperties->DeviceDesc); + rh->DeviceClass = PACHAR_TO_STRING(rhInfo->UsbDeviceProperties->DeviceClass); + + // Roothub protocol is same as HC protocol + rh->UsbProtocol = hcParent->UsbProtocol; + } + + rh->HubNodeInformation = gcnew HubNodeInformationType(); + XmlAddHubNodeInformation(rh->HubNodeInformation, rhInfo->HubInfo); + + rh->HubInformationEx = gcnew HubInformationExType(); + XmlAddHubInformationEx(rh->HubInformationEx, rhInfo->HubInfoEx); + + rh->HubCapabilityEx = gcnew HubCapabilitiesExType(); + XmlAddHubCapabilitiesEx(rh->HubCapabilityEx, rhInfo->HubCapabilityEx); + + // Push root hub on to stack + gXmlStack->Push(rh); + } + else + { + // Root hub should be connected to a host controller + hr = E_FAIL; + } + return S_OK; +} + +/***************************************************************************** + + XmlSetVersion() + + Set version information in XML tree + *****************************************************************************/ +VOID XmlSetVersion( + UCHAR uvcMajorVersion, + UCHAR uvcMinorVersion, + UCHAR uvcMajorSpecVersion, + UCHAR uvcMinorSpecVersion + ) +{ + MachineInfoType ^ mInfo; + gXmlView->MachineInfo = gcnew MachineInfoType(); + + mInfo = gXmlView->MachineInfo; + + mInfo->UvcMajorVersion = uvcMajorVersion; + mInfo->UvcMinorVersion = uvcMinorVersion; + mInfo->UvcMajorSpecVersion = uvcMajorSpecVersion; + mInfo->UvcMinorSpecVersion = uvcMinorSpecVersion; + +} + +/***************************************************************************** + + InitXmlHelper() + + Initialize XML helper + *****************************************************************************/ +HRESULT InitXmlHelper() +{ + HRESULT hr = S_OK; + + (XmlGlobal::Instance())->ViewAll = gcnew UvcViewAll(); + (XmlGlobal::Instance())->ViewAll->UvcView = gcnew UvcViewType(); + + // + // Initialize fields to null so we can check against them for allocation + // + (XmlGlobal::Instance())->ViewAll->UvcView->MachineInfo = nullptr; + (XmlGlobal::Instance())->ViewAll->UvcView->UsbTree = nullptr; + + XmlSetVersion( + UVC_SPEC_MAJOR_VERSION, + UVC_SPEC_MINOR_VERSION, + USBVIEW_MAJOR_VERSION, + USBVIEW_MINOR_VERSION + ); + + gXmlStack->Push(gXmlView); + + gXmlViewInitialized = TRUE; + + return hr; +} + +/***************************************************************************** + + SaveXml() + + Saves the inmemory USB view as XML file + *****************************************************************************/ +HRESULT SaveXml(LPTSTR szfileName, DWORD dwCreationDisposition) +{ + HRESULT hr = S_OK; + + if (gXmlViewInitialized) + { + try + { + String ^fileName = PACHAR_TO_STRING(szfileName); + XmlSerializer ^ serializer = gcnew XmlSerializer(UvcViewAll::typeid); + TextWriter ^ writer = nullptr; + + if (dwCreationDisposition != CREATE_ALWAYS) + { + // Check if file exits and return failure if it does + if (File::Exists(fileName)) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_EXISTS); + } + } + + // Check if file name is NULL + if (String::IsNullOrEmpty(fileName)) + { + hr = E_INVALIDARG; + } + + if (SUCCEEDED(hr)) + { + writer = gcnew StreamWriter(fileName); + serializer->Serialize(writer, (XmlGlobal::Instance())->ViewAll); + writer->Close(); + } + + // Release and reinit XML View for next iteration if requested + ReleaseXmlWriter(); + InitXmlHelper(); + + } + catch(Exception ^ ex) + { + hr = (HRESULT) Marshal::GetHRForException(ex); + } + } + else + { + hr = E_FAIL; + } + + return hr; +} + + +/***************************************************************************** + + ReleaseXmlWriter() + + *****************************************************************************/ +HRESULT ReleaseXmlWriter() +{ + HRESULT hr = S_OK; + + if (gXmlViewInitialized) + { + gXmlViewInitialized = FALSE; + delete XmlGlobal::Instance(); + } + + return hr; +} + diff --git a/usb/usbview/xmlhelper.h b/usb/usbview/xmlhelper.h new file mode 100644 index 00000000..b5ee271b --- /dev/null +++ b/usb/usbview/xmlhelper.h @@ -0,0 +1,41 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + + XMLHELPER.H + +Abstract: + + This helper file declaration for XML helper APIs + +Environment: + + user mode + +Revision History: + + 05-05-11 : created + +--*/ + +#pragma once + +/***************************************************************************** + I N C L U D E S +*****************************************************************************/ +#include "uvcview.h" + +EXTERN_C HRESULT InitXmlHelper(); +EXTERN_C HRESULT ReleaseXmlWriter(); +EXTERN_C HRESULT SaveXml(LPTSTR szfileName, DWORD dwCreationDisposition); +EXTERN_C HRESULT XmlAddHostController( + PSTR hcName, + PUSBHOSTCONTROLLERINFO hcInfo + ); +EXTERN_C HRESULT XmlAddRootHub(PSTR rhName, PUSBROOTHUBINFO rhInfo); +EXTERN_C HRESULT XmlAddExternalHub(PSTR ehName, PUSBEXTERNALHUBINFO ehInfo); +EXTERN_C HRESULT XmlAddUsbDevice(PSTR devName, PUSBDEVICEINFO deviceInfo); +EXTERN_C VOID XmlNotifyEndOfNodeList(PVOID pContext); + |
