/*++ Copyright (c) 1996 Microsoft Corporation Module Name: usbdiag.h Environment: Kernel & user mode Revision History: 5-10-96 : created --*/ #ifndef __USBDIAG_H__ #define __USBDIAG_H__ #define IRP_TYPE_READ_PIPE 0 #define IPR_TYPE_OTHER 1 #define FDO_FROM_DEVICE_HANDLE(dev) (((PDEVICE_LIST_ENTRY)(dev))->DeviceObject) #define USBDIAG_NAME_MAX 64 #define NAME_MAX 256 #define MAX_INTERFACE 8 #define USBDIAG_MAX_PIPES 256 #define MAX_DOWNSTREAM_DEVICES 10 #define USBD_WIN98_GOLD_VERSION 0x0101 #define USBD_WIN98_SE_VERSION 0x0200 #define USBD_WIN2K_VERSION 0x0200 typedef struct _IRPNODE { LIST_ENTRY entry; PIRP Irp; struct _IRPNODE * next; } IRPNODE, * PIRPNODE; typedef struct _COMPLETION_CONTEXT { PDEVICE_OBJECT DeviceObject; PIRP Irp; PIO_COMPLETION_ROUTINE CompletionRoutine; PVOID Context; KEVENT DoneEvent; } COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT; typedef struct _DEVICE_LIST_ENTRY { PDEVICE_OBJECT PhysicalDeviceObject; PDEVICE_OBJECT DeviceObject; struct _DEVICE_LIST_ENTRY *Next; ULONG DeviceNumber; } DEVICE_LIST_ENTRY, *PDEVICE_LIST_ENTRY; typedef struct _USBDIAG_WORKITEM { WORK_QUEUE_ITEM WorkItem; PDEVICE_OBJECT DeviceObject; } USBDIAG_WORKITEM, *PUSBDIAG_WORKITEM; 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; ULONG DeviceHackFlags; PIRP PowerIrp; KEVENT WaitWakeEvent; // handle to configuration that was selected USBD_CONFIGURATION_HANDLE ConfigurationHandle; ULONG numPipesInUse; // number of pipes in use LIST_ENTRY ListHead; KSPIN_LOCK SpinLock; KEVENT CancelEvent; PKEVENT SelfRequestedPowerIrpEvent; BOOLEAN Stopped; // keeps track of device status BOOLEAN bTestDevice; // flag for test devices PDEVICE_OBJECT RootHubPdo; PDEVICE_OBJECT TopOfHcdStackDeviceObject; //BOOLEAN WaitWakePending; PIRP WaitWakeIrp; DEVICE_CAPABILITIES DeviceCapabilities; POWER_STATE CurrentSystemState; POWER_STATE CurrentDeviceState; // remember the irp corresponding to the interrupt pipe PIRP InterruptIrp; PUSBD_DEVICE_DATA DeviceData[MAX_DOWNSTREAM_DEVICES+1]; // pointers to downstream devices PUSB_CONFIGURATION_DESCRIPTOR DownstreamConfigDescriptor[MAX_DOWNSTREAM_DEVICES+1]; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; #if DBG #define USBDIAG_KdPrint(_x_) DbgPrint _x_ ; #define TRAP() DbgBreakPoint() #else #define USBDIAG_KdPrint(_x_) #define TRAP() #endif PVOID USBDIAG_ExAllocatePool( IN POOL_TYPE PoolType, IN ULONG NumberOfBytes ); VOID USBDIAG_ExFreePool( IN PVOID P ); NTSTATUS USBDIAG_Dispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_PnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_Power( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID USBDIAG_Unload( IN PDRIVER_OBJECT DriverObject ); NTSTATUS USBDIAG_StartDevice( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_StopDevice( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_CallUSBD( IN PDEVICE_OBJECT DeviceObject, IN PURB Urb ); NTSTATUS USBDIAG_PnPAddDevice( IN PDRIVER_OBJECT DriverObject, IN OUT PDEVICE_OBJECT PhysicalDeviceObject ); NTSTATUS USBDIAG_CreateDeviceObject( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT *DeviceObject, BOOLEAN Global ); NTSTATUS USBDIAG_ProcessIOCTL( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_Configure_Device ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS USBDIAG_SelectInterfaces( IN PDEVICE_OBJECT DeviceObject, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, IN OUT struct _REQ_SET_DEVICE_CONFIG * REQSetDeviceConfig ); NTSTATUS USBDIAG_Chap9Control( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_HIDP_GetCollection( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_RemoveGlobalDeviceObject( ); NTSTATUS USBDIAG_Ch9CallUSBD( IN PDEVICE_OBJECT DeviceObject, IN PURB Urb, IN BOOLEAN fBlock, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID pvContext, BOOLEAN fWantTimeOut ); NTSTATUS USBDIAG_SendPacket( IN PDEVICE_OBJECT DeviceObject, IN CHAR SetUpPacket[], PVOID TxBuffer, ULONG * TxBufferLen, ULONG * pulUrbStatus ); VOID USBDIAG_SyncTimeoutDPC( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); VOID USBDIAG_IoCancelRoutine ( PDEVICE_OBJECT DeviceObject, PIRP Irp ); NTSTATUS USBDIAG_IoGenericCompletionRoutine ( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID context ); NTSTATUS USBDIAG_IssueWaitWake( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_RequestWaitWakeCompletion( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); NTSTATUS USBDIAG_PoRequestCompletion( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); NTSTATUS USBDIAG_PowerIrpCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS USBDIAG_SetDevicePowerState( IN PDEVICE_OBJECT DeviceObject, IN ULONG ulPowerState ); NTSTATUS USBDIAG_PoSelfRequestCompletion( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); NTSTATUS USBDIAG_SaveIrp( IN PDEVICE_EXTENSION deviceExtension, IN PIRP irp ); NTSTATUS USBDIAG_ClearSavedIrp( IN PDEVICE_EXTENSION deviceExtension, IN PIRP irp ); NTSTATUS USBDIAG_ResetParentPort( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_CancelAllIrps( PDEVICE_EXTENSION deviceExtension ); NTSTATUS USBDIAG_WaitWakeCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); VOID USBDIAG_WaitWakeCancelRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_RemoveDownstreamDevice( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_Chap11SetConfiguration( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_Chap11EnableRemoteWakeup( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject ); NTSTATUS USBDIAG_Chap11SendPacketDownstream( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject, IN PREQ_SEND_PACKET_DOWNSTREAM pSendPacketDownstream ); // ******************************************** #if DBG #define DEBUG_LOG #define DEBUG_HEAP #endif #define SIG_DEVICE 0x56454455 //"UDEV" signature for device handle #if DBG #define ASSERT_DEVICE(d) ASSERT((d)->Sig == SIG_DEVICE) ULONG _cdecl USBD_KdPrintX( PCH Format, ... ); extern ULONG USBD_Debug_Trace_Level; #define USBD_KdPrint(l, _x_) if ((l) <= USBD_Debug_Trace_Level) \ {USBD_KdPrintX _x_;\ } VOID USBD_Assert( PVOID FailedAssertion, PVOID FileName, ULONG LineNumber, PCHAR Message ); #define USBD_ASSERT( exp ) \ if (!(exp)) \ USBD_Assert( #exp, __FILE__, __LINE__, NULL ) #define USBD_ASSERTMSG( msg, exp ) \ if (!(exp)) \ USBD_Assert( #exp, __FILE__, __LINE__, msg ) // TEST_TRAP() is a code coverage trap these should be removed // if you are able to 'g' past the OK // // TRAP() breaks in the debugger on the debugger build // these indicate bugs in client drivers or fatal error // conditions that should be debugged. also used to mark // code for features not implemented yet. // // KdBreak() breaks in the debugger when in MAX_DEBUG mode // ie debug trace info is turned on, these are intended to help // debug drivers devices and special conditions on the // bus. #ifdef NTKERN // Ntkern currently implements DebugBreak with a global int 3, // we really would like the int 3 in our own code. #define DBGBREAK() _asm { int 3 } #else #define DBGBREAK() DbgBreakPoint() #endif /* NTKERN */ #define TEST_TRAP() { DbgPrint( " Code Coverage Trap %s %d\n", __FILE__, __LINE__); \ DBGBREAK(); } #ifdef MAX_DEBUG #define USBD_KdBreak(_x_) { DbgPrint("USBD:"); \ DbgPrint _x_ ; \ DBGBREAK(); } #else #define USBD_KdBreak(_x_) #endif #define USBD_KdTrap(_x_) { DbgPrint( "USBD: "); \ DbgPrint _x_; \ DBGBREAK(); } #else /* DBG not defined */ #define USBD_KdBreak(_x_) #define USBD_KdTrap(_x_) #define TEST_TRAP() #define ASSERT_DEVICE(d) #define USBD_ASSERT( exp ) #define USBD_ASSERTMSG( msg, exp ) #endif /* DBG */ #ifndef __HCDI_H__ #define __HCDI_H__ typedef NTSTATUS ROOT_HUB_POWER_FUNCTION(PDEVICE_OBJECT DeviceObject, PIRP Irp); typedef NTSTATUS HCD_DEFFERED_START_FUNCTION(PDEVICE_OBJECT DeviceObject, PIRP Irp); typedef NTSTATUS HCD_SET_DEVICE_POWER_STATE(PDEVICE_OBJECT DeviceObject, PIRP Irp, DEVICE_POWER_STATE DeviceState); typedef struct _USBD_EXTENSION { // ptr to true device extension or NULL if this // is the true extension PVOID TrueDeviceExtension; // size of this structure ULONG Length; ROOT_HUB_POWER_FUNCTION *RootHubPower; HCD_DEFFERED_START_FUNCTION *HcdDeferredStartDevice; HCD_SET_DEVICE_POWER_STATE *HcdSetDevicePowerState; DEVICE_POWER_STATE HcCurrentDevicePowerState; KEVENT PnpStartEvent; // // Owner of frame length control for this HC // PVOID FrameLengthControlOwner; // // HCD device object we are connected to. // PDEVICE_OBJECT HcdDeviceObject; // wake irp passed to us by the hub driver // for the root hub PIRP PendingWakeIrp; // wakeup irp we send down the HC stack PIRP HcWakeIrp; // // device object for top of the HCD stack // this = HcdDeviceObject when no filters // are present. // PDEVICE_OBJECT HcdTopOfStackDeviceObject; PDEVICE_OBJECT HcdTopOfPdoStackDeviceObject; // // copy of the host controller device // capabilities // DEVICE_CAPABILITIES HcDeviceCapabilities; DEVICE_CAPABILITIES RootHubDeviceCapabilities; PIRP PowerIrp; // // Used to serialize open/close endpoint and // device configuration // KSEMAPHORE UsbDeviceMutex; // // Bitmap of assigned USB addresses // ULONG AddressList[4]; // // Remember the Root Hub PDO we created. // PDEVICE_OBJECT RootHubPDO; PDRIVER_OBJECT DriverObject; // // symbolic link created for HCD stack // UNICODE_STRING DeviceLinkUnicodeString; BOOLEAN DiagnosticMode; BOOLEAN DiagIgnoreHubs; BOOLEAN Reserved; // used to be supportNonComp UCHAR HcWakeFlags; ULONG DeviceHackFlags; // // Store away the PDO // PDEVICE_OBJECT HcdPhysicalDeviceObject; PVOID RootHubDeviceData; DEVICE_POWER_STATE RootHubDeviceState; // current USB defined power state of the bus // during last suspend. DEVICE_POWER_STATE SuspendPowerState; UNICODE_STRING RootHubSymbolicLinkName; } USBD_EXTENSION, *PUSBD_EXTENSION; #define HC_ENABLED_FOR_WAKEUP 0x01 #define HC_WAKE_PENDING 0x02 // device hack flags, these flags alter the stacks default behavior // in order to support certain broken "legacy" devices #define USBD_DEVHACK_SLOW_ENUMERATION 0x00000001 #define USBD_DEVHACK_DISABLE_SN 0x00000002 // // This macro returns the true device object for the HCD give // either the true device_object or a PDO owned by the HCD/BUS // driver. // // // HCD specific URB commands // #define URB_FUNCTION_HCD_OPEN_ENDPOINT 0x1000 #define URB_FUNCTION_HCD_CLOSE_ENDPOINT 0x1001 #define URB_FUNCTION_HCD_GET_ENDPOINT_STATE 0x1002 #define URB_FUNCTION_HCD_SET_ENDPOINT_STATE 0x1003 #define URB_FUNCTION_HCD_ABORT_ENDPOINT 0x1004 // this bit is set for all functions that must be handled by HCD #define HCD_URB_FUNCTION 0x1000 // this bit is set in the function code by USBD to indicate that // this is an internal call originating from USBD #define HCD_NO_USBD_CALL 0x2000 // // values for HcdEndpointState // // // set if the current state of the endpoint in the HCD is 'stalled' // #define HCD_ENDPOINT_HALTED_BIT 0 #define HCD_ENDPOINT_HALTED (1<HcdEndpoint == NULL) #define GET_DEVICE_EXTENSION(DeviceObject) (((PUSBD_EXTENSION)(DeviceObject->DeviceExtension))->TrueDeviceExtension) //#define GET_DEVICE_EXTENSION(DeviceObject) ((PUSBD_EXTENSION)(DeviceObject->DeviceExtension)) #define HCD_DEVICE_OBJECT(DeviceObject) (DeviceObject) #define DEVICE_FROM_DEVICEHANDLEROBJECT(UsbdDeviceHandle) (PUSBD_DEVICE_DATA) (UsbdDeviceHandle) #define SET_USBD_ERROR(err) ((err) | USBD_STATUS_ERROR) #define HC_URB(urb) ((PHCD_URB)(urb)) // // we use a semaphore to serialize access to the configuration functions // in USBD // #define InitializeUsbDeviceMutex(de) KeInitializeSemaphore(&(de)->UsbDeviceMutex, 1, 1); #define USBD_WaitForUsbDeviceMutex(de) { USBD_KdPrint(3, ("'***WAIT dev mutex %x\n", &(de)->UsbDeviceMutex)); \ KeWaitForSingleObject(&(de)->UsbDeviceMutex, \ Executive,\ KernelMode, \ FALSE, \ NULL); \ } #define USBD_ReleaseUsbDeviceMutex(de) { USBD_KdPrint(3, ("'***RELEASE dev mutex %x\n", &(de)->UsbDeviceMutex));\ KeReleaseSemaphore(&(de)->UsbDeviceMutex,\ LOW_REALTIME_PRIORITY,\ 1,\ FALSE);\ // //Function Prototypes // #if DBG VOID USBD_Warning( PUSBD_DEVICE_DATA DeviceData, PUCHAR Message, BOOLEAN DebugBreak ); #else #define USBD_Warning(x, y, z) #endif NTSTATUS USBD_Internal_Device_Control( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PUSBD_EXTENSION DeviceExtension, IN PBOOLEAN IrpIsPending ); NTSTATUS USBD_SendCommand( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject, IN USHORT RequestCode, IN USHORT WValue, IN USHORT WIndex, IN USHORT WLength, IN PVOID Buffer, IN ULONG BufferLength, OUT PULONG BytesReturned, OUT USBD_STATUS *UsbStatus ); #if 0 NTSTATUS USBDIAG_CreateDevice( IN OUT PUSBD_DEVICE_DATA *DeviceData, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeviceIsLowSpeed, IN ULONG MaxPacketSize_Endpoint0, IN OUT PULONG NonCompliantDevice ); #endif NTSTATUS USBD_ProcessURB( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PURB Urb, OUT PBOOLEAN IrpIsPending ); NTSTATUS USBD_MapError_UrbToNT( IN PURB Urb, IN NTSTATUS NtStatus ); NTSTATUS USBD_Irp_Complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); #if 0 USHORT USBD_AllocateUsbAddress( IN PDEVICE_OBJECT DeviceObject ); #endif NTSTATUS USBDIAG_CreateInitDownstreamDevice( PREQ_ENUMERATE_DOWNSTREAM_DEVICE pEnumerate, PDEVICE_EXTENSION deviceExtension ); NTSTATUS USBD_GetDescriptor( IN PUSBD_DEVICE_DATA Device, IN PDEVICE_OBJECT DeviceObject, OUT PUCHAR DescriptorBuffer, IN USHORT DescriptorBufferLength, IN USHORT DescriptorTypeAndIndex ); NTSTATUS USBD_CloseEndpoint( IN PUSBD_DEVICE_DATA Device, IN PDEVICE_OBJECT DeviceObject, IN PUSBD_PIPE PipeHandle, OUT USBD_STATUS *UsbStatus ); NTSTATUS USBD_SubmitSynchronousURB( IN PURB Urb, IN PDEVICE_OBJECT DeviceObject, IN PUSBD_DEVICE_DATA DeviceData ); NTSTATUS USBD_GetEndpointState( IN PUSBD_DEVICE_DATA DeviceData, IN PDEVICE_OBJECT DeviceObject, IN PUSBD_PIPE PipeHandle, OUT USBD_STATUS *UsbStatus, OUT PULONG EndpointState ); NTSTATUS USBDIAG_SyncGetRootHubPdo( IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN OUT PDEVICE_OBJECT *RootHubPdo, IN OUT PDEVICE_OBJECT *TopOfHcdStackDeviceObject ); NTSTATUS USBDIAG_PowerIrp_Complete( IN PDEVICE_OBJECT NullDeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS USBDIAG_SetCfgEnableRWu( PDEVICE_EXTENSION deviceExtension, PREQ_ENUMERATE_DOWNSTREAM_DEVICE pEnumerate ); NTSTATUS USBDIAG_WaitForWakeup( PDEVICE_EXTENSION deviceExtension ); NTSTATUS USBD_SetPdoRegistryParameter ( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PWCHAR KeyName, IN ULONG KeyNameLength, IN PVOID Data, IN ULONG DataLength, IN ULONG KeyType, IN ULONG DevInstKeyType ); NTSTATUS USBD_SetRegistryKeyValue ( IN HANDLE Handle, IN PUNICODE_STRING KeyNameUnicodeString, IN PVOID Data, IN ULONG DataLength, IN ULONG KeyType ); NTSTATUS USBDIAG_DisableRemoteWakeupEnable( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN bDisable ); NTSTATUS USBDIAG_PassDownIrp ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBDIAG_QueryCapabilitiesCompletionRoutine( IN PDEVICE_OBJECT NullDeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS USBDIAG_GenericCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); #endif //__USBDIAG_H__