ReactOS  0.4.15-dev-2721-g5912c11
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
395 {
396  KIRQL OldIrql;
397 
399  {
403 
404  return STATUS_SUCCESS;
405  }
406 
407  return STATUS_UNSUCCESSFUL;
408 }
409 
410 USHORT
411 NTAPI
413 {
414  USHORT i = 0, FoundIndex = 0xFFFF;
415  ULONG NewSize;
416  PVOID NewList;
417 
418  /* Acquire the lock */
420 
421  /* Loop all entries */
422  while (i < PnpBusTypeGuidList->GuidCount)
423  {
424  /* Try to find a match */
425  if (RtlCompareMemory(BusTypeGuid,
427  sizeof(GUID)) == sizeof(GUID))
428  {
429  /* Found it */
430  FoundIndex = i;
431  goto Quickie;
432  }
433  i++;
434  }
435 
436  /* Check if we have to grow the list */
438  {
439  /* Calculate the new size */
440  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
441  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
442 
443  /* Allocate the new copy */
444  NewList = ExAllocatePool(PagedPool, NewSize);
445 
446  if (!NewList)
447  {
448  /* Fail */
450  goto Quickie;
451  }
452 
453  /* Now copy them, decrease the size too */
454  NewSize -= sizeof(GUID);
456 
457  /* Free the old list */
459 
460  /* Use the new buffer */
461  PnpBusTypeGuidList = NewList;
462  }
463 
464  /* Copy the new GUID */
466  BusTypeGuid,
467  sizeof(GUID));
468 
469  /* The new entry is the index */
470  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
472 
473 Quickie:
475  return FoundIndex;
476 }
477 
478 NTSTATUS
479 NTAPI
484 {
485  IO_STACK_LOCATION IoStackLocation;
486 
487  /* Fill out the stack information */
488  RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
489  IoStackLocation.MajorFunction = IRP_MJ_PNP;
490  IoStackLocation.MinorFunction = MinorFunction;
491  if (Stack)
492  {
493  /* Copy the rest */
494  RtlCopyMemory(&IoStackLocation.Parameters,
495  &Stack->Parameters,
496  sizeof(Stack->Parameters));
497  }
498 
499  /* Do the PnP call */
501  &IoStackLocation,
503  return IoStatusBlock->Status;
504 }
505 
506 /*
507  * IopCreateDeviceKeyPath
508  *
509  * Creates a registry key
510  *
511  * Parameters
512  * RegistryPath
513  * Name of the key to be created.
514  * Handle
515  * Handle to the newly created key
516  *
517  * Remarks
518  * This method can create nested trees, so parent of RegistryPath can
519  * be not existant, and will be created if needed.
520  */
521 NTSTATUS
522 NTAPI
526 {
528  HANDLE hParent = NULL, hKey;
531  PCWSTR Current, Last;
532  USHORT Length;
534 
535  /* Assume failure */
536  *Handle = NULL;
537 
538  /* Open root key for device instances */
540  if (!NT_SUCCESS(Status))
541  {
542  DPRINT1("ZwOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
543  return Status;
544  }
545 
546  Current = KeyName.Buffer = RegistryPath->Buffer;
547  Last = &RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)];
548 
549  /* Go up to the end of the string */
550  while (Current <= Last)
551  {
552  if (Current != Last && *Current != L'\\')
553  {
554  /* Not the end of the string and not a separator */
555  Current++;
556  continue;
557  }
558 
559  /* Prepare relative key name */
560  Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
561  KeyName.MaximumLength = KeyName.Length = Length;
562  DPRINT("Create '%wZ'\n", &KeyName);
563 
564  /* Open key */
566  &KeyName,
568  hParent,
569  NULL);
570  Status = ZwCreateKey(&hKey,
571  Current == Last ? KEY_ALL_ACCESS : KEY_CREATE_SUB_KEY,
573  0,
574  NULL,
576  NULL);
577 
578  /* Close parent key handle, we don't need it anymore */
579  if (hParent)
580  ZwClose(hParent);
581 
582  /* Key opening/creating failed? */
583  if (!NT_SUCCESS(Status))
584  {
585  DPRINT1("ZwCreateKey('%wZ') failed with status 0x%08lx\n", &KeyName, Status);
586  return Status;
587  }
588 
589  /* Check if it is the end of the string */
590  if (Current == Last)
591  {
592  /* Yes, return success */
593  *Handle = hKey;
594  return STATUS_SUCCESS;
595  }
596 
597  /* Start with this new parent key */
598  hParent = hKey;
599  Current++;
600  KeyName.Buffer = (PWSTR)Current;
601  }
602 
603  return STATUS_UNSUCCESSFUL;
604 }
605 
606 NTSTATUS
609 {
612  HANDLE LogConfKey, ControlKey, DeviceParamsKey;
613  ULONG ResCount;
616 
617  DPRINT("IopSetDeviceInstanceData() called\n");
618 
619  /* Create the 'LogConf' key */
620  RtlInitUnicodeString(&KeyName, L"LogConf");
622  &KeyName,
624  InstanceKey,
625  NULL);
626  Status = ZwCreateKey(&LogConfKey,
629  0,
630  NULL,
631  // FIXME? In r53694 it was silently turned from non-volatile into this,
632  // without any extra warning. Is this still needed??
634  NULL);
635  if (NT_SUCCESS(Status))
636  {
637  /* Set 'BootConfig' value */
638  if (DeviceNode->BootResources != NULL)
639  {
640  ResCount = DeviceNode->BootResources->Count;
641  if (ResCount != 0)
642  {
643  RtlInitUnicodeString(&KeyName, L"BootConfig");
644  Status = ZwSetValueKey(LogConfKey,
645  &KeyName,
646  0,
648  DeviceNode->BootResources,
649  PnpDetermineResourceListSize(DeviceNode->BootResources));
650  }
651  }
652 
653  /* Set 'BasicConfigVector' value */
654  if (DeviceNode->ResourceRequirements != NULL &&
655  DeviceNode->ResourceRequirements->ListSize != 0)
656  {
657  RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
658  Status = ZwSetValueKey(LogConfKey,
659  &KeyName,
660  0,
662  DeviceNode->ResourceRequirements,
663  DeviceNode->ResourceRequirements->ListSize);
664  }
665 
666  ZwClose(LogConfKey);
667  }
668 
669  /* Set the 'ConfigFlags' value */
670  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
671  Status = ZwQueryValueKey(InstanceKey,
672  &KeyName,
674  NULL,
675  0,
676  &ResultLength);
678  {
679  /* Write the default value */
680  ULONG DefaultConfigFlags = 0;
681  Status = ZwSetValueKey(InstanceKey,
682  &KeyName,
683  0,
684  REG_DWORD,
685  &DefaultConfigFlags,
686  sizeof(DefaultConfigFlags));
687  }
688 
689  /* Create the 'Control' key */
690  RtlInitUnicodeString(&KeyName, L"Control");
692  &KeyName,
694  InstanceKey,
695  NULL);
696  Status = ZwCreateKey(&ControlKey,
697  0,
699  0,
700  NULL,
702  NULL);
703  if (NT_SUCCESS(Status))
704  ZwClose(ControlKey);
705 
706  /* Create the 'Device Parameters' key and set the 'FirmwareIdentified' value for all ACPI-enumerated devices */
707  if (_wcsnicmp(DeviceNode->InstancePath.Buffer, L"ACPI\\", 5) == 0)
708  {
709  RtlInitUnicodeString(&KeyName, L"Device Parameters");
711  &KeyName,
713  InstanceKey,
714  NULL);
715  Status = ZwCreateKey(&DeviceParamsKey,
716  0,
718  0,
719  NULL,
721  NULL);
722  if (NT_SUCCESS(Status))
723  {
724  ULONG FirmwareIdentified = 1;
725  RtlInitUnicodeString(&KeyName, L"FirmwareIdentified");
726  Status = ZwSetValueKey(DeviceParamsKey,
727  &KeyName,
728  0,
729  REG_DWORD,
730  &FirmwareIdentified,
731  sizeof(FirmwareIdentified));
732 
733  ZwClose(DeviceParamsKey);
734  }
735  }
736 
737  DPRINT("IopSetDeviceInstanceData() done\n");
738 
739  return Status;
740 }
741 
742 /*
743  * IopGetParentIdPrefix
744  *
745  * Retrieve (or create) a string which identifies a device.
746  *
747  * Parameters
748  * DeviceNode
749  * Pointer to device node.
750  * ParentIdPrefix
751  * Pointer to the string where is returned the parent node identifier
752  *
753  * Remarks
754  * If the return code is STATUS_SUCCESS, the ParentIdPrefix string is
755  * valid and its Buffer field is NULL-terminated. The caller needs to
756  * to free the string with RtlFreeUnicodeString when it is no longer
757  * needed.
758  */
759 
760 NTSTATUS
762  PUNICODE_STRING ParentIdPrefix)
763 {
764  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
765  ULONG KeyNameBufferLength;
766  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
767  UNICODE_STRING KeyName = {0, 0, NULL};
768  UNICODE_STRING KeyValue;
770  HANDLE hKey = NULL;
771  ULONG crc32;
773 
774  /* HACK: As long as some devices have a NULL device
775  * instance path, the following test is required :(
776  */
777  if (DeviceNode->Parent->InstancePath.Length == 0)
778  {
779  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
780  &DeviceNode->InstancePath);
781  return STATUS_UNSUCCESSFUL;
782  }
783 
784  /* 1. Try to retrieve ParentIdPrefix from registry */
785  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
786  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
787  KeyNameBufferLength + sizeof(UNICODE_NULL),
788  TAG_IO);
789  if (!ParentIdPrefixInformation)
790  {
792  }
793 
794  KeyName.Length = 0;
795  KeyName.MaximumLength = EnumKeyPath.Length +
796  DeviceNode->Parent->InstancePath.Length +
797  sizeof(UNICODE_NULL);
799  KeyName.MaximumLength,
800  TAG_IO);
801  if (!KeyName.Buffer)
802  {
804  goto cleanup;
805  }
806 
807  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
808  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
809 
811  if (!NT_SUCCESS(Status))
812  {
813  goto cleanup;
814  }
815  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
816  Status = ZwQueryValueKey(hKey,
817  &ValueName,
819  ParentIdPrefixInformation,
820  KeyNameBufferLength,
821  &KeyNameBufferLength);
822  if (NT_SUCCESS(Status))
823  {
824  if (ParentIdPrefixInformation->Type != REG_SZ)
825  {
827  }
828  else
829  {
830  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
831  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
832  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
833  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
834  }
835  goto cleanup;
836  }
838  {
839  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
840  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
841  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
842  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
843  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
844  goto cleanup;
845  }
846 
847  /* 2. Create the ParentIdPrefix value */
849  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
850  DeviceNode->Parent->InstancePath.Length);
851 
852  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
853  KeyNameBufferLength,
854  L"%lx&%lx",
855  DeviceNode->Parent->Level,
856  crc32);
857  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
858 
859  /* 3. Try to write the ParentIdPrefix to registry */
860  Status = ZwSetValueKey(hKey,
861  &ValueName,
862  0,
863  REG_SZ,
864  KeyValue.Buffer,
865  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
866 
867 cleanup:
868  if (NT_SUCCESS(Status))
869  {
870  /* Duplicate the string to return it */
872  &KeyValue,
873  ParentIdPrefix);
874  }
875  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
877  if (hKey != NULL)
878  {
879  ZwClose(hKey);
880  }
881  return Status;
882 }
883 
884 static
885 CODE_SEG("INIT")
886 NTSTATUS
888  IN HANDLE hBaseKey,
889  IN PUNICODE_STRING RelativePath OPTIONAL,
890  IN HANDLE hRootKey,
891  IN BOOLEAN EnumerateSubKeys,
892  IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources,
893  IN ULONG ParentBootResourcesLength)
894 {
895  UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
896  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
897  UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
898  UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
899  UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
901  HANDLE hDevicesKey = NULL;
902  HANDLE hDeviceKey = NULL;
903  HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
904  UNICODE_STRING Level2NameU;
905  WCHAR Level2Name[5];
906  ULONG IndexDevice = 0;
907  ULONG IndexSubKey;
908  PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
909  ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
910  PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
911  ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
914  PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
915  ULONG BootResourcesLength;
917 
918  const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
919  UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
920  static ULONG DeviceIndexSerial = 0;
921  const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
922  UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
923  static ULONG DeviceIndexKeyboard = 0;
924  const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
925  /* FIXME: IopEnumerateDetectedDevices() should be rewritten.
926  * The PnP identifiers can either be hardcoded or parsed from a LegacyXlate
927  * sections of driver INF files.
928  */
929 #if defined(SARCH_PC98)
930  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*nEC1F00\0");
931 #else
932  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
933 #endif
934  static ULONG DeviceIndexMouse = 0;
935  const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"ParallelController");
936  UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
937  static ULONG DeviceIndexParallel = 0;
938  const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
939  UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
940  static ULONG DeviceIndexFloppy = 0;
941  UNICODE_STRING HardwareIdKey;
942  PUNICODE_STRING pHardwareId;
943  ULONG DeviceIndex = 0;
944  PUCHAR CmResourceList;
945  ULONG ListCount;
946 
947  if (RelativePath)
948  {
949  Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS);
950  if (!NT_SUCCESS(Status))
951  {
952  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
953  goto cleanup;
954  }
955  }
956  else
957  hDevicesKey = hBaseKey;
958 
959  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
960  if (!pDeviceInformation)
961  {
962  DPRINT("ExAllocatePool() failed\n");
964  goto cleanup;
965  }
966 
967  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
968  if (!pValueInformation)
969  {
970  DPRINT("ExAllocatePool() failed\n");
972  goto cleanup;
973  }
974 
975  while (TRUE)
976  {
977  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
979  break;
981  {
982  ExFreePool(pDeviceInformation);
983  DeviceInfoLength = RequiredSize;
984  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
985  if (!pDeviceInformation)
986  {
987  DPRINT("ExAllocatePool() failed\n");
989  goto cleanup;
990  }
991  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
992  }
993  if (!NT_SUCCESS(Status))
994  {
995  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
996  goto cleanup;
997  }
998  IndexDevice++;
999 
1000  /* Open device key */
1001  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1002  DeviceName.Buffer = pDeviceInformation->Name;
1003 
1004  Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
1005  KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
1006  if (!NT_SUCCESS(Status))
1007  {
1008  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1009  goto cleanup;
1010  }
1011 
1012  /* Read boot resources, and add then to parent ones */
1013  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1015  {
1016  ExFreePool(pValueInformation);
1017  ValueInfoLength = RequiredSize;
1018  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1019  if (!pValueInformation)
1020  {
1021  DPRINT("ExAllocatePool() failed\n");
1022  ZwDeleteKey(hLevel2Key);
1024  goto cleanup;
1025  }
1026  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1027  }
1029  {
1030  BootResources = ParentBootResources;
1031  BootResourcesLength = ParentBootResourcesLength;
1032  }
1033  else if (!NT_SUCCESS(Status))
1034  {
1035  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1036  goto nextdevice;
1037  }
1038  else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
1039  {
1040  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
1041  goto nextdevice;
1042  }
1043  else
1044  {
1045  static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
1046 
1047  /* Concatenate current resources and parent ones */
1048  if (ParentBootResourcesLength == 0)
1049  BootResourcesLength = pValueInformation->DataLength;
1050  else
1051  BootResourcesLength = ParentBootResourcesLength
1052  + pValueInformation->DataLength
1053  - Header;
1054  BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
1055  if (!BootResources)
1056  {
1057  DPRINT("ExAllocatePool() failed\n");
1058  goto nextdevice;
1059  }
1060  if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1061  {
1062  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1063  }
1064  else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
1065  {
1066  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
1067  RtlCopyMemory(
1068  (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
1069  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1070  ParentBootResourcesLength - Header);
1071  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1072  }
1073  else
1074  {
1075  RtlCopyMemory(BootResources, pValueInformation->Data, Header);
1076  RtlCopyMemory(
1077  (PVOID)((ULONG_PTR)BootResources + Header),
1078  (PVOID)((ULONG_PTR)ParentBootResources + Header),
1079  ParentBootResourcesLength - Header);
1080  RtlCopyMemory(
1081  (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
1082  pValueInformation->Data + Header,
1083  pValueInformation->DataLength - Header);
1084  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
1085  }
1086  }
1087 
1088  if (EnumerateSubKeys)
1089  {
1090  IndexSubKey = 0;
1091  while (TRUE)
1092  {
1093  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1095  break;
1097  {
1098  ExFreePool(pDeviceInformation);
1099  DeviceInfoLength = RequiredSize;
1100  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
1101  if (!pDeviceInformation)
1102  {
1103  DPRINT("ExAllocatePool() failed\n");
1105  goto cleanup;
1106  }
1107  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
1108  }
1109  if (!NT_SUCCESS(Status))
1110  {
1111  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
1112  goto cleanup;
1113  }
1114  IndexSubKey++;
1115  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
1116  DeviceName.Buffer = pDeviceInformation->Name;
1117 
1119  hDeviceKey,
1120  &DeviceName,
1121  hRootKey,
1122  TRUE,
1123  BootResources,
1124  BootResourcesLength);
1125  if (!NT_SUCCESS(Status))
1126  goto cleanup;
1127  }
1128  }
1129 
1130  /* Read identifier */
1131  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1133  {
1134  ExFreePool(pValueInformation);
1135  ValueInfoLength = RequiredSize;
1136  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
1137  if (!pValueInformation)
1138  {
1139  DPRINT("ExAllocatePool() failed\n");
1141  goto cleanup;
1142  }
1143  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
1144  }
1145  if (!NT_SUCCESS(Status))
1146  {
1148  {
1149  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
1150  goto nextdevice;
1151  }
1152  ValueName.Length = ValueName.MaximumLength = 0;
1153  }
1154  else if (pValueInformation->Type != REG_SZ)
1155  {
1156  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
1157  goto nextdevice;
1158  }
1159  else
1160  {
1161  /* Assign hardware id to this device */
1162  ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
1163  ValueName.Buffer = (PWCHAR)pValueInformation->Data;
1164  if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
1165  ValueName.Length -= sizeof(WCHAR);
1166  }
1167 
1168  if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
1169  {
1170  pHardwareId = &HardwareIdSerial;
1171  DeviceIndex = DeviceIndexSerial++;
1172  }
1173  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
1174  {
1175  pHardwareId = &HardwareIdKeyboard;
1176  DeviceIndex = DeviceIndexKeyboard++;
1177  }
1178  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
1179  {
1180  pHardwareId = &HardwareIdMouse;
1181  DeviceIndex = DeviceIndexMouse++;
1182  }
1183  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
1184  {
1185  pHardwareId = &HardwareIdParallel;
1186  DeviceIndex = DeviceIndexParallel++;
1187  }
1188  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
1189  {
1190  pHardwareId = &HardwareIdFloppy;
1191  DeviceIndex = DeviceIndexFloppy++;
1192  }
1193  else
1194  {
1195  /* Unknown key path */
1196  DPRINT("Unknown key path '%wZ'\n", RelativePath);
1197  goto nextdevice;
1198  }
1199 
1200  /* Prepare hardware id key (hardware id value without final \0) */
1201  HardwareIdKey = *pHardwareId;
1202  HardwareIdKey.Length -= sizeof(UNICODE_NULL);
1203 
1204  /* Add the detected device to Root key */
1205  InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL);
1206  Status = ZwCreateKey(
1207  &hLevel1Key,
1210  0,
1211  NULL,
1213  NULL);
1214  if (!NT_SUCCESS(Status))
1215  {
1216  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1217  goto nextdevice;
1218  }
1219  swprintf(Level2Name, L"%04lu", DeviceIndex);
1220  RtlInitUnicodeString(&Level2NameU, Level2Name);
1221  InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL);
1222  Status = ZwCreateKey(
1223  &hLevel2Key,
1226  0,
1227  NULL,
1229  NULL);
1230  ZwClose(hLevel1Key);
1231  if (!NT_SUCCESS(Status))
1232  {
1233  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1234  goto nextdevice;
1235  }
1236  DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
1237  Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
1238  if (!NT_SUCCESS(Status))
1239  {
1240  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1241  ZwDeleteKey(hLevel2Key);
1242  goto nextdevice;
1243  }
1244  /* Create 'LogConf' subkey */
1246  Status = ZwCreateKey(
1247  &hLogConf,
1248  KEY_SET_VALUE,
1250  0,
1251  NULL,
1253  NULL);
1254  if (!NT_SUCCESS(Status))
1255  {
1256  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1257  ZwDeleteKey(hLevel2Key);
1258  goto nextdevice;
1259  }
1260  if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
1261  {
1262  CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
1263  if (!CmResourceList)
1264  {
1265  ZwClose(hLogConf);
1266  ZwDeleteKey(hLevel2Key);
1267  goto nextdevice;
1268  }
1269 
1270  /* Add the list count (1st member of CM_RESOURCE_LIST) */
1271  ListCount = 1;
1272  RtlCopyMemory(CmResourceList,
1273  &ListCount,
1274  sizeof(ULONG));
1275 
1276  /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
1277  RtlCopyMemory(CmResourceList + sizeof(ULONG),
1278  BootResources,
1279  BootResourcesLength);
1280 
1281  /* Save boot resources to 'LogConf\BootConfig' */
1282  Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
1283  if (!NT_SUCCESS(Status))
1284  {
1285  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1286  ZwClose(hLogConf);
1287  ZwDeleteKey(hLevel2Key);
1288  goto nextdevice;
1289  }
1290  }
1291  ZwClose(hLogConf);
1292 
1293 nextdevice:
1294  if (BootResources && BootResources != ParentBootResources)
1295  {
1296  ExFreePool(BootResources);
1297  BootResources = NULL;
1298  }
1299  if (hLevel2Key)
1300  {
1301  ZwClose(hLevel2Key);
1302  hLevel2Key = NULL;
1303  }
1304  if (hDeviceKey)
1305  {
1306  ZwClose(hDeviceKey);
1307  hDeviceKey = NULL;
1308  }
1309  }
1310 
1312 
1313 cleanup:
1314  if (hDevicesKey && hDevicesKey != hBaseKey)
1315  ZwClose(hDevicesKey);
1316  if (hDeviceKey)
1317  ZwClose(hDeviceKey);
1318  if (pDeviceInformation)
1319  ExFreePool(pDeviceInformation);
1320  if (pValueInformation)
1321  ExFreePool(pValueInformation);
1322  return Status;
1323 }
1324 
1325 static
1326 CODE_SEG("INIT")
1327 BOOLEAN
1329 {
1330  UNICODE_STRING KeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CURRENTCONTROLSET\\Control\\Pnp");
1331  UNICODE_STRING KeyNameU = RTL_CONSTANT_STRING(L"DisableFirmwareMapper");
1333  HANDLE hPnpKey;
1334  PKEY_VALUE_PARTIAL_INFORMATION KeyInformation;
1335  ULONG DesiredLength, Length;
1336  ULONG KeyValue = 0;
1337  NTSTATUS Status;
1338 
1340  Status = ZwOpenKey(&hPnpKey, KEY_QUERY_VALUE, &ObjectAttributes);
1341  if (NT_SUCCESS(Status))
1342  {
1343  Status = ZwQueryValueKey(hPnpKey,
1344  &KeyNameU,
1346  NULL,
1347  0,
1348  &DesiredLength);
1349  if ((Status == STATUS_BUFFER_TOO_SMALL) ||
1351  {
1352  Length = DesiredLength;
1353  KeyInformation = ExAllocatePool(PagedPool, Length);
1354  if (KeyInformation)
1355  {
1356  Status = ZwQueryValueKey(hPnpKey,
1357  &KeyNameU,
1359  KeyInformation,
1360  Length,
1361  &DesiredLength);
1362  if (NT_SUCCESS(Status) && KeyInformation->DataLength == sizeof(ULONG))
1363  {
1364  KeyValue = (ULONG)(*KeyInformation->Data);
1365  }
1366  else
1367  {
1368  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed\n", &KeyPathU, &KeyNameU);
1369  }
1370 
1371  ExFreePool(KeyInformation);
1372  }
1373  else
1374  {
1375  DPRINT1("Failed to allocate memory for registry query\n");
1376  }
1377  }
1378  else
1379  {
1380  DPRINT1("ZwQueryValueKey(%wZ%wZ) failed with status 0x%08lx\n", &KeyPathU, &KeyNameU, Status);
1381  }
1382 
1383  ZwClose(hPnpKey);
1384  }
1385  else
1386  {
1387  DPRINT1("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyPathU, Status);
1388  }
1389 
1390  DPRINT("Firmware mapper is %s\n", KeyValue != 0 ? "disabled" : "enabled");
1391 
1392  return (KeyValue != 0) ? TRUE : FALSE;
1393 }
1394 
1395 CODE_SEG("INIT")
1396 NTSTATUS
1397 NTAPI
1399 {
1400  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
1401  UNICODE_STRING RootPathU = RTL_CONSTANT_STRING(L"Root");
1402  UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
1404  HANDLE hEnum, hRoot;
1405  NTSTATUS Status;
1406 
1409  if (!NT_SUCCESS(Status))
1410  {
1411  DPRINT1("ZwCreateKey() failed with status 0x%08lx\n", Status);
1412  return Status;
1413  }
1414 
1417  ZwClose(hEnum);
1418  if (!NT_SUCCESS(Status))
1419  {
1420  DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
1421  return Status;
1422  }
1423 
1425  {
1426  Status = IopOpenRegistryKeyEx(&hEnum, NULL, &MultiKeyPathU, KEY_ENUMERATE_SUB_KEYS);
1427  if (!NT_SUCCESS(Status))
1428  {
1429  /* Nothing to do, don't return with an error status */
1430  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
1431  ZwClose(hRoot);
1432  return STATUS_SUCCESS;
1433  }
1435  hEnum,
1436  NULL,
1437  hRoot,
1438  TRUE,
1439  NULL,
1440  0);
1441  ZwClose(hEnum);
1442  }
1443  else
1444  {
1445  /* Enumeration is disabled */
1447  }
1448 
1449  ZwClose(hRoot);
1450 
1451  return Status;
1452 }
1453 
1454 NTSTATUS
1455 NTAPI
1457  HANDLE ParentKey,
1460 {
1462  NTSTATUS Status;
1463 
1464  PAGED_CODE();
1465 
1466  *KeyHandle = NULL;
1467 
1469  Name,
1471  ParentKey,
1472  NULL);
1473 
1475 
1476  return Status;
1477 }
1478 
1479 NTSTATUS
1480 NTAPI
1482  IN HANDLE RootHandle OPTIONAL,
1487 {
1489  ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
1490  USHORT Length;
1491  HANDLE HandleArray[2];
1492  BOOLEAN Recursing = TRUE;
1493  PWCHAR pp, p, p1;
1494  UNICODE_STRING KeyString;
1496  PAGED_CODE();
1497 
1498  /* P1 is start, pp is end */
1499  p1 = KeyName->Buffer;
1500  pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
1501 
1502  /* Create the target key */
1504  KeyName,
1506  RootHandle,
1507  NULL);
1508  Status = ZwCreateKey(&HandleArray[i],
1509  DesiredAccess,
1511  0,
1512  NULL,
1513  CreateOptions,
1514  &KeyDisposition);
1515 
1516  /* Now we check if this failed */
1517  if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
1518  {
1519  /* Target key failed, so we'll need to create its parent. Setup array */
1520  HandleArray[0] = NULL;
1521  HandleArray[1] = RootHandle;
1522 
1523  /* Keep recursing for each missing parent */
1524  while (Recursing)
1525  {
1526  /* And if we're deep enough, close the last handle */
1527  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1528 
1529  /* We're setup to ping-pong between the two handle array entries */
1530  RootHandleIndex = i;
1531  i = (i + 1) & 1;
1532 
1533  /* Clear the one we're attempting to open now */
1534  HandleArray[i] = NULL;
1535 
1536  /* Process the parent key name */
1537  for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
1538  Length = (USHORT)(p - p1) * sizeof(WCHAR);
1539 
1540  /* Is there a parent name? */
1541  if (Length)
1542  {
1543  /* Build the unicode string for it */
1544  KeyString.Buffer = p1;
1545  KeyString.Length = KeyString.MaximumLength = Length;
1546 
1547  /* Now try opening the parent */
1549  &KeyString,
1551  HandleArray[RootHandleIndex],
1552  NULL);
1553  Status = ZwCreateKey(&HandleArray[i],
1554  DesiredAccess,
1556  0,
1557  NULL,
1558  CreateOptions,
1559  &KeyDisposition);
1560  if (NT_SUCCESS(Status))
1561  {
1562  /* It worked, we have one more handle */
1563  NestedCloseLevel++;
1564  }
1565  else
1566  {
1567  /* Parent key creation failed, abandon loop */
1568  Recursing = FALSE;
1569  continue;
1570  }
1571  }
1572  else
1573  {
1574  /* We don't have a parent name, probably corrupted key name */
1576  Recursing = FALSE;
1577  continue;
1578  }
1579 
1580  /* Now see if there's more parents to create */
1581  p1 = p + 1;
1582  if ((p == pp) || (p1 == pp))
1583  {
1584  /* We're done, hopefully successfully, so stop */
1585  Recursing = FALSE;
1586  }
1587  }
1588 
1589  /* Outer loop check for handle nesting that requires closing the top handle */
1590  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
1591  }
1592 
1593  /* Check if we broke out of the loop due to success */
1594  if (NT_SUCCESS(Status))
1595  {
1596  /* Return the target handle (we closed all the parent ones) and disposition */
1597  *Handle = HandleArray[i];
1598  if (Disposition) *Disposition = KeyDisposition;
1599  }
1600 
1601  /* Return the success state */
1602  return Status;
1603 }
1604 
1605 NTSTATUS
1606 NTAPI
1608  IN PWSTR ValueName,
1610 {
1611  UNICODE_STRING ValueString;
1612  NTSTATUS Status;
1613  PKEY_VALUE_FULL_INFORMATION FullInformation;
1614  ULONG Size;
1615  PAGED_CODE();
1616 
1617  RtlInitUnicodeString(&ValueString, ValueName);
1618 
1619  Status = ZwQueryValueKey(Handle,
1620  &ValueString,
1622  NULL,
1623  0,
1624  &Size);
1625  if ((Status != STATUS_BUFFER_OVERFLOW) &&
1627  {
1628  return Status;
1629  }
1630 
1631  FullInformation = ExAllocatePool(NonPagedPool, Size);
1632  if (!FullInformation) return STATUS_INSUFFICIENT_RESOURCES;
1633 
1634  Status = ZwQueryValueKey(Handle,
1635  &ValueString,
1637  FullInformation,
1638  Size,
1639  &Size);
1640  if (!NT_SUCCESS(Status))
1641  {
1642  ExFreePool(FullInformation);
1643  return Status;
1644  }
1645 
1646  *Information = FullInformation;
1647  return STATUS_SUCCESS;
1648 }
1649 
1651 NTAPI
1655 {
1656  /* FIXME: TODO */
1657  ASSERT(FALSE);
1658  return 0;
1659 }
1660 
1661 //
1662 // The allocation function is called by the generic table package whenever
1663 // it needs to allocate memory for the table.
1664 //
1665 
1666 PVOID
1667 NTAPI
1669  IN CLONG ByteSize)
1670 {
1671  /* FIXME: TODO */
1672  ASSERT(FALSE);
1673  return NULL;
1674 }
1675 
1676 VOID
1677 NTAPI
1679  IN PVOID Buffer)
1680 {
1681  /* FIXME: TODO */
1682  ASSERT(FALSE);
1683 }
1684 
1685 VOID
1686 NTAPI
1688 {
1689  /* Setup the guarded mutex and AVL table */
1696  NULL);
1697 }
1698 
1699 BOOLEAN
1700 NTAPI
1702 {
1703  /* Initialize the resource when accessing device registry data */
1705 
1706  /* Setup the device reference AVL table */
1708  return TRUE;
1709 }
1710 
1711 BOOLEAN
1712 NTAPI
1714 {
1715  /* Check the initialization phase */
1716  switch (ExpInitializationPhase)
1717  {
1718  case 0:
1719 
1720  /* Do Phase 0 */
1721  return PiInitPhase0();
1722 
1723  case 1:
1724 
1725  /* Do Phase 1 */
1726  return TRUE;
1727  //return PiInitPhase1();
1728 
1729  default:
1730 
1731  /* Don't know any other phase! Bugcheck! */
1732  KeBugCheck(UNEXPECTED_INITIALIZATION_CALL);
1733  return FALSE;
1734  }
1735 }
1736 
1737 /* PUBLIC FUNCTIONS **********************************************************/
1738 
1739 NTSTATUS
1740 NTAPI
1742  IN LPGUID BusTypeGuid)
1743 {
1745 
1746  /* Acquire the lock */
1748 
1749  /* Validate size */
1750  if (Index < PnpBusTypeGuidList->GuidCount)
1751  {
1752  /* Copy the data */
1753  RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID));
1754  }
1755  else
1756  {
1757  /* Failure path */
1759  }
1760 
1761  /* Release lock and return status */
1763  return Status;
1764 }
1765 
1766 NTSTATUS
1767 NTAPI
1769  IN PHANDLE DeviceInstanceHandle,
1771 {
1772  NTSTATUS Status;
1773  HANDLE KeyHandle;
1775  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
1776  PAGED_CODE();
1777 
1778  /* Open the enum key */
1780  NULL,
1781  &KeyName,
1782  KEY_READ);
1783  if (!NT_SUCCESS(Status)) return Status;
1784 
1785  /* Make sure we have an instance path */
1787  if ((DeviceNode) && (DeviceNode->InstancePath.Length))
1788  {
1789  /* Get the instance key */
1790  Status = IopOpenRegistryKeyEx(DeviceInstanceHandle,
1791  KeyHandle,
1792  &DeviceNode->InstancePath,
1793  DesiredAccess);
1794  }
1795  else
1796  {
1797  /* Fail */
1799  }
1800 
1801  /* Close the handle and return status */
1802  ZwClose(KeyHandle);
1803  return Status;
1804 }
1805 
1806 ULONG
1807 NTAPI
1809 {
1810  ULONG FinalSize, PartialSize, EntrySize, i, j;
1811  PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
1812  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
1813 
1814  /* If we don't have one, that's easy */
1815  if (!ResourceList) return 0;
1816 
1817  /* Start with the minimum size possible */
1818  FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
1819 
1820  /* Loop each full descriptor */
1821  FullDescriptor = ResourceList->List;
1822  for (i = 0; i < ResourceList->Count; i++)
1823  {
1824  /* Start with the minimum size possible */
1825  PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
1826  FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
1827 
1828  /* Loop each partial descriptor */
1829  PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
1830  for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
1831  {
1832  /* Start with the minimum size possible */
1834 
1835  /* Check if there is extra data */
1836  if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
1837  {
1838  /* Add that data */
1839  EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize;
1840  }
1841 
1842  /* The size of partial descriptors is bigger */
1843  PartialSize += EntrySize;
1844 
1845  /* Go to the next partial descriptor */
1846  PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize);
1847  }
1848 
1849  /* The size of full descriptors is bigger */
1850  FinalSize += PartialSize;
1851 
1852  /* Go to the next full descriptor */
1853  FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize);
1854  }
1855 
1856  /* Return the final size */
1857  return FinalSize;
1858 }
1859 
1860 NTSTATUS
1861 NTAPI
1863  IN ULONG ValueType,
1864  IN PWSTR ValueName,
1865  IN PWSTR KeyName,
1866  OUT PVOID Buffer,
1868 {
1869  NTSTATUS Status;
1870  HANDLE KeyHandle, SubHandle;
1871  UNICODE_STRING KeyString;
1872  PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
1873  ULONG Length;
1874  PAGED_CODE();
1875 
1876  /* Find the instance key */
1878  if (NT_SUCCESS(Status))
1879  {
1880  /* Check for name given by caller */
1881  if (KeyName)
1882  {
1883  /* Open this key */
1884  RtlInitUnicodeString(&KeyString, KeyName);
1885  Status = IopOpenRegistryKeyEx(&SubHandle,
1886  KeyHandle,
1887  &KeyString,
1888  KEY_READ);
1889  if (NT_SUCCESS(Status))
1890  {
1891  /* And use this handle instead */
1892  ZwClose(KeyHandle);
1893  KeyHandle = SubHandle;
1894  }
1895  }
1896 
1897  /* Check if sub-key handle succeeded (or no-op if no key name given) */
1898  if (NT_SUCCESS(Status))
1899  {
1900  /* Now get the size of the property */
1902  ValueName,
1903  &KeyValueInfo);
1904  }
1905 
1906  /* Close the key */
1907  ZwClose(KeyHandle);
1908  }
1909 
1910  /* Fail if any of the registry operations failed */
1911  if (!NT_SUCCESS(Status)) return Status;
1912 
1913  /* Check how much data we have to copy */
1914  Length = KeyValueInfo->DataLength;
1915  if (*BufferLength >= Length)
1916  {
1917  /* Check for a match in the value type */
1918  if (KeyValueInfo->Type == ValueType)
1919  {
1920  /* Copy the data */
1922  (PVOID)((ULONG_PTR)KeyValueInfo +
1923  KeyValueInfo->DataOffset),
1924  Length);
1925  }
1926  else
1927  {
1928  /* Invalid registry property type, fail */
1930  }
1931  }
1932  else
1933  {
1934  /* Buffer is too small to hold data */
1936  }
1937 
1938  /* Return the required buffer length, free the buffer, and return status */
1939  *BufferLength = Length;
1940  ExFreePool(KeyValueInfo);
1941  return Status;
1942 }
1943 
1944 #define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;}
1945 #define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;}
1946 #define PIP_UNIMPLEMENTED() {UNIMPLEMENTED_DBGBREAK(); break;}
1947 
1948 /*
1949  * @implemented
1950  */
1951 NTSTATUS
1952 NTAPI
1958 {
1960  DEVICE_CAPABILITIES DeviceCaps;
1961  ULONG ReturnLength = 0, Length = 0, ValueType;
1962  PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
1963  PVOID Data = NULL;
1965  GUID BusTypeGuid;
1966  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
1967  BOOLEAN NullTerminate = FALSE;
1969 
1970  DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
1971 
1972  /* Assume failure */
1973  *ResultLength = 0;
1974 
1975  /* Only PDOs can call this */
1977 
1978  /* Handle all properties */
1979  switch (DeviceProperty)
1980  {
1982 
1983  /* Get the GUID from the internal cache */
1984  Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
1985  if (!NT_SUCCESS(Status)) return Status;
1986 
1987  /* This is the format of the returned data */
1988  PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
1989 
1991 
1992  /* Validate correct interface type */
1993  if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
1995 
1996  /* This is the format of the returned data */
1997  PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
1998 
2000 
2001  /* Validate correct bus number */
2002  if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
2004 
2005  /* This is the format of the returned data */
2006  PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
2007 
2009 
2010  /* Get the instance path */
2011  DeviceInstanceName = DeviceNode->InstancePath.Buffer;
2012 
2013  /* Sanity checks */
2014  ASSERT((BufferLength & 1) == 0);
2015  ASSERT(DeviceInstanceName != NULL);
2016 
2017  /* Get the name from the path */
2018  EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
2019  ASSERT(EnumeratorNameEnd);
2020 
2021  /* This string needs to be NULL-terminated */
2022  NullTerminate = TRUE;
2023 
2024  /* This is the format of the returned data */
2025  PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
2026  DeviceInstanceName);
2027 
2028  case DevicePropertyAddress:
2029 
2030  /* Query the device caps */
2032  if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
2034 
2035  /* This is the format of the returned data */
2036  PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
2037 
2039 
2040  /* Validate we have resources */
2041  if (!DeviceNode->BootResources)
2042 // if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
2043  {
2044  /* No resources will still fake success, but with 0 bytes */
2045  *ResultLength = 0;
2046  return STATUS_SUCCESS;
2047  }
2048 
2049  /* This is the format of the returned data */
2050  PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
2051  DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
2052 
2054 
2055  /* Sanity check for Unicode-sized string */
2056  ASSERT((BufferLength & 1) == 0);
2057 
2058  /* Allocate name buffer */
2060  ObjectNameInfo = ExAllocatePool(PagedPool, Length);
2061  if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
2062 
2063  /* Query the PDO name */
2065  ObjectNameInfo,
2066  Length,
2067  ResultLength);
2069  {
2070  /* It's up to the caller to try again */
2072  }
2073 
2074  /* This string needs to be NULL-terminated */
2075  NullTerminate = TRUE;
2076 
2077  /* Return if successful */
2078  if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
2079  ObjectNameInfo->Name.Buffer);
2080 
2081  /* Let the caller know how big the name is */
2083  break;
2084 
2086 
2087  Policy = DeviceNode->RemovalPolicy;
2088  PIP_RETURN_DATA(sizeof(Policy), &Policy);
2089 
2090  /* Handle the registry-based properties */
2114  //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
2116  break;
2119  break;
2124  default:
2126  }
2127 
2128  /* Having a registry value name implies registry data */
2129  if (ValueName)
2130  {
2131  /* We know up-front how much data to expect */
2133 
2134  /* Go get the data, use the LogConf subkey if necessary */
2136  ValueType,
2137  ValueName,
2138  (DeviceProperty ==
2140  L"LogConf": NULL,
2142  ResultLength);
2143  }
2144  else if (NT_SUCCESS(Status))
2145  {
2146  /* We know up-front how much data to expect, check the caller's buffer */
2147  *ResultLength = ReturnLength + (NullTerminate ? sizeof(UNICODE_NULL) : 0);
2148  if (*ResultLength <= BufferLength)
2149  {
2150  /* Buffer is all good, copy the data */
2152 
2153  /* Check if we need to NULL-terminate the string */
2154  if (NullTerminate)
2155  {
2156  /* Terminate the string */
2158  }
2159 
2160  /* This is the success path */
2162  }
2163  else
2164  {
2165  /* Failure path */
2167  }
2168  }
2169 
2170  /* Free any allocation we may have made, and return the status code */
2171  if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
2172  return Status;
2173 }
2174 
2190 NTSTATUS
2191 NTAPI
2196 {
2197  static WCHAR RootKeyName[] =
2198  L"\\Registry\\Machine\\System\\CurrentControlSet\\";
2199  static WCHAR ProfileKeyName[] =
2200  L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
2201  static WCHAR ClassKeyName[] = L"Control\\Class\\";
2202  static WCHAR EnumKeyName[] = L"Enum\\";
2203  static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
2205  PWSTR KeyNameBuffer;
2207  ULONG DriverKeyLength;
2210  NTSTATUS Status;
2211 
2212  DPRINT("IoOpenDeviceRegistryKey() called\n");
2213 
2215  {
2216  DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
2217  return STATUS_INVALID_PARAMETER;
2218  }
2219 
2223 
2224  /*
2225  * Calculate the length of the base key name. This is the full
2226  * name for driver key or the name excluding "Device Parameters"
2227  * subkey for device key.
2228  */
2229 
2230  KeyNameLength = sizeof(RootKeyName);
2232  KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
2234  {
2235  KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
2237  0, NULL, &DriverKeyLength);
2239  return Status;
2240  KeyNameLength += DriverKeyLength;
2241  }
2242  else
2243  {
2244  KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
2245  DeviceNode->InstancePath.Length;
2246  }
2247 
2248  /*
2249  * Now allocate the buffer for the key name...
2250  */
2251 
2252  KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
2253  if (KeyNameBuffer == NULL)
2255 
2256  KeyName.Length = 0;
2257  KeyName.MaximumLength = (USHORT)KeyNameLength;
2258  KeyName.Buffer = KeyNameBuffer;
2259 
2260  /*
2261  * ...and build the key name.
2262  */
2263 
2264  KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
2265  RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
2266 
2268  RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
2269 
2271  {
2272  RtlAppendUnicodeToString(&KeyName, ClassKeyName);
2274  DriverKeyLength, KeyNameBuffer +
2275  (KeyName.Length / sizeof(WCHAR)),
2276  &DriverKeyLength);
2277  if (!NT_SUCCESS(Status))
2278  {
2279  DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
2280  ExFreePool(KeyNameBuffer);
2281  return Status;
2282  }
2283  KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
2284  }
2285  else
2286  {
2287  RtlAppendUnicodeToString(&KeyName, EnumKeyName);
2289  if (DeviceNode->InstancePath.Length == 0)
2290  {
2291  ExFreePool(KeyNameBuffer);
2292  return Status;
2293  }
2294  }
2295 
2296  /*
2297  * Open the base key.
2298  */
2300  if (!NT_SUCCESS(Status))
2301  {
2302  DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
2303  ExFreePool(KeyNameBuffer);
2304  return Status;
2305  }
2306  ExFreePool(KeyNameBuffer);
2307 
2308  /*
2309  * For driver key we're done now.
2310  */
2311 
2313  return Status;
2314 
2315  /*
2316  * Let's go further. For device key we must open "Device Parameters"
2317  * subkey and create it if it doesn't exist yet.
2318  */
2319 
2320  RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
2322  &KeyName,
2324  *DevInstRegKey,
2325  NULL);
2326  Status = ZwCreateKey(DevInstRegKey,
2327  DesiredAccess,
2329  0,
2330  NULL,
2332  NULL);
2333  ZwClose(ObjectAttributes.RootDirectory);
2334 
2335  return Status;
2336 }
2337 
2338 /*
2339  * @implemented
2340  */
2341 VOID
2342 NTAPI
2346 {
2348  {
2349  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)DeviceObject, 0, 0);
2350  }
2351 
2352  switch (Type)
2353  {
2354  case BusRelations:
2355  /* Enumerate the device */
2357  break;
2358  default:
2359  /* Everything else is not implemented */
2360  break;
2361  }
2362 }
2363 
2364 /*
2365  * @implemented
2366  */
2367 NTSTATUS
2368 NTAPI
2372 {
2373  PAGED_CODE();
2374 
2376  {
2377  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG_PTR)DeviceObject, 0, 0);
2378  }
2379 
2380  switch (Type)
2381  {
2382  case BusRelations:
2383  /* Enumerate the device */
2385  case PowerRelations:
2386  /* Not handled yet */
2387  return STATUS_NOT_IMPLEMENTED;
2388  case TargetDeviceRelation:
2389  /* Nothing to do */
2390  return STATUS_SUCCESS;
2391  default:
2392  /* Ejection relations are not supported */
2393  return STATUS_NOT_SUPPORTED;
2394  }
2395 }
2396 
2397 /*
2398  * @implemented
2399  */
2400 BOOLEAN
2401 NTAPI
2403  IN ULONG BusNumber,
2407 {
2408  /* FIXME: Notify the resource arbiter */
2409 
2411  BusNumber,
2412  BusAddress,
2413  AddressSpace,
2415 }
BOOLEAN PnPBootDriversLoaded
Definition: pnpmgr.c:21
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2369
DEVICE_REGISTRY_PROPERTY
Definition: iotypes.h:1194
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:428
#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:850
_In_ ULONG _In_ PHYSICAL_ADDRESS BusAddress
Definition: iofuncs.h:2272
VOID NTAPI PiFreeGenericTableEntry(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: pnpmgr.c:1678
#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:2616
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_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:2786
#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:1456
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1125
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
_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:523
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:1741
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:427
PVOID NTAPI PiAllocateGenericTableEntry(IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
Definition: pnpmgr.c:1668
DEVICE_CAPABILITIES
Definition: iotypes.h:965
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
uint16_t * PWCHAR
Definition: typedefs.h:56
#define swprintf
Definition: precomp.h:40
#define REGSTR_VAL_FRIENDLYNAME
Definition: regstr.h:465
if(dx==0 &&dy==0)
Definition: linetemp.h:174
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2272
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
#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:394
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:1862
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
_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
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:1701
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1697
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:1953
Definition: bufpool.h:45
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
CODE_SEG("INIT")
Definition: Interface.c:1810
#define PIP_UNIMPLEMENTED()
Definition: pnpmgr.c:1946
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:412
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
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
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@377 u
NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:607
NTSTATUS NTAPI PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1768
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
NTSTATUS IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:383
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:761
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
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
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
BOOLEAN NTAPI PpInitSystem(VOID)
Definition: pnpmgr.c:1713
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@377::@386 DeviceSpecificData
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:2402
#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:1687
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#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:1328
#define PIP_REGISTRY_DATA(x, y)
Definition: pnpmgr.c:1945
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1808
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:480
RTL_AVL_FREE_ROUTINE * PRTL_AVL_FREE_ROUTINE
Definition: rtltypes.h:402
_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:1481
#define REGSTR_VAL_HARDWAREID
Definition: regstr.h:485
_In_ ULONG _In_ ACCESS_MASK _Out_ PHANDLE DevInstRegKey
Definition: iofuncs.h:1125
#define IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)
Definition: io.h:238
#define REGSTR_VAL_DEVDESC
Definition: regstr.h:292
NTSTATUS NTAPI IopUpdateRootKey(VOID)
Definition: pnpmgr.c:1398
_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:2675
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:2343
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69
#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:853
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
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:2192
#define PIP_RETURN_DATA(x, y)
Definition: pnpmgr.c:1944
_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
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
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:887
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
#define REGSTR_VAL_BOOTCONFIG
Definition: regstr.h:293
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
ULONG ExpInitializationPhase
Definition: init.c:66
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:651
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:1652
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
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:2788
#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