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