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.

230 lines
6.2 KiB

  1. /*
  2. *************************************************************************
  3. * File: USBCCGP.C
  4. *
  5. * Module: USBCCGP.SYS
  6. * USB Common Class Generic Parent driver.
  7. *
  8. * Copyright (c) 1998 Microsoft Corporation
  9. *
  10. *
  11. * Author: ervinp
  12. *
  13. *************************************************************************
  14. */
  15. #include <wdm.h>
  16. #include <usbdi.h>
  17. #include <usbdlib.h>
  18. #include <usbioctl.h>
  19. #include "usbccgp.h"
  20. #include "debug.h"
  21. #ifdef ALLOC_PRAGMA
  22. #pragma alloc_text(PAGE, DriverEntry)
  23. #pragma alloc_text(PAGE, USBC_AddDevice)
  24. #pragma alloc_text(PAGE, USBC_DriverUnload)
  25. #pragma alloc_text(PAGE, RegQueryGenericCompositeUSBDeviceString)
  26. #endif
  27. PWCHAR GenericCompositeUSBDeviceString = NULL;
  28. NTSTATUS GetConfigValue(
  29. IN PWSTR ValueName,
  30. IN ULONG ValueType,
  31. IN PVOID ValueData,
  32. IN ULONG ValueLength,
  33. IN PVOID Context,
  34. IN PVOID EntryContext
  35. )
  36. /*++
  37. Routine Description:
  38. This routine is a callback routine for RtlQueryRegistryValues
  39. It is called for each entry in the Parameters
  40. node to set the config values. The table is set up
  41. so that this function will be called with correct default
  42. values for keys that are not present.
  43. Arguments:
  44. ValueName - The name of the value (ignored).
  45. ValueType - The type of the value
  46. ValueData - The data for the value.
  47. ValueLength - The length of ValueData.
  48. Context - A pointer to the CONFIG structure.
  49. EntryContext - The index in Config->Parameters to save the value.
  50. Return Value:
  51. --*/
  52. {
  53. NTSTATUS ntStatus = STATUS_SUCCESS;
  54. PWCHAR tmpStr;
  55. switch (ValueType) {
  56. // case REG_DWORD:
  57. // *(PVOID*)EntryContext = *(PVOID*)ValueData;
  58. // break;
  59. // case REG_BINARY:
  60. // RtlCopyMemory(EntryContext, ValueData, ValueLength);
  61. // break;
  62. case REG_SZ:
  63. if (ValueLength) {
  64. tmpStr = ExAllocatePool(PagedPool, ValueLength);
  65. if (tmpStr) {
  66. RtlZeroMemory(tmpStr, ValueLength);
  67. RtlCopyMemory(tmpStr, ValueData, ValueLength);
  68. *(PWCHAR *)EntryContext = tmpStr;
  69. } else {
  70. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  71. }
  72. } else {
  73. ntStatus = STATUS_INVALID_PARAMETER;
  74. }
  75. break;
  76. default:
  77. // TEST_TRAP();
  78. ntStatus = STATUS_INVALID_PARAMETER;
  79. }
  80. return ntStatus;
  81. }
  82. NTSTATUS RegQueryGenericCompositeUSBDeviceString(IN OUT PWCHAR *GenericCompositeUSBDeviceString)
  83. {
  84. NTSTATUS ntStatus;
  85. RTL_QUERY_REGISTRY_TABLE QueryTable[2];
  86. PWCHAR usbstr = L"usbflags";
  87. PWCHAR valuename = L"GenericCompositeUSBDeviceString";
  88. PAGED_CODE();
  89. //
  90. // Set up QueryTable to do the following:
  91. //
  92. // Upgrade install flag
  93. QueryTable[0].QueryRoutine = GetConfigValue;
  94. QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
  95. QueryTable[0].Name = valuename;
  96. QueryTable[0].EntryContext = GenericCompositeUSBDeviceString;
  97. QueryTable[0].DefaultType = 0;
  98. QueryTable[0].DefaultData = NULL;
  99. QueryTable[0].DefaultLength = 0;
  100. //
  101. // Stop
  102. //
  103. QueryTable[1].QueryRoutine = NULL;
  104. QueryTable[1].Flags = 0;
  105. QueryTable[1].Name = NULL;
  106. ntStatus = RtlQueryRegistryValues(
  107. RTL_REGISTRY_CONTROL,
  108. usbstr,
  109. QueryTable, // QueryTable
  110. NULL, // Context
  111. NULL); // Environment
  112. return ntStatus;
  113. }
  114. NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObj, IN PUNICODE_STRING uniRegistryPath)
  115. {
  116. PAGED_CODE();
  117. driverObj->MajorFunction[IRP_MJ_CREATE] =
  118. driverObj->MajorFunction[IRP_MJ_CLOSE] =
  119. driverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
  120. driverObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
  121. driverObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
  122. driverObj->MajorFunction[IRP_MJ_PNP] =
  123. driverObj->MajorFunction[IRP_MJ_POWER] = USBC_Dispatch;
  124. driverObj->DriverUnload = USBC_DriverUnload;
  125. driverObj->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)USBC_AddDevice;
  126. RegQueryGenericCompositeUSBDeviceString(&GenericCompositeUSBDeviceString);
  127. return STATUS_SUCCESS;
  128. }
  129. /*
  130. * USBC_AddDevice
  131. *
  132. */
  133. NTSTATUS USBC_AddDevice(IN PDRIVER_OBJECT driverObj, IN PDEVICE_OBJECT pdo)
  134. {
  135. NTSTATUS status;
  136. PDEVICE_OBJECT fdo = NULL;
  137. PAGED_CODE();
  138. status = IoCreateDevice( driverObj,
  139. sizeof(DEVEXT),
  140. NULL, // name for this device
  141. FILE_DEVICE_UNKNOWN,
  142. FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
  143. FALSE, // not exclusive
  144. &fdo); // our device object
  145. if (NT_SUCCESS(status)){
  146. PDEVEXT devExt;
  147. PPARENT_FDO_EXT parentFdoExt;
  148. ASSERT(fdo);
  149. devExt = (PDEVEXT)fdo->DeviceExtension;
  150. RtlZeroMemory(devExt, sizeof(DEVEXT));
  151. devExt->signature = USBCCGP_TAG;
  152. devExt->isParentFdo = TRUE;
  153. parentFdoExt = &devExt->parentFdoExt;
  154. parentFdoExt->driverObj = driverObj;
  155. parentFdoExt->pdo = pdo;
  156. parentFdoExt->fdo = fdo;
  157. parentFdoExt->state = STATE_INITIALIZED;
  158. parentFdoExt->topDevObj = IoAttachDeviceToDeviceStack(fdo, pdo);
  159. parentFdoExt->pendingActionCount = 0;
  160. KeInitializeEvent(&parentFdoExt->removeEvent, NotificationEvent, FALSE);
  161. KeInitializeSpinLock(&parentFdoExt->parentFdoExtSpinLock);
  162. InitializeListHead(&parentFdoExt->functionWaitWakeIrpQueue);
  163. InitializeListHead(&parentFdoExt->pendingResetPortIrpQueue);
  164. InitializeListHead(&parentFdoExt->pendingCyclePortIrpQueue);
  165. fdo->Flags |= (parentFdoExt->topDevObj->Flags & DO_POWER_PAGABLE);
  166. fdo->Flags &= ~DO_DEVICE_INITIALIZING;
  167. DBGVERBOSE(("Created parent FDO %p", pdo));
  168. }
  169. ASSERT(NT_SUCCESS(status));
  170. return status;
  171. }
  172. VOID USBC_DriverUnload(IN PDRIVER_OBJECT DriverObject)
  173. {
  174. PAGED_CODE();
  175. if (GenericCompositeUSBDeviceString) {
  176. ExFreePool(GenericCompositeUSBDeviceString);
  177. GenericCompositeUSBDeviceString = NULL;
  178. }
  179. }