ReactOS  0.4.13-dev-551-gf37fb1f
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 PCWSTR DeviceId,
97  OUT PPNPROOT_DEVICE* ChildDevice)
98 {
100  UNICODE_STRING DeviceIdU, InstanceIdU;
101  PLIST_ENTRY NextEntry;
102 
103  /* Initialize the strings to compare */
104  RtlInitUnicodeString(&DeviceIdU, DeviceId);
105  RtlInitUnicodeString(&InstanceIdU, InstanceId);
106 
107  /* Start looping */
108  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
109  NextEntry != &DeviceExtension->DeviceListHead;
110  NextEntry = NextEntry->Flink)
111  {
112  /* Get the entry */
113  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
114 
115  /* See if the strings match */
116  if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE) &&
117  RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
118  {
119  /* They do, so set the pointer and return success */
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  WCHAR DevicePath[MAX_PATH + 1];
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  _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName);
211 
212  /* Initialize a PNPROOT_DEVICE structure */
214  if (!Device)
215  {
216  DPRINT("ExAllocatePoolWithTag() failed\n");
218  goto cleanup;
219  }
221  if (!RtlCreateUnicodeString(&Device->DeviceID, DevicePath))
222  {
224  goto cleanup;
225  }
226 
227  Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
228  if (NT_SUCCESS(Status))
229  {
231  &Device->DeviceID,
233  EnumHandle,
234  NULL);
235  Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
236  ObCloseHandle(EnumHandle, KernelMode);
237  }
238 
239  if (!NT_SUCCESS(Status))
240  {
241  DPRINT1("Failed to open registry key\n");
242  goto cleanup;
243  }
244 
245 tryagain:
247  QueryTable[0].Name = L"NextInstance";
248  QueryTable[0].EntryContext = &NextInstance;
250 
252  (PWSTR)DeviceKeyHandle,
253  QueryTable,
254  NULL,
255  NULL);
256  if (!NT_SUCCESS(Status))
257  {
258  for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
259  {
260  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
261  Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
263  break;
264  }
265 
266  if (NextInstance > 9999)
267  {
268  DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
270  goto cleanup;
271  }
272  }
273 
274  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
275  Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
276  if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
277  {
278  DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
280  (PWSTR)DeviceKeyHandle,
281  L"NextInstance");
282  goto tryagain;
283  }
284 
285  NextInstance++;
287  (PWSTR)DeviceKeyHandle,
288  L"NextInstance",
289  REG_DWORD,
290  &NextInstance,
291  sizeof(NextInstance));
292  if (!NT_SUCCESS(Status))
293  {
294  DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
295  goto cleanup;
296  }
297 
298  if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
299  {
301  goto cleanup;
302  }
303 
304  /* Finish creating the instance path in the registry */
306  &Device->InstanceID,
308  DeviceKeyHandle,
309  NULL);
310  Status = ZwCreateKey(&InstanceKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
311  if (!NT_SUCCESS(Status))
312  {
313  DPRINT1("Failed to create instance path (0x%x)\n", Status);
314  goto cleanup;
315  }
316 
317  /* Just close the handle */
318  ObCloseHandle(InstanceKeyHandle, KernelMode);
319 
320  if (FullInstancePath)
321  {
322  FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
323  FullInstancePath->Length = 0;
324  FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
325  if (!FullInstancePath->Buffer)
326  {
328  goto cleanup;
329  }
330 
331  RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
332  RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
333  RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
334  }
335 
336  /* Initialize a device object */
340  NULL,
343  FALSE,
344  &Device->Pdo);
345  if (!NT_SUCCESS(Status))
346  {
347  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
349  goto cleanup;
350  }
351 
352  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
353  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
354  PdoDeviceExtension->Common.IsFDO = FALSE;
355  PdoDeviceExtension->DeviceInfo = Device;
356 
357  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
358  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
359 
361  &DeviceExtension->DeviceListHead,
362  &Device->ListEntry);
363  DeviceExtension->DeviceListCount++;
364 
366  DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject, &Device->DeviceID, &Device->InstanceID);
367  Device = NULL;
369 
370 cleanup:
371  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
372  if (Device)
373  {
374  if (Device->Pdo)
375  IoDeleteDevice(Device->Pdo);
376  RtlFreeUnicodeString(&Device->DeviceID);
377  RtlFreeUnicodeString(&Device->InstanceID);
379  }
380  if (DeviceKeyHandle != NULL)
381  ObCloseHandle(DeviceKeyHandle, KernelMode);
382  return Status;
383 }
384 
385 static NTSTATUS NTAPI
391  IN PVOID Context,
393 {
396 
397  if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
398  {
399  Destination->Length = 0;
402  return STATUS_SUCCESS;
403  }
404 
405  Source.MaximumLength = Source.Length = (USHORT)ValueLength;
406  Source.Buffer = ValueData;
407 
409 }
410 
411 static NTSTATUS NTAPI
417  IN PVOID Context,
419 {
421  PVOID BinaryValue;
422 
423  if (ValueLength == 0)
424  {
425  *Buffer->Data = NULL;
426  return STATUS_SUCCESS;
427  }
428 
430  if (BinaryValue == NULL)
431  return STATUS_NO_MEMORY;
432  RtlCopyMemory(BinaryValue, ValueData, ValueLength);
433  *Buffer->Data = BinaryValue;
434  if (Buffer->Length) *Buffer->Length = ValueLength;
435  return STATUS_SUCCESS;
436 }
437 
438 static NTSTATUS
441 {
442  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
443  PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
444  UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
447  WCHAR DevicePath[MAX_PATH + 1];
452  HANDLE DeviceKeyHandle = NULL;
454  ULONG ResultSize;
455  ULONG Index1, Index2;
456  BUFFER Buffer1, Buffer2;
458 
459  DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
460 
462  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
463 
464  BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH + 1) * sizeof(WCHAR);
466  if (!KeyInfo)
467  {
468  DPRINT("ExAllocatePoolWithTag() failed\n");
470  goto cleanup;
471  }
473  if (!SubKeyInfo)
474  {
475  DPRINT("ExAllocatePoolWithTag() failed\n");
477  goto cleanup;
478  }
479 
481  if (!NT_SUCCESS(Status))
482  {
483  DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
484  goto cleanup;
485  }
486 
487  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
488  * KeyHandle. We'll first do a first enumeration to have first level keys,
489  * and an inner one to have the real devices list.
490  */
491  Index1 = 0;
492  while (TRUE)
493  {
494  Status = ZwEnumerateKey(
495  KeyHandle,
496  Index1,
498  KeyInfo,
499  BufferSize,
500  &ResultSize);
502  {
504  break;
505  }
506  else if (!NT_SUCCESS(Status))
507  {
508  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
509  goto cleanup;
510  }
511 
512  /* Terminate the string */
513  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
514 
515  /* Check if it is a legacy driver */
517  if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
518  {
519  DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
520  Index1++;
521  continue;
522  }
523 
524  /* Open the key */
526  if (!NT_SUCCESS(Status))
527  {
528  DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
529  &SubKeyName, Status);
530  break;
531  }
532 
533  /* Enumerate the sub-keys */
534  Index2 = 0;
535  while (TRUE)
536  {
537  Status = ZwEnumerateKey(
538  SubKeyHandle,
539  Index2,
541  SubKeyInfo,
542  BufferSize,
543  &ResultSize);
545  break;
546  else if (!NT_SUCCESS(Status))
547  {
548  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
549  break;
550  }
551 
552  /* Terminate the string */
553  SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
554 
555  _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR),
556  L"%s\\%s", REGSTR_KEY_ROOTENUM, KeyInfo->Name);
557  DPRINT("Found device %S\\%s!\n", DevicePath, SubKeyInfo->Name);
558  if (LocateChildDevice(DeviceExtension, DevicePath, SubKeyInfo->Name, &Device) == STATUS_NO_SUCH_DEVICE)
559  {
560  /* Create a PPNPROOT_DEVICE object, and add if in the list of known devices */
562  if (!Device)
563  {
564  DPRINT("ExAllocatePoolWithTag() failed\n");
566  goto cleanup;
567  }
569 
570  /* Fill device ID and instance ID */
571  if (!RtlCreateUnicodeString(&Device->DeviceID, DevicePath))
572  {
573  DPRINT1("RtlCreateUnicodeString() failed\n");
575  goto cleanup;
576  }
577 
578  if (!RtlCreateUnicodeString(&Device->InstanceID, SubKeyInfo->Name))
579  {
580  DPRINT1("RtlCreateUnicodeString() failed\n");
582  goto cleanup;
583  }
584 
585  /* Open registry key to fill other informations */
586  Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
587  if (!NT_SUCCESS(Status))
588  {
589  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
590  &Device->InstanceID, Status);
591  break;
592  }
593 
594  /* Fill information from the device instance key */
597  QueryTable[0].Name = L"DeviceDesc";
598  QueryTable[0].EntryContext = &Device->DeviceDescription;
599 
601  (PCWSTR)DeviceKeyHandle,
602  QueryTable,
603  NULL,
604  NULL);
605 
606  /* Fill information from the LogConf subkey */
607  Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
608  Buffer1.Length = NULL;
609  Buffer2.Data = (PVOID *)&Device->ResourceList;
610  Buffer2.Length = &Device->ResourceListSize;
613  QueryTable[0].Name = L"LogConf";
615  QueryTable[1].Name = L"BasicConfigVector";
616  QueryTable[1].EntryContext = &Buffer1;
618  QueryTable[2].Name = L"BootConfig";
619  QueryTable[2].EntryContext = &Buffer2;
620 
622  (PCWSTR)DeviceKeyHandle,
623  QueryTable,
624  NULL,
625  NULL)))
626  {
627  /* Non-fatal error */
628  DPRINT1("Failed to read the LogConf key for %S\\%S\n", DevicePath, SubKeyInfo->Name);
629  }
630 
631  ZwClose(DeviceKeyHandle);
632  DeviceKeyHandle = NULL;
633 
634  /* Insert the newly created device into the list */
636  &DeviceExtension->DeviceListHead,
637  &Device->ListEntry);
638  DeviceExtension->DeviceListCount++;
639  }
640  Device = NULL;
641 
642  Index2++;
643  }
644 
646  SubKeyHandle = NULL;
647  Index1++;
648  }
649 
650 cleanup:
651  if (Device)
652  {
653  /* We have a device that has not been added to device list. We need to clean it up */
654  /* FIXME */
656  }
657  if (DeviceKeyHandle != NULL)
658  ZwClose(DeviceKeyHandle);
659  if (SubKeyHandle != NULL)
661  if (KeyHandle != NULL)
663  if (KeyInfo)
665  if (SubKeyInfo)
666  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
667  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
668  return Status;
669 }
670 
671 /* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
672  * ARGUMENTS:
673  * DeviceObject = Pointer to functional device object of the root bus driver
674  * Irp = Pointer to IRP that should be handled
675  * RETURNS:
676  * Status
677  */
678 static NTSTATUS
681  IN PIRP Irp)
682 {
683  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
684  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
685  PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
687  ULONG Size;
689  PLIST_ENTRY NextEntry;
690 
691  DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
692 
694  if (!NT_SUCCESS(Status))
695  {
696  DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
697  return Status;
698  }
699 
701 
702  Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
703  if (OtherRelations)
704  {
705  /* Another bus driver has already created a DEVICE_RELATIONS
706  * structure so we must merge this structure with our own */
707 
708  Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
709  }
711  if (!Relations)
712  {
713  DPRINT("ExAllocatePoolWithTag() failed\n");
715  goto cleanup;
716  }
717  RtlZeroMemory(Relations, Size);
718  if (OtherRelations)
719  {
720  Relations->Count = OtherRelations->Count;
721  RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
722  }
723 
724  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
725 
726  /* Start looping */
727  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
728  NextEntry != &DeviceExtension->DeviceListHead;
729  NextEntry = NextEntry->Flink)
730  {
731  /* Get the entry */
732  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
733 
734  if (!Device->Pdo)
735  {
736  /* Create a physical device object for the
737  * device as it does not already have one */
739  DeviceObject->DriverObject,
741  NULL,
744  FALSE,
745  &Device->Pdo);
746  if (!NT_SUCCESS(Status))
747  {
748  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
749  break;
750  }
751 
752  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
753  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
754  PdoDeviceExtension->Common.IsFDO = FALSE;
755  PdoDeviceExtension->DeviceInfo = Device;
756 
757  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
758  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
759  }
760 
761  /* Reference the physical device object. The PnP manager
762  will dereference it again when it is no longer needed */
764 
765  Relations->Objects[Relations->Count++] = Device->Pdo;
766  }
767  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
768 
769  Irp->IoStatus.Information = (ULONG_PTR)Relations;
770 
771 cleanup:
772  if (!NT_SUCCESS(Status))
773  {
774  if (OtherRelations)
775  ExFreePool(OtherRelations);
776  if (Relations)
777  ExFreePool(Relations);
778  if (Device && Device->Pdo)
779  {
780  IoDeleteDevice(Device->Pdo);
781  Device->Pdo = NULL;
782  }
783  }
784 
785  return Status;
786 }
787 
788 /*
789  * FUNCTION: Handle Plug and Play IRPs for the root bus device object
790  * ARGUMENTS:
791  * DeviceObject = Pointer to functional device object of the root bus driver
792  * Irp = Pointer to IRP that should be handled
793  * RETURNS:
794  * Status
795  */
796 static NTSTATUS
799  IN PIRP Irp)
800 {
801  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
804 
806  Status = Irp->IoStatus.Status;
808 
809  switch (IrpSp->MinorFunction)
810  {
812  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
814  break;
815 
816  case IRP_MN_START_DEVICE:
817  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
818  if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
820  else
821  {
822  Status = Irp->IoStatus.Status;
823  if (NT_SUCCESS(Status))
824  DeviceExtension->State = dsStarted;
825  }
826 
827  Irp->IoStatus.Status = Status;
829  return Status;
830 
831  case IRP_MN_STOP_DEVICE:
832  DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
833  /* Root device cannot be stopped */
834  Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
836  return Status;
837 
838  default:
839  DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
840  break;
841  }
842 
843  if (Status != STATUS_PENDING)
844  {
845  Irp->IoStatus.Status = Status;
847  }
848 
849  return Status;
850 }
851 
852 static NTSTATUS
855  IN PIRP Irp,
857 {
858  PDEVICE_RELATIONS Relations;
859  NTSTATUS Status = Irp->IoStatus.Status;
860 
861  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
862  return Status;
863 
864  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
866  if (!Relations)
867  {
868  DPRINT("ExAllocatePoolWithTag() failed\n");
870  }
871  else
872  {
874  Relations->Count = 1;
875  Relations->Objects[0] = DeviceObject;
877  Irp->IoStatus.Information = (ULONG_PTR)Relations;
878  }
879 
880  return Status;
881 }
882 
883 static NTSTATUS
886  IN PIRP Irp,
888 {
890 
891  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
892 
893  if (DeviceCapabilities->Version != 1)
895 
896  DeviceCapabilities->UniqueID = TRUE;
897  /* FIXME: Fill other fields */
898 
899  return STATUS_SUCCESS;
900 }
901 
902 static NTSTATUS
905  IN PIRP Irp,
907 {
908  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
910 
912 
913  if (DeviceExtension->DeviceInfo->ResourceList)
914  {
915  /* Copy existing resource requirement list */
917  PagedPool,
918  DeviceExtension->DeviceInfo->ResourceListSize);
919  if (!ResourceList)
920  return STATUS_NO_MEMORY;
921 
923  ResourceList,
924  DeviceExtension->DeviceInfo->ResourceList,
925  DeviceExtension->DeviceInfo->ResourceListSize);
926 
927  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
928 
929  return STATUS_SUCCESS;
930  }
931  else
932  {
933  /* No resources so just return without changing the status */
934  return Irp->IoStatus.Status;
935  }
936 }
937 
938 static NTSTATUS
941  IN PIRP Irp,
943 {
944  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
946 
948 
949  if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
950  {
951  /* Copy existing resource requirement list */
953  if (!ResourceList)
954  return STATUS_NO_MEMORY;
955 
957  ResourceList,
958  DeviceExtension->DeviceInfo->ResourceRequirementsList,
959  DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
960 
961  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
962 
963  return STATUS_SUCCESS;
964  }
965  else
966  {
967  /* No resource requirements so just return without changing the status */
968  return Irp->IoStatus.Status;
969  }
970 }
971 
972 static NTSTATUS
975  IN PIRP Irp,
977 {
978  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
979  DEVICE_TEXT_TYPE DeviceTextType;
980  NTSTATUS Status = Irp->IoStatus.Status;
981 
983  DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
984 
985  switch (DeviceTextType)
986  {
988  {
990  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
991 
992  if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
993  {
995  &DeviceExtension->DeviceInfo->DeviceDescription,
996  &String);
997  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
998  }
999  break;
1000  }
1001 
1003  {
1004  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1005  break;
1006  }
1007 
1008  default:
1009  {
1010  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1011  }
1012  }
1013 
1014  return Status;
1015 }
1016 
1017 static NTSTATUS
1020  IN PIRP Irp,
1022 {
1023  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1025  NTSTATUS Status = Irp->IoStatus.Status;
1026 
1028  IdType = IrpSp->Parameters.QueryId.IdType;
1029 
1030  switch (IdType)
1031  {
1032  case BusQueryDeviceID:
1033  {
1035  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1036 
1039  &DeviceExtension->DeviceInfo->DeviceID,
1040  &String);
1041  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1042  break;
1043  }
1044 
1045  case BusQueryHardwareIDs:
1046  case BusQueryCompatibleIDs:
1047  {
1048  /* Optional, do nothing */
1049  break;
1050  }
1051 
1052  case BusQueryInstanceID:
1053  {
1055  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1056 
1059  &DeviceExtension->DeviceInfo->InstanceID,
1060  &String);
1061  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1062  break;
1063  }
1064 
1065  default:
1066  {
1067  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1068  }
1069  }
1070 
1071  return Status;
1072 }
1073 
1074 static NTSTATUS
1077  IN PIRP Irp,
1079 {
1080  PPNP_BUS_INFORMATION BusInfo;
1081  NTSTATUS Status;
1082 
1084  if (!BusInfo)
1086  else
1087  {
1088  RtlCopyMemory(
1089  &BusInfo->BusTypeGuid,
1090  &GUID_BUS_TYPE_INTERNAL,
1091  sizeof(BusInfo->BusTypeGuid));
1092  BusInfo->LegacyBusType = PNPBus;
1093  /* We're the only root bus enumerator on the computer */
1094  BusInfo->BusNumber = 0;
1095  Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1097  }
1098 
1099  return Status;
1100 }
1101 
1102 /*
1103  * FUNCTION: Handle Plug and Play IRPs for the child device
1104  * ARGUMENTS:
1105  * DeviceObject = Pointer to physical device object of the child device
1106  * Irp = Pointer to IRP that should be handled
1107  * RETURNS:
1108  * Status
1109  */
1110 static NTSTATUS
1113  IN PIRP Irp)
1114 {
1115  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1116  PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1118  NTSTATUS Status;
1119 
1120  DeviceExtension = DeviceObject->DeviceExtension;
1121  FdoDeviceExtension = PnpRootDeviceObject->DeviceExtension;
1122  Status = Irp->IoStatus.Status;
1124 
1125  switch (IrpSp->MinorFunction)
1126  {
1127  case IRP_MN_START_DEVICE: /* 0x00 */
1128  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1130  break;
1131 
1132  case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1134  break;
1135 
1136  case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1137  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1139  break;
1140 
1141  case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1142  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1144  break;
1145 
1146  case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1147  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1149  break;
1150 
1151  case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1152  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1154  break;
1155 
1156  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
1157  DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1158  break;
1159 
1160  case IRP_MN_REMOVE_DEVICE:
1161  /* Remove the device from the device list and decrement the device count*/
1162  KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1163  RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1164  FdoDeviceExtension->DeviceListCount--;
1165  KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1166 
1167  /* Free some strings we created */
1169  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1170  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1171 
1172  /* Free the resource requirements list */
1173  if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1174  ExFreePool(DeviceExtension->DeviceInfo->ResourceRequirementsList);
1175 
1176  /* Free the boot resources list */
1177  if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1178  ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1179 
1180  /* Free the device info */
1181  ExFreePool(DeviceExtension->DeviceInfo);
1182 
1183  /* Finally, delete the device object */
1185 
1186  /* Return success */
1188  break;
1189 
1190  case IRP_MN_QUERY_ID: /* 0x13 */
1192  break;
1193 
1194  case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1195  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1196  break;
1197 
1198  case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1199  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1201  break;
1202 
1203  default:
1204  DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1205  break;
1206  }
1207 
1208  if (Status != STATUS_PENDING)
1209  {
1210  Irp->IoStatus.Status = Status;
1212  }
1213 
1214  return Status;
1215 }
1216 
1217 /*
1218  * FUNCTION: Handle Plug and Play IRPs
1219  * ARGUMENTS:
1220  * DeviceObject = Pointer to PDO or FDO
1221  * Irp = Pointer to IRP that should be handled
1222  * RETURNS:
1223  * Status
1224  */
1225 static NTSTATUS NTAPI
1228  IN PIRP Irp)
1229 {
1230  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
1231  NTSTATUS Status;
1232 
1234 
1235  if (DeviceExtension->IsFDO)
1237  else
1239 
1240  return Status;
1241 }
1242 
1243 /*
1244  * FUNCTION: Handle Power IRPs
1245  * ARGUMENTS:
1246  * DeviceObject = Pointer to PDO or FDO
1247  * Irp = Pointer to IRP that should be handled
1248  * RETURNS:
1249  * Status
1250  */
1251 static NTSTATUS NTAPI
1254  IN PIRP Irp)
1255 {
1256  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1258  NTSTATUS Status;
1259 
1260  DeviceExtension = DeviceObject->DeviceExtension;
1261  Status = Irp->IoStatus.Status;
1263 
1264  if (DeviceExtension->Common.IsFDO)
1265  {
1266  ASSERT(!DeviceExtension->Common.IsFDO);
1269  Status = PoCallDriver(DeviceExtension->Ldo, Irp);
1270  }
1271  else
1272  {
1273  switch (IrpSp->MinorFunction)
1274  {
1275  case IRP_MN_QUERY_POWER:
1276  case IRP_MN_SET_POWER:
1278  break;
1279  }
1280  Irp->IoStatus.Status = Status;
1283  }
1284 
1285  return Status;
1286 }
1287 
1288 NTSTATUS
1289 NTAPI
1293 {
1294  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1295  NTSTATUS Status;
1296 
1297  DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject, PhysicalDeviceObject);
1298 
1299  if (!PhysicalDeviceObject)
1300  {
1301  DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
1303  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1304  }
1305 
1307  DriverObject,
1309  NULL,
1312  TRUE,
1314  if (!NT_SUCCESS(Status))
1315  {
1316  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
1317  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1318  }
1319  DPRINT("Created FDO %p\n", PnpRootDeviceObject);
1320 
1322  RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
1323 
1324  DeviceExtension->Common.IsFDO = TRUE;
1325  DeviceExtension->State = dsStopped;
1326  InitializeListHead(&DeviceExtension->DeviceListHead);
1327  DeviceExtension->DeviceListCount = 0;
1328  KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
1329 
1333  &DeviceExtension->Ldo);
1334  if (!NT_SUCCESS(Status))
1335  {
1336  DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
1337  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1338  }
1339 
1341 
1342  DPRINT("Done AddDevice()\n");
1343 
1344  return STATUS_SUCCESS;
1345 }
1346 
1347 #if MI_TRACE_PFNS
1348 PDEVICE_OBJECT IopPfnDumpDeviceObject;
1349 
1351 PnpRootCreateClose(
1353  _In_ PIRP Irp)
1354 {
1355  PIO_STACK_LOCATION IoStack;
1356 
1357  if (DeviceObject != IopPfnDumpDeviceObject)
1358  {
1359  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1362  }
1363 
1364  IoStack = IoGetCurrentIrpStackLocation(Irp);
1365  if (IoStack->MajorFunction == IRP_MJ_CREATE)
1366  {
1368  }
1369 
1370  Irp->IoStatus.Status = STATUS_SUCCESS;
1372  return STATUS_SUCCESS;
1373 }
1374 #endif
1375 
1380 {
1381 #if MI_TRACE_PFNS
1382  NTSTATUS Status;
1383  UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1384 #endif
1385 
1386  DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1387 
1389 
1391 
1392 #if MI_TRACE_PFNS
1393  DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1394  DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1395 #endif
1398 
1399 #if MI_TRACE_PFNS
1401  0,
1402  &PfnDumpDeviceName,
1404  0,
1405  FALSE,
1406  &IopPfnDumpDeviceObject);
1407  if (!NT_SUCCESS(Status))
1408  {
1409  DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1410  }
1411  else
1412  {
1413  IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1414  }
1415 #endif
1416 
1417  return STATUS_SUCCESS;
1418 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
PNPROOT_DEVICE_STATE
Definition: pnproot.c:41
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
const uint16_t * PCWSTR
Definition: typedefs.h:55
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define IN
Definition: typedefs.h:38
static NTSTATUS EnumerateDevices(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:439
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:193
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define IRP_MN_QUERY_POWER
static NTSTATUS LocateChildDevice(IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, IN PCWSTR DeviceId, IN PCWSTR InstanceId, OUT PPNPROOT_DEVICE *ChildDevice)
Definition: pnproot.c:93
_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
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
_In_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
uint16_t * PWSTR
Definition: typedefs.h:54
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:2054
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
#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
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
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:1018
#define REGSTR_PATH_SYSTEMENUM
Definition: regstr.h:483
struct _PNPROOT_DEVICE * PPNPROOT_DEVICE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
PDEVICE_OBJECT Pdo
Definition: pnproot.c:27
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:853
static WCHAR String[]
Definition: stringtable.c:55
static NTSTATUS PdoQueryBusInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1075
#define InsertTailList(ListHead, Entry)
static NTSTATUS PnpRootFdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:797
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
static NTSTATUS PdoQueryResources(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:903
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:69
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
PNPROOT_DEVICE_STATE State
Definition: pnproot.c:73
struct _PNPROOT_FDO_DEVICE_EXTENSION * PPNPROOT_FDO_DEVICE_EXTENSION
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:109
#define UNICODE_NULL
#define REGSTR_KEY_ROOTENUM
Definition: regstr.h:10
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2173
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_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:3988
PULONG Length
Definition: pnproot.c:85
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
#define DO_BUS_ENUMERATED_DEVICE
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
#define DeviceCapabilities
Definition: wingdi.h:4427
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
Definition: bufpool.h:45
switch(r->id)
Definition: btrfs.c:2743
NTSTATUS NTAPI PnpRootAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnproot.c:1290
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:357
#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
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT OPTIONAL PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:186
struct _BUFFER BUFFER
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define IRP_MN_STOP_DEVICE
if(!(yy_init))
Definition: macro.lex.yy.c:714
__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
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
struct _PNPROOT_PDO_DEVICE_EXTENSION PNPROOT_PDO_DEVICE_EXTENSION
#define MAX_PATH
Definition: compat.h:26
#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:1377
#define BufferSize
Definition: classpnp.h:419
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2875
#define IRP_MN_QUERY_DEVICE_TEXT
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: Node.h:9
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4723
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:34
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IRP_MJ_POWER
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static NTSTATUS PnpRootQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:679
#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:412
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
static const WCHAR L[]
Definition: oid.c:1250
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#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:117
static PDEVICE_OBJECT PnpRootDeviceObject
Definition: pnproot.c:88
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
* PDEVICE_CAPABILITIES
Definition: iotypes.h:927
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2111
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3670
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
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:4157
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
static NTSTATUS NTAPI PnpRootPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1226
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:60
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
struct _PNPROOT_COMMON_DEVICE_EXTENSION PNPROOT_COMMON_DEVICE_EXTENSION
KGUARDED_MUTEX DeviceListLock
Definition: pnproot.c:79
#define TAG_PNP_ROOT
Definition: tag.h:95
unsigned int * PULONG
Definition: retypes.h:1
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:139
#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
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
UNICODE_STRING InstanceID
Definition: pnproot.c:31
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
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:261
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
char * cleanup(char *str)
Definition: wpickclick.c:99
_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:884
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:973
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static NTSTATUS PdoQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:939
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
Definition: pnproot.c:35
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:147
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define REG_DWORD
Definition: sdbapi.c:596
static NTSTATUS NTAPI PnpRootPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1252
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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:1111
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
#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:107
#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:386
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
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68