ReactOS  0.4.15-dev-1384-g878186b
pnpmgr.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/pnpmgr.c
5  * PURPOSE: Initializes the PnP manager
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 
22 
24 
25 /* DATA **********************************************************************/
26 
29 
30 /* FUNCTIONS *****************************************************************/
31 
32 VOID
34 {
36 
37  for (i = 0; i < Length; i++)
38  {
39  if (String[i] == L'\\')
40  String[i] = L'#';
41  }
42 }
43 
44 VOID
45 NTAPI
47 {
49  HANDLE CriticalDeviceKey, InstanceKey;
51  UNICODE_STRING CriticalDeviceKeyU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\CriticalDeviceDatabase");
52  UNICODE_STRING CompatibleIdU = RTL_CONSTANT_STRING(L"CompatibleIDs");
53  UNICODE_STRING HardwareIdU = RTL_CONSTANT_STRING(L"HardwareID");
54  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
55  UNICODE_STRING ClassGuidU = RTL_CONSTANT_STRING(L"ClassGUID");
57  ULONG HidLength = 0, CidLength = 0, BufferLength;
58  PWCHAR IdBuffer, OriginalIdBuffer;
59 
60  /* Open the device instance key */
61  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
62  if (Status != STATUS_SUCCESS)
63  return;
64 
65  Status = ZwQueryValueKey(InstanceKey,
66  &HardwareIdU,
68  NULL,
69  0,
70  &HidLength);
72  {
73  ZwClose(InstanceKey);
74  return;
75  }
76 
77  Status = ZwQueryValueKey(InstanceKey,
78  &CompatibleIdU,
80  NULL,
81  0,
82  &CidLength);
84  {
85  CidLength = 0;
86  }
87 
88  BufferLength = HidLength + CidLength;
89  BufferLength -= (((CidLength != 0) ? 2 : 1) * FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data));
90 
91  /* Allocate a buffer to hold data from both */
92  OriginalIdBuffer = IdBuffer = ExAllocatePool(PagedPool, BufferLength);
93  if (!IdBuffer)
94  {
95  ZwClose(InstanceKey);
96  return;
97  }
98 
99  /* Compute the buffer size */
100  if (HidLength > CidLength)
101  BufferLength = HidLength;
102  else
103  BufferLength = CidLength;
104 
105  PartialInfo = ExAllocatePool(PagedPool, BufferLength);
106  if (!PartialInfo)
107  {
108  ZwClose(InstanceKey);
109  ExFreePool(OriginalIdBuffer);
110  return;
111  }
112 
113  Status = ZwQueryValueKey(InstanceKey,
114  &HardwareIdU,
116  PartialInfo,
117  HidLength,
118  &HidLength);
119  if (Status != STATUS_SUCCESS)
120  {
121  ExFreePool(PartialInfo);
122  ExFreePool(OriginalIdBuffer);
123  ZwClose(InstanceKey);
124  return;
125  }
126 
127  /* Copy in HID info first (without 2nd terminating NULL if CID is present) */
128  HidLength = PartialInfo->DataLength - ((CidLength != 0) ? sizeof(WCHAR) : 0);
129  RtlCopyMemory(IdBuffer, PartialInfo->Data, HidLength);
130 
131  if (CidLength != 0)
132  {
133  Status = ZwQueryValueKey(InstanceKey,
134  &CompatibleIdU,
136  PartialInfo,
137  CidLength,
138  &CidLength);
139  if (Status != STATUS_SUCCESS)
140  {
141  ExFreePool(PartialInfo);
142  ExFreePool(OriginalIdBuffer);
143  ZwClose(InstanceKey);
144  return;
145  }
146 
147  /* Copy CID next */
148  CidLength = PartialInfo->DataLength;
149  RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength);
150  }
151 
152  /* Free our temp buffer */
153  ExFreePool(PartialInfo);
154 
156  &CriticalDeviceKeyU,
158  NULL,
159  NULL);
160  Status = ZwOpenKey(&CriticalDeviceKey,
163  if (!NT_SUCCESS(Status))
164  {
165  /* The critical device database doesn't exist because
166  * we're probably in 1st stage setup, but it's ok */
167  ExFreePool(OriginalIdBuffer);
168  ZwClose(InstanceKey);
169  return;
170  }
171 
172  while (*IdBuffer)
173  {
174  USHORT StringLength = (USHORT)wcslen(IdBuffer) + 1, Index;
175 
176  IopFixupDeviceId(IdBuffer);
177 
178  /* Look through all subkeys for a match */
179  for (Index = 0; TRUE; Index++)
180  {
181  ULONG NeededLength;
182  PKEY_BASIC_INFORMATION BasicInfo;
183 
184  Status = ZwEnumerateKey(CriticalDeviceKey,
185  Index,
187  NULL,
188  0,
189  &NeededLength);
191  break;
193  {
194  UNICODE_STRING ChildIdNameU, RegKeyNameU;
195 
196  BasicInfo = ExAllocatePool(PagedPool, NeededLength);
197  if (!BasicInfo)
198  {
199  /* No memory */
200  ExFreePool(OriginalIdBuffer);
201  ZwClose(CriticalDeviceKey);
202  ZwClose(InstanceKey);
203  return;
204  }
205 
206  Status = ZwEnumerateKey(CriticalDeviceKey,
207  Index,
209  BasicInfo,
210  NeededLength,
211  &NeededLength);
212  if (Status != STATUS_SUCCESS)
213  {
214  /* This shouldn't happen */
215  ExFreePool(BasicInfo);
216  continue;
217  }
218 
219  ChildIdNameU.Buffer = IdBuffer;
220  ChildIdNameU.MaximumLength = ChildIdNameU.Length = (StringLength - 1) * sizeof(WCHAR);
221  RegKeyNameU.Buffer = BasicInfo->Name;
222  RegKeyNameU.MaximumLength = RegKeyNameU.Length = (USHORT)BasicInfo->NameLength;
223 
224  if (RtlEqualUnicodeString(&ChildIdNameU, &RegKeyNameU, TRUE))
225  {
226  HANDLE ChildKeyHandle;
227 
229  &ChildIdNameU,
231  CriticalDeviceKey,
232  NULL);
233 
234  Status = ZwOpenKey(&ChildKeyHandle,
237  if (Status != STATUS_SUCCESS)
238  {
239  ExFreePool(BasicInfo);
240  continue;
241  }
242 
243  /* Check if there's already a driver installed */
244  Status = ZwQueryValueKey(InstanceKey,
245  &ClassGuidU,
247  NULL,
248  0,
249  &NeededLength);
251  {
252  ExFreePool(BasicInfo);
253  continue;
254  }
255 
256  Status = ZwQueryValueKey(ChildKeyHandle,
257  &ClassGuidU,
259  NULL,
260  0,
261  &NeededLength);
263  {
264  ExFreePool(BasicInfo);
265  continue;
266  }
267 
268  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
269  if (!PartialInfo)
270  {
271  ExFreePool(OriginalIdBuffer);
272  ExFreePool(BasicInfo);
273  ZwClose(InstanceKey);
274  ZwClose(ChildKeyHandle);
275  ZwClose(CriticalDeviceKey);
276  return;
277  }
278 
279  /* Read ClassGUID entry in the CDDB */
280  Status = ZwQueryValueKey(ChildKeyHandle,
281  &ClassGuidU,
283  PartialInfo,
284  NeededLength,
285  &NeededLength);
286  if (Status != STATUS_SUCCESS)
287  {
288  ExFreePool(BasicInfo);
289  continue;
290  }
291 
292  /* Write it to the ENUM key */
293  Status = ZwSetValueKey(InstanceKey,
294  &ClassGuidU,
295  0,
296  REG_SZ,
297  PartialInfo->Data,
298  PartialInfo->DataLength);
299  if (Status != STATUS_SUCCESS)
300  {
301  ExFreePool(BasicInfo);
302  ExFreePool(PartialInfo);
303  ZwClose(ChildKeyHandle);
304  continue;
305  }
306 
307  Status = ZwQueryValueKey(ChildKeyHandle,
308  &ServiceU,
310  NULL,
311  0,
312  &NeededLength);
314  {
315  ExFreePool(PartialInfo);
316  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
317  if (!PartialInfo)
318  {
319  ExFreePool(OriginalIdBuffer);
320  ExFreePool(BasicInfo);
321  ZwClose(InstanceKey);
322  ZwClose(ChildKeyHandle);
323  ZwClose(CriticalDeviceKey);
324  return;
325  }
326 
327  /* Read the service entry from the CDDB */
328  Status = ZwQueryValueKey(ChildKeyHandle,
329  &ServiceU,
331  PartialInfo,
332  NeededLength,
333  &NeededLength);
334  if (Status != STATUS_SUCCESS)
335  {
336  ExFreePool(BasicInfo);
337  ExFreePool(PartialInfo);
338  ZwClose(ChildKeyHandle);
339  continue;
340  }
341 
342  /* Write it to the ENUM key */
343  Status = ZwSetValueKey(InstanceKey,
344  &ServiceU,
345  0,
346  REG_SZ,
347  PartialInfo->Data,
348  PartialInfo->DataLength);
349  if (Status != STATUS_SUCCESS)
350  {
351  ExFreePool(BasicInfo);
352  ExFreePool(PartialInfo);
353  ZwClose(ChildKeyHandle);
354  continue;
355  }
356 
357  DPRINT("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
358  }
359  else
360  {
361  DPRINT1("Installed NULL service for critical device '%wZ'\n", &ChildIdNameU);
362  }
363 
364  ExFreePool(OriginalIdBuffer);
365  ExFreePool(PartialInfo);
366  ExFreePool(BasicInfo);
367  ZwClose(InstanceKey);
368  ZwClose(ChildKeyHandle);
369  ZwClose(CriticalDeviceKey);
370 
371  /* That's it */
372  return;
373  }
374 
375  ExFreePool(BasicInfo);
376  }
377  else
378  {
379  /* Umm, not sure what happened here */
380  continue;
381  }
382  }
383 
384  /* Advance to the next ID */
385  IdBuffer += StringLength;
386  }
387 
388  ExFreePool(OriginalIdBuffer);
389  ZwClose(InstanceKey);
390  ZwClose(CriticalDeviceKey);
391 }
392 
393 NTSTATUS
394 FASTCALL
397 {
400 
401  if (!DriverObject)
402  {
403  /* Special case for bus driven devices */
404  DeviceNode->Flags |= DNF_ADDED;
405  return STATUS_SUCCESS;
406  }
407 
408  if (!DriverObject->DriverExtension->AddDevice)
409  {
410  DeviceNode->Flags |= DNF_LEGACY_DRIVER;
411  }
412 
413  if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
414  {
415  DeviceNode->Flags |= (DNF_ADDED | DNF_STARTED);
416  return STATUS_SUCCESS;
417  }
418 
419  /* This is a Plug and Play driver */
420  DPRINT("Plug and Play driver found\n");
421  ASSERT(DeviceNode->PhysicalDeviceObject);
422 
423  DPRINT("Calling %wZ->AddDevice(%wZ)\n",
424  &DriverObject->DriverName,
425  &DeviceNode->InstancePath);
426  Status = DriverObject->DriverExtension->AddDevice(DriverObject,
427  DeviceNode->PhysicalDeviceObject);
428  if (!NT_SUCCESS(Status))
429  {
430  DPRINT1("%wZ->AddDevice(%wZ) failed with status 0x%x\n",
431  &DriverObject->DriverName,
432  &DeviceNode->InstancePath,
433  Status);
435  DeviceNode->Problem = CM_PROB_FAILED_ADD;
436  return Status;
437  }
438 
439  Fdo = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
440 
441  /* Check if we have a ACPI device (needed for power management) */
442  if (Fdo->DeviceType == FILE_DEVICE_ACPI)
443  {
444  static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
445 
446  /* There can be only one system power device */
447  if (!SystemPowerDeviceNodeCreated)
448  {
451  SystemPowerDeviceNodeCreated = TRUE;
452  }
453  }
454 
456 
458 
459  return STATUS_SUCCESS;
460 }
461 
462 NTSTATUS
464 {
465  KIRQL OldIrql;
466 
468  {
472 
473  return STATUS_SUCCESS;
474  }
475 
476  return STATUS_UNSUCCESSFUL;
477 }
478 
479 USHORT
480 NTAPI
482 {
483  USHORT i = 0, FoundIndex = 0xFFFF;
484  ULONG NewSize;
485  PVOID NewList;
486 
487  /* Acquire the lock */
489 
490  /* Loop all entries */
491  while (i < PnpBusTypeGuidList->GuidCount)
492  {
493  /* Try to find a match */
494  if (RtlCompareMemory(BusTypeGuid,
496  sizeof(GUID)) == sizeof(GUID))
497  {
498  /* Found it */
499  FoundIndex = i;
500  goto Quickie;
501  }
502  i++;
503  }
504 
505  /* Check if we have to grow the list */
507  {
508  /* Calculate the new size */
509  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
510  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
511 
512  /* Allocate the new copy */
513  NewList = ExAllocatePool(PagedPool, NewSize);
514 
515  if (!NewList)
516  {
517  /* Fail */
519  goto Quickie;
520  }
521 
522  /* Now copy them, decrease the size too */
523  NewSize -= sizeof(GUID);
525 
526  /* Free the old list */
528 
529  /* Use the new buffer */
530  PnpBusTypeGuidList = NewList;
531  }
532 
533  /* Copy the new GUID */
535  BusTypeGuid,
536  sizeof(GUID));
537 
538  /* The new entry is the index */
539  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
541 
542 Quickie:
544  return FoundIndex;
545 }
546 
547 NTSTATUS
548 NTAPI
550  IN PIO_STACK_LOCATION IoStackLocation,
552 {
553  PIRP Irp;
554  PIO_STACK_LOCATION IrpStack;
556  KEVENT Event;
558  PDEVICE_OBJECT TopDeviceObject;
559  PAGED_CODE();
560 
561  /* Call the top of the device stack */
562  TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
563 
564  /* Allocate an IRP */
565  Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
566  if (!Irp)
567  {
568  ObDereferenceObject(TopDeviceObject);
570  }
571 
572  /* Initialize to failure */
573  Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
574  Irp->IoStatus.Information = IoStatusBlock.Information = 0;
575 
576  /* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
577  if ((IoStackLocation->MajorFunction == IRP_MJ_PNP) &&
578  (IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS))
579  {
580  /* Copy the resource requirements list into the IOSB */
581  Irp->IoStatus.Information =
582  IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
583  }
584 
585  /* Initialize the event */
587 
588  /* Set them up */
589  Irp->UserIosb = &IoStatusBlock;
590  Irp->UserEvent = &Event;
591 
592  /* Queue the IRP */
593  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
595 
596  /* Copy-in the stack */
597  IrpStack = IoGetNextIrpStackLocation(Irp);
598  *IrpStack = *IoStackLocation;
599 
600  /* Call the driver */
601  Status = IoCallDriver(TopDeviceObject, Irp);
602  if (Status == STATUS_PENDING)
603  {
604  /* Wait for it */
606  Executive,
607  KernelMode,
608  FALSE,
609  NULL);
611  }
612 
613  /* Remove the reference */
614  ObDereferenceObject(TopDeviceObject);
615 
616  /* Return the information */
618  return Status;
619 }
620 
621 NTSTATUS
622 NTAPI
627 {
628  IO_STACK_LOCATION IoStackLocation;
629 
630  /* Fill out the stack information */
631  RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
632  IoStackLocation.MajorFunction = IRP_MJ_PNP;
633  IoStackLocation.MinorFunction = MinorFunction;
634  if (Stack)
635  {
636  /* Copy the rest */
637  RtlCopyMemory(&IoStackLocation.Parameters,
638  &Stack->Parameters,
639  sizeof(Stack->Parameters));
640  }
641 
642  /* Do the PnP call */
644  &IoStackLocation,
646  return IoStatusBlock->Status;
647 }
648 
649 /*
650  * IopCreateDeviceKeyPath
651  *
652  * Creates a registry key
653  *
654  * Parameters
655  * RegistryPath
656  * Name of the key to be created.
657  * Handle
658  * Handle to the newly created key
659  *
660  * Remarks
661  * This method can create nested trees, so parent of RegistryPath can
662  * be not existant, and will be created if needed.
663  */
664 NTSTATUS
665 NTAPI
669 {
671  HANDLE hParent = NULL, hKey;
674  PCWSTR Current, Last;
675  USHORT Length;
677 
678  /* Assume failure */
679  *Handle = NULL;
680 
681  /* Open root key for device instances */
683  if (!NT_SUCCESS(Status))
684  {
685  DPRINT1("ZwOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
686  return Status;
687  }
688 
689  Current = KeyName.Buffer = RegistryPath->Buffer;
690  Last = &RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)];
691 
692  /* Go up to the end of the string */
693  while (Current <= Last)
694  {
695  if (Current != Last && *Current != L'\\')
696  {
697  /* Not the end of the string and not a separator */
698  Current++;
699  continue;
700  }
701 
702  /* Prepare relative key name */
703  Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
704  KeyName.MaximumLength = KeyName.Length = Length;
705  DPRINT("Create '%wZ'\n", &KeyName);
706 
707  /* Open key */
709  &KeyName,
711  hParent,
712  NULL);
713  Status = ZwCreateKey(&hKey,
714  Current == Last ? KEY_ALL_ACCESS : KEY_CREATE_SUB_KEY,
716  0,
717  NULL,
719  NULL);
720 
721  /* Close parent key handle, we don't need it anymore */
722  if (hParent)
723  ZwClose(hParent);
724 
725  /* Key opening/creating failed? */
726  if (!NT_SUCCESS(Status))
727  {
728  DPRINT1("ZwCreateKey('%wZ') failed with status 0x%08lx\n", &KeyName, Status);
729  return Status;
730  }
731 
732  /* Check if it is the end of the string */
733  if (Current == Last)
734  {
735  /* Yes, return success */
736  *Handle = hKey;
737  return STATUS_SUCCESS;
738  }
739 
740  /* Start with this new parent key */
741  hParent = hKey;
742  Current++;
743  KeyName.Buffer = (PWSTR)Current;
744  }
745 
746  return STATUS_UNSUCCESSFUL;
747 }
748 
749 NTSTATUS
752 {
755  HANDLE LogConfKey, ControlKey, DeviceParamsKey;
756  ULONG ResCount;
759 
760  DPRINT("IopSetDeviceInstanceData() called\n");
761 
762  /* Create the 'LogConf' key */
763  RtlInitUnicodeString(&KeyName, L"LogConf");
765  &KeyName,
767  InstanceKey,
768  NULL);
769  Status = ZwCreateKey(&LogConfKey,
772  0,
773  NULL,
774  // FIXME? In r53694 it was silently turned from non-volatile into this,
775  // without any extra warning. Is this still needed??
777  NULL);
778  if (NT_SUCCESS(Status))
779  {
780  /* Set 'BootConfig' value */
781  if (DeviceNode->BootResources != NULL)
782  {
783  ResCount = DeviceNode->BootResources->Count;
784  if (ResCount != 0)
785  {
786  RtlInitUnicodeString(&KeyName, L"BootConfig");
787  Status = ZwSetValueKey(LogConfKey,
788  &KeyName,
789  0,
791  DeviceNode->BootResources,
792  PnpDetermineResourceListSize(DeviceNode->BootResources));
793  }
794  }
795 
796  /* Set 'BasicConfigVector' value */
797  if (DeviceNode->ResourceRequirements != NULL &&
798  DeviceNode->ResourceRequirements->ListSize != 0)
799  {
800  RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
801  Status = ZwSetValueKey(LogConfKey,
802  &KeyName,
803  0,
805  DeviceNode->ResourceRequirements,
806  DeviceNode->ResourceRequirements->ListSize);
807  }
808 
809  ZwClose(LogConfKey);
810  }
811 
812  /* Set the 'ConfigFlags' value */
813  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
814  Status = ZwQueryValueKey(InstanceKey,
815  &KeyName,
817  NULL,
818  0,
819  &ResultLength);
821  {
822  /* Write the default value */
823  ULONG DefaultConfigFlags = 0;
824  Status = ZwSetValueKey(InstanceKey,
825  &KeyName,
826  0,
827  REG_DWORD,
828  &DefaultConfigFlags,
829  sizeof(DefaultConfigFlags));
830  }
831 
832  /* Create the 'Control' key */
833  RtlInitUnicodeString(&KeyName, L"Control");
835  &KeyName,
837  InstanceKey,
838  NULL);
839  Status = ZwCreateKey(&ControlKey,
840  0,
842  0,
843  NULL,
845  NULL);
846  if (NT_SUCCESS(Status))
847  ZwClose(ControlKey);
848 
849  /* Create the 'Device Parameters' key and set the 'FirmwareIdentified' value for all ACPI-enumerated devices */
850  if (_wcsnicmp(DeviceNode->InstancePath.Buffer, L"ACPI\\", 5) == 0)
851  {
852  RtlInitUnicodeString(&KeyName, L"Device Parameters");
854  &KeyName,
856  InstanceKey,
857  NULL);
858  Status = ZwCreateKey(&DeviceParamsKey,
859  0,
861  0,
862  NULL,
864  NULL);
865  if (NT_SUCCESS(Status))
866  {
867  ULONG FirmwareIdentified = 1;
868  RtlInitUnicodeString(&KeyName, L"FirmwareIdentified");
869  Status = ZwSetValueKey(DeviceParamsKey,
870  &KeyName,
871  0,
872  REG_DWORD,
873  &FirmwareIdentified,
874  sizeof(FirmwareIdentified));
875 
876  ZwClose(DeviceParamsKey);
877  }
878  }
879 
880  DPRINT("IopSetDeviceInstanceData() done\n");
881 
882  return Status;
883 }
884 
885 /*
886  * IopGetParentIdPrefix
887  *
888  * Retrieve (or create) a string which identifies a device.
889  *
890  * Parameters
891  * DeviceNode
892  * Pointer to device node.
893  * ParentIdPrefix
894  * Pointer to the string where is returned the parent node identifier
895  *
896  * Remarks
897  * If the return code is STATUS_SUCCESS, the ParentIdPrefix string is
898  * valid and its Buffer field is NULL-terminated. The caller needs to
899  * to free the string with RtlFreeUnicodeString when it is no longer
900  * needed.
901  */
902 
903 NTSTATUS
905  PUNICODE_STRING ParentIdPrefix)
906 {
907  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
908  ULONG KeyNameBufferLength;
909  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
910  UNICODE_STRING KeyName = {0, 0, NULL};
911  UNICODE_STRING KeyValue;
913  HANDLE hKey = NULL;
914  ULONG crc32;
916 
917  /* HACK: As long as some devices have a NULL device
918  * instance path, the following test is required :(
919  */
920  if (DeviceNode->Parent->InstancePath.Length == 0)
921  {
922  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
923  &DeviceNode->InstancePath);
924  return STATUS_UNSUCCESSFUL;
925  }
926 
927  /* 1. Try to retrieve ParentIdPrefix from registry */
928  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
929  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
930  KeyNameBufferLength + sizeof(UNICODE_NULL),
931  TAG_IO);
932  if (!ParentIdPrefixInformation)
933  {
935  }
936 
937  KeyName.Length = 0;
938  KeyName.MaximumLength = EnumKeyPath.Length +
939  DeviceNode->Parent->InstancePath.Length +
940  sizeof(UNICODE_NULL);
942  KeyName.MaximumLength,
943  TAG_IO);
944  if (!KeyName.Buffer)
945  {
947  goto cleanup;
948  }
949 
950  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
951  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
952 
954  if (!NT_SUCCESS(Status))
955  {
956  goto cleanup;
957  }
958  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
959  Status = ZwQueryValueKey(hKey,
960  &ValueName,
962  ParentIdPrefixInformation,
963  KeyNameBufferLength,
964  &KeyNameBufferLength);
965  if (NT_SUCCESS(Status))
966  {
967  if (ParentIdPrefixInformation->Type != REG_SZ)
968  {
970  }
971  else
972  {
973  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
974  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
975  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
976  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
977  }
978  goto cleanup;
979  }
981  {
982  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
983  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
984  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
985  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
986  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
987  goto cleanup;
988  }
989 
990  /* 2. Create the ParentIdPrefix value */
992  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
993  DeviceNode->Parent->InstancePath.Length);
994 
995  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
996  KeyNameBufferLength,
997  L"%lx&%lx",
998  DeviceNode->Parent->Level,
999  crc32);
1000  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
1001 
1002  /* 3. Try to write the ParentIdPrefix to registry */
1003  Status = ZwSetValueKey(hKey,
1004  &ValueName,
1005  0,
1006  REG_SZ,
1007  KeyValue.Buffer,
1008  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
1009 
1010 cleanup:
1011  if (NT_SUCCESS(Status))
1012  {
1013  /* Duplicate the string to return it */
1015  &KeyValue,
1016  ParentIdPrefix);
1017  }
1018  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
1020  if (hKey != NULL)
1021  {
1022  ZwClose(hKey);
1023  }
1024  return Status;
1025 }
1026 
1027 static
1028 CODE_SEG("INIT")
1029 NTSTATUS
1031  IN HANDLE hBaseKey,
1032  IN PUNICODE_STRING RelativePath OPTIONAL,
1033  IN HANDLE hRootKey,
1034  IN BOOLEAN EnumerateSubKeys,
1035  IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources,
1036  IN ULONG ParentBootResourcesLength)
1037 {
1038  UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
1039  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
1040  UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
1041  UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
1042  UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
1044  HANDLE hDevicesKey = NULL;
1045  HANDLE hDeviceKey = NULL;
1046  HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
1047  UNICODE_STRING Level2NameU;
1048  WCHAR Level2Name[5];
1049  ULONG IndexDevice = 0;
1050  ULONG IndexSubKey;
1051  PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
1052  ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
1053  PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
1054  ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
1057  PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
1058  ULONG BootResourcesLength;
1059  NTSTATUS Status;
1060 
1061  const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
1062  UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
1063  static ULONG DeviceIndexSerial = 0;
1064  const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
1065  UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
1066  static ULONG DeviceIndexKeyboard = 0;
1067  const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
1068  /* FIXME: IopEnumerateDetectedDevices() should be rewritten.
1069  * The PnP identifiers can either be hardcoded or parsed from a LegacyXlate
1070  * sections of driver INF files.
1071  */
1072 #if defined(SARCH_PC98)
1073  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*nEC1F00\0");
1074 #else
1075  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
1076 #endif
1077  static ULONG DeviceIndexMouse = 0;
1078  const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"ParallelController");
1079  UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
1080  static ULONG DeviceIndexParallel = 0;
1081  const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
1082  UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
1083  static ULONG DeviceIndexFloppy = 0;
1084  UNICODE_STRING HardwareIdKey;
1085  PUNICODE_STRING pHardwareId;
1086  ULONG DeviceIndex = 0;
1087  PUCHAR CmResourceList;
1088  ULONG ListCount;
1089 
1090  if (RelativePath)
1091  {
1092  Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS);
1093  if (!NT_SUCCESS(Status))
1094  {
1095  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1096  goto cleanup;
1097  }
1098  }
1099  else
1100  hDevicesKey = hBaseKey;
1101 
1102  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1103  if (!pDeviceInformation)
1104  {
1105  DPRINT("ExAllocatePool() failed\n");
1107  goto cleanup;
1108  }
1109 
1110  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1111  if (!pValueInformation)
1112  {
1113  DPRINT("ExAllocatePool() failed\n");
1115  goto cleanup;
1116  }
1117 
1118  while (TRUE)
1119  {
1120  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1122  break;
1124  {
1125  ExFreePool(pDeviceInformation);
1126  DeviceInfoLength = RequiredSize;
1127  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1128  if (!pDeviceInformation)
1129  {
1130  DPRINT("ExAllocatePool() failed\n");
1132  goto cleanup;
1133  }
1134  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1135  }
1136  if (!NT_SUCCESS(Status))
1137  {
1138  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
1139  goto cleanup;
1140  }
1141  IndexDevice++;
1142 
1143  /* Open device key */
1144  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1145  DeviceName.Buffer = pDeviceInformation->Name;
1146 
1147  Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
1148  KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
1149  if (!NT_SUCCESS(Status))
1150  {
1151  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1152  goto cleanup;
1153  }
1154 
1155  /* Read boot resources, and add then to parent ones */
1156  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1158  {
1159  ExFreePool(pValueInformation);
1160  ValueInfoLength = RequiredSize;
1161  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1162  if (!pValueInformation)
1163  {
1164  DPRINT("ExAllocatePool() failed\n");
1165  ZwDeleteKey(hLevel2Key);
1167  goto cleanup;
1168  }
1169  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1170  }
1172  {
1173  BootResources = ParentBootResources;
1174  BootResourcesLength = ParentBootResourcesLength;
1175  }
1176  else if (!NT_SUCCESS(Status))
1177  {
1178  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1179  goto nextdevice;
1180  }
1181  else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
1182  {
1183  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
1184  goto nextdevice;
1185  }
1186  else
1187  {
1188  static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
1189 
1190  /* Concatenate current resources and parent ones */
1191  if (ParentBootResourcesLength == 0)
1192  BootResourcesLength = pValueInformation->DataLength;
1193  else
1194  BootResourcesLength = ParentBootResourcesLength
1195  + pValueInformation->DataLength
1196  - Header;
1197  BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
1198  if (!BootResources)
1199  {
1200  DPRINT("ExAllocatePool() failed\n");
1201  goto nextdevice;
1202  }
1203  if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1204  {
1205  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1206  }
1207  else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
1208  {
1209  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1210  RtlCopyMemory(
1211  (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
1212  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1213  ParentBootResourcesLength - Header);
1214  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1215  }
1216  else
1217  {
1218  RtlCopyMemory(BootResources, pValueInformation->Data, Header);
1219  RtlCopyMemory(
1220  (PVOID)((ULONG_PTR)BootResources + Header),
1221  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1222  ParentBootResourcesLength - Header);
1223  RtlCopyMemory(
1224  (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
1225  pValueInformation->Data + Header,
1226  pValueInformation->DataLength - Header);
1227  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1228  }
1229  }
1230 
1231  if (EnumerateSubKeys)
1232  {
1233  IndexSubKey = 0;
1234  while (TRUE)
1235  {
1236  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1238  break;
1240  {
1241  ExFreePool(pDeviceInformation);
1242  DeviceInfoLength = RequiredSize;
1243  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1244  if (!pDeviceInformation)
1245  {
1246  DPRINT("ExAllocatePool() failed\n");
1248  goto cleanup;
1249  }
1250  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1251  }
1252  if (!NT_SUCCESS(Status))
1253  {
1254  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
1255  goto cleanup;
1256  }
1257  IndexSubKey++;
1258  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1259  DeviceName.Buffer = pDeviceInformation->Name;
1260 
1262  hDeviceKey,
1263  &DeviceName,
1264  hRootKey,
1265  TRUE,
1266  BootResources,
1267  BootResourcesLength);
1268  if (!NT_SUCCESS(Status))
1269  goto cleanup;
1270  }
1271  }
1272 
1273  /* Read identifier */
1274  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1276  {
1277  ExFreePool(pValueInformation);
1278  ValueInfoLength = RequiredSize;
1279  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1280  if (!pValueInformation)
1281  {
1282  DPRINT("ExAllocatePool() failed\n");
1284  goto cleanup;
1285  }
1286  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1287  }
1288  if (!NT_SUCCESS(Status))
1289  {
1291  {
1292  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1293  goto nextdevice;
1294  }
1295  ValueName.Length = ValueName.MaximumLength = 0;
1296  }
1297  else if (pValueInformation->Type != REG_SZ)
1298  {
1299  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
1300  goto nextdevice;
1301  }
1302  else
1303  {
1304  /* Assign hardware id to this device */
1305  ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
1306  ValueName.Buffer = (PWCHAR)pValueInformation->Data;
1307  if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
1308  ValueName.Length -= sizeof(WCHAR);
1309  }
1310 
1311  if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
1312  {
1313  pHardwareId = &HardwareIdSerial;
1314  DeviceIndex = DeviceIndexSerial++;
1315  }
1316  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
1317  {
1318  pHardwareId = &HardwareIdKeyboard;
1319  DeviceIndex = DeviceIndexKeyboard++;
1320  }
1321  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
1322  {
1323  pHardwareId = &HardwareIdMouse;
1324  DeviceIndex = DeviceIndexMouse++;
1325  }
1326  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
1327  {
1328  pHardwareId = &HardwareIdParallel;
1329  DeviceIndex = DeviceIndexParallel++;
1330  }
1331  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
1332  {
1333  pHardwareId = &HardwareIdFloppy;
1334  DeviceIndex = DeviceIndexFloppy++;
1335  }
1336  else
1337  {
1338  /* Unknown key path */
1339  DPRINT("Unknown key path '%wZ'\n", RelativePath);
1340  goto nextdevice;
1341  }
1342 
1343  /* Prepare hardware id key (hardware id value without final \0) */
1344  HardwareIdKey = *pHardwareId;
1345  HardwareIdKey.Length -= sizeof(UNICODE_NULL);
1346 
1347  /* Add the detected device to Root key */
1348  InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL);
1349  Status = ZwCreateKey(
1350  &hLevel1Key,
1353  0,
1354  NULL,
1356  NULL);
1357  if (!NT_SUCCESS(Status))
1358  {
1359  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1360  goto nextdevice;
1361  }
1362  swprintf(Level2Name, L"%04lu", DeviceIndex);
1363  RtlInitUnicodeString(&Level2NameU, Level2Name);
1364  InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL);
1365  Status = ZwCreateKey(
1366  &hLevel2Key,
1369  0,
1370  NULL,
1372  NULL);
1373  ZwClose(hLevel1Key);
1374  if (!NT_SUCCESS(Status))
1375  {
1376  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1377  goto nextdevice;
1378  }
1379  DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
1380  Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
1381  if (!NT_SUCCESS(Status))
1382  {
1383  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1384  ZwDeleteKey(hLevel2Key);
1385  goto nextdevice;
1386  }
1387  /* Create 'LogConf' subkey */
1389  Status = ZwCreateKey(
1390  &hLogConf,
1391  KEY_SET_VALUE,
1393  0,
1394  NULL,
1396  NULL);
1397  if (!NT_SUCCESS(Status))
1398  {
1399  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1400  ZwDeleteKey(hLevel2Key);
1401  goto nextdevice;
1402  }
1403  if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1404  {
1405  CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
1406  if (!CmResourceList)
1407  {
1408  ZwClose(hLogConf);
1409  ZwDeleteKey(hLevel2Key);
1410  goto nextdevice;
1411  }
1412 
1413  /* Add the list count (1st member of CM_RESOURCE_LIST) */
1414  ListCount = 1;
1415  RtlCopyMemory(CmResourceList,
1416  &ListCount,
1417  sizeof(ULONG));
1418 
1419  /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
1420  RtlCopyMemory(CmResourceList + sizeof(ULONG),
1421  BootResources,
1422  BootResourcesLength);
1423 
1424  /* Save boot resources to 'LogConf\BootConfig' */
1425  Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
1426  if (!NT_SUCCESS(Status))
1427  {
1428  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1429  ZwClose(hLogConf);
1430  ZwDeleteKey(hLevel2Key);
1431  goto nextdevice;
1432  }
1433  }
1434  ZwClose(hLogConf);
1435 
1436 nextdevice:
1437  if (BootResources && BootResources != ParentBootResources)
1438  {
1439  ExFreePool(BootResources);
1440  BootResources = NULL;
1441  }
1442  if (hLevel2Key)
1443  {
1444  ZwClose(hLevel2Key);
1445  hLevel2Key = NULL;
1446  }
1447  if (hDeviceKey)
1448  {
1449  ZwClose(hDeviceKey);
1450  hDeviceKey = NULL;
1451  }
1452  }
1453 
1455 
1456 cleanup:
1457  if (hDevicesKey && hDevicesKey != hBaseKey)
1458  ZwClose(hDevicesKey);
1459  if (hDeviceKey)
1460  ZwClose(hDeviceKey);
1461  if (pDeviceInformation)
1462  ExFreePool(pDeviceInformation);
1463  if (pValueInformation)
1464  ExFreePool(pValueInformation);
1465  return Status;
1466 }
1467 
1468 static
1469 CODE_SEG("INIT")
1470 BOOLEAN
1472 {
1473  UNICODE_STRING KeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CURRENTCONTROLSET\\Control\\Pnp");
1474  UNICODE_STRING KeyNameU = RTL_CONSTANT_STRING(L"DisableFirmwareMapper");
1476  HANDLE hPnpKey;
1477  PKEY_VALUE_PARTIAL_INFORMATION KeyInformation;
1478  ULONG DesiredLength, Length;
1479  ULONG KeyValue = 0;
1480  NTSTATUS Status;
1481 
1483  Status = ZwOpenKey(&hPnpKey, KEY_QUERY_VALUE, &ObjectAttributes);
1484  if (NT_SUCCESS(Status))
1485  {
1486  Status = ZwQueryValueKey(hPnpKey,
1487  &KeyNameU,
1489  NULL,
1490  0,
1491  &DesiredLength);
1492  if ((Status == STATUS_BUFFER_TOO_SMALL) ||
1494  {
1495  Length = DesiredLength;
1496  KeyInformation = ExAllocatePool(PagedPool, Length);
1497  if (KeyInformation)
1498  {
1499  Status = ZwQueryValueKey(hPnpKey,
1500  &KeyNameU,
1502  KeyInformation,
1503  Length,
1504  &DesiredLength);
1505  if (NT_SUCCESS(Status) && KeyInformation->DataLength == sizeof(ULONG))
1506  {
1507  KeyValue = (ULONG)(*KeyInformation->Data);
1508  }
1509  else
1510  {
1511  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU);
1512  }
1513 
1514  ExFreePool(KeyInformation);
1515  }
1516  else
1517  {
1518  DPRINT1("Failed to allocate memory for registry query\n");
1519  }
1520  }
1521  else
1522  {
1523  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status);
1524  }
1525 
1526  ZwClose(hPnpKey);
1527  }
1528  else
1529  {
1530  DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status);
1531  }
1532 
1533  DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled");
1534 
1535  return (KeyValue != 0) ? TRUE : FALSE;
1536 }
1537 
1538 CODE_SEG("INIT")
1539 NTSTATUS
1540 NTAPI
1542 {
1543  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
1544  UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"Root");
1545  UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
1547  HANDLE hEnum, hRoot;
1548  NTSTATUS Status;
1549 
1552  if (!NT_SUCCESS(Status))
1553  {
1554  DPRINT1("ZwCreateKey() failed with status 0x%08lx\n", Status);
1555  return Status;
1556  }
1557 
1560  ZwClose(hEnum);
1561  if (!NT_SUCCESS(Status))
1562  {
1563  DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
1564  return Status;
1565  }
1566 
1568  {
1569  Status = IopOpenRegistryKeyEx(&hEnum, NULL, &MultiKeyPathU, KEY_ENUMERATE_SUB_KEYS);
1570  if (!NT_SUCCESS(Status))
1571  {
1572  /* Nothing to do, don't return with an error status */
1573  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1574  ZwClose(hRoot);
1575  return STATUS_SUCCESS;
1576  }
1578  hEnum,
1579  NULL,
1580  hRoot,
1581  TRUE,
1582  NULL,
1583  0);
1584  ZwClose(hEnum);
1585  }
1586  else
1587  {
1588  /* Enumeration is disabled */
1590  }
1591 
1592  ZwClose(hRoot);
1593 
1594  return Status;
1595 }
1596 
1597 NTSTATUS
1598 NTAPI
1600  HANDLE ParentKey,
1603 {
1605  NTSTATUS Status;
1606 
1607  PAGED_CODE();
1608 
1609  *KeyHandle = NULL;
1610 
1612  Name,
1614  ParentKey,
1615  NULL);
1616 
1618 
1619  return Status;
1620 }
1621 
1622 NTSTATUS
1623 NTAPI
1625  IN HANDLE RootHandle OPTIONAL,
1630 {
1632  ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
1633  USHORT Length;
1634  HANDLE HandleArray[2];
1635  BOOLEAN Recursing = TRUE;
1636  PWCHAR pp, p, p1;
1637  UNICODE_STRING KeyString;
1639  PAGED_CODE();
1640 
1641  /* P1 is start, pp is end */
1642  p1 = KeyName->Buffer;
1643  pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
1644 
1645  /* Create the target key */
1647  KeyName,
1649  RootHandle,
1650  NULL);
1651  Status = ZwCreateKey(&HandleArray[i],
1652  DesiredAccess,
1654  0,
1655  NULL,
1656  CreateOptions,
1657  &KeyDisposition);
1658 
1659  /* Now we check if this failed */
1660  if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
1661  {
1662  /* Target key failed, so we'll need to create its parent. Setup array */
1663  HandleArray[0] = NULL;
1664  HandleArray[1] = RootHandle;
1665 
1666  /* Keep recursing for each missing parent */
1667  while (Recursing)
1668  {
1669  /* And if we're deep enough, close the last handle */
1670  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1671 
1672  /* We're setup to ping-pong between the two handle array entries */
1673  RootHandleIndex = i;
1674  i = (i + 1) & 1;
1675 
1676  /* Clear the one we're attempting to open now */
1677  HandleArray[i] = NULL;
1678 
1679  /* Process the parent key name */
1680  for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
1681  Length = (USHORT)(p - p1) * sizeof(WCHAR);
1682 
1683  /* Is there a parent name? */
1684  if (Length)
1685  {
1686  /* Build the unicode string for it */
1687  KeyString.Buffer = p1;
1688  KeyString.Length = KeyString.MaximumLength = Length;
1689 
1690  /* Now try opening the parent */
1692  &KeyString,
1694  HandleArray[RootHandleIndex],
1695  NULL);
1696  Status = ZwCreateKey(&HandleArray[i],
1697  DesiredAccess,
1699  0,
1700  NULL,
1701  CreateOptions,
1702  &KeyDisposition);
1703  if (NT_SUCCESS(Status))
1704  {
1705  /* It worked, we have one more handle */
1706  NestedCloseLevel++;
1707  }
1708  else
1709  {
1710  /* Parent key creation failed, abandon loop */
1711  Recursing = FALSE;
1712  continue;
1713  }
1714  }
1715  else
1716  {
1717  /* We don't have a parent name, probably corrupted key name */
1719  Recursing = FALSE;
1720  continue;
1721  }
1722 
1723  /* Now see if there's more parents to create */
1724  p1 = p + 1;
1725  if ((p == pp) || (p1 == pp))
1726  {
1727  /* We're done, hopefully successfully, so stop */
1728  Recursing = FALSE;
1729  }
1730  }
1731 
1732  /* Outer loop check for handle nesting that requires closing the top handle */
1733  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1734  }
1735 
1736  /* Check if we broke out of the loop due to success */
1737  if (NT_SUCCESS(Status))
1738  {
1739  /* Return the target handle (we closed all the parent ones) and disposition */
1740  *Handle = HandleArray[i];
1741  if (Disposition) *Disposition = KeyDisposition;
1742  }
1743 
1744  /* Return the success state */
1745  return Status;
1746 }
1747 
1748 NTSTATUS
1749 NTAPI
1751  IN PWSTR ValueName,
1753 {
1754  UNICODE_STRING ValueString;
1755  NTSTATUS Status;
1756  PKEY_VALUE_FULL_INFORMATION FullInformation;
1757  ULONG Size;
1758  PAGED_CODE();
1759 
1760  RtlInitUnicodeString(&ValueString, ValueName);
1761 
1762  Status = ZwQueryValueKey(Handle,
1763  &ValueString,
1765  NULL,
1766  0,
1767  &Size);
1768  if ((Status != STATUS_BUFFER_OVERFLOW) &&
1770  {
1771  return Status;
1772  }
1773 
1774  FullInformation = ExAllocatePool(NonPagedPool, Size);
1775  if (!FullInformation) return STATUS_INSUFFICIENT_RESOURCES;
1776 
1777  Status = ZwQueryValueKey(Handle,
1778  &ValueString,
1780  FullInformation,
1781  Size,
1782  &Size);
1783  if (!NT_SUCCESS(Status))
1784  {
1785  ExFreePool(FullInformation);
1786  return Status;
1787  }
1788 
1789  *Information = FullInformation;
1790  return STATUS_SUCCESS;
1791 }
1792 
1794 NTAPI
1798 {
1799  /* FIXME: TODO */
1800  ASSERT(FALSE);
1801  return 0;
1802 }
1803 
1804 //
1805 // The allocation function is called by the generic table package whenever
1806 // it needs to allocate memory for the table.
1807 //
1808 
1809 PVOID
1810 NTAPI
1812  IN CLONG ByteSize)
1813 {
1814  /* FIXME: TODO */
1815  ASSERT(FALSE);
1816  return NULL;
1817 }
1818 
1819 VOID
1820 NTAPI
1822  IN PVOID Buffer)
1823 {
1824  /* FIXME: TODO */
1825  ASSERT(FALSE);
1826 }
1827 
1828 VOID
1829 NTAPI
1831 {
1832  /* Setup the guarded mutex and AVL table */
1839  NULL);
1840 }
1841 
1842 BOOLEAN
1843 NTAPI
1845 {
1846  /* Initialize the resource when accessing device registry data */
1848 
1849  /* Setup the device reference AVL table */
1851  return TRUE;
1852 }
1853 
1854 BOOLEAN
1855 NTAPI
1857 {
1858  /* Check the initialization phase */
1859  switch (ExpInitializationPhase)
1860  {
1861  case 0:
1862 
1863  /* Do Phase 0 */
1864  return PiInitPhase0();
1865 
1866  case 1:
1867 
1868  /* Do Phase 1 */
1869  return TRUE;
1870  //return PiInitPhase1();
1871 
1872  default:
1873 
1874  /* Don't know any other phase! Bugcheck! */
1875  KeBugCheck(UNEXPECTED_INITIALIZATION_CALL);
1876  return FALSE;
1877  }
1878 }
1879 
1880 /* PUBLIC FUNCTIONS **********************************************************/
1881 
1882 NTSTATUS
1883 NTAPI
1885  IN LPGUID BusTypeGuid)
1886 {
1888 
1889  /* Acquire the lock */
1891 
1892  /* Validate size */
1893  if (Index < PnpBusTypeGuidList->GuidCount)
1894  {
1895  /* Copy the data */
1896  RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID));
1897  }
1898  else
1899  {
1900  /* Failure path */
1902  }
1903 
1904  /* Release lock and return status */
1906  return Status;
1907 }
1908 
1909 NTSTATUS
1910 NTAPI
1912  IN PHANDLE DeviceInstanceHandle,
1914 {
1915  NTSTATUS Status;
1916  HANDLE KeyHandle;
1918  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
1919  PAGED_CODE();
1920 
1921  /* Open the enum key */
1923  NULL,
1924  &KeyName,
1925  KEY_READ);
1926  if (!NT_SUCCESS(Status)) return Status;
1927 
1928  /* Make sure we have an instance path */
1930  if ((DeviceNode) && (DeviceNode->InstancePath.Length))
1931  {
1932  /* Get the instance key */
1933  Status = IopOpenRegistryKeyEx(DeviceInstanceHandle,
1934  KeyHandle,
1935  &DeviceNode->InstancePath,
1936  DesiredAccess);
1937  }
1938  else
1939  {
1940  /* Fail */
1942  }
1943 
1944  /* Close the handle and return status */
1945  ZwClose(KeyHandle);
1946  return Status;
1947 }
1948 
1949 ULONG
1950 NTAPI
1952 {
1953  ULONG FinalSize, PartialSize, EntrySize, i, j;
1954  PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
1955  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1956 
1957  /* If we don't have one, that's easy */
1958  if (!ResourceList) return 0;
1959 
1960  /* Start with the minimum size possible */
1961  FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
1962 
1963  /* Loop each full descriptor */
1964  FullDescriptor = ResourceList->List;
1965  for (i = 0; i < ResourceList->Count; i++)
1966  {
1967  /* Start with the minimum size possible */
1968  PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
1969  FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
1970 
1971  /* Loop each partial descriptor */
1972  PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
1973  for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
1974  {
1975  /* Start with the minimum size possible */
1977 
1978  /* Check if there is extra data */
1979  if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
1980  {
1981  /* Add that data */
1982  EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize;
1983  }
1984 
1985  /* The size of partial descriptors is bigger */
1986  PartialSize += EntrySize;
1987 
1988  /* Go to the next partial descriptor */
1989  PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize);
1990  }
1991 
1992  /* The size of full descriptors is bigger */
1993  FinalSize += PartialSize;
1994 
1995  /* Go to the next full descriptor */
1996  FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize);
1997  }
1998 
1999  /* Return the final size */
2000  return FinalSize;
2001 }
2002 
2003 NTSTATUS
2004 NTAPI
2006  IN ULONG ValueType,
2007  IN PWSTR ValueName,
2008  IN PWSTR KeyName,
2009  OUT PVOID Buffer,
2011 {
2012  NTSTATUS Status;
2013  HANDLE KeyHandle, SubHandle;
2014  UNICODE_STRING KeyString;
2015  PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
2016  ULONG Length;
2017  PAGED_CODE();
2018 
2019  /* Find the instance key */
2021  if (NT_SUCCESS(Status))
2022  {
2023  /* Check for name given by caller */
2024  if (KeyName)
2025  {
2026  /* Open this key */
2027  RtlInitUnicodeString(&KeyString, KeyName);
2028  Status = IopOpenRegistryKeyEx(&SubHandle,
2029  KeyHandle,
2030  &KeyString,
2031  KEY_READ);
2032  if (NT_SUCCESS(Status))
2033  {
2034  /* And use this handle instead */
2035  ZwClose(KeyHandle);
2036  KeyHandle = SubHandle;
2037  }
2038  }
2039 
2040  /* Check if sub-key handle succeeded (or no-op if no key name given) */
2041  if (NT_SUCCESS(Status))
2042  {
2043  /* Now get the size of the property */
2045  ValueName,
2046  &KeyValueInfo);
2047  }
2048 
2049  /* Close the key */
2050  ZwClose(KeyHandle);
2051  }
2052 
2053  /* Fail if any of the registry operations failed */
2054  if (!NT_SUCCESS(Status)) return Status;
2055 
2056  /* Check how much data we have to copy */
2057  Length = KeyValueInfo->DataLength;
2058  if (*BufferLength >= Length)
2059  {
2060  /* Check for a match in the value type */
2061  if (KeyValueInfo->Type == ValueType)
2062  {
2063  /* Copy the data */
2065  (PVOID)((ULONG_PTR)KeyValueInfo +
2066  KeyValueInfo->DataOffset),
2067  Length);
2068  }
2069  else
2070  {
2071  /* Invalid registry property type, fail */
2073  }
2074  }
2075  else
2076  {
2077  /* Buffer is too small to hold data */
2079  }
2080 
2081  /* Return the required buffer length, free the buffer, and return status */
2082  *BufferLength = Length;
2083  ExFreePool(KeyValueInfo);
2084  return Status;
2085 }
2086 
2087 #define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;}
2088 #define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;}
2089 #define PIP_UNIMPLEMENTED() {UNIMPLEMENTED_DBGBREAK(); break;}
2090 
2091 /*
2092  * @implemented
2093  */
2094 NTSTATUS
2095 NTAPI
2101 {
2103  DEVICE_CAPABILITIES DeviceCaps;
2104  ULONG ReturnLength = 0, Length = 0, ValueType;
2105  PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
2106  PVOID Data = NULL;
2108  GUID BusTypeGuid;
2109  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
2110  BOOLEAN NullTerminate = FALSE;
2112 
2113  DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
2114 
2115  /* Assume failure */
2116  *ResultLength = 0;
2117 
2118  /* Only PDOs can call this */
2120 
2121  /* Handle all properties */
2122  switch (DeviceProperty)
2123  {
2125 
2126  /* Get the GUID from the internal cache */
2127  Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
2128  if (!NT_SUCCESS(Status)) return Status;
2129 
2130  /* This is the format of the returned data */
2131  PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
2132 
2134 
2135  /* Validate correct interface type */
2136  if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
2138 
2139  /* This is the format of the returned data */
2140  PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
2141 
2143 
2144  /* Validate correct bus number */
2145  if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
2147 
2148  /* This is the format of the returned data */
2149  PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
2150 
2152 
2153  /* Get the instance path */
2154  DeviceInstanceName = DeviceNode->InstancePath.Buffer;
2155 
2156  /* Sanity checks */
2157  ASSERT((BufferLength & 1) == 0);
2158  ASSERT(DeviceInstanceName != NULL);
2159 
2160  /* Get the name from the path */
2161  EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
2162  ASSERT(EnumeratorNameEnd);
2163 
2164  /* This string needs to be NULL-terminated */
2165  NullTerminate = TRUE;
2166 
2167  /* This is the format of the returned data */
2168  PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
2169  DeviceInstanceName);
2170 
2171  case DevicePropertyAddress:
2172 
2173  /* Query the device caps */
2175  if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
2177 
2178  /* This is the format of the returned data */
2179  PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
2180 
2182 
2183  /* Validate we have resources */
2184  if (!DeviceNode->BootResources)
2185 // if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
2186  {
2187  /* No resources will still fake success, but with 0 bytes */
2188  *ResultLength = 0;
2189  return STATUS_SUCCESS;
2190  }
2191 
2192  /* This is the format of the returned data */
2193  PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
2194  DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
2195 
2197 
2198  /* Sanity check for Unicode-sized string */
2199  ASSERT((BufferLength & 1) == 0);
2200 
2201  /* Allocate name buffer */
2203  ObjectNameInfo = ExAllocatePool(PagedPool, Length);
2204  if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
2205 
2206  /* Query the PDO name */
2208  ObjectNameInfo,
2209  Length,
2210  ResultLength);
2212  {
2213  /* It's up to the caller to try again */
2215  }
2216 
2217  /* This string needs to be NULL-terminated */
2218  NullTerminate = TRUE;
2219 
2220  /* Return if successful */
2221  if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
2222  ObjectNameInfo->Name.Buffer);
2223 
2224  /* Let the caller know how big the name is */
2226  break;
2227 
2229 
2230  Policy = DeviceNode->RemovalPolicy;
2231  PIP_RETURN_DATA(sizeof(Policy), &Policy);
2232 
2233  /* Handle the registry-based properties */
2257  //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
2259  break;
2262  break;
2267  default:
2269  }
2270 
2271  /* Having a registry value name implies registry data */
2272  if (ValueName)
2273  {
2274  /* We know up-front how much data to expect */
2276 
2277  /* Go get the data, use the LogConf subkey if necessary */
2279  ValueType,
2280  ValueName,
2281  (DeviceProperty ==
2283  L"LogConf": NULL,
2285  ResultLength);
2286  }
2287  else if (NT_SUCCESS(Status))
2288  {
2289  /* We know up-front how much data to expect, check the caller's buffer */
2290  *ResultLength = ReturnLength + (NullTerminate ? sizeof(UNICODE_NULL) : 0);
2291  if (*ResultLength <= BufferLength)
2292  {
2293  /* Buffer is all good, copy the data */
2295 
2296  /* Check if we need to NULL-terminate the string */
2297  if (NullTerminate)
2298  {
2299  /* Terminate the string */
2301  }
2302 
2303  /* This is the success path */
2305  }
2306  else
2307  {
2308  /* Failure path */
2310  }
2311  }
2312 
2313  /* Free any allocation we may have made, and return the status code */
2314  if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
2315  return Status;
2316 }
2317 
2333 NTSTATUS
2334 NTAPI
2339 {
2340  static WCHAR RootKeyName[] =
2341  L"\\Registry\\Machine\\System\\CurrentControlSet\\";
2342  static WCHAR ProfileKeyName[] =
2343  L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
2344  static WCHAR ClassKeyName[] = L"Control\\Class\\";
2345  static WCHAR EnumKeyName[] = L"Enum\\";
2346  static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
2348  PWSTR KeyNameBuffer;
2350  ULONG DriverKeyLength;
2353  NTSTATUS Status;
2354 
2355  DPRINT("IoOpenDeviceRegistryKey() called\n");
2356 
2358  {
2359  DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
2360  return STATUS_INVALID_PARAMETER;
2361  }
2362 
2366 
2367  /*
2368  * Calculate the length of the base key name. This is the full
2369  * name for driver key or the name excluding "Device Parameters"
2370  * subkey for device key.
2371  */
2372 
2373  KeyNameLength = sizeof(RootKeyName);
2375  KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
2377  {
2378  KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
2380  0, NULL, &DriverKeyLength);
2382  return Status;
2383  KeyNameLength += DriverKeyLength;
2384  }
2385  else
2386  {
2387  KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
2388  DeviceNode->InstancePath.Length;
2389  }
2390 
2391  /*
2392  * Now allocate the buffer for the key name...
2393  */
2394 
2395  KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
2396  if (KeyNameBuffer == NULL)
2398 
2399  KeyName.Length = 0;
2400  KeyName.MaximumLength = (USHORT)KeyNameLength;
2401  KeyName.Buffer = KeyNameBuffer;
2402 
2403  /*
2404  * ...and build the key name.
2405  */
2406 
2407  KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
2408  RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
2409 
2411  RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
2412 
2414  {
2415  RtlAppendUnicodeToString(&KeyName, ClassKeyName);
2417  DriverKeyLength, KeyNameBuffer +
2418  (KeyName.Length / sizeof(WCHAR)),
2419  &DriverKeyLength);
2420  if (!NT_SUCCESS(Status))
2421  {
2422  DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
2423  ExFreePool(KeyNameBuffer);
2424  return Status;
2425  }
2426  KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
2427  }
2428  else
2429  {
2430  RtlAppendUnicodeToString(&KeyName, EnumKeyName);
2432  if (DeviceNode->InstancePath.Length == 0)
2433  {
2434  ExFreePool(KeyNameBuffer);
2435  return Status;
2436  }
2437  }
2438 
2439  /*
2440  * Open the base key.
2441  */
2443  if (!NT_SUCCESS(Status))
2444  {
2445  DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
2446  ExFreePool(KeyNameBuffer);
2447  return Status;
2448  }
2449  ExFreePool(KeyNameBuffer);
2450 
2451  /*
2452  * For driver key we're done now.
2453  */
2454 
2456  return Status;
2457 
2458  /*
2459  * Let's go further. For device key we must open "Device Parameters"
2460  * subkey and create it if it doesn't exist yet.
2461  */
2462 
2463  RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
2465  &KeyName,
2467  *DevInstRegKey,
2468  NULL);
2469  Status = ZwCreateKey(DevInstRegKey,
2470  DesiredAccess,
2472  0,
2473  NULL,
2475  NULL);
2476  ZwClose(ObjectAttributes.RootDirectory);
2477 
2478  return Status;
2479 }
2480 
2481 /*
2482  * @implemented
2483  */
2484 VOID
2485 NTAPI
2489 {
2491  {
2492  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)DeviceObject, 0, 0);
2493  }
2494 
2495  switch (Type)
2496  {
2497  case BusRelations:
2498  /* Enumerate the device */
2500  break;
2501  default:
2502  /* Everything else is not implemented */
2503  break;
2504  }
2505 }
2506 
2507 /*
2508  * @implemented
2509  */
2510 NTSTATUS
2511 NTAPI
2515 {
2516  PAGED_CODE();
2517 
2519  {
2520  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)DeviceObject, 0, 0);
2521  }
2522 
2523  switch (Type)
2524  {
2525  case BusRelations:
2526  /* Enumerate the device */
2528  case PowerRelations:
2529  /* Not handled yet */
2530  return STATUS_NOT_IMPLEMENTED;
2531  case TargetDeviceRelation:
2532  /* Nothing to do */
2533  return STATUS_SUCCESS;
2534  default:
2535  /* Ejection relations are not supported */
2536  return STATUS_NOT_SUPPORTED;
2537  }
2538 }
2539 
2540 /*
2541  * @implemented
2542  */
2543 BOOLEAN
2544 NTAPI
2546  IN ULONG BusNumber,
2550 {
2551  /* FIXME: Notify the resource arbiter */
2552 
2554  BusNumber,
2555  BusAddress,
2556  AddressSpace,
2558 }
BOOLEAN PnPBootDriversLoaded
Definition: pnpmgr.c:21
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2512
DEVICE_REGISTRY_PROPERTY
Definition: iotypes.h:1177
KGUARDED_MUTEX PpDeviceReferenceTableLock
Definition: pnpmgr.c:19
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define REGSTR_VAL_CLASS
Definition: regstr.h:291
GUID Guids[1]
Definition: io.h:440
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
return STATUS_NOT_SUPPORTED
RTL_AVL_COMPARE_ROUTINE * PRTL_AVL_COMPARE_ROUTINE
Definition: rtltypes.h:385
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
ASMGENDATA Table[]
Definition: genincdata.c:61
#define REGSTR_VAL_DRIVER
Definition: regstr.h:385
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
_In_ ULONG _In_ PHYSICAL_ADDRESS BusAddress
Definition: iofuncs.h:2268
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:549
VOID NTAPI PiFreeGenericTableEntry(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: pnpmgr.c:1821
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
enum _INTERFACE_TYPE INTERFACE_TYPE
#define TAG_IO
Definition: tag.h:69
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList
Definition: pnpmgr.c:28
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2474
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_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
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2782
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1599
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1123
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY DeviceProperty
Definition: wdfdevice.h:3767
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:666
VOID NTAPI IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI PnpBusTypeGuidGet(IN USHORT Index, IN LPGUID BusTypeGuid)
Definition: pnpmgr.c:1884
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
#define REGSTR_VAL_CONFIGFLAGS
Definition: regstr.h:388
FAST_MUTEX Lock
Definition: io.h:439
PVOID NTAPI PiAllocateGenericTableEntry(IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
Definition: pnpmgr.c:1811
DEVICE_CAPABILITIES
Definition: iotypes.h:948
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@385::@394 DeviceSpecificData
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
uint16_t * PWCHAR
Definition: typedefs.h:56
#define REGSTR_VAL_FRIENDLYNAME
Definition: regstr.h:465
VOID NTAPI IoQueueThreadIrp(IN PIRP Irp)
Definition: irp.c:1954
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1750
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1044
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:304
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1504
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
Definition: pnpmgr.c:463
NTSTATUS NTAPI PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject, IN ULONG ValueType, IN PWSTR ValueName, IN PWSTR KeyName, OUT PVOID Buffer, IN PULONG BufferLength)
Definition: pnpmgr.c:2005
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define REGSTR_VAL_COMPATIBLEIDS
Definition: regstr.h:296
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
UCHAR KIRQL
Definition: env_spec_w32.h:591
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
ULONG CLONG
Definition: umtypes.h:126
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
return STATUS_NOT_IMPLEMENTED
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@385 u
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
Definition: Header.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
static HTREEITEM hRoot
Definition: treeview.c:381
#define REG_MULTI_SZ
Definition: nt_native.h:1501
BOOLEAN NTAPI PiInitPhase0(VOID)
Definition: pnpmgr.c:1844
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1697
NTSTATUS FASTCALL IopInitializeDevice(PDEVICE_NODE DeviceNode, PDRIVER_OBJECT DriverObject)
Definition: pnpmgr.c:395
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
#define pp
Definition: hlsl.yy.c:1208
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
ERESOURCE PpRegistryDeviceResource
Definition: pnpmgr.c:18
RTL_AVL_TABLE PpDeviceReferenceTable
Definition: pnpmgr.c:20
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:2096
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define PIP_UNIMPLEMENTED()
Definition: pnpmgr.c:2089
void * PVOID
Definition: retypes.h:9
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
USHORT NTAPI IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
Definition: pnpmgr.c:481
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DNF_STARTED
Definition: iotypes.h:168
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:750
NTSTATUS NTAPI PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1911
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:383
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
_In_ WDFCOLLECTION _In_ ULONG Index
#define ENUM_ROOT
Definition: io.h:53
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:904
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define ObDereferenceObject
Definition: obfuncs.h:203
struct _IO_BUS_TYPE_GUID_LIST IO_BUS_TYPE_GUID_LIST
Type
Definition: Type.h:6
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define REGSTR_VAL_CLASSGUID
Definition: regstr.h:422
CODE_SEG("INIT")
Definition: fsrtlpc.c:19
PDEVICE_NODE PopSystemPowerDeviceNode
Definition: power.c:25
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
BOOLEAN NTAPI PpInitSystem(VOID)
Definition: pnpmgr.c:1856
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
unsigned char UCHAR
Definition: xmlstorage.h:181
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
BOOLEAN NTAPI IoTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
Definition: pnpmgr.c:2545
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
VOID NTAPI PpInitializeDeviceReferenceTable(VOID)
Definition: pnpmgr.c:1830
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#define DNF_LEGACY_DRIVER
Definition: iotypes.h:181
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID PropertyBuffer
Definition: wdfdevice.h:4431
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:383
VOID NTAPI RtlInitializeGenericTableAvl(IN OUT PRTL_AVL_TABLE Table, IN PRTL_AVL_COMPARE_ROUTINE CompareRoutine, IN PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: avltable.c:26
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
VOID IopFixupDeviceId(PWCHAR String)
Definition: pnpmgr.c:33
static BOOLEAN IopIsFirmwareMapperDisabled(VOID)
Definition: pnpmgr.c:1471
#define DNF_DISABLED
Definition: iotypes.h:188
#define PIP_REGISTRY_DATA(x, y)
Definition: pnpmgr.c:2088
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1951
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:623
RTL_AVL_FREE_ROUTINE * PRTL_AVL_FREE_ROUTINE
Definition: rtltypes.h:402
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_In_ ULONG _In_ ULONG KeyNameLength
Definition: usbdlib.h:208
NTSTATUS NTAPI IopCreateRegistryKeyEx(OUT PHANDLE Handle, IN HANDLE RootHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: pnpmgr.c:1624
#define REGSTR_VAL_HARDWAREID
Definition: regstr.h:485
_In_ ULONG _In_ ACCESS_MASK _Out_ PHANDLE DevInstRegKey
Definition: iofuncs.h:1123
#define IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)
Definition: io.h:238
#define REGSTR_VAL_DEVDESC
Definition: regstr.h:292
NTSTATUS NTAPI IopUpdateRootKey(VOID)
Definition: pnpmgr.c:1541
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:112
NTSTATUS PiPerformSyncDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
Perfom a device operation synchronously via PiQueueDeviceAction.
Definition: devaction.c:2533
BOOLEAN NTAPI HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
Definition: bus.c:140
#define MAXULONG
Definition: typedefs.h:251
#define RtlComputeCrc32
Definition: compat.h:669
ULONG_PTR SIZE_T
Definition: typedefs.h:80
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define REGSTR_VAL_MFG
Definition: regstr.h:306
struct _GUID GUID
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2486
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
unsigned short USHORT
Definition: pedump.c:61
FxAutoRegKey hKey
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:329
enum _DEVICE_REMOVAL_POLICY DEVICE_REMOVAL_POLICY
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:2335
#define PIP_RETURN_DATA(x, y)
Definition: pnpmgr.c:2087
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
#define DPRINT1
Definition: precomp.h:8
#define crc32(crc, buf, len)
Definition: inflate.c:1081
_In_ HANDLE Handle
Definition: extypes.h:390
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define FILE_DEVICE_ACPI
Definition: winioctl.h:155
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
RTL_AVL_ALLOCATE_ROUTINE * PRTL_AVL_ALLOCATE_ROUTINE
Definition: rtltypes.h:394
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4431
static NTSTATUS IopEnumerateDetectedDevices(IN HANDLE hBaseKey, IN PUNICODE_STRING RelativePath OPTIONAL, IN HANDLE hRootKey, IN BOOLEAN EnumerateSubKeys, IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources, IN ULONG ParentBootResourcesLength)
Definition: pnpmgr.c:1030
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define CM_PROB_FAILED_ADD
Definition: cfg.h:61
GLfloat GLfloat p
Definition: glext.h:8902
#define REGSTR_VAL_BOOTCONFIG
Definition: regstr.h:293
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
ULONG ExpInitializationPhase
Definition: init.c:66
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:651
#define DNF_ADDED
Definition: iotypes.h:179
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:27
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
#define REG_DWORD
Definition: sdbapi.c:596
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
RTL_GENERIC_COMPARE_RESULTS NTAPI PiCompareInstancePath(IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
Definition: pnpmgr.c:1795
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG ACCESS_MASK
Definition: nt_native.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:461
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 PLUGPLAY_REGKEY_CURRENT_HWPROFILE
Definition: iofuncs.h:2784
#define REGSTR_VAL_LOCATION_INFORMATION
Definition: regstr.h:423
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
#define PAGED_CODE()
#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