ReactOS 0.4.15-dev-5875-g7c755d9
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
41typedef enum
42{
49
51{
52 // Wether this device extension is for an FDO or PDO
55
56/* Physical Device Object device extension for a child device */
58{
59 // Common device data
61 // Informations about the device
64
65/* Physical Device Object device extension for the Root bus device object */
67{
68 // Common device data
70 // Lower device object
72 // Current state of the driver
74 // Namespace device list
76 // Number of (not removed) devices in device list
78 // Lock for namespace device list
81
82typedef struct _BUFFER
83{
87
89
90/* FUNCTIONS *****************************************************************/
91
92static NTSTATUS
94 IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
95 IN PCUNICODE_STRING DeviceId,
97 OUT PPNPROOT_DEVICE* ChildDevice OPTIONAL)
98{
100 UNICODE_STRING InstanceIdU;
101 PLIST_ENTRY NextEntry;
102
103 /* Initialize the string to compare */
104 RtlInitUnicodeString(&InstanceIdU, InstanceId);
105
106 /* Start looping */
107 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
108 NextEntry != &DeviceExtension->DeviceListHead;
109 NextEntry = NextEntry->Flink)
110 {
111 /* Get the entry */
112 Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
113
114 /* See if the strings match */
115 if (RtlEqualUnicodeString(DeviceId, &Device->DeviceID, TRUE) &&
116 RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
117 {
118 /* They do, so set the pointer and return success */
119 if (ChildDevice)
120 *ChildDevice = Device;
121 return STATUS_SUCCESS;
122 }
123 }
124
125 /* No device found */
127}
128
132{
136 PWSTR InstancePath;
137 UNICODE_STRING InstancePathCopy;
138
140 if (!Device) return STATUS_NO_MEMORY;
141
143 if (!RtlCreateUnicodeString(&InstancePathCopy, DeviceNode->InstancePath.Buffer))
144 {
146 return STATUS_NO_MEMORY;
147 }
148
149 InstancePath = wcsrchr(InstancePathCopy.Buffer, L'\\');
150 ASSERT(InstancePath);
151
152 if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath + 1))
153 {
154 RtlFreeUnicodeString(&InstancePathCopy);
156 return STATUS_NO_MEMORY;
157 }
158
159 InstancePath[0] = UNICODE_NULL;
160
161 if (!RtlCreateUnicodeString(&Device->DeviceID, InstancePathCopy.Buffer))
162 {
163 RtlFreeUnicodeString(&InstancePathCopy);
164 RtlFreeUnicodeString(&Device->InstanceID);
166 return STATUS_NO_MEMORY;
167 }
168
169 InstancePath[0] = L'\\';
170
171 Device->Pdo = DeviceObject;
172
173 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
174 InsertTailList(&DeviceExtension->DeviceListHead,
175 &Device->ListEntry);
176 DeviceExtension->DeviceListCount++;
177 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
178
179 RtlFreeUnicodeString(&InstancePathCopy);
180
181 return STATUS_SUCCESS;
182}
183
184/* Creates a new PnP device for a legacy driver */
190 OUT OPTIONAL PUNICODE_STRING FullInstancePath)
191{
192 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
193 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
194 UNICODE_STRING DevicePath;
195 WCHAR InstancePath[5];
198 UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
199 ULONG NextInstance;
200 UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM);
201 HANDLE EnumHandle, DeviceKeyHandle = NULL, InstanceKeyHandle;
204
205 DeviceExtension = PnpRootDeviceObject->DeviceExtension;
206 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
207
208 DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
209
210 DevicePath.Length = 0;
211 DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + ServiceName->Length;
213 DevicePath.MaximumLength,
215 if (DevicePath.Buffer == NULL)
216 {
217 DPRINT1("ExAllocatePoolWithTag() failed\n");
219 goto cleanup;
220 }
223
224 /* Initialize a PNPROOT_DEVICE structure */
226 if (!Device)
227 {
228 DPRINT("ExAllocatePoolWithTag() failed\n");
230 goto cleanup;
231 }
233 Device->DeviceID = DevicePath;
234 RtlInitEmptyUnicodeString(&DevicePath, NULL, 0);
235
236 Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ);
237 if (NT_SUCCESS(Status))
238 {
240 &Device->DeviceID,
242 EnumHandle,
243 NULL);
244 Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
245 ObCloseHandle(EnumHandle, KernelMode);
246 }
247
248 if (!NT_SUCCESS(Status))
249 {
250 DPRINT1("Failed to open registry key\n");
251 goto cleanup;
252 }
253
254tryagain:
256 QueryTable[0].Name = L"NextInstance";
257 QueryTable[0].EntryContext = &NextInstance;
259
261 (PWSTR)DeviceKeyHandle,
263 NULL,
264 NULL);
265 for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
266 {
267 _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
268 Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
270 break;
271 }
272
273 if (NextInstance > 9999)
274 {
275 DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
277 goto cleanup;
278 }
279
280 _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
281 Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
282 if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
283 {
284 DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
286 (PWSTR)DeviceKeyHandle,
287 L"NextInstance");
288 goto tryagain;
289 }
290
291 NextInstance++;
293 (PWSTR)DeviceKeyHandle,
294 L"NextInstance",
295 REG_DWORD,
296 &NextInstance,
297 sizeof(NextInstance));
298 if (!NT_SUCCESS(Status))
299 {
300 DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status);
301 goto cleanup;
302 }
303
304 if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
305 {
307 goto cleanup;
308 }
309
310 /* Finish creating the instance path in the registry */
312 &Device->InstanceID,
314 DeviceKeyHandle,
315 NULL);
316 Status = ZwCreateKey(&InstanceKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
317 if (!NT_SUCCESS(Status))
318 {
319 DPRINT1("Failed to create instance path (0x%x)\n", Status);
320 goto cleanup;
321 }
322
323 /* Just close the handle */
324 ObCloseHandle(InstanceKeyHandle, KernelMode);
325
326 if (FullInstancePath)
327 {
328 FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
329 FullInstancePath->Length = 0;
330 FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
331 if (!FullInstancePath->Buffer)
332 {
334 goto cleanup;
335 }
336
337 RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
338 RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
339 RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
340 }
341
342 /* Initialize a device object */
346 NULL,
349 FALSE,
350 &Device->Pdo);
351 if (!NT_SUCCESS(Status))
352 {
353 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
355 goto cleanup;
356 }
357
358 PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
359 RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
360 PdoDeviceExtension->Common.IsFDO = FALSE;
361 PdoDeviceExtension->DeviceInfo = Device;
362
363 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
364 Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
365
367 &DeviceExtension->DeviceListHead,
368 &Device->ListEntry);
369 DeviceExtension->DeviceListCount++;
370
372 DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject, &Device->DeviceID, &Device->InstanceID);
373 Device = NULL;
375
376cleanup:
377 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
378 if (Device)
379 {
380 if (Device->Pdo)
382 RtlFreeUnicodeString(&Device->DeviceID);
383 RtlFreeUnicodeString(&Device->InstanceID);
385 }
386 RtlFreeUnicodeString(&DevicePath);
387 if (DeviceKeyHandle != NULL)
388 ObCloseHandle(DeviceKeyHandle, KernelMode);
389 return Status;
390}
391
392static NTSTATUS NTAPI
400{
403
404 if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
405 {
406 Destination->Length = 0;
409 return STATUS_SUCCESS;
410 }
411
412 Source.MaximumLength = Source.Length = (USHORT)ValueLength;
413 Source.Buffer = ValueData;
414
416}
417
418static NTSTATUS NTAPI
426{
428 PVOID BinaryValue;
429
430 if (ValueLength == 0)
431 {
432 *Buffer->Data = NULL;
433 return STATUS_SUCCESS;
434 }
435
437 if (BinaryValue == NULL)
438 return STATUS_NO_MEMORY;
439 RtlCopyMemory(BinaryValue, ValueData, ValueLength);
440 *Buffer->Data = BinaryValue;
441 if (Buffer->Length) *Buffer->Length = ValueLength;
442 return STATUS_SUCCESS;
443}
444
445static
449 _Inout_ PUNICODE_STRING DevicePath,
452{
455 HANDLE DeviceKeyHandle = NULL;
457 BUFFER Buffer1, Buffer2;
458
459 /* If the device already exists, there's nothing to do */
460 Status = LocateChildDevice(DeviceExtension, DevicePath, InstanceId, &Device);
462 {
463 return STATUS_SUCCESS;
464 }
465
466 /* Create a PPNPROOT_DEVICE object, and add it to the list of known devices */
468 if (!Device)
469 {
470 DPRINT("ExAllocatePoolWithTag() failed\n");
472 goto cleanup;
473 }
475
476 /* Fill device ID and instance ID */
477 Device->DeviceID = *DevicePath;
478 RtlInitEmptyUnicodeString(DevicePath, NULL, 0);
479 if (!RtlCreateUnicodeString(&Device->InstanceID, InstanceId))
480 {
481 DPRINT1("RtlCreateUnicodeString() failed\n");
483 goto cleanup;
484 }
485
486 /* Open registry key to fill other informations */
487 Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, SubKeyHandle, &Device->InstanceID, KEY_READ);
488 if (!NT_SUCCESS(Status))
489 {
490 /* If our key disappeared, let the caller go on */
491 DPRINT1("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
492 &Device->InstanceID, Status);
494 goto cleanup;
495 }
496
497 /* Fill information from the device instance key */
500 QueryTable[0].Name = L"DeviceDesc";
501 QueryTable[0].EntryContext = &Device->DeviceDescription;
502
504 (PCWSTR)DeviceKeyHandle,
506 NULL,
507 NULL);
508
509 /* Fill information from the LogConf subkey */
510 Buffer1.Data = (PVOID *)&Device->ResourceRequirementsList;
511 Buffer1.Length = NULL;
512 Buffer2.Data = (PVOID *)&Device->ResourceList;
513 Buffer2.Length = &Device->ResourceListSize;
516 QueryTable[0].Name = L"LogConf";
518 QueryTable[1].Name = L"BasicConfigVector";
519 QueryTable[1].EntryContext = &Buffer1;
521 QueryTable[2].Name = L"BootConfig";
522 QueryTable[2].EntryContext = &Buffer2;
523
525 (PCWSTR)DeviceKeyHandle,
527 NULL,
528 NULL)))
529 {
530 /* Non-fatal error */
531 DPRINT1("Failed to read the LogConf key for %wZ\\%S\n", &Device->DeviceID, InstanceId);
532 }
533
534 /* Insert the newly created device into the list */
535 InsertTailList(&DeviceExtension->DeviceListHead,
536 &Device->ListEntry);
537 DeviceExtension->DeviceListCount++;
538 Device = NULL;
539
540cleanup:
541 if (DeviceKeyHandle != NULL)
542 {
543 ZwClose(DeviceKeyHandle);
544 }
545 if (Device != NULL)
546 {
547 /* We have a device that has not been added to device list. We need to clean it up */
548 RtlFreeUnicodeString(&Device->DeviceID);
549 RtlFreeUnicodeString(&Device->InstanceID);
551 }
552 return Status;
553}
554
555static NTSTATUS
557 IN HANDLE SubKey,
559{
560 UNICODE_STRING DeviceReportedValue = RTL_CONSTANT_STRING(L"DeviceReported");
562 UNICODE_STRING InstanceIDU;
563 PKEY_VALUE_FULL_INFORMATION pKeyValueFullInformation;
564 HANDLE InstanceKey, ControlKey;
566 ULONG Size, DeviceReported, ResultLength;
568
569 Size = 128;
570 pKeyValueFullInformation = ExAllocatePool(PagedPool, Size);
571 if (!pKeyValueFullInformation)
573
574 /* Open Instance key */
575 RtlInitUnicodeString(&InstanceIDU, InstanceID);
577 &InstanceIDU,
579 SubKey,
580 NULL);
581 Status = ZwOpenKey(&InstanceKey,
584 if (!NT_SUCCESS(Status))
585 {
586 ExFreePool(pKeyValueFullInformation);
587 return Status;
588 }
589
590 /* Read 'DeviceReported' Key */
591 Status = ZwQueryValueKey(InstanceKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
593 {
594 ZwClose(InstanceKey);
595 ExFreePool(pKeyValueFullInformation);
596 DPRINT("No 'DeviceReported' value\n");
597 return STATUS_SUCCESS;
598 }
599 else if (!NT_SUCCESS(Status))
600 {
601 ZwClose(InstanceKey);
602 ExFreePool(pKeyValueFullInformation);
603 return Status;
604 }
605 if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
606 {
607 ZwClose(InstanceKey);
608 ExFreePool(pKeyValueFullInformation);
609 return STATUS_UNSUCCESSFUL;
610 }
611 RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
612 /* FIXME: Check DeviceReported value? */
613 ASSERT(DeviceReported == 1);
614
615 /* Open Control key */
617 &Control,
619 InstanceKey,
620 NULL);
621 Status = ZwOpenKey(&ControlKey,
624 ZwClose(InstanceKey);
626 {
627 DPRINT("No 'Control' key\n");
629 }
630 else if (!NT_SUCCESS(Status))
631 {
632 ExFreePool(pKeyValueFullInformation);
633 return Status;
634 }
635
636 /* Read 'DeviceReported' Key */
637 Status = ZwQueryValueKey(ControlKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
638 ZwClose(ControlKey);
640 {
641 ExFreePool(pKeyValueFullInformation);
642 DPRINT("No 'DeviceReported' value\n");
644 }
645 else if (!NT_SUCCESS(Status))
646 {
647 ExFreePool(pKeyValueFullInformation);
648 return Status;
649 }
650 if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
651 {
652 ExFreePool(pKeyValueFullInformation);
653 return STATUS_UNSUCCESSFUL;
654 }
655 RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
656 /* FIXME: Check DeviceReported value? */
657 ASSERT(DeviceReported == 1);
658
659 ExFreePool(pKeyValueFullInformation);
660 return STATUS_SUCCESS;
661}
662
663static NTSTATUS
666{
667 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
668 PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
669 UNICODE_STRING LegacyU = RTL_CONSTANT_STRING(L"LEGACY_");
672 UNICODE_STRING DevicePath;
675 ULONG KeyInfoSize, SubKeyInfoSize;
676 ULONG ResultSize;
677 ULONG Index1, Index2;
679
680 DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
681
682 DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
683 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
684
685 /* Should hold most key names, but we reallocate below if it's too small */
686 KeyInfoSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + 64 * sizeof(WCHAR);
688 KeyInfoSize + sizeof(UNICODE_NULL),
690 if (!KeyInfo)
691 {
692 DPRINT("ExAllocatePoolWithTag() failed\n");
694 goto cleanup;
695 }
696 SubKeyInfoSize = KeyInfoSize;
697 SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
698 SubKeyInfoSize + sizeof(UNICODE_NULL),
700 if (!SubKeyInfo)
701 {
702 DPRINT("ExAllocatePoolWithTag() failed\n");
704 goto cleanup;
705 }
706
708 if (!NT_SUCCESS(Status))
709 {
710 DPRINT("IopOpenRegistryKeyEx(%wZ) failed with status 0x%08lx\n", &KeyName, Status);
711 goto cleanup;
712 }
713
714 /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
715 * KeyHandle. We'll first do a first enumeration to have first level keys,
716 * and an inner one to have the real devices list.
717 */
718 Index1 = 0;
719 while (TRUE)
720 {
721 Status = ZwEnumerateKey(
722 KeyHandle,
723 Index1,
725 KeyInfo,
726 KeyInfoSize,
727 &ResultSize);
729 {
731 break;
732 }
733 else if (Status == STATUS_BUFFER_OVERFLOW ||
735 {
736 ASSERT(KeyInfoSize < ResultSize);
737 KeyInfoSize = ResultSize;
740 KeyInfoSize + sizeof(UNICODE_NULL),
742 if (!KeyInfo)
743 {
744 DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", KeyInfoSize);
746 goto cleanup;
747 }
748 continue;
749 }
750 else if (!NT_SUCCESS(Status))
751 {
752 DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
753 goto cleanup;
754 }
755
756 /* Terminate the string */
757 KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
758
759 /* Check if it is a legacy driver */
761 if (RtlPrefixUnicodeString(&LegacyU, &SubKeyName, FALSE))
762 {
763 DPRINT("Ignoring legacy driver '%wZ'\n", &SubKeyName);
764 Index1++;
765 continue;
766 }
767
768 /* Open the key */
770 if (!NT_SUCCESS(Status))
771 {
772 DPRINT("IopOpenRegistryKeyEx() failed for '%wZ' with status 0x%lx\n",
774 break;
775 }
776
777 /* Enumerate the sub-keys */
778 Index2 = 0;
779 while (TRUE)
780 {
781 Status = ZwEnumerateKey(
783 Index2,
785 SubKeyInfo,
786 SubKeyInfoSize,
787 &ResultSize);
789 {
790 break;
791 }
792 else if (Status == STATUS_BUFFER_OVERFLOW ||
794 {
795 ASSERT(SubKeyInfoSize < ResultSize);
796 SubKeyInfoSize = ResultSize;
797 ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
798 SubKeyInfo = ExAllocatePoolWithTag(PagedPool,
799 SubKeyInfoSize + sizeof(UNICODE_NULL),
801 if (!SubKeyInfo)
802 {
803 DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", SubKeyInfoSize);
805 goto cleanup;
806 }
807 continue;
808 }
809 else if (!NT_SUCCESS(Status))
810 {
811 DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
812 break;
813 }
814
815 /* Terminate the string */
816 SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
817
818 /* Compute device ID */
819 DevicePath.Length = 0;
820 DevicePath.MaximumLength = sizeof(REGSTR_KEY_ROOTENUM) + sizeof(L'\\') + SubKeyName.Length;
822 DevicePath.MaximumLength,
824 if (DevicePath.Buffer == NULL)
825 {
826 DPRINT1("ExAllocatePoolWithTag() failed\n");
828 goto cleanup;
829 }
830
833 DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
834
835 Status = IopShouldProcessDevice(SubKeyHandle, SubKeyInfo->Name);
836 if (NT_SUCCESS(Status))
837 {
838 Status = CreateDeviceFromRegistry(DeviceExtension,
839 &DevicePath,
840 SubKeyInfo->Name,
842
843 /* If CreateDeviceFromRegistry didn't take ownership and zero this,
844 * we need to free it
845 */
846 RtlFreeUnicodeString(&DevicePath);
847
848 if (!NT_SUCCESS(Status))
849 {
850 goto cleanup;
851 }
852 }
853 else if (Status == STATUS_NO_SUCH_DEVICE)
854 {
855 DPRINT("Skipping device %wZ\\%S (not reported yet)\n", &DevicePath, SubKeyInfo->Name);
856 }
857 else
858 {
859 goto cleanup;
860 }
861
862 Index2++;
863 }
864
867 Index1++;
868 }
869
870cleanup:
871 if (SubKeyHandle != NULL)
873 if (KeyHandle != NULL)
875 if (KeyInfo)
877 if (SubKeyInfo)
878 ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
879 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
880 return Status;
881}
882
883/* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
884 * ARGUMENTS:
885 * DeviceObject = Pointer to functional device object of the root bus driver
886 * Irp = Pointer to IRP that should be handled
887 * RETURNS:
888 * Status
889 */
890static NTSTATUS
893 IN PIRP Irp)
894{
895 PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
896 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
897 PDEVICE_RELATIONS Relations = NULL, OtherRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
899 ULONG Size;
901 PLIST_ENTRY NextEntry;
902
903 DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
904
906 if (!NT_SUCCESS(Status))
907 {
908 DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
909 return Status;
910 }
911
912 DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
913
914 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * DeviceExtension->DeviceListCount;
915 if (OtherRelations)
916 {
917 /* Another bus driver has already created a DEVICE_RELATIONS
918 * structure so we must merge this structure with our own */
919
920 Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
921 }
923 if (!Relations)
924 {
925 DPRINT("ExAllocatePoolWithTag() failed\n");
927 goto cleanup;
928 }
929 RtlZeroMemory(Relations, Size);
930 if (OtherRelations)
931 {
932 Relations->Count = OtherRelations->Count;
933 RtlCopyMemory(Relations->Objects, OtherRelations->Objects, sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
934 }
935
936 KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
937
938 /* Start looping */
939 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
940 NextEntry != &DeviceExtension->DeviceListHead;
941 NextEntry = NextEntry->Flink)
942 {
943 /* Get the entry */
944 Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
945
946 if (!Device->Pdo)
947 {
948 /* Create a physical device object for the
949 * device as it does not already have one */
951 DeviceObject->DriverObject,
953 NULL,
956 FALSE,
957 &Device->Pdo);
958 if (!NT_SUCCESS(Status))
959 {
960 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
961 break;
962 }
963
964 PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
965 RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
966 PdoDeviceExtension->Common.IsFDO = FALSE;
967 PdoDeviceExtension->DeviceInfo = Device;
968
969 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
970 Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
971 }
972
973 /* Reference the physical device object. The PnP manager
974 will dereference it again when it is no longer needed */
976
977 Relations->Objects[Relations->Count++] = Device->Pdo;
978 }
979 KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
980
981 Irp->IoStatus.Information = (ULONG_PTR)Relations;
982
983cleanup:
984 if (!NT_SUCCESS(Status))
985 {
986 if (OtherRelations)
987 ExFreePool(OtherRelations);
988 if (Relations)
989 ExFreePool(Relations);
990 if (Device && Device->Pdo)
991 {
993 Device->Pdo = NULL;
994 }
995 }
996
997 return Status;
998}
999
1000/*
1001 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
1002 * ARGUMENTS:
1003 * DeviceObject = Pointer to functional device object of the root bus driver
1004 * Irp = Pointer to IRP that should be handled
1005 * RETURNS:
1006 * Status
1007 */
1008static NTSTATUS
1011 IN PIRP Irp)
1012{
1013 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1016
1017 DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1018 Status = Irp->IoStatus.Status;
1020
1021 switch (IrpSp->MinorFunction)
1022 {
1024 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
1026 break;
1027
1029 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1030 if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
1032 else
1033 {
1034 Status = Irp->IoStatus.Status;
1035 if (NT_SUCCESS(Status))
1036 DeviceExtension->State = dsStarted;
1037 }
1038
1039 Irp->IoStatus.Status = Status;
1041 return Status;
1042
1043 case IRP_MN_STOP_DEVICE:
1044 DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
1045 /* Root device cannot be stopped */
1046 Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
1048 return Status;
1049
1050 default:
1051 DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1052 break;
1053 }
1054
1055 if (Status != STATUS_PENDING)
1056 {
1057 Irp->IoStatus.Status = Status;
1059 }
1060
1061 return Status;
1062}
1063
1064static NTSTATUS
1067 IN PIRP Irp,
1069{
1070 PDEVICE_RELATIONS Relations;
1071 NTSTATUS Status = Irp->IoStatus.Status;
1072
1073 if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
1074 return Status;
1075
1076 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
1078 if (!Relations)
1079 {
1080 DPRINT("ExAllocatePoolWithTag() failed\n");
1082 }
1083 else
1084 {
1086 Relations->Count = 1;
1087 Relations->Objects[0] = DeviceObject;
1089 Irp->IoStatus.Information = (ULONG_PTR)Relations;
1090 }
1091
1092 return Status;
1093}
1094
1095static NTSTATUS
1098 IN PIRP Irp,
1100{
1102
1103 DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
1104
1105 if (DeviceCapabilities->Version != 1)
1107
1108 DeviceCapabilities->UniqueID = TRUE;
1109 /* FIXME: Fill other fields */
1110
1111 return STATUS_SUCCESS;
1112}
1113
1114static NTSTATUS
1117 IN PIRP Irp,
1119{
1120 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1122
1123 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1124
1125 if (DeviceExtension->DeviceInfo->ResourceList)
1126 {
1127 /* Copy existing resource requirement list */
1129 PagedPool,
1130 DeviceExtension->DeviceInfo->ResourceListSize);
1131 if (!ResourceList)
1132 return STATUS_NO_MEMORY;
1133
1136 DeviceExtension->DeviceInfo->ResourceList,
1137 DeviceExtension->DeviceInfo->ResourceListSize);
1138
1139 Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1140
1141 return STATUS_SUCCESS;
1142 }
1143 else
1144 {
1145 /* No resources so just return without changing the status */
1146 return Irp->IoStatus.Status;
1147 }
1148}
1149
1150static NTSTATUS
1153 IN PIRP Irp,
1155{
1156 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1158
1159 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1160
1161 if (DeviceExtension->DeviceInfo->ResourceRequirementsList)
1162 {
1163 /* Copy existing resource requirement list */
1165 if (!ResourceList)
1166 return STATUS_NO_MEMORY;
1167
1170 DeviceExtension->DeviceInfo->ResourceRequirementsList,
1171 DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
1172
1173 Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1174
1175 return STATUS_SUCCESS;
1176 }
1177 else
1178 {
1179 /* No resource requirements so just return without changing the status */
1180 return Irp->IoStatus.Status;
1181 }
1182}
1183
1184static NTSTATUS
1187 IN PIRP Irp,
1189{
1190 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1191 DEVICE_TEXT_TYPE DeviceTextType;
1192 NTSTATUS Status = Irp->IoStatus.Status;
1193
1194 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1195 DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
1196
1197 switch (DeviceTextType)
1198 {
1200 {
1202 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
1203
1204 if (DeviceExtension->DeviceInfo->DeviceDescription.Buffer != NULL)
1205 {
1207 &DeviceExtension->DeviceInfo->DeviceDescription,
1208 &String);
1209 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1210 }
1211 break;
1212 }
1213
1215 {
1216 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
1217 break;
1218 }
1219
1220 default:
1221 {
1222 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type 0x%lx\n", DeviceTextType);
1223 }
1224 }
1225
1226 return Status;
1227}
1228
1229static NTSTATUS
1232 IN PIRP Irp,
1234{
1235 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1237 NTSTATUS Status = Irp->IoStatus.Status;
1238
1239 DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1240 IdType = IrpSp->Parameters.QueryId.IdType;
1241
1242 switch (IdType)
1243 {
1244 case BusQueryDeviceID:
1245 {
1247 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
1248
1251 &DeviceExtension->DeviceInfo->DeviceID,
1252 &String);
1253 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1254 break;
1255 }
1256
1259 {
1260 /* Optional, do nothing */
1261 break;
1262 }
1263
1264 case BusQueryInstanceID:
1265 {
1267 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
1268
1271 &DeviceExtension->DeviceInfo->InstanceID,
1272 &String);
1273 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
1274 break;
1275 }
1276
1277 default:
1278 {
1279 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
1280 }
1281 }
1282
1283 return Status;
1284}
1285
1286static NTSTATUS
1289 IN PIRP Irp,
1291{
1292 PPNP_BUS_INFORMATION BusInfo;
1294
1296 if (!BusInfo)
1298 else
1299 {
1301 &BusInfo->BusTypeGuid,
1302 &GUID_BUS_TYPE_INTERNAL,
1303 sizeof(BusInfo->BusTypeGuid));
1304 BusInfo->LegacyBusType = PNPBus;
1305 /* We're the only root bus enumerator on the computer */
1306 BusInfo->BusNumber = 0;
1307 Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
1309 }
1310
1311 return Status;
1312}
1313
1314/*
1315 * FUNCTION: Handle Plug and Play IRPs for the child device
1316 * ARGUMENTS:
1317 * DeviceObject = Pointer to physical device object of the child device
1318 * Irp = Pointer to IRP that should be handled
1319 * RETURNS:
1320 * Status
1321 */
1322static NTSTATUS
1325 IN PIRP Irp)
1326{
1327 PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
1328 PPNPROOT_FDO_DEVICE_EXTENSION FdoDeviceExtension;
1331
1332 DeviceExtension = DeviceObject->DeviceExtension;
1333 FdoDeviceExtension = PnpRootDeviceObject->DeviceExtension;
1334 Status = Irp->IoStatus.Status;
1336
1337 switch (IrpSp->MinorFunction)
1338 {
1339 case IRP_MN_START_DEVICE: /* 0x00 */
1340 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1342 break;
1343
1344 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1346 break;
1347
1348 case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
1349 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
1351 break;
1352
1353 case IRP_MN_QUERY_RESOURCES: /* 0x0a */
1354 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
1356 break;
1357
1358 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
1359 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1361 break;
1362
1363 case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
1364 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
1366 break;
1367
1369 DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1370 break;
1371
1373 /* Remove the device from the device list and decrement the device count*/
1374 KeAcquireGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1375 RemoveEntryList(&DeviceExtension->DeviceInfo->ListEntry);
1376 FdoDeviceExtension->DeviceListCount--;
1377 KeReleaseGuardedMutex(&FdoDeviceExtension->DeviceListLock);
1378
1379 /* Free some strings we created */
1381 RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->DeviceID);
1382 RtlFreeUnicodeString(&DeviceExtension->DeviceInfo->InstanceID);
1383
1384 /* Free the resource requirements list */
1385 if (DeviceExtension->DeviceInfo->ResourceRequirementsList != NULL)
1387
1388 /* Free the boot resources list */
1389 if (DeviceExtension->DeviceInfo->ResourceList != NULL)
1390 ExFreePool(DeviceExtension->DeviceInfo->ResourceList);
1391
1392 /* Free the device info */
1393 ExFreePool(DeviceExtension->DeviceInfo);
1394
1395 /* Finally, delete the device object */
1397
1398 /* Return success */
1400 break;
1401
1402 case IRP_MN_QUERY_ID: /* 0x13 */
1404 break;
1405
1406 case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1407 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1408 break;
1409
1410 case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
1411 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
1413 break;
1414
1415 default:
1416 DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction);
1417 break;
1418 }
1419
1420 if (Status != STATUS_PENDING)
1421 {
1422 Irp->IoStatus.Status = Status;
1424 }
1425
1426 return Status;
1427}
1428
1429/*
1430 * FUNCTION: Handle Plug and Play IRPs
1431 * ARGUMENTS:
1432 * DeviceObject = Pointer to PDO or FDO
1433 * Irp = Pointer to IRP that should be handled
1434 * RETURNS:
1435 * Status
1436 */
1437static NTSTATUS NTAPI
1440 IN PIRP Irp)
1441{
1442 PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
1444
1445 DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1446
1447 if (DeviceExtension->IsFDO)
1449 else
1451
1452 return Status;
1453}
1454
1455/*
1456 * FUNCTION: Handle Power IRPs
1457 * ARGUMENTS:
1458 * DeviceObject = Pointer to PDO or FDO
1459 * Irp = Pointer to IRP that should be handled
1460 * RETURNS:
1461 * Status
1462 */
1463static NTSTATUS NTAPI
1466 IN PIRP Irp)
1467{
1468 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1471
1472 DeviceExtension = DeviceObject->DeviceExtension;
1473 Status = Irp->IoStatus.Status;
1475
1476 if (DeviceExtension->Common.IsFDO)
1477 {
1478 ASSERT(!DeviceExtension->Common.IsFDO);
1481 Status = PoCallDriver(DeviceExtension->Ldo, Irp);
1482 }
1483 else
1484 {
1485 switch (IrpSp->MinorFunction)
1486 {
1487 case IRP_MN_QUERY_POWER:
1488 case IRP_MN_SET_POWER:
1490 break;
1491 }
1492 Irp->IoStatus.Status = Status;
1495 }
1496
1497 return Status;
1498}
1499
1501NTAPI
1505{
1506 PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
1508
1509 DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject, PhysicalDeviceObject);
1510
1512 {
1513 DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
1515 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1516 }
1517
1521 NULL,
1524 TRUE,
1526 if (!NT_SUCCESS(Status))
1527 {
1528 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
1529 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1530 }
1531 DPRINT("Created FDO %p\n", PnpRootDeviceObject);
1532
1534 RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
1535
1536 DeviceExtension->Common.IsFDO = TRUE;
1537 DeviceExtension->State = dsStopped;
1538 InitializeListHead(&DeviceExtension->DeviceListHead);
1539 DeviceExtension->DeviceListCount = 0;
1540 KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
1541
1545 &DeviceExtension->Ldo);
1546 if (!NT_SUCCESS(Status))
1547 {
1548 DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
1549 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
1550 }
1551
1552 PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1553
1554 DPRINT("Done AddDevice()\n");
1555
1556 return STATUS_SUCCESS;
1557}
1558
1559#if MI_TRACE_PFNS
1560PDEVICE_OBJECT IopPfnDumpDeviceObject;
1561
1563PnpRootCreateClose(
1565 _In_ PIRP Irp)
1566{
1567 PIO_STACK_LOCATION IoStack;
1568
1569 if (DeviceObject != IopPfnDumpDeviceObject)
1570 {
1571 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1574 }
1575
1577 if (IoStack->MajorFunction == IRP_MJ_CREATE)
1578 {
1580 }
1581
1582 Irp->IoStatus.Status = STATUS_SUCCESS;
1584 return STATUS_SUCCESS;
1585}
1586#endif
1587
1592{
1593#if MI_TRACE_PFNS
1595 UNICODE_STRING PfnDumpDeviceName = RTL_CONSTANT_STRING(L"\\Device\\PfnDump");
1596#endif
1597
1598 DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
1599
1601
1603
1604#if MI_TRACE_PFNS
1605 DriverObject->MajorFunction[IRP_MJ_CREATE] = PnpRootCreateClose;
1606 DriverObject->MajorFunction[IRP_MJ_CLOSE] = PnpRootCreateClose;
1607#endif
1608 DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
1610
1611#if MI_TRACE_PFNS
1613 0,
1614 &PfnDumpDeviceName,
1616 0,
1617 FALSE,
1618 &IopPfnDumpDeviceObject);
1619 if (!NT_SUCCESS(Status))
1620 {
1621 DPRINT1("Creating PFN Dump device failed with %lx\n", Status);
1622 }
1623 else
1624 {
1625 IopPfnDumpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1626 }
1627#endif
1628
1629 return STATUS_SUCCESS;
1630}
@ DeviceNode
Definition: Node.h:9
unsigned char BOOLEAN
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 FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#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 NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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:1099
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
_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:4196
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4197
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2992
@ 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
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
PDRIVER_OBJECT IopRootDriverObject
Definition: pnpmgr.c:26
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
NTSTATUS NTAPI IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)
Definition: device.c:980
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#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:1115
struct _PNPROOT_PDO_DEVICE_EXTENSION PNPROOT_PDO_DEVICE_EXTENSION
static NTSTATUS NTAPI PnpRootPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1464
static NTSTATUS PdoQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1096
static NTSTATUS NTAPI PnpRootPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1438
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:419
static PDEVICE_OBJECT PnpRootDeviceObject
Definition: pnproot.c:88
static NTSTATUS PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1185
static NTSTATUS PdoQueryBusInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1287
static NTSTATUS PdoQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1151
NTSTATUS PnpRootRegisterDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:130
static NTSTATUS CreateDeviceFromRegistry(_Inout_ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, _Inout_ PUNICODE_STRING DevicePath, _In_ PCWSTR InstanceId, _In_ HANDLE SubKeyHandle)
Definition: pnproot.c:447
struct _PNPROOT_COMMON_DEVICE_EXTENSION * PPNPROOT_COMMON_DEVICE_EXTENSION
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:393
static NTSTATUS PnpRootPdoPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pnproot.c:1323
NTSTATUS NTAPI PnpRootDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: pnproot.c:1589
static NTSTATUS PdoQueryId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1230
NTSTATUS NTAPI PnpRootAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnproot.c:1502
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:891
static NTSTATUS PdoQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pnproot.c:1065
static NTSTATUS LocateChildDevice(IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension, IN PCUNICODE_STRING DeviceId, IN PCWSTR InstanceId, OUT PPNPROOT_DEVICE *ChildDevice OPTIONAL)
Definition: pnproot.c:93
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT OPTIONAL PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:186
static NTSTATUS EnumerateDevices(IN PDEVICE_OBJECT DeviceObject)
Definition: pnproot.c:664
struct _PNPROOT_DEVICE PNPROOT_DEVICE
PNPROOT_DEVICE_STATE
Definition: pnproot.c:42
@ dsSurpriseRemoved
Definition: pnproot.c:47
@ dsStopped
Definition: pnproot.c:43
@ dsPaused
Definition: pnproot.c:45
@ dsStarted
Definition: pnproot.c:44
@ dsRemoved
Definition: pnproot.c:46
struct _BUFFER * PBUFFER
static NTSTATUS IopShouldProcessDevice(IN HANDLE SubKey, IN PCWSTR InstanceID)
Definition: pnproot.c:556
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:1009
struct _PNPROOT_COMMON_DEVICE_EXTENSION PNPROOT_COMMON_DEVICE_EXTENSION
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:148
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:110
#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
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 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:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID * Data
Definition: pnproot.c:84
PULONG Length
Definition: pnproot.c:85
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2220
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
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:79
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:69
PNPROOT_DEVICE_STATE State
Definition: pnproot.c:73
PPNPROOT_DEVICE DeviceInfo
Definition: pnproot.c:62
PNPROOT_COMMON_DEVICE_EXTENSION Common
Definition: pnproot.c:60
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
#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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
@ 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
#define IRP_MN_STOP_DEVICE
@ 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