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.

276 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. initunlo.c
  5. Abstract:
  6. This module contains the code that is very specific to initialization
  7. and unload operations in the irenum driver
  8. Author:
  9. Brian Lieuallen, 7-13-2000
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "internal.h"
  15. ULONG DebugFlags;
  16. ULONG DebugMemoryTag='nErI';
  17. PVOID PagedCodeSectionHandle;
  18. UNICODE_STRING DriverEntryRegPath;
  19. ULONG EnumStaticDevice=0;
  20. NTSTATUS
  21. DriverEntry(
  22. IN PDRIVER_OBJECT DriverObject,
  23. IN PUNICODE_STRING RegistryPath
  24. );
  25. VOID
  26. IrEnumUnload(
  27. IN PDRIVER_OBJECT DriverObject
  28. );
  29. NTSTATUS
  30. UnHandledDispatch(
  31. PDEVICE_OBJECT DeviceObject,
  32. PIRP Irp
  33. );
  34. #pragma alloc_text(INIT,DriverEntry)
  35. #pragma alloc_text(PAGE,IrEnumUnload)
  36. NTSTATUS
  37. DriverEntry(
  38. IN PDRIVER_OBJECT DriverObject,
  39. IN PUNICODE_STRING RegistryPath
  40. )
  41. /*++
  42. Routine Description:
  43. The entry point that the system point calls to initialize
  44. any driver.
  45. Arguments:
  46. DriverObject - Just what it says, really of little use
  47. to the driver itself, it is something that the IO system
  48. cares more about.
  49. PathToRegistry - points to the entry for this driver
  50. in the current control set of the registry.
  51. Return Value:
  52. STATUS_SUCCESS if we could initialize a single device,
  53. otherwise STATUS_NO_SUCH_DEVICE.
  54. --*/
  55. {
  56. //
  57. // We use this to query into the registry as to whether we
  58. // should break at driver entry.
  59. //
  60. RTL_QUERY_REGISTRY_TABLE paramTable[4];
  61. ULONG zero = 0;
  62. ULONG debugLevel = 0;
  63. ULONG debugFlags = 0;
  64. ULONG shouldBreak = 0;
  65. DriverEntryRegPath.Length=RegistryPath->Length;
  66. DriverEntryRegPath.MaximumLength=DriverEntryRegPath.Length+sizeof(WCHAR);
  67. DriverEntryRegPath.Buffer=ALLOCATE_PAGED_POOL(DriverEntryRegPath.MaximumLength);
  68. if (DriverEntryRegPath.Buffer == NULL) {
  69. return STATUS_INSUFFICIENT_RESOURCES;
  70. }
  71. RtlCopyMemory(
  72. DriverEntryRegPath.Buffer,
  73. RegistryPath->Buffer,
  74. RegistryPath->Length
  75. );
  76. //
  77. // NULL terminate the string
  78. //
  79. DriverEntryRegPath.Buffer[RegistryPath->Length/sizeof(WCHAR)]=L'\0';
  80. //
  81. // Since the registry path parameter is a "counted" UNICODE string, it
  82. // might not be zero terminated. For a very short time allocate memory
  83. // to hold the registry path zero terminated so that we can use it to
  84. // delve into the registry.
  85. //
  86. RtlZeroMemory(
  87. &paramTable[0],
  88. sizeof(paramTable)
  89. );
  90. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  91. paramTable[0].Name = L"BreakOnEntry";
  92. paramTable[0].EntryContext = &shouldBreak;
  93. paramTable[0].DefaultType = REG_DWORD;
  94. paramTable[0].DefaultData = &zero;
  95. paramTable[0].DefaultLength = sizeof(ULONG);
  96. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  97. paramTable[1].Name = L"DebugFlags";
  98. paramTable[1].EntryContext = &debugFlags;
  99. paramTable[1].DefaultType = REG_DWORD;
  100. paramTable[1].DefaultData = &zero;
  101. paramTable[1].DefaultLength = sizeof(ULONG);
  102. paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  103. paramTable[2].Name = L"EnumStaticDevice";
  104. paramTable[2].EntryContext = &EnumStaticDevice;
  105. paramTable[2].DefaultType = REG_DWORD;
  106. paramTable[2].DefaultData = &zero;
  107. paramTable[2].DefaultLength = sizeof(ULONG);
  108. if (!NT_SUCCESS(RtlQueryRegistryValues(
  109. RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  110. DriverEntryRegPath.Buffer,
  111. &paramTable[0],
  112. NULL,
  113. NULL
  114. ))) {
  115. shouldBreak = 0;
  116. }
  117. #if DBG
  118. DebugFlags=debugFlags;
  119. #endif
  120. if (shouldBreak) {
  121. DbgBreakPoint();
  122. }
  123. //
  124. // pnp driver entry point
  125. //
  126. DriverObject->DriverExtension->AddDevice = IrEnumAddDevice;
  127. //
  128. // Initialize the Driver Object with driver's entry points
  129. //
  130. DriverObject->DriverUnload = IrEnumUnload;
  131. {
  132. ULONG i;
  133. for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  134. DriverObject->MajorFunction[i]=UnHandledDispatch;
  135. }
  136. }
  137. DriverObject->MajorFunction[IRP_MJ_PNP] = IrEnumPnP;
  138. DriverObject->MajorFunction[IRP_MJ_POWER] = IrEnumPower;
  139. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IrEnumWmi;
  140. D_PNP(DbgPrint("IRENUM: DriverEntry\n");)
  141. //
  142. // lock and unlock here so we can get a handle to the section
  143. // so future calls will be faster
  144. //
  145. PagedCodeSectionHandle=MmLockPagableCodeSection(IrEnumUnload);
  146. MmUnlockPagableImageSection(PagedCodeSectionHandle);
  147. return STATUS_SUCCESS;
  148. }
  149. VOID
  150. IrEnumUnload(
  151. IN PDRIVER_OBJECT DriverObject
  152. )
  153. {
  154. D_PNP(DbgPrint("IRENUM: UnLoad\n");)
  155. FREE_POOL(DriverEntryRegPath.Buffer);
  156. return;
  157. }
  158. NTSTATUS
  159. UnHandledDispatch(
  160. PDEVICE_OBJECT DeviceObject,
  161. PIRP Irp
  162. )
  163. {
  164. NTSTATUS Status=STATUS_NOT_SUPPORTED;
  165. PFDO_DEVICE_EXTENSION DeviceExtension=DeviceObject->DeviceExtension;
  166. if (DeviceExtension->DoType == DO_TYPE_FDO) {
  167. //
  168. // this irp is for the parent devnode, just send it down the stack
  169. //
  170. IoSkipCurrentIrpStackLocation(Irp);
  171. Status=IoCallDriver(DeviceExtension->LowerDevice, Irp);
  172. } else {
  173. //
  174. // this irp is for the child PDO, it does not handle this irp
  175. // since it is at the bottom of the stack by definition, it can only complete it
  176. //
  177. #if DBG
  178. PIO_STACK_LOCATION IrpSp=IoGetCurrentIrpStackLocation(Irp);
  179. D_ERROR(DbgPrint("IRENUM: Unhandled irp for PDO: mj= %x\n",IrpSp->MajorFunction);)
  180. #endif
  181. Irp->IoStatus.Status=Status;
  182. Irp->IoStatus.Information=0;
  183. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  184. }
  185. return Status;
  186. }