ReactOS 0.4.16-dev-338-g34e76ad
pnproot.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * COPYRIGHT: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/pnpmgr/pnproot.c
5 * PURPOSE: PnP manager root device
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Copyright 2007 Herv? Poussineau (hpoussin@reactos.org)
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS *******************************************************************/
17
18#define ENUM_NAME_ROOT L"Root"
19
20/* DATA **********************************************************************/
21
22typedef struct _PNPROOT_DEVICE
23{
24 // Entry on device list
26 // Physical Device Object of device
28 // Device ID
30 // Instance ID
32 // Device description
34 // Resource requirement list
36 // Associated resource list
40
41/* Physical Device Object device extension for a child device */
43{
44 // Informations about the device
47
48/* Physical Device Object device extension for the Root bus device object */
50{
51 // Namespace device list
53 // Number of (not removed) devices in device list
55 // Lock for namespace device list
58
59typedef struct _BUFFER
60{
64
66
67/* FUNCTIONS *****************************************************************/
68
69static NTSTATUS
71 IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
72 IN PCUNICODE_STRING DeviceId,
74 OUT PPNPROOT_DEVICE* ChildDevice OPTIONAL)
75{
77 UNICODE_STRING InstanceIdU;
78 PLIST_ENTRY NextEntry;
79
80 /* Initialize the string to compare */
81 RtlInitUnicodeString(&InstanceIdU, InstanceId);
82
83 /* Start looping */
84 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
85 NextEntry != &DeviceExtension->DeviceListHead;
86 NextEntry = NextEntry->Flink)
87 {
88 /* Get the entry */
89 Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
90
91 /* See if the strings match */
92 if (RtlEqualUnicodeString(DeviceId, &Device->DeviceID, TRUE) &&
93 RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
94 {
95 /* They do, so set the pointer and return success */
96 if (ChildDevice)
97 *ChildDevice = Device;
98 return STATUS_SUCCESS;
99 }
100 }
101
102 /* No device found */
104}
105
109{
111 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
114 PWSTR InstancePath;
115 UNICODE_STRING InstancePathCopy;
116
118 if (!Device) return STATUS_NO_MEMORY;
119
121 if (!RtlCreateUnicodeString(&InstancePathCopy, DeviceNode->InstancePath.Buffer))
122 {
124 return STATUS_NO_MEMORY;
125 }
126
127 InstancePath = wcsrchr(InstancePathCopy.Buffer, L'\\');
128 ASSERT(InstancePath);
129
130 if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath + 1))
131 {
132 RtlFreeUnicodeString(&InstancePathCopy);
134 return STATUS_NO_MEMORY;
135 }
136
137 InstancePath[0] = UNICODE_NULL;
138
139 if (!RtlCreateUnicodeString(&Device->DeviceID, InstancePathCopy.Buffer))
140 {
141 RtlFreeUnicodeString(&InstancePathCopy);
142 RtlFreeUnicodeString(&Device->InstanceID);
144 return STATUS_NO_MEMORY;
145 }
146
147 InstancePath[0] = L'\\';
148
149 Device->Pdo = DeviceObject;
150
151 PdoDeviceExtension = DeviceObject->DeviceExtension;
152 RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
153 PdoDeviceExtension->DeviceInfo = Device;
154
155 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
156 InsertTailList(&DeviceExtension->DeviceListHead,
157 &Device->ListEntry);
158 DeviceExtension->DeviceListCount++;
159 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
160
161 RtlFreeUnicodeString(&InstancePathCopy);
162
163 return STATUS_SUCCESS;
164}
165
169{
173 NULL,
176 FALSE,
178
179 return status;
180}
181
182/* Creates a new PnP device for a legacy driver */
187 OUT PUNICODE_STRING FullInstancePath)
188{
189 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
190 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
191 UNICODE_STRING DevicePath;
192 WCHAR InstancePath[5];
195 ULONG NextInstance;
196 UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
197 HANDLE EnumHandle, DeviceKeyHandle = NULL, InstanceKeyHandle;
200
201 DeviceExtension = &PnpRootDOExtension;
202 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
203
204 DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
205
206 DevicePath.Length = 0;
207 DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + ServiceName->Length;
209 DevicePath.MaximumLength,
211 if (DevicePath.Buffer == NULL)
212 {
213 DPRINT1("ExAllocatePoolWithTag() failed\n");
215 goto cleanup;
216 }
219
220 /* Initialize a PNPROOT_DEVICE structure */
222 if (!Device)
223 {
224 DPRINT("ExAllocatePoolWithTag() failed\n");
226 goto cleanup;
227 }
229 Device->DeviceID = DevicePath; // "Root<service_name>"
230 RtlInitEmptyUnicodeString(&DevicePath, NULL, 0);
231
232 Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
233 if (NT_SUCCESS(Status))
234 {
236 &Device->DeviceID,
238 EnumHandle,
239 NULL);
240 Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
241 ObCloseHandle(EnumHandle, KernelMode);
242 }
243
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT1("Failed to open registry key\n");
247 goto cleanup;
248 }
249
250tryagain:
252 QueryTable[0].Name = L"NextInstance";
253 QueryTable[0].EntryContext = &NextInstance;
255
257 (PWSTR)DeviceKeyHandle,
259 NULL,
260 NULL);
261 for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
262 {
263 _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
264 Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
266 break;
267 }
268
269 if (NextInstance > 9999)
270 {
271 DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
273 goto cleanup;
274 }
275
276 _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
277 Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
278 if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
279 {
280 DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
282 (PWSTR)DeviceKeyHandle,
283 L"NextInstance");
284 goto tryagain;
285 }
286
287 NextInstance++;
289 (PWSTR)DeviceKeyHandle,
290 L"NextInstance",
291 REG_DWORD,
292 &NextInstance,
293 sizeof(NextInstance));
294 if (!NT_SUCCESS(Status))
295 {
296 DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
297 goto cleanup;
298 }
299
300 // "0000" or higher
301 if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
302 {
304 goto cleanup;
305 }
306
307 /* Finish creating the instance path in the registry */
309 &Device->InstanceID,
311 DeviceKeyHandle,
312 NULL);
313 Status = ZwCreateKey(&InstanceKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
314 if (!NT_SUCCESS(Status))
315 {
316 DPRINT1("Failed to create instance path (0x%x)\n", Status);
317 goto cleanup;
318 }
319
320 /* Just close the handle */
321 ObCloseHandle(InstanceKeyHandle, KernelMode);
322
323 // generate the full device instance path
324 FullInstancePath->MaximumLength = Device->DeviceID.Length + sizeof(L'\\') + Device->InstanceID.Length;
325 FullInstancePath->Length = 0;
326 FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
327 if (!FullInstancePath->Buffer)
328 {
330 goto cleanup;
331 }
332
333 RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
334 RtlAppendUnicodeToString(FullInstancePath, L"\\");
335 RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
336
337 /* Initialize a device object */
339 if (!NT_SUCCESS(Status))
340 {
341 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
343 goto cleanup;
344 }
345
346 PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
347 RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
348 PdoDeviceExtension->DeviceInfo = Device;
349
350 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
351 Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
352
354 &DeviceExtension->DeviceListHead,
355 &Device->ListEntry);
356 DeviceExtension->DeviceListCount++;
357
359 DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject, &Device->DeviceID, &Device->InstanceID);
360 Device = NULL;
362
363cleanup:
364 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
365 if (Device)
366 {
367 if (Device->Pdo)
369 RtlFreeUnicodeString(&Device->DeviceID);
370 RtlFreeUnicodeString(&Device->InstanceID);
372 }
373 RtlFreeUnicodeString(&DevicePath);
374 if (DeviceKeyHandle != NULL)
375 ObCloseHandle(DeviceKeyHandle, KernelMode);
376 return Status;
377}
378
379static NTSTATUS NTAPI
387{
390
391 if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
392 {
393 Destination->Length = 0;
396 return STATUS_SUCCESS;
397 }
398
399 Source.MaximumLength = Source.Length = (USHORT)ValueLength;
400 Source.Buffer = ValueData;
401
403}
404
405static NTSTATUS NTAPI
413{
415 PVOID BinaryValue;
416
417 if (ValueLength == 0)
418 {
419 *Buffer->Data = NULL;
420 return STATUS_SUCCESS;
421 }
422
424 if (BinaryValue == NULL)
425 return STATUS_NO_MEMORY;
426 RtlCopyMemory(BinaryValue, ValueData, ValueLength);
427 *Buffer->Data = BinaryValue;
428 if (Buffer->Length) *Buffer->Length = ValueLength;
429 return STATUS_SUCCESS;
430}
431
432static
436 _Inout_ PUNICODE_STRING DevicePath,
439{
442 HANDLE DeviceKeyHandle = NULL;
444 BUFFER Buffer1, Buffer2;
445
446 /* If the device already exists, there's nothing to do */
447 Status = LocateChildDevice(DeviceExtension, DevicePath, InstanceId, &Device);
449 {
450 return STATUS_SUCCESS;
451 }
452
453 /* Create a PPNPROOT_DEVICE object, and add it to the list of known devices */
455 if (!Device)
456 {
457 DPRINT("ExAllocatePoolWithTag() failed\n");
459 goto cleanup;
460 }
462
463 /* Fill device ID and instance ID */
464 Device->DeviceID = *DevicePath;
465 RtlInitEmptyUnicodeString(DevicePath, NULL, 0);
466 if (!RtlCreateUnicodeString(&Device->InstanceID, InstanceId))
467 {
468 DPRINT1("RtlCreateUnicodeString() failed\n");
470 goto cleanup;
471 }
472
473 /* Open registry key to fill other informations */
474 Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
475 if (!NT_SUCCESS(Status))
476 {
477 /* If our key disappeared, let the caller go on */
478 DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
479 &Device->InstanceID, Status);
481 goto cleanup;
482 }
483
484 /* Fill information from the device instance key */
487 QueryTable[0].Name = L"DeviceDesc";
488 QueryTable[0].EntryContext = &Device->DeviceDescription;
489
491 (PCWSTR)DeviceKeyHandle,
493 NULL,
494 NULL);
495
496 /* Fill information from the LogConf subkey */
497 Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
498 Buffer1.Length = NULL;
499 Buffer2.Data = (PVOID *)&Device->ResourceList;
500 Buffer2.Length = &Device->ResourceListSize;
503 QueryTable[0].Name = L"LogConf";
505 QueryTable[1].Name = L"BasicConfigVector";
506 QueryTable[1].EntryContext = &Buffer1;
508 QueryTable[2].Name = L"BootConfig";
509 QueryTable[2].EntryContext = &Buffer2;
510
512 (PCWSTR)DeviceKeyHandle,
514 NULL,
515 NULL)))
516 {
517 /* Non-fatal error */
518 DPRINT1("Failed to read the LogConf key for %wZ\\%S\n", &Device->DeviceID, InstanceId);
519 }
520
521 /* Insert the newly created device into the list */
522 InsertTailList(&DeviceExtension->DeviceListHead,
523 &Device->ListEntry);
524 DeviceExtension->DeviceListCount++;
525 Device = NULL;
526
527cleanup:
528 if (DeviceKeyHandle != NULL)
529 {
530 ZwClose(DeviceKeyHandle);
531 }
532 if (Device != NULL)
533 {
534 /* We have a device that has not been added to device list. We need to clean it up */
535 RtlFreeUnicodeString(&Device->DeviceID);
536 RtlFreeUnicodeString(&Device->InstanceID);
538 }
539 return Status;
540}
541
542static NTSTATUS
544 IN HANDLE SubKey,
546{
547 UNICODE_STRING DeviceReportedValue = RTL_CONSTANT_STRING(L"DeviceReported");
549 UNICODE_STRING InstanceIDU;
550 PKEY_VALUE_FULL_INFORMATION pKeyValueFullInformation;
551 HANDLE InstanceKey, ControlKey;
553 ULONG Size, DeviceReported, ResultLength;
555
556 Size = 128;
557 pKeyValueFullInformation = ExAllocatePool(PagedPool, Size);
558 if (!pKeyValueFullInformation)
560
561 /* Open Instance key */
562 RtlInitUnicodeString(&InstanceIDU, InstanceID);
564 &InstanceIDU,
566 SubKey,
567 NULL);
568 Status = ZwOpenKey(&InstanceKey,
571 if (!NT_SUCCESS(Status))
572 {
573 ExFreePool(pKeyValueFullInformation);
574 return Status;
575 }
576
577 /* Read 'DeviceReported' Key */
578 Status = ZwQueryValueKey(InstanceKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
580 {
581 ZwClose(InstanceKey);
582 ExFreePool(pKeyValueFullInformation);
583 DPRINT("No 'DeviceReported' value\n");
584 return STATUS_SUCCESS;
585 }
586 else if (!NT_SUCCESS(Status))
587 {
588 ZwClose(InstanceKey);
589 ExFreePool(pKeyValueFullInformation);
590 return Status;
591 }
592 if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
593 {
594 ZwClose(InstanceKey);
595 ExFreePool(pKeyValueFullInformation);
596 return STATUS_UNSUCCESSFUL;
597 }
598 RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
599 /* FIXME: Check DeviceReported value? */
600 ASSERT(DeviceReported == 1);
601
602 /* Open Control key */
604 &Control,
606 InstanceKey,
607 NULL);
608 Status = ZwOpenKey(&ControlKey,
611 ZwClose(InstanceKey);
613 {
614 DPRINT("No 'Control' key\n");
616 }
617 else if (!NT_SUCCESS(Status))
618 {
619 ExFreePool(pKeyValueFullInformation);
620 return Status;
621 }
622
623 /* Read 'DeviceReported' Key */
624 Status = ZwQueryValueKey(ControlKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
625 ZwClose(ControlKey);
627 {
628 ExFreePool(pKeyValueFullInformation);
629 DPRINT("No 'DeviceReported' value\n");
631 }
632 else if (!NT_SUCCESS(Status))
633 {
634 ExFreePool(pKeyValueFullInformation);
635 return Status;
636 }
637 if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
638 {
639 ExFreePool(pKeyValueFullInformation);
640 return STATUS_UNSUCCESSFUL;
641 }
642 RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
643 /* FIXME: Check DeviceReported value? */
644 ASSERT(DeviceReported == 1);
645
646 ExFreePool(pKeyValueFullInformation);
647 return STATUS_SUCCESS;
648}
649
650static NTSTATUS
653{
654 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
655 PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
656 UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
659 UNICODE_STRING DevicePath;
662 ULONG KeyInfoSize, SubKeyInfoSize;
663 ULONG ResultSize;
664 ULONG Index1, Index2;
666
667 DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
668
669 DeviceExtension = &PnpRootDOExtension;
670 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
671
672 /* Should hold most key names, but we reallocate below if it's too small */
673 KeyInfoSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + 64 * sizeof(WCHAR);
675 KeyInfoSize + sizeof(UNICODE_NULL),
677 if (!KeyInfo)
678 {
679 DPRINT("ExAllocatePoolWithTag() failed\n");
681 goto cleanup;
682 }
683 SubKeyInfoSize = KeyInfoSize;
684 SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
685 SubKeyInfoSize + sizeof(UNICODE_NULL),
687 if (!SubKeyInfo)
688 {
689 DPRINT("ExAllocatePoolWithTag() failed\n");
691 goto cleanup;
692 }
693
695 if (!NT_SUCCESS(Status))
696 {
697 DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
698 goto cleanup;
699 }
700
701 /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
702 * KeyHandle. We'll first do a first enumeration to have first level keys,
703 * and an inner one to have the real devices list.
704 */
705 Index1 = 0;
706 while (TRUE)
707 {
708 Status = ZwEnumerateKey(
709 KeyHandle,
710 Index1,
712 KeyInfo,
713 KeyInfoSize,
714 &ResultSize);
716 {
718 break;
719 }
720 else if (Status == STATUS_BUFFER_OVERFLOW ||
722 {
723 ASSERT(KeyInfoSize < ResultSize);
724 KeyInfoSize = ResultSize;
727 KeyInfoSize + sizeof(UNICODE_NULL),
729 if (!KeyInfo)
730 {
731 DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", KeyInfoSize);
733 goto cleanup;
734 }
735 continue;
736 }
737 else if (!NT_SUCCESS(Status))
738 {
739 DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
740 goto cleanup;
741 }
742
743 /* Terminate the string */
744 KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
745
746 /* Check if it is a legacy driver */
748 if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
749 {
750 DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
751 Index1++;
752 continue;
753 }
754
755 /* Open the key */
757 if (!NT_SUCCESS(Status))
758 {
759 DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
761 break;
762 }
763
764 /* Enumerate the sub-keys */
765 Index2 = 0;
766 while (TRUE)
767 {
768 Status = ZwEnumerateKey(
770 Index2,
772 SubKeyInfo,
773 SubKeyInfoSize,
774 &ResultSize);
776 {
777 break;
778 }
779 else if (Status == STATUS_BUFFER_OVERFLOW ||
781 {
782 ASSERT(SubKeyInfoSize < ResultSize);
783 SubKeyInfoSize = ResultSize;
784 ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
785 SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
786 SubKeyInfoSize + sizeof(UNICODE_NULL),
788 if (!SubKeyInfo)
789 {
790 DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", SubKeyInfoSize);
792 goto cleanup;
793 }
794 continue;
795 }
796 else if (!NT_SUCCESS(Status))
797 {
798 DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
799 break;
800 }
801
802 /* Terminate the string */
803 SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
804
805 /* Compute device ID */
806 DevicePath.Length = 0;
807 DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + SubKeyName.Length;
809 DevicePath.MaximumLength,
811 if (DevicePath.Buffer == NULL)
812 {
813 DPRINT1("ExAllocatePoolWithTag() failed\n");
815 goto cleanup;
816 }
817
820 DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
821
822 Status = IopShouldProcessDevice(SubKeyHandle, SubKeyInfo->Name);
823 if (NT_SUCCESS(Status))
824 {
825 Status = CreateDeviceFromRegistry(DeviceExtension,
826 &DevicePath,
827 SubKeyInfo->Name,
829
830 /* If CreateDeviceFromRegistry didn't take ownership and zero this,
831 * we need to free it
832 */
833 RtlFreeUnicodeString(&DevicePath);
834
835 if (!NT_SUCCESS(Status))
836 {
837 goto cleanup;
838 }
839 }
840 else if (Status == STATUS_NO_SUCH_DEVICE)
841 {
842 DPRINT("Skipping device %wZ\\%S (not reported yet)\n", &DevicePath, SubKeyInfo->Name);
843 }
844 else
845 {
846 goto cleanup;
847 }
848
849 Index2++;
850 }
851
854 Index1++;
855 }
856
857cleanup:
858 if (SubKeyHandle != NULL)
860 if (KeyHandle != NULL)
862 if (KeyInfo)
864 if (SubKeyInfo)
865 ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
866 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
867 return Status;
868}
869
870/* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
871 * ARGUMENTS:
872 * DeviceObject = Pointer to functional device object of the root bus driver
873 * Irp = Pointer to IRP that should be handled
874 * RETURNS:
875 * Status
876 */
877static NTSTATUS
880 IN PIRP Irp)
881{
882 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
883 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
884 PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
886 ULONG Size;
888 PLIST_ENTRY NextEntry;
889
890 DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
891
893 if (!NT_SUCCESS(Status))
894 {
895 DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
896 return Status;
897 }
898
899 DeviceExtension = &PnpRootDOExtension;
900
901 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
902 if (OtherRelations)
903 {
904 /* Another bus driver has already created a DEVICE_RELATIONS
905 * structure so we must merge this structure with our own */
906
907 Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
908 }
910 if (!Relations)
911 {
912 DPRINT("ExAllocatePoolWithTag() failed\n");
914 goto cleanup;
915 }
916 RtlZeroMemory(Relations, Size);
917 if (OtherRelations)
918 {
919 Relations->Count = OtherRelations->Count;
920 RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
921 }
922
923 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
924
925 /* Start looping */
926 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
927 NextEntry != &DeviceExtension->DeviceListHead;
928 NextEntry = NextEntry->Flink)
929 {
930 /* Get the entry */
931 Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
932
933 if (!Device->Pdo)
934 {
935 /* Create a physical device object for the
936 * device as it does not already have one */
938 if (!NT_SUCCESS(Status))
939 {
940 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
941 break;
942 }
943
944 PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
945 RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
946 PdoDeviceExtension->DeviceInfo = Device;
947
948 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
949 Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
950 }
951
952 /* Reference the physical device object. The PnP manager
953 will dereference it again when it is no longer needed */
955
956 Relations->Objects[Relations->Count++] = Device->Pdo;
957 }
958 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
959
960 Irp->IoStatus.Information = (ULONG_PTR)Relations;
961
962cleanup:
963 if (!NT_SUCCESS(Status))
964 {
965 if (OtherRelations)
966 ExFreePool(OtherRelations);
967 if (Relations)
968 ExFreePool(Relations);
969 if (Device && Device->Pdo)
970 {
972 Device->Pdo = NULL;
973 }
974 }
975
976 return Status;
977}
978
979/*
980 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
981 * ARGUMENTS:
982 * DeviceObject = Pointer to functional device object of the root bus driver
983 * Irp = Pointer to IRP that should be handled
984 * RETURNS:
985 * Status
986 */
987static NTSTATUS
990 IN PIRP Irp)
991{
994
995 Status = Irp->IoStatus.Status;
997
998 switch (IrpSp->MinorFunction)
999 {
1001 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
1003 break;
1004
1005 default:
1006 // The root device object can receive only IRP_MN_QUERY_DEVICE_RELATIONS
1007 ASSERT(FALSE);
1008 DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1009 break;
1010 }
1011
1012 if (Status != STATUS_PENDING)
1013 {
1014 Irp->IoStatus.Status = Status;
1016 }
1017
1018 return Status;
1019}
1020
1021static NTSTATUS
1024 IN PIRP Irp,
1026{
1027 PDEVICE_RELATIONS Relations;
1028 NTSTATUS Status = Irp->IoStatus.Status;
1029
1031 return Status;
1032
1033 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
1035 if (!Relations)
1036 {
1037 DPRINT("ExAllocatePoolWithTag() failed\n");
1039 }
1040 else
1041 {
1043 Relations->Count = 1;
1044 Relations->Objects[0] = DeviceObject;
1046 Irp->IoStatus.Information = (ULONG_PTR)Relations;
1047 }
1048
1049 return Status;
1050}
1051
1052static NTSTATUS
1055 IN PIRP Irp,
1057{
1059
1061
1062 if (DeviceCapabilities->Version != 1)
1064
1065 DeviceCapabilities->UniqueID = TRUE;
1066 /* FIXME: Fill other fields */
1067
1068 return STATUS_SUCCESS;
1069}
1070
1071static NTSTATUS
1074 IN PIRP Irp,
1076{
1077 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1079
1080 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1081
1082 if (DeviceExtension->DeviceInfo->ResourceList)
1083 {
1084 /* Copy existing resource requirement list */
1086 PagedPool,
1087 DeviceExtension->DeviceInfo->ResourceListSize);
1088 if (!ResourceList)
1089 return STATUS_NO_MEMORY;
1090
1093 DeviceExtension->DeviceInfo->ResourceList,
1094 DeviceExtension->DeviceInfo->ResourceListSize);
1095
1096 Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1097
1098 return STATUS_SUCCESS;
1099 }
1100 else
1101 {
1102 /* No resources so just return without changing the status */
1103 return Irp->IoStatus.Status;
1104 }
1105}
1106
1107static NTSTATUS
1110 IN PIRP Irp,
1112{
1113 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1115
1116 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1117
1118 if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
1119 {
1120 /* Copy existing resource requirement list */
1122 if (!ResourceList)
1123 return STATUS_NO_MEMORY;
1124
1127 DeviceExtension->DeviceInfo->ResourceRequirementsList,
1128 DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
1129
1130 Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1131
1132 return STATUS_SUCCESS;
1133 }
1134 else
1135 {
1136 /* No resource requirements so just return without changing the status */
1137 return Irp->IoStatus.Status;
1138 }
1139}
1140
1141static NTSTATUS
1144 IN PIRP Irp,
1146{
1147 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1148 DEVICE_TEXT_TYPE DeviceTextType;
1149 NTSTATUS Status = Irp->IoStatus.Status;
1150
1151 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1152 DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
1153
1154 switch (DeviceTextType)
1155 {
1157 {
1159 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
1160
1161 if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
1162 {
1164 &DeviceExtension->DeviceInfo->DeviceDescription,
1165 &String);
1166 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1167 }
1168 break;
1169 }
1170
1172 {
1173 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1174 break;
1175 }
1176
1177 default:
1178 {
1179 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1180 }
1181 }
1182
1183 return Status;
1184}
1185
1186static NTSTATUS
1189 IN PIRP Irp,
1191{
1192 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1194 NTSTATUS Status = Irp->IoStatus.Status;
1195
1196 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1197 IdType = IrpSp->Parameters.QueryId.IdType;
1198
1199 switch (IdType)
1200 {
1201 case BusQueryDeviceID:
1202 {
1204 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1205
1208 &DeviceExtension->DeviceInfo->DeviceID,
1209 &String);
1210 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1211 break;
1212 }
1213
1216 {
1217 /* Optional, do nothing */
1218 break;
1219 }
1220
1221 case BusQueryInstanceID:
1222 {
1224 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1225
1228 &DeviceExtension->DeviceInfo->InstanceID,
1229 &String);
1230 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1231 break;
1232 }
1233
1234 default:
1235 {
1236 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1237 }
1238 }
1239
1240 return Status;
1241}
1242
1243static NTSTATUS
1246 IN PIRP Irp,
1248{
1249 PPNP_BUS_INFORMATION BusInfo;
1251
1253 if (!BusInfo)
1255 else
1256 {
1258 &BusInfo->BusTypeGuid,
1259 &GUID_BUS_TYPE_INTERNAL,
1260 sizeof(BusInfo->BusTypeGuid));
1261 BusInfo->LegacyBusType = PNPBus;
1262 /* We're the only root bus enumerator on the computer */
1263 BusInfo->BusNumber = 0;
1264 Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1266 }
1267
1268 return Status;
1269}
1270
1271/*
1272 * FUNCTION: Handle Plug and Play IRPs for the child device
1273 * ARGUMENTS:
1274 * DeviceObject = Pointer to physical device object of the child device
1275 * Irp = Pointer to IRP that should be handled
1276 * RETURNS:
1277 * Status
1278 */
1279static NTSTATUS
1282 IN PIRP Irp)
1283{
1284 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1285 PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1288
1289 DeviceExtension = DeviceObject->DeviceExtension;
1290 FdoDeviceExtension = &PnpRootDOExtension;
1291 Status = Irp->IoStatus.Status;
1293
1294 switch (IrpSp->MinorFunction)
1295 {
1296 case IRP_MN_START_DEVICE: /* 0x00 */
1297 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1299 break;
1300
1301 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1303 break;
1304
1305 case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1306 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1308 break;
1309
1310 case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1311 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1313 break;
1314
1315 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1316 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1318 break;
1319
1320 case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1321 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1323 break;
1324
1326 DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1327 break;
1328
1330 /* Remove the device from the device list and decrement the device count*/
1331 KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1332 RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1333 FdoDeviceExtension->DeviceListCount--;
1334 KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1335
1336 /* Free some strings we created */
1338 RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1339 RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1340
1341 /* Free the resource requirements list */
1342 if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1344
1345 /* Free the boot resources list */
1346 if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1347 ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1348
1349 /* Free the device info */
1350 ExFreePool(DeviceExtension->DeviceInfo);
1351
1352 /* Finally, delete the device object */
1354
1355 /* Return success */
1357 break;
1358
1359 case IRP_MN_QUERY_ID: /* 0x13 */
1361 break;
1362
1363 case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1364 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1365 break;
1366
1367 case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1368 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1370 break;
1371
1372 default:
1373 DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1374 break;
1375 }
1376
1377 if (Status != STATUS_PENDING)
1378 {
1379 Irp->IoStatus.Status = Status;
1381 }
1382
1383 return Status;
1384}
1385
1386/*
1387 * FUNCTION: Handle Plug and Play IRPs
1388 * ARGUMENTS:
1389 * DeviceObject = Pointer to PDO or FDO
1390 * Irp = Pointer to IRP that should be handled
1391 * RETURNS:
1392 * Status
1393 */
1394static NTSTATUS NTAPI
1397 IN PIRP Irp)
1398{
1400
1403 else
1405
1406 return Status;
1407}
1408
1409/*
1410 * FUNCTION: Handle Power IRPs
1411 * ARGUMENTS:
1412 * DeviceObject = Pointer to PDO or FDO
1413 * Irp = Pointer to IRP that should be handled
1414 * RETURNS:
1415 * Status
1416 */
1417static NTSTATUS NTAPI
1420 IN PIRP Irp)
1421{
1423 NTSTATUS Status = Irp->IoStatus.Status;
1424
1425 switch (IrpSp->MinorFunction)
1426 {
1427 case IRP_MN_QUERY_POWER:
1428 case IRP_MN_SET_POWER:
1430 break;
1431 }
1432 Irp->IoStatus.Status = Status;
1435
1436 return Status;
1437}
1438
1439VOID
1441{
1445}
1446
1448NTAPI
1452{
1453 // AddDevice must never be called for the root driver
1454 ASSERT(FALSE);
1455 return STATUS_SUCCESS;
1456}
1457
1458#if MI_TRACE_PFNS
1459PDEVICE_OBJECT IopPfnDumpDeviceObject;
1460
1462PnpRootCreateClose(
1464 _In_ PIRP Irp)
1465{
1466 PIO_STACK_LOCATION IoStack;
1467
1468 if (DeviceObject != IopPfnDumpDeviceObject)
1469 {
1470 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1473 }
1474
1476 if (IoStack->MajorFunction == IRP_MJ_CREATE)
1477 {
1479 }
1480
1481 Irp->IoStatus.Status = STATUS_SUCCESS;
1483 return STATUS_SUCCESS;
1484}
1485#endif
1486
1491{
1492#if MI_TRACE_PFNS
1494 UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1495#endif
1496
1497 DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1498
1500
1502
1503#if MI_TRACE_PFNS
1504 DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1505 DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1506#endif
1507 DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
1509
1510#if MI_TRACE_PFNS
1512 0,
1513 &PfnDumpDeviceName,
1515 0,
1516 FALSE,
1517 &IopPfnDumpDeviceObject);
1518 if (!NT_SUCCESS(Status))
1519 {
1520 DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1521 }
1522 else
1523 {
1524 IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1525 }
1526#endif
1527
1528 return STATUS_SUCCESS;
1529}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
@ DeviceNode
Definition: Node.h:9
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static WCHAR ServiceName[]
Definition: browser.c:19
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: bufpool.h:45
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:374
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define wcsrchr
Definition: compat.h:16
static void cleanup(void)
Definition: main.c:1335
switch(r->id)
Definition: btrfs.c:3046
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:908
Status
Definition: gdiplustypes.h:25
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
@ PNPBus
Definition: hwresource.cpp:152
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4726
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:34
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4219
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4220
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
@ KeyBasicInformation
Definition: nt_native.h:1131
#define RTL_QUERY_REGISTRY_SUBKEY
Definition: nt_native.h:125
@ KeyValueFullInformation
Definition: nt_native.h:1181
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define UNICODE_NULL
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:885
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:26
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
VOID NTAPI MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
Definition: mminit.c:1474
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
unsigned short USHORT
Definition: pedump.c:61
struct _PNPROOT_FDO_DEVICE_EXTENSION * PPNPROOT_FDO_DEVICE_EXTENSION
static NTSTATUS PdoQueryResources(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1072
struct _PNPROOT_PDO_DEVICE_EXTENSION PNPROOT_PDO_DEVICE_EXTENSION
VOID PnpRootInitializeDevExtension(VOID)
Definition: pnproot.c:1440
static NTSTATUS NTAPI PnpRootPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1418
static NTSTATUS PdoQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1053
static NTSTATUS NTAPI PnpRootPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1395
static NTSTATUS NTAPI QueryBinaryValueCallback(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: pnproot.c:406
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1142
static NTSTATUS PdoQueryBusInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1244
static PNPROOT_FDO_DEVICE_EXTENSION PnpRootDOExtension
Definition: pnproot.c:65
static NTSTATUS PdoQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1108
NTSTATUS PnpRootRegisterDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:107
static NTSTATUS CreateDeviceFromRegistry(_Inout_ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, _Inout_ PUNICODE_STRING DevicePath, _In_ PCWSTR InstanceId, _In_ HANDLE SubKeyHandle)
Definition: pnproot.c:434
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:184
static NTSTATUS NTAPI QueryStringCallback(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: pnproot.c:380
static NTSTATUS PnpRootPdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1280
NTSTATUS NTAPI PnpRootDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: pnproot.c:1488
static NTSTATUS PdoQueryId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1187
NTSTATUS NTAPI PnpRootAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnproot.c:1449
struct _PNPROOT_DEVICE * PPNPROOT_DEVICE
struct _PNPROOT_PDO_DEVICE_EXTENSION * PPNPROOT_PDO_DEVICE_EXTENSION
static NTSTATUS PnpRootQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:878
static NTSTATUS PdoQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1022
static NTSTATUS LocateChildDevice(IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, IN PCUNICODE_STRING DeviceId, IN PCWSTR InstanceId, OUT PPNPROOT_DEVICE *ChildDevice OPTIONAL)
Definition: pnproot.c:70
static NTSTATUS EnumerateDevices(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:651
struct _PNPROOT_DEVICE PNPROOT_DEVICE
struct _BUFFER * PBUFFER
static NTSTATUS IopShouldProcessDevice(IN HANDLE SubKey, IN PCWSTR InstanceID)
Definition: pnproot.c:543
struct _PNPROOT_FDO_DEVICE_EXTENSION PNPROOT_FDO_DEVICE_EXTENSION
struct _BUFFER BUFFER
static NTSTATUS PnpRootFdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:988
NTSTATUS PnpRootCreateDeviceObject(OUT PDEVICE_OBJECT *DeviceObject)
Definition: pnproot.c:167
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:79
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:49
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define REGSTR_KEY_ROOTENUM
Definition: regstr.h:10
#define REGSTR_PATH_SYSTEMENUM
Definition: regstr.h:483
#define REG_DWORD
Definition: sdbapi.c:596
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID * Data
Definition: pnproot.c:61
PULONG Length
Definition: pnproot.c:62
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2220
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@4007 DeviceCapabilities
struct _IO_STACK_LOCATION::@3980::@4005 QueryDeviceRelations
struct _IO_STACK_LOCATION::@3980::@4012 QueryDeviceText
struct _IO_STACK_LOCATION::@3980::@4011 QueryId
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PCM_RESOURCE_LIST ResourceList
Definition: pnproot.c:37
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
Definition: pnproot.c:35
UNICODE_STRING DeviceID
Definition: pnproot.c:29
ULONG ResourceListSize
Definition: pnproot.c:38
UNICODE_STRING InstanceID
Definition: pnproot.c:31
PDEVICE_OBJECT Pdo
Definition: pnproot.c:27
LIST_ENTRY ListEntry
Definition: pnproot.c:25
UNICODE_STRING DeviceDescription
Definition: pnproot.c:33
KGUARDED_MUTEX DeviceListLock
Definition: pnproot.c:56
PPNPROOT_DEVICE DeviceInfo
Definition: pnproot.c:45
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:365
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ps.c:97
#define TAG_PNP_ROOT
Definition: tag.h:92
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING InstanceID
Definition: wdfpdo.h:309
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
#define DeviceCapabilities
Definition: wingdi.h:4449
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
@ TargetDeviceRelation
Definition: iotypes.h:2156
#define IRP_MN_QUERY_PNP_DEVICE_STATE
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define DO_BUS_ENUMERATED_DEVICE
#define IRP_MN_START_DEVICE
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_ID
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_CAPABILITIES
#define IRP_MN_QUERY_RESOURCES
#define IRP_MN_SET_POWER
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
@ DeviceTextLocationInformation
Definition: iotypes.h:2946
@ DeviceTextDescription
Definition: iotypes.h:2945
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
#define IRP_MJ_POWER
@ BusQueryCompatibleIDs
Definition: iotypes.h:2938
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
#define IRP_MN_QUERY_POWER
#define IRP_MN_QUERY_BUS_INFORMATION
#define ObReferenceObject
Definition: obfuncs.h:204
__wchar_t WCHAR
Definition: xmlstorage.h:180