ReactOS  0.4.15-dev-3712-gf1ad684
pnproot.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * COPYRIGHT: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/pnpmgr/pnproot.c
5  * PURPOSE: PnP manager root device
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * Copyright 2007 Herv? Poussineau (hpoussin@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS *******************************************************************/
17 
18 #define ENUM_NAME_ROOT L"Root"
19 
20 /* DATA **********************************************************************/
21 
22 typedef struct _PNPROOT_DEVICE
23 {
24  // Entry on device list
26  // Physical Device Object of device
28  // Device ID
30  // Instance ID
32  // Device description
34  // Resource requirement list
36  // Associated resource list
40 
41 typedef enum
42 {
49 
51 {
52  // Wether this device extension is for an FDO or PDO
55 
56 /* Physical Device Object device extension for a child device */
58 {
59  // Common device data
61  // Informations about the device
64 
65 /* Physical Device Object device extension for the Root bus device object */
67 {
68  // Common device data
70  // Lower device object
72  // Current state of the driver
74  // Namespace device list
76  // Number of (not removed) devices in device list
78  // Lock for namespace device list
81 
82 typedef struct _BUFFER
83 {
86 } BUFFER, *PBUFFER;
87 
89 
90 /* FUNCTIONS *****************************************************************/
91 
92 static NTSTATUS
94  IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
95  IN PCUNICODE_STRING DeviceId,
97  OUT PPNPROOT_DEVICE* ChildDevice OPTIONAL)
98 {
100  UNICODE_STRING InstanceIdU;
101  PLIST_ENTRY NextEntry;
102 
103  /* Initialize the string to compare */
104  RtlInitUnicodeString(&InstanceIdU, InstanceId);
105 
106  /* Start looping */
107  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
108  NextEntry != &DeviceExtension->DeviceListHead;
109  NextEntry = NextEntry->Flink)
110  {
111  /* Get the entry */
112  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
113 
114  /* See if the strings match */
115  if (RtlEqualUnicodeString(DeviceId, &Device->DeviceID, TRUE) &&
116  RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
117  {
118  /* They do, so set the pointer and return success */
119  if (ChildDevice)
120  *ChildDevice = Device;
121  return STATUS_SUCCESS;
122  }
123  }
124 
125  /* No device found */
126  return STATUS_NO_SUCH_DEVICE;
127 }
128 
129 NTSTATUS
132 {
136  PWSTR InstancePath;
137  UNICODE_STRING InstancePathCopy;
138 
140  if (!Device) return STATUS_NO_MEMORY;
141 
143  if (!RtlCreateUnicodeString(&InstancePathCopy, DeviceNode->InstancePath.Buffer))
144  {
146  return STATUS_NO_MEMORY;
147  }
148 
149  InstancePath = wcsrchr(InstancePathCopy.Buffer, L'\\');
150  ASSERT(InstancePath);
151 
152  if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath + 1))
153  {
154  RtlFreeUnicodeString(&InstancePathCopy);
156  return STATUS_NO_MEMORY;
157  }
158 
159  InstancePath[0] = UNICODE_NULL;
160 
161  if (!RtlCreateUnicodeString(&Device->DeviceID, InstancePathCopy.Buffer))
162  {
163  RtlFreeUnicodeString(&InstancePathCopy);
164  RtlFreeUnicodeString(&Device->InstanceID);
166  return STATUS_NO_MEMORY;
167  }
168 
169  InstancePath[0] = L'\\';
170 
171  Device->Pdo = DeviceObject;
172 
173  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
174  InsertTailList(&DeviceExtension->DeviceListHead,
175  &Device->ListEntry);
176  DeviceExtension->DeviceListCount++;
177  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
178 
179  RtlFreeUnicodeString(&InstancePathCopy);
180 
181  return STATUS_SUCCESS;
182 }
183 
184 /* Creates a new PnP device for a legacy driver */
185 NTSTATUS
190  OUT OPTIONAL PUNICODE_STRING FullInstancePath)
191 {
192  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
193  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
194  UNICODE_STRING DevicePath;
195  WCHAR InstancePath[5];
198  UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
199  ULONG NextInstance;
200  UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
201  HANDLE EnumHandle, DeviceKeyHandle = NULL, InstanceKeyHandle;
204 
205  DeviceExtension = PnpRootDeviceObject->DeviceExtension;
206  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
207 
208  DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
209 
210  DevicePath.Length = 0;
211  DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + ServiceName->Length;
213  DevicePath.MaximumLength,
214  TAG_PNP_ROOT);
215  if (DevicePath.Buffer == NULL)
216  {
217  DPRINT1("ExAllocatePoolWithTag() failed\n");
219  goto cleanup;
220  }
223 
224  /* Initialize a PNPROOT_DEVICE structure */
226  if (!Device)
227  {
228  DPRINT("ExAllocatePoolWithTag() failed\n");
230  goto cleanup;
231  }
233  Device->DeviceID = DevicePath;
234  RtlInitEmptyUnicodeString(&DevicePath, NULL, 0);
235 
236  Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
237  if (NT_SUCCESS(Status))
238  {
240  &Device->DeviceID,
242  EnumHandle,
243  NULL);
244  Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
245  ObCloseHandle(EnumHandle, KernelMode);
246  }
247 
248  if (!NT_SUCCESS(Status))
249  {
250  DPRINT1("Failed to open registry key\n");
251  goto cleanup;
252  }
253 
254 tryagain:
256  QueryTable[0].Name = L"NextInstance";
257  QueryTable[0].EntryContext = &NextInstance;
259 
261  (PWSTR)DeviceKeyHandle,
262  QueryTable,
263  NULL,
264  NULL);
265  for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
266  {
267  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
268  Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
270  break;
271  }
272 
273  if (NextInstance > 9999)
274  {
275  DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
277  goto cleanup;
278  }
279 
280  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
281  Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
282  if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
283  {
284  DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
286  (PWSTR)DeviceKeyHandle,
287  L"NextInstance");
288  goto tryagain;
289  }
290 
291  NextInstance++;
293  (PWSTR)DeviceKeyHandle,
294  L"NextInstance",
295  REG_DWORD,
296  &NextInstance,
297  sizeof(NextInstance));
298  if (!NT_SUCCESS(Status))
299  {
300  DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
301  goto cleanup;
302  }
303 
304  if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
305  {
307  goto cleanup;
308  }
309 
310  /* Finish creating the instance path in the registry */
312  &Device->InstanceID,
314  DeviceKeyHandle,
315  NULL);
316  Status = ZwCreateKey(&InstanceKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
317  if (!NT_SUCCESS(Status))
318  {
319  DPRINT1("Failed to create instance path (0x%x)\n", Status);
320  goto cleanup;
321  }
322 
323  /* Just close the handle */
324  ObCloseHandle(InstanceKeyHandle, KernelMode);
325 
326  if (FullInstancePath)
327  {
328  FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
329  FullInstancePath->Length = 0;
330  FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
331  if (!FullInstancePath->Buffer)
332  {
334  goto cleanup;
335  }
336 
337  RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
338  RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
339  RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
340  }
341 
342  /* Initialize a device object */
346  NULL,
349  FALSE,
350  &Device->Pdo);
351  if (!NT_SUCCESS(Status))
352  {
353  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
355  goto cleanup;
356  }
357 
358  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
359  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
360  PdoDeviceExtension->Common.IsFDO = FALSE;
361  PdoDeviceExtension->DeviceInfo = Device;
362 
363  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
364  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
365 
367  &DeviceExtension->DeviceListHead,
368  &Device->ListEntry);
369  DeviceExtension->DeviceListCount++;
370 
372  DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject, &Device->DeviceID, &Device->InstanceID);
373  Device = NULL;
375 
376 cleanup:
377  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
378  if (Device)
379  {
380  if (Device->Pdo)
381  IoDeleteDevice(Device->Pdo);
382  RtlFreeUnicodeString(&Device->DeviceID);
383  RtlFreeUnicodeString(&Device->InstanceID);
385  }
386  RtlFreeUnicodeString(&DevicePath);
387  if (DeviceKeyHandle != NULL)
388  ObCloseHandle(DeviceKeyHandle, KernelMode);
389  return Status;
390 }
391 
392 static NTSTATUS NTAPI
398  IN PVOID Context,
400 {
403 
404  if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
405  {
406  Destination->Length = 0;
409  return STATUS_SUCCESS;
410  }
411 
412  Source.MaximumLength = Source.Length = (USHORT)ValueLength;
413  Source.Buffer = ValueData;
414 
416 }
417 
418 static NTSTATUS NTAPI
424  IN PVOID Context,
426 {
428  PVOID BinaryValue;
429 
430  if (ValueLength == 0)
431  {
432  *Buffer->Data = NULL;
433  return STATUS_SUCCESS;
434  }
435 
437  if (BinaryValue == NULL)
438  return STATUS_NO_MEMORY;
439  RtlCopyMemory(BinaryValue, ValueData, ValueLength);
440  *Buffer->Data = BinaryValue;
441  if (Buffer->Length) *Buffer->Length = ValueLength;
442  return STATUS_SUCCESS;
443 }
444 
445 static
446 NTSTATUS
448  _Inout_ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
449  _Inout_ PUNICODE_STRING DevicePath,
452 {
455  HANDLE DeviceKeyHandle = NULL;
457  BUFFER Buffer1, Buffer2;
458 
459  /* If the device already exists, there's nothing to do */
460  Status = LocateChildDevice(DeviceExtension, DevicePath, InstanceId, &Device);
462  {
463  return STATUS_SUCCESS;
464  }
465 
466  /* Create a PPNPROOT_DEVICE object, and add it to the list of known devices */
468  if (!Device)
469  {
470  DPRINT("ExAllocatePoolWithTag() failed\n");
472  goto cleanup;
473  }
475 
476  /* Fill device ID and instance ID */
477  Device->DeviceID = *DevicePath;
478  RtlInitEmptyUnicodeString(DevicePath, NULL, 0);
479  if (!RtlCreateUnicodeString(&Device->InstanceID, InstanceId))
480  {
481  DPRINT1("RtlCreateUnicodeString() failed\n");
483  goto cleanup;
484  }
485 
486  /* Open registry key to fill other informations */
487  Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
488  if (!NT_SUCCESS(Status))
489  {
490  /* If our key disappeared, let the caller go on */
491  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
492  &Device->InstanceID, Status);
494  goto cleanup;
495  }
496 
497  /* Fill information from the device instance key */
500  QueryTable[0].Name = L"DeviceDesc";
501  QueryTable[0].EntryContext = &Device->DeviceDescription;
502 
504  (PCWSTR)DeviceKeyHandle,
505  QueryTable,
506  NULL,
507  NULL);
508 
509  /* Fill information from the LogConf subkey */
510  Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
511  Buffer1.Length = NULL;
512  Buffer2.Data = (PVOID *)&Device->ResourceList;
513  Buffer2.Length = &Device->ResourceListSize;
516  QueryTable[0].Name = L"LogConf";
518  QueryTable[1].Name = L"BasicConfigVector";
519  QueryTable[1].EntryContext = &Buffer1;
521  QueryTable[2].Name = L"BootConfig";
522  QueryTable[2].EntryContext = &Buffer2;
523 
525  (PCWSTR)DeviceKeyHandle,
526  QueryTable,
527  NULL,
528  NULL)))
529  {
530  /* Non-fatal error */
531  DPRINT1("Failed to read the LogConf key for %wZ\\%S\n", &Device->DeviceID, InstanceId);
532  }
533 
534  /* Insert the newly created device into the list */
535  InsertTailList(&DeviceExtension->DeviceListHead,
536  &Device->ListEntry);
537  DeviceExtension->DeviceListCount++;
538  Device = NULL;
539 
540 cleanup:
541  if (DeviceKeyHandle != NULL)
542  {
543  ZwClose(DeviceKeyHandle);
544  }
545  if (Device != NULL)
546  {
547  /* We have a device that has not been added to device list. We need to clean it up */
548  RtlFreeUnicodeString(&Device->DeviceID);
549  RtlFreeUnicodeString(&Device->InstanceID);
551  }
552  return Status;
553 }
554 
555 static NTSTATUS
557  IN HANDLE SubKey,
559 {
560  UNICODE_STRING DeviceReportedValue = RTL_CONSTANT_STRING(L"DeviceReported");
562  UNICODE_STRING InstanceIDU;
563  PKEY_VALUE_FULL_INFORMATION pKeyValueFullInformation;
564  HANDLE InstanceKey, ControlKey;
566  ULONG Size, DeviceReported, ResultLength;
568 
569  Size = 128;
570  pKeyValueFullInformation = ExAllocatePool(PagedPool, Size);
571  if (!pKeyValueFullInformation)
573 
574  /* Open Instance key */
575  RtlInitUnicodeString(&InstanceIDU, InstanceID);
577  &InstanceIDU,
579  SubKey,
580  NULL);
581  Status = ZwOpenKey(&InstanceKey,
584  if (!NT_SUCCESS(Status))
585  {
586  ExFreePool(pKeyValueFullInformation);
587  return Status;
588  }
589 
590  /* Read 'DeviceReported' Key */
591  Status = ZwQueryValueKey(InstanceKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
593  {
594  ZwClose(InstanceKey);
595  ExFreePool(pKeyValueFullInformation);
596  DPRINT("No 'DeviceReported' value\n");
597  return STATUS_SUCCESS;
598  }
599  else if (!NT_SUCCESS(Status))
600  {
601  ZwClose(InstanceKey);
602  ExFreePool(pKeyValueFullInformation);
603  return Status;
604  }
605  if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
606  {
607  ZwClose(InstanceKey);
608  ExFreePool(pKeyValueFullInformation);
609  return STATUS_UNSUCCESSFUL;
610  }
611  RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
612  /* FIXME: Check DeviceReported value? */
613  ASSERT(DeviceReported == 1);
614 
615  /* Open Control key */
617  &Control,
619  InstanceKey,
620  NULL);
621  Status = ZwOpenKey(&ControlKey,
624  ZwClose(InstanceKey);
626  {
627  DPRINT("No 'Control' key\n");
628  return STATUS_NO_SUCH_DEVICE;
629  }
630  else if (!NT_SUCCESS(Status))
631  {
632  ExFreePool(pKeyValueFullInformation);
633  return Status;
634  }
635 
636  /* Read 'DeviceReported' Key */
637  Status = ZwQueryValueKey(ControlKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
638  ZwClose(ControlKey);
640  {
641  ExFreePool(pKeyValueFullInformation);
642  DPRINT("No 'DeviceReported' value\n");
643  return STATUS_NO_SUCH_DEVICE;
644  }
645  else if (!NT_SUCCESS(Status))
646  {
647  ExFreePool(pKeyValueFullInformation);
648  return Status;
649  }
650  if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
651  {
652  ExFreePool(pKeyValueFullInformation);
653  return STATUS_UNSUCCESSFUL;
654  }
655  RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
656  /* FIXME: Check DeviceReported value? */
657  ASSERT(DeviceReported == 1);
658 
659  ExFreePool(pKeyValueFullInformation);
660  return STATUS_SUCCESS;
661 }
662 
663 static NTSTATUS
666 {
667  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
668  PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
669  UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
672  UNICODE_STRING DevicePath;
675  ULONG KeyInfoSize, SubKeyInfoSize;
676  ULONG ResultSize;
677  ULONG Index1, Index2;
679 
680  DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
681 
682  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
683  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
684 
685  /* Should hold most key names, but we reallocate below if it's too small */
686  KeyInfoSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + 64 * sizeof(WCHAR);
688  KeyInfoSize + sizeof(UNICODE_NULL),
689  TAG_PNP_ROOT);
690  if (!KeyInfo)
691  {
692  DPRINT("ExAllocatePoolWithTag() failed\n");
694  goto cleanup;
695  }
696  SubKeyInfoSize = KeyInfoSize;
697  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
698  SubKeyInfoSize + sizeof(UNICODE_NULL),
699  TAG_PNP_ROOT);
700  if (!SubKeyInfo)
701  {
702  DPRINT("ExAllocatePoolWithTag() failed\n");
704  goto cleanup;
705  }
706 
708  if (!NT_SUCCESS(Status))
709  {
710  DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
711  goto cleanup;
712  }
713 
714  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
715  * KeyHandle. We'll first do a first enumeration to have first level keys,
716  * and an inner one to have the real devices list.
717  */
718  Index1 = 0;
719  while (TRUE)
720  {
721  Status = ZwEnumerateKey(
722  KeyHandle,
723  Index1,
725  KeyInfo,
726  KeyInfoSize,
727  &ResultSize);
729  {
731  break;
732  }
733  else if (Status == STATUS_BUFFER_OVERFLOW ||
735  {
736  ASSERT(KeyInfoSize < ResultSize);
737  KeyInfoSize = ResultSize;
740  KeyInfoSize + sizeof(UNICODE_NULL),
741  TAG_PNP_ROOT);
742  if (!KeyInfo)
743  {
744  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", KeyInfoSize);
746  goto cleanup;
747  }
748  continue;
749  }
750  else if (!NT_SUCCESS(Status))
751  {
752  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
753  goto cleanup;
754  }
755 
756  /* Terminate the string */
757  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
758 
759  /* Check if it is a legacy driver */
761  if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
762  {
763  DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
764  Index1++;
765  continue;
766  }
767 
768  /* Open the key */
770  if (!NT_SUCCESS(Status))
771  {
772  DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
773  &SubKeyName, Status);
774  break;
775  }
776 
777  /* Enumerate the sub-keys */
778  Index2 = 0;
779  while (TRUE)
780  {
781  Status = ZwEnumerateKey(
782  SubKeyHandle,
783  Index2,
785  SubKeyInfo,
786  SubKeyInfoSize,
787  &ResultSize);
789  {
790  break;
791  }
792  else if (Status == STATUS_BUFFER_OVERFLOW ||
794  {
795  ASSERT(SubKeyInfoSize < ResultSize);
796  SubKeyInfoSize = ResultSize;
797  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
798  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
799  SubKeyInfoSize + sizeof(UNICODE_NULL),
800  TAG_PNP_ROOT);
801  if (!SubKeyInfo)
802  {
803  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", SubKeyInfoSize);
805  goto cleanup;
806  }
807  continue;
808  }
809  else if (!NT_SUCCESS(Status))
810  {
811  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
812  break;
813  }
814 
815  /* Terminate the string */
816  SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
817 
818  /* Compute device ID */
819  DevicePath.Length = 0;
820  DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + SubKeyName.Length;
822  DevicePath.MaximumLength,
823  TAG_PNP_ROOT);
824  if (DevicePath.Buffer == NULL)
825  {
826  DPRINT1("ExAllocatePoolWithTag() failed\n");
828  goto cleanup;
829  }
830 
833  DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
834 
835  Status = IopShouldProcessDevice(SubKeyHandle, SubKeyInfo->Name);
836  if (NT_SUCCESS(Status))
837  {
838  Status = CreateDeviceFromRegistry(DeviceExtension,
839  &DevicePath,
840  SubKeyInfo->Name,
841  SubKeyHandle);
842 
843  /* If CreateDeviceFromRegistry didn't take ownership and zero this,
844  * we need to free it
845  */
846  RtlFreeUnicodeString(&DevicePath);
847 
848  if (!NT_SUCCESS(Status))
849  {
850  goto cleanup;
851  }
852  }
853  else if (Status == STATUS_NO_SUCH_DEVICE)
854  {
855  DPRINT("Skipping device %wZ\\%S (not reported yet)\n", &DevicePath, SubKeyInfo->Name);
856  }
857  else
858  {
859  goto cleanup;
860  }
861 
862  Index2++;
863  }
864 
866  SubKeyHandle = NULL;
867  Index1++;
868  }
869 
870 cleanup:
871  if (SubKeyHandle != NULL)
873  if (KeyHandle != NULL)
875  if (KeyInfo)
877  if (SubKeyInfo)
878  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
879  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
880  return Status;
881 }
882 
883 /* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
884  * ARGUMENTS:
885  * DeviceObject = Pointer to functional device object of the root bus driver
886  * Irp = Pointer to IRP that should be handled
887  * RETURNS:
888  * Status
889  */
890 static NTSTATUS
893  IN PIRP Irp)
894 {
895  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
896  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
897  PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
899  ULONG Size;
901  PLIST_ENTRY NextEntry;
902 
903  DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
904 
906  if (!NT_SUCCESS(Status))
907  {
908  DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
909  return Status;
910  }
911 
912  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
913 
914  Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
915  if (OtherRelations)
916  {
917  /* Another bus driver has already created a DEVICE_RELATIONS
918  * structure so we must merge this structure with our own */
919 
920  Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
921  }
923  if (!Relations)
924  {
925  DPRINT("ExAllocatePoolWithTag() failed\n");
927  goto cleanup;
928  }
929  RtlZeroMemory(Relations, Size);
930  if (OtherRelations)
931  {
932  Relations->Count = OtherRelations->Count;
933  RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
934  }
935 
936  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
937 
938  /* Start looping */
939  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
940  NextEntry != &DeviceExtension->DeviceListHead;
941  NextEntry = NextEntry->Flink)
942  {
943  /* Get the entry */
944  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
945 
946  if (!Device->Pdo)
947  {
948  /* Create a physical device object for the
949  * device as it does not already have one */
951  DeviceObject->DriverObject,
953  NULL,
956  FALSE,
957  &Device->Pdo);
958  if (!NT_SUCCESS(Status))
959  {
960  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
961  break;
962  }
963 
964  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
965  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
966  PdoDeviceExtension->Common.IsFDO = FALSE;
967  PdoDeviceExtension->DeviceInfo = Device;
968 
969  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
970  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
971  }
972 
973  /* Reference the physical device object. The PnP manager
974  will dereference it again when it is no longer needed */
976 
977  Relations->Objects[Relations->Count++] = Device->Pdo;
978  }
979  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
980 
981  Irp->IoStatus.Information = (ULONG_PTR)Relations;
982 
983 cleanup:
984  if (!NT_SUCCESS(Status))
985  {
986  if (OtherRelations)
987  ExFreePool(OtherRelations);
988  if (Relations)
989  ExFreePool(Relations);
990  if (Device && Device->Pdo)
991  {
992  IoDeleteDevice(Device->Pdo);
993  Device->Pdo = NULL;
994  }
995  }
996 
997  return Status;
998 }
999 
1000 /*
1001  * FUNCTION: Handle Plug and Play IRPs for the root bus device object
1002  * ARGUMENTS:
1003  * DeviceObject = Pointer to functional device object of the root bus driver
1004  * Irp = Pointer to IRP that should be handled
1005  * RETURNS:
1006  * Status
1007  */
1008 static NTSTATUS
1011  IN PIRP Irp)
1012 {
1013  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1015  NTSTATUS Status;
1016 
1017  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1018  Status = Irp->IoStatus.Status;
1020 
1021  switch (IrpSp->MinorFunction)
1022  {
1024  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
1026  break;
1027 
1028  case IRP_MN_START_DEVICE:
1029  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1030  if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
1032  else
1033  {
1034  Status = Irp->IoStatus.Status;
1035  if (NT_SUCCESS(Status))
1036  DeviceExtension->State = dsStarted;
1037  }
1038 
1039  Irp->IoStatus.Status = Status;
1041  return Status;
1042 
1043  case IRP_MN_STOP_DEVICE:
1044  DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
1045  /* Root device cannot be stopped */
1046  Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
1048  return Status;
1049 
1050  default:
1051  DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1052  break;
1053  }
1054 
1055  if (Status != STATUS_PENDING)
1056  {
1057  Irp->IoStatus.Status = Status;
1059  }
1060 
1061  return Status;
1062 }
1063 
1064 static NTSTATUS
1067  IN PIRP Irp,
1069 {
1070  PDEVICE_RELATIONS Relations;
1071  NTSTATUS Status = Irp->IoStatus.Status;
1072 
1073  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
1074  return Status;
1075 
1076  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
1078  if (!Relations)
1079  {
1080  DPRINT("ExAllocatePoolWithTag() failed\n");
1082  }
1083  else
1084  {
1086  Relations->Count = 1;
1087  Relations->Objects[0] = DeviceObject;
1089  Irp->IoStatus.Information = (ULONG_PTR)Relations;
1090  }
1091 
1092  return Status;
1093 }
1094 
1095 static NTSTATUS
1098  IN PIRP Irp,
1100 {
1102 
1103  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
1104 
1105  if (DeviceCapabilities->Version != 1)
1106  return STATUS_REVISION_MISMATCH;
1107 
1108  DeviceCapabilities->UniqueID = TRUE;
1109  /* FIXME: Fill other fields */
1110 
1111  return STATUS_SUCCESS;
1112 }
1113 
1114 static NTSTATUS
1117  IN PIRP Irp,
1119 {
1120  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1122 
1123  DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1124 
1125  if (DeviceExtension->DeviceInfo->ResourceList)
1126  {
1127  /* Copy existing resource requirement list */
1129  PagedPool,
1130  DeviceExtension->DeviceInfo->ResourceListSize);
1131  if (!ResourceList)
1132  return STATUS_NO_MEMORY;
1133 
1134  RtlCopyMemory(
1135  ResourceList,
1136  DeviceExtension->DeviceInfo->ResourceList,
1137  DeviceExtension->DeviceInfo->ResourceListSize);
1138 
1139  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1140 
1141  return STATUS_SUCCESS;
1142  }
1143  else
1144  {
1145  /* No resources so just return without changing the status */
1146  return Irp->IoStatus.Status;
1147  }
1148 }
1149 
1150 static NTSTATUS
1153  IN PIRP Irp,
1155 {
1156  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1158 
1159  DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1160 
1161  if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
1162  {
1163  /* Copy existing resource requirement list */
1165  if (!ResourceList)
1166  return STATUS_NO_MEMORY;
1167 
1168  RtlCopyMemory(
1169  ResourceList,
1170  DeviceExtension->DeviceInfo->ResourceRequirementsList,
1171  DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
1172 
1173  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1174 
1175  return STATUS_SUCCESS;
1176  }
1177  else
1178  {
1179  /* No resource requirements so just return without changing the status */
1180  return Irp->IoStatus.Status;
1181  }
1182 }
1183 
1184 static NTSTATUS
1187  IN PIRP Irp,
1189 {
1190  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1191  DEVICE_TEXT_TYPE DeviceTextType;
1192  NTSTATUS Status = Irp->IoStatus.Status;
1193 
1194  DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1195  DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
1196 
1197  switch (DeviceTextType)
1198  {
1199  case DeviceTextDescription:
1200  {
1202  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
1203 
1204  if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
1205  {
1207  &DeviceExtension->DeviceInfo->DeviceDescription,
1208  &String);
1209  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1210  }
1211  break;
1212  }
1213 
1215  {
1216  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1217  break;
1218  }
1219 
1220  default:
1221  {
1222  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1223  }
1224  }
1225 
1226  return Status;
1227 }
1228 
1229 static NTSTATUS
1232  IN PIRP Irp,
1234 {
1235  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1237  NTSTATUS Status = Irp->IoStatus.Status;
1238 
1239  DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1240  IdType = IrpSp->Parameters.QueryId.IdType;
1241 
1242  switch (IdType)
1243  {
1244  case BusQueryDeviceID:
1245  {
1247  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1248 
1251  &DeviceExtension->DeviceInfo->DeviceID,
1252  &String);
1253  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1254  break;
1255  }
1256 
1257  case BusQueryHardwareIDs:
1258  case BusQueryCompatibleIDs:
1259  {
1260  /* Optional, do nothing */
1261  break;
1262  }
1263 
1264  case BusQueryInstanceID:
1265  {
1267  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1268 
1271  &DeviceExtension->DeviceInfo->InstanceID,
1272  &String);
1273  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1274  break;
1275  }
1276 
1277  default:
1278  {
1279  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1280  }
1281  }
1282 
1283  return Status;
1284 }
1285 
1286 static NTSTATUS
1289  IN PIRP Irp,
1291 {
1292  PPNP_BUS_INFORMATION BusInfo;
1293  NTSTATUS Status;
1294 
1296  if (!BusInfo)
1298  else
1299  {
1300  RtlCopyMemory(
1301  &BusInfo->BusTypeGuid,
1302  &GUID_BUS_TYPE_INTERNAL,
1303  sizeof(BusInfo->BusTypeGuid));
1304  BusInfo->LegacyBusType = PNPBus;
1305  /* We're the only root bus enumerator on the computer */
1306  BusInfo->BusNumber = 0;
1307  Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1309  }
1310 
1311  return Status;
1312 }
1313 
1314 /*
1315  * FUNCTION: Handle Plug and Play IRPs for the child device
1316  * ARGUMENTS:
1317  * DeviceObject = Pointer to physical device object of the child device
1318  * Irp = Pointer to IRP that should be handled
1319  * RETURNS:
1320  * Status
1321  */
1322 static NTSTATUS
1325  IN PIRP Irp)
1326 {
1327  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1328  PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1330  NTSTATUS Status;
1331 
1332  DeviceExtension = DeviceObject->DeviceExtension;
1333  FdoDeviceExtension = PnpRootDeviceObject->DeviceExtension;
1334  Status = Irp->IoStatus.Status;
1336 
1337  switch (IrpSp->MinorFunction)
1338  {
1339  case IRP_MN_START_DEVICE: /* 0x00 */
1340  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1342  break;
1343 
1344  case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1346  break;
1347 
1348  case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1349  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1351  break;
1352 
1353  case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1354  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1356  break;
1357 
1358  case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1359  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1361  break;
1362 
1363  case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1364  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1366  break;
1367 
1368  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
1369  DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1370  break;
1371 
1372  case IRP_MN_REMOVE_DEVICE:
1373  /* Remove the device from the device list and decrement the device count*/
1374  KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1375  RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1376  FdoDeviceExtension->DeviceListCount--;
1377  KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1378 
1379  /* Free some strings we created */
1381  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1382  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1383 
1384  /* Free the resource requirements list */
1385  if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1386  ExFreePool(DeviceExtension->DeviceInfo->ResourceRequirementsList);
1387 
1388  /* Free the boot resources list */
1389  if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1390  ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1391 
1392  /* Free the device info */
1393  ExFreePool(DeviceExtension->DeviceInfo);
1394 
1395  /* Finally, delete the device object */
1397 
1398  /* Return success */
1400  break;
1401 
1402  case IRP_MN_QUERY_ID: /* 0x13 */
1404  break;
1405 
1406  case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1407  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1408  break;
1409 
1410  case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1411  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1413  break;
1414 
1415  default:
1416  DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1417  break;
1418  }
1419 
1420  if (Status != STATUS_PENDING)
1421  {
1422  Irp->IoStatus.Status = Status;
1424  }
1425 
1426  return Status;
1427 }
1428 
1429 /*
1430  * FUNCTION: Handle Plug and Play IRPs
1431  * ARGUMENTS:
1432  * DeviceObject = Pointer to PDO or FDO
1433  * Irp = Pointer to IRP that should be handled
1434  * RETURNS:
1435  * Status
1436  */
1437 static NTSTATUS NTAPI
1440  IN PIRP Irp)
1441 {
1442  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
1443  NTSTATUS Status;
1444 
1445  DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1446 
1447  if (DeviceExtension->IsFDO)
1449  else
1451 
1452  return Status;
1453 }
1454 
1455 /*
1456  * FUNCTION: Handle Power IRPs
1457  * ARGUMENTS:
1458  * DeviceObject = Pointer to PDO or FDO
1459  * Irp = Pointer to IRP that should be handled
1460  * RETURNS:
1461  * Status
1462  */
1463 static NTSTATUS NTAPI
1466  IN PIRP Irp)
1467 {
1468  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1470  NTSTATUS Status;
1471 
1472  DeviceExtension = DeviceObject->DeviceExtension;
1473  Status = Irp->IoStatus.Status;
1475 
1476  if (DeviceExtension->Common.IsFDO)
1477  {
1478  ASSERT(!DeviceExtension->Common.IsFDO);
1481  Status = PoCallDriver(DeviceExtension->Ldo, Irp);
1482  }
1483  else
1484  {
1485  switch (IrpSp->MinorFunction)
1486  {
1487  case IRP_MN_QUERY_POWER:
1488  case IRP_MN_SET_POWER:
1490  break;
1491  }
1492  Irp->IoStatus.Status = Status;
1495  }
1496 
1497  return Status;
1498 }
1499 
1500 NTSTATUS
1501 NTAPI
1505 {
1506  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1507  NTSTATUS Status;
1508 
1509  DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject, PhysicalDeviceObject);
1510 
1511  if (!PhysicalDeviceObject)
1512  {
1513  DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
1515  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1516  }
1517 
1519  DriverObject,
1521  NULL,
1524  TRUE,
1526  if (!NT_SUCCESS(Status))
1527  {
1528  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
1529  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1530  }
1531  DPRINT("Created FDO %p\n", PnpRootDeviceObject);
1532 
1534  RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
1535 
1536  DeviceExtension->Common.IsFDO = TRUE;
1537  DeviceExtension->State = dsStopped;
1538  InitializeListHead(&DeviceExtension->DeviceListHead);
1539  DeviceExtension->DeviceListCount = 0;
1540  KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
1541 
1545  &DeviceExtension->Ldo);
1546  if (!NT_SUCCESS(Status))
1547  {
1548  DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
1549  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1550  }
1551 
1553 
1554  DPRINT("Done AddDevice()\n");
1555 
1556  return STATUS_SUCCESS;
1557 }
1558 
1559 #if MI_TRACE_PFNS
1560 PDEVICE_OBJECT IopPfnDumpDeviceObject;
1561 
1563 PnpRootCreateClose(
1565  _In_ PIRP Irp)
1566 {
1567  PIO_STACK_LOCATION IoStack;
1568 
1569  if (DeviceObject != IopPfnDumpDeviceObject)
1570  {
1571  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1574  }
1575 
1576  IoStack = IoGetCurrentIrpStackLocation(Irp);
1577  if (IoStack->MajorFunction == IRP_MJ_CREATE)
1578  {
1580  }
1581 
1582  Irp->IoStatus.Status = STATUS_SUCCESS;
1584  return STATUS_SUCCESS;
1585 }
1586 #endif
1587 
1592 {
1593 #if MI_TRACE_PFNS
1594  NTSTATUS Status;
1595  UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1596 #endif
1597 
1598  DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1599 
1601 
1603 
1604 #if MI_TRACE_PFNS
1605  DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1606  DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1607 #endif
1608  DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
1609  DriverObject->MajorFunction[IRP_MJ_POWER] = PnpRootPowerControl;
1610 
1611 #if MI_TRACE_PFNS
1613  0,
1614  &PfnDumpDeviceName,
1616  0,
1617  FALSE,
1618  &IopPfnDumpDeviceObject);
1619  if (!NT_SUCCESS(Status))
1620  {
1621  DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1622  }
1623  else
1624  {
1625  IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1626  }
1627 #endif
1628 
1629  return STATUS_SUCCESS;
1630 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
PNPROOT_DEVICE_STATE
Definition: pnproot.c:41
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:57
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
#define IN
Definition: typedefs.h:39
static NTSTATUS EnumerateDevices(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:664
NTSTATUS PnpRootRegisterDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:130
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MN_QUERY_RESOURCES
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
UNICODE_STRING DeviceDescription
Definition: pnproot.c:33
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define _Inout_
Definition: ms_sal.h:378
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IRP_MN_QUERY_POWER
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
struct _PNPROOT_PDO_DEVICE_EXTENSION * PPNPROOT_PDO_DEVICE_EXTENSION
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
uint16_t * PWSTR
Definition: typedefs.h:56
VOID NTAPI MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
Definition: mminit.c:1474
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
PCM_RESOURCE_LIST ResourceList
Definition: pnproot.c:37
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
ULONG ResourceListSize
Definition: pnproot.c:38
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY ListEntry
Definition: pnproot.c:25
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
PPNPROOT_DEVICE DeviceInfo
Definition: pnproot.c:62
static NTSTATUS PdoQueryId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1230
#define REGSTR_PATH_SYSTEMENUM
Definition: regstr.h:483
struct _PNPROOT_DEVICE * PPNPROOT_DEVICE
static NTSTATUS CreateDeviceFromRegistry(_Inout_ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, _Inout_ PUNICODE_STRING DevicePath, _In_ PCWSTR InstanceId, _In_ HANDLE SubKeyHandle)
Definition: pnproot.c:447
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
PDEVICE_OBJECT Pdo
Definition: pnproot.c:27
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct _PNPROOT_COMMON_DEVICE_EXTENSION * PPNPROOT_COMMON_DEVICE_EXTENSION
static NTSTATUS PdoQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1065
static NTSTATUS PdoQueryBusInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1287
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
#define InsertTailList(ListHead, Entry)
static NTSTATUS PnpRootFdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1009
if(dx==0 &&dy==0)
Definition: linetemp.h:174
static NTSTATUS IopShouldProcessDevice(IN HANDLE SubKey, IN PCWSTR InstanceID)
Definition: pnproot.c:556
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:304
static NTSTATUS PdoQueryResources(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1115
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:69
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2868
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define L(x)
Definition: ntvdm.h:50
PNPROOT_DEVICE_STATE State
Definition: pnproot.c:73
struct _PNPROOT_FDO_DEVICE_EXTENSION * PPNPROOT_FDO_DEVICE_EXTENSION
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define REGSTR_KEY_ROOTENUM
Definition: regstr.h:10
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PVOID * Data
Definition: pnproot.c:84
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4155
PULONG Length
Definition: pnproot.c:85
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
#define DO_BUS_ENUMERATED_DEVICE
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
#define _In_
Definition: ms_sal.h:308
#define IoCompleteRequest
Definition: irp.c:1240
#define DeviceCapabilities
Definition: wingdi.h:4449
Definition: bufpool.h:45
switch(r->id)
Definition: btrfs.c:2980
NTSTATUS NTAPI PnpRootAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnproot.c:1502
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:374
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT OPTIONAL PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:186
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _BUFFER BUFFER
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:980
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UNICODE_STRING DeviceID
Definition: pnproot.c:29
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
struct _PNPROOT_PDO_DEVICE_EXTENSION PNPROOT_PDO_DEVICE_EXTENSION
#define IRP_MN_START_DEVICE
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
NTSTATUS NTAPI PnpRootDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: pnproot.c:1589
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2950
#define IRP_MN_QUERY_DEVICE_TEXT
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING InstanceID
Definition: wdfpdo.h:306
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
Definition: Node.h:9
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4723
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IRP_MN_QUERY_BUS_INFORMATION
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:26
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3378
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IRP_MJ_POWER
static NTSTATUS PnpRootQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:891
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static NTSTATUS NTAPI QueryBinaryValueCallback(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: pnproot.c:419
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define IRP_MN_SET_POWER
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
static PDEVICE_OBJECT PnpRootDeviceObject
Definition: pnproot.c:88
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2220
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
static NTSTATUS NTAPI PnpRootPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1438
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:60
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
struct _PNPROOT_COMMON_DEVICE_EXTENSION PNPROOT_COMMON_DEVICE_EXTENSION
KGUARDED_MUTEX DeviceListLock
Definition: pnproot.c:79
#define TAG_PNP_ROOT
Definition: tag.h:87
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define IRP_MN_QUERY_DEVICE_RELATIONS
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
static NTSTATUS LocateChildDevice(IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, IN PCUNICODE_STRING DeviceId, IN PCWSTR InstanceId, OUT PPNPROOT_DEVICE *ChildDevice OPTIONAL)
Definition: pnproot.c:93
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
UNICODE_STRING InstanceID
Definition: pnproot.c:31
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
static NTSTATUS PdoQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1096
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1185
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
static NTSTATUS PdoQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1151
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
Definition: pnproot.c:35
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:148
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static NTSTATUS NTAPI PnpRootPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1464
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
static NTSTATUS PnpRootPdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1323
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:365
#define IRP_MN_QUERY_PNP_DEVICE_STATE
struct _PNPROOT_DEVICE PNPROOT_DEVICE
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
static NTSTATUS NTAPI QueryStringCallback(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: pnproot.c:393
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
#define IRP_MN_QUERY_CAPABILITIES
struct _BUFFER * PBUFFER
struct _PNPROOT_FDO_DEVICE_EXTENSION PNPROOT_FDO_DEVICE_EXTENSION
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68