/* ************************************************************************* * File: USBCCGP.H * * Module: USBCCGP.SYS * USB Common Class Generic Parent driver. * * Copyright (c) 1998 Microsoft Corporation * * * Author: ervinp * ************************************************************************* */ #include // Internal definitions for MS OS Desc. /* * USBCCGP signature tag for memory allocations */ #define USBCCGP_TAG (ULONG)'CbsU' #define GUARD_WORD 'draG' extern PWCHAR GenericCompositeUSBDeviceString; enum deviceState { STATE_INITIALIZED, STATE_STARTING, STATE_STARTED, STATE_START_FAILED, STATE_STOPPING, STATE_STOPPED, // implies device was previously started successfully STATE_SUSPENDED, STATE_REMOVING, STATE_REMOVED }; typedef struct PARENT_FDO_EXTENSION { enum deviceState state; PDRIVER_OBJECT driverObj; PDEVICE_OBJECT pdo; PDEVICE_OBJECT fdo; PDEVICE_OBJECT topDevObj; /* * Counter to keep driver from getting unloaded before all IO completes to us. */ LONG pendingActionCount; KEVENT removeEvent; /* * This buffer will hold a USB_CONFIGURATION_DESCRIPTOR plus * the following interface descriptors. */ PUSB_CONFIGURATION_DESCRIPTOR configDesc; PUSB_CONFIGURATION_DESCRIPTOR selectedConfigDesc; USBD_CONFIGURATION_HANDLE selectedConfigHandle; PUSBD_INTERFACE_LIST_ENTRY interfaceList; USB_DEVICE_DESCRIPTOR deviceDesc; /* * The parent device has some number of functions. * For each function, we create a PDO and store * it in the deviceRelations array. */ ULONG numFunctions; PDEVICE_RELATIONS deviceRelations; /* * deviceCapabilities includes a * table mapping system power states to device power states. */ DEVICE_CAPABILITIES deviceCapabilities; PURB dynamicNotifyUrb; PIRP parentWaitWakeIrp; PIRP currentSetPowerIrp; BOOLEAN isWaitWakePending; LIST_ENTRY functionWaitWakeIrpQueue; // WW irps from function client drivers KSPIN_LOCK parentFdoExtSpinLock; BOOLEAN haveCSInterface; ULONG CSInterfaceNumber; ULONG CSChannelId; BOOLEAN resetPortInProgress; LIST_ENTRY pendingResetPortIrpQueue; BOOLEAN cyclePortInProgress; LIST_ENTRY pendingCyclePortIrpQueue; PIRP pendingIdleIrp; USB_IDLE_CALLBACK_INFO idleCallbackInfo; PMS_EXT_CONFIG_DESC msExtConfigDesc; } PARENT_FDO_EXT, *PPARENT_FDO_EXT; typedef struct FUNCTION_PDO_EXTENSION { ULONG functionIndex; ULONG baseInterfaceNumber; ULONG numInterfaces; enum deviceState state; PDEVICE_OBJECT pdo; PPARENT_FDO_EXT parentFdoExt; /* * functionInterfaceList is a pointer into the parent's interfaceList array. */ PUSBD_INTERFACE_LIST_ENTRY functionInterfaceList; PUSB_CONFIGURATION_DESCRIPTOR dynamicFunctionConfigDesc; USB_DEVICE_DESCRIPTOR functionDeviceDesc; KSPIN_LOCK functionPdoExtSpinLock; PIRP idleNotificationIrp; } FUNCTION_PDO_EXT, *PFUNCTION_PDO_EXT; typedef struct DEVICE_EXTENSION { ULONG signature; /* * Does the associated device object represent * the parent FDO that we attached to the device object * we got from USBHUB * (as opposed to the function PDO we created * to represent a single function on that device) ? */ BOOLEAN isParentFdo; union { PARENT_FDO_EXT parentFdoExt; FUNCTION_PDO_EXT functionPdoExt; }; } DEVEXT, *PDEVEXT; typedef struct _USB_REQUEST_TIMEOUT_CONTEXT { PKEVENT event; PLONG lock; } USB_REQUEST_TIMEOUT_CONTEXT, *PUSB_REQUEST_TIMEOUT_CONTEXT; #define ALLOCPOOL(pooltype, size) ExAllocatePoolWithTag(pooltype, size, USBCCGP_TAG) #define FREEPOOL(ptr) ExFreePool(ptr) #define MAX(a, b) (((a) >= (b)) ? (a) : (b)) #define MIN(a, b) (((a) <= (b)) ? (a) : (b)) #define POINTER_DISTANCE(ptr1, ptr2) (ULONG)(((PUCHAR)(ptr1))-((PUCHAR)(ptr2))) // Counting the byte count of an ascii string or wide char string // #define STRLEN( Length, p )\ {\ int i;\ for ( i=0; (p)[i]; i++ );\ Length = i*sizeof(*p);\ } /* * We use this value, which is guaranteed to never be defined as a status by the kernel, * as a default status code to indicate "do nothing and pass the irp down". */ #define NO_STATUS 0x80000000 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING UniRegistryPath); NTSTATUS USBC_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject); VOID USBC_DriverUnload(IN PDRIVER_OBJECT DriverObject); NTSTATUS USBC_Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS USBC_Create(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_Close(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_DeviceControl(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_SystemControl(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_InternalDeviceControl(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_PnP(PDEVEXT devExt, PIRP irp); NTSTATUS USBC_PnpComplete(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context); NTSTATUS USBC_Power(PDEVEXT devExt, PIRP irp); NTSTATUS CreateStaticFunctionPDOs(PPARENT_FDO_EXT fdoExt); NTSTATUS TryGetConfigDescriptor(PPARENT_FDO_EXT parentFdoExt); NTSTATUS GetConfigDescriptor(PPARENT_FDO_EXT fdoExt); VOID PrepareParentFDOForRemove(PPARENT_FDO_EXT parentFdoExt); VOID FreeParentFDOResources(PPARENT_FDO_EXT fdoExt); PWCHAR BuildCompatibleIDs(IN PUCHAR CompatibleID, IN PUCHAR SubCompatibleID, IN UCHAR Class, IN UCHAR SubClass, IN UCHAR Protocol); NTSTATUS QueryFunctionPdoID(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS QueryParentDeviceRelations(PPARENT_FDO_EXT parentFdoExt, PIRP irp); NTSTATUS QueryFunctionDeviceRelations(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS QueryFunctionCapabilities(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS HandleParentFdoPower(PPARENT_FDO_EXT parentFdoExt, PIRP irp); NTSTATUS HandleFunctionPdoPower(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); VOID ParentPowerRequestCompletion(IN PDEVICE_OBJECT devObj, IN UCHAR minorFunction, IN POWER_STATE powerState, IN PVOID context, IN PIO_STATUS_BLOCK ioStatus); NTSTATUS StartParentFdo(PPARENT_FDO_EXT parentFdoExt, PIRP irp); NTSTATUS QueryFunctionCapabilities(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS ParentPdoPowerCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context); NTSTATUS FunctionInternalDeviceControl(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS ParentInternalDeviceControl(PPARENT_FDO_EXT parentFdoExt, PIRP irp); NTSTATUS ParentResetOrCyclePort(PPARENT_FDO_EXT parentFdoExt, PIRP irp, ULONG ioControlCode); NTSTATUS BuildFunctionConfigurationDescriptor(PFUNCTION_PDO_EXT functionPdoExt, PUCHAR buffer, ULONG bufferLength, PULONG bytesReturned); VOID FreeFunctionPDOResources(PFUNCTION_PDO_EXT functionPdoExt); NTSTATUS GetParentFdoCapabilities(PPARENT_FDO_EXT parentFdoExt); NTSTATUS CallDriverSyncCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context); NTSTATUS CallDriverSync(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); NTSTATUS CallNextDriverSync(PPARENT_FDO_EXT parentFdoExt, PIRP irp); VOID IncrementPendingActionCount(PPARENT_FDO_EXT parentFdoExt); VOID DecrementPendingActionCount(PPARENT_FDO_EXT parentFdoExt); PWCHAR AppendInterfaceNumber(PWCHAR oldIDs, ULONG interfaceNum); PVOID MemDup(PVOID dataPtr, ULONG length); ULONG WStrLen(PWCHAR str); ULONG WStrCpy(PWCHAR dest, PWCHAR src); BOOLEAN WStrCompareN(PWCHAR str1, PWCHAR str2, ULONG maxChars); NTSTATUS GetDeviceDescriptor(PPARENT_FDO_EXT parentFdoExt); NTSTATUS SubmitUrb(PPARENT_FDO_EXT parentFdoExt, PURB urb, BOOLEAN synchronous, PVOID completionRoutine, PVOID completionContext); NTSTATUS UrbFunctionSelectConfiguration(PFUNCTION_PDO_EXT functionPdoExt, PURB urb); NTSTATUS UrbFunctionGetDescriptorFromDevice(PFUNCTION_PDO_EXT functionPdoExt, PURB urb); PFUNCTION_PDO_EXT FindFunctionByIndex(PPARENT_FDO_EXT parentFdoExt, ULONG functionIndex); PUSBD_INTERFACE_LIST_ENTRY GetFunctionInterfaceListBase(PPARENT_FDO_EXT parentFdoExt, ULONG functionIndex, PULONG numFunctionInterfaces); PDEVICE_RELATIONS CopyDeviceRelations(PDEVICE_RELATIONS deviceRelations); PUSBD_INTERFACE_LIST_ENTRY GetInterfaceList(PPARENT_FDO_EXT parentFdoExt, PUSB_CONFIGURATION_DESCRIPTOR configDesc); VOID FreeInterfaceList(PPARENT_FDO_EXT parentFdoExt, BOOLEAN freeListItself); NTSTATUS ParentSelectConfiguration(PPARENT_FDO_EXT parentFdoExt, PUSB_CONFIGURATION_DESCRIPTOR configDesc, PUSBD_INTERFACE_LIST_ENTRY interfaceList); VOID ParentCloseConfiguration(PPARENT_FDO_EXT parentFdoExt); NTSTATUS GetStringDescriptor(PPARENT_FDO_EXT parentFdoExt, UCHAR stringIndex, LANGID langId, PUSB_STRING_DESCRIPTOR stringDesc, ULONG bufferLen); NTSTATUS SetPdoRegistryParameter(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PWCHAR KeyName, IN PVOID Data, IN ULONG DataLength, IN ULONG KeyType, IN ULONG DevInstKeyType); NTSTATUS GetPdoRegistryParameter(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PWCHAR ValueName, OUT PVOID Data, IN ULONG DataLength, OUT PULONG Type, OUT PULONG ActualDataLength); NTSTATUS GetMsOsFeatureDescriptor(PPARENT_FDO_EXT ParentFdoExt, UCHAR Recipient, UCHAR InterfaceNumber, USHORT Index, PVOID DataBuffer, ULONG DataBufferLength, PULONG BytesReturned); NTSTATUS GetMsExtendedConfigDescriptor(IN PPARENT_FDO_EXT ParentFdoExt); BOOLEAN ValidateMsExtendedConfigDescriptor(IN PMS_EXT_CONFIG_DESC MsExtConfigDesc, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); NTSTATUS GetDeviceText(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); NTSTATUS EnqueueFunctionWaitWakeIrp(PFUNCTION_PDO_EXT functionPdoExt, PIRP irp); VOID FunctionWaitWakeIrpCancelRoutine(IN PDEVICE_OBJECT deviceObject, IN PIRP irp); NTSTATUS SubmitParentWaitWakeIrp(PPARENT_FDO_EXT parentFdoExt); NTSTATUS ParentWaitWakeComplete(IN PDEVICE_OBJECT deviceObject, IN UCHAR minorFunction, IN POWER_STATE powerState, IN PVOID context, IN PIO_STATUS_BLOCK ioStatus); VOID CompleteAllFunctionWaitWakeIrps(PPARENT_FDO_EXT parentFdoExt, NTSTATUS status); VOID CompleteAllFunctionIdleIrps(PPARENT_FDO_EXT parentFdoExt, NTSTATUS status); VOID InstallExtPropDesc(IN PFUNCTION_PDO_EXT FunctionPdoExt); VOID InstallExtPropDescSections(PDEVICE_OBJECT DeviceObject, PMS_EXT_PROP_DESC pMsExtPropDesc); NTSTATUS ParentDeviceControl(PPARENT_FDO_EXT parentFdoExt, PIRP irp); VOID CompleteFunctionIdleNotification(PFUNCTION_PDO_EXT functionPdoExt); VOID CheckParentIdle(PPARENT_FDO_EXT parentFdoExt); NTSTATUS ParentSetD0(IN PPARENT_FDO_EXT parentFdoExt); NTSTATUS USBC_SetContentId(IN PIRP irp, IN PVOID pKsProperty, IN PVOID pvData); NTSTATUS RegQueryGenericCompositeUSBDeviceString(PWCHAR *GenericCompositeUSBDeviceString);