3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/io/resource.c
23 * PURPOSE: Hardware resource managment
24 * PROGRAMMER: David Welch (welch@mcmail.com)
25 * Alex Ionescu (alex@relsoft.net)
30 /* INCLUDES *****************************************************************/
33 #include <internal/debug.h>
35 /* GLOBALS *******************************************************************/
37 static CONFIGURATION_INFORMATION
38 SystemConfigurationInformation
= {0, 0, 0, 0, 0, 0, 0, FALSE
, FALSE
};
40 /* API Parameters to Pass in IopQueryBusDescription */
41 typedef struct IO_QUERY
{
42 PINTERFACE_TYPE BusType
;
44 PCONFIGURATION_TYPE ControllerType
;
45 PULONG ControllerNumber
;
46 PCONFIGURATION_TYPE PeripheralType
;
47 PULONG PeripheralNumber
;
48 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
;
50 } IO_QUERY
, *PIO_QUERY
;
52 PWSTR ArcTypes
[42] = {
55 L
"FloatingPointProcessor",
65 L
"MultifunctionAdapter",
73 L
"ParallelController",
75 L
"KeyboardController",
79 L
"FloppyDiskPeripheral",
85 L
"KeyboardPeripheral",
86 L
"TerminalPeripheral",
91 L
"DockingInformation",
92 L
"RealModeIrqRoutingTable",
93 L
"RealModePCIEnumeration",
97 #define TAG_IO_RESOURCE TAG('R', 'S', 'R', 'C')
99 /* PRIVATE FUNCTIONS **********************************************************/
102 * IopQueryDeviceDescription
105 * Reads and returns Hardware information from the appropriate hardware
106 * registry key. Helper sub of IopQueryBusDescription.
109 * Query - What the parent function wants.
110 * RootKey - Which key to look in
111 * RootKeyHandle - Handle to the key
113 * BusInformation - The Configuration Information Sent
120 IopQueryDeviceDescription(
122 UNICODE_STRING RootKey
,
123 HANDLE RootKeyHandle
,
125 PKEY_VALUE_FULL_INFORMATION
*BusInformation
)
127 NTSTATUS Status
= STATUS_SUCCESS
;
129 /* Controller Stuff */
130 UNICODE_STRING ControllerString
;
131 UNICODE_STRING ControllerRootRegName
= RootKey
;
132 UNICODE_STRING ControllerRegName
;
133 HANDLE ControllerKeyHandle
;
134 PKEY_FULL_INFORMATION ControllerFullInformation
= NULL
;
135 PKEY_VALUE_FULL_INFORMATION ControllerInformation
[3] = {NULL
, NULL
, NULL
};
136 ULONG ControllerNumber
;
137 ULONG ControllerLoop
;
138 ULONG MaximumControllerNumber
;
140 /* Peripheral Stuff */
141 UNICODE_STRING PeripheralString
;
142 HANDLE PeripheralKeyHandle
;
143 PKEY_FULL_INFORMATION PeripheralFullInformation
;
144 PKEY_VALUE_FULL_INFORMATION PeripheralInformation
[3] = {NULL
, NULL
, NULL
};
145 ULONG PeripheralNumber
;
146 ULONG PeripheralLoop
;
147 ULONG MaximumPeripheralNumber
;
149 /* Global Registry Stuff */
150 OBJECT_ATTRIBUTES ObjectAttributes
;
151 ULONG LenFullInformation
;
152 ULONG LenKeyFullInformation
;
153 UNICODE_STRING TempString
;
154 WCHAR TempBuffer
[14];
157 L
"Configuration Data",
158 L
"Component Information"
161 /* Temporary String */
162 TempString
.MaximumLength
= sizeof(TempBuffer
);
163 TempString
.Length
= 0;
164 TempString
.Buffer
= TempBuffer
;
166 /* Add Controller Name to String */
167 RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
168 RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->ControllerType
]);
170 /* Set the Controller Number if specified */
171 if (Query
->ControllerNumber
&& *(Query
->ControllerNumber
))
173 ControllerNumber
= *Query
->ControllerNumber
;
174 MaximumControllerNumber
= ControllerNumber
+ 1;
176 /* Find out how many Controller Numbers there are */
177 InitializeObjectAttributes(
179 &ControllerRootRegName
,
180 OBJ_CASE_INSENSITIVE
,
184 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
185 if (NT_SUCCESS(Status
))
187 /* How much buffer space */
188 ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
191 ControllerFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
193 /* Get the Information */
194 Status
= ZwQueryKey(ControllerKeyHandle
, KeyFullInformation
, ControllerFullInformation
, LenFullInformation
, &LenFullInformation
);
195 ZwClose(ControllerKeyHandle
);
196 ControllerKeyHandle
= NULL
;
199 /* No controller was found, go back to function. */
200 if (!NT_SUCCESS(Status
))
202 if (ControllerFullInformation
!= NULL
)
203 ExFreePool(ControllerFullInformation
);
207 /* Find out Controller Numbers */
208 ControllerNumber
= 0;
209 MaximumControllerNumber
= ControllerFullInformation
->SubKeys
;
212 ExFreePool(ControllerFullInformation
);
213 ControllerFullInformation
= NULL
;
217 ControllerRegName
= ControllerRootRegName
;
219 /* Loop through controllers */
220 for (; ControllerNumber
< MaximumControllerNumber
; ControllerNumber
++)
223 ControllerRootRegName
= ControllerRegName
;
225 /* Controller Number to Registry String */
226 Status
= RtlIntegerToUnicodeString(ControllerNumber
, 10, &TempString
);
229 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
230 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
232 /* Something messed up */
233 if (!NT_SUCCESS(Status
)) break;
235 /* Open the Registry Key */
236 InitializeObjectAttributes(
238 &ControllerRootRegName
,
239 OBJ_CASE_INSENSITIVE
,
243 Status
= ZwOpenKey(&ControllerKeyHandle
, KEY_READ
, &ObjectAttributes
);
245 /* Read the Configuration Data... */
246 if (NT_SUCCESS(Status
))
248 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
250 /* Identifier String First */
251 RtlInitUnicodeString(&ControllerString
, Strings
[ControllerLoop
]);
253 /* How much buffer space */
254 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
256 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
260 ControllerInformation
[ControllerLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
262 /* Get the Information */
263 Status
= ZwQueryValueKey(ControllerKeyHandle
, &ControllerString
, KeyValueFullInformation
, ControllerInformation
[ControllerLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
267 ZwClose(ControllerKeyHandle
);
268 ControllerKeyHandle
= NULL
;
271 /* Something messed up */
272 if (!NT_SUCCESS(Status
))
275 /* We now have Bus *AND* Controller Information.. is it enough? */
276 if (!(*Query
->PeripheralType
))
278 Status
= Query
->CalloutRoutine(
280 &ControllerRootRegName
,
284 *Query
->ControllerType
,
286 ControllerInformation
,
293 /* Not enough...caller also wants peripheral name */
294 Status
= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
295 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, ArcTypes
[*Query
->PeripheralType
]);
297 /* Something messed up */
298 if (!NT_SUCCESS(Status
)) goto EndLoop
;
300 /* Set the Peripheral Number if specified */
301 if (Query
->PeripheralNumber
&& *Query
->PeripheralNumber
)
303 PeripheralNumber
= *Query
->PeripheralNumber
;
304 MaximumPeripheralNumber
= PeripheralNumber
+ 1;
306 /* Find out how many Peripheral Numbers there are */
307 InitializeObjectAttributes(
309 &ControllerRootRegName
,
310 OBJ_CASE_INSENSITIVE
,
314 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
316 if (NT_SUCCESS(Status
))
318 /* How much buffer space */
319 ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
322 PeripheralFullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
324 /* Get the Information */
325 Status
= ZwQueryKey(PeripheralKeyHandle
, KeyFullInformation
, PeripheralFullInformation
, LenFullInformation
, &LenFullInformation
);
326 ZwClose(PeripheralKeyHandle
);
327 PeripheralKeyHandle
= NULL
;
330 /* No controller was found, go back to function but clean up first */
331 if (!NT_SUCCESS(Status
))
333 Status
= STATUS_SUCCESS
;
337 /* Find out Peripheral Number */
338 PeripheralNumber
= 0;
339 MaximumPeripheralNumber
= PeripheralFullInformation
->SubKeys
;
342 ExFreePool(PeripheralFullInformation
);
343 PeripheralFullInformation
= NULL
;
347 ControllerRegName
= ControllerRootRegName
;
349 /* Loop through Peripherals */
350 for (; PeripheralNumber
< MaximumPeripheralNumber
; PeripheralNumber
++)
353 ControllerRootRegName
= ControllerRegName
;
355 /* Peripheral Number to Registry String */
356 Status
= RtlIntegerToUnicodeString(PeripheralNumber
, 10, &TempString
);
359 Status
|= RtlAppendUnicodeToString(&ControllerRootRegName
, L
"\\");
360 Status
|= RtlAppendUnicodeStringToString(&ControllerRootRegName
, &TempString
);
362 /* Something messed up */
363 if (!NT_SUCCESS(Status
)) break;
365 /* Open the Registry Key */
366 InitializeObjectAttributes(
368 &ControllerRootRegName
,
369 OBJ_CASE_INSENSITIVE
,
373 Status
= ZwOpenKey(&PeripheralKeyHandle
, KEY_READ
, &ObjectAttributes
);
375 if (NT_SUCCESS(Status
))
377 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
379 /* Identifier String First */
380 RtlInitUnicodeString(&PeripheralString
, Strings
[PeripheralLoop
]);
382 /* How much buffer space */
383 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
385 if(!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
387 PeripheralInformation
[PeripheralLoop
] = NULL
;
392 PeripheralInformation
[PeripheralLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
394 /* Get the Information */
395 Status
= ZwQueryValueKey(PeripheralKeyHandle
, &PeripheralString
, KeyValueFullInformation
, PeripheralInformation
[PeripheralLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
399 ZwClose(PeripheralKeyHandle
);
400 PeripheralKeyHandle
= NULL
;
402 /* We now have everything the caller could possibly want */
403 if (NT_SUCCESS(Status
))
405 Status
= Query
->CalloutRoutine(
407 &ControllerRootRegName
,
411 *Query
->ControllerType
,
413 ControllerInformation
,
414 *Query
->PeripheralType
,
416 PeripheralInformation
);
419 /* Free the allocated memory */
420 for (PeripheralLoop
= 0; PeripheralLoop
< 3; PeripheralLoop
++)
422 if (PeripheralInformation
[PeripheralLoop
])
424 ExFreePool(PeripheralInformation
[PeripheralLoop
]);
425 PeripheralInformation
[PeripheralLoop
] = NULL
;
429 /* Something Messed up */
430 if (!NT_SUCCESS(Status
)) break;
435 /* Free the allocated memory */
436 for (ControllerLoop
= 0; ControllerLoop
< 3; ControllerLoop
++)
438 if (ControllerInformation
[ControllerLoop
])
440 ExFreePool(ControllerInformation
[ControllerLoop
]);
441 ControllerInformation
[ControllerLoop
] = NULL
;
445 /* Something Messed up */
446 if (!NT_SUCCESS(Status
)) break;
453 * IopQueryBusDescription
456 * Reads and returns Hardware information from the appropriate hardware
457 * registry key. Helper sub of IoQueryDeviceDescription. Has two modes
458 * of operation, either looking for Root Bus Types or for sub-Bus
462 * Query - What the parent function wants.
463 * RootKey - Which key to look in
464 * RootKeyHandle - Handle to the key
466 * KeyIsRoot - Whether we are looking for Root Bus Types or
467 * information under them.
474 IopQueryBusDescription(
476 UNICODE_STRING RootKey
,
477 HANDLE RootKeyHandle
,
483 UNICODE_STRING SubRootRegName
;
484 UNICODE_STRING BusString
;
485 UNICODE_STRING SubBusString
;
486 ULONG LenBasicInformation
= 0;
487 ULONG LenFullInformation
;
488 ULONG LenKeyFullInformation
;
490 HANDLE SubRootKeyHandle
;
491 PKEY_FULL_INFORMATION FullInformation
;
492 PKEY_BASIC_INFORMATION BasicInformation
= NULL
;
493 OBJECT_ATTRIBUTES ObjectAttributes
;
494 PKEY_VALUE_FULL_INFORMATION BusInformation
[3] = {NULL
, NULL
, NULL
};
496 /* How much buffer space */
497 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, NULL
, 0, &LenFullInformation
);
499 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
)
503 FullInformation
= ExAllocatePoolWithTag(PagedPool
, LenFullInformation
, TAG_IO_RESOURCE
);
506 return STATUS_NO_MEMORY
;
508 /* Get the Information */
509 Status
= ZwQueryKey(RootKeyHandle
, KeyFullInformation
, FullInformation
, LenFullInformation
, &LenFullInformation
);
511 /* Everything was fine */
512 if (NT_SUCCESS(Status
))
514 /* Buffer needed for all the keys under this one */
515 LenBasicInformation
= FullInformation
->MaxNameLen
+ sizeof(KEY_BASIC_INFORMATION
);
518 BasicInformation
= ExAllocatePoolWithTag(PagedPool
, LenBasicInformation
, TAG_IO_RESOURCE
);
521 /* Deallocate the old Buffer */
522 ExFreePool(FullInformation
);
524 /* Try to find a Bus */
525 for (BusLoop
= 0; NT_SUCCESS(Status
); BusLoop
++)
527 /* Bus parameter was passed and number was matched */
528 if ((Query
->BusNumber
) && (*(Query
->BusNumber
)) == *Bus
) break;
530 /* Enumerate the Key */
531 Status
= ZwEnumerateKey(
539 /* Everything enumerated */
540 if (!NT_SUCCESS(Status
)) break;
542 /* What Bus are we going to go down? (only check if this is a Root Key) */
545 if (wcsncmp(BasicInformation
->Name
, L
"MultifunctionAdapter", BasicInformation
->NameLength
/ 2) &&
546 wcsncmp(BasicInformation
->Name
, L
"EisaAdapter", BasicInformation
->NameLength
/ 2) &&
547 wcsncmp(BasicInformation
->Name
, L
"TcAdapter", BasicInformation
->NameLength
/ 2))
549 /* Nothing found, check next */
554 /* Enumerate the Bus. */
555 BusString
.Buffer
= BasicInformation
->Name
;
556 BusString
.Length
= BasicInformation
->NameLength
;
557 BusString
.MaximumLength
= BasicInformation
->NameLength
;
559 /* Open a handle to the Root Registry Key */
560 InitializeObjectAttributes(
563 OBJ_CASE_INSENSITIVE
,
567 Status
= ZwOpenKey(&SubRootKeyHandle
, KEY_READ
, &ObjectAttributes
);
569 /* Go on if we can't */
570 if (!NT_SUCCESS(Status
)) continue;
572 /* Key opened. Create the path */
573 SubRootRegName
= RootKey
;
574 RtlAppendUnicodeToString(&SubRootRegName
, L
"\\");
575 RtlAppendUnicodeStringToString(&SubRootRegName
, &BusString
);
579 /* Parsing a SubBus-key */
583 L
"Configuration Data",
584 L
"Component Information"};
586 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
588 /* Identifier String First */
589 RtlInitUnicodeString(&SubBusString
, Strings
[SubBusLoop
]);
591 /* How much buffer space */
592 ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, NULL
, 0, &LenKeyFullInformation
);
595 BusInformation
[SubBusLoop
] = ExAllocatePoolWithTag(PagedPool
, LenKeyFullInformation
, TAG_IO_RESOURCE
);
597 /* Get the Information */
598 Status
= ZwQueryValueKey(SubRootKeyHandle
, &SubBusString
, KeyValueFullInformation
, BusInformation
[SubBusLoop
], LenKeyFullInformation
, &LenKeyFullInformation
);
601 if (NT_SUCCESS(Status
))
603 /* Do we have something */
604 if (BusInformation
[1] != NULL
&&
605 BusInformation
[1]->DataLength
!= 0 &&
606 /* Does it match what we want? */
607 (((PCM_FULL_RESOURCE_DESCRIPTOR
)((ULONG_PTR
)BusInformation
[1] + BusInformation
[1]->DataOffset
))->InterfaceType
== *(Query
->BusType
)))
612 /* Is it the bus we wanted */
613 if (Query
->BusNumber
== NULL
|| *(Query
->BusNumber
) == *Bus
)
615 /* If we don't want Controller Information, we're done... call the callback */
616 if (Query
->ControllerType
== NULL
)
618 Status
= Query
->CalloutRoutine(
631 /* We want Controller Info...get it */
632 Status
= IopQueryDeviceDescription(Query
, SubRootRegName
, RootKeyHandle
, *Bus
, (PKEY_VALUE_FULL_INFORMATION
*)BusInformation
);
638 /* Free the allocated memory */
639 for (SubBusLoop
= 0; SubBusLoop
< 3; SubBusLoop
++)
641 if (BusInformation
[SubBusLoop
])
643 ExFreePool(BusInformation
[SubBusLoop
]);
644 BusInformation
[SubBusLoop
] = NULL
;
648 /* Exit the Loop if we found the bus */
649 if (Query
->BusNumber
!= NULL
&& *(Query
->BusNumber
) == *Bus
)
651 ZwClose(SubRootKeyHandle
);
652 SubRootKeyHandle
= NULL
;
657 /* Enumerate the buses below us recursively if we haven't found the bus yet */
658 Status
= IopQueryBusDescription(Query
, SubRootRegName
, SubRootKeyHandle
, Bus
, !KeyIsRoot
);
660 /* Everything enumerated */
661 if (Status
== STATUS_NO_MORE_ENTRIES
) Status
= STATUS_SUCCESS
;
663 ZwClose(SubRootKeyHandle
);
664 SubRootKeyHandle
= NULL
;
667 /* Free the last remaining Allocated Memory */
668 if (BasicInformation
)
669 ExFreePool(BasicInformation
);
674 /* PUBLIC FUNCTIONS ***********************************************************/
679 PCONFIGURATION_INFORMATION STDCALL
680 IoGetConfigurationInformation(VOID
)
682 return(&SystemConfigurationInformation
);
689 IoReportResourceUsage(PUNICODE_STRING DriverClassName
,
690 PDRIVER_OBJECT DriverObject
,
691 PCM_RESOURCE_LIST DriverList
,
692 ULONG DriverListSize
,
693 PDEVICE_OBJECT DeviceObject
,
694 PCM_RESOURCE_LIST DeviceList
,
695 ULONG DeviceListSize
,
696 BOOLEAN OverrideConflict
,
697 PBOOLEAN ConflictDetected
)
699 * FUNCTION: Reports hardware resources in the
700 * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
701 * loaded driver cannot attempt to use the same resources.
703 * DriverClassName - The class of driver under which the resource
704 * information should be stored.
705 * DriverObject - The driver object that was input to the
707 * DriverList - Resources that claimed for the driver rather than
709 * DriverListSize - Size in bytes of the DriverList.
710 * DeviceObject - The device object for which resources should be
712 * DeviceList - List of resources which should be claimed for the
714 * DeviceListSize - Size of the per-device resource list in bytes.
715 * OverrideConflict - True if the resources should be cliamed
716 * even if a conflict is found.
717 * ConflictDetected - Points to a variable that receives TRUE if
718 * a conflict is detected with another driver.
721 DPRINT1("IoReportResourceUsage is unimplemented\n");
722 *ConflictDetected
= FALSE
;
723 return STATUS_SUCCESS
;
730 IoAssignResources(PUNICODE_STRING RegistryPath
,
731 PUNICODE_STRING DriverClassName
,
732 PDRIVER_OBJECT DriverObject
,
733 PDEVICE_OBJECT DeviceObject
,
734 PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources
,
735 PCM_RESOURCE_LIST
* AllocatedResources
)
738 return(STATUS_NOT_IMPLEMENTED
);
743 * Reads and returns Hardware information from the appropriate hardware registry key.
746 * BusType - MCA, ISA, EISA...specifies the Bus Type
747 * BusNumber - Which bus of above should be queried
748 * ControllerType - Specifices the Controller Type
749 * ControllerNumber - Which of the controllers to query.
750 * CalloutRoutine - Which function to call for each valid query.
751 * Context - Value to pass to the callback.
761 IoQueryDeviceDescription(PINTERFACE_TYPE BusType
,
763 PCONFIGURATION_TYPE ControllerType
,
764 PULONG ControllerNumber
,
765 PCONFIGURATION_TYPE PeripheralType
,
766 PULONG PeripheralNumber
,
767 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine
,
771 ULONG BusLoopNumber
= -1; /* Root Bus */
772 OBJECT_ATTRIBUTES ObjectAttributes
;
773 UNICODE_STRING RootRegKey
;
774 HANDLE RootRegHandle
;
775 WCHAR RootRegString
[] = L
"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
778 /* Set up the String */
779 RootRegKey
.Length
= 0;
780 RootRegKey
.MaximumLength
= 2048;
781 RootRegKey
.Buffer
= ExAllocatePoolWithTag(PagedPool
, RootRegKey
.MaximumLength
, TAG_IO_RESOURCE
);
782 RtlAppendUnicodeToString(&RootRegKey
, RootRegString
);
784 /* Open a handle to the Root Registry Key */
785 InitializeObjectAttributes(
788 OBJ_CASE_INSENSITIVE
,
792 Status
= ZwOpenKey(&RootRegHandle
, KEY_READ
, &ObjectAttributes
);
794 if (NT_SUCCESS(Status
))
796 /* Use a helper function to loop though this key and get the info */
797 Query
.BusType
= BusType
;
798 Query
.BusNumber
= BusNumber
;
799 Query
.ControllerType
= ControllerType
;
800 Query
.ControllerNumber
= ControllerNumber
;
801 Query
.PeripheralType
= PeripheralType
;
802 Query
.PeripheralNumber
= PeripheralNumber
;
803 Query
.CalloutRoutine
= CalloutRoutine
;
804 Query
.Context
= Context
;
805 Status
= IopQueryBusDescription(&Query
, RootRegKey
, RootRegHandle
, &BusLoopNumber
, TRUE
);
808 ZwClose(RootRegHandle
);
812 ExFreePool(RootRegKey
.Buffer
);
821 IoReportHalResourceUsage(PUNICODE_STRING HalDescription
,
822 PCM_RESOURCE_LIST RawList
,
823 PCM_RESOURCE_LIST TranslatedList
,
827 * Reports hardware resources of the HAL in the
828 * \Registry\Machine\Hardware\ResourceMap tree.
830 * HalDescription: Descriptive name of the HAL.
831 * RawList: List of raw (bus specific) resources which should be
832 * claimed for the HAL.
833 * TranslatedList: List of translated (system wide) resources which
834 * should be claimed for the HAL.
835 * ListSize: Size in bytes of the raw and translated resource lists.
836 * Both lists have the same size.
841 OBJECT_ATTRIBUTES ObjectAttributes
;
845 HANDLE ResourcemapKey
;
847 HANDLE DescriptionKey
;
849 /* Open/Create 'RESOURCEMAP' key. */
850 RtlRosInitUnicodeStringFromLiteral(&Name
,
851 L
"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
852 InitializeObjectAttributes(&ObjectAttributes
,
854 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
857 Status
= NtCreateKey(&ResourcemapKey
,
864 if (!NT_SUCCESS(Status
))
867 /* Open/Create 'Hardware Abstraction Layer' key */
868 RtlRosInitUnicodeStringFromLiteral(&Name
,
869 L
"Hardware Abstraction Layer");
870 InitializeObjectAttributes(&ObjectAttributes
,
872 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
,
875 Status
= NtCreateKey(&HalKey
,
882 NtClose(ResourcemapKey
);
883 if (!NT_SUCCESS(Status
))
886 /* Create 'HalDescription' key */
887 InitializeObjectAttributes(&ObjectAttributes
,
889 OBJ_CASE_INSENSITIVE
,
892 Status
= NtCreateKey(&DescriptionKey
,
900 if (!NT_SUCCESS(Status
))
903 /* Add '.Raw' value. */
904 RtlRosInitUnicodeStringFromLiteral(&Name
,
906 Status
= NtSetValueKey(DescriptionKey
,
912 if (!NT_SUCCESS(Status
))
914 NtClose(DescriptionKey
);
918 /* Add '.Translated' value. */
919 RtlRosInitUnicodeStringFromLiteral(&Name
,
921 Status
= NtSetValueKey(DescriptionKey
,
927 NtClose(DescriptionKey
);