ReactOS  0.4.14-dev-554-g2f8d847
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;
453  ULONG KeyInfoSize, SubKeyInfoSize;
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  /* Should hold most key names, but we reallocate below if it's too small */
465  KeyInfoSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + 64 * sizeof(WCHAR);
467  KeyInfoSize + sizeof(UNICODE_NULL),
468  TAG_PNP_ROOT);
469  if (!KeyInfo)
470  {
471  DPRINT("ExAllocatePoolWithTag() failed\n");
473  goto cleanup;
474  }
475  SubKeyInfoSize = KeyInfoSize;
476  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
477  SubKeyInfoSize + sizeof(UNICODE_NULL),
478  TAG_PNP_ROOT);
479  if (!SubKeyInfo)
480  {
481  DPRINT("ExAllocatePoolWithTag() failed\n");
483  goto cleanup;
484  }
485 
487  if (!NT_SUCCESS(Status))
488  {
489  DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
490  goto cleanup;
491  }
492 
493  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
494  * KeyHandle. We'll first do a first enumeration to have first level keys,
495  * and an inner one to have the real devices list.
496  */
497  Index1 = 0;
498  while (TRUE)
499  {
500  Status = ZwEnumerateKey(
501  KeyHandle,
502  Index1,
504  KeyInfo,
505  KeyInfoSize,
506  &ResultSize);
508  {
510  break;
511  }
512  else if (Status == STATUS_BUFFER_OVERFLOW ||
514  {
515  ASSERT(KeyInfoSize < ResultSize);
516  KeyInfoSize = ResultSize;
519  KeyInfoSize + sizeof(UNICODE_NULL),
520  TAG_PNP_ROOT);
521  if (!KeyInfo)
522  {
523  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", KeyInfoSize);
525  goto cleanup;
526  }
527  continue;
528  }
529  else if (!NT_SUCCESS(Status))
530  {
531  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
532  goto cleanup;
533  }
534 
535  /* Terminate the string */
536  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
537 
538  /* Check if it is a legacy driver */
540  if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
541  {
542  DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
543  Index1++;
544  continue;
545  }
546 
547  /* Open the key */
549  if (!NT_SUCCESS(Status))
550  {
551  DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
552  &SubKeyName, Status);
553  break;
554  }
555 
556  /* Enumerate the sub-keys */
557  Index2 = 0;
558  while (TRUE)
559  {
560  Status = ZwEnumerateKey(
561  SubKeyHandle,
562  Index2,
564  SubKeyInfo,
565  SubKeyInfoSize,
566  &ResultSize);
568  {
569  break;
570  }
571  else if (Status == STATUS_BUFFER_OVERFLOW ||
573  {
574  ASSERT(SubKeyInfoSize < ResultSize);
575  SubKeyInfoSize = ResultSize;
576  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
577  SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
578  SubKeyInfoSize + sizeof(UNICODE_NULL),
579  TAG_PNP_ROOT);
580  if (!SubKeyInfo)
581  {
582  DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", SubKeyInfoSize);
584  goto cleanup;
585  }
586  continue;
587  }
588  else if (!NT_SUCCESS(Status))
589  {
590  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
591  break;
592  }
593 
594  /* Terminate the string */
595  SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
596 
597  _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR),
598  L"%s\\%s", REGSTR_KEY_ROOTENUM, KeyInfo->Name);
599  DPRINT("Found device %S\\%s!\n", DevicePath, SubKeyInfo->Name);
600  if (LocateChildDevice(DeviceExtension, DevicePath, SubKeyInfo->Name, &Device) == STATUS_NO_SUCH_DEVICE)
601  {
602  /* Create a PPNPROOT_DEVICE object, and add if in the list of known devices */
604  if (!Device)
605  {
606  DPRINT("ExAllocatePoolWithTag() failed\n");
608  goto cleanup;
609  }
611 
612  /* Fill device ID and instance ID */
613  if (!RtlCreateUnicodeString(&Device->DeviceID, DevicePath))
614  {
615  DPRINT1("RtlCreateUnicodeString() failed\n");
617  goto cleanup;
618  }
619 
620  if (!RtlCreateUnicodeString(&Device->InstanceID, SubKeyInfo->Name))
621  {
622  DPRINT1("RtlCreateUnicodeString() failed\n");
624  goto cleanup;
625  }
626 
627  /* Open registry key to fill other informations */
628  Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
629  if (!NT_SUCCESS(Status))
630  {
631  DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
632  &Device->InstanceID, Status);
633  break;
634  }
635 
636  /* Fill information from the device instance key */
639  QueryTable[0].Name = L"DeviceDesc";
640  QueryTable[0].EntryContext = &Device->DeviceDescription;
641 
643  (PCWSTR)DeviceKeyHandle,
644  QueryTable,
645  NULL,
646  NULL);
647 
648  /* Fill information from the LogConf subkey */
649  Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
650  Buffer1.Length = NULL;
651  Buffer2.Data = (PVOID *)&Device->ResourceList;
652  Buffer2.Length = &Device->ResourceListSize;
655  QueryTable[0].Name = L"LogConf";
657  QueryTable[1].Name = L"BasicConfigVector";
658  QueryTable[1].EntryContext = &Buffer1;
660  QueryTable[2].Name = L"BootConfig";
661  QueryTable[2].EntryContext = &Buffer2;
662 
664  (PCWSTR)DeviceKeyHandle,
665  QueryTable,
666  NULL,
667  NULL)))
668  {
669  /* Non-fatal error */
670  DPRINT1("Failed to read the LogConf key for %S\\%S\n", DevicePath, SubKeyInfo->Name);
671  }
672 
673  ZwClose(DeviceKeyHandle);
674  DeviceKeyHandle = NULL;
675 
676  /* Insert the newly created device into the list */
678  &DeviceExtension->DeviceListHead,
679  &Device->ListEntry);
680  DeviceExtension->DeviceListCount++;
681  }
682  Device = NULL;
683 
684  Index2++;
685  }
686 
688  SubKeyHandle = NULL;
689  Index1++;
690  }
691 
692 cleanup:
693  if (Device)
694  {
695  /* We have a device that has not been added to device list. We need to clean it up */
696  /* FIXME */
698  }
699  if (DeviceKeyHandle != NULL)
700  ZwClose(DeviceKeyHandle);
701  if (SubKeyHandle != NULL)
703  if (KeyHandle != NULL)
705  if (KeyInfo)
707  if (SubKeyInfo)
708  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
709  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
710  return Status;
711 }
712 
713 /* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
714  * ARGUMENTS:
715  * DeviceObject = Pointer to functional device object of the root bus driver
716  * Irp = Pointer to IRP that should be handled
717  * RETURNS:
718  * Status
719  */
720 static NTSTATUS
723  IN PIRP Irp)
724 {
725  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
726  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
727  PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
729  ULONG Size;
731  PLIST_ENTRY NextEntry;
732 
733  DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
734 
736  if (!NT_SUCCESS(Status))
737  {
738  DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
739  return Status;
740  }
741 
743 
744  Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
745  if (OtherRelations)
746  {
747  /* Another bus driver has already created a DEVICE_RELATIONS
748  * structure so we must merge this structure with our own */
749 
750  Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
751  }
753  if (!Relations)
754  {
755  DPRINT("ExAllocatePoolWithTag() failed\n");
757  goto cleanup;
758  }
759  RtlZeroMemory(Relations, Size);
760  if (OtherRelations)
761  {
762  Relations->Count = OtherRelations->Count;
763  RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
764  }
765 
766  KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
767 
768  /* Start looping */
769  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
770  NextEntry != &DeviceExtension->DeviceListHead;
771  NextEntry = NextEntry->Flink)
772  {
773  /* Get the entry */
774  Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
775 
776  if (!Device->Pdo)
777  {
778  /* Create a physical device object for the
779  * device as it does not already have one */
781  DeviceObject->DriverObject,
783  NULL,
786  FALSE,
787  &Device->Pdo);
788  if (!NT_SUCCESS(Status))
789  {
790  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
791  break;
792  }
793 
794  PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
795  RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
796  PdoDeviceExtension->Common.IsFDO = FALSE;
797  PdoDeviceExtension->DeviceInfo = Device;
798 
799  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
800  Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
801  }
802 
803  /* Reference the physical device object. The PnP manager
804  will dereference it again when it is no longer needed */
806 
807  Relations->Objects[Relations->Count++] = Device->Pdo;
808  }
809  KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
810 
811  Irp->IoStatus.Information = (ULONG_PTR)Relations;
812 
813 cleanup:
814  if (!NT_SUCCESS(Status))
815  {
816  if (OtherRelations)
817  ExFreePool(OtherRelations);
818  if (Relations)
819  ExFreePool(Relations);
820  if (Device && Device->Pdo)
821  {
822  IoDeleteDevice(Device->Pdo);
823  Device->Pdo = NULL;
824  }
825  }
826 
827  return Status;
828 }
829 
830 /*
831  * FUNCTION: Handle Plug and Play IRPs for the root bus device object
832  * ARGUMENTS:
833  * DeviceObject = Pointer to functional device object of the root bus driver
834  * Irp = Pointer to IRP that should be handled
835  * RETURNS:
836  * Status
837  */
838 static NTSTATUS
841  IN PIRP Irp)
842 {
843  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
846 
848  Status = Irp->IoStatus.Status;
850 
851  switch (IrpSp->MinorFunction)
852  {
854  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
856  break;
857 
858  case IRP_MN_START_DEVICE:
859  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
860  if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
862  else
863  {
864  Status = Irp->IoStatus.Status;
865  if (NT_SUCCESS(Status))
866  DeviceExtension->State = dsStarted;
867  }
868 
869  Irp->IoStatus.Status = Status;
871  return Status;
872 
873  case IRP_MN_STOP_DEVICE:
874  DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
875  /* Root device cannot be stopped */
876  Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
878  return Status;
879 
880  default:
881  DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
882  break;
883  }
884 
885  if (Status != STATUS_PENDING)
886  {
887  Irp->IoStatus.Status = Status;
889  }
890 
891  return Status;
892 }
893 
894 static NTSTATUS
897  IN PIRP Irp,
899 {
900  PDEVICE_RELATIONS Relations;
901  NTSTATUS Status = Irp->IoStatus.Status;
902 
903  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
904  return Status;
905 
906  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
908  if (!Relations)
909  {
910  DPRINT("ExAllocatePoolWithTag() failed\n");
912  }
913  else
914  {
916  Relations->Count = 1;
917  Relations->Objects[0] = DeviceObject;
919  Irp->IoStatus.Information = (ULONG_PTR)Relations;
920  }
921 
922  return Status;
923 }
924 
925 static NTSTATUS
928  IN PIRP Irp,
930 {
932 
933  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
934 
935  if (DeviceCapabilities->Version != 1)
937 
938  DeviceCapabilities->UniqueID = TRUE;
939  /* FIXME: Fill other fields */
940 
941  return STATUS_SUCCESS;
942 }
943 
944 static NTSTATUS
947  IN PIRP Irp,
949 {
950  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
952 
954 
955  if (DeviceExtension->DeviceInfo->ResourceList)
956  {
957  /* Copy existing resource requirement list */
959  PagedPool,
960  DeviceExtension->DeviceInfo->ResourceListSize);
961  if (!ResourceList)
962  return STATUS_NO_MEMORY;
963 
965  ResourceList,
966  DeviceExtension->DeviceInfo->ResourceList,
967  DeviceExtension->DeviceInfo->ResourceListSize);
968 
969  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
970 
971  return STATUS_SUCCESS;
972  }
973  else
974  {
975  /* No resources so just return without changing the status */
976  return Irp->IoStatus.Status;
977  }
978 }
979 
980 static NTSTATUS
983  IN PIRP Irp,
985 {
986  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
988 
990 
991  if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
992  {
993  /* Copy existing resource requirement list */
995  if (!ResourceList)
996  return STATUS_NO_MEMORY;
997 
999  ResourceList,
1000  DeviceExtension->DeviceInfo->ResourceRequirementsList,
1001  DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
1002 
1003  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1004 
1005  return STATUS_SUCCESS;
1006  }
1007  else
1008  {
1009  /* No resource requirements so just return without changing the status */
1010  return Irp->IoStatus.Status;
1011  }
1012 }
1013 
1014 static NTSTATUS
1017  IN PIRP Irp,
1019 {
1020  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1021  DEVICE_TEXT_TYPE DeviceTextType;
1022  NTSTATUS Status = Irp->IoStatus.Status;
1023 
1025  DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
1026 
1027  switch (DeviceTextType)
1028  {
1029  case DeviceTextDescription:
1030  {
1032  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
1033 
1034  if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
1035  {
1037  &DeviceExtension->DeviceInfo->DeviceDescription,
1038  &String);
1039  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1040  }
1041  break;
1042  }
1043 
1045  {
1046  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1047  break;
1048  }
1049 
1050  default:
1051  {
1052  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1053  }
1054  }
1055 
1056  return Status;
1057 }
1058 
1059 static NTSTATUS
1062  IN PIRP Irp,
1064 {
1065  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1067  NTSTATUS Status = Irp->IoStatus.Status;
1068 
1070  IdType = IrpSp->Parameters.QueryId.IdType;
1071 
1072  switch (IdType)
1073  {
1074  case BusQueryDeviceID:
1075  {
1077  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1078 
1081  &DeviceExtension->DeviceInfo->DeviceID,
1082  &String);
1083  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1084  break;
1085  }
1086 
1087  case BusQueryHardwareIDs:
1088  case BusQueryCompatibleIDs:
1089  {
1090  /* Optional, do nothing */
1091  break;
1092  }
1093 
1094  case BusQueryInstanceID:
1095  {
1097  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1098 
1101  &DeviceExtension->DeviceInfo->InstanceID,
1102  &String);
1103  Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1104  break;
1105  }
1106 
1107  default:
1108  {
1109  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1110  }
1111  }
1112 
1113  return Status;
1114 }
1115 
1116 static NTSTATUS
1119  IN PIRP Irp,
1121 {
1122  PPNP_BUS_INFORMATION BusInfo;
1123  NTSTATUS Status;
1124 
1126  if (!BusInfo)
1128  else
1129  {
1130  RtlCopyMemory(
1131  &BusInfo->BusTypeGuid,
1132  &GUID_BUS_TYPE_INTERNAL,
1133  sizeof(BusInfo->BusTypeGuid));
1134  BusInfo->LegacyBusType = PNPBus;
1135  /* We're the only root bus enumerator on the computer */
1136  BusInfo->BusNumber = 0;
1137  Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1139  }
1140 
1141  return Status;
1142 }
1143 
1144 /*
1145  * FUNCTION: Handle Plug and Play IRPs for the child device
1146  * ARGUMENTS:
1147  * DeviceObject = Pointer to physical device object of the child device
1148  * Irp = Pointer to IRP that should be handled
1149  * RETURNS:
1150  * Status
1151  */
1152 static NTSTATUS
1155  IN PIRP Irp)
1156 {
1157  PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1158  PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1160  NTSTATUS Status;
1161 
1162  DeviceExtension = DeviceObject->DeviceExtension;
1163  FdoDeviceExtension = PnpRootDeviceObject->DeviceExtension;
1164  Status = Irp->IoStatus.Status;
1166 
1167  switch (IrpSp->MinorFunction)
1168  {
1169  case IRP_MN_START_DEVICE: /* 0x00 */
1170  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1172  break;
1173 
1174  case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1176  break;
1177 
1178  case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1179  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1181  break;
1182 
1183  case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1184  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1186  break;
1187 
1188  case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1189  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1191  break;
1192 
1193  case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1194  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1196  break;
1197 
1198  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
1199  DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1200  break;
1201 
1202  case IRP_MN_REMOVE_DEVICE:
1203  /* Remove the device from the device list and decrement the device count*/
1204  KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1205  RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1206  FdoDeviceExtension->DeviceListCount--;
1207  KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1208 
1209  /* Free some strings we created */
1211  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1212  RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1213 
1214  /* Free the resource requirements list */
1215  if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1216  ExFreePool(DeviceExtension->DeviceInfo->ResourceRequirementsList);
1217 
1218  /* Free the boot resources list */
1219  if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1220  ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1221 
1222  /* Free the device info */
1223  ExFreePool(DeviceExtension->DeviceInfo);
1224 
1225  /* Finally, delete the device object */
1227 
1228  /* Return success */
1230  break;
1231 
1232  case IRP_MN_QUERY_ID: /* 0x13 */
1234  break;
1235 
1236  case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1237  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1238  break;
1239 
1240  case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1241  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1243  break;
1244 
1245  default:
1246  DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1247  break;
1248  }
1249 
1250  if (Status != STATUS_PENDING)
1251  {
1252  Irp->IoStatus.Status = Status;
1254  }
1255 
1256  return Status;
1257 }
1258 
1259 /*
1260  * FUNCTION: Handle Plug and Play IRPs
1261  * ARGUMENTS:
1262  * DeviceObject = Pointer to PDO or FDO
1263  * Irp = Pointer to IRP that should be handled
1264  * RETURNS:
1265  * Status
1266  */
1267 static NTSTATUS NTAPI
1270  IN PIRP Irp)
1271 {
1272  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
1273  NTSTATUS Status;
1274 
1276 
1277  if (DeviceExtension->IsFDO)
1279  else
1281 
1282  return Status;
1283 }
1284 
1285 /*
1286  * FUNCTION: Handle Power IRPs
1287  * ARGUMENTS:
1288  * DeviceObject = Pointer to PDO or FDO
1289  * Irp = Pointer to IRP that should be handled
1290  * RETURNS:
1291  * Status
1292  */
1293 static NTSTATUS NTAPI
1296  IN PIRP Irp)
1297 {
1298  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1300  NTSTATUS Status;
1301 
1302  DeviceExtension = DeviceObject->DeviceExtension;
1303  Status = Irp->IoStatus.Status;
1305 
1306  if (DeviceExtension->Common.IsFDO)
1307  {
1308  ASSERT(!DeviceExtension->Common.IsFDO);
1311  Status = PoCallDriver(DeviceExtension->Ldo, Irp);
1312  }
1313  else
1314  {
1315  switch (IrpSp->MinorFunction)
1316  {
1317  case IRP_MN_QUERY_POWER:
1318  case IRP_MN_SET_POWER:
1320  break;
1321  }
1322  Irp->IoStatus.Status = Status;
1325  }
1326 
1327  return Status;
1328 }
1329 
1330 NTSTATUS
1331 NTAPI
1335 {
1336  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1337  NTSTATUS Status;
1338 
1339  DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject, PhysicalDeviceObject);
1340 
1341  if (!PhysicalDeviceObject)
1342  {
1343  DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
1345  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1346  }
1347 
1349  DriverObject,
1351  NULL,
1354  TRUE,
1356  if (!NT_SUCCESS(Status))
1357  {
1358  DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
1359  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1360  }
1361  DPRINT("Created FDO %p\n", PnpRootDeviceObject);
1362 
1364  RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
1365 
1366  DeviceExtension->Common.IsFDO = TRUE;
1367  DeviceExtension->State = dsStopped;
1368  InitializeListHead(&DeviceExtension->DeviceListHead);
1369  DeviceExtension->DeviceListCount = 0;
1370  KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
1371 
1375  &DeviceExtension->Ldo);
1376  if (!NT_SUCCESS(Status))
1377  {
1378  DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
1379  KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1380  }
1381 
1383 
1384  DPRINT("Done AddDevice()\n");
1385 
1386  return STATUS_SUCCESS;
1387 }
1388 
1389 #if MI_TRACE_PFNS
1390 PDEVICE_OBJECT IopPfnDumpDeviceObject;
1391 
1393 PnpRootCreateClose(
1395  _In_ PIRP Irp)
1396 {
1397  PIO_STACK_LOCATION IoStack;
1398 
1399  if (DeviceObject != IopPfnDumpDeviceObject)
1400  {
1401  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1404  }
1405 
1406  IoStack = IoGetCurrentIrpStackLocation(Irp);
1407  if (IoStack->MajorFunction == IRP_MJ_CREATE)
1408  {
1410  }
1411 
1412  Irp->IoStatus.Status = STATUS_SUCCESS;
1414  return STATUS_SUCCESS;
1415 }
1416 #endif
1417 
1422 {
1423 #if MI_TRACE_PFNS
1424  NTSTATUS Status;
1425  UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1426 #endif
1427 
1428  DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1429 
1431 
1433 
1434 #if MI_TRACE_PFNS
1435  DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1436  DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1437 #endif
1440 
1441 #if MI_TRACE_PFNS
1443  0,
1444  &PfnDumpDeviceName,
1446  0,
1447  FALSE,
1448  &IopPfnDumpDeviceObject);
1449  if (!NT_SUCCESS(Status))
1450  {
1451  DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1452  }
1453  else
1454  {
1455  IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1456  }
1457 #endif
1458 
1459  return STATUS_SUCCESS;
1460 }
#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:4004
#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:2055
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
#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:1060
#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:895
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:1117
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
#define InsertTailList(ListHead, Entry)
static NTSTATUS PnpRootFdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:839
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:945
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: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:2174
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:4004
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
_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:2904
NTSTATUS NTAPI PnpRootAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnproot.c:1332
_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:1419
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
#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:721
#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:928
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:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
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:3688
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
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:1268
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:2181
UNICODE_STRING InstanceID
Definition: pnproot.c:31
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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:926
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1015
#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:981
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
Definition: pnproot.c:35
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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:1294
#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:1153
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