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.

297 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. #pragma alloc_text(PAGE, WaitForLowerDriverToCompleteIrp)
  16. NTSTATUS
  17. IoCompletionSetEvent(
  18. IN PDEVICE_OBJECT DeviceObject,
  19. IN PIRP Irp,
  20. IN PKEVENT pdoIoCompletedEvent
  21. )
  22. {
  23. #if DBG
  24. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  25. UCHAR *Pnp="PnP";
  26. UCHAR *Power="Power";
  27. UCHAR *Create="Create";
  28. UCHAR *Close="Close";
  29. UCHAR *Other="Other";
  30. PUCHAR IrpType;
  31. switch(irpSp->MajorFunction) {
  32. case IRP_MJ_PNP:
  33. IrpType=Pnp;
  34. break;
  35. case IRP_MJ_CREATE:
  36. IrpType=Create;
  37. break;
  38. case IRP_MJ_CLOSE:
  39. IrpType=Close;
  40. break;
  41. default:
  42. IrpType=Other;
  43. break;
  44. }
  45. D_PNP(DbgPrint("IRENUM: Setting event for %s wait, completed with %08lx\n",IrpType,Irp->IoStatus.Status);)
  46. #endif
  47. KeSetEvent(pdoIoCompletedEvent, IO_NO_INCREMENT, FALSE);
  48. return STATUS_MORE_PROCESSING_REQUIRED;
  49. }
  50. NTSTATUS
  51. WaitForLowerDriverToCompleteIrp(
  52. PDEVICE_OBJECT TargetDeviceObject,
  53. PIRP Irp,
  54. BOOLEAN CopyCurrentToNext
  55. )
  56. {
  57. NTSTATUS Status;
  58. KEVENT Event;
  59. #if DBG
  60. PIO_STACK_LOCATION IrpSp=IoGetCurrentIrpStackLocation(Irp);
  61. #endif
  62. KeInitializeEvent(
  63. &Event,
  64. NotificationEvent,
  65. FALSE
  66. );
  67. if (CopyCurrentToNext) {
  68. IoCopyCurrentIrpStackLocationToNext(Irp);
  69. }
  70. IoSetCompletionRoutine(
  71. Irp,
  72. IoCompletionSetEvent,
  73. &Event,
  74. TRUE,
  75. TRUE,
  76. TRUE
  77. );
  78. Status = IoCallDriver(TargetDeviceObject, Irp);
  79. if (Status == STATUS_PENDING) {
  80. D_ERROR(DbgPrint("IRENUM: Waiting for PDO\n");)
  81. KeWaitForSingleObject(
  82. &Event,
  83. Executive,
  84. KernelMode,
  85. FALSE,
  86. NULL
  87. );
  88. }
  89. #if DBG
  90. ASSERT(IrpSp == IoGetCurrentIrpStackLocation(Irp));
  91. RtlZeroMemory(&Event,sizeof(Event));
  92. #endif
  93. return Irp->IoStatus.Status;
  94. }
  95. #if DBG
  96. NTSTATUS
  97. UnhandledPnpIrpCompletion(
  98. IN PDEVICE_OBJECT DeviceObject,
  99. IN PIRP Irp,
  100. IN PVOID Context
  101. )
  102. {
  103. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  104. D_PNP(DbgPrint("IRENUM: Forwarded IRP, MN func=%d, completed with %08lx\n",irpSp->MinorFunction,Irp->IoStatus.Status);)
  105. return STATUS_SUCCESS;
  106. }
  107. #endif
  108. NTSTATUS
  109. ForwardIrp(
  110. PDEVICE_OBJECT NextDevice,
  111. PIRP Irp
  112. )
  113. {
  114. #if DBG
  115. IoMarkIrpPending(Irp);
  116. IoCopyCurrentIrpStackLocationToNext(Irp);
  117. IoSetCompletionRoutine(
  118. Irp,
  119. UnhandledPnpIrpCompletion,
  120. NULL,
  121. TRUE,
  122. TRUE,
  123. TRUE
  124. );
  125. IoCallDriver(NextDevice, Irp);
  126. return STATUS_PENDING;
  127. #else
  128. IoSkipCurrentIrpStackLocation(Irp);
  129. return IoCallDriver(NextDevice, Irp);
  130. #endif
  131. }
  132. NTSTATUS
  133. GetRegistryKeyValue (
  134. IN PDEVICE_OBJECT Pdo,
  135. IN ULONG DevInstKeyType,
  136. IN PWCHAR KeyNameString,
  137. IN PVOID Data,
  138. IN ULONG DataLength
  139. )
  140. /*++
  141. Routine Description:
  142. Reads a registry key value from an already opened registry key.
  143. Arguments:
  144. Handle Handle to the opened registry key
  145. KeyNameString ANSI string to the desired key
  146. KeyNameStringLength Length of the KeyNameString
  147. Data Buffer to place the key value in
  148. DataLength Length of the data buffer
  149. Return Value:
  150. STATUS_SUCCESS if all works, otherwise status of system call that
  151. went wrong.
  152. --*/
  153. {
  154. UNICODE_STRING keyName;
  155. ULONG length;
  156. PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
  157. NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  158. HANDLE Handle;
  159. PAGED_CODE();
  160. ntStatus = IoOpenDeviceRegistryKey(
  161. Pdo,
  162. DevInstKeyType,
  163. STANDARD_RIGHTS_READ,
  164. &Handle
  165. );
  166. if (NT_SUCCESS(ntStatus)) {
  167. RtlInitUnicodeString (&keyName, KeyNameString);
  168. length = sizeof(KEY_VALUE_FULL_INFORMATION) + DataLength;
  169. PartialInfo = ALLOCATE_PAGED_POOL(length);
  170. if (PartialInfo) {
  171. ntStatus = ZwQueryValueKey (Handle,
  172. &keyName,
  173. KeyValuePartialInformation,
  174. PartialInfo,
  175. length,
  176. &length);
  177. if (NT_SUCCESS(ntStatus)) {
  178. //
  179. // If there is enough room in the data buffer, copy the output
  180. //
  181. if (DataLength >= PartialInfo->DataLength) {
  182. RtlCopyMemory (Data,
  183. PartialInfo->Data,
  184. PartialInfo->DataLength);
  185. } else {
  186. ntStatus=STATUS_BUFFER_TOO_SMALL;
  187. }
  188. } else {
  189. D_ERROR(DbgPrint("IRENUM: could not query value, %08lx\n",ntStatus);)
  190. }
  191. FREE_POOL(PartialInfo);
  192. }
  193. ZwClose(Handle);
  194. } else {
  195. D_ERROR(DbgPrint("IRENUM: could open device reg key, %08lx\n",ntStatus);)
  196. }
  197. return ntStatus;
  198. }