ReactOS  0.4.15-dev-440-g5f37b68
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 
21 
23 
24 /* DATA **********************************************************************/
25 
28 
29 /* FUNCTIONS *****************************************************************/
30 
31 VOID
33 {
35 
36  for (i = 0; i < Length; i++)
37  {
38  if (String[i] == L'\\')
39  String[i] = L'#';
40  }
41 }
42 
43 VOID
44 NTAPI
46 {
48  HANDLE CriticalDeviceKey, InstanceKey;
50  UNICODE_STRING CriticalDeviceKeyU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\CriticalDeviceDatabase");
51  UNICODE_STRING CompatibleIdU = RTL_CONSTANT_STRING(L"CompatibleIDs");
52  UNICODE_STRING HardwareIdU = RTL_CONSTANT_STRING(L"HardwareID");
53  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
54  UNICODE_STRING ClassGuidU = RTL_CONSTANT_STRING(L"ClassGUID");
56  ULONG HidLength = 0, CidLength = 0, BufferLength;
57  PWCHAR IdBuffer, OriginalIdBuffer;
58 
59  /* Open the device instance key */
60  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
61  if (Status != STATUS_SUCCESS)
62  return;
63 
64  Status = ZwQueryValueKey(InstanceKey,
65  &HardwareIdU,
67  NULL,
68  0,
69  &HidLength);
71  {
72  ZwClose(InstanceKey);
73  return;
74  }
75 
76  Status = ZwQueryValueKey(InstanceKey,
77  &CompatibleIdU,
79  NULL,
80  0,
81  &CidLength);
83  {
84  CidLength = 0;
85  }
86 
87  BufferLength = HidLength + CidLength;
88  BufferLength -= (((CidLength != 0) ? 2 : 1) * FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data));
89 
90  /* Allocate a buffer to hold data from both */
91  OriginalIdBuffer = IdBuffer = ExAllocatePool(PagedPool, BufferLength);
92  if (!IdBuffer)
93  {
94  ZwClose(InstanceKey);
95  return;
96  }
97 
98  /* Compute the buffer size */
99  if (HidLength > CidLength)
100  BufferLength = HidLength;
101  else
102  BufferLength = CidLength;
103 
104  PartialInfo = ExAllocatePool(PagedPool, BufferLength);
105  if (!PartialInfo)
106  {
107  ZwClose(InstanceKey);
108  ExFreePool(OriginalIdBuffer);
109  return;
110  }
111 
112  Status = ZwQueryValueKey(InstanceKey,
113  &HardwareIdU,
115  PartialInfo,
116  HidLength,
117  &HidLength);
118  if (Status != STATUS_SUCCESS)
119  {
120  ExFreePool(PartialInfo);
121  ExFreePool(OriginalIdBuffer);
122  ZwClose(InstanceKey);
123  return;
124  }
125 
126  /* Copy in HID info first (without 2nd terminating NULL if CID is present) */
127  HidLength = PartialInfo->DataLength - ((CidLength != 0) ? sizeof(WCHAR) : 0);
128  RtlCopyMemory(IdBuffer, PartialInfo->Data, HidLength);
129 
130  if (CidLength != 0)
131  {
132  Status = ZwQueryValueKey(InstanceKey,
133  &CompatibleIdU,
135  PartialInfo,
136  CidLength,
137  &CidLength);
138  if (Status != STATUS_SUCCESS)
139  {
140  ExFreePool(PartialInfo);
141  ExFreePool(OriginalIdBuffer);
142  ZwClose(InstanceKey);
143  return;
144  }
145 
146  /* Copy CID next */
147  CidLength = PartialInfo->DataLength;
148  RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength);
149  }
150 
151  /* Free our temp buffer */
152  ExFreePool(PartialInfo);
153 
155  &CriticalDeviceKeyU,
157  NULL,
158  NULL);
159  Status = ZwOpenKey(&CriticalDeviceKey,
162  if (!NT_SUCCESS(Status))
163  {
164  /* The critical device database doesn't exist because
165  * we're probably in 1st stage setup, but it's ok */
166  ExFreePool(OriginalIdBuffer);
167  ZwClose(InstanceKey);
168  return;
169  }
170 
171  while (*IdBuffer)
172  {
173  USHORT StringLength = (USHORT)wcslen(IdBuffer) + 1, Index;
174 
175  IopFixupDeviceId(IdBuffer);
176 
177  /* Look through all subkeys for a match */
178  for (Index = 0; TRUE; Index++)
179  {
180  ULONG NeededLength;
181  PKEY_BASIC_INFORMATION BasicInfo;
182 
183  Status = ZwEnumerateKey(CriticalDeviceKey,
184  Index,
186  NULL,
187  0,
188  &NeededLength);
190  break;
192  {
193  UNICODE_STRING ChildIdNameU, RegKeyNameU;
194 
195  BasicInfo = ExAllocatePool(PagedPool, NeededLength);
196  if (!BasicInfo)
197  {
198  /* No memory */
199  ExFreePool(OriginalIdBuffer);
200  ZwClose(CriticalDeviceKey);
201  ZwClose(InstanceKey);
202  return;
203  }
204 
205  Status = ZwEnumerateKey(CriticalDeviceKey,
206  Index,
208  BasicInfo,
209  NeededLength,
210  &NeededLength);
211  if (Status != STATUS_SUCCESS)
212  {
213  /* This shouldn't happen */
214  ExFreePool(BasicInfo);
215  continue;
216  }
217 
218  ChildIdNameU.Buffer = IdBuffer;
219  ChildIdNameU.MaximumLength = ChildIdNameU.Length = (StringLength - 1) * sizeof(WCHAR);
220  RegKeyNameU.Buffer = BasicInfo->Name;
221  RegKeyNameU.MaximumLength = RegKeyNameU.Length = (USHORT)BasicInfo->NameLength;
222 
223  if (RtlEqualUnicodeString(&ChildIdNameU, &RegKeyNameU, TRUE))
224  {
225  HANDLE ChildKeyHandle;
226 
228  &ChildIdNameU,
230  CriticalDeviceKey,
231  NULL);
232 
233  Status = ZwOpenKey(&ChildKeyHandle,
236  if (Status != STATUS_SUCCESS)
237  {
238  ExFreePool(BasicInfo);
239  continue;
240  }
241 
242  /* Check if there's already a driver installed */
243  Status = ZwQueryValueKey(InstanceKey,
244  &ClassGuidU,
246  NULL,
247  0,
248  &NeededLength);
250  {
251  ExFreePool(BasicInfo);
252  continue;
253  }
254 
255  Status = ZwQueryValueKey(ChildKeyHandle,
256  &ClassGuidU,
258  NULL,
259  0,
260  &NeededLength);
262  {
263  ExFreePool(BasicInfo);
264  continue;
265  }
266 
267  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
268  if (!PartialInfo)
269  {
270  ExFreePool(OriginalIdBuffer);
271  ExFreePool(BasicInfo);
272  ZwClose(InstanceKey);
273  ZwClose(ChildKeyHandle);
274  ZwClose(CriticalDeviceKey);
275  return;
276  }
277 
278  /* Read ClassGUID entry in the CDDB */
279  Status = ZwQueryValueKey(ChildKeyHandle,
280  &ClassGuidU,
282  PartialInfo,
283  NeededLength,
284  &NeededLength);
285  if (Status != STATUS_SUCCESS)
286  {
287  ExFreePool(BasicInfo);
288  continue;
289  }
290 
291  /* Write it to the ENUM key */
292  Status = ZwSetValueKey(InstanceKey,
293  &ClassGuidU,
294  0,
295  REG_SZ,
296  PartialInfo->Data,
297  PartialInfo->DataLength);
298  if (Status != STATUS_SUCCESS)
299  {
300  ExFreePool(BasicInfo);
301  ExFreePool(PartialInfo);
302  ZwClose(ChildKeyHandle);
303  continue;
304  }
305 
306  Status = ZwQueryValueKey(ChildKeyHandle,
307  &ServiceU,
309  NULL,
310  0,
311  &NeededLength);
313  {
314  ExFreePool(PartialInfo);
315  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
316  if (!PartialInfo)
317  {
318  ExFreePool(OriginalIdBuffer);
319  ExFreePool(BasicInfo);
320  ZwClose(InstanceKey);
321  ZwClose(ChildKeyHandle);
322  ZwClose(CriticalDeviceKey);
323  return;
324  }
325 
326  /* Read the service entry from the CDDB */
327  Status = ZwQueryValueKey(ChildKeyHandle,
328  &ServiceU,
330  PartialInfo,
331  NeededLength,
332  &NeededLength);
333  if (Status != STATUS_SUCCESS)
334  {
335  ExFreePool(BasicInfo);
336  ExFreePool(PartialInfo);
337  ZwClose(ChildKeyHandle);
338  continue;
339  }
340 
341  /* Write it to the ENUM key */
342  Status = ZwSetValueKey(InstanceKey,
343  &ServiceU,
344  0,
345  REG_SZ,
346  PartialInfo->Data,
347  PartialInfo->DataLength);
348  if (Status != STATUS_SUCCESS)
349  {
350  ExFreePool(BasicInfo);
351  ExFreePool(PartialInfo);
352  ZwClose(ChildKeyHandle);
353  continue;
354  }
355 
356  DPRINT("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
357  }
358  else
359  {
360  DPRINT1("Installed NULL service for critical device '%wZ'\n", &ChildIdNameU);
361  }
362 
363  ExFreePool(OriginalIdBuffer);
364  ExFreePool(PartialInfo);
365  ExFreePool(BasicInfo);
366  ZwClose(InstanceKey);
367  ZwClose(ChildKeyHandle);
368  ZwClose(CriticalDeviceKey);
369 
370  /* That's it */
371  return;
372  }
373 
374  ExFreePool(BasicInfo);
375  }
376  else
377  {
378  /* Umm, not sure what happened here */
379  continue;
380  }
381  }
382 
383  /* Advance to the next ID */
384  IdBuffer += StringLength;
385  }
386 
387  ExFreePool(OriginalIdBuffer);
388  ZwClose(InstanceKey);
389  ZwClose(CriticalDeviceKey);
390 }
391 
392 NTSTATUS
393 FASTCALL
396 {
397  PDEVICE_OBJECT Fdo;
399 
400  if (!DriverObject)
401  {
402  /* Special case for bus driven devices */
403  DeviceNode->Flags |= DNF_ADDED;
404  return STATUS_SUCCESS;
405  }
406 
408  {
409  DeviceNode->Flags |= DNF_LEGACY_DRIVER;
410  }
411 
412  if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
413  {
414  DeviceNode->Flags |= (DNF_ADDED | DNF_STARTED);
415  return STATUS_SUCCESS;
416  }
417 
418  /* This is a Plug and Play driver */
419  DPRINT("Plug and Play driver found\n");
420  ASSERT(DeviceNode->PhysicalDeviceObject);
421 
422  DPRINT("Calling %wZ->AddDevice(%wZ)\n",
424  &DeviceNode->InstancePath);
426  DeviceNode->PhysicalDeviceObject);
427  if (!NT_SUCCESS(Status))
428  {
429  DPRINT1("%wZ->AddDevice(%wZ) failed with status 0x%x\n",
431  &DeviceNode->InstancePath,
432  Status);
434  DeviceNode->Problem = CM_PROB_FAILED_ADD;
435  return Status;
436  }
437 
438  Fdo = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
439 
440  /* Check if we have a ACPI device (needed for power management) */
441  if (Fdo->DeviceType == FILE_DEVICE_ACPI)
442  {
443  static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
444 
445  /* There can be only one system power device */
446  if (!SystemPowerDeviceNodeCreated)
447  {
450  SystemPowerDeviceNodeCreated = TRUE;
451  }
452  }
453 
454  ObDereferenceObject(Fdo);
455 
457 
458  return STATUS_SUCCESS;
459 }
460 
461 NTSTATUS
463 {
464  KIRQL OldIrql;
465 
467  {
471 
472  return STATUS_SUCCESS;
473  }
474 
475  return STATUS_UNSUCCESSFUL;
476 }
477 
478 USHORT
479 NTAPI
481 {
482  USHORT i = 0, FoundIndex = 0xFFFF;
483  ULONG NewSize;
484  PVOID NewList;
485 
486  /* Acquire the lock */
488 
489  /* Loop all entries */
490  while (i < PnpBusTypeGuidList->GuidCount)
491  {
492  /* Try to find a match */
493  if (RtlCompareMemory(BusTypeGuid,
495  sizeof(GUID)) == sizeof(GUID))
496  {
497  /* Found it */
498  FoundIndex = i;
499  goto Quickie;
500  }
501  i++;
502  }
503 
504  /* Check if we have to grow the list */
506  {
507  /* Calculate the new size */
508  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
509  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
510 
511  /* Allocate the new copy */
512  NewList = ExAllocatePool(PagedPool, NewSize);
513 
514  if (!NewList)
515  {
516  /* Fail */
518  goto Quickie;
519  }
520 
521  /* Now copy them, decrease the size too */
522  NewSize -= sizeof(GUID);
524 
525  /* Free the old list */
527 
528  /* Use the new buffer */
529  PnpBusTypeGuidList = NewList;
530  }
531 
532  /* Copy the new GUID */
534  BusTypeGuid,
535  sizeof(GUID));
536 
537  /* The new entry is the index */
538  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
540 
541 Quickie:
543  return FoundIndex;
544 }
545 
546 NTSTATUS
547 NTAPI
549  IN PIO_STACK_LOCATION IoStackLocation,
551 {
552  PIRP Irp;
553  PIO_STACK_LOCATION IrpStack;
555  KEVENT Event;
557  PDEVICE_OBJECT TopDeviceObject;
558  PAGED_CODE();
559 
560  /* Call the top of the device stack */
561  TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
562 
563  /* Allocate an IRP */
564  Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
565  if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
566 
567  /* Initialize to failure */
568  Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
569  Irp->IoStatus.Information = IoStatusBlock.Information = 0;
570 
571  /* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
572  if ((IoStackLocation->MajorFunction == IRP_MJ_PNP) &&
573  (IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS))
574  {
575  /* Copy the resource requirements list into the IOSB */
576  Irp->IoStatus.Information =
577  IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
578  }
579 
580  /* Initialize the event */
582 
583  /* Set them up */
584  Irp->UserIosb = &IoStatusBlock;
585  Irp->UserEvent = &Event;
586 
587  /* Queue the IRP */
588  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
590 
591  /* Copy-in the stack */
592  IrpStack = IoGetNextIrpStackLocation(Irp);
593  *IrpStack = *IoStackLocation;
594 
595  /* Call the driver */
596  Status = IoCallDriver(TopDeviceObject, Irp);
597  if (Status == STATUS_PENDING)
598  {
599  /* Wait for it */
601  Executive,
602  KernelMode,
603  FALSE,
604  NULL);
606  }
607 
608  /* Remove the reference */
609  ObDereferenceObject(TopDeviceObject);
610 
611  /* Return the information */
613  return Status;
614 }
615 
616 NTSTATUS
617 NTAPI
622 {
623  IO_STACK_LOCATION IoStackLocation;
624 
625  /* Fill out the stack information */
626  RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
627  IoStackLocation.MajorFunction = IRP_MJ_PNP;
628  IoStackLocation.MinorFunction = MinorFunction;
629  if (Stack)
630  {
631  /* Copy the rest */
632  RtlCopyMemory(&IoStackLocation.Parameters,
633  &Stack->Parameters,
634  sizeof(Stack->Parameters));
635  }
636 
637  /* Do the PnP call */
639  &IoStackLocation,
641  return IoStatusBlock->Status;
642 }
643 
644 /*
645  * IopCreateDeviceKeyPath
646  *
647  * Creates a registry key
648  *
649  * Parameters
650  * RegistryPath
651  * Name of the key to be created.
652  * Handle
653  * Handle to the newly created key
654  *
655  * Remarks
656  * This method can create nested trees, so parent of RegistryPath can
657  * be not existant, and will be created if needed.
658  */
659 NTSTATUS
660 NTAPI
664 {
666  HANDLE hParent = NULL, hKey;
669  PCWSTR Current, Last;
670  USHORT Length;
672 
673  /* Assume failure */
674  *Handle = NULL;
675 
676  /* Open root key for device instances */
678  if (!NT_SUCCESS(Status))
679  {
680  DPRINT1("ZwOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
681  return Status;
682  }
683 
684  Current = KeyName.Buffer = RegistryPath->Buffer;
685  Last = &RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)];
686 
687  /* Go up to the end of the string */
688  while (Current <= Last)
689  {
690  if (Current != Last && *Current != L'\\')
691  {
692  /* Not the end of the string and not a separator */
693  Current++;
694  continue;
695  }
696 
697  /* Prepare relative key name */
698  Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
699  KeyName.MaximumLength = KeyName.Length = Length;
700  DPRINT("Create '%wZ'\n", &KeyName);
701 
702  /* Open key */
704  &KeyName,
706  hParent,
707  NULL);
708  Status = ZwCreateKey(&hKey,
709  Current == Last ? KEY_ALL_ACCESS : KEY_CREATE_SUB_KEY,
711  0,
712  NULL,
714  NULL);
715 
716  /* Close parent key handle, we don't need it anymore */
717  if (hParent)
718  ZwClose(hParent);
719 
720  /* Key opening/creating failed? */
721  if (!NT_SUCCESS(Status))
722  {
723  DPRINT1("ZwCreateKey('%wZ') failed with status 0x%08lx\n", &KeyName, Status);
724  return Status;
725  }
726 
727  /* Check if it is the end of the string */
728  if (Current == Last)
729  {
730  /* Yes, return success */
731  *Handle = hKey;
732  return STATUS_SUCCESS;
733  }
734 
735  /* Start with this new parent key */
736  hParent = hKey;
737  Current++;
738  KeyName.Buffer = (PWSTR)Current;
739  }
740 
741  return STATUS_UNSUCCESSFUL;
742 }
743 
744 NTSTATUS
747 {
750  HANDLE LogConfKey, ControlKey, DeviceParamsKey;
751  ULONG ResCount;
754 
755  DPRINT("IopSetDeviceInstanceData() called\n");
756 
757  /* Create the 'LogConf' key */
758  RtlInitUnicodeString(&KeyName, L"LogConf");
760  &KeyName,
762  InstanceKey,
763  NULL);
764  Status = ZwCreateKey(&LogConfKey,
767  0,
768  NULL,
769  // FIXME? In r53694 it was silently turned from non-volatile into this,
770  // without any extra warning. Is this still needed??
772  NULL);
773  if (NT_SUCCESS(Status))
774  {
775  /* Set 'BootConfig' value */
776  if (DeviceNode->BootResources != NULL)
777  {
778  ResCount = DeviceNode->BootResources->Count;
779  if (ResCount != 0)
780  {
781  RtlInitUnicodeString(&KeyName, L"BootConfig");
782  Status = ZwSetValueKey(LogConfKey,
783  &KeyName,
784  0,
786  DeviceNode->BootResources,
787  PnpDetermineResourceListSize(DeviceNode->BootResources));
788  }
789  }
790 
791  /* Set 'BasicConfigVector' value */
792  if (DeviceNode->ResourceRequirements != NULL &&
793  DeviceNode->ResourceRequirements->ListSize != 0)
794  {
795  RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
796  Status = ZwSetValueKey(LogConfKey,
797  &KeyName,
798  0,
800  DeviceNode->ResourceRequirements,
801  DeviceNode->ResourceRequirements->ListSize);
802  }
803 
804  ZwClose(LogConfKey);
805  }
806 
807  /* Set the 'ConfigFlags' value */
808  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
809  Status = ZwQueryValueKey(InstanceKey,
810  &KeyName,
812  NULL,
813  0,
814  &ResultLength);
816  {
817  /* Write the default value */
818  ULONG DefaultConfigFlags = 0;
819  Status = ZwSetValueKey(InstanceKey,
820  &KeyName,
821  0,
822  REG_DWORD,
823  &DefaultConfigFlags,
824  sizeof(DefaultConfigFlags));
825  }
826 
827  /* Create the 'Control' key */
828  RtlInitUnicodeString(&KeyName, L"Control");
830  &KeyName,
832  InstanceKey,
833  NULL);
834  Status = ZwCreateKey(&ControlKey,
835  0,
837  0,
838  NULL,
840  NULL);
841  if (NT_SUCCESS(Status))
842  ZwClose(ControlKey);
843 
844  /* Create the 'Device Parameters' key and set the 'FirmwareIdentified' value for all ACPI-enumerated devices */
845  if (_wcsnicmp(DeviceNode->InstancePath.Buffer, L"ACPI\\", 5) == 0)
846  {
847  RtlInitUnicodeString(&KeyName, L"Device Parameters");
849  &KeyName,
851  InstanceKey,
852  NULL);
853  Status = ZwCreateKey(&DeviceParamsKey,
854  0,
856  0,
857  NULL,
859  NULL);
860  if (NT_SUCCESS(Status))
861  {
862  ULONG FirmwareIdentified = 1;
863  RtlInitUnicodeString(&KeyName, L"FirmwareIdentified");
864  Status = ZwSetValueKey(DeviceParamsKey,
865  &KeyName,
866  0,
867  REG_DWORD,
868  &FirmwareIdentified,
869  sizeof(FirmwareIdentified));
870 
871  ZwClose(DeviceParamsKey);
872  }
873  }
874 
875  DPRINT("IopSetDeviceInstanceData() done\n");
876 
877  return Status;
878 }
879 
880 /*
881  * IopGetParentIdPrefix
882  *
883  * Retrieve (or create) a string which identifies a device.
884  *
885  * Parameters
886  * DeviceNode
887  * Pointer to device node.
888  * ParentIdPrefix
889  * Pointer to the string where is returned the parent node identifier
890  *
891  * Remarks
892  * If the return code is STATUS_SUCCESS, the ParentIdPrefix string is
893  * valid and its Buffer field is NULL-terminated. The caller needs to
894  * to free the string with RtlFreeUnicodeString when it is no longer
895  * needed.
896  */
897 
898 NTSTATUS
900  PUNICODE_STRING ParentIdPrefix)
901 {
902  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
903  ULONG KeyNameBufferLength;
904  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
905  UNICODE_STRING KeyName = {0, 0, NULL};
906  UNICODE_STRING KeyValue;
908  HANDLE hKey = NULL;
909  ULONG crc32;
911 
912  /* HACK: As long as some devices have a NULL device
913  * instance path, the following test is required :(
914  */
915  if (DeviceNode->Parent->InstancePath.Length == 0)
916  {
917  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
918  &DeviceNode->InstancePath);
919  return STATUS_UNSUCCESSFUL;
920  }
921 
922  /* 1. Try to retrieve ParentIdPrefix from registry */
923  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
924  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
925  KeyNameBufferLength + sizeof(UNICODE_NULL),
926  TAG_IO);
927  if (!ParentIdPrefixInformation)
928  {
930  }
931 
932  KeyName.Length = 0;
933  KeyName.MaximumLength = EnumKeyPath.Length +
934  DeviceNode->Parent->InstancePath.Length +
935  sizeof(UNICODE_NULL);
937  KeyName.MaximumLength,
938  TAG_IO);
939  if (!KeyName.Buffer)
940  {
942  goto cleanup;
943  }
944 
945  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
946  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
947 
949  if (!NT_SUCCESS(Status))
950  {
951  goto cleanup;
952  }
953  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
954  Status = ZwQueryValueKey(hKey,
955  &ValueName,
957  ParentIdPrefixInformation,
958  KeyNameBufferLength,
959  &KeyNameBufferLength);
960  if (NT_SUCCESS(Status))
961  {
962  if (ParentIdPrefixInformation->Type != REG_SZ)
963  {
965  }
966  else
967  {
968  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
969  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
970  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
971  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
972  }
973  goto cleanup;
974  }
976  {
977  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
978  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
979  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
980  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
981  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
982  goto cleanup;
983  }
984 
985  /* 2. Create the ParentIdPrefix value */
987  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
988  DeviceNode->Parent->InstancePath.Length);
989 
990  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
991  KeyNameBufferLength,
992  L"%lx&%lx",
993  DeviceNode->Parent->Level,
994  crc32);
995  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
996 
997  /* 3. Try to write the ParentIdPrefix to registry */
998  Status = ZwSetValueKey(hKey,
999  &ValueName,
1000  0,
1001  REG_SZ,
1002  KeyValue.Buffer,
1003  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
1004 
1005 cleanup:
1006  if (NT_SUCCESS(Status))
1007  {
1008  /* Duplicate the string to return it */
1010  &KeyValue,
1011  ParentIdPrefix);
1012  }
1013  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
1015  if (hKey != NULL)
1016  {
1017  ZwClose(hKey);
1018  }
1019  return Status;
1020 }
1021 
1022 static
1023 INIT_FUNCTION
1024 NTSTATUS
1026  IN HANDLE hBaseKey,
1027  IN PUNICODE_STRING RelativePath OPTIONAL,
1028  IN HANDLE hRootKey,
1029  IN BOOLEAN EnumerateSubKeys,
1030  IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources,
1031  IN ULONG ParentBootResourcesLength)
1032 {
1033  UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
1034  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
1035  UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
1036  UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
1037  UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
1039  HANDLE hDevicesKey = NULL;
1040  HANDLE hDeviceKey = NULL;
1041  HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
1042  UNICODE_STRING Level2NameU;
1043  WCHAR Level2Name[5];
1044  ULONG IndexDevice = 0;
1045  ULONG IndexSubKey;
1046  PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
1047  ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
1048  PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
1049  ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
1052  PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
1053  ULONG BootResourcesLength;
1054  NTSTATUS Status;
1055 
1056  const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
1057  UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
1058  static ULONG DeviceIndexSerial = 0;
1059  const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
1060  UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
1061  static ULONG DeviceIndexKeyboard = 0;
1062  const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
1063  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
1064  static ULONG DeviceIndexMouse = 0;
1065  const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"ParallelController");
1066  UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
1067  static ULONG DeviceIndexParallel = 0;
1068  const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
1069  UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
1070  static ULONG DeviceIndexFloppy = 0;
1071  UNICODE_STRING HardwareIdKey;
1072  PUNICODE_STRING pHardwareId;
1073  ULONG DeviceIndex = 0;
1074  PUCHAR CmResourceList;
1075  ULONG ListCount;
1076 
1077  if (RelativePath)
1078  {
1079  Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS);
1080  if (!NT_SUCCESS(Status))
1081  {
1082  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1083  goto cleanup;
1084  }
1085  }
1086  else
1087  hDevicesKey = hBaseKey;
1088 
1089  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1090  if (!pDeviceInformation)
1091  {
1092  DPRINT("ExAllocatePool() failed\n");
1094  goto cleanup;
1095  }
1096 
1097  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1098  if (!pValueInformation)
1099  {
1100  DPRINT("ExAllocatePool() failed\n");
1102  goto cleanup;
1103  }
1104 
1105  while (TRUE)
1106  {
1107  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1109  break;
1111  {
1112  ExFreePool(pDeviceInformation);
1113  DeviceInfoLength = RequiredSize;
1114  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1115  if (!pDeviceInformation)
1116  {
1117  DPRINT("ExAllocatePool() failed\n");
1119  goto cleanup;
1120  }
1121  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1122  }
1123  if (!NT_SUCCESS(Status))
1124  {
1125  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
1126  goto cleanup;
1127  }
1128  IndexDevice++;
1129 
1130  /* Open device key */
1131  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1132  DeviceName.Buffer = pDeviceInformation->Name;
1133 
1134  Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
1135  KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
1136  if (!NT_SUCCESS(Status))
1137  {
1138  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1139  goto cleanup;
1140  }
1141 
1142  /* Read boot resources, and add then to parent ones */
1143  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1145  {
1146  ExFreePool(pValueInformation);
1147  ValueInfoLength = RequiredSize;
1148  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1149  if (!pValueInformation)
1150  {
1151  DPRINT("ExAllocatePool() failed\n");
1152  ZwDeleteKey(hLevel2Key);
1154  goto cleanup;
1155  }
1156  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1157  }
1159  {
1160  BootResources = ParentBootResources;
1161  BootResourcesLength = ParentBootResourcesLength;
1162  }
1163  else if (!NT_SUCCESS(Status))
1164  {
1165  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1166  goto nextdevice;
1167  }
1168  else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
1169  {
1170  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
1171  goto nextdevice;
1172  }
1173  else
1174  {
1175  static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
1176 
1177  /* Concatenate current resources and parent ones */
1178  if (ParentBootResourcesLength == 0)
1179  BootResourcesLength = pValueInformation->DataLength;
1180  else
1181  BootResourcesLength = ParentBootResourcesLength
1182  + pValueInformation->DataLength
1183  - Header;
1184  BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
1185  if (!BootResources)
1186  {
1187  DPRINT("ExAllocatePool() failed\n");
1188  goto nextdevice;
1189  }
1190  if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1191  {
1192  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1193  }
1194  else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
1195  {
1196  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1197  RtlCopyMemory(
1198  (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
1199  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1200  ParentBootResourcesLength - Header);
1201  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1202  }
1203  else
1204  {
1205  RtlCopyMemory(BootResources, pValueInformation->Data, Header);
1206  RtlCopyMemory(
1207  (PVOID)((ULONG_PTR)BootResources + Header),
1208  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1209  ParentBootResourcesLength - Header);
1210  RtlCopyMemory(
1211  (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
1212  pValueInformation->Data + Header,
1213  pValueInformation->DataLength - Header);
1214  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1215  }
1216  }
1217 
1218  if (EnumerateSubKeys)
1219  {
1220  IndexSubKey = 0;
1221  while (TRUE)
1222  {
1223  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1225  break;
1227  {
1228  ExFreePool(pDeviceInformation);
1229  DeviceInfoLength = RequiredSize;
1230  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1231  if (!pDeviceInformation)
1232  {
1233  DPRINT("ExAllocatePool() failed\n");
1235  goto cleanup;
1236  }
1237  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1238  }
1239  if (!NT_SUCCESS(Status))
1240  {
1241  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
1242  goto cleanup;
1243  }
1244  IndexSubKey++;
1245  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1246  DeviceName.Buffer = pDeviceInformation->Name;
1247 
1249  hDeviceKey,
1250  &DeviceName,
1251  hRootKey,
1252  TRUE,
1253  BootResources,
1254  BootResourcesLength);
1255  if (!NT_SUCCESS(Status))
1256  goto cleanup;
1257  }
1258  }
1259 
1260  /* Read identifier */
1261  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1263  {
1264  ExFreePool(pValueInformation);
1265  ValueInfoLength = RequiredSize;
1266  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1267  if (!pValueInformation)
1268  {
1269  DPRINT("ExAllocatePool() failed\n");
1271  goto cleanup;
1272  }
1273  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1274  }
1275  if (!NT_SUCCESS(Status))
1276  {
1278  {
1279  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1280  goto nextdevice;
1281  }
1283  }
1284  else if (pValueInformation->Type != REG_SZ)
1285  {
1286  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
1287  goto nextdevice;
1288  }
1289  else
1290  {
1291  /* Assign hardware id to this device */
1292  ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
1293  ValueName.Buffer = (PWCHAR)pValueInformation->Data;
1294  if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
1295  ValueName.Length -= sizeof(WCHAR);
1296  }
1297 
1298  if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
1299  {
1300  pHardwareId = &HardwareIdSerial;
1301  DeviceIndex = DeviceIndexSerial++;
1302  }
1303  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
1304  {
1305  pHardwareId = &HardwareIdKeyboard;
1306  DeviceIndex = DeviceIndexKeyboard++;
1307  }
1308  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
1309  {
1310  pHardwareId = &HardwareIdMouse;
1311  DeviceIndex = DeviceIndexMouse++;
1312  }
1313  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
1314  {
1315  pHardwareId = &HardwareIdParallel;
1316  DeviceIndex = DeviceIndexParallel++;
1317  }
1318  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
1319  {
1320  pHardwareId = &HardwareIdFloppy;
1321  DeviceIndex = DeviceIndexFloppy++;
1322  }
1323  else
1324  {
1325  /* Unknown key path */
1326  DPRINT("Unknown key path '%wZ'\n", RelativePath);
1327  goto nextdevice;
1328  }
1329 
1330  /* Prepare hardware id key (hardware id value without final \0) */
1331  HardwareIdKey = *pHardwareId;
1332  HardwareIdKey.Length -= sizeof(UNICODE_NULL);
1333 
1334  /* Add the detected device to Root key */
1335  InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL);
1336  Status = ZwCreateKey(
1337  &hLevel1Key,
1340  0,
1341  NULL,
1343  NULL);
1344  if (!NT_SUCCESS(Status))
1345  {
1346  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1347  goto nextdevice;
1348  }
1349  swprintf(Level2Name, L"%04lu", DeviceIndex);
1350  RtlInitUnicodeString(&Level2NameU, Level2Name);
1351  InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL);
1352  Status = ZwCreateKey(
1353  &hLevel2Key,
1356  0,
1357  NULL,
1359  NULL);
1360  ZwClose(hLevel1Key);
1361  if (!NT_SUCCESS(Status))
1362  {
1363  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1364  goto nextdevice;
1365  }
1366  DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
1367  Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
1368  if (!NT_SUCCESS(Status))
1369  {
1370  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1371  ZwDeleteKey(hLevel2Key);
1372  goto nextdevice;
1373  }
1374  /* Create 'LogConf' subkey */
1376  Status = ZwCreateKey(
1377  &hLogConf,
1378  KEY_SET_VALUE,
1380  0,
1381  NULL,
1383  NULL);
1384  if (!NT_SUCCESS(Status))
1385  {
1386  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1387  ZwDeleteKey(hLevel2Key);
1388  goto nextdevice;
1389  }
1390  if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1391  {
1392  CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
1393  if (!CmResourceList)
1394  {
1395  ZwClose(hLogConf);
1396  ZwDeleteKey(hLevel2Key);
1397  goto nextdevice;
1398  }
1399 
1400  /* Add the list count (1st member of CM_RESOURCE_LIST) */
1401  ListCount = 1;
1402  RtlCopyMemory(CmResourceList,
1403  &ListCount,
1404  sizeof(ULONG));
1405 
1406  /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
1407  RtlCopyMemory(CmResourceList + sizeof(ULONG),
1408  BootResources,
1409  BootResourcesLength);
1410 
1411  /* Save boot resources to 'LogConf\BootConfig' */
1412  Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
1413  if (!NT_SUCCESS(Status))
1414  {
1415  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1416  ZwClose(hLogConf);
1417  ZwDeleteKey(hLevel2Key);
1418  goto nextdevice;
1419  }
1420  }
1421  ZwClose(hLogConf);
1422 
1423 nextdevice:
1424  if (BootResources && BootResources != ParentBootResources)
1425  {
1426  ExFreePool(BootResources);
1427  BootResources = NULL;
1428  }
1429  if (hLevel2Key)
1430  {
1431  ZwClose(hLevel2Key);
1432  hLevel2Key = NULL;
1433  }
1434  if (hDeviceKey)
1435  {
1436  ZwClose(hDeviceKey);
1437  hDeviceKey = NULL;
1438  }
1439  }
1440 
1442 
1443 cleanup:
1444  if (hDevicesKey && hDevicesKey != hBaseKey)
1445  ZwClose(hDevicesKey);
1446  if (hDeviceKey)
1447  ZwClose(hDeviceKey);
1448  if (pDeviceInformation)
1449  ExFreePool(pDeviceInformation);
1450  if (pValueInformation)
1451  ExFreePool(pValueInformation);
1452  return Status;
1453 }
1454 
1455 static
1456 INIT_FUNCTION
1457 BOOLEAN
1459 {
1460  UNICODE_STRING KeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CURRENTCONTROLSET\\Control\\Pnp");
1461  UNICODE_STRING KeyNameU = RTL_CONSTANT_STRING(L"DisableFirmwareMapper");
1463  HANDLE hPnpKey;
1464  PKEY_VALUE_PARTIAL_INFORMATION KeyInformation;
1465  ULONG DesiredLength, Length;
1466  ULONG KeyValue = 0;
1467  NTSTATUS Status;
1468 
1470  Status = ZwOpenKey(&hPnpKey, KEY_QUERY_VALUE, &ObjectAttributes);
1471  if (NT_SUCCESS(Status))
1472  {
1473  Status = ZwQueryValueKey(hPnpKey,
1474  &KeyNameU,
1476  NULL,
1477  0,
1478  &DesiredLength);
1479  if ((Status == STATUS_BUFFER_TOO_SMALL) ||
1481  {
1482  Length = DesiredLength;
1483  KeyInformation = ExAllocatePool(PagedPool, Length);
1484  if (KeyInformation)
1485  {
1486  Status = ZwQueryValueKey(hPnpKey,
1487  &KeyNameU,
1489  KeyInformation,
1490  Length,
1491  &DesiredLength);
1492  if (NT_SUCCESS(Status) && KeyInformation->DataLength == sizeof(ULONG))
1493  {
1494  KeyValue = (ULONG)(*KeyInformation->Data);
1495  }
1496  else
1497  {
1498  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU);
1499  }
1500 
1501  ExFreePool(KeyInformation);
1502  }
1503  else
1504  {
1505  DPRINT1("Failed to allocate memory for registry query\n");
1506  }
1507  }
1508  else
1509  {
1510  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status);
1511  }
1512 
1513  ZwClose(hPnpKey);
1514  }
1515  else
1516  {
1517  DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status);
1518  }
1519 
1520  DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled");
1521 
1522  return (KeyValue != 0) ? TRUE : FALSE;
1523 }
1524 
1525 INIT_FUNCTION
1526 NTSTATUS
1527 NTAPI
1529 {
1530  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
1531  UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"Root");
1532  UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
1534  HANDLE hEnum, hRoot;
1535  NTSTATUS Status;
1536 
1539  if (!NT_SUCCESS(Status))
1540  {
1541  DPRINT1("ZwCreateKey() failed with status 0x%08lx\n", Status);
1542  return Status;
1543  }
1544 
1547  ZwClose(hEnum);
1548  if (!NT_SUCCESS(Status))
1549  {
1550  DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
1551  return Status;
1552  }
1553 
1555  {
1556  Status = IopOpenRegistryKeyEx(&hEnum, NULL, &MultiKeyPathU, KEY_ENUMERATE_SUB_KEYS);
1557  if (!NT_SUCCESS(Status))
1558  {
1559  /* Nothing to do, don't return with an error status */
1560  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1561  ZwClose(hRoot);
1562  return STATUS_SUCCESS;
1563  }
1565  hEnum,
1566  NULL,
1567  hRoot,
1568  TRUE,
1569  NULL,
1570  0);
1571  ZwClose(hEnum);
1572  }
1573  else
1574  {
1575  /* Enumeration is disabled */
1577  }
1578 
1579  ZwClose(hRoot);
1580 
1581  return Status;
1582 }
1583 
1584 NTSTATUS
1585 NTAPI
1587  HANDLE ParentKey,
1590 {
1592  NTSTATUS Status;
1593 
1594  PAGED_CODE();
1595 
1596  *KeyHandle = NULL;
1597 
1599  Name,
1601  ParentKey,
1602  NULL);
1603 
1605 
1606  return Status;
1607 }
1608 
1609 NTSTATUS
1610 NTAPI
1612  IN HANDLE RootHandle OPTIONAL,
1617 {
1619  ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
1620  USHORT Length;
1621  HANDLE HandleArray[2];
1622  BOOLEAN Recursing = TRUE;
1623  PWCHAR pp, p, p1;
1624  UNICODE_STRING KeyString;
1626  PAGED_CODE();
1627 
1628  /* P1 is start, pp is end */
1629  p1 = KeyName->Buffer;
1630  pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
1631 
1632  /* Create the target key */
1634  KeyName,
1636  RootHandle,
1637  NULL);
1638  Status = ZwCreateKey(&HandleArray[i],
1639  DesiredAccess,
1641  0,
1642  NULL,
1643  CreateOptions,
1644  &KeyDisposition);
1645 
1646  /* Now we check if this failed */
1647  if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
1648  {
1649  /* Target key failed, so we'll need to create its parent. Setup array */
1650  HandleArray[0] = NULL;
1651  HandleArray[1] = RootHandle;
1652 
1653  /* Keep recursing for each missing parent */
1654  while (Recursing)
1655  {
1656  /* And if we're deep enough, close the last handle */
1657  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1658 
1659  /* We're setup to ping-pong between the two handle array entries */
1660  RootHandleIndex = i;
1661  i = (i + 1) & 1;
1662 
1663  /* Clear the one we're attempting to open now */
1664  HandleArray[i] = NULL;
1665 
1666  /* Process the parent key name */
1667  for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
1668  Length = (USHORT)(p - p1) * sizeof(WCHAR);
1669 
1670  /* Is there a parent name? */
1671  if (Length)
1672  {
1673  /* Build the unicode string for it */
1674  KeyString.Buffer = p1;
1675  KeyString.Length = KeyString.MaximumLength = Length;
1676 
1677  /* Now try opening the parent */
1679  &KeyString,
1681  HandleArray[RootHandleIndex],
1682  NULL);
1683  Status = ZwCreateKey(&HandleArray[i],
1684  DesiredAccess,
1686  0,
1687  NULL,
1688  CreateOptions,
1689  &KeyDisposition);
1690  if (NT_SUCCESS(Status))
1691  {
1692  /* It worked, we have one more handle */
1693  NestedCloseLevel++;
1694  }
1695  else
1696  {
1697  /* Parent key creation failed, abandon loop */
1698  Recursing = FALSE;
1699  continue;
1700  }
1701  }
1702  else
1703  {
1704  /* We don't have a parent name, probably corrupted key name */
1706  Recursing = FALSE;
1707  continue;
1708  }
1709 
1710  /* Now see if there's more parents to create */
1711  p1 = p + 1;
1712  if ((p == pp) || (p1 == pp))
1713  {
1714  /* We're done, hopefully successfully, so stop */
1715  Recursing = FALSE;
1716  }
1717  }
1718 
1719  /* Outer loop check for handle nesting that requires closing the top handle */
1720  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1721  }
1722 
1723  /* Check if we broke out of the loop due to success */
1724  if (NT_SUCCESS(Status))
1725  {
1726  /* Return the target handle (we closed all the parent ones) and disposition */
1727  *Handle = HandleArray[i];
1728  if (Disposition) *Disposition = KeyDisposition;
1729  }
1730 
1731  /* Return the success state */
1732  return Status;
1733 }
1734 
1735 NTSTATUS
1736 NTAPI
1738  IN PWSTR ValueName,
1740 {
1741  UNICODE_STRING ValueString;
1742  NTSTATUS Status;
1743  PKEY_VALUE_FULL_INFORMATION FullInformation;
1744  ULONG Size;
1745  PAGED_CODE();
1746 
1747  RtlInitUnicodeString(&ValueString, ValueName);
1748 
1749  Status = ZwQueryValueKey(Handle,
1750  &ValueString,
1752  NULL,
1753  0,
1754  &Size);
1755  if ((Status != STATUS_BUFFER_OVERFLOW) &&
1757  {
1758  return Status;
1759  }
1760 
1761  FullInformation = ExAllocatePool(NonPagedPool, Size);
1762  if (!FullInformation) return STATUS_INSUFFICIENT_RESOURCES;
1763 
1764  Status = ZwQueryValueKey(Handle,
1765  &ValueString,
1767  FullInformation,
1768  Size,
1769  &Size);
1770  if (!NT_SUCCESS(Status))
1771  {
1772  ExFreePool(FullInformation);
1773  return Status;
1774  }
1775 
1776  *Information = FullInformation;
1777  return STATUS_SUCCESS;
1778 }
1779 
1781 NTAPI
1785 {
1786  /* FIXME: TODO */
1787  ASSERT(FALSE);
1788  return 0;
1789 }
1790 
1791 //
1792 // The allocation function is called by the generic table package whenever
1793 // it needs to allocate memory for the table.
1794 //
1795 
1796 PVOID
1797 NTAPI
1799  IN CLONG ByteSize)
1800 {
1801  /* FIXME: TODO */
1802  ASSERT(FALSE);
1803  return NULL;
1804 }
1805 
1806 VOID
1807 NTAPI
1809  IN PVOID Buffer)
1810 {
1811  /* FIXME: TODO */
1812  ASSERT(FALSE);
1813 }
1814 
1815 VOID
1816 NTAPI
1818 {
1819  /* Setup the guarded mutex and AVL table */
1826  NULL);
1827 }
1828 
1829 BOOLEAN
1830 NTAPI
1832 {
1833  /* Initialize the resource when accessing device registry data */
1835 
1836  /* Setup the device reference AVL table */
1838  return TRUE;
1839 }
1840 
1841 BOOLEAN
1842 NTAPI
1844 {
1845  /* Check the initialization phase */
1846  switch (ExpInitializationPhase)
1847  {
1848  case 0:
1849 
1850  /* Do Phase 0 */
1851  return PiInitPhase0();
1852 
1853  case 1:
1854 
1855  /* Do Phase 1 */
1856  return TRUE;
1857  //return PiInitPhase1();
1858 
1859  default:
1860 
1861  /* Don't know any other phase! Bugcheck! */
1862  KeBugCheck(UNEXPECTED_INITIALIZATION_CALL);
1863  return FALSE;
1864  }
1865 }
1866 
1867 /* PUBLIC FUNCTIONS **********************************************************/
1868 
1869 NTSTATUS
1870 NTAPI
1872  IN LPGUID BusTypeGuid)
1873 {
1875 
1876  /* Acquire the lock */
1878 
1879  /* Validate size */
1880  if (Index < PnpBusTypeGuidList->GuidCount)
1881  {
1882  /* Copy the data */
1883  RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID));
1884  }
1885  else
1886  {
1887  /* Failure path */
1889  }
1890 
1891  /* Release lock and return status */
1893  return Status;
1894 }
1895 
1896 NTSTATUS
1897 NTAPI
1899  IN PHANDLE DeviceInstanceHandle,
1901 {
1902  NTSTATUS Status;
1903  HANDLE KeyHandle;
1905  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
1906  PAGED_CODE();
1907 
1908  /* Open the enum key */
1910  NULL,
1911  &KeyName,
1912  KEY_READ);
1913  if (!NT_SUCCESS(Status)) return Status;
1914 
1915  /* Make sure we have an instance path */
1917  if ((DeviceNode) && (DeviceNode->InstancePath.Length))
1918  {
1919  /* Get the instance key */
1920  Status = IopOpenRegistryKeyEx(DeviceInstanceHandle,
1921  KeyHandle,
1922  &DeviceNode->InstancePath,
1923  DesiredAccess);
1924  }
1925  else
1926  {
1927  /* Fail */
1929  }
1930 
1931  /* Close the handle and return status */
1932  ZwClose(KeyHandle);
1933  return Status;
1934 }
1935 
1936 ULONG
1937 NTAPI
1939 {
1940  ULONG FinalSize, PartialSize, EntrySize, i, j;
1941  PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
1942  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1943 
1944  /* If we don't have one, that's easy */
1945  if (!ResourceList) return 0;
1946 
1947  /* Start with the minimum size possible */
1948  FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
1949 
1950  /* Loop each full descriptor */
1951  FullDescriptor = ResourceList->List;
1952  for (i = 0; i < ResourceList->Count; i++)
1953  {
1954  /* Start with the minimum size possible */
1955  PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
1956  FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
1957 
1958  /* Loop each partial descriptor */
1959  PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
1960  for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
1961  {
1962  /* Start with the minimum size possible */
1964 
1965  /* Check if there is extra data */
1966  if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
1967  {
1968  /* Add that data */
1969  EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize;
1970  }
1971 
1972  /* The size of partial descriptors is bigger */
1973  PartialSize += EntrySize;
1974 
1975  /* Go to the next partial descriptor */
1976  PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize);
1977  }
1978 
1979  /* The size of full descriptors is bigger */
1980  FinalSize += PartialSize;
1981 
1982  /* Go to the next full descriptor */
1983  FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize);
1984  }
1985 
1986  /* Return the final size */
1987  return FinalSize;
1988 }
1989 
1990 NTSTATUS
1991 NTAPI
1993  IN ULONG ValueType,
1994  IN PWSTR ValueName,
1995  IN PWSTR KeyName,
1996  OUT PVOID Buffer,
1998 {
1999  NTSTATUS Status;
2000  HANDLE KeyHandle, SubHandle;
2001  UNICODE_STRING KeyString;
2002  PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
2003  ULONG Length;
2004  PAGED_CODE();
2005 
2006  /* Find the instance key */
2008  if (NT_SUCCESS(Status))
2009  {
2010  /* Check for name given by caller */
2011  if (KeyName)
2012  {
2013  /* Open this key */
2014  RtlInitUnicodeString(&KeyString, KeyName);
2015  Status = IopOpenRegistryKeyEx(&SubHandle,
2016  KeyHandle,
2017  &KeyString,
2018  KEY_READ);
2019  if (NT_SUCCESS(Status))
2020  {
2021  /* And use this handle instead */
2022  ZwClose(KeyHandle);
2023  KeyHandle = SubHandle;
2024  }
2025  }
2026 
2027  /* Check if sub-key handle succeeded (or no-op if no key name given) */
2028  if (NT_SUCCESS(Status))
2029  {
2030  /* Now get the size of the property */
2032  ValueName,
2033  &KeyValueInfo);
2034  }
2035 
2036  /* Close the key */
2037  ZwClose(KeyHandle);
2038  }
2039 
2040  /* Fail if any of the registry operations failed */
2041  if (!NT_SUCCESS(Status)) return Status;
2042 
2043  /* Check how much data we have to copy */
2044  Length = KeyValueInfo->DataLength;
2045  if (*BufferLength >= Length)
2046  {
2047  /* Check for a match in the value type */
2048  if (KeyValueInfo->Type == ValueType)
2049  {
2050  /* Copy the data */
2052  (PVOID)((ULONG_PTR)KeyValueInfo +
2053  KeyValueInfo->DataOffset),
2054  Length);
2055  }
2056  else
2057  {
2058  /* Invalid registry property type, fail */
2060  }
2061  }
2062  else
2063  {
2064  /* Buffer is too small to hold data */
2066  }
2067 
2068  /* Return the required buffer length, free the buffer, and return status */
2069  *BufferLength = Length;
2070  ExFreePool(KeyValueInfo);
2071  return Status;
2072 }
2073 
2074 #define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;}
2075 #define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;}
2076 #define PIP_UNIMPLEMENTED() {UNIMPLEMENTED_DBGBREAK(); break;}
2077 
2078 /*
2079  * @implemented
2080  */
2081 NTSTATUS
2082 NTAPI
2086  OUT PVOID PropertyBuffer,
2088 {
2090  DEVICE_CAPABILITIES DeviceCaps;
2091  ULONG ReturnLength = 0, Length = 0, ValueType;
2092  PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
2093  PVOID Data = NULL;
2095  GUID BusTypeGuid;
2096  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
2097  BOOLEAN NullTerminate = FALSE;
2098  DEVICE_REMOVAL_POLICY Policy;
2099 
2100  DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
2101 
2102  /* Assume failure */
2103  *ResultLength = 0;
2104 
2105  /* Only PDOs can call this */
2107 
2108  /* Handle all properties */
2109  switch (DeviceProperty)
2110  {
2112 
2113  /* Get the GUID from the internal cache */
2114  Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
2115  if (!NT_SUCCESS(Status)) return Status;
2116 
2117  /* This is the format of the returned data */
2118  PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
2119 
2121 
2122  /* Validate correct interface type */
2123  if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
2125 
2126  /* This is the format of the returned data */
2127  PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
2128 
2130 
2131  /* Validate correct bus number */
2132  if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
2134 
2135  /* This is the format of the returned data */
2136  PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
2137 
2139 
2140  /* Get the instance path */
2141  DeviceInstanceName = DeviceNode->InstancePath.Buffer;
2142 
2143  /* Sanity checks */
2144  ASSERT((BufferLength & 1) == 0);
2145  ASSERT(DeviceInstanceName != NULL);
2146 
2147  /* Get the name from the path */
2148  EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
2149  ASSERT(EnumeratorNameEnd);
2150 
2151  /* This string needs to be NULL-terminated */
2152  NullTerminate = TRUE;
2153 
2154  /* This is the format of the returned data */
2155  PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
2156  DeviceInstanceName);
2157 
2158  case DevicePropertyAddress:
2159 
2160  /* Query the device caps */
2162  if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
2164 
2165  /* This is the format of the returned data */
2166  PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
2167 
2169 
2170  /* Validate we have resources */
2171  if (!DeviceNode->BootResources)
2172 // if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
2173  {
2174  /* No resources will still fake success, but with 0 bytes */
2175  *ResultLength = 0;
2176  return STATUS_SUCCESS;
2177  }
2178 
2179  /* This is the format of the returned data */
2180  PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
2181  DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
2182 
2184 
2185  /* Sanity check for Unicode-sized string */
2186  ASSERT((BufferLength & 1) == 0);
2187 
2188  /* Allocate name buffer */
2190  ObjectNameInfo = ExAllocatePool(PagedPool, Length);
2191  if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
2192 
2193  /* Query the PDO name */
2195  ObjectNameInfo,
2196  Length,
2197  ResultLength);
2199  {
2200  /* It's up to the caller to try again */
2202  }
2203 
2204  /* This string needs to be NULL-terminated */
2205  NullTerminate = TRUE;
2206 
2207  /* Return if successful */
2208  if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
2209  ObjectNameInfo->Name.Buffer);
2210 
2211  /* Let the caller know how big the name is */
2213  break;
2214 
2216 
2217  Policy = DeviceNode->RemovalPolicy;
2218  PIP_RETURN_DATA(sizeof(Policy), &Policy);
2219 
2220  /* Handle the registry-based properties */
2244  //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
2246  break;
2249  break;
2254  default:
2256  }
2257 
2258  /* Having a registry value name implies registry data */
2259  if (ValueName)
2260  {
2261  /* We know up-front how much data to expect */
2263 
2264  /* Go get the data, use the LogConf subkey if necessary */
2266  ValueType,
2267  ValueName,
2268  (DeviceProperty ==
2270  L"LogConf": NULL,
2271  PropertyBuffer,
2272  ResultLength);
2273  }
2274  else if (NT_SUCCESS(Status))
2275  {
2276  /* We know up-front how much data to expect, check the caller's buffer */
2277  *ResultLength = ReturnLength + (NullTerminate ? sizeof(UNICODE_NULL) : 0);
2278  if (*ResultLength <= BufferLength)
2279  {
2280  /* Buffer is all good, copy the data */
2281  RtlCopyMemory(PropertyBuffer, Data, ReturnLength);
2282 
2283  /* Check if we need to NULL-terminate the string */
2284  if (NullTerminate)
2285  {
2286  /* Terminate the string */
2287  ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL;
2288  }
2289 
2290  /* This is the success path */
2292  }
2293  else
2294  {
2295  /* Failure path */
2297  }
2298  }
2299 
2300  /* Free any allocation we may have made, and return the status code */
2301  if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
2302  return Status;
2303 }
2304 
2320 NTSTATUS
2321 NTAPI
2326 {
2327  static WCHAR RootKeyName[] =
2328  L"\\Registry\\Machine\\System\\CurrentControlSet\\";
2329  static WCHAR ProfileKeyName[] =
2330  L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
2331  static WCHAR ClassKeyName[] = L"Control\\Class\\";
2332  static WCHAR EnumKeyName[] = L"Enum\\";
2333  static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
2335  PWSTR KeyNameBuffer;
2337  ULONG DriverKeyLength;
2340  NTSTATUS Status;
2341 
2342  DPRINT("IoOpenDeviceRegistryKey() called\n");
2343 
2345  {
2346  DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
2347  return STATUS_INVALID_PARAMETER;
2348  }
2349 
2353 
2354  /*
2355  * Calculate the length of the base key name. This is the full
2356  * name for driver key or the name excluding "Device Parameters"
2357  * subkey for device key.
2358  */
2359 
2360  KeyNameLength = sizeof(RootKeyName);
2362  KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
2364  {
2365  KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
2367  0, NULL, &DriverKeyLength);
2369  return Status;
2370  KeyNameLength += DriverKeyLength;
2371  }
2372  else
2373  {
2374  KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
2375  DeviceNode->InstancePath.Length;
2376  }
2377 
2378  /*
2379  * Now allocate the buffer for the key name...
2380  */
2381 
2382  KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
2383  if (KeyNameBuffer == NULL)
2385 
2386  KeyName.Length = 0;
2387  KeyName.MaximumLength = (USHORT)KeyNameLength;
2388  KeyName.Buffer = KeyNameBuffer;
2389 
2390  /*
2391  * ...and build the key name.
2392  */
2393 
2394  KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
2395  RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
2396 
2398  RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
2399 
2401  {
2402  RtlAppendUnicodeToString(&KeyName, ClassKeyName);
2404  DriverKeyLength, KeyNameBuffer +
2405  (KeyName.Length / sizeof(WCHAR)),
2406  &DriverKeyLength);
2407  if (!NT_SUCCESS(Status))
2408  {
2409  DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
2410  ExFreePool(KeyNameBuffer);
2411  return Status;
2412  }
2413  KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
2414  }
2415  else
2416  {
2417  RtlAppendUnicodeToString(&KeyName, EnumKeyName);
2419  if (DeviceNode->InstancePath.Length == 0)
2420  {
2421  ExFreePool(KeyNameBuffer);
2422  return Status;
2423  }
2424  }
2425 
2426  /*
2427  * Open the base key.
2428  */
2430  if (!NT_SUCCESS(Status))
2431  {
2432  DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
2433  ExFreePool(KeyNameBuffer);
2434  return Status;
2435  }
2436  ExFreePool(KeyNameBuffer);
2437 
2438  /*
2439  * For driver key we're done now.
2440  */
2441 
2443  return Status;
2444 
2445  /*
2446  * Let's go further. For device key we must open "Device Parameters"
2447  * subkey and create it if it doesn't exist yet.
2448  */
2449 
2450  RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
2452  &KeyName,
2454  *DevInstRegKey,
2455  NULL);
2456  Status = ZwCreateKey(DevInstRegKey,
2457  DesiredAccess,
2459  0,
2460  NULL,
2462  NULL);
2463  ZwClose(ObjectAttributes.RootDirectory);
2464 
2465  return Status;
2466 }
2467 
2468 /*
2469  * @implemented
2470  */
2471 VOID
2472 NTAPI
2476 {
2477  DEVICE_ACTION_DATA ActionData;
2478 
2479  ActionData.DeviceObject = DeviceObject;
2481  ActionData.InvalidateDeviceRelations.Type = Type;
2482 
2483  IopQueueDeviceAction(&ActionData);
2484 }
2485 
2486 /*
2487  * @implemented
2488  */
2489 NTSTATUS
2490 NTAPI
2494 {
2495  PAGED_CODE();
2496 
2497  switch (Type)
2498  {
2499  case BusRelations:
2500  /* Enumerate the device */
2502  case PowerRelations:
2503  /* Not handled yet */
2504  return STATUS_NOT_IMPLEMENTED;
2505  case TargetDeviceRelation:
2506  /* Nothing to do */
2507  return STATUS_SUCCESS;
2508  default:
2509  /* Ejection relations are not supported */
2510  return STATUS_NOT_SUPPORTED;
2511  }
2512 }
2513 
2514 /*
2515  * @implemented
2516  */
2517 BOOLEAN
2518 NTAPI
2520  IN ULONG BusNumber,
2524 {
2525  /* FIXME: Notify the resource arbiter */
2526 
2527  return HalTranslateBusAddress(InterfaceType,
2528  BusNumber,
2529  BusAddress,
2530  AddressSpace,
2532 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2491
DEVICE_REGISTRY_PROPERTY
Definition: iotypes.h:1154
KGUARDED_MUTEX PpDeviceReferenceTableLock
Definition: pnpmgr.c:19
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
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define REGSTR_VAL_CLASS
Definition: regstr.h:291
VOID IopQueueDeviceAction(_In_ PDEVICE_ACTION_DATA ActionData)
Definition: devaction.c:2341
GUID Guids[1]
Definition: io.h:440
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
const uint16_t * PCWSTR
Definition: typedefs.h:56
#define IN
Definition: typedefs.h:39
RTL_AVL_COMPARE_ROUTINE * PRTL_AVL_COMPARE_ROUTINE
Definition: rtltypes.h:381
ASMGENDATA Table[]
Definition: genincdata.c:61
#define REGSTR_VAL_DRIVER
Definition: regstr.h:385
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:548
VOID NTAPI PiFreeGenericTableEntry(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: pnpmgr.c:1808
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
enum _INTERFACE_TYPE INTERFACE_TYPE
#define TAG_IO
Definition: tag.h:69
static INIT_FUNCTION BOOLEAN IopIsFirmwareMapperDisabled(VOID)
Definition: pnpmgr.c:1458
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
Type
Definition: Type.h:6
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList
Definition: pnpmgr.c:27
#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
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32 __fastcall crc32(IN uint8 *s, IN uint32 len)
Definition: udf_info.cpp:4290
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2738
_In_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
#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:1586
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
uint16_t * PWSTR
Definition: typedefs.h:55
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1123
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:661
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4062
VOID NTAPI IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:45
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI PnpBusTypeGuidGet(IN USHORT Index, IN LPGUID BusTypeGuid)
Definition: pnpmgr.c:1871
INIT_FUNCTION NTSTATUS NTAPI IopUpdateRootKey(VOID)
Definition: pnpmgr.c:1528
LONG NTSTATUS
Definition: precomp.h:26
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
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:1798
DEVICE_CAPABILITIES
Definition: iotypes.h:928
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static WCHAR String[]
Definition: stringtable.c:55
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
uint16_t * PWCHAR
Definition: typedefs.h:55
WCHAR DeviceName[]
Definition: adapter.cpp:21
#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
DEVICE_ACTION Action
Definition: io.h:554
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:1737
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
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:462
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:1992
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define REGSTR_VAL_COMPATIBLEIDS
Definition: regstr.h:296
UCHAR KIRQL
Definition: env_spec_w32.h:591
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
ULONG CLONG
Definition: umtypes.h:126
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
Definition: Header.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#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:1831
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
NTSTATUS FASTCALL IopInitializeDevice(PDEVICE_NODE DeviceNode, PDRIVER_OBJECT DriverObject)
Definition: pnpmgr.c:394
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#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
smooth NULL
Definition: ftsmooth.c:416
ERESOURCE PpRegistryDeviceResource
Definition: pnpmgr.c:18
RTL_AVL_TABLE PpDeviceReferenceTable
Definition: pnpmgr.c:20
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:2083
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:2076
void * PVOID
Definition: retypes.h:9
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
USHORT NTAPI IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
Definition: pnpmgr.c:480
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
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
#define DNF_STARTED
Definition: iotypes.h:168
NTSTATUS IopEnumerateDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:2054
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
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_In_ HANDLE Handle
Definition: extypes.h:390
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:745
NTSTATUS NTAPI PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1898
_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:379
LIST_ENTRY List
Definition: psmgr.c:57
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
#define ENUM_ROOT
Definition: io.h:53
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:899
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
static const UCHAR Index[8]
Definition: usbohci.c:18
struct _IO_BUS_TYPE_GUID_LIST IO_BUS_TYPE_GUID_LIST
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@379::@388 DeviceSpecificData
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define REGSTR_VAL_CLASSGUID
Definition: regstr.h:422
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PDEVICE_NODE PopSystemPowerDeviceNode
Definition: power.c:25
Definition: Node.h:9
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
BOOLEAN NTAPI PpInitSystem(VOID)
Definition: pnpmgr.c:1843
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:2519
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
VOID NTAPI PpInitializeDeviceReferenceTable(VOID)
Definition: pnpmgr.c:1817
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
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:379
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
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@379 u
VOID IopFixupDeviceId(PWCHAR String)
Definition: pnpmgr.c:32
#define DNF_DISABLED
Definition: iotypes.h:188
#define PIP_REGISTRY_DATA(x, y)
Definition: pnpmgr.c:2075
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1938
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
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:618
RTL_AVL_FREE_ROUTINE * PRTL_AVL_FREE_ROUTINE
Definition: rtltypes.h:398
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
_In_ ULONG _In_ ULONG KeyNameLength
Definition: usbdlib.h:195
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:1611
#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
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
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
ULONG_PTR SIZE_T
Definition: typedefs.h:79
struct _DEVICE_ACTION_DATA::@1761::@1763 InvalidateDeviceRelations
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define REGSTR_VAL_MFG
Definition: regstr.h:306
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
struct _GUID GUID
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2473
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSYSAPI ULONG NTAPI RtlComputeCrc32(_In_ ULONG InitialCrc, _In_ PUCHAR Buffer, _In_ ULONG Length)
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
_In_ DEVICE_REGISTRY_PROPERTY DeviceProperty
Definition: iofuncs.h:1003
unsigned short USHORT
Definition: pedump.c:61
#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
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4137
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:300
enum _DEVICE_REMOVAL_POLICY DEVICE_REMOVAL_POLICY
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
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:2322
#define PIP_RETURN_DATA(x, y)
Definition: pnpmgr.c:2074
#define DPRINT1
Definition: precomp.h:8
#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
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
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:28
char * cleanup(char *str)
Definition: wpickclick.c:99
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
RTL_AVL_ALLOCATE_ROUTINE * PRTL_AVL_ALLOCATE_ROUTINE
Definition: rtltypes.h:390
#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
static INIT_FUNCTION 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:1025
GLfloat GLfloat p
Definition: glext.h:8902
#define REGSTR_VAL_BOOTCONFIG
Definition: regstr.h:293
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
ULONG ExpInitializationPhase
Definition: init.c:66
return STATUS_SUCCESS
Definition: btrfs.c:3014
PDEVICE_OBJECT DeviceObject
Definition: io.h:553
#define DNF_ADDED
Definition: iotypes.h:179
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:26
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389
#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:1782
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
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PLUGPLAY_REGKEY_CURRENT_HWPROFILE
Definition: iofuncs.h:2740
UNICODE_STRING DriverName
Definition: iotypes.h:2175
Iosb Information
Definition: create.c:4353
#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