2025-04-27 07:49:33 -04:00

652 lines
16 KiB
C

/*++
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 <wdm.h>
#include <usbioctl.h>
#include <usbdi.h>
#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