/*++ Copyright (c) 1997 Microsoft Corporation Module Name: usbverfy.h Abstract: This module contains the common private declarations for the mouse packet filter Environment: kernel mode only Notes: Revision History: --*/ #ifndef USBVERIFY_H #define USBVERIFY_H #include #include #include #include "str.h" #define DO_INTERFACE #define USBVERIFY_POOL_TAG (ULONG) 'vBSU' #undef ExAllocatePool #define ExAllocatePool(type, size) \ ExAllocatePoolWithTag (type, size, USBVERIFY_POOL_TAG) #define USB_VERIFY_FILL 0xEA // 0xFF instead? #define USB_VERIFY_WIN9X_SERVICE_PATH L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\USBVer9x" #if DBG #define TRAP() DbgBreakPoint() #define DbgRaiseIrql(_x_,_y_) KeRaiseIrql(_x_,_y_) #define DbgLowerIrql(_x_) KeLowerIrql(_x_) #else // DBG #define TRAP() #define DbgRaiseIrql(_x_,_y_) #define DbgLowerIrql(_x_) #endif // #define USB_VERIFY_NOT_IMPLEMENTED 1 #define AllocStruct(memtype, type, count) \ ((type*) ExAllocatePool(memtype, sizeof(type) * count)) typedef enum _USB_VERIFY_STATE { Uninitialized = 0, Started, Stopped, SurpriseRemoved, Removed } USB_VERIFY_STATE, *PUSB_VERIFY_STATE; typedef enum _USB_VERIFY_REMOVAL_CAUSE { RemoveSelectConfigZero = 0, RemoveSelectConfig, RemoveSelectInterface, RemoveDeviceRemoved, RemoveNewList } USB_VERIFY_REMOVAL_CAUSE; #define LOG_PNP 0x00000001 #define LOG_PIPES 0x00000010 #define LOG_INTERFACES 0x00000020 // BUGBUG determine which flags we want on by default #define LOG_FLAGS_DEFAULT 0xFF // 0x0 #define LOG_SIZE_DEFAULT 0x100 // For all pnp log entries: // Arg0: - , Arg1: - #define LOG_PNP_START 'TRTS' #define LOG_PNP_STOP 'POTS' #define LOG_PNP_REMOVE 'vomR' #define LOG_PNP_SURPRISE_REMOVE 'vmRS' // Arg0: PipeHandle, Arg1: PipeType #define LOG_PIPE_NEW 'PweN' // (cont of LOG_PIPE_NEW) // Arg0: MaximumPacketSize, Arg1: UW, Interval; LW, EndpointAddress #define LOG_PIPE_NEW2 '2PwN' // (cont of LOG_PIPE_NEW) // Arg0: MaximumTranswerSize, Arg1: PipeFlags #define LOG_PIPE_NEW3 '3PwN' // Arg0: Pipe , Arg1: USB_VERIFY_REMOVAL_CAUSE #define LOG_PIPE_REMOVE 'PmeR' // Arg0: InterfaceNumber, Arg1: AlternateSettting #define LOG_INTERFACE_NEW 'intN' #define LOG_INTERFACE_REMOVE 'tniR' #define LOG #define LOG_URB_SELECT_CONFIG 'gfcS' #define LOG_URB_SELECT_INTERFACE 'ftnS' // // Verify flags // #define UsbVerify_CheckVerifyFlags(de, f) ((de)->VerifyFlags & (f)) #define VERIFY_TEST_MEMORY 0x00000001 #define VERIFY_PIPES 0x00000002 #define VERIFY_NOT_IMPLEMENTED 0x00000004 #define VERIFY_REPLACE_URBS 0x00000010 #define VERIFY_TRACK_URBS 0x00000020 // BUGBUG determine what functionality we want on by default #define VERIFY_FLAGS_DEFAULT 0xFF // 0x0 #define UsbVerify_Print(de, _flags_, _x_) \ if (!(_flags_) || (de)->PrintFlags & (_flags_) ) { \ DbgPrint ("usbverfy: "); \ DbgPrint _x_; \ } #define PRINT_ALWAYS 0x00000000 #define PRINT_PIPE_NOISE 0x00000001 #define PRINT_PIPE_TRACE 0x00000002 #define PRINT_PIPE_INFO 0x00000004 #define PRINT_PIPE_ERROR 0x00000008 #define PRINT_URB_NOISE 0x00000010 #define PRINT_URB_TRACE 0x00000020 #define PRINT_URB_INFO 0x00000040 #define PRINT_URB_ERROR 0x00000080 #define PRINT_LIST_NOISE 0x00000100 #define PRINT_LIST_TRACE 0x00000200 #define PRINT_LIST_INFO 0x00000400 #define PRINT_LIST_ERROR 0x00000800 #define PRINT_FLAGS_DEFAULT (PRINT_PIPE_ERROR | PRINT_URB_ERROR | PRINT_LIST_ERROR) typedef enum _USB_VERIFY_LOG_TYPE { LogTypeNewPipe, LogTypeRemovePipe, LogTypePnpEvent } USB_VERIFY_LOG_TYPE; typedef struct _USB_VERIFY_LOG_PNP_EVENT { UCHAR MinorFunction; } USB_VERIFY_LOG_PNP_EVENT; typedef struct _USB_VERIFY_LOG_PIPE { USHORT NewPipe; USHORT RemovalCause; USBD_PIPE_INFORMATION PipeInfo; } USB_VERIFY_LOG_PIPE; typedef struct _USB_VERIFY_LOG_INTERFACE { USHORT NewInterface; UCHAR Number; UCHAR AlternateSetting; } USB_VERIFY_LOG_INTERFACE; typedef struct _USB_VERIFY_LOG_ENTRY { ULONG Type; LARGE_INTEGER CurrentTick; union { USB_VERIFY_LOG_PNP_EVENT PnpEvent; USB_VERIFY_LOG_PIPE Pipe; USB_VERIFY_LOG_INTERFACE Interface; } u; } USB_VERIFY_LOG_ENTRY, *PUSB_VERIFY_LOG_ENTRY; #define ZeroLogEntry(entry) RtlZeroMemory(entry, sizeof(USB_VERIFY_LOG_ENTRY)) // // The field that are in the first four DWORDs are important. We want to keep // the most used fields there b/c when a we run a !dflink, it will print the // first 4 DWORDS in the struct (the LINK_ENTRY + 2 DWORDS) // typedef struct _USB_VERIFY_TRACK_URB { // // list entry into the linked list // LIST_ENTRY Link; // // Keep Irp and Urb right after Link. when you run !dflink or !dblink, it // will dump the 2 dwords after the LIST_ENTRY structure. // // // The irp we are tracking // PIRP Irp; // // The URB contained in the irp. If we are replacing URBS // (VERIFY_REPLACE_URBS is set), then original Urb will be the context for // the completion routine (and in the OriginalUrb field below). // PURB Urb; // // If we are placing URBs, then this will contain the clients original URB. // Otherwise, it is NULL. // PURB OriginalUrb; // // Time stamp of when we inserted the irp into our list // LARGE_INTEGER ArrivalTime; } USB_VERIFY_TRACK_URB, *PUSB_VERIFY_TRACK_URB; // // Assertion based defines // #define USB_VERIFY_ASSERT_COUNT 1 typedef struct _USB_VERIFY_ASSERT_NAME { ULONG Number; PWCHAR Name; } USB_VERIFY_ASSERT_NAME, *PUSB_VERIFY_ASSERT_NAME; typedef ULONG USB_VERIFY_ASSERT_STATE; typedef USB_VERIFY_ASSERT_STATE USB_VERIFY_ASSERT_TABLE[USB_VERIFY_ASSERT_COUNT]; typedef USB_VERIFY_ASSERT_TABLE *PUSB_VERIFY_ASSERT_TABLE; typedef struct _USB_VERIFY_DEVICE_EXTENSION { // // A backpointer to the device object for which this is the extension // PDEVICE_OBJECT Self; // // "THE PDO" (ejected by the bus) // PDEVICE_OBJECT PDO; // // The top of the stack before this filter was added. AKA the location // to which all IRPS should be directed. // PDEVICE_OBJECT TopOfStack; // // Control over exactly what we verify // ULONG VerifyFlags; // // Control over exactly what we print // ULONG PrintFlags; // // Events to log // ULONG LogFlags; PUSB_VERIFY_LOG_ENTRY Log; ULONG LogSize; PUSB_VERIFY_LOG_ENTRY CurrentLogEntry; // // Lock that synchronizes access to the InterfaceList // KSPIN_LOCK InterfaceListSpinLock; // // The actual pipe list, an array of interface pointers (each of which contain // an array of pipes) // PUSBD_INTERFACE_INFORMATION *InterfaceList; // // Number of items in the InterfaceList which are valid (InUse == TRUE) // LONG InterfaceListCount; // // Total size of the InterfaceList // LONG InterfaceListSize; ULONG InterfaceListLocked; // // Lock that synchronizes access to the UrbList // KSPIN_LOCK UrbListSpinLock; // // Linked list of URBs (actually, the IRPs that contain them) // LIST_ENTRY UrbList; // // Number of URBs in UrbList // ULONG UrbListCount; ULONG UrbListLowMemoryCount; ULONG UrbListLocked; ULONG ReplaceUrbsLowMemoryCount; USBD_CONFIGURATION_HANDLE ValidConfigurationHandle; // // current power state of the device // DEVICE_POWER_STATE PowerState; // // State of the stack and this device object // USB_VERIFY_STATE VerifyState; #ifdef DO_INTERFACE UNICODE_STRING SymbolicLinkName; #endif // // Number of creates sent down // ULONG EnableCount; ULONG TreatWarningsAsErrors; // // Status of where the take frame control urb has been sent or not // BOOLEAN HasFrameLengthControl; BOOLEAN Initialized; } USB_VERIFY_DEVICE_EXTENSION, *PUSB_VERIFY_DEVICE_EXTENSION; #define GetExtension(dev) ((PUSB_VERIFY_DEVICE_EXTENSION) (dev)->DeviceExtension) #define UsbVerify_InitializeUrbList(de) InitializeListHead(&(de)->UrbList); #define UsbVerify_InitializeInterfaceListLock(de) KeInitializeSpinLock(&(de)->InterfaceListSpinLock); #define UsbVerify_LockInterfaceList(de, irql) { \ KeAcquireSpinLock(&(de)->InterfaceListSpinLock, &irql); \ (de)->InterfaceListLocked = TRUE; \ } #define UsbVerify_UnlockInterfaceList(de, irql) { \ (de)->InterfaceListLocked = FALSE; \ KeReleaseSpinLock(&(de)->InterfaceListSpinLock, irql); \ } #define UsbVerify_AssertInterfaceListLocked(de) \ UsbVerify_ASSERT((de)->InterfaceListLocked, (de)->Self, NULL, NULL) #define UsbVerify_InitializeUrbListLock(de) KeInitializeSpinLock(&(de)->UrbListSpinLock); #define UsbVerify_LockUrbList(de, irql) { \ KeAcquireSpinLock(&(de)->UrbListSpinLock, &irql); \ (de)->UrbListLocked = TRUE; \ } #define UsbVerify_UnlockUrbList(de, irql) { \ (de)->UrbListLocked = FALSE; \ KeReleaseSpinLock(&(de)->UrbListSpinLock, irql); \ } #define UsbVerify_ASSERT( exp, devObj, irp, urb ) \ if (!(exp)) { \ static ULONG _UsbVerifyAssertState = 0x0; \ UsbVerify_Assert( #exp, devObj, irp, urb, &_UsbVerifyAssertState); \ } #define UsbVerify_ASSERT_MSG( exp, msg, devObj, irp, urb ) \ if (!(exp)) { \ static ULONG _UsbVerifyAssertState = 0x0; \ UsbVerify_Assert( msg, devObj, irp, urb, &_UsbVerifyAssertState); \ } #define UsbVerify_WARNING( exp, devObj, irp, urb ) \ if (!(exp)) { \ static ULONG _UsbVerifyWarningState = 0x0; \ UsbVerify_Warning( #exp, devObj, irp, urb, &_UsbVerifyWarningState); \ } #define UsbVerify_WARNING_MSG( exp, msg, devObj, irp, urb ) \ if (!(exp)) { \ static ULONG _UsbVerifyWarningState = 0x0; \ UsbVerify_Warning( msg, devObj, irp, urb, &_UsbVerifyWarningState); \ } #define ASSERT_AS_WARNING 0x00000001 #define ASSERT_REMOVED 0x00000010 #define USB_VERIFY_PF_RESETTING 0x10000000 #define USB_VERIFY_PF_ABORTING 0x20000000 // // Prototypes // VOID UsbVerify_Assert( PCHAR Msg, PDEVICE_OBJECT DeviceObject, PIRP Irp, PURB Urb, PULONG AssertState ); VOID UsbVerify_Warning( PCHAR Msg, PDEVICE_OBJECT DeviceObject, PIRP Irp, PURB Urb, PULONG WarningState ); NTSTATUS UsbVerify_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT BusDeviceObject ); NTSTATUS UsbVerify_Complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS UsbVerify_UrbComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS UsbVerify_CreateClose ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS UsbVerify_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS UsbVerify_InternIoCtl ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS UsbVerify_UsbSubmitUrb( PDEVICE_OBJECT DeviceObject, PIRP Irp ); NTSTATUS UsbVerify_IoCtl ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS UsbVerify_PnP ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS UsbVerify_Power ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID UsbVerify_Unload ( IN PDRIVER_OBJECT DriverObject ); VOID UsbVerify_InitLog( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_DestroyLog( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_Log ( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, PUSB_VERIFY_LOG_ENTRY LogEntry ); /* PUNICODE_STRING UsbVerify_GetRegistryPath( PDRIVER_OBJECT DriverObject ); */ #define UsbVerify_GetRegistryPath(DriverObject) \ (PUNICODE_STRING)IoGetDriverObjectExtension(DriverObject, (PVOID) 1) NTSTATUS UsbVerify_QueryKey ( IN HANDLE Handle, IN PWCHAR ValueNameString, OUT PVOID Data, IN ULONG DataLength ); VOID UsbVerify_InitializeFromRegistry( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, HANDLE Handle ); HANDLE UsbVerify_OpenServiceParameters( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_RemoveDevice( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_StartDevice( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); NTSTATUS UsbVerify_SendIrpSynchronously( PDEVICE_OBJECT DeviceObject, PIRP Irp ); NTSTATUS UsbVerify_SendUrbSynchronously( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, PIRP Irp, PURB OldUrb ); VOID UsbVerify_PostVerifyUrb( PDEVICE_OBJECT DeviceObject, PIRP Irp ); VOID UsbVerify_PostProcessUrb( PDEVICE_OBJECT DeviceObject, PIRP Irp, PURB OldUrb ); VOID UsbVerify_PreProcessUrb( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, PIRP Irp, PURB *OriginalIrb ); VOID UsbVerify_FreePendingUrbsList( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_CheckReplacedUrbs( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension ); VOID UsbVerify_LogError( ULONG StringIndex, PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, PIRP Irp, PURB Urb ); VOID UsbVerify_InitializeInterfaceList( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, ULONG NumberOfInterfaces, BOOLEAN RemoveOldEntries ); VOID UsbVerify_InterfaceListAddInterface( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, PUSBD_INTERFACE_INFORMATION NewInterface ); VOID UsbVerify_ClearInterfaceList( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, USB_VERIFY_REMOVAL_CAUSE Cause ); PUSBD_PIPE_INFORMATION UsbVerify_ValidatePipe( PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension, USBD_PIPE_HANDLE PipeHandle ); #endif // USBVERIFY_H