Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

265 lines
12 KiB

/*
*************************************************************************
* File: USBCCGP.H
*
* Module: USBCCGP.SYS
* USB Common Class Generic Parent driver.
*
* Copyright (c) 1998 Microsoft Corporation
*
*
* Author: ervinp
*
*************************************************************************
*/
#include <msosdesc.h> // 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);