3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/resource.c
6 * PURPOSE: Hardware resource managment
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 * Alex Ionescu (alex@relsoft.net)
12 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 static CONFIGURATION_INFORMATION
20 SystemConfigurationInformation
= {0, 0, 0, 0, 0, 0, 0, FALSE
, FALSE
};
22 /* API Parameters to Pass in IopQueryBusDescription */
23 typedef struct IO_QUERY
{
24 PINTERFACE_TYPE BusType
;
26 PCONFIGURATION_TYPE ControllerType
;
27 PULONG ControllerNumber
;
28 PCONFIGURATION_TYPE PeripheralType
;
29 PULONG PeripheralNumber
;
30 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
;
32 } IO_QUERY
, *PIO_QUERY
;
34 PWSTR ArcTypes
[42] = {
37 L
"FloatingPointProcessor",
47 L
"MultifunctionAdapter",
55 L
"ParallelController",
57 L
"KeyboardController",
61 L
"FloppyDiskPeripheral",
67 L
"KeyboardPeripheral",
68 L
"TerminalPeripheral",
73 L
"DockingInformation",
74 L
"RealModeIrqRoutingTable",
75 L
"RealModePCIEnumeration",
79 #define TAG_IO_RESOURCE TAG('R', 'S', 'R', 'C')
81 /* PRIVATE FUNCTIONS **********************************************************/
84 * IopQueryDeviceDescription
87 * Reads and returns Hardware information from the appropriate hardware
88 * registry key. Helper sub of IopQueryBusDescription.
91 * Query - What the parent function wants.
92 * RootKey - Which key to look in
93 * RootKeyHandle - Handle to the key
95 * BusInformation - The Configuration Information Sent
102 IopQueryDeviceDescription(
104 UNICODE_STRING RootKey
,
105 HANDLE RootKeyHandle
,
107 PKEY_VALUE_FULL_INFORMATION
*BusInformation
)
109 NTSTATUS Status
= STATUS_SUCCESS
;
111 /* Controller Stuff */
112 UNICODE_STRING ControllerString
;
113 UNICODE_STRING ControllerRootRegName
= RootKey
;
114 UNICODE_STRING ControllerRegName
;
115 HANDLE ControllerKeyHandle
;
116 PKEY_FULL_INFORMATION ControllerFullInformation
= NULL
;
117 PKEY_VALUE_FULL_INFORMATION ControllerInformation
[3] = {NULL
, NULL
, NULL
};
118 ULONG ControllerNumber
;
119 ULONG ControllerLoop
;
120 ULONG MaximumControllerNumber
;
122 /* Peripheral Stuff */
123 UNICODE_STRING PeripheralString
;
124 HANDLE PeripheralKeyHandle
;
125 PKEY_FULL_INFORMATION PeripheralFullInformation
;
126 PKEY_VALUE_FULL_INFORMATION PeripheralInformation
[3] = {NULL
, NULL
, NULL
};
127 ULONG PeripheralNumber
;
128 ULONG PeripheralLoop
;
129 ULONG MaximumPeripheralNumber
;
131 /* Global Registry Stuff */
132 OBJECT_ATTRIBUTES ObjectAttributes
;
133 ULONG LenFullInformation
;
134 ULONG LenKeyFullInformation
;
135 UNICODE_STRING TempString
;
136 WCHAR TempBuffer
[14];
139 L
"Configuration Data",
140 L
"Component Information"
143 /* Temporary String */
144 TempString
.MaximumLength
= sizeof(TempBuffer
);
145 TempString
.Length
= 0;
146 TempString
.Buffer
= TempBuffer
;
148 /* Add Controller Name to String */
149 RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
150 RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->ControllerType
]);
152 /* Set the Controller Number if specified */
153 if (Query
->ControllerNumber
&& *(Query
->ControllerNumber
))
155 ControllerNumber
= *Query
->ControllerNumber
;
156 MaximumControllerNumber
= ControllerNumber
+ 1;
158 /* Find out how many Controller Numbers there are */
159 InitializeObjectAttributes(
161 &ControllerRootRegName
,
162 OBJ_CASE_INSENSITIVE
,
166 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
167 if (NT_SUCCESS(Status
))
169 /* How much buffer space */
170 ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
173 ControllerFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
175 /* Get the Information */
176 Status
= ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, ControllerFullInformation
, LenFullInformation
, &LenFullInformation
);
177 ZwClose(ControllerKeyHandle
);
178 ControllerKeyHandle
= NULL
;
181 /* No controller was found, go back to function. */
182 if (!NT_SUCCESS(Status
))
184 if (ControllerFullInformation
!= NULL
)
185 ExFreePool(ControllerFullInformation
);
189 /* Find out Controller Numbers */
190 ControllerNumber
= 0;
191 MaximumControllerNumber
= ControllerFullInformation
->SubKeys
;
194 ExFreePool(ControllerFullInformation
);
195 ControllerFullInformation
= NULL
;
199 ControllerRegName
= ControllerRootRegName
;
201 /* Loop through controllers */
202 for (; ControllerNumber
< MaximumControllerNumber
; ControllerNumber
++)
205 ControllerRootRegName
= ControllerRegName
;
207 /* Controller Number to Registry String */
208 Status
= RtlIntegerToUnicodeString(ControllerNumber
, 10, &TempString
);
211 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
212 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
214 /* Something messed up */
215 if (!NT_SUCCESS(Status
)) break;
217 /* Open the Registry Key */
218 InitializeObjectAttributes(
220 &ControllerRootRegName
,
221 OBJ_CASE_INSENSITIVE
,
225 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
227 /* Read the Configuration Data... */
228 if (NT_SUCCESS(Status
))
230 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
232 /* Identifier String First */
233 RtlInitUnicodeString(&ControllerString
, Strings
[ControllerLoop
]);
235 /* How much buffer space */
236 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
238 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
242 ControllerInformation
[ControllerLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
244 /* Get the Information */
245 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, ControllerInformation
[ControllerLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
249 ZwClose(ControllerKeyHandle
);
250 ControllerKeyHandle
= NULL
;
253 /* Something messed up */
254 if (!NT_SUCCESS(Status
))
257 /* We now have Bus *AND* Controller Information.. is it enough? */
258 if (!(*Query
->PeripheralType
))
260 Status
= Query
->CalloutRoutine(
262 &ControllerRootRegName
,
266 *Query
->ControllerType
,
268 ControllerInformation
,
275 /* Not enough...caller also wants peripheral name */
276 Status
= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
277 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->PeripheralType
]);
279 /* Something messed up */
280 if (!NT_SUCCESS(Status
)) goto EndLoop
;
282 /* Set the Peripheral Number if specified */
283 if (Query
->PeripheralNumber
&& *Query
->PeripheralNumber
)
285 PeripheralNumber
= *Query
->PeripheralNumber
;
286 MaximumPeripheralNumber
= PeripheralNumber
+ 1;
288 /* Find out how many Peripheral Numbers there are */
289 InitializeObjectAttributes(
291 &ControllerRootRegName
,
292 OBJ_CASE_INSENSITIVE
,
296 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
298 if (NT_SUCCESS(Status
))
300 /* How much buffer space */
301 ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
304 PeripheralFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
306 /* Get the Information */
307 Status
= ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, PeripheralFullInformation
, LenFullInformation
, &LenFullInformation
);
308 ZwClose(PeripheralKeyHandle
);
309 PeripheralKeyHandle
= NULL
;
312 /* No controller was found, go back to function but clean up first */
313 if (!NT_SUCCESS(Status
))
315 Status
= STATUS_SUCCESS
;
319 /* Find out Peripheral Number */
320 PeripheralNumber
= 0;
321 MaximumPeripheralNumber
= PeripheralFullInformation
->SubKeys
;
324 ExFreePool(PeripheralFullInformation
);
325 PeripheralFullInformation
= NULL
;
329 ControllerRegName
= ControllerRootRegName
;
331 /* Loop through Peripherals */
332 for (; PeripheralNumber
< MaximumPeripheralNumber
; PeripheralNumber
++)
335 ControllerRootRegName
= ControllerRegName
;
337 /* Peripheral Number to Registry String */
338 Status
= RtlIntegerToUnicodeString(PeripheralNumber
, 10, &TempString
);
341 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
342 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
344 /* Something messed up */
345 if (!NT_SUCCESS(Status
)) break;
347 /* Open the Registry Key */
348 InitializeObjectAttributes(
350 &ControllerRootRegName
,
351 OBJ_CASE_INSENSITIVE
,
355 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
357 if (NT_SUCCESS(Status
))
359 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
361 /* Identifier String First */
362 RtlInitUnicodeString(&PeripheralString
, Strings
[PeripheralLoop
]);
364 /* How much buffer space */
365 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
367 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
369 PeripheralInformation
[PeripheralLoop
] = NULL
;
374 PeripheralInformation
[PeripheralLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
376 /* Get the Information */
377 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, PeripheralInformation
[PeripheralLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
381 ZwClose(PeripheralKeyHandle
);
382 PeripheralKeyHandle
= NULL
;
384 /* We now have everything the caller could possibly want */
385 if (NT_SUCCESS(Status
))
387 Status
= Query
->CalloutRoutine(
389 &ControllerRootRegName
,
393 *Query
->ControllerType
,
395 ControllerInformation
,
396 *Query
->PeripheralType
,
398 PeripheralInformation
);
401 /* Free the allocated memory */
402 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
404 if (PeripheralInformation
[PeripheralLoop
])
406 ExFreePool(PeripheralInformation
[PeripheralLoop
]);
407 PeripheralInformation
[PeripheralLoop
] = NULL
;
411 /* Something Messed up */
412 if (!NT_SUCCESS(Status
)) break;
417 /* Free the allocated memory */
418 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
420 if (ControllerInformation
[ControllerLoop
])
422 ExFreePool(ControllerInformation
[ControllerLoop
]);
423 ControllerInformation
[ControllerLoop
] = NULL
;
427 /* Something Messed up */
428 if (!NT_SUCCESS(Status
)) break;
435 * IopQueryBusDescription
438 * Reads and returns Hardware information from the appropriate hardware
439 * registry key. Helper sub of IoQueryDeviceDescription. Has two modes
440 * of operation, either looking for Root Bus Types or for sub-Bus
444 * Query - What the parent function wants.
445 * RootKey - Which key to look in
446 * RootKeyHandle - Handle to the key
448 * KeyIsRoot - Whether we are looking for Root Bus Types or
449 * information under them.
456 IopQueryBusDescription(
458 UNICODE_STRING RootKey
,
459 HANDLE RootKeyHandle
,
465 UNICODE_STRING SubRootRegName
;
466 UNICODE_STRING BusString
;
467 UNICODE_STRING SubBusString
;
468 ULONG LenBasicInformation
= 0;
469 ULONG LenFullInformation
;
470 ULONG LenKeyFullInformation
;
472 HANDLE SubRootKeyHandle
;
473 PKEY_FULL_INFORMATION FullInformation
;
474 PKEY_BASIC_INFORMATION BasicInformation
= NULL
;
475 OBJECT_ATTRIBUTES ObjectAttributes
;
476 PKEY_VALUE_FULL_INFORMATION BusInformation
[3] = {NULL
, NULL
, NULL
};
478 /* How much buffer space */
479 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
481 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
485 FullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
488 return STATUS_NO_MEMORY
;
490 /* Get the Information */
491 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, FullInformation
, LenFullInformation
, &LenFullInformation
);
493 /* Everything was fine */
494 if (NT_SUCCESS(Status
))
496 /* Buffer needed for all the keys under this one */
497 LenBasicInformation
= FullInformation
->MaxNameLen
+ sizeof(KEY_BASIC_INFORMATION
);
500 BasicInformation
= ExAllocatePoolWithTag(PagedPool
, LenBasicInformation
, TAG_IO_RESOURCE
);
503 /* Deallocate the old Buffer */
504 ExFreePool(FullInformation
);
506 /* Try to find a Bus */
507 for (BusLoop
= 0; NT_SUCCESS(Status
); BusLoop
++)
509 /* Bus parameter was passed and number was matched */
510 if ((Query
->BusNumber
) && (*(Query
->BusNumber
)) == *Bus
) break;
512 /* Enumerate the Key */
513 Status
= ZwEnumerateKey(
521 /* Everything enumerated */
522 if (!NT_SUCCESS(Status
)) break;
524 /* What Bus are we going to go down? (only check if this is a Root Key) */
527 if (wcsncmp(BasicInformation
->Name
, L
"MultifunctionAdapter", BasicInformation
->NameLength
/ 2) &&
528 wcsncmp(BasicInformation
->Name
, L
"EisaAdapter", BasicInformation
->NameLength
/ 2) &&
529 wcsncmp(BasicInformation
->Name
, L
"TcAdapter", BasicInformation
->NameLength
/ 2))
531 /* Nothing found, check next */
536 /* Enumerate the Bus. */
537 BusString
.Buffer
= BasicInformation
->Name
;
538 BusString
.Length
= BasicInformation
->NameLength
;
539 BusString
.MaximumLength
= BasicInformation
->NameLength
;
541 /* Open a handle to the Root Registry Key */
542 InitializeObjectAttributes(
545 OBJ_CASE_INSENSITIVE
,
549 Status
= ZwOpenKey(&SubRootKeyHandle
, KEY_READ
, &ObjectAttributes
);
551 /* Go on if we can't */
552 if (!NT_SUCCESS(Status
)) continue;
554 /* Key opened. Create the path */
555 SubRootRegName
= RootKey
;
556 RtlAppendUnicodeToString(&SubRootRegName
, L
"\\");
557 RtlAppendUnicodeStringToString(&SubRootRegName
, &BusString
);
561 /* Parsing a SubBus-key */
565 L
"Configuration Data",
566 L
"Component Information"};
568 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
570 /* Identifier String First */
571 RtlInitUnicodeString(&SubBusString
, Strings
[SubBusLoop
]);
573 /* How much buffer space */
574 ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
577 BusInformation
[SubBusLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
579 /* Get the Information */
580 Status
= ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, BusInformation
[SubBusLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
583 if (NT_SUCCESS(Status
))
585 /* Do we have something */
586 if (BusInformation
[1] != NULL
&&
587 BusInformation
[1]->DataLength
!= 0 &&
588 /* Does it match what we want? */
589 (((PCM_FULL_RESOURCE_DESCRIPTOR
)((ULONG_PTR
)BusInformation
[1] + BusInformation
[1]->DataOffset
))->InterfaceType
== *(Query
->BusType
)))
594 /* Is it the bus we wanted */
595 if (Query
->BusNumber
== NULL
|| *(Query
->BusNumber
) == *Bus
)
597 /* If we don't want Controller Information, we're done... call the callback */
598 if (Query
->ControllerType
== NULL
)
600 Status
= Query
->CalloutRoutine(
613 /* We want Controller Info...get it */
614 Status
= IopQueryDeviceDescription(Query
, SubRootRegName
, RootKeyHandle
, *Bus
, (PKEY_VALUE_FULL_INFORMATION
*)BusInformation
);
620 /* Free the allocated memory */
621 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
623 if (BusInformation
[SubBusLoop
])
625 ExFreePool(BusInformation
[SubBusLoop
]);
626 BusInformation
[SubBusLoop
] = NULL
;
630 /* Exit the Loop if we found the bus */
631 if (Query
->BusNumber
!= NULL
&& *(Query
->BusNumber
) == *Bus
)
633 ZwClose(SubRootKeyHandle
);
634 SubRootKeyHandle
= NULL
;
639 /* Enumerate the buses below us recursively if we haven't found the bus yet */
640 Status
= IopQueryBusDescription(Query
, SubRootRegName
, SubRootKeyHandle
, Bus
, !KeyIsRoot
);
642 /* Everything enumerated */
643 if (Status
== STATUS_NO_MORE_ENTRIES
) Status
= STATUS_SUCCESS
;
645 ZwClose(SubRootKeyHandle
);
646 SubRootKeyHandle
= NULL
;
649 /* Free the last remaining Allocated Memory */
650 if (BasicInformation
)
651 ExFreePool(BasicInformation
);
656 /* PUBLIC FUNCTIONS ***********************************************************/
661 PCONFIGURATION_INFORMATION STDCALL
662 IoGetConfigurationInformation(VOID
)
664 return(&SystemConfigurationInformation
);
671 IoReportResourceUsage(PUNICODE_STRING DriverClassName
,
672 PDRIVER_OBJECT DriverObject
,
673 PCM_RESOURCE_LIST DriverList
,
674 ULONG DriverListSize
,
675 PDEVICE_OBJECT DeviceObject
,
676 PCM_RESOURCE_LIST DeviceList
,
677 ULONG DeviceListSize
,
678 BOOLEAN OverrideConflict
,
679 PBOOLEAN ConflictDetected
)
681 * FUNCTION: Reports hardware resources in the
682 * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
683 * loaded driver cannot attempt to use the same resources.
685 * DriverClassName - The class of driver under which the resource
686 * information should be stored.
687 * DriverObject - The driver object that was input to the
689 * DriverList - Resources that claimed for the driver rather than
691 * DriverListSize - Size in bytes of the DriverList.
692 * DeviceObject - The device object for which resources should be
694 * DeviceList - List of resources which should be claimed for the
696 * DeviceListSize - Size of the per-device resource list in bytes.
697 * OverrideConflict - True if the resources should be cliamed
698 * even if a conflict is found.
699 * ConflictDetected - Points to a variable that receives TRUE if
700 * a conflict is detected with another driver.
703 DPRINT1("IoReportResourceUsage is unimplemented\n");
704 *ConflictDetected
= FALSE
;
705 return STATUS_SUCCESS
;
712 IoAssignResources(PUNICODE_STRING RegistryPath
,
713 PUNICODE_STRING DriverClassName
,
714 PDRIVER_OBJECT DriverObject
,
715 PDEVICE_OBJECT DeviceObject
,
716 PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources
,
717 PCM_RESOURCE_LIST
* AllocatedResources
)
720 return(STATUS_NOT_IMPLEMENTED
);
725 * Reads and returns Hardware information from the appropriate hardware registry key.
728 * BusType - MCA, ISA, EISA...specifies the Bus Type
729 * BusNumber - Which bus of above should be queried
730 * ControllerType - Specifices the Controller Type
731 * ControllerNumber - Which of the controllers to query.
732 * CalloutRoutine - Which function to call for each valid query.
733 * Context - Value to pass to the callback.
743 IoQueryDeviceDescription(PINTERFACE_TYPE BusType
,
745 PCONFIGURATION_TYPE ControllerType
,
746 PULONG ControllerNumber
,
747 PCONFIGURATION_TYPE PeripheralType
,
748 PULONG PeripheralNumber
,
749 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
,
753 ULONG BusLoopNumber
= -1; /* Root Bus */
754 OBJECT_ATTRIBUTES ObjectAttributes
;
755 UNICODE_STRING RootRegKey
;
756 HANDLE RootRegHandle
;
757 WCHAR RootRegString
[] = L
"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
760 /* Set up the String */
761 RootRegKey
.Length
= 0;
762 RootRegKey
.MaximumLength
= 2048;
763 RootRegKey
.Buffer
= ExAllocatePoolWithTag(PagedPool
, RootRegKey
.MaximumLength
, TAG_IO_RESOURCE
);
764 RtlAppendUnicodeToString(&RootRegKey
, RootRegString
);
766 /* Open a handle to the Root Registry Key */
767 InitializeObjectAttributes(
770 OBJ_CASE_INSENSITIVE
,
774 Status
= ZwOpenKey(&RootRegHandle
, KEY_READ
, &ObjectAttributes
);
776 if (NT_SUCCESS(Status
))
778 /* Use a helper function to loop though this key and get the info */
779 Query
.BusType
= BusType
;
780 Query
.BusNumber
= BusNumber
;
781 Query
.ControllerType
= ControllerType
;
782 Query
.ControllerNumber
= ControllerNumber
;
783 Query
.PeripheralType
= PeripheralType
;
784 Query
.PeripheralNumber
= PeripheralNumber
;
785 Query
.CalloutRoutine
= CalloutRoutine
;
786 Query
.Context
= Context
;
787 Status
= IopQueryBusDescription(&Query
, RootRegKey
, RootRegHandle
, &BusLoopNumber
, TRUE
);
790 ZwClose(RootRegHandle
);
794 ExFreePool(RootRegKey
.Buffer
);
803 IoReportHalResourceUsage(PUNICODE_STRING HalDescription
,
804 PCM_RESOURCE_LIST RawList
,
805 PCM_RESOURCE_LIST TranslatedList
,
809 * Reports hardware resources of the HAL in the
810 * \Registry\Machine\Hardware\ResourceMap tree.
812 * HalDescription: Descriptive name of the HAL.
813 * RawList: List of raw (bus specific) resources which should be
814 * claimed for the HAL.
815 * TranslatedList: List of translated (system wide) resources which
816 * should be claimed for the HAL.
817 * ListSize: Size in bytes of the raw and translated resource lists.
818 * Both lists have the same size.
823 OBJECT_ATTRIBUTES ObjectAttributes
;
827 HANDLE ResourcemapKey
;
829 HANDLE DescriptionKey
;
831 /* Open/Create 'RESOURCEMAP' key. */
832 RtlRosInitUnicodeStringFromLiteral(&Name
,
833 L
"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
834 InitializeObjectAttributes(&ObjectAttributes
,
836 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
839 Status
= ZwCreateKey(&ResourcemapKey
,
846 if (!NT_SUCCESS(Status
))
849 /* Open/Create 'Hardware Abstraction Layer' key */
850 RtlRosInitUnicodeStringFromLiteral(&Name
,
851 L
"Hardware Abstraction Layer");
852 InitializeObjectAttributes(&ObjectAttributes
,
854 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
857 Status
= ZwCreateKey(&HalKey
,
864 ZwClose(ResourcemapKey
);
865 if (!NT_SUCCESS(Status
))
868 /* Create 'HalDescription' key */
869 InitializeObjectAttributes(&ObjectAttributes
,
871 OBJ_CASE_INSENSITIVE
,
874 Status
= ZwCreateKey(&DescriptionKey
,
882 if (!NT_SUCCESS(Status
))
885 /* Add '.Raw' value. */
886 RtlRosInitUnicodeStringFromLiteral(&Name
,
888 Status
= ZwSetValueKey(DescriptionKey
,
894 if (!NT_SUCCESS(Status
))
896 ZwClose(DescriptionKey
);
900 /* Add '.Translated' value. */
901 RtlRosInitUnicodeStringFromLiteral(&Name
,
903 Status
= ZwSetValueKey(DescriptionKey
,
909 ZwClose(DescriptionKey
);