/**************************************************************************** Copyright (c) 1993 Microsoft Corporation Module Name: usbloop.h Abstract: This header file is used both by ring3 app and ring0 driver, hence the use of #define DRIVER Environment: Kernel & user mode Revision History: 1-10-96 : created ****************************************************************************/ #ifdef DRIVER #include #include #include #else #include #endif #include #include #include #define NAME_MAX 256 #define MAX_INTERFACE 8 #define USBLOOP_PARENT "\\\\.\\USBLOOPXXX" // IOCTL info #define USBLOOP_IOCTL_INDEX 0x0080 #define GET_NUM_DEVICES CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+0, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define GET_DEVICE_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+1, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define GET_DEVICE_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+2, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+3, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+4, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define GET_INTERFACE_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+5, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define USBLOOP_START_ISO_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, \ USBLOOP_IOCTL_INDEX+6, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #ifdef DRIVER #define USBDIAG_NAME_MAX 64 #define USBLOOP_MAX_PIPES 256 #define USBLOOP_MAX_XFER_SIZE 16384 // 16K #define USBLOOP_MAX_ENUM_DEVICES 8 typedef struct _DEVICE_LIST_ENTRY { PDEVICE_OBJECT PhysicalDeviceObject; PDEVICE_OBJECT DeviceObject; struct _DEVICE_LIST_ENTRY *Next; ULONG DeviceNumber; } DEVICE_LIST_ENTRY, *PDEVICE_LIST_ENTRY; // data structure to describe each pipe typedef struct _PipeDescr { BOOLEAN bPipeInUse; // pipe in use flag // layout of PipeAttr is LSB|ep|alt_interface|interface|configuration|MSB ULONG PipeAttr; // describes pipe configuration, interface, etc. } PipeDescr, *pPipeDescr; // device extension for driver instance, used to store needed data typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT PhysicalDeviceObject; // physical device object PDEVICE_OBJECT StackDeviceObject; // stack device object PDEVICE_LIST_ENTRY DeviceList; ULONG ulInstance; // keeps track of device instance // Name buffer for our named Functional device object link WCHAR DeviceLinkNameBuffer[USBDIAG_NAME_MAX]; // descriptors for device instance PUSB_CONFIGURATION_DESCRIPTOR pUsbConfigDesc; PUSBD_INTERFACE_INFORMATION Interface[MAX_INTERFACE]; ULONG OpenFRC; PUSB_DEVICE_DESCRIPTOR pDeviceDescriptor; KTIMER TimeoutTimer; KDPC TimeoutDpc; // handle to configuration that was selected USBD_CONFIGURATION_HANDLE ConfigurationHandle; ULONG numPipesInUse; // number of pipes in use PipeDescr pipes[USBLOOP_MAX_PIPES]; // array of pipe descriptors //Pointer to an Irp outstanding on this device // BUGBUG (kosar) This should really be kept on a per-pipe basis but // we're only keeping on outstanding Irp on this device // at a time. PIRP pIrp; BOOLEAN Stopped; // keeps track of device status BOOLEAN bTestDevice; // flag for test devices } DEVICE_EXTENSION, *PDEVICE_EXTENSION; #define PIPE_MASK 0xff #define NUM_ATTR_BYTES 4 #define ALT_INT_SHIFT 8 #define INT_SHIFT 16 #define CONFIG_SHIFT 24 #define DEADMAN_TIMEOUT 5000 // extract alt interface from FsContext #define ALT_INTERFACE(context) ((ULONG) ((ULONG) context >> ALT_INT_SHIFT) & PIPE_MASK) // extract interface from FsContext #define INTERFACE(context) ((ULONG) ((ULONG) context >> INT_SHIFT) & PIPE_MASK) // extract configuration from FsContext #define CONFIGURATION(context) ((ULONG) ((ULONG) context >> CONFIG_SHIFT) & PIPE_MASK) // extract pipe number from FsContext #define PIPENUM(context) ((ULONG) context & PIPE_MASK) // turns ULONGs into attribute byte for pipe #define MAKEPIPEATTR(config, interface, alt_interface, pipenum) \ ((ULONG) (((config & PIPE_MASK) << CONFIG_SHIFT) + \ ((interface & PIPE_MASK) << INT_SHIFT) + \ ((alt_interface & PIPE_MASK) << ALT_INT_SHIFT) + \ (pipenum & PIPE_MASK))) ULONG ulNumLogDev; static WCHAR deviceLinkBuffer[NAME_MAX] = L"\\DosDevices\\USBLOOP"; static WCHAR deviceNameBuffer[NAME_MAX] = L"\\Device\\USBLOOP"; // this data structure will be used for async transfers, contains urb // structure, a timer object, pointer to the irp, and a callback object for // the timer. The timer will be cancelled when the USB transfer completes typedef struct AsyncTransfer { struct _URB_BULK_OR_INTERRUPT_TRANSFER urb; KTIMER TimeoutTimer; PIRP irp; KDPC TimeoutDpc; BOOLEAN bTimerExpired; } AsyncTransfer, *pAsyncTransfer; #if DBG #define USBLOOP_KdPrint(_x_) DbgPrint("USBLOOP.SYS: "); \ DbgPrint _x_ ; #define USBLOOP_TRAP() DbgBreakPoint() #else #define USBLOOP_KdPrint(_x_) #define USBLOOP_TRAP() #endif NTSTATUS USBLOOP_Dispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID USBLOOP_Unload( IN PDRIVER_OBJECT DriverObject ); NTSTATUS USBLOOP_StartDevice( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBLOOP_StopDevice( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBLOOP_CreateDeviceObject( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT *DeviceObject, ULONG Instance ); NTSTATUS USBLOOP_CallUSBD( IN PDEVICE_OBJECT DeviceObject, IN PURB Urb ); NTSTATUS USBLOOP_PnPAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ); NTSTATUS USBLOOP_SelectInterfaces( IN PDEVICE_OBJECT DeviceObject, IN PUSB_CONFIGURATION_DESCRIPTOR configDesc ); NTSTATUS USBLOOP_ConfigureDevice( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBLOOP_GetDescriptor( IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescType, IN OUT PVOID pvBuffer ); NTSTATUS USBLOOP_Read( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBLOOP_Write( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBLOOP_getPipeAttr( IN PCWSTR pDeviceName, OUT PULONG pPipeAttr ); pAsyncTransfer USBLOOP_BuildAsyncRequest( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN USBD_PIPE_HANDLE PipeHandle, IN BOOLEAN Read ); NTSTATUS USBLOOP_AsyncReadWrite_Complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); VOID USBLOOP_SyncTimeoutDPC( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); #endif