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 /* PRIVATE FUNCTIONS **********************************************************/
82 * IopQueryDeviceDescription
85 * Reads and returns Hardware information from the appropriate hardware
86 * registry key. Helper sub of IopQueryBusDescription.
89 * Query - What the parent function wants.
90 * RootKey - Which key to look in
91 * RootKeyHandle - Handle to the key
93 * BusInformation - The Configuration Information Sent
100 IopQueryDeviceDescription(
102 UNICODE_STRING RootKey
,
103 HANDLE RootKeyHandle
,
105 PKEY_VALUE_FULL_INFORMATION
*BusInformation
)
107 NTSTATUS Status
= STATUS_SUCCESS
;
109 /* Controller Stuff */
110 UNICODE_STRING ControllerString
;
111 UNICODE_STRING ControllerRootRegName
= RootKey
;
112 UNICODE_STRING ControllerRegName
;
113 HANDLE ControllerKeyHandle
;
114 PKEY_FULL_INFORMATION ControllerFullInformation
= NULL
;
115 PKEY_VALUE_FULL_INFORMATION ControllerInformation
[3] = {NULL
, NULL
, NULL
};
116 ULONG ControllerNumber
;
117 ULONG ControllerLoop
;
118 ULONG MaximumControllerNumber
;
120 /* Peripheral Stuff */
121 UNICODE_STRING PeripheralString
;
122 HANDLE PeripheralKeyHandle
;
123 PKEY_FULL_INFORMATION PeripheralFullInformation
;
124 PKEY_VALUE_FULL_INFORMATION PeripheralInformation
[3] = {NULL
, NULL
, NULL
};
125 ULONG PeripheralNumber
;
126 ULONG PeripheralLoop
;
127 ULONG MaximumPeripheralNumber
;
129 /* Global Registry Stuff */
130 OBJECT_ATTRIBUTES ObjectAttributes
;
131 ULONG LenFullInformation
;
132 ULONG LenKeyFullInformation
;
133 UNICODE_STRING TempString
;
134 WCHAR TempBuffer
[14];
137 L
"Configuration Data",
138 L
"Component Information"
141 /* Temporary String */
142 TempString
.MaximumLength
= sizeof(TempBuffer
);
143 TempString
.Length
= 0;
144 TempString
.Buffer
= TempBuffer
;
146 /* Add Controller Name to String */
147 RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
148 RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->ControllerType
]);
150 /* Set the Controller Number if specified */
151 if (Query
->ControllerNumber
&& *(Query
->ControllerNumber
))
153 ControllerNumber
= *Query
->ControllerNumber
;
154 MaximumControllerNumber
= ControllerNumber
+ 1;
156 /* Find out how many Controller Numbers there are */
157 InitializeObjectAttributes(
159 &ControllerRootRegName
,
160 OBJ_CASE_INSENSITIVE
,
164 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
165 if (NT_SUCCESS(Status
))
167 /* How much buffer space */
168 ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
171 ControllerFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
173 /* Get the Information */
174 Status
= ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, ControllerFullInformation
, LenFullInformation
, &LenFullInformation
);
175 ZwClose(ControllerKeyHandle
);
176 ControllerKeyHandle
= NULL
;
179 /* No controller was found, go back to function. */
180 if (!NT_SUCCESS(Status
))
182 if (ControllerFullInformation
!= NULL
)
183 ExFreePool(ControllerFullInformation
);
187 /* Find out Controller Numbers */
188 ControllerNumber
= 0;
189 MaximumControllerNumber
= ControllerFullInformation
->SubKeys
;
192 ExFreePool(ControllerFullInformation
);
193 ControllerFullInformation
= NULL
;
197 ControllerRegName
= ControllerRootRegName
;
199 /* Loop through controllers */
200 for (; ControllerNumber
< MaximumControllerNumber
; ControllerNumber
++)
203 ControllerRootRegName
= ControllerRegName
;
205 /* Controller Number to Registry String */
206 Status
= RtlIntegerToUnicodeString(ControllerNumber
, 10, &TempString
);
209 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
210 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
212 /* Something messed up */
213 if (!NT_SUCCESS(Status
)) break;
215 /* Open the Registry Key */
216 InitializeObjectAttributes(
218 &ControllerRootRegName
,
219 OBJ_CASE_INSENSITIVE
,
223 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
225 /* Read the Configuration Data... */
226 if (NT_SUCCESS(Status
))
228 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
230 /* Identifier String First */
231 RtlInitUnicodeString(&ControllerString
, Strings
[ControllerLoop
]);
233 /* How much buffer space */
234 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
236 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
240 ControllerInformation
[ControllerLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
242 /* Get the Information */
243 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, ControllerInformation
[ControllerLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
247 ZwClose(ControllerKeyHandle
);
248 ControllerKeyHandle
= NULL
;
251 /* Something messed up */
252 if (!NT_SUCCESS(Status
))
255 /* We now have Bus *AND* Controller Information.. is it enough? */
256 if (!Query
->PeripheralType
|| !(*Query
->PeripheralType
))
258 Status
= Query
->CalloutRoutine(
260 &ControllerRootRegName
,
264 *Query
->ControllerType
,
266 ControllerInformation
,
273 /* Not enough...caller also wants peripheral name */
274 Status
= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
275 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->PeripheralType
]);
277 /* Something messed up */
278 if (!NT_SUCCESS(Status
)) goto EndLoop
;
280 /* Set the Peripheral Number if specified */
281 if (Query
->PeripheralNumber
&& *Query
->PeripheralNumber
)
283 PeripheralNumber
= *Query
->PeripheralNumber
;
284 MaximumPeripheralNumber
= PeripheralNumber
+ 1;
286 /* Find out how many Peripheral Numbers there are */
287 InitializeObjectAttributes(
289 &ControllerRootRegName
,
290 OBJ_CASE_INSENSITIVE
,
294 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
296 if (NT_SUCCESS(Status
))
298 /* How much buffer space */
299 ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
302 PeripheralFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
304 /* Get the Information */
305 Status
= ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, PeripheralFullInformation
, LenFullInformation
, &LenFullInformation
);
306 ZwClose(PeripheralKeyHandle
);
307 PeripheralKeyHandle
= NULL
;
310 /* No controller was found, go back to function but clean up first */
311 if (!NT_SUCCESS(Status
))
313 Status
= STATUS_SUCCESS
;
317 /* Find out Peripheral Number */
318 PeripheralNumber
= 0;
319 MaximumPeripheralNumber
= PeripheralFullInformation
->SubKeys
;
322 ExFreePool(PeripheralFullInformation
);
323 PeripheralFullInformation
= NULL
;
327 ControllerRegName
= ControllerRootRegName
;
329 /* Loop through Peripherals */
330 for (; PeripheralNumber
< MaximumPeripheralNumber
; PeripheralNumber
++)
333 ControllerRootRegName
= ControllerRegName
;
335 /* Peripheral Number to Registry String */
336 Status
= RtlIntegerToUnicodeString(PeripheralNumber
, 10, &TempString
);
339 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
340 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
342 /* Something messed up */
343 if (!NT_SUCCESS(Status
)) break;
345 /* Open the Registry Key */
346 InitializeObjectAttributes(
348 &ControllerRootRegName
,
349 OBJ_CASE_INSENSITIVE
,
353 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
355 if (NT_SUCCESS(Status
))
357 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
359 /* Identifier String First */
360 RtlInitUnicodeString(&PeripheralString
, Strings
[PeripheralLoop
]);
362 /* How much buffer space */
363 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
365 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
367 PeripheralInformation
[PeripheralLoop
] = NULL
;
372 PeripheralInformation
[PeripheralLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
374 /* Get the Information */
375 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, PeripheralInformation
[PeripheralLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
379 ZwClose(PeripheralKeyHandle
);
380 PeripheralKeyHandle
= NULL
;
382 /* We now have everything the caller could possibly want */
383 if (NT_SUCCESS(Status
))
385 Status
= Query
->CalloutRoutine(
387 &ControllerRootRegName
,
391 *Query
->ControllerType
,
393 ControllerInformation
,
394 *Query
->PeripheralType
,
396 PeripheralInformation
);
399 /* Free the allocated memory */
400 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
402 if (PeripheralInformation
[PeripheralLoop
])
404 ExFreePool(PeripheralInformation
[PeripheralLoop
]);
405 PeripheralInformation
[PeripheralLoop
] = NULL
;
409 /* Something Messed up */
410 if (!NT_SUCCESS(Status
)) break;
415 /* Free the allocated memory */
416 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
418 if (ControllerInformation
[ControllerLoop
])
420 ExFreePool(ControllerInformation
[ControllerLoop
]);
421 ControllerInformation
[ControllerLoop
] = NULL
;
425 /* Something Messed up */
426 if (!NT_SUCCESS(Status
)) break;
433 * IopQueryBusDescription
436 * Reads and returns Hardware information from the appropriate hardware
437 * registry key. Helper sub of IoQueryDeviceDescription. Has two modes
438 * of operation, either looking for Root Bus Types or for sub-Bus
442 * Query - What the parent function wants.
443 * RootKey - Which key to look in
444 * RootKeyHandle - Handle to the key
446 * KeyIsRoot - Whether we are looking for Root Bus Types or
447 * information under them.
454 IopQueryBusDescription(
456 UNICODE_STRING RootKey
,
457 HANDLE RootKeyHandle
,
463 UNICODE_STRING SubRootRegName
;
464 UNICODE_STRING BusString
;
465 UNICODE_STRING SubBusString
;
466 ULONG LenBasicInformation
= 0;
467 ULONG LenFullInformation
;
468 ULONG LenKeyFullInformation
;
470 HANDLE SubRootKeyHandle
;
471 PKEY_FULL_INFORMATION FullInformation
;
472 PKEY_BASIC_INFORMATION BasicInformation
= NULL
;
473 OBJECT_ATTRIBUTES ObjectAttributes
;
474 PKEY_VALUE_FULL_INFORMATION BusInformation
[3] = {NULL
, NULL
, NULL
};
476 /* How much buffer space */
477 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
479 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
483 FullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
486 return STATUS_NO_MEMORY
;
488 /* Get the Information */
489 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, FullInformation
, LenFullInformation
, &LenFullInformation
);
491 /* Everything was fine */
492 if (NT_SUCCESS(Status
))
494 /* Buffer needed for all the keys under this one */
495 LenBasicInformation
= FullInformation
->MaxNameLen
+ sizeof(KEY_BASIC_INFORMATION
);
498 BasicInformation
= ExAllocatePoolWithTag(PagedPool
, LenBasicInformation
, TAG_IO_RESOURCE
);
501 /* Deallocate the old Buffer */
502 ExFreePool(FullInformation
);
504 /* Try to find a Bus */
505 for (BusLoop
= 0; NT_SUCCESS(Status
); BusLoop
++)
507 /* Bus parameter was passed and number was matched */
508 if ((Query
->BusNumber
) && (*(Query
->BusNumber
)) == *Bus
) break;
510 /* Enumerate the Key */
511 Status
= ZwEnumerateKey(
519 /* Everything enumerated */
520 if (!NT_SUCCESS(Status
)) break;
522 /* What Bus are we going to go down? (only check if this is a Root Key) */
525 if (wcsncmp(BasicInformation
->Name
, L
"MultifunctionAdapter", BasicInformation
->NameLength
/ 2) &&
526 wcsncmp(BasicInformation
->Name
, L
"EisaAdapter", BasicInformation
->NameLength
/ 2) &&
527 wcsncmp(BasicInformation
->Name
, L
"TcAdapter", BasicInformation
->NameLength
/ 2))
529 /* Nothing found, check next */
534 /* Enumerate the Bus. */
535 BusString
.Buffer
= BasicInformation
->Name
;
536 BusString
.Length
= BasicInformation
->NameLength
;
537 BusString
.MaximumLength
= BasicInformation
->NameLength
;
539 /* Open a handle to the Root Registry Key */
540 InitializeObjectAttributes(
543 OBJ_CASE_INSENSITIVE
,
547 Status
= ZwOpenKey(&SubRootKeyHandle
, KEY_READ
, &ObjectAttributes
);
549 /* Go on if we can't */
550 if (!NT_SUCCESS(Status
)) continue;
552 /* Key opened. Create the path */
553 SubRootRegName
= RootKey
;
554 RtlAppendUnicodeToString(&SubRootRegName
, L
"\\");
555 RtlAppendUnicodeStringToString(&SubRootRegName
, &BusString
);
559 /* Parsing a SubBus-key */
563 L
"Configuration Data",
564 L
"Component Information"};
566 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
568 /* Identifier String First */
569 RtlInitUnicodeString(&SubBusString
, Strings
[SubBusLoop
]);
571 /* How much buffer space */
572 ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
575 BusInformation
[SubBusLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
577 /* Get the Information */
578 Status
= ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, BusInformation
[SubBusLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
581 if (NT_SUCCESS(Status
))
583 /* Do we have something */
584 if (BusInformation
[1] != NULL
&&
585 BusInformation
[1]->DataLength
!= 0 &&
586 /* Does it match what we want? */
587 (((PCM_FULL_RESOURCE_DESCRIPTOR
)((ULONG_PTR
)BusInformation
[1] + BusInformation
[1]->DataOffset
))->InterfaceType
== *(Query
->BusType
)))
592 /* Is it the bus we wanted */
593 if (Query
->BusNumber
== NULL
|| *(Query
->BusNumber
) == *Bus
)
595 /* If we don't want Controller Information, we're done... call the callback */
596 if (Query
->ControllerType
== NULL
)
598 Status
= Query
->CalloutRoutine(
611 /* We want Controller Info...get it */
612 Status
= IopQueryDeviceDescription(Query
, SubRootRegName
, RootKeyHandle
, *Bus
, (PKEY_VALUE_FULL_INFORMATION
*)BusInformation
);
618 /* Free the allocated memory */
619 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
621 if (BusInformation
[SubBusLoop
])
623 ExFreePool(BusInformation
[SubBusLoop
]);
624 BusInformation
[SubBusLoop
] = NULL
;
628 /* Exit the Loop if we found the bus */
629 if (Query
->BusNumber
!= NULL
&& *(Query
->BusNumber
) == *Bus
)
631 ZwClose(SubRootKeyHandle
);
632 SubRootKeyHandle
= NULL
;
637 /* Enumerate the buses below us recursively if we haven't found the bus yet */
638 Status
= IopQueryBusDescription(Query
, SubRootRegName
, SubRootKeyHandle
, Bus
, !KeyIsRoot
);
640 /* Everything enumerated */
641 if (Status
== STATUS_NO_MORE_ENTRIES
) Status
= STATUS_SUCCESS
;
643 ZwClose(SubRootKeyHandle
);
644 SubRootKeyHandle
= NULL
;
647 /* Free the last remaining Allocated Memory */
648 if (BasicInformation
)
649 ExFreePool(BasicInformation
);
654 /* PUBLIC FUNCTIONS ***********************************************************/
659 PCONFIGURATION_INFORMATION STDCALL
660 IoGetConfigurationInformation(VOID
)
662 return(&_SystemConfigurationInformation
);
669 IoReportResourceUsage(PUNICODE_STRING DriverClassName
,
670 PDRIVER_OBJECT DriverObject
,
671 PCM_RESOURCE_LIST DriverList
,
672 ULONG DriverListSize
,
673 PDEVICE_OBJECT DeviceObject
,
674 PCM_RESOURCE_LIST DeviceList
,
675 ULONG DeviceListSize
,
676 BOOLEAN OverrideConflict
,
677 PBOOLEAN ConflictDetected
)
679 * FUNCTION: Reports hardware resources in the
680 * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
681 * loaded driver cannot attempt to use the same resources.
683 * DriverClassName - The class of driver under which the resource
684 * information should be stored.
685 * DriverObject - The driver object that was input to the
687 * DriverList - Resources that claimed for the driver rather than
689 * DriverListSize - Size in bytes of the DriverList.
690 * DeviceObject - The device object for which resources should be
692 * DeviceList - List of resources which should be claimed for the
694 * DeviceListSize - Size of the per-device resource list in bytes.
695 * OverrideConflict - True if the resources should be cliamed
696 * even if a conflict is found.
697 * ConflictDetected - Points to a variable that receives TRUE if
698 * a conflict is detected with another driver.
701 DPRINT1("IoReportResourceUsage is unimplemented\n");
702 *ConflictDetected
= FALSE
;
703 return STATUS_SUCCESS
;
710 IoAssignResources(PUNICODE_STRING RegistryPath
,
711 PUNICODE_STRING DriverClassName
,
712 PDRIVER_OBJECT DriverObject
,
713 PDEVICE_OBJECT DeviceObject
,
714 PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources
,
715 PCM_RESOURCE_LIST
* AllocatedResources
)
718 return(STATUS_NOT_IMPLEMENTED
);
723 * Reads and returns Hardware information from the appropriate hardware registry key.
726 * BusType - MCA, ISA, EISA...specifies the Bus Type
727 * BusNumber - Which bus of above should be queried
728 * ControllerType - Specifices the Controller Type
729 * ControllerNumber - Which of the controllers to query.
730 * CalloutRoutine - Which function to call for each valid query.
731 * Context - Value to pass to the callback.
741 IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL
,
742 PULONG BusNumber OPTIONAL
,
743 PCONFIGURATION_TYPE ControllerType OPTIONAL
,
744 PULONG ControllerNumber OPTIONAL
,
745 PCONFIGURATION_TYPE PeripheralType OPTIONAL
,
746 PULONG PeripheralNumber OPTIONAL
,
747 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
,
751 ULONG BusLoopNumber
= -1; /* Root Bus */
752 OBJECT_ATTRIBUTES ObjectAttributes
;
753 UNICODE_STRING RootRegKey
;
754 HANDLE RootRegHandle
;
755 WCHAR RootRegString
[] = L
"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
758 /* Set up the String */
759 RootRegKey
.Length
= 0;
760 RootRegKey
.MaximumLength
= 2048;
761 RootRegKey
.Buffer
= ExAllocatePoolWithTag(PagedPool
, RootRegKey
.MaximumLength
, TAG_IO_RESOURCE
);
762 RtlAppendUnicodeToString(&RootRegKey
, RootRegString
);
764 /* Open a handle to the Root Registry Key */
765 InitializeObjectAttributes(
768 OBJ_CASE_INSENSITIVE
,
772 Status
= ZwOpenKey(&RootRegHandle
, KEY_READ
, &ObjectAttributes
);
774 if (NT_SUCCESS(Status
))
776 /* Use a helper function to loop though this key and get the info */
777 Query
.BusType
= BusType
;
778 Query
.BusNumber
= BusNumber
;
779 Query
.ControllerType
= ControllerType
;
780 Query
.ControllerNumber
= ControllerNumber
;
781 Query
.PeripheralType
= PeripheralType
;
782 Query
.PeripheralNumber
= PeripheralNumber
;
783 Query
.CalloutRoutine
= CalloutRoutine
;
784 Query
.Context
= Context
;
785 Status
= IopQueryBusDescription(&Query
, RootRegKey
, RootRegHandle
, &BusLoopNumber
, TRUE
);
788 ZwClose(RootRegHandle
);
792 ExFreePool(RootRegKey
.Buffer
);
801 IoReportHalResourceUsage(PUNICODE_STRING HalDescription
,
802 PCM_RESOURCE_LIST RawList
,
803 PCM_RESOURCE_LIST TranslatedList
,
807 * Reports hardware resources of the HAL in the
808 * \Registry\Machine\Hardware\ResourceMap tree.
810 * HalDescription: Descriptive name of the HAL.
811 * RawList: List of raw (bus specific) resources which should be
812 * claimed for the HAL.
813 * TranslatedList: List of translated (system wide) resources which
814 * should be claimed for the HAL.
815 * ListSize: Size in bytes of the raw and translated resource lists.
816 * Both lists have the same size.
821 OBJECT_ATTRIBUTES ObjectAttributes
;
825 HANDLE ResourcemapKey
;
827 HANDLE DescriptionKey
;
829 /* Open/Create 'RESOURCEMAP' key. */
830 RtlInitUnicodeString(&Name
,
831 L
"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
832 InitializeObjectAttributes(&ObjectAttributes
,
834 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
837 Status
= ZwCreateKey(&ResourcemapKey
,
844 if (!NT_SUCCESS(Status
))
847 /* Open/Create 'Hardware Abstraction Layer' key */
848 RtlInitUnicodeString(&Name
,
849 L
"Hardware Abstraction Layer");
850 InitializeObjectAttributes(&ObjectAttributes
,
852 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
855 Status
= ZwCreateKey(&HalKey
,
862 ZwClose(ResourcemapKey
);
863 if (!NT_SUCCESS(Status
))
866 /* Create 'HalDescription' key */
867 InitializeObjectAttributes(&ObjectAttributes
,
869 OBJ_CASE_INSENSITIVE
,
872 Status
= ZwCreateKey(&DescriptionKey
,
880 if (!NT_SUCCESS(Status
))
883 /* Add '.Raw' value. */
884 RtlInitUnicodeString(&Name
,
886 Status
= ZwSetValueKey(DescriptionKey
,
892 if (!NT_SUCCESS(Status
))
894 ZwClose(DescriptionKey
);
898 /* Add '.Translated' value. */
899 RtlInitUnicodeString(&Name
,
901 Status
= ZwSetValueKey(DescriptionKey
,
907 ZwClose(DescriptionKey
);