2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/resource.c
5 * PURPOSE: Hardware resource managment
7 * PROGRAMMERS: David Welch (welch@mcmail.com)
8 * Alex Ionescu (alex@relsoft.net)
11 /* INCLUDES *****************************************************************/
16 /* GLOBALS *******************************************************************/
18 static CONFIGURATION_INFORMATION
19 _SystemConfigurationInformation
= { 0, 0, 0, 0, 0, 0, 0, FALSE
, FALSE
, 0, 0 };
21 /* API Parameters to Pass in IopQueryBusDescription */
22 typedef struct IO_QUERY
{
23 PINTERFACE_TYPE BusType
;
25 PCONFIGURATION_TYPE ControllerType
;
26 PULONG ControllerNumber
;
27 PCONFIGURATION_TYPE PeripheralType
;
28 PULONG PeripheralNumber
;
29 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
;
31 } IO_QUERY
, *PIO_QUERY
;
33 PWSTR ArcTypes
[42] = {
36 L
"FloatingPointProcessor",
46 L
"MultifunctionAdapter",
54 L
"ParallelController",
56 L
"KeyboardController",
60 L
"FloppyDiskPeripheral",
66 L
"KeyboardPeripheral",
67 L
"TerminalPeripheral",
72 L
"DockingInformation",
73 L
"RealModeIrqRoutingTable",
74 L
"RealModePCIEnumeration",
78 /* PRIVATE FUNCTIONS **********************************************************/
81 * IopQueryDeviceDescription
84 * Reads and returns Hardware information from the appropriate hardware
85 * registry key. Helper sub of IopQueryBusDescription.
88 * Query - What the parent function wants.
89 * RootKey - Which key to look in
90 * RootKeyHandle - Handle to the key
92 * BusInformation - The Configuration Information Sent
99 IopQueryDeviceDescription(
101 UNICODE_STRING RootKey
,
102 HANDLE RootKeyHandle
,
104 PKEY_VALUE_FULL_INFORMATION
*BusInformation
)
106 NTSTATUS Status
= STATUS_SUCCESS
;
108 /* Controller Stuff */
109 UNICODE_STRING ControllerString
;
110 UNICODE_STRING ControllerRootRegName
= RootKey
;
111 UNICODE_STRING ControllerRegName
;
112 HANDLE ControllerKeyHandle
;
113 PKEY_FULL_INFORMATION ControllerFullInformation
= NULL
;
114 PKEY_VALUE_FULL_INFORMATION ControllerInformation
[3] = {NULL
, NULL
, NULL
};
115 ULONG ControllerNumber
;
116 ULONG ControllerLoop
;
117 ULONG MaximumControllerNumber
;
119 /* Peripheral Stuff */
120 UNICODE_STRING PeripheralString
;
121 HANDLE PeripheralKeyHandle
;
122 PKEY_FULL_INFORMATION PeripheralFullInformation
;
123 PKEY_VALUE_FULL_INFORMATION PeripheralInformation
[3] = {NULL
, NULL
, NULL
};
124 ULONG PeripheralNumber
;
125 ULONG PeripheralLoop
;
126 ULONG MaximumPeripheralNumber
;
128 /* Global Registry Stuff */
129 OBJECT_ATTRIBUTES ObjectAttributes
;
130 ULONG LenFullInformation
;
131 ULONG LenKeyFullInformation
;
132 UNICODE_STRING TempString
;
133 WCHAR TempBuffer
[14];
136 L
"Configuration Data",
137 L
"Component Information"
140 /* Temporary String */
141 TempString
.MaximumLength
= sizeof(TempBuffer
);
142 TempString
.Length
= 0;
143 TempString
.Buffer
= TempBuffer
;
145 /* Add Controller Name to String */
146 RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
147 RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->ControllerType
]);
149 /* Set the Controller Number if specified */
150 if (Query
->ControllerNumber
&& *(Query
->ControllerNumber
))
152 ControllerNumber
= *Query
->ControllerNumber
;
153 MaximumControllerNumber
= ControllerNumber
+ 1;
155 /* Find out how many Controller Numbers there are */
156 InitializeObjectAttributes(
158 &ControllerRootRegName
,
159 OBJ_CASE_INSENSITIVE
,
163 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
164 if (NT_SUCCESS(Status
))
166 /* How much buffer space */
167 ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
170 ControllerFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
172 /* Get the Information */
173 Status
= ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, ControllerFullInformation
, LenFullInformation
, &LenFullInformation
);
174 ZwClose(ControllerKeyHandle
);
175 ControllerKeyHandle
= NULL
;
178 /* No controller was found, go back to function. */
179 if (!NT_SUCCESS(Status
))
181 if (ControllerFullInformation
!= NULL
)
182 ExFreePoolWithTag(ControllerFullInformation
, TAG_IO_RESOURCE
);
186 /* Find out Controller Numbers */
187 ControllerNumber
= 0;
188 MaximumControllerNumber
= ControllerFullInformation
->SubKeys
;
191 ExFreePoolWithTag(ControllerFullInformation
, TAG_IO_RESOURCE
);
192 ControllerFullInformation
= NULL
;
196 ControllerRegName
= ControllerRootRegName
;
198 /* Loop through controllers */
199 for (; ControllerNumber
< MaximumControllerNumber
; ControllerNumber
++)
202 ControllerRootRegName
= ControllerRegName
;
204 /* Controller Number to Registry String */
205 Status
= RtlIntegerToUnicodeString(ControllerNumber
, 10, &TempString
);
208 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
209 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
211 /* Something messed up */
212 if (!NT_SUCCESS(Status
)) break;
214 /* Open the Registry Key */
215 InitializeObjectAttributes(
217 &ControllerRootRegName
,
218 OBJ_CASE_INSENSITIVE
,
222 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
224 /* Read the Configuration Data... */
225 if (NT_SUCCESS(Status
))
227 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
229 /* Identifier String First */
230 RtlInitUnicodeString(&ControllerString
, Strings
[ControllerLoop
]);
232 /* How much buffer space */
233 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
235 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
239 ControllerInformation
[ControllerLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
241 /* Get the Information */
242 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, ControllerInformation
[ControllerLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
246 ZwClose(ControllerKeyHandle
);
247 ControllerKeyHandle
= NULL
;
250 /* Something messed up */
251 if (!NT_SUCCESS(Status
))
254 /* We now have Bus *AND* Controller Information.. is it enough? */
255 if (!Query
->PeripheralType
|| !(*Query
->PeripheralType
))
257 Status
= Query
->CalloutRoutine(
259 &ControllerRootRegName
,
263 *Query
->ControllerType
,
265 ControllerInformation
,
272 /* Not enough...caller also wants peripheral name */
273 Status
= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
274 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->PeripheralType
]);
276 /* Something messed up */
277 if (!NT_SUCCESS(Status
)) goto EndLoop
;
279 /* Set the Peripheral Number if specified */
280 if (Query
->PeripheralNumber
&& *Query
->PeripheralNumber
)
282 PeripheralNumber
= *Query
->PeripheralNumber
;
283 MaximumPeripheralNumber
= PeripheralNumber
+ 1;
285 /* Find out how many Peripheral Numbers there are */
286 InitializeObjectAttributes(
288 &ControllerRootRegName
,
289 OBJ_CASE_INSENSITIVE
,
293 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
295 if (NT_SUCCESS(Status
))
297 /* How much buffer space */
298 ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
301 PeripheralFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
303 /* Get the Information */
304 Status
= ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, PeripheralFullInformation
, LenFullInformation
, &LenFullInformation
);
305 ZwClose(PeripheralKeyHandle
);
306 PeripheralKeyHandle
= NULL
;
309 /* No controller was found, go back to function but clean up first */
310 if (!NT_SUCCESS(Status
))
312 Status
= STATUS_SUCCESS
;
316 /* Find out Peripheral Number */
317 PeripheralNumber
= 0;
318 MaximumPeripheralNumber
= PeripheralFullInformation
->SubKeys
;
321 ExFreePoolWithTag(PeripheralFullInformation
, TAG_IO_RESOURCE
);
322 PeripheralFullInformation
= NULL
;
326 ControllerRegName
= ControllerRootRegName
;
328 /* Loop through Peripherals */
329 for (; PeripheralNumber
< MaximumPeripheralNumber
; PeripheralNumber
++)
332 ControllerRootRegName
= ControllerRegName
;
334 /* Peripheral Number to Registry String */
335 Status
= RtlIntegerToUnicodeString(PeripheralNumber
, 10, &TempString
);
338 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
339 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
341 /* Something messed up */
342 if (!NT_SUCCESS(Status
)) break;
344 /* Open the Registry Key */
345 InitializeObjectAttributes(
347 &ControllerRootRegName
,
348 OBJ_CASE_INSENSITIVE
,
352 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
354 if (NT_SUCCESS(Status
))
356 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
358 /* Identifier String First */
359 RtlInitUnicodeString(&PeripheralString
, Strings
[PeripheralLoop
]);
361 /* How much buffer space */
362 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
364 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
366 PeripheralInformation
[PeripheralLoop
] = NULL
;
371 PeripheralInformation
[PeripheralLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
373 /* Get the Information */
374 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, PeripheralInformation
[PeripheralLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
378 ZwClose(PeripheralKeyHandle
);
379 PeripheralKeyHandle
= NULL
;
381 /* We now have everything the caller could possibly want */
382 if (NT_SUCCESS(Status
))
384 Status
= Query
->CalloutRoutine(
386 &ControllerRootRegName
,
390 *Query
->ControllerType
,
392 ControllerInformation
,
393 *Query
->PeripheralType
,
395 PeripheralInformation
);
398 /* Free the allocated memory */
399 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
401 if (PeripheralInformation
[PeripheralLoop
])
403 ExFreePoolWithTag(PeripheralInformation
[PeripheralLoop
], TAG_IO_RESOURCE
);
404 PeripheralInformation
[PeripheralLoop
] = NULL
;
408 /* Something Messed up */
409 if (!NT_SUCCESS(Status
)) break;
414 /* Free the allocated memory */
415 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
417 if (ControllerInformation
[ControllerLoop
])
419 ExFreePoolWithTag(ControllerInformation
[ControllerLoop
], TAG_IO_RESOURCE
);
420 ControllerInformation
[ControllerLoop
] = NULL
;
424 /* Something Messed up */
425 if (!NT_SUCCESS(Status
)) break;
432 * IopQueryBusDescription
435 * Reads and returns Hardware information from the appropriate hardware
436 * registry key. Helper sub of IoQueryDeviceDescription. Has two modes
437 * of operation, either looking for Root Bus Types or for sub-Bus
441 * Query - What the parent function wants.
442 * RootKey - Which key to look in
443 * RootKeyHandle - Handle to the key
445 * KeyIsRoot - Whether we are looking for Root Bus Types or
446 * information under them.
453 IopQueryBusDescription(
455 UNICODE_STRING RootKey
,
456 HANDLE RootKeyHandle
,
462 UNICODE_STRING SubRootRegName
;
463 UNICODE_STRING BusString
;
464 UNICODE_STRING SubBusString
;
465 ULONG LenBasicInformation
= 0;
466 ULONG LenFullInformation
;
467 ULONG LenKeyFullInformation
;
469 HANDLE SubRootKeyHandle
;
470 PKEY_FULL_INFORMATION FullInformation
;
471 PKEY_BASIC_INFORMATION BasicInformation
= NULL
;
472 OBJECT_ATTRIBUTES ObjectAttributes
;
473 PKEY_VALUE_FULL_INFORMATION BusInformation
[3] = {NULL
, NULL
, NULL
};
475 /* How much buffer space */
476 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
478 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
482 FullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
485 return STATUS_NO_MEMORY
;
487 /* Get the Information */
488 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, FullInformation
, LenFullInformation
, &LenFullInformation
);
490 /* Everything was fine */
491 if (NT_SUCCESS(Status
))
493 /* Buffer needed for all the keys under this one */
494 LenBasicInformation
= FullInformation
->MaxNameLen
+ sizeof(KEY_BASIC_INFORMATION
);
497 BasicInformation
= ExAllocatePoolWithTag(PagedPool
, LenBasicInformation
, TAG_IO_RESOURCE
);
500 /* Deallocate the old Buffer */
501 ExFreePoolWithTag(FullInformation
, TAG_IO_RESOURCE
);
503 /* Try to find a Bus */
504 for (BusLoop
= 0; NT_SUCCESS(Status
); BusLoop
++)
506 /* Bus parameter was passed and number was matched */
507 if ((Query
->BusNumber
) && (*(Query
->BusNumber
)) == *Bus
) break;
509 /* Enumerate the Key */
510 Status
= ZwEnumerateKey(
518 /* Everything enumerated */
519 if (!NT_SUCCESS(Status
)) break;
521 /* What Bus are we going to go down? (only check if this is a Root Key) */
524 if (wcsncmp(BasicInformation
->Name
, L
"MultifunctionAdapter", BasicInformation
->NameLength
/ 2) &&
525 wcsncmp(BasicInformation
->Name
, L
"EisaAdapter", BasicInformation
->NameLength
/ 2) &&
526 wcsncmp(BasicInformation
->Name
, L
"TcAdapter", BasicInformation
->NameLength
/ 2))
528 /* Nothing found, check next */
533 /* Enumerate the Bus. */
534 BusString
.Buffer
= BasicInformation
->Name
;
535 BusString
.Length
= (USHORT
)BasicInformation
->NameLength
;
536 BusString
.MaximumLength
= (USHORT
)BasicInformation
->NameLength
;
538 /* Open a handle to the Root Registry Key */
539 InitializeObjectAttributes(
542 OBJ_CASE_INSENSITIVE
,
546 Status
= ZwOpenKey(&SubRootKeyHandle
, KEY_READ
, &ObjectAttributes
);
548 /* Go on if we can't */
549 if (!NT_SUCCESS(Status
)) continue;
551 /* Key opened. Create the path */
552 SubRootRegName
= RootKey
;
553 RtlAppendUnicodeToString(&SubRootRegName
, L
"\\");
554 RtlAppendUnicodeStringToString(&SubRootRegName
, &BusString
);
558 /* Parsing a SubBus-key */
562 L
"Configuration Data",
563 L
"Component Information"};
565 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
567 /* Identifier String First */
568 RtlInitUnicodeString(&SubBusString
, Strings
[SubBusLoop
]);
570 /* How much buffer space */
571 ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
574 BusInformation
[SubBusLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
576 /* Get the Information */
577 Status
= ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, BusInformation
[SubBusLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
580 if (NT_SUCCESS(Status
))
582 /* Do we have something */
583 if (BusInformation
[1] != NULL
&&
584 BusInformation
[1]->DataLength
!= 0 &&
585 /* Does it match what we want? */
586 (((PCM_FULL_RESOURCE_DESCRIPTOR
)((ULONG_PTR
)BusInformation
[1] + BusInformation
[1]->DataOffset
))->InterfaceType
== *(Query
->BusType
)))
591 /* Is it the bus we wanted */
592 if (Query
->BusNumber
== NULL
|| *(Query
->BusNumber
) == *Bus
)
594 /* If we don't want Controller Information, we're done... call the callback */
595 if (Query
->ControllerType
== NULL
)
597 Status
= Query
->CalloutRoutine(
610 /* We want Controller Info...get it */
611 Status
= IopQueryDeviceDescription(Query
, SubRootRegName
, RootKeyHandle
, *Bus
, (PKEY_VALUE_FULL_INFORMATION
*)BusInformation
);
617 /* Free the allocated memory */
618 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
620 if (BusInformation
[SubBusLoop
])
622 ExFreePoolWithTag(BusInformation
[SubBusLoop
], TAG_IO_RESOURCE
);
623 BusInformation
[SubBusLoop
] = NULL
;
627 /* Exit the Loop if we found the bus */
628 if (Query
->BusNumber
!= NULL
&& *(Query
->BusNumber
) == *Bus
)
630 ZwClose(SubRootKeyHandle
);
631 SubRootKeyHandle
= NULL
;
636 /* Enumerate the buses below us recursively if we haven't found the bus yet */
637 Status
= IopQueryBusDescription(Query
, SubRootRegName
, SubRootKeyHandle
, Bus
, !KeyIsRoot
);
639 /* Everything enumerated */
640 if (Status
== STATUS_NO_MORE_ENTRIES
) Status
= STATUS_SUCCESS
;
642 ZwClose(SubRootKeyHandle
);
643 SubRootKeyHandle
= NULL
;
646 /* Free the last remaining Allocated Memory */
647 if (BasicInformation
)
648 ExFreePoolWithTag(BasicInformation
, TAG_IO_RESOURCE
);
653 /* PUBLIC FUNCTIONS ***********************************************************/
658 PCONFIGURATION_INFORMATION NTAPI
659 IoGetConfigurationInformation(VOID
)
661 return(&_SystemConfigurationInformation
);
668 IoReportResourceUsage(PUNICODE_STRING DriverClassName
,
669 PDRIVER_OBJECT DriverObject
,
670 PCM_RESOURCE_LIST DriverList
,
671 ULONG DriverListSize
,
672 PDEVICE_OBJECT DeviceObject
,
673 PCM_RESOURCE_LIST DeviceList
,
674 ULONG DeviceListSize
,
675 BOOLEAN OverrideConflict
,
676 PBOOLEAN ConflictDetected
)
678 * FUNCTION: Reports hardware resources in the
679 * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
680 * loaded driver cannot attempt to use the same resources.
682 * DriverClassName - The class of driver under which the resource
683 * information should be stored.
684 * DriverObject - The driver object that was input to the
686 * DriverList - Resources that claimed for the driver rather than
688 * DriverListSize - Size in bytes of the DriverList.
689 * DeviceObject - The device object for which resources should be
691 * DeviceList - List of resources which should be claimed for the
693 * DeviceListSize - Size of the per-device resource list in bytes.
694 * OverrideConflict - True if the resources should be cliamed
695 * even if a conflict is found.
696 * ConflictDetected - Points to a variable that receives TRUE if
697 * a conflict is detected with another driver.
701 *ConflictDetected
= FALSE
;
702 return STATUS_SUCCESS
;
709 IoAssignResources(PUNICODE_STRING RegistryPath
,
710 PUNICODE_STRING DriverClassName
,
711 PDRIVER_OBJECT DriverObject
,
712 PDEVICE_OBJECT DeviceObject
,
713 PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources
,
714 PCM_RESOURCE_LIST
* AllocatedResources
)
717 return(STATUS_NOT_IMPLEMENTED
);
722 * Reads and returns Hardware information from the appropriate hardware registry key.
725 * BusType - MCA, ISA, EISA...specifies the Bus Type
726 * BusNumber - Which bus of above should be queried
727 * ControllerType - Specifices the Controller Type
728 * ControllerNumber - Which of the controllers to query.
729 * CalloutRoutine - Which function to call for each valid query.
730 * Context - Value to pass to the callback.
740 IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL
,
741 PULONG BusNumber OPTIONAL
,
742 PCONFIGURATION_TYPE ControllerType OPTIONAL
,
743 PULONG ControllerNumber OPTIONAL
,
744 PCONFIGURATION_TYPE PeripheralType OPTIONAL
,
745 PULONG PeripheralNumber OPTIONAL
,
746 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
,
750 ULONG BusLoopNumber
= -1; /* Root Bus */
751 OBJECT_ATTRIBUTES ObjectAttributes
;
752 UNICODE_STRING RootRegKey
;
753 HANDLE RootRegHandle
;
754 WCHAR RootRegString
[] = L
"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
757 /* Set up the String */
758 RootRegKey
.Length
= 0;
759 RootRegKey
.MaximumLength
= 2048;
760 RootRegKey
.Buffer
= ExAllocatePoolWithTag(PagedPool
, RootRegKey
.MaximumLength
, TAG_IO_RESOURCE
);
761 RtlAppendUnicodeToString(&RootRegKey
, RootRegString
);
763 /* Open a handle to the Root Registry Key */
764 InitializeObjectAttributes(
767 OBJ_CASE_INSENSITIVE
,
771 Status
= ZwOpenKey(&RootRegHandle
, KEY_READ
, &ObjectAttributes
);
773 if (NT_SUCCESS(Status
))
775 /* Use a helper function to loop though this key and get the info */
776 Query
.BusType
= BusType
;
777 Query
.BusNumber
= BusNumber
;
778 Query
.ControllerType
= ControllerType
;
779 Query
.ControllerNumber
= ControllerNumber
;
780 Query
.PeripheralType
= PeripheralType
;
781 Query
.PeripheralNumber
= PeripheralNumber
;
782 Query
.CalloutRoutine
= CalloutRoutine
;
783 Query
.Context
= Context
;
784 Status
= IopQueryBusDescription(&Query
, RootRegKey
, RootRegHandle
, &BusLoopNumber
, TRUE
);
787 ZwClose(RootRegHandle
);
791 ExFreePoolWithTag(RootRegKey
.Buffer
, TAG_IO_RESOURCE
);
800 IoReportHalResourceUsage(PUNICODE_STRING HalDescription
,
801 PCM_RESOURCE_LIST RawList
,
802 PCM_RESOURCE_LIST TranslatedList
,
806 * Reports hardware resources of the HAL in the
807 * \Registry\Machine\Hardware\ResourceMap tree.
809 * HalDescription: Descriptive name of the HAL.
810 * RawList: List of raw (bus specific) resources which should be
811 * claimed for the HAL.
812 * TranslatedList: List of translated (system wide) resources which
813 * should be claimed for the HAL.
814 * ListSize: Size in bytes of the raw and translated resource lists.
815 * Both lists have the same size.
820 OBJECT_ATTRIBUTES ObjectAttributes
;
824 HANDLE ResourcemapKey
;
826 HANDLE DescriptionKey
;
828 /* Open/Create 'RESOURCEMAP' key. */
829 RtlInitUnicodeString(&Name
,
830 L
"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
831 InitializeObjectAttributes(&ObjectAttributes
,
833 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
836 Status
= ZwCreateKey(&ResourcemapKey
,
843 if (!NT_SUCCESS(Status
))
846 /* Open/Create 'Hardware Abstraction Layer' key */
847 RtlInitUnicodeString(&Name
,
848 L
"Hardware Abstraction Layer");
849 InitializeObjectAttributes(&ObjectAttributes
,
851 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
854 Status
= ZwCreateKey(&HalKey
,
861 ZwClose(ResourcemapKey
);
862 if (!NT_SUCCESS(Status
))
865 /* Create 'HalDescription' key */
866 InitializeObjectAttributes(&ObjectAttributes
,
868 OBJ_CASE_INSENSITIVE
,
871 Status
= ZwCreateKey(&DescriptionKey
,
879 if (!NT_SUCCESS(Status
))
882 /* Add '.Raw' value. */
883 RtlInitUnicodeString(&Name
,
885 Status
= ZwSetValueKey(DescriptionKey
,
891 if (!NT_SUCCESS(Status
))
893 ZwClose(DescriptionKey
);
897 /* Add '.Translated' value. */
898 RtlInitUnicodeString(&Name
,
900 Status
= ZwSetValueKey(DescriptionKey
,
906 ZwClose(DescriptionKey
);