ReactOS  0.4.15-dev-980-ge160524
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)
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  *ChildDevice = Device;
120  return STATUS_SUCCESS;
121  }
122  }
123 
124  /* No device found */
125  return STATUS_NO_SUCH_DEVICE;
126 }
127 
128 NTSTATUS
131 {
135  PWSTR InstancePath;
136  UNICODE_STRING InstancePathCopy;
137 
139  if (!Device) return STATUS_NO_MEMORY;
140 
142  if (!RtlCreateUnicodeString(&InstancePathCopy, DeviceNode->InstancePath.Buffer))
143  {
145  return STATUS_NO_MEMORY;
146  }
147 
148  InstancePath = wcsrchr(InstancePathCopy.Buffer, L'\\');
149  ASSERT(InstancePath);
150 
151  if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath + 1))
152  {
153  RtlFreeUnicodeString(&InstancePathCopy);
155  return STATUS_NO_MEMORY;
156  }
157 
158  InstancePath[0] = UNICODE_NULL;
159 
160  if (!RtlCreateUnicodeString(&Device->DeviceID, InstancePathCopy.Buffer))
161  {
162  RtlFreeUnicodeString(&InstancePathCopy);
163  RtlFreeUnicodeString(&Device->InstanceID);
165  return STATUS_NO_MEMORY;
166  }
167 
168  InstancePath[0] = L'\\';
169 
170  Device->Pdo = DeviceObject;
171 
172  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
173  InsertTailList(&DeviceExtension->DeviceListHead,
174  &Device->ListEntry);
175  DeviceExtension->DeviceListCount++;
176  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
177 
178  RtlFreeUnicodeString(&InstancePathCopy);
179 
180  return STATUS_SUCCESS;
181 }
182 
183 /* Creates a new PnP device for a legacy driver */
184 NTSTATUS
189  OUT OPTIONAL PUNICODE_STRING FullInstancePath)
190 {
191  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
192  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
193  UNICODE_STRING DevicePath;
194  WCHAR InstancePath[5];
197  UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
198  ULONG NextInstance;
199  UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
200  HANDLE EnumHandle, DeviceKeyHandle = NULL, InstanceKeyHandle;
203 
204  DeviceExtension = PnpRootDeviceObject->DeviceExtension;
205  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
206 
207  DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
208 
209  DevicePath.Length = 0;
210  DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + ServiceName->Length;
212  DevicePath.MaximumLength,
213  TAG_PNP_ROOT);
214  if (DevicePath.Buffer == NULL)
215  {
216  DPRINT1("ExAllocatePoolWithTag() failed\n");
218  goto cleanup;
219  }
222 
223  /* Initialize a PNPROOT_DEVICE structure */
225  if (!Device)
226  {
227  DPRINT("ExAllocatePoolWithTag() failed\n");
229  goto cleanup;
230  }
232  Device->DeviceID = DevicePath;
233  RtlInitEmptyUnicodeString(&DevicePath, NULL, 0);
234 
235  Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
236  if (NT_SUCCESS(Status))
237  {
239  &Device->DeviceID,
241  EnumHandle,
242  NULL);
243  Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
244  ObCloseHandle(EnumHandle, KernelMode);
245  }
246 
247  if (!NT_SUCCESS(Status))
248  {
249  DPRINT1("Failed to open registry key\n");
250  goto cleanup;
251  }
252 
253 tryagain:
255  QueryTable[0].Name = L"NextInstance";
256  QueryTable[0].EntryContext = &NextInstance;
258 
260  (PWSTR)DeviceKeyHandle,
261  QueryTable,
262  NULL,
263  NULL);
264  if (!NT_SUCCESS(Status))
265  {
266  for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
267  {
268  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
269  Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, &Device);
271  break;
272  }
273 
274  if (NextInstance > 9999)
275  {
276  DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
278  goto cleanup;
279  }
280  }
281 
282  _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
283  Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, &Device);
284  if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
285  {
286  DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
288  (PWSTR)DeviceKeyHandle,
289  L"NextInstance");
290  goto tryagain;
291  }
292 
293  NextInstance++;
295  (PWSTR)DeviceKeyHandle,
296  L"NextInstance",
297  REG_DWORD,
298  &NextInstance,
299  sizeof(NextInstance));
300  if (!NT_SUCCESS(Status))
301  {
302  DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
303  goto cleanup;
304  }
305 
306  if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
307  {
309  goto cleanup;
310  }
311 
312  /* Finish creating the instance path in the registry */
314  &Device->InstanceID,
316  DeviceKeyHandle,
317  NULL);
318  Status = ZwCreateKey(&InstanceKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
319  if (!NT_SUCCESS(Status))
320  {
321  DPRINT1("Failed to create instance path (0x%x)\n", Status);
322  goto cleanup;
323  }
324 
325  /* Just close the handle */
326  ObCloseHandle(InstanceKeyHandle, KernelMode);
327 
328  if (FullInstancePath)
329  {
330  FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
331  FullInstancePath->Length = 0;
332  FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
333  if (!FullInstancePath->Buffer)
334  {
336  goto cleanup;
337  }
338 
339  RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
340  RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
341  RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
342  }
343 
344  /* Initialize a device object */
348  NULL,
351  FALSE,
352  &Device->Pdo);
353  if (!NT_SUCCESS(Status))
354  {
355  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
357  goto cleanup;
358  }
359 
360  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
361  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
362  PdoDeviceExtension->Common.IsFDO = FALSE;
363  PdoDeviceExtension->DeviceInfo = Device;
364 
365  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
366  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
367 
369  &DeviceExtension->DeviceListHead,
370  &Device->ListEntry);
371  DeviceExtension->DeviceListCount++;
372 
374  DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject, &Device->DeviceID, &Device->InstanceID);
375  Device = NULL;
377 
378 cleanup:
379  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
380  if (Device)
381  {
382  if (Device->Pdo)
383  IoDeleteDevice(Device->Pdo);
384  RtlFreeUnicodeString(&Device->DeviceID);
385  RtlFreeUnicodeString(&Device->InstanceID);
387  }
388  RtlFreeUnicodeString(&DevicePath);
389  if (DeviceKeyHandle != NULL)
390  ObCloseHandle(DeviceKeyHandle, KernelMode);
391  return Status;
392 }
393 
394 static NTSTATUS NTAPI
400  IN PVOID Context,
402 {
405 
406  if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
407  {
408  Destination->Length = 0;
411  return STATUS_SUCCESS;
412  }
413 
414  Source.MaximumLength = Source.Length = (USHORT)ValueLength;
415  Source.Buffer = ValueData;
416 
418 }
419 
420 static NTSTATUS NTAPI
426  IN PVOID Context,
428 {
430  PVOID BinaryValue;
431 
432  if (ValueLength == 0)
433  {
434  *Buffer->Data = NULL;
435  return STATUS_SUCCESS;
436  }
437 
439  if (BinaryValue == NULL)
440  return STATUS_NO_MEMORY;
441  RtlCopyMemory(BinaryValue, ValueData, ValueLength);
442  *Buffer->Data = BinaryValue;
443  if (Buffer->Length) *Buffer->Length = ValueLength;
444  return STATUS_SUCCESS;
445 }
446 
447 static
448 NTSTATUS
450  _Inout_ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
451  _Inout_ PUNICODE_STRING DevicePath,
454 {
457  HANDLE DeviceKeyHandle = NULL;
459  BUFFER Buffer1, Buffer2;
460 
461  /* If the device already exists, there's nothing to do */
462  Status = LocateChildDevice(DeviceExtension, DevicePath, InstanceId, &Device);
464  {
465  return STATUS_SUCCESS;
466  }
467 
468  /* Create a PPNPROOT_DEVICE object, and add it to the list of known devices */
470  if (!Device)
471  {
472  DPRINT("ExAllocatePoolWithTag() failed\n");
474  goto cleanup;
475  }
477 
478  /* Fill device ID and instance ID */
479  Device->DeviceID = *DevicePath;
480  RtlInitEmptyUnicodeString(DevicePath, NULL, 0);
481  if (!RtlCreateUnicodeString(&Device->InstanceID, InstanceId))
482  {
483  DPRINT1("RtlCreateUnicodeString() failed\n");
485  goto cleanup;
486  }
487 
488  /* Open registry key to fill other informations */
489  Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
490  if (!NT_SUCCESS(Status))
491  {
492  /* If our key disappeared, let the caller go on */
493  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
494  &Device->InstanceID, Status);
496  goto cleanup;
497  }
498 
499  /* Fill information from the device instance key */
502  QueryTable[0].Name = L"DeviceDesc";
503  QueryTable[0].EntryContext = &Device->DeviceDescription;
504 
506  (PCWSTR)DeviceKeyHandle,
507  QueryTable,
508  NULL,
509  NULL);
510 
511  /* Fill information from the LogConf subkey */
512  Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
513  Buffer1.Length = NULL;
514  Buffer2.Data = (PVOID *)&Device->ResourceList;
515  Buffer2.Length = &Device->ResourceListSize;
518  QueryTable[0].Name = L"LogConf";
520  QueryTable[1].Name = L"BasicConfigVector";
521  QueryTable[1].EntryContext = &Buffer1;
523  QueryTable[2].Name = L"BootConfig";
524  QueryTable[2].EntryContext = &Buffer2;
525 
527  (PCWSTR)DeviceKeyHandle,
528  QueryTable,
529  NULL,
530  NULL)))
531  {
532  /* Non-fatal error */
533  DPRINT1("Failed to read the LogConf key for %wZ\\%S\n", &Device->DeviceID, InstanceId);
534  }
535 
536  /* Insert the newly created device into the list */
537  InsertTailList(&DeviceExtension->DeviceListHead,
538  &Device->ListEntry);
539  DeviceExtension->DeviceListCount++;
540  Device = NULL;
541 
542 cleanup:
543  if (DeviceKeyHandle != NULL)
544  {
545  ZwClose(DeviceKeyHandle);
546  }
547  if (Device != NULL)
548  {
549  /* We have a device that has not been added to device list. We need to clean it up */
550  RtlFreeUnicodeString(&Device->DeviceID);
551  RtlFreeUnicodeString(&Device->InstanceID);
553  }
554  return Status;
555 }
556 
557 static NTSTATUS
560 {
561  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
562  PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
563  UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
566  UNICODE_STRING DevicePath;
569  ULONG KeyInfoSize, SubKeyInfoSize;
570  ULONG ResultSize;
571  ULONG Index1, Index2;
573 
574  DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
575 
577  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
578 
579  /* Should hold most key names, but we reallocate below if it's too small */
580  KeyInfoSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + 64 * sizeof(WCHAR);
582  KeyInfoSize + sizeof(UNICODE_NULL),
583  TAG_PNP_ROOT);
584  if (!KeyInfo)
585  {
586  DPRINT("ExAllocatePoolWithTag() failed\n");
588  goto cleanup;
589  }
590  SubKeyInfoSize = KeyInfoSize;
591  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
592  SubKeyInfoSize + sizeof(UNICODE_NULL),
593  TAG_PNP_ROOT);
594  if (!SubKeyInfo)
595  {
596  DPRINT("ExAllocatePoolWithTag() failed\n");
598  goto cleanup;
599  }
600 
602  if (!NT_SUCCESS(Status))
603  {
604  DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
605  goto cleanup;
606  }
607 
608  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
609  * KeyHandle. We'll first do a first enumeration to have first level keys,
610  * and an inner one to have the real devices list.
611  */
612  Index1 = 0;
613  while (TRUE)
614  {
615  Status = ZwEnumerateKey(
616  KeyHandle,
617  Index1,
619  KeyInfo,
620  KeyInfoSize,
621  &ResultSize);
623  {
625  break;
626  }
627  else if (Status == STATUS_BUFFER_OVERFLOW ||
629  {
630  ASSERT(KeyInfoSize < ResultSize);
631  KeyInfoSize = ResultSize;
634  KeyInfoSize + sizeof(UNICODE_NULL),
635  TAG_PNP_ROOT);
636  if (!KeyInfo)
637  {
638  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", KeyInfoSize);
640  goto cleanup;
641  }
642  continue;
643  }
644  else if (!NT_SUCCESS(Status))
645  {
646  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
647  goto cleanup;
648  }
649 
650  /* Terminate the string */
651  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
652 
653  /* Check if it is a legacy driver */
655  if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
656  {
657  DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
658  Index1++;
659  continue;
660  }
661 
662  /* Open the key */
664  if (!NT_SUCCESS(Status))
665  {
666  DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
667  &SubKeyName, Status);
668  break;
669  }
670 
671  /* Enumerate the sub-keys */
672  Index2 = 0;
673  while (TRUE)
674  {
675  Status = ZwEnumerateKey(
676  SubKeyHandle,
677  Index2,
679  SubKeyInfo,
680  SubKeyInfoSize,
681  &ResultSize);
683  {
684  break;
685  }
686  else if (Status == STATUS_BUFFER_OVERFLOW ||
688  {
689  ASSERT(SubKeyInfoSize < ResultSize);
690  SubKeyInfoSize = ResultSize;
691  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
692  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
693  SubKeyInfoSize + sizeof(UNICODE_NULL),
694  TAG_PNP_ROOT);
695  if (!SubKeyInfo)
696  {
697  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", SubKeyInfoSize);
699  goto cleanup;
700  }
701  continue;
702  }
703  else if (!NT_SUCCESS(Status))
704  {
705  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
706  break;
707  }
708 
709  /* Terminate the string */
710  SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
711 
712  /* Compute device ID */
713  DevicePath.Length = 0;
714  DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + SubKeyName.Length;
716  DevicePath.MaximumLength,
717  TAG_PNP_ROOT);
718  if (DevicePath.Buffer == NULL)
719  {
720  DPRINT1("ExAllocatePoolWithTag() failed\n");
722  goto cleanup;
723  }
724 
727  DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
728  Status = CreateDeviceFromRegistry(DeviceExtension,
729  &DevicePath,
730  SubKeyInfo->Name,
731  SubKeyHandle);
732 
733  /* If CreateDeviceFromRegistry didn't take ownership and zero this,
734  * we need to free it
735  */
736  RtlFreeUnicodeString(&DevicePath);
737 
738  if (!NT_SUCCESS(Status))
739  {
740  goto cleanup;
741  }
742 
743  Index2++;
744  }
745 
747  SubKeyHandle = NULL;
748  Index1++;
749  }
750 
751 cleanup:
752  if (SubKeyHandle != NULL)
754  if (KeyHandle != NULL)
756  if (KeyInfo)
758  if (SubKeyInfo)
759  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
760  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
761  return Status;
762 }
763 
764 /* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
765  * ARGUMENTS:
766  * DeviceObject = Pointer to functional device object of the root bus driver
767  * Irp = Pointer to IRP that should be handled
768  * RETURNS:
769  * Status
770  */
771 static NTSTATUS
774  IN PIRP Irp)
775 {
776  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
777  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
778  PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
780  ULONG Size;
782  PLIST_ENTRY NextEntry;
783 
784  DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
785 
787  if (!NT_SUCCESS(Status))
788  {
789  DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
790  return Status;
791  }
792 
794 
795  Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
796  if (OtherRelations)
797  {
798  /* Another bus driver has already created a DEVICE_RELATIONS
799  * structure so we must merge this structure with our own */
800 
801  Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
802  }
804  if (!Relations)
805  {
806  DPRINT("ExAllocatePoolWithTag() failed\n");
808  goto cleanup;
809  }
810  RtlZeroMemory(Relations, Size);
811  if (OtherRelations)
812  {
813  Relations->Count = OtherRelations->Count;
814  RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
815  }
816 
817  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
818 
819  /* Start looping */
820  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
821  NextEntry != &DeviceExtension->DeviceListHead;
822  NextEntry = NextEntry->Flink)
823  {
824  /* Get the entry */
825  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
826 
827  if (!Device->Pdo)
828  {
829  /* Create a physical device object for the
830  * device as it does not already have one */
832  DeviceObject->DriverObject,
834  NULL,
837  FALSE,
838  &Device->Pdo);
839  if (!NT_SUCCESS(Status))
840  {
841  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
842  break;
843  }
844 
845  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
846  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
847  PdoDeviceExtension->Common.IsFDO = FALSE;
848  PdoDeviceExtension->DeviceInfo = Device;
849 
850  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
851  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
852  }
853 
854  /* Reference the physical device object. The PnP manager
855  will dereference it again when it is no longer needed */
857 
858  Relations->Objects[Relations->Count++] = Device->Pdo;
859  }
860  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
861 
862  Irp->IoStatus.Information = (ULONG_PTR)Relations;
863 
864 cleanup:
865  if (!NT_SUCCESS(Status))
866  {
867  if (OtherRelations)
868  ExFreePool(OtherRelations);
869  if (Relations)
870  ExFreePool(Relations);
871  if (Device && Device->Pdo)
872  {
873  IoDeleteDevice(Device->Pdo);
874  Device->Pdo = NULL;
875  }
876  }
877 
878  return Status;
879 }
880 
881 /*
882  * FUNCTION: Handle Plug and Play IRPs for the root bus device object
883  * ARGUMENTS:
884  * DeviceObject = Pointer to functional device object of the root bus driver
885  * Irp = Pointer to IRP that should be handled
886  * RETURNS:
887  * Status
888  */
889 static NTSTATUS
892  IN PIRP Irp)
893 {
894  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
897 
899  Status = Irp->IoStatus.Status;
901 
902  switch (IrpSp->MinorFunction)
903  {
905  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
907  break;
908 
909  case IRP_MN_START_DEVICE:
910  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
911  if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
913  else
914  {
915  Status = Irp->IoStatus.Status;
916  if (NT_SUCCESS(Status))
917  DeviceExtension->State = dsStarted;
918  }
919 
920  Irp->IoStatus.Status = Status;
922  return Status;
923 
924  case IRP_MN_STOP_DEVICE:
925  DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
926  /* Root device cannot be stopped */
927  Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
929  return Status;
930 
931  default:
932  DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
933  break;
934  }
935 
936  if (Status != STATUS_PENDING)
937  {
938  Irp->IoStatus.Status = Status;
940  }
941 
942  return Status;
943 }
944 
945 static NTSTATUS
948  IN PIRP Irp,
950 {
951  PDEVICE_RELATIONS Relations;
952  NTSTATUS Status = Irp->IoStatus.Status;
953 
954  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
955  return Status;
956 
957  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
959  if (!Relations)
960  {
961  DPRINT("ExAllocatePoolWithTag() failed\n");
963  }
964  else
965  {
967  Relations->Count = 1;
968  Relations->Objects[0] = DeviceObject;
970  Irp->IoStatus.Information = (ULONG_PTR)Relations;
971  }
972 
973  return Status;
974 }
975 
976 static NTSTATUS
979  IN PIRP Irp,
981 {
983 
984  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
985 
986  if (DeviceCapabilities->Version != 1)
988 
989  DeviceCapabilities->UniqueID = TRUE;
990  /* FIXME: Fill other fields */
991 
992  return STATUS_SUCCESS;
993 }
994 
995 static NTSTATUS
998  IN PIRP Irp,
1000 {
1001  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1003 
1005 
1006  if (DeviceExtension->DeviceInfo->ResourceList)
1007  {
1008  /* Copy existing resource requirement list */
1010  PagedPool,
1011  DeviceExtension->DeviceInfo->ResourceListSize);
1012  if (!ResourceList)
1013  return STATUS_NO_MEMORY;
1014 
1015  RtlCopyMemory(
1016  ResourceList,
1017  DeviceExtension->DeviceInfo->ResourceList,
1018  DeviceExtension->DeviceInfo->ResourceListSize);
1019 
1020  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1021 
1022  return STATUS_SUCCESS;
1023  }
1024  else
1025  {
1026  /* No resources so just return without changing the status */
1027  return Irp->IoStatus.Status;
1028  }
1029 }
1030 
1031 static NTSTATUS
1034  IN PIRP Irp,
1036 {
1037  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1039 
1041 
1042  if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
1043  {
1044  /* Copy existing resource requirement list */
1046  if (!ResourceList)
1047  return STATUS_NO_MEMORY;
1048 
1049  RtlCopyMemory(
1050  ResourceList,
1051  DeviceExtension->DeviceInfo->ResourceRequirementsList,
1052  DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
1053 
1054  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1055 
1056  return STATUS_SUCCESS;
1057  }
1058  else
1059  {
1060  /* No resource requirements so just return without changing the status */
1061  return Irp->IoStatus.Status;
1062  }
1063 }
1064 
1065 static NTSTATUS
1068  IN PIRP Irp,
1070 {
1071  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1072  DEVICE_TEXT_TYPE DeviceTextType;
1073  NTSTATUS Status = Irp->IoStatus.Status;
1074 
1076  DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
1077 
1078  switch (DeviceTextType)
1079  {
1080  case DeviceTextDescription:
1081  {
1083  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
1084 
1085  if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
1086  {
1088  &DeviceExtension->DeviceInfo->DeviceDescription,
1089  &String);
1090  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1091  }
1092  break;
1093  }
1094 
1096  {
1097  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1098  break;
1099  }
1100 
1101  default:
1102  {
1103  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1104  }
1105  }
1106 
1107  return Status;
1108 }
1109 
1110 static NTSTATUS
1113  IN PIRP Irp,
1115 {
1116  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1118  NTSTATUS Status = Irp->IoStatus.Status;
1119 
1121  IdType = IrpSp->Parameters.QueryId.IdType;
1122 
1123  switch (IdType)
1124  {
1125  case BusQueryDeviceID:
1126  {
1128  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1129 
1132  &DeviceExtension->DeviceInfo->DeviceID,
1133  &String);
1134  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1135  break;
1136  }
1137 
1138  case BusQueryHardwareIDs:
1139  case BusQueryCompatibleIDs:
1140  {
1141  /* Optional, do nothing */
1142  break;
1143  }
1144 
1145  case BusQueryInstanceID:
1146  {
1148  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1149 
1152  &DeviceExtension->DeviceInfo->InstanceID,
1153  &String);
1154  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1155  break;
1156  }
1157 
1158  default:
1159  {
1160  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1161  }
1162  }
1163 
1164  return Status;
1165 }
1166 
1167 static NTSTATUS
1170  IN PIRP Irp,
1172 {
1173  PPNP_BUS_INFORMATION BusInfo;
1174  NTSTATUS Status;
1175 
1177  if (!BusInfo)
1179  else
1180  {
1181  RtlCopyMemory(
1182  &BusInfo->BusTypeGuid,
1183  &GUID_BUS_TYPE_INTERNAL,
1184  sizeof(BusInfo->BusTypeGuid));
1185  BusInfo->LegacyBusType = PNPBus;
1186  /* We're the only root bus enumerator on the computer */
1187  BusInfo->BusNumber = 0;
1188  Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1190  }
1191 
1192  return Status;
1193 }
1194 
1195 /*
1196  * FUNCTION: Handle Plug and Play IRPs for the child device
1197  * ARGUMENTS:
1198  * DeviceObject = Pointer to physical device object of the child device
1199  * Irp = Pointer to IRP that should be handled
1200  * RETURNS:
1201  * Status
1202  */
1203 static NTSTATUS
1206  IN PIRP Irp)
1207 {
1208  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1209  PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1211  NTSTATUS Status;
1212 
1213  DeviceExtension = DeviceObject->DeviceExtension;
1214  FdoDeviceExtension = PnpRootDeviceObject->DeviceExtension;
1215  Status = Irp->IoStatus.Status;
1217 
1218  switch (IrpSp->MinorFunction)
1219  {
1220  case IRP_MN_START_DEVICE: /* 0x00 */
1221  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1223  break;
1224 
1225  case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1227  break;
1228 
1229  case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1230  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1232  break;
1233 
1234  case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1235  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1237  break;
1238 
1239  case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1240  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1242  break;
1243 
1244  case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1245  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1247  break;
1248 
1249  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
1250  DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1251  break;
1252 
1253  case IRP_MN_REMOVE_DEVICE:
1254  /* Remove the device from the device list and decrement the device count*/
1255  KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1256  RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1257  FdoDeviceExtension->DeviceListCount--;
1258  KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1259 
1260  /* Free some strings we created */
1262  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1263  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1264 
1265  /* Free the resource requirements list */
1266  if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1267  ExFreePool(DeviceExtension->DeviceInfo->ResourceRequirementsList);
1268 
1269  /* Free the boot resources list */
1270  if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1271  ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1272 
1273  /* Free the device info */
1274  ExFreePool(DeviceExtension->DeviceInfo);
1275 
1276  /* Finally, delete the device object */
1278 
1279  /* Return success */
1281  break;
1282 
1283  case IRP_MN_QUERY_ID: /* 0x13 */
1285  break;
1286 
1287  case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1288  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1289  break;
1290 
1291  case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1292  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1294  break;
1295 
1296  default:
1297  DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1298  break;
1299  }
1300 
1301  if (Status != STATUS_PENDING)
1302  {
1303  Irp->IoStatus.Status = Status;
1305  }
1306 
1307  return Status;
1308 }
1309 
1310 /*
1311  * FUNCTION: Handle Plug and Play IRPs
1312  * ARGUMENTS:
1313  * DeviceObject = Pointer to PDO or FDO
1314  * Irp = Pointer to IRP that should be handled
1315  * RETURNS:
1316  * Status
1317  */
1318 static NTSTATUS NTAPI
1321  IN PIRP Irp)
1322 {
1323  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
1324  NTSTATUS Status;
1325 
1327 
1328  if (DeviceExtension->IsFDO)
1330  else
1332 
1333  return Status;
1334 }
1335 
1336 /*
1337  * FUNCTION: Handle Power IRPs
1338  * ARGUMENTS:
1339  * DeviceObject = Pointer to PDO or FDO
1340  * Irp = Pointer to IRP that should be handled
1341  * RETURNS:
1342  * Status
1343  */
1344 static NTSTATUS NTAPI
1347  IN PIRP Irp)
1348 {
1349  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1351  NTSTATUS Status;
1352 
1353  DeviceExtension = DeviceObject->DeviceExtension;
1354  Status = Irp->IoStatus.Status;
1356 
1357  if (DeviceExtension->Common.IsFDO)
1358  {
1359  ASSERT(!DeviceExtension->Common.IsFDO);
1362  Status = PoCallDriver(DeviceExtension->Ldo, Irp);
1363  }
1364  else
1365  {
1366  switch (IrpSp->MinorFunction)
1367  {
1368  case IRP_MN_QUERY_POWER:
1369  case IRP_MN_SET_POWER:
1371  break;
1372  }
1373  Irp->IoStatus.Status = Status;
1376  }
1377 
1378  return Status;
1379 }
1380 
1381 NTSTATUS
1382 NTAPI
1386 {
1387  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1388  NTSTATUS Status;
1389 
1390  DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject, PhysicalDeviceObject);
1391 
1392  if (!PhysicalDeviceObject)
1393  {
1394  DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
1396  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1397  }
1398 
1400  DriverObject,
1402  NULL,
1405  TRUE,
1407  if (!NT_SUCCESS(Status))
1408  {
1409  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
1410  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1411  }
1412  DPRINT("Created FDO %p\n", PnpRootDeviceObject);
1413 
1415  RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
1416 
1417  DeviceExtension->Common.IsFDO = TRUE;
1418  DeviceExtension->State = dsStopped;
1419  InitializeListHead(&DeviceExtension->DeviceListHead);
1420  DeviceExtension->DeviceListCount = 0;
1421  KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
1422 
1426  &DeviceExtension->Ldo);
1427  if (!NT_SUCCESS(Status))
1428  {
1429  DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
1430  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1431  }
1432 
1434 
1435  DPRINT("Done AddDevice()\n");
1436 
1437  return STATUS_SUCCESS;
1438 }
1439 
1440 #if MI_TRACE_PFNS
1441 PDEVICE_OBJECT IopPfnDumpDeviceObject;
1442 
1444 PnpRootCreateClose(
1446  _In_ PIRP Irp)
1447 {
1448  PIO_STACK_LOCATION IoStack;
1449 
1450  if (DeviceObject != IopPfnDumpDeviceObject)
1451  {
1452  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1455  }
1456 
1457  IoStack = IoGetCurrentIrpStackLocation(Irp);
1458  if (IoStack->MajorFunction == IRP_MJ_CREATE)
1459  {
1461  }
1462 
1463  Irp->IoStatus.Status = STATUS_SUCCESS;
1465  return STATUS_SUCCESS;
1466 }
1467 #endif
1468 
1473 {
1474 #if MI_TRACE_PFNS
1475  NTSTATUS Status;
1476  UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1477 #endif
1478 
1479  DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1480 
1482 
1484 
1485 #if MI_TRACE_PFNS
1486  DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1487  DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1488 #endif
1491 
1492 #if MI_TRACE_PFNS
1494  0,
1495  &PfnDumpDeviceName,
1497  0,
1498  FALSE,
1499  &IopPfnDumpDeviceObject);
1500  if (!NT_SUCCESS(Status))
1501  {
1502  DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1503  }
1504  else
1505  {
1506  IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1507  }
1508 #endif
1509 
1510  return STATUS_SUCCESS;
1511 }
#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
_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:57
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
#define IN
Definition: typedefs.h:39
static NTSTATUS EnumerateDevices(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:558
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS PnpRootRegisterDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:129
#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
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2029
_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
_In_ PIRP Irp
Definition: csq.h:116
#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:2062
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4154
#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
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:1111
#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:449
#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:946
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:1168
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:890
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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:996
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:69
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
_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 FALSE
Definition: types.h:117
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define REGSTR_KEY_ROOTENUM
Definition: regstr.h:10
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2181
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:4142
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:4448
void DPRINT(...)
Definition: polytest.cpp:61
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:1383
_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
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT OPTIONAL PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:185
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
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
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
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:1470
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2937
#define IRP_MN_QUERY_DEVICE_TEXT
#define _Inout_
Definition: no_sal2.h:244
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:27
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
static NTSTATUS PnpRootQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:772
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
Status
Definition: gdiplustypes.h:24
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:421
static const WCHAR L[]
Definition: oid.c:1250
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
* PDEVICE_CAPABILITIES
Definition: iotypes.h:932
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2119
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:1591
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:737
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:1319
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: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:40
#define ObReferenceObject
Definition: obfuncs.h:204
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2188
UNICODE_STRING InstanceID
Definition: pnproot.c:31
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:570
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
_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:977
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1066
#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:1032
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
Definition: pnproot.c:35
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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:1345
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:1204
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:395
static NTSTATUS LocateChildDevice(IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, IN PCUNICODE_STRING DeviceId, IN PCWSTR InstanceId, OUT PPNPROOT_DEVICE *ChildDevice)
Definition: pnproot.c:93
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