1c2c66affSColin Finck /*
22674e26cSHermès Bélusca-Maïto * PROJECT: ReactOS Kernel
32674e26cSHermès Bélusca-Maïto * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
42674e26cSHermès Bélusca-Maïto * PURPOSE: Hardware resource management
52674e26cSHermès Bélusca-Maïto * COPYRIGHT: Copyright 1998 David Welch <welch@mcmail.com>
62674e26cSHermès Bélusca-Maïto * Copyright 2001 Eric Kohl <eric.kohl@reactos.org>
72674e26cSHermès Bélusca-Maïto * Copyright 2004-2013 Alex Ionescu <alex.ionescu@reactos.org>
82674e26cSHermès Bélusca-Maïto * Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org>
92674e26cSHermès Bélusca-Maïto * Copyright 2010 Pierre Schweitzer <pierre@reactos.org>
10c2c66affSColin Finck */
11c2c66affSColin Finck
12c2c66affSColin Finck /* INCLUDES *****************************************************************/
13c2c66affSColin Finck
14c2c66affSColin Finck #include <ntoskrnl.h>
150b695a6fSHermès Bélusca-Maïto #define NDEBUG
16c2c66affSColin Finck #include <debug.h>
17c2c66affSColin Finck
180b695a6fSHermès Bélusca-Maïto #ifndef NDEBUG
190b695a6fSHermès Bélusca-Maïto #define IORSRCTRACE(...) DbgPrint(__VA_ARGS__)
200b695a6fSHermès Bélusca-Maïto #else
210b695a6fSHermès Bélusca-Maïto #if defined(_MSC_VER)
220b695a6fSHermès Bélusca-Maïto #define IORSRCTRACE __noop
230b695a6fSHermès Bélusca-Maïto #else
240b695a6fSHermès Bélusca-Maïto #define IORSRCTRACE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
250b695a6fSHermès Bélusca-Maïto #endif
260b695a6fSHermès Bélusca-Maïto #endif
270b695a6fSHermès Bélusca-Maïto
28c2c66affSColin Finck /* GLOBALS *******************************************************************/
29c2c66affSColin Finck
30c2c66affSColin Finck static CONFIGURATION_INFORMATION
31c2c66affSColin Finck _SystemConfigurationInformation = { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE, 0, 0 };
32c2c66affSColin Finck
332674e26cSHermès Bélusca-Maïto /* API parameters to pass to IopQueryBusDescription() */
342674e26cSHermès Bélusca-Maïto typedef struct _IO_QUERY
352674e26cSHermès Bélusca-Maïto {
36c2c66affSColin Finck PINTERFACE_TYPE BusType;
37c2c66affSColin Finck PULONG BusNumber;
38c2c66affSColin Finck PCONFIGURATION_TYPE ControllerType;
39c2c66affSColin Finck PULONG ControllerNumber;
40c2c66affSColin Finck PCONFIGURATION_TYPE PeripheralType;
41c2c66affSColin Finck PULONG PeripheralNumber;
42c2c66affSColin Finck PIO_QUERY_DEVICE_ROUTINE CalloutRoutine;
43c2c66affSColin Finck PVOID Context;
44c2c66affSColin Finck } IO_QUERY, *PIO_QUERY;
45c2c66affSColin Finck
462674e26cSHermès Bélusca-Maïto /* Strings corresponding to CONFIGURATION_TYPE */
472674e26cSHermès Bélusca-Maïto PCWSTR ArcTypes[MaximumType + 1] =
482674e26cSHermès Bélusca-Maïto {
49c2c66affSColin Finck L"System",
50c2c66affSColin Finck L"CentralProcessor",
51c2c66affSColin Finck L"FloatingPointProcessor",
52c2c66affSColin Finck L"PrimaryICache",
53c2c66affSColin Finck L"PrimaryDCache",
54c2c66affSColin Finck L"SecondaryICache",
55c2c66affSColin Finck L"SecondaryDCache",
56c2c66affSColin Finck L"SecondaryCache",
57c2c66affSColin Finck L"EisaAdapter",
58c2c66affSColin Finck L"TcAdapter",
59c2c66affSColin Finck L"ScsiAdapter",
60c2c66affSColin Finck L"DtiAdapter",
61c2c66affSColin Finck L"MultifunctionAdapter",
62c2c66affSColin Finck L"DiskController",
63c2c66affSColin Finck L"TapeController",
64c2c66affSColin Finck L"CdRomController",
65c2c66affSColin Finck L"WormController",
66c2c66affSColin Finck L"SerialController",
67c2c66affSColin Finck L"NetworkController",
68c2c66affSColin Finck L"DisplayController",
69c2c66affSColin Finck L"ParallelController",
70c2c66affSColin Finck L"PointerController",
71c2c66affSColin Finck L"KeyboardController",
72c2c66affSColin Finck L"AudioController",
73c2c66affSColin Finck L"OtherController",
74c2c66affSColin Finck L"DiskPeripheral",
75c2c66affSColin Finck L"FloppyDiskPeripheral",
76c2c66affSColin Finck L"TapePeripheral",
77c2c66affSColin Finck L"ModemPeripheral",
78c2c66affSColin Finck L"MonitorPeripheral",
79c2c66affSColin Finck L"PrinterPeripheral",
80c2c66affSColin Finck L"PointerPeripheral",
81c2c66affSColin Finck L"KeyboardPeripheral",
82c2c66affSColin Finck L"TerminalPeripheral",
83c2c66affSColin Finck L"OtherPeripheral",
84c2c66affSColin Finck L"LinePeripheral",
85c2c66affSColin Finck L"NetworkPeripheral",
86c2c66affSColin Finck L"SystemMemory",
87c2c66affSColin Finck L"DockingInformation",
88c2c66affSColin Finck L"RealModeIrqRoutingTable",
89c2c66affSColin Finck L"RealModePCIEnumeration",
90c2c66affSColin Finck L"Undefined"
91c2c66affSColin Finck };
92c2c66affSColin Finck
932674e26cSHermès Bélusca-Maïto /* Strings corresponding to IO_QUERY_DEVICE_DATA_FORMAT */
942674e26cSHermès Bélusca-Maïto PCWSTR IoDeviceInfoNames[IoQueryDeviceMaxData] =
95c2c66affSColin Finck {
96c2c66affSColin Finck L"Identifier",
97c2c66affSColin Finck L"Configuration Data",
98c2c66affSColin Finck L"Component Information"
99c2c66affSColin Finck };
100c2c66affSColin Finck
1012674e26cSHermès Bélusca-Maïto /* PRIVATE FUNCTIONS **********************************************************/
1022674e26cSHermès Bélusca-Maïto
1032674e26cSHermès Bélusca-Maïto /**
1042674e26cSHermès Bélusca-Maïto * @brief
1052674e26cSHermès Bélusca-Maïto * Reads and returns Hardware information from the appropriate hardware
1062674e26cSHermès Bélusca-Maïto * registry key. Helper stub of IopQueryBusDescription().
1072674e26cSHermès Bélusca-Maïto *
1082674e26cSHermès Bélusca-Maïto * @param[in] Query
1092674e26cSHermès Bélusca-Maïto * What the parent function wants.
1102674e26cSHermès Bélusca-Maïto *
1112674e26cSHermès Bélusca-Maïto * @param[in] RootKey
1122674e26cSHermès Bélusca-Maïto * Which key to look in.
1132674e26cSHermès Bélusca-Maïto *
1142674e26cSHermès Bélusca-Maïto * @param[in] RootKeyHandle
1152674e26cSHermès Bélusca-Maïto * Handle to the key.
1162674e26cSHermès Bélusca-Maïto *
1172674e26cSHermès Bélusca-Maïto * @param[in] Bus
1182674e26cSHermès Bélusca-Maïto * The bus number.
1192674e26cSHermès Bélusca-Maïto *
1202674e26cSHermès Bélusca-Maïto * @param[in] BusInformation
1212674e26cSHermès Bélusca-Maïto * The configuration information being sent.
1222674e26cSHermès Bélusca-Maïto *
1232674e26cSHermès Bélusca-Maïto * @return A status code.
1242674e26cSHermès Bélusca-Maïto **/
1252674e26cSHermès Bélusca-Maïto static NTSTATUS
IopQueryDeviceDescription(_In_ PIO_QUERY Query,_In_ UNICODE_STRING RootKey,_In_ HANDLE RootKeyHandle,_In_ ULONG Bus,_In_ PKEY_VALUE_FULL_INFORMATION * BusInformation)1262674e26cSHermès Bélusca-Maïto IopQueryDeviceDescription(
1272674e26cSHermès Bélusca-Maïto _In_ PIO_QUERY Query,
1282674e26cSHermès Bélusca-Maïto _In_ UNICODE_STRING RootKey,
1292674e26cSHermès Bélusca-Maïto _In_ HANDLE RootKeyHandle,
1302674e26cSHermès Bélusca-Maïto _In_ ULONG Bus,
1312674e26cSHermès Bélusca-Maïto _In_ PKEY_VALUE_FULL_INFORMATION* BusInformation)
1322674e26cSHermès Bélusca-Maïto {
1332674e26cSHermès Bélusca-Maïto NTSTATUS Status = STATUS_SUCCESS;
1342674e26cSHermès Bélusca-Maïto
1352674e26cSHermès Bélusca-Maïto /* Controller data */
1362674e26cSHermès Bélusca-Maïto UNICODE_STRING ControllerString;
1372674e26cSHermès Bélusca-Maïto UNICODE_STRING ControllerRootRegName = RootKey;
1382674e26cSHermès Bélusca-Maïto UNICODE_STRING ControllerRegName;
1392674e26cSHermès Bélusca-Maïto HANDLE ControllerKeyHandle;
1402674e26cSHermès Bélusca-Maïto PKEY_FULL_INFORMATION ControllerFullInformation = NULL;
1412674e26cSHermès Bélusca-Maïto PKEY_VALUE_FULL_INFORMATION ControllerInformation[IoQueryDeviceMaxData] =
1422674e26cSHermès Bélusca-Maïto {NULL, NULL, NULL};
1432674e26cSHermès Bélusca-Maïto ULONG ControllerNumber;
1442674e26cSHermès Bélusca-Maïto ULONG ControllerLoop;
1452674e26cSHermès Bélusca-Maïto ULONG MaximumControllerNumber;
1462674e26cSHermès Bélusca-Maïto
1472674e26cSHermès Bélusca-Maïto /* Peripheral data */
1482674e26cSHermès Bélusca-Maïto UNICODE_STRING PeripheralString;
1492674e26cSHermès Bélusca-Maïto HANDLE PeripheralKeyHandle;
1502674e26cSHermès Bélusca-Maïto PKEY_FULL_INFORMATION PeripheralFullInformation;
1512674e26cSHermès Bélusca-Maïto PKEY_VALUE_FULL_INFORMATION PeripheralInformation[IoQueryDeviceMaxData] =
1522674e26cSHermès Bélusca-Maïto {NULL, NULL, NULL};
1532674e26cSHermès Bélusca-Maïto ULONG PeripheralNumber;
1542674e26cSHermès Bélusca-Maïto ULONG PeripheralLoop;
1552674e26cSHermès Bélusca-Maïto ULONG MaximumPeripheralNumber;
1562674e26cSHermès Bélusca-Maïto
1572674e26cSHermès Bélusca-Maïto /* Global Registry data */
1582674e26cSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes;
1592674e26cSHermès Bélusca-Maïto ULONG LenFullInformation;
1602674e26cSHermès Bélusca-Maïto ULONG LenKeyFullInformation;
1612674e26cSHermès Bélusca-Maïto UNICODE_STRING TempString;
1622674e26cSHermès Bélusca-Maïto WCHAR TempBuffer[14];
1632674e26cSHermès Bélusca-Maïto
1640b695a6fSHermès Bélusca-Maïto IORSRCTRACE("\nIopQueryDeviceDescription(Query: 0x%p)\n"
1650b695a6fSHermès Bélusca-Maïto " RootKey: '%wZ'\n"
1660b695a6fSHermès Bélusca-Maïto " RootKeyHandle: 0x%p\n"
1670b695a6fSHermès Bélusca-Maïto " Bus: %lu\n",
1680b695a6fSHermès Bélusca-Maïto Query,
1690b695a6fSHermès Bélusca-Maïto &RootKey, RootKeyHandle,
1700b695a6fSHermès Bélusca-Maïto Bus);
1710b695a6fSHermès Bélusca-Maïto
1722674e26cSHermès Bélusca-Maïto /* Temporary string */
173*84b4a80bSHermès Bélusca-Maïto RtlInitEmptyUnicodeString(&TempString, TempBuffer, sizeof(TempBuffer));
174c2c66affSColin Finck
1752674e26cSHermès Bélusca-Maïto /* Append controller name to string */
176c2c66affSColin Finck RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
177c2c66affSColin Finck RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->ControllerType]);
178c2c66affSColin Finck
1792674e26cSHermès Bélusca-Maïto /* Set the controller number if specified */
180*84b4a80bSHermès Bélusca-Maïto if (Query->ControllerNumber)
181c2c66affSColin Finck {
182*84b4a80bSHermès Bélusca-Maïto ControllerNumber = *(Query->ControllerNumber);
183c2c66affSColin Finck MaximumControllerNumber = ControllerNumber + 1;
1840b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Getting controller #%lu\n", ControllerNumber);
1852674e26cSHermès Bélusca-Maïto }
1862674e26cSHermès Bélusca-Maïto else
1872674e26cSHermès Bélusca-Maïto {
1880b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Enumerating controllers in '%wZ'...\n", &ControllerRootRegName);
1890b695a6fSHermès Bélusca-Maïto
1902674e26cSHermès Bélusca-Maïto /* Find out how many controllers there are */
1912674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
192c2c66affSColin Finck &ControllerRootRegName,
193c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
194c2c66affSColin Finck NULL,
195c2c66affSColin Finck NULL);
196c2c66affSColin Finck
197c2c66affSColin Finck Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes);
1982674e26cSHermès Bélusca-Maïto
199c2c66affSColin Finck if (NT_SUCCESS(Status))
200c2c66affSColin Finck {
2012674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
2022674e26cSHermès Bélusca-Maïto ZwQueryKey(ControllerKeyHandle,
2032674e26cSHermès Bélusca-Maïto KeyFullInformation,
2042674e26cSHermès Bélusca-Maïto NULL, 0,
2052674e26cSHermès Bélusca-Maïto &LenFullInformation);
206c2c66affSColin Finck
207c2c66affSColin Finck /* Allocate it */
208c2c66affSColin Finck ControllerFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
209*84b4a80bSHermès Bélusca-Maïto if (!ControllerFullInformation)
210*84b4a80bSHermès Bélusca-Maïto {
211*84b4a80bSHermès Bélusca-Maïto ZwClose(ControllerKeyHandle);
212*84b4a80bSHermès Bélusca-Maïto return STATUS_INSUFFICIENT_RESOURCES;
213*84b4a80bSHermès Bélusca-Maïto }
214c2c66affSColin Finck
2152674e26cSHermès Bélusca-Maïto /* Get the information */
2162674e26cSHermès Bélusca-Maïto Status = ZwQueryKey(ControllerKeyHandle,
2172674e26cSHermès Bélusca-Maïto KeyFullInformation,
2182674e26cSHermès Bélusca-Maïto ControllerFullInformation,
2192674e26cSHermès Bélusca-Maïto LenFullInformation,
2202674e26cSHermès Bélusca-Maïto &LenFullInformation);
221c2c66affSColin Finck ZwClose(ControllerKeyHandle);
222c2c66affSColin Finck ControllerKeyHandle = NULL;
223c2c66affSColin Finck }
224c2c66affSColin Finck
2252674e26cSHermès Bélusca-Maïto /* No controller was found, bail out */
226c2c66affSColin Finck if (!NT_SUCCESS(Status))
227c2c66affSColin Finck {
228*84b4a80bSHermès Bélusca-Maïto if (ControllerFullInformation)
229c2c66affSColin Finck ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE);
230c2c66affSColin Finck return Status;
231c2c66affSColin Finck }
232c2c66affSColin Finck
2332674e26cSHermès Bélusca-Maïto /* Find out the controllers */
234c2c66affSColin Finck ControllerNumber = 0;
235c2c66affSColin Finck MaximumControllerNumber = ControllerFullInformation->SubKeys;
236c2c66affSColin Finck
2372674e26cSHermès Bélusca-Maïto /* Cleanup */
238c2c66affSColin Finck ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE);
239c2c66affSColin Finck ControllerFullInformation = NULL;
240c2c66affSColin Finck }
241c2c66affSColin Finck
2422674e26cSHermès Bélusca-Maïto /* Save string */
243c2c66affSColin Finck ControllerRegName = ControllerRootRegName;
244c2c66affSColin Finck
245c2c66affSColin Finck /* Loop through controllers */
246c2c66affSColin Finck for (; ControllerNumber < MaximumControllerNumber; ControllerNumber++)
247c2c66affSColin Finck {
2482674e26cSHermès Bélusca-Maïto /* Load string */
249c2c66affSColin Finck ControllerRootRegName = ControllerRegName;
250c2c66affSColin Finck
2512674e26cSHermès Bélusca-Maïto /* Convert controller number to registry string */
252c2c66affSColin Finck Status = RtlIntegerToUnicodeString(ControllerNumber, 10, &TempString);
253c2c66affSColin Finck
2542674e26cSHermès Bélusca-Maïto /* Create string */
255c2c66affSColin Finck Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
256c2c66affSColin Finck Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);
257c2c66affSColin Finck
258c2c66affSColin Finck /* Something messed up */
2592674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
2602674e26cSHermès Bélusca-Maïto break;
261c2c66affSColin Finck
2620b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Retrieving controller '%wZ'\n", &ControllerRootRegName);
2630b695a6fSHermès Bélusca-Maïto
2642674e26cSHermès Bélusca-Maïto /* Open the registry key */
2652674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
266c2c66affSColin Finck &ControllerRootRegName,
267c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
268c2c66affSColin Finck NULL,
269c2c66affSColin Finck NULL);
270c2c66affSColin Finck
271c2c66affSColin Finck Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes);
272c2c66affSColin Finck
2732674e26cSHermès Bélusca-Maïto /* Read the configuration data */
274c2c66affSColin Finck if (NT_SUCCESS(Status))
275c2c66affSColin Finck {
2762674e26cSHermès Bélusca-Maïto for (ControllerLoop = 0; ControllerLoop < RTL_NUMBER_OF(IoDeviceInfoNames); ControllerLoop++)
277c2c66affSColin Finck {
2782674e26cSHermès Bélusca-Maïto /* Identifier string first */
2792674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&ControllerString, IoDeviceInfoNames[ControllerLoop]);
280c2c66affSColin Finck
2812674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
2822674e26cSHermès Bélusca-Maïto Status = ZwQueryValueKey(ControllerKeyHandle,
2832674e26cSHermès Bélusca-Maïto &ControllerString,
2842674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
2852674e26cSHermès Bélusca-Maïto NULL, 0,
2862674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
287c2c66affSColin Finck
2882674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status) &&
2892674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_TOO_SMALL) &&
2902674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_OVERFLOW))
2912674e26cSHermès Bélusca-Maïto {
292*84b4a80bSHermès Bélusca-Maïto ControllerInformation[ControllerLoop] = NULL;
293c2c66affSColin Finck continue;
2942674e26cSHermès Bélusca-Maïto }
295c2c66affSColin Finck
296c2c66affSColin Finck /* Allocate it */
297c2c66affSColin Finck ControllerInformation[ControllerLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
298*84b4a80bSHermès Bélusca-Maïto if (!ControllerInformation[ControllerLoop])
299*84b4a80bSHermès Bélusca-Maïto {
300*84b4a80bSHermès Bélusca-Maïto Status = STATUS_INSUFFICIENT_RESOURCES;
301*84b4a80bSHermès Bélusca-Maïto break;
302*84b4a80bSHermès Bélusca-Maïto }
303c2c66affSColin Finck
3042674e26cSHermès Bélusca-Maïto /* Get the information */
3052674e26cSHermès Bélusca-Maïto Status = ZwQueryValueKey(ControllerKeyHandle,
3062674e26cSHermès Bélusca-Maïto &ControllerString,
3072674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
3082674e26cSHermès Bélusca-Maïto ControllerInformation[ControllerLoop],
3092674e26cSHermès Bélusca-Maïto LenKeyFullInformation,
3102674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
311c2c66affSColin Finck }
312c2c66affSColin Finck
3132674e26cSHermès Bélusca-Maïto /* Cleanup */
314c2c66affSColin Finck ZwClose(ControllerKeyHandle);
315c2c66affSColin Finck ControllerKeyHandle = NULL;
316c2c66affSColin Finck }
317c2c66affSColin Finck
318c2c66affSColin Finck /* Something messed up */
319c2c66affSColin Finck if (!NT_SUCCESS(Status))
320c2c66affSColin Finck goto EndLoop;
321c2c66affSColin Finck
3222674e26cSHermès Bélusca-Maïto /* We now have bus *AND* controller information, is it enough? */
323c2c66affSColin Finck if (!Query->PeripheralType || !(*Query->PeripheralType))
324c2c66affSColin Finck {
3250b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" --> Bus #%lu Controller #%lu Callout: '%wZ'\n",
3260b695a6fSHermès Bélusca-Maïto Bus, ControllerNumber, &ControllerRootRegName);
3270b695a6fSHermès Bélusca-Maïto
3282674e26cSHermès Bélusca-Maïto Status = Query->CalloutRoutine(Query->Context,
329c2c66affSColin Finck &ControllerRootRegName,
330c2c66affSColin Finck *Query->BusType,
331c2c66affSColin Finck Bus,
332c2c66affSColin Finck BusInformation,
333c2c66affSColin Finck *Query->ControllerType,
334c2c66affSColin Finck ControllerNumber,
335c2c66affSColin Finck ControllerInformation,
336c2c66affSColin Finck 0,
337c2c66affSColin Finck 0,
338c2c66affSColin Finck NULL);
339c2c66affSColin Finck goto EndLoop;
340c2c66affSColin Finck }
341c2c66affSColin Finck
3422674e26cSHermès Bélusca-Maïto /* Not enough: the caller also wants peripheral name */
343c2c66affSColin Finck Status = RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
344c2c66affSColin Finck Status |= RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->PeripheralType]);
345c2c66affSColin Finck
346c2c66affSColin Finck /* Something messed up */
3472674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
3482674e26cSHermès Bélusca-Maïto goto EndLoop;
349c2c66affSColin Finck
3502674e26cSHermès Bélusca-Maïto /* Set the peripheral number if specified */
351*84b4a80bSHermès Bélusca-Maïto if (Query->PeripheralNumber)
352c2c66affSColin Finck {
353*84b4a80bSHermès Bélusca-Maïto PeripheralNumber = *(Query->PeripheralNumber);
354c2c66affSColin Finck MaximumPeripheralNumber = PeripheralNumber + 1;
3550b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Getting peripheral #%lu\n", PeripheralNumber);
3562674e26cSHermès Bélusca-Maïto }
3572674e26cSHermès Bélusca-Maïto else
3582674e26cSHermès Bélusca-Maïto {
3590b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Enumerating peripherals in '%wZ'...\n", &ControllerRootRegName);
3600b695a6fSHermès Bélusca-Maïto
3612674e26cSHermès Bélusca-Maïto /* Find out how many peripherals there are */
3622674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
363c2c66affSColin Finck &ControllerRootRegName,
364c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
365c2c66affSColin Finck NULL,
366c2c66affSColin Finck NULL);
367c2c66affSColin Finck
368c2c66affSColin Finck Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes);
369c2c66affSColin Finck
370c2c66affSColin Finck if (NT_SUCCESS(Status))
371c2c66affSColin Finck {
3722674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
3732674e26cSHermès Bélusca-Maïto ZwQueryKey(PeripheralKeyHandle,
3742674e26cSHermès Bélusca-Maïto KeyFullInformation,
3752674e26cSHermès Bélusca-Maïto NULL, 0,
3762674e26cSHermès Bélusca-Maïto &LenFullInformation);
377c2c66affSColin Finck
378c2c66affSColin Finck /* Allocate it */
379c2c66affSColin Finck PeripheralFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
380*84b4a80bSHermès Bélusca-Maïto if (!PeripheralFullInformation)
381*84b4a80bSHermès Bélusca-Maïto {
382*84b4a80bSHermès Bélusca-Maïto ZwClose(PeripheralKeyHandle);
383*84b4a80bSHermès Bélusca-Maïto Status = STATUS_INSUFFICIENT_RESOURCES;
384*84b4a80bSHermès Bélusca-Maïto goto EndLoop;
385*84b4a80bSHermès Bélusca-Maïto }
386c2c66affSColin Finck
3872674e26cSHermès Bélusca-Maïto /* Get the information */
3882674e26cSHermès Bélusca-Maïto Status = ZwQueryKey(PeripheralKeyHandle,
3892674e26cSHermès Bélusca-Maïto KeyFullInformation,
3902674e26cSHermès Bélusca-Maïto PeripheralFullInformation,
3912674e26cSHermès Bélusca-Maïto LenFullInformation,
3922674e26cSHermès Bélusca-Maïto &LenFullInformation);
393c2c66affSColin Finck ZwClose(PeripheralKeyHandle);
394c2c66affSColin Finck PeripheralKeyHandle = NULL;
395c2c66affSColin Finck }
396c2c66affSColin Finck
3972674e26cSHermès Bélusca-Maïto /* No controller was found, cleanup and bail out */
398c2c66affSColin Finck if (!NT_SUCCESS(Status))
399c2c66affSColin Finck {
400c2c66affSColin Finck Status = STATUS_SUCCESS;
401c2c66affSColin Finck goto EndLoop;
402c2c66affSColin Finck }
403c2c66affSColin Finck
4042674e26cSHermès Bélusca-Maïto /* Find out peripheral number */
405c2c66affSColin Finck PeripheralNumber = 0;
406c2c66affSColin Finck MaximumPeripheralNumber = PeripheralFullInformation->SubKeys;
407c2c66affSColin Finck
4082674e26cSHermès Bélusca-Maïto /* Cleanup */
409c2c66affSColin Finck ExFreePoolWithTag(PeripheralFullInformation, TAG_IO_RESOURCE);
410c2c66affSColin Finck PeripheralFullInformation = NULL;
411c2c66affSColin Finck }
412c2c66affSColin Finck
4132674e26cSHermès Bélusca-Maïto /* Save name */
414c2c66affSColin Finck ControllerRegName = ControllerRootRegName;
415c2c66affSColin Finck
4162674e26cSHermès Bélusca-Maïto /* Loop through peripherals */
417c2c66affSColin Finck for (; PeripheralNumber < MaximumPeripheralNumber; PeripheralNumber++)
418c2c66affSColin Finck {
4192674e26cSHermès Bélusca-Maïto /* Restore name */
420c2c66affSColin Finck ControllerRootRegName = ControllerRegName;
421c2c66affSColin Finck
4222674e26cSHermès Bélusca-Maïto /* Convert peripheral number to registry string */
423c2c66affSColin Finck Status = RtlIntegerToUnicodeString(PeripheralNumber, 10, &TempString);
424c2c66affSColin Finck
4252674e26cSHermès Bélusca-Maïto /* Create string */
426c2c66affSColin Finck Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
427c2c66affSColin Finck Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);
428c2c66affSColin Finck
429c2c66affSColin Finck /* Something messed up */
4302674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
4312674e26cSHermès Bélusca-Maïto break;
432c2c66affSColin Finck
4330b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Retrieving peripheral '%wZ'\n", &ControllerRootRegName);
4340b695a6fSHermès Bélusca-Maïto
4352674e26cSHermès Bélusca-Maïto /* Open the registry key */
4362674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
437c2c66affSColin Finck &ControllerRootRegName,
438c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
439c2c66affSColin Finck NULL,
440c2c66affSColin Finck NULL);
441c2c66affSColin Finck
442c2c66affSColin Finck Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes);
443c2c66affSColin Finck
444c2c66affSColin Finck if (NT_SUCCESS(Status))
445c2c66affSColin Finck {
4462674e26cSHermès Bélusca-Maïto for (PeripheralLoop = 0; PeripheralLoop < RTL_NUMBER_OF(IoDeviceInfoNames); PeripheralLoop++)
447c2c66affSColin Finck {
4482674e26cSHermès Bélusca-Maïto /* Identifier string first */
4492674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&PeripheralString, IoDeviceInfoNames[PeripheralLoop]);
450c2c66affSColin Finck
4512674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
4522674e26cSHermès Bélusca-Maïto Status = ZwQueryValueKey(PeripheralKeyHandle,
4532674e26cSHermès Bélusca-Maïto &PeripheralString,
4542674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
4552674e26cSHermès Bélusca-Maïto NULL, 0,
4562674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
457c2c66affSColin Finck
4582674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status) &&
4592674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_TOO_SMALL) &&
4602674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_OVERFLOW))
461c2c66affSColin Finck {
462c2c66affSColin Finck PeripheralInformation[PeripheralLoop] = NULL;
463c2c66affSColin Finck continue;
464c2c66affSColin Finck }
465c2c66affSColin Finck
466c2c66affSColin Finck /* Allocate it */
467c2c66affSColin Finck PeripheralInformation[PeripheralLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
468*84b4a80bSHermès Bélusca-Maïto if (!PeripheralInformation[PeripheralLoop])
469*84b4a80bSHermès Bélusca-Maïto {
470*84b4a80bSHermès Bélusca-Maïto Status = STATUS_INSUFFICIENT_RESOURCES;
471*84b4a80bSHermès Bélusca-Maïto break;
472*84b4a80bSHermès Bélusca-Maïto }
473c2c66affSColin Finck
4742674e26cSHermès Bélusca-Maïto /* Get the information */
4752674e26cSHermès Bélusca-Maïto Status = ZwQueryValueKey(PeripheralKeyHandle,
4762674e26cSHermès Bélusca-Maïto &PeripheralString,
4772674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
4782674e26cSHermès Bélusca-Maïto PeripheralInformation[PeripheralLoop],
4792674e26cSHermès Bélusca-Maïto LenKeyFullInformation,
4802674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
481c2c66affSColin Finck }
482c2c66affSColin Finck
4832674e26cSHermès Bélusca-Maïto /* Cleanup */
484c2c66affSColin Finck ZwClose(PeripheralKeyHandle);
485c2c66affSColin Finck PeripheralKeyHandle = NULL;
486c2c66affSColin Finck
487c2c66affSColin Finck /* We now have everything the caller could possibly want */
488c2c66affSColin Finck if (NT_SUCCESS(Status))
489c2c66affSColin Finck {
4900b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" --> Bus #%lu Controller #%lu Peripheral #%lu Callout: '%wZ'\n",
4910b695a6fSHermès Bélusca-Maïto Bus, ControllerNumber, PeripheralNumber, &ControllerRootRegName);
4920b695a6fSHermès Bélusca-Maïto
4932674e26cSHermès Bélusca-Maïto Status = Query->CalloutRoutine(Query->Context,
494c2c66affSColin Finck &ControllerRootRegName,
495c2c66affSColin Finck *Query->BusType,
496c2c66affSColin Finck Bus,
497c2c66affSColin Finck BusInformation,
498c2c66affSColin Finck *Query->ControllerType,
499c2c66affSColin Finck ControllerNumber,
500c2c66affSColin Finck ControllerInformation,
501c2c66affSColin Finck *Query->PeripheralType,
502c2c66affSColin Finck PeripheralNumber,
503c2c66affSColin Finck PeripheralInformation);
504c2c66affSColin Finck }
505c2c66affSColin Finck
506c2c66affSColin Finck /* Free the allocated memory */
5072674e26cSHermès Bélusca-Maïto for (PeripheralLoop = 0; PeripheralLoop < RTL_NUMBER_OF(IoDeviceInfoNames); PeripheralLoop++)
508c2c66affSColin Finck {
509c2c66affSColin Finck if (PeripheralInformation[PeripheralLoop])
510c2c66affSColin Finck {
511c2c66affSColin Finck ExFreePoolWithTag(PeripheralInformation[PeripheralLoop], TAG_IO_RESOURCE);
512c2c66affSColin Finck PeripheralInformation[PeripheralLoop] = NULL;
513c2c66affSColin Finck }
514c2c66affSColin Finck }
515c2c66affSColin Finck
5162674e26cSHermès Bélusca-Maïto /* Something messed up */
5172674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
5182674e26cSHermès Bélusca-Maïto break;
519c2c66affSColin Finck }
520c2c66affSColin Finck }
521c2c66affSColin Finck
522c2c66affSColin Finck EndLoop:
523c2c66affSColin Finck /* Free the allocated memory */
5242674e26cSHermès Bélusca-Maïto for (ControllerLoop = 0; ControllerLoop < RTL_NUMBER_OF(IoDeviceInfoNames); ControllerLoop++)
525c2c66affSColin Finck {
526c2c66affSColin Finck if (ControllerInformation[ControllerLoop])
527c2c66affSColin Finck {
528c2c66affSColin Finck ExFreePoolWithTag(ControllerInformation[ControllerLoop], TAG_IO_RESOURCE);
529c2c66affSColin Finck ControllerInformation[ControllerLoop] = NULL;
530c2c66affSColin Finck }
531c2c66affSColin Finck }
532c2c66affSColin Finck
5332674e26cSHermès Bélusca-Maïto /* Something messed up */
5342674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
5352674e26cSHermès Bélusca-Maïto break;
536c2c66affSColin Finck }
537c2c66affSColin Finck
538c2c66affSColin Finck return Status;
539c2c66affSColin Finck }
540c2c66affSColin Finck
5412674e26cSHermès Bélusca-Maïto /**
5422674e26cSHermès Bélusca-Maïto * @brief
543c2c66affSColin Finck * Reads and returns Hardware information from the appropriate hardware
5442674e26cSHermès Bélusca-Maïto * registry key. Helper stub of IoQueryDeviceDescription(). Has two modes
5452674e26cSHermès Bélusca-Maïto * of operation, either looking for root bus types or for sub-bus
546c2c66affSColin Finck * information.
547c2c66affSColin Finck *
5482674e26cSHermès Bélusca-Maïto * @param[in] Query
5492674e26cSHermès Bélusca-Maïto * What the parent function wants.
550c2c66affSColin Finck *
5512674e26cSHermès Bélusca-Maïto * @param[in] RootKey
5522674e26cSHermès Bélusca-Maïto * Which key to look in.
5532674e26cSHermès Bélusca-Maïto *
5542674e26cSHermès Bélusca-Maïto * @param[in] RootKeyHandle
5552674e26cSHermès Bélusca-Maïto * Handle to the key.
5562674e26cSHermès Bélusca-Maïto *
5572674e26cSHermès Bélusca-Maïto * @param[in,out] Bus
5582674e26cSHermès Bélusca-Maïto * Pointer to the current bus number.
5592674e26cSHermès Bélusca-Maïto *
5602674e26cSHermès Bélusca-Maïto * @param[in] KeyIsRoot
5612674e26cSHermès Bélusca-Maïto * Whether we are looking for root bus types or information under them.
5622674e26cSHermès Bélusca-Maïto *
5632674e26cSHermès Bélusca-Maïto * @return A status code.
5642674e26cSHermès Bélusca-Maïto **/
5652674e26cSHermès Bélusca-Maïto static NTSTATUS
IopQueryBusDescription(_In_ PIO_QUERY Query,_In_ UNICODE_STRING RootKey,_In_ HANDLE RootKeyHandle,_Inout_ PULONG Bus,_In_ BOOLEAN KeyIsRoot)566c2c66affSColin Finck IopQueryBusDescription(
5672674e26cSHermès Bélusca-Maïto _In_ PIO_QUERY Query,
5682674e26cSHermès Bélusca-Maïto _In_ UNICODE_STRING RootKey,
5692674e26cSHermès Bélusca-Maïto _In_ HANDLE RootKeyHandle,
5702674e26cSHermès Bélusca-Maïto _Inout_ PULONG Bus,
5712674e26cSHermès Bélusca-Maïto _In_ BOOLEAN KeyIsRoot)
572c2c66affSColin Finck {
573c2c66affSColin Finck NTSTATUS Status;
574c2c66affSColin Finck ULONG BusLoop;
575c2c66affSColin Finck UNICODE_STRING SubRootRegName;
576c2c66affSColin Finck UNICODE_STRING BusString;
577c2c66affSColin Finck UNICODE_STRING SubBusString;
578c2c66affSColin Finck ULONG LenBasicInformation = 0;
579c2c66affSColin Finck ULONG LenFullInformation;
580c2c66affSColin Finck ULONG LenKeyFullInformation;
581c2c66affSColin Finck ULONG LenKey;
582c2c66affSColin Finck HANDLE SubRootKeyHandle;
583c2c66affSColin Finck PKEY_FULL_INFORMATION FullInformation;
584c2c66affSColin Finck PKEY_BASIC_INFORMATION BasicInformation = NULL;
585c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
5862674e26cSHermès Bélusca-Maïto PKEY_VALUE_FULL_INFORMATION BusInformation[IoQueryDeviceMaxData] =
5872674e26cSHermès Bélusca-Maïto {NULL, NULL, NULL};
588c2c66affSColin Finck
5890b695a6fSHermès Bélusca-Maïto IORSRCTRACE("\nIopQueryBusDescription(Query: 0x%p)\n"
5900b695a6fSHermès Bélusca-Maïto " RootKey: '%wZ'\n"
5910b695a6fSHermès Bélusca-Maïto " RootKeyHandle: 0x%p\n"
5920b695a6fSHermès Bélusca-Maïto " KeyIsRoot: %s\n"
5930b695a6fSHermès Bélusca-Maïto " Bus: 0x%p (%lu)\n",
5940b695a6fSHermès Bélusca-Maïto Query,
5950b695a6fSHermès Bélusca-Maïto &RootKey, RootKeyHandle,
5960b695a6fSHermès Bélusca-Maïto KeyIsRoot ? "TRUE" : "FALSE",
5970b695a6fSHermès Bélusca-Maïto Bus, Bus ? *Bus : -1);
5980b695a6fSHermès Bélusca-Maïto
5992674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
6002674e26cSHermès Bélusca-Maïto Status = ZwQueryKey(RootKeyHandle,
6012674e26cSHermès Bélusca-Maïto KeyFullInformation,
6022674e26cSHermès Bélusca-Maïto NULL, 0,
6032674e26cSHermès Bélusca-Maïto &LenFullInformation);
604c2c66affSColin Finck
6052674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status) &&
6062674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_TOO_SMALL) &&
6072674e26cSHermès Bélusca-Maïto (Status != STATUS_BUFFER_OVERFLOW))
6082674e26cSHermès Bélusca-Maïto {
609c2c66affSColin Finck return Status;
6102674e26cSHermès Bélusca-Maïto }
611c2c66affSColin Finck
612c2c66affSColin Finck /* Allocate it */
613c2c66affSColin Finck FullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
614c2c66affSColin Finck if (!FullInformation)
615*84b4a80bSHermès Bélusca-Maïto return STATUS_INSUFFICIENT_RESOURCES;
616c2c66affSColin Finck
6172674e26cSHermès Bélusca-Maïto /* Get the information */
6182674e26cSHermès Bélusca-Maïto Status = ZwQueryKey(RootKeyHandle,
6192674e26cSHermès Bélusca-Maïto KeyFullInformation,
6202674e26cSHermès Bélusca-Maïto FullInformation,
6212674e26cSHermès Bélusca-Maïto LenFullInformation,
6222674e26cSHermès Bélusca-Maïto &LenFullInformation);
623c2c66affSColin Finck if (NT_SUCCESS(Status))
624c2c66affSColin Finck {
625c2c66affSColin Finck /* Buffer needed for all the keys under this one */
626c2c66affSColin Finck LenBasicInformation = FullInformation->MaxNameLen + sizeof(KEY_BASIC_INFORMATION);
627c2c66affSColin Finck
628c2c66affSColin Finck /* Allocate it */
629c2c66affSColin Finck BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE);
630*84b4a80bSHermès Bélusca-Maïto if (!BasicInformation)
631*84b4a80bSHermès Bélusca-Maïto {
632*84b4a80bSHermès Bélusca-Maïto ExFreePoolWithTag(FullInformation, TAG_IO_RESOURCE);
633*84b4a80bSHermès Bélusca-Maïto return STATUS_INSUFFICIENT_RESOURCES;
634*84b4a80bSHermès Bélusca-Maïto }
635c2c66affSColin Finck }
636c2c66affSColin Finck
6372674e26cSHermès Bélusca-Maïto /* Deallocate the old buffer */
638c2c66affSColin Finck ExFreePoolWithTag(FullInformation, TAG_IO_RESOURCE);
639c2c66affSColin Finck
6402674e26cSHermès Bélusca-Maïto /* Try to find a bus */
641c2c66affSColin Finck for (BusLoop = 0; NT_SUCCESS(Status); BusLoop++)
642c2c66affSColin Finck {
643c2c66affSColin Finck /* Bus parameter was passed and number was matched */
6442674e26cSHermès Bélusca-Maïto if (Query->BusNumber && (*(Query->BusNumber) == *Bus))
6452674e26cSHermès Bélusca-Maïto break;
646c2c66affSColin Finck
647c2c66affSColin Finck /* Enumerate the Key */
6482674e26cSHermès Bélusca-Maïto Status = ZwEnumerateKey(RootKeyHandle,
649c2c66affSColin Finck BusLoop,
650c2c66affSColin Finck KeyBasicInformation,
651c2c66affSColin Finck BasicInformation,
652c2c66affSColin Finck LenBasicInformation,
653c2c66affSColin Finck &LenKey);
654c2c66affSColin Finck
6552674e26cSHermès Bélusca-Maïto /* Stop if everything was enumerated */
6562674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
6572674e26cSHermès Bélusca-Maïto break;
658c2c66affSColin Finck
6590b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Seen: '%.*ws'\n", BasicInformation->NameLength/sizeof(WCHAR), BasicInformation->Name);
6600b695a6fSHermès Bélusca-Maïto
6612674e26cSHermès Bélusca-Maïto /* What bus are we going to go down? (only check if this is a root key) */
662c2c66affSColin Finck if (KeyIsRoot)
663c2c66affSColin Finck {
6642674e26cSHermès Bélusca-Maïto if (wcsncmp(BasicInformation->Name, L"MultifunctionAdapter", BasicInformation->NameLength / sizeof(WCHAR)) &&
6652674e26cSHermès Bélusca-Maïto wcsncmp(BasicInformation->Name, L"EisaAdapter", BasicInformation->NameLength / sizeof(WCHAR)) &&
6662674e26cSHermès Bélusca-Maïto wcsncmp(BasicInformation->Name, L"TcAdapter", BasicInformation->NameLength / sizeof(WCHAR)))
667c2c66affSColin Finck {
668c2c66affSColin Finck /* Nothing found, check next */
669c2c66affSColin Finck continue;
670c2c66affSColin Finck }
671c2c66affSColin Finck }
672c2c66affSColin Finck
6732674e26cSHermès Bélusca-Maïto /* Enumerate the bus */
674c2c66affSColin Finck BusString.Buffer = BasicInformation->Name;
675c2c66affSColin Finck BusString.Length = (USHORT)BasicInformation->NameLength;
676c2c66affSColin Finck BusString.MaximumLength = (USHORT)BasicInformation->NameLength;
677c2c66affSColin Finck
6782674e26cSHermès Bélusca-Maïto /* Open a handle to the root registry key */
6792674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
680c2c66affSColin Finck &BusString,
681c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
682c2c66affSColin Finck RootKeyHandle,
683c2c66affSColin Finck NULL);
684c2c66affSColin Finck
685c2c66affSColin Finck Status = ZwOpenKey(&SubRootKeyHandle, KEY_READ, &ObjectAttributes);
686c2c66affSColin Finck
6872674e26cSHermès Bélusca-Maïto /* Go on if we failed */
6882674e26cSHermès Bélusca-Maïto if (!NT_SUCCESS(Status))
6892674e26cSHermès Bélusca-Maïto continue;
690c2c66affSColin Finck
6912674e26cSHermès Bélusca-Maïto /* Key opened, create the path */
692c2c66affSColin Finck SubRootRegName = RootKey;
693c2c66affSColin Finck RtlAppendUnicodeToString(&SubRootRegName, L"\\");
694c2c66affSColin Finck RtlAppendUnicodeStringToString(&SubRootRegName, &BusString);
695c2c66affSColin Finck
6960b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" SubRootRegName: '%wZ'\n", &SubRootRegName);
6970b695a6fSHermès Bélusca-Maïto
698c2c66affSColin Finck if (!KeyIsRoot)
699c2c66affSColin Finck {
7002674e26cSHermès Bélusca-Maïto /* Parsing a sub-bus key */
7012674e26cSHermès Bélusca-Maïto ULONG SubBusLoop;
7022674e26cSHermès Bélusca-Maïto for (SubBusLoop = 0; SubBusLoop < RTL_NUMBER_OF(IoDeviceInfoNames); SubBusLoop++)
703c2c66affSColin Finck {
7042674e26cSHermès Bélusca-Maïto /* Identifier string first */
7052674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&SubBusString, IoDeviceInfoNames[SubBusLoop]);
706c2c66affSColin Finck
7070b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" Getting bus value: '%wZ'\n", &SubBusString);
7080b695a6fSHermès Bélusca-Maïto
7092674e26cSHermès Bélusca-Maïto /* Retrieve the necessary buffer space */
7102674e26cSHermès Bélusca-Maïto ZwQueryValueKey(SubRootKeyHandle,
7112674e26cSHermès Bélusca-Maïto &SubBusString,
7122674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
7132674e26cSHermès Bélusca-Maïto NULL, 0,
7142674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
715c2c66affSColin Finck
716c2c66affSColin Finck /* Allocate it */
717c2c66affSColin Finck BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
718*84b4a80bSHermès Bélusca-Maïto if (!BusInformation[SubBusLoop])
719*84b4a80bSHermès Bélusca-Maïto {
720*84b4a80bSHermès Bélusca-Maïto Status = STATUS_INSUFFICIENT_RESOURCES;
721*84b4a80bSHermès Bélusca-Maïto break;
722*84b4a80bSHermès Bélusca-Maïto }
723c2c66affSColin Finck
7242674e26cSHermès Bélusca-Maïto /* Get the information */
7252674e26cSHermès Bélusca-Maïto Status = ZwQueryValueKey(SubRootKeyHandle,
7262674e26cSHermès Bélusca-Maïto &SubBusString,
7272674e26cSHermès Bélusca-Maïto KeyValueFullInformation,
7282674e26cSHermès Bélusca-Maïto BusInformation[SubBusLoop],
7292674e26cSHermès Bélusca-Maïto LenKeyFullInformation,
7302674e26cSHermès Bélusca-Maïto &LenKeyFullInformation);
731c2c66affSColin Finck }
732c2c66affSColin Finck
733c2c66affSColin Finck if (NT_SUCCESS(Status))
734c2c66affSColin Finck {
7352674e26cSHermès Bélusca-Maïto PKEY_VALUE_FULL_INFORMATION BusConfigData =
7362674e26cSHermès Bélusca-Maïto BusInformation[IoQueryDeviceConfigurationData];
7372674e26cSHermès Bélusca-Maïto
7382674e26cSHermès Bélusca-Maïto /* Do we have something? */
7392674e26cSHermès Bélusca-Maïto if (BusConfigData != NULL &&
7402674e26cSHermès Bélusca-Maïto BusConfigData->DataLength != 0 &&
741c2c66affSColin Finck /* Does it match what we want? */
7422674e26cSHermès Bélusca-Maïto (((PCM_FULL_RESOURCE_DESCRIPTOR)((ULONG_PTR)BusConfigData +
7432674e26cSHermès Bélusca-Maïto BusConfigData->DataOffset))->InterfaceType == *(Query->BusType)))
744c2c66affSColin Finck {
745c2c66affSColin Finck /* Found a bus */
746c2c66affSColin Finck (*Bus)++;
747c2c66affSColin Finck
7482674e26cSHermès Bélusca-Maïto /* Is it the bus we wanted? */
749c2c66affSColin Finck if (Query->BusNumber == NULL || *(Query->BusNumber) == *Bus)
750c2c66affSColin Finck {
751c2c66affSColin Finck if (Query->ControllerType == NULL)
752c2c66affSColin Finck {
7530b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" --> Bus #%lu Callout: '%wZ'\n", *Bus, &SubRootRegName);
7540b695a6fSHermès Bélusca-Maïto
7552674e26cSHermès Bélusca-Maïto /* We don't want controller information: call the callback */
7562674e26cSHermès Bélusca-Maïto Status = Query->CalloutRoutine(Query->Context,
757c2c66affSColin Finck &SubRootRegName,
758c2c66affSColin Finck *(Query->BusType),
759c2c66affSColin Finck *Bus,
760c2c66affSColin Finck BusInformation,
761c2c66affSColin Finck 0,
762c2c66affSColin Finck 0,
763c2c66affSColin Finck NULL,
764c2c66affSColin Finck 0,
765c2c66affSColin Finck 0,
766c2c66affSColin Finck NULL);
7672674e26cSHermès Bélusca-Maïto }
7682674e26cSHermès Bélusca-Maïto else
7692674e26cSHermès Bélusca-Maïto {
7700b695a6fSHermès Bélusca-Maïto IORSRCTRACE(" --> Getting device on Bus #%lu : '%wZ'\n", *Bus, &SubRootRegName);
7710b695a6fSHermès Bélusca-Maïto
7722674e26cSHermès Bélusca-Maïto /* We want controller information: get it */
7732674e26cSHermès Bélusca-Maïto Status = IopQueryDeviceDescription(Query,
7742674e26cSHermès Bélusca-Maïto SubRootRegName,
7752674e26cSHermès Bélusca-Maïto RootKeyHandle,
7762674e26cSHermès Bélusca-Maïto *Bus,
7772674e26cSHermès Bélusca-Maïto (PKEY_VALUE_FULL_INFORMATION*)BusInformation);
778c2c66affSColin Finck }
779c2c66affSColin Finck }
780c2c66affSColin Finck }
781c2c66affSColin Finck }
782c2c66affSColin Finck
783c2c66affSColin Finck /* Free the allocated memory */
7842674e26cSHermès Bélusca-Maïto for (SubBusLoop = 0; SubBusLoop < RTL_NUMBER_OF(IoDeviceInfoNames); SubBusLoop++)
785c2c66affSColin Finck {
786c2c66affSColin Finck if (BusInformation[SubBusLoop])
787c2c66affSColin Finck {
788c2c66affSColin Finck ExFreePoolWithTag(BusInformation[SubBusLoop], TAG_IO_RESOURCE);
789c2c66affSColin Finck BusInformation[SubBusLoop] = NULL;
790c2c66affSColin Finck }
791c2c66affSColin Finck }
792c2c66affSColin Finck
7932674e26cSHermès Bélusca-Maïto /* Exit the loop if we found the bus */
7942674e26cSHermès Bélusca-Maïto if (Query->BusNumber && (*(Query->BusNumber) == *Bus))
795c2c66affSColin Finck {
796c2c66affSColin Finck ZwClose(SubRootKeyHandle);
797c2c66affSColin Finck SubRootKeyHandle = NULL;
798c2c66affSColin Finck continue;
799c2c66affSColin Finck }
800c2c66affSColin Finck }
801c2c66affSColin Finck
802c2c66affSColin Finck /* Enumerate the buses below us recursively if we haven't found the bus yet */
803c2c66affSColin Finck Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot);
804c2c66affSColin Finck
805c2c66affSColin Finck /* Everything enumerated */
806*84b4a80bSHermès Bélusca-Maïto if (Status == STATUS_NO_MORE_ENTRIES)
807*84b4a80bSHermès Bélusca-Maïto Status = STATUS_SUCCESS;
808c2c66affSColin Finck
809c2c66affSColin Finck ZwClose(SubRootKeyHandle);
810c2c66affSColin Finck SubRootKeyHandle = NULL;
811c2c66affSColin Finck }
812c2c66affSColin Finck
8132674e26cSHermès Bélusca-Maïto /* Free the last remaining allocated memory */
814c2c66affSColin Finck if (BasicInformation)
815c2c66affSColin Finck ExFreePoolWithTag(BasicInformation, TAG_IO_RESOURCE);
816c2c66affSColin Finck
817c2c66affSColin Finck return Status;
818c2c66affSColin Finck }
819c2c66affSColin Finck
820c2c66affSColin Finck NTSTATUS
IopFetchConfigurationInformation(_Out_ PWSTR * SymbolicLinkList,_In_ GUID Guid,_In_ ULONG ExpectedInterfaces,_Out_ PULONG Interfaces)8212674e26cSHermès Bélusca-Maïto IopFetchConfigurationInformation(
8222674e26cSHermès Bélusca-Maïto _Out_ PWSTR* SymbolicLinkList,
8232674e26cSHermès Bélusca-Maïto _In_ GUID Guid,
8242674e26cSHermès Bélusca-Maïto _In_ ULONG ExpectedInterfaces,
8252674e26cSHermès Bélusca-Maïto _Out_ PULONG Interfaces)
826c2c66affSColin Finck {
827c2c66affSColin Finck NTSTATUS Status;
8282674e26cSHermès Bélusca-Maïto ULONG interfaces = 0;
8292674e26cSHermès Bélusca-Maïto PWSTR symbolicLinkList;
830c2c66affSColin Finck
831c2c66affSColin Finck /* Get the associated enabled interfaces with the given GUID */
832c2c66affSColin Finck Status = IoGetDeviceInterfaces(&Guid, NULL, 0, SymbolicLinkList);
833c2c66affSColin Finck if (!NT_SUCCESS(Status))
834c2c66affSColin Finck {
835c2c66affSColin Finck /* Zero output and leave */
8362674e26cSHermès Bélusca-Maïto if (SymbolicLinkList)
8372674e26cSHermès Bélusca-Maïto *SymbolicLinkList = NULL;
838c2c66affSColin Finck
839c2c66affSColin Finck return STATUS_UNSUCCESSFUL;
840c2c66affSColin Finck }
841c2c66affSColin Finck
8422674e26cSHermès Bélusca-Maïto symbolicLinkList = *SymbolicLinkList;
843c2c66affSColin Finck
844c2c66affSColin Finck /* Count the number of enabled interfaces by counting the number of symbolic links */
8452674e26cSHermès Bélusca-Maïto while (*symbolicLinkList != UNICODE_NULL)
846c2c66affSColin Finck {
8472674e26cSHermès Bélusca-Maïto interfaces++;
8482674e26cSHermès Bélusca-Maïto symbolicLinkList += (wcslen(symbolicLinkList) + 1);
849c2c66affSColin Finck }
850c2c66affSColin Finck
851c2c66affSColin Finck /* Matching result will define the result */
8522674e26cSHermès Bélusca-Maïto Status = (interfaces >= ExpectedInterfaces) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
853c2c66affSColin Finck /* Finally, give back to the caller the number of found interfaces */
8542674e26cSHermès Bélusca-Maïto *Interfaces = interfaces;
855c2c66affSColin Finck
856c2c66affSColin Finck return Status;
857c2c66affSColin Finck }
858c2c66affSColin Finck
859c2c66affSColin Finck VOID
IopStoreSystemPartitionInformation(_In_ PUNICODE_STRING NtSystemPartitionDeviceName,_In_ PUNICODE_STRING OsLoaderPathName)8602674e26cSHermès Bélusca-Maïto IopStoreSystemPartitionInformation(
8612674e26cSHermès Bélusca-Maïto _In_ PUNICODE_STRING NtSystemPartitionDeviceName,
8622674e26cSHermès Bélusca-Maïto _In_ PUNICODE_STRING OsLoaderPathName)
863c2c66affSColin Finck {
864c2c66affSColin Finck NTSTATUS Status;
865c2c66affSColin Finck UNICODE_STRING LinkTarget, KeyName;
866c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
867c2c66affSColin Finck HANDLE LinkHandle, RegistryHandle, KeyHandle;
868c2c66affSColin Finck WCHAR LinkTargetBuffer[256];
869c2c66affSColin Finck UNICODE_STRING CmRegistryMachineSystemName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM");
870c2c66affSColin Finck
871c2c66affSColin Finck ASSERT(NtSystemPartitionDeviceName->MaximumLength >= NtSystemPartitionDeviceName->Length + sizeof(WCHAR));
872c2c66affSColin Finck ASSERT(NtSystemPartitionDeviceName->Buffer[NtSystemPartitionDeviceName->Length / sizeof(WCHAR)] == UNICODE_NULL);
873c2c66affSColin Finck ASSERT(OsLoaderPathName->MaximumLength >= OsLoaderPathName->Length + sizeof(WCHAR));
874c2c66affSColin Finck ASSERT(OsLoaderPathName->Buffer[OsLoaderPathName->Length / sizeof(WCHAR)] == UNICODE_NULL);
875c2c66affSColin Finck
876c2c66affSColin Finck /* First define needed stuff to open NtSystemPartitionDeviceName symbolic link */
877c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
878c2c66affSColin Finck NtSystemPartitionDeviceName,
879c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
880c2c66affSColin Finck NULL,
881c2c66affSColin Finck NULL);
882c2c66affSColin Finck
883c2c66affSColin Finck /* Open NtSystemPartitionDeviceName symbolic link */
884c2c66affSColin Finck Status = ZwOpenSymbolicLinkObject(&LinkHandle,
885c2c66affSColin Finck SYMBOLIC_LINK_QUERY,
886c2c66affSColin Finck &ObjectAttributes);
887c2c66affSColin Finck if (!NT_SUCCESS(Status))
888c2c66affSColin Finck {
889c2c66affSColin Finck DPRINT("Failed to open symlink %wZ, Status=%lx\n", NtSystemPartitionDeviceName, Status);
890c2c66affSColin Finck return;
891c2c66affSColin Finck }
892c2c66affSColin Finck
893*84b4a80bSHermès Bélusca-Maïto /* Prepare the string that will receive where symbolic link points to.
894*84b4a80bSHermès Bélusca-Maïto * We will zero the end of the string after having received it */
895*84b4a80bSHermès Bélusca-Maïto RtlInitEmptyUnicodeString(&LinkTarget, LinkTargetBuffer,
896*84b4a80bSHermès Bélusca-Maïto sizeof(LinkTargetBuffer) - sizeof(UNICODE_NULL));
897c2c66affSColin Finck
898c2c66affSColin Finck /* Query target */
8992674e26cSHermès Bélusca-Maïto Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL);
900c2c66affSColin Finck
901c2c66affSColin Finck /* We are done with symbolic link */
902c2c66affSColin Finck ObCloseHandle(LinkHandle, KernelMode);
903c2c66affSColin Finck
904c2c66affSColin Finck if (!NT_SUCCESS(Status))
905c2c66affSColin Finck {
906c2c66affSColin Finck DPRINT("Failed querying symlink %wZ, Status=%lx\n", NtSystemPartitionDeviceName, Status);
907c2c66affSColin Finck return;
908c2c66affSColin Finck }
909c2c66affSColin Finck
910c2c66affSColin Finck /* As promised, we zero the end */
911c2c66affSColin Finck LinkTarget.Buffer[LinkTarget.Length / sizeof(WCHAR)] = UNICODE_NULL;
912c2c66affSColin Finck
913c2c66affSColin Finck /* Open registry to save data (HKLM\SYSTEM) */
914c2c66affSColin Finck Status = IopOpenRegistryKeyEx(&RegistryHandle,
915c2c66affSColin Finck NULL,
916c2c66affSColin Finck &CmRegistryMachineSystemName,
917c2c66affSColin Finck KEY_ALL_ACCESS);
918c2c66affSColin Finck if (!NT_SUCCESS(Status))
919c2c66affSColin Finck {
920c2c66affSColin Finck DPRINT("Failed to open HKLM\\SYSTEM, Status=%lx\n", Status);
921c2c66affSColin Finck return;
922c2c66affSColin Finck }
923c2c66affSColin Finck
924c2c66affSColin Finck /* Open or create the Setup subkey where we'll store in */
925c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"Setup");
926c2c66affSColin Finck
927c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&KeyHandle,
928c2c66affSColin Finck RegistryHandle,
929c2c66affSColin Finck &KeyName,
930c2c66affSColin Finck KEY_ALL_ACCESS,
931c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
932c2c66affSColin Finck NULL);
933c2c66affSColin Finck
934c2c66affSColin Finck /* We're done with HKLM\SYSTEM */
935c2c66affSColin Finck ObCloseHandle(RegistryHandle, KernelMode);
936c2c66affSColin Finck
937c2c66affSColin Finck if (!NT_SUCCESS(Status))
938c2c66affSColin Finck {
939c2c66affSColin Finck DPRINT("Failed opening/creating Setup key, Status=%lx\n", Status);
940c2c66affSColin Finck return;
941c2c66affSColin Finck }
942c2c66affSColin Finck
9432674e26cSHermès Bélusca-Maïto /* Prepare first data writing */
944c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"SystemPartition");
945c2c66affSColin Finck
946c2c66affSColin Finck /* Write SystemPartition value which is the target of the symbolic link */
947c2c66affSColin Finck Status = ZwSetValueKey(KeyHandle,
948c2c66affSColin Finck &KeyName,
949c2c66affSColin Finck 0,
950c2c66affSColin Finck REG_SZ,
951c2c66affSColin Finck LinkTarget.Buffer,
952c2c66affSColin Finck LinkTarget.Length + sizeof(WCHAR));
953c2c66affSColin Finck if (!NT_SUCCESS(Status))
954c2c66affSColin Finck {
955c2c66affSColin Finck DPRINT("Failed writing SystemPartition value, Status=%lx\n", Status);
956c2c66affSColin Finck }
957c2c66affSColin Finck
9582674e26cSHermès Bélusca-Maïto /* Prepare for second data writing */
959c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"OsLoaderPath");
960c2c66affSColin Finck
961c2c66affSColin Finck /* Remove trailing slash if any (one slash only excepted) */
962c2c66affSColin Finck if (OsLoaderPathName->Length > sizeof(WCHAR) &&
963c2c66affSColin Finck OsLoaderPathName->Buffer[(OsLoaderPathName->Length / sizeof(WCHAR)) - 1] == OBJ_NAME_PATH_SEPARATOR)
964c2c66affSColin Finck {
965c2c66affSColin Finck OsLoaderPathName->Length -= sizeof(WCHAR);
966c2c66affSColin Finck OsLoaderPathName->Buffer[OsLoaderPathName->Length / sizeof(WCHAR)] = UNICODE_NULL;
967c2c66affSColin Finck }
968c2c66affSColin Finck
969c2c66affSColin Finck /* Then, write down data */
970c2c66affSColin Finck Status = ZwSetValueKey(KeyHandle,
971c2c66affSColin Finck &KeyName,
972c2c66affSColin Finck 0,
973c2c66affSColin Finck REG_SZ,
974c2c66affSColin Finck OsLoaderPathName->Buffer,
975c2c66affSColin Finck OsLoaderPathName->Length + sizeof(UNICODE_NULL));
976c2c66affSColin Finck if (!NT_SUCCESS(Status))
977c2c66affSColin Finck {
978c2c66affSColin Finck DPRINT("Failed writing OsLoaderPath value, Status=%lx\n", Status);
979c2c66affSColin Finck }
980c2c66affSColin Finck
981c2c66affSColin Finck /* We're finally done! */
982c2c66affSColin Finck ObCloseHandle(KeyHandle, KernelMode);
983c2c66affSColin Finck }
984c2c66affSColin Finck
985c2c66affSColin Finck /* PUBLIC FUNCTIONS ***********************************************************/
986c2c66affSColin Finck
9872674e26cSHermès Bélusca-Maïto /**
9882674e26cSHermès Bélusca-Maïto * @brief
9892674e26cSHermès Bélusca-Maïto * Returns a pointer to the I/O manager's global configuration
9902674e26cSHermès Bélusca-Maïto * information structure.
9912674e26cSHermès Bélusca-Maïto *
9922674e26cSHermès Bélusca-Maïto * This structure contains the current values for how many physical storage
9932674e26cSHermès Bélusca-Maïto * media, SCSI HBA, serial, and parallel devices have device objects created
9942674e26cSHermès Bélusca-Maïto * to represent them by drivers as they are loaded.
9952674e26cSHermès Bélusca-Maïto **/
9962674e26cSHermès Bélusca-Maïto PCONFIGURATION_INFORMATION
9972674e26cSHermès Bélusca-Maïto NTAPI
IoGetConfigurationInformation(VOID)998c2c66affSColin Finck IoGetConfigurationInformation(VOID)
999c2c66affSColin Finck {
10002674e26cSHermès Bélusca-Maïto return &_SystemConfigurationInformation;
1001c2c66affSColin Finck }
1002c2c66affSColin Finck
10032674e26cSHermès Bélusca-Maïto /**
1004c2c66affSColin Finck * @halfplemented
10052674e26cSHermès Bélusca-Maïto *
10062674e26cSHermès Bélusca-Maïto * @brief
10072674e26cSHermès Bélusca-Maïto * Reports hardware resources in the \Registry\Machine\Hardware\ResourceMap
10082674e26cSHermès Bélusca-Maïto * tree, so that a subsequently loaded driver cannot attempt to use the
10092674e26cSHermès Bélusca-Maïto * same resources.
10102674e26cSHermès Bélusca-Maïto *
10112674e26cSHermès Bélusca-Maïto * @param[in] DriverClassName
10122674e26cSHermès Bélusca-Maïto * The driver class under which the resource information should be stored.
10132674e26cSHermès Bélusca-Maïto *
10142674e26cSHermès Bélusca-Maïto * @param[in] DriverObject
10152674e26cSHermès Bélusca-Maïto * The driver object that was provided to the DriverEntry routine.
10162674e26cSHermès Bélusca-Maïto *
10172674e26cSHermès Bélusca-Maïto * @param[in] DriverList
10182674e26cSHermès Bélusca-Maïto * Resources claimed for the all the driver's devices, rather than per-device.
10192674e26cSHermès Bélusca-Maïto *
10202674e26cSHermès Bélusca-Maïto * @param[in] DriverListSize
10212674e26cSHermès Bélusca-Maïto * Size in bytes of the DriverList.
10222674e26cSHermès Bélusca-Maïto *
10232674e26cSHermès Bélusca-Maïto * @param[in] DeviceObject
10242674e26cSHermès Bélusca-Maïto * The device object for which resources should be claimed.
10252674e26cSHermès Bélusca-Maïto *
10262674e26cSHermès Bélusca-Maïto * @param[in] DeviceList
10272674e26cSHermès Bélusca-Maïto * List of resources that should be claimed for the device.
10282674e26cSHermès Bélusca-Maïto *
10292674e26cSHermès Bélusca-Maïto * @param[in] DeviceListSize
10302674e26cSHermès Bélusca-Maïto * Size of the per-device resource list in bytes.
10312674e26cSHermès Bélusca-Maïto *
10322674e26cSHermès Bélusca-Maïto * @param[in] OverrideConflict
10332674e26cSHermès Bélusca-Maïto * TRUE if the resources should be claimed even if a conflict is found.
10342674e26cSHermès Bélusca-Maïto *
10352674e26cSHermès Bélusca-Maïto * @param[out] ConflictDetected
10362674e26cSHermès Bélusca-Maïto * Points to a variable that receives TRUE if a conflict is detected
10372674e26cSHermès Bélusca-Maïto * with another driver.
10382674e26cSHermès Bélusca-Maïto **/
10392674e26cSHermès Bélusca-Maïto NTSTATUS
10402674e26cSHermès Bélusca-Maïto NTAPI
IoReportResourceUsage(_In_opt_ PUNICODE_STRING DriverClassName,_In_ PDRIVER_OBJECT DriverObject,_In_reads_bytes_opt_ (DriverListSize)PCM_RESOURCE_LIST DriverList,_In_opt_ ULONG DriverListSize,_In_opt_ PDEVICE_OBJECT DeviceObject,_In_reads_bytes_opt_ (DeviceListSize)PCM_RESOURCE_LIST DeviceList,_In_opt_ ULONG DeviceListSize,_In_ BOOLEAN OverrideConflict,_Out_ PBOOLEAN ConflictDetected)10412674e26cSHermès Bélusca-Maïto IoReportResourceUsage(
10422674e26cSHermès Bélusca-Maïto _In_opt_ PUNICODE_STRING DriverClassName,
10432674e26cSHermès Bélusca-Maïto _In_ PDRIVER_OBJECT DriverObject,
10442674e26cSHermès Bélusca-Maïto _In_reads_bytes_opt_(DriverListSize) PCM_RESOURCE_LIST DriverList,
10452674e26cSHermès Bélusca-Maïto _In_opt_ ULONG DriverListSize,
10462674e26cSHermès Bélusca-Maïto _In_opt_ PDEVICE_OBJECT DeviceObject,
10472674e26cSHermès Bélusca-Maïto _In_reads_bytes_opt_(DeviceListSize) PCM_RESOURCE_LIST DeviceList,
10482674e26cSHermès Bélusca-Maïto _In_opt_ ULONG DeviceListSize,
10492674e26cSHermès Bélusca-Maïto _In_ BOOLEAN OverrideConflict,
10502674e26cSHermès Bélusca-Maïto _Out_ PBOOLEAN ConflictDetected)
1051c2c66affSColin Finck {
1052c2c66affSColin Finck NTSTATUS Status;
1053c2c66affSColin Finck PCM_RESOURCE_LIST ResourceList;
1054c2c66affSColin Finck
1055c2c66affSColin Finck DPRINT1("IoReportResourceUsage is halfplemented!\n");
1056c2c66affSColin Finck
1057c2c66affSColin Finck if (!DriverList && !DeviceList)
1058c2c66affSColin Finck return STATUS_INVALID_PARAMETER;
1059c2c66affSColin Finck
1060c2c66affSColin Finck if (DeviceList)
1061c2c66affSColin Finck ResourceList = DeviceList;
1062c2c66affSColin Finck else
1063c2c66affSColin Finck ResourceList = DriverList;
1064c2c66affSColin Finck
1065c2c66affSColin Finck Status = IopDetectResourceConflict(ResourceList, FALSE, NULL);
1066c2c66affSColin Finck if (Status == STATUS_CONFLICTING_ADDRESSES)
1067c2c66affSColin Finck {
1068c2c66affSColin Finck *ConflictDetected = TRUE;
1069c2c66affSColin Finck
1070c2c66affSColin Finck if (!OverrideConflict)
1071c2c66affSColin Finck {
1072c2c66affSColin Finck DPRINT1("Denying an attempt to claim resources currently in use by another device!\n");
1073c2c66affSColin Finck return STATUS_CONFLICTING_ADDRESSES;
1074c2c66affSColin Finck }
1075c2c66affSColin Finck else
1076c2c66affSColin Finck {
1077c2c66affSColin Finck DPRINT1("Proceeding with conflicting resources\n");
1078c2c66affSColin Finck }
1079c2c66affSColin Finck }
1080c2c66affSColin Finck else if (!NT_SUCCESS(Status))
1081c2c66affSColin Finck {
1082c2c66affSColin Finck return Status;
1083c2c66affSColin Finck }
1084c2c66affSColin Finck
1085c2c66affSColin Finck /* TODO: Claim resources in registry */
1086c2c66affSColin Finck
1087c2c66affSColin Finck *ConflictDetected = FALSE;
1088c2c66affSColin Finck
1089c2c66affSColin Finck return STATUS_SUCCESS;
1090c2c66affSColin Finck }
1091c2c66affSColin Finck
10922674e26cSHermès Bélusca-Maïto static NTSTATUS
IopLegacyResourceAllocation(_In_ ARBITER_REQUEST_SOURCE AllocationType,_In_ PDRIVER_OBJECT DriverObject,_In_opt_ PDEVICE_OBJECT DeviceObject,_In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements,_Inout_ PCM_RESOURCE_LIST * AllocatedResources)10932674e26cSHermès Bélusca-Maïto IopLegacyResourceAllocation(
10942674e26cSHermès Bélusca-Maïto _In_ ARBITER_REQUEST_SOURCE AllocationType,
10952674e26cSHermès Bélusca-Maïto _In_ PDRIVER_OBJECT DriverObject,
10962674e26cSHermès Bélusca-Maïto _In_opt_ PDEVICE_OBJECT DeviceObject,
10972674e26cSHermès Bélusca-Maïto _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements,
10982674e26cSHermès Bélusca-Maïto _Inout_ PCM_RESOURCE_LIST* AllocatedResources)
1099c2c66affSColin Finck {
1100c2c66affSColin Finck NTSTATUS Status;
1101c2c66affSColin Finck
1102c2c66affSColin Finck DPRINT1("IopLegacyResourceAllocation is halfplemented!\n");
1103c2c66affSColin Finck
11049967d9aaSHervé Poussineau if (!ResourceRequirements)
11059967d9aaSHervé Poussineau {
11069967d9aaSHervé Poussineau /* We can get there by calling IoAssignResources() with RequestedResources = NULL.
11079967d9aaSHervé Poussineau * TODO: not sure what we should do, but we shouldn't crash.
11082674e26cSHermès Bélusca-Maïto */
11099967d9aaSHervé Poussineau UNIMPLEMENTED;
11109967d9aaSHervé Poussineau return STATUS_NOT_IMPLEMENTED;
11119967d9aaSHervé Poussineau }
11129967d9aaSHervé Poussineau
1113c2c66affSColin Finck Status = IopFixupResourceListWithRequirements(ResourceRequirements,
1114c2c66affSColin Finck AllocatedResources);
1115c2c66affSColin Finck if (!NT_SUCCESS(Status))
1116c2c66affSColin Finck {
1117c2c66affSColin Finck if (Status == STATUS_CONFLICTING_ADDRESSES)
1118c2c66affSColin Finck {
1119c2c66affSColin Finck DPRINT1("Denying an attempt to claim resources currently in use by another device!\n");
1120c2c66affSColin Finck }
1121c2c66affSColin Finck
1122c2c66affSColin Finck return Status;
1123c2c66affSColin Finck }
1124c2c66affSColin Finck
1125c2c66affSColin Finck /* TODO: Claim resources in registry */
1126c2c66affSColin Finck return STATUS_SUCCESS;
1127c2c66affSColin Finck }
1128c2c66affSColin Finck
1129c2c66affSColin Finck /*
1130c2c66affSColin Finck * @implemented
1131c2c66affSColin Finck */
1132c2c66affSColin Finck NTSTATUS
1133c2c66affSColin Finck NTAPI
IoAssignResources(_In_ PUNICODE_STRING RegistryPath,_In_opt_ PUNICODE_STRING DriverClassName,_In_ PDRIVER_OBJECT DriverObject,_In_opt_ PDEVICE_OBJECT DeviceObject,_In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,_Inout_ PCM_RESOURCE_LIST * AllocatedResources)11342674e26cSHermès Bélusca-Maïto IoAssignResources(
11352674e26cSHermès Bélusca-Maïto _In_ PUNICODE_STRING RegistryPath,
11362674e26cSHermès Bélusca-Maïto _In_opt_ PUNICODE_STRING DriverClassName,
11372674e26cSHermès Bélusca-Maïto _In_ PDRIVER_OBJECT DriverObject,
11382674e26cSHermès Bélusca-Maïto _In_opt_ PDEVICE_OBJECT DeviceObject,
11392674e26cSHermès Bélusca-Maïto _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
11402674e26cSHermès Bélusca-Maïto _Inout_ PCM_RESOURCE_LIST* AllocatedResources)
1141c2c66affSColin Finck {
1142c2c66affSColin Finck PDEVICE_NODE DeviceNode;
1143c2c66affSColin Finck
11442674e26cSHermès Bélusca-Maïto UNREFERENCED_PARAMETER(RegistryPath);
11452674e26cSHermès Bélusca-Maïto UNREFERENCED_PARAMETER(DriverClassName);
11462674e26cSHermès Bélusca-Maïto
1147c2c66affSColin Finck /* Do we have a DO? */
1148c2c66affSColin Finck if (DeviceObject)
1149c2c66affSColin Finck {
1150c2c66affSColin Finck /* Get its device node */
1151c2c66affSColin Finck DeviceNode = IopGetDeviceNode(DeviceObject);
11522674e26cSHermès Bélusca-Maïto if (DeviceNode && !(DeviceNode->Flags & DNF_LEGACY_RESOURCE_DEVICENODE))
1153c2c66affSColin Finck {
1154c2c66affSColin Finck /* New drivers should not call this API */
1155c2c66affSColin Finck KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
1156*84b4a80bSHermès Bélusca-Maïto 0x2,
1157c2c66affSColin Finck (ULONG_PTR)DeviceObject,
1158*84b4a80bSHermès Bélusca-Maïto (ULONG_PTR)DriverObject,
1159*84b4a80bSHermès Bélusca-Maïto 0);
1160c2c66affSColin Finck }
1161c2c66affSColin Finck }
1162c2c66affSColin Finck
1163c2c66affSColin Finck /* Did the driver supply resources? */
1164c2c66affSColin Finck if (RequestedResources)
1165c2c66affSColin Finck {
1166c2c66affSColin Finck /* Make sure there's actually something useful in them */
1167c2c66affSColin Finck if (!(RequestedResources->AlternativeLists) || !(RequestedResources->List[0].Count))
1168c2c66affSColin Finck {
1169c2c66affSColin Finck /* Empty resources are no resources */
1170c2c66affSColin Finck RequestedResources = NULL;
1171c2c66affSColin Finck }
1172c2c66affSColin Finck }
1173c2c66affSColin Finck
1174c2c66affSColin Finck /* Initialize output if given */
11752674e26cSHermès Bélusca-Maïto if (AllocatedResources)
11762674e26cSHermès Bélusca-Maïto *AllocatedResources = NULL;
1177c2c66affSColin Finck
1178c2c66affSColin Finck /* Call internal helper function */
1179c2c66affSColin Finck return IopLegacyResourceAllocation(ArbiterRequestLegacyAssigned,
1180c2c66affSColin Finck DriverObject,
1181c2c66affSColin Finck DeviceObject,
1182c2c66affSColin Finck RequestedResources,
1183c2c66affSColin Finck AllocatedResources);
1184c2c66affSColin Finck }
1185c2c66affSColin Finck
11862674e26cSHermès Bélusca-Maïto /**
11872674e26cSHermès Bélusca-Maïto * @brief
11882674e26cSHermès Bélusca-Maïto * Reads and returns Hardware information from the appropriate
11892674e26cSHermès Bélusca-Maïto * hardware registry key.
1190c2c66affSColin Finck *
11912674e26cSHermès Bélusca-Maïto * @param[in] BusType
11922674e26cSHermès Bélusca-Maïto * Specifies the bus type, for example: MCA, ISA, EISA, etc.
1193c2c66affSColin Finck *
11942674e26cSHermès Bélusca-Maïto * @param[in] BusNumber
11952674e26cSHermès Bélusca-Maïto * The number of the specified bus type to query.
1196c2c66affSColin Finck *
11972674e26cSHermès Bélusca-Maïto * @param[in] ControllerType
11982674e26cSHermès Bélusca-Maïto * Specifies the controller type
11992674e26cSHermès Bélusca-Maïto *
12002674e26cSHermès Bélusca-Maïto * @param[in] ControllerNumber
12012674e26cSHermès Bélusca-Maïto * The number of the specified controller type to query.
12022674e26cSHermès Bélusca-Maïto *
12032674e26cSHermès Bélusca-Maïto * @param[in] CalloutRoutine
12042674e26cSHermès Bélusca-Maïto * A user-provided callback function to call for each valid query.
12052674e26cSHermès Bélusca-Maïto *
12062674e26cSHermès Bélusca-Maïto * @param[in] Context
12072674e26cSHermès Bélusca-Maïto * A callback-specific context value.
12082674e26cSHermès Bélusca-Maïto *
12092674e26cSHermès Bélusca-Maïto * @return A status code.
12102674e26cSHermès Bélusca-Maïto **/
12112674e26cSHermès Bélusca-Maïto NTSTATUS
12122674e26cSHermès Bélusca-Maïto NTAPI
IoQueryDeviceDescription(_In_opt_ PINTERFACE_TYPE BusType,_In_opt_ PULONG BusNumber,_In_opt_ PCONFIGURATION_TYPE ControllerType,_In_opt_ PULONG ControllerNumber,_In_opt_ PCONFIGURATION_TYPE PeripheralType,_In_opt_ PULONG PeripheralNumber,_In_ PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,_In_opt_ PVOID Context)12132674e26cSHermès Bélusca-Maïto IoQueryDeviceDescription(
12142674e26cSHermès Bélusca-Maïto _In_opt_ PINTERFACE_TYPE BusType,
12152674e26cSHermès Bélusca-Maïto _In_opt_ PULONG BusNumber,
12162674e26cSHermès Bélusca-Maïto _In_opt_ PCONFIGURATION_TYPE ControllerType,
12172674e26cSHermès Bélusca-Maïto _In_opt_ PULONG ControllerNumber,
12182674e26cSHermès Bélusca-Maïto _In_opt_ PCONFIGURATION_TYPE PeripheralType,
12192674e26cSHermès Bélusca-Maïto _In_opt_ PULONG PeripheralNumber,
12202674e26cSHermès Bélusca-Maïto _In_ PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
12212674e26cSHermès Bélusca-Maïto _In_opt_ PVOID Context)
1222c2c66affSColin Finck {
1223c2c66affSColin Finck NTSTATUS Status;
1224c2c66affSColin Finck ULONG BusLoopNumber = -1; /* Root Bus */
1225c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
1226c2c66affSColin Finck UNICODE_STRING RootRegKey;
1227c2c66affSColin Finck HANDLE RootRegHandle;
1228c2c66affSColin Finck IO_QUERY Query;
1229c2c66affSColin Finck
12300b695a6fSHermès Bélusca-Maïto IORSRCTRACE("\nIoQueryDeviceDescription()\n"
12310b695a6fSHermès Bélusca-Maïto " BusType: 0x%p (%lu)\n"
12320b695a6fSHermès Bélusca-Maïto " BusNumber: 0x%p (%lu)\n"
12330b695a6fSHermès Bélusca-Maïto " ControllerType: 0x%p (%lu)\n"
12340b695a6fSHermès Bélusca-Maïto " ControllerNumber: 0x%p (%lu)\n"
12350b695a6fSHermès Bélusca-Maïto " PeripheralType: 0x%p (%lu)\n"
12360b695a6fSHermès Bélusca-Maïto " PeripheralNumber: 0x%p (%lu)\n"
12370b695a6fSHermès Bélusca-Maïto " CalloutRoutine: 0x%p\n"
12380b695a6fSHermès Bélusca-Maïto " Context: 0x%p\n"
12390b695a6fSHermès Bélusca-Maïto "--> Query: 0x%p\n",
12400b695a6fSHermès Bélusca-Maïto BusType, BusType ? *BusType : -1,
12410b695a6fSHermès Bélusca-Maïto BusNumber, BusNumber ? *BusNumber : -1,
12420b695a6fSHermès Bélusca-Maïto ControllerType, ControllerType ? *ControllerType : -1,
12430b695a6fSHermès Bélusca-Maïto ControllerNumber, ControllerNumber ? *ControllerNumber : -1,
12440b695a6fSHermès Bélusca-Maïto PeripheralType, PeripheralType ? *PeripheralType : -1,
12450b695a6fSHermès Bélusca-Maïto PeripheralNumber, PeripheralNumber ? *PeripheralNumber : -1,
12460b695a6fSHermès Bélusca-Maïto CalloutRoutine, Context,
12470b695a6fSHermès Bélusca-Maïto &Query);
12480b695a6fSHermès Bélusca-Maïto
1249*84b4a80bSHermès Bélusca-Maïto if (!BusType)
1250*84b4a80bSHermès Bélusca-Maïto return STATUS_NOT_IMPLEMENTED;
1251*84b4a80bSHermès Bélusca-Maïto
12522674e26cSHermès Bélusca-Maïto /* Set up the string */
1253c2c66affSColin Finck RootRegKey.Length = 0;
1254c2c66affSColin Finck RootRegKey.MaximumLength = 2048;
1255c2c66affSColin Finck RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
1256*84b4a80bSHermès Bélusca-Maïto if (!RootRegKey.Buffer)
1257*84b4a80bSHermès Bélusca-Maïto return STATUS_INSUFFICIENT_RESOURCES;
1258*84b4a80bSHermès Bélusca-Maïto
1259c2c66affSColin Finck RtlAppendUnicodeToString(&RootRegKey, L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
1260c2c66affSColin Finck
1261c2c66affSColin Finck /* Open a handle to the Root Registry Key */
12622674e26cSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes,
1263c2c66affSColin Finck &RootRegKey,
1264c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
1265c2c66affSColin Finck NULL,
1266c2c66affSColin Finck NULL);
1267c2c66affSColin Finck
1268c2c66affSColin Finck Status = ZwOpenKey(&RootRegHandle, KEY_READ, &ObjectAttributes);
1269c2c66affSColin Finck
1270c2c66affSColin Finck if (NT_SUCCESS(Status))
1271c2c66affSColin Finck {
12722674e26cSHermès Bélusca-Maïto /* Use a helper function to loop though this key and get the information */
1273c2c66affSColin Finck Query.BusType = BusType;
1274c2c66affSColin Finck Query.BusNumber = BusNumber;
1275c2c66affSColin Finck Query.ControllerType = ControllerType;
1276c2c66affSColin Finck Query.ControllerNumber = ControllerNumber;
1277c2c66affSColin Finck Query.PeripheralType = PeripheralType;
1278c2c66affSColin Finck Query.PeripheralNumber = PeripheralNumber;
1279c2c66affSColin Finck Query.CalloutRoutine = CalloutRoutine;
1280c2c66affSColin Finck Query.Context = Context;
12812674e26cSHermès Bélusca-Maïto Status = IopQueryBusDescription(&Query,
12822674e26cSHermès Bélusca-Maïto RootRegKey,
12832674e26cSHermès Bélusca-Maïto RootRegHandle,
12842674e26cSHermès Bélusca-Maïto &BusLoopNumber,
12852674e26cSHermès Bélusca-Maïto TRUE);
1286c2c66affSColin Finck
12872674e26cSHermès Bélusca-Maïto /* Close registry key */
1288c2c66affSColin Finck ZwClose(RootRegHandle);
1289c2c66affSColin Finck }
1290c2c66affSColin Finck
12912674e26cSHermès Bélusca-Maïto /* Cleanup */
1292c2c66affSColin Finck ExFreePoolWithTag(RootRegKey.Buffer, TAG_IO_RESOURCE);
1293c2c66affSColin Finck
1294c2c66affSColin Finck return Status;
1295c2c66affSColin Finck }
1296c2c66affSColin Finck
12972674e26cSHermès Bélusca-Maïto /**
12982674e26cSHermès Bélusca-Maïto * @brief
1299c2c66affSColin Finck * Reports hardware resources of the HAL in the
1300c2c66affSColin Finck * \Registry\Machine\Hardware\ResourceMap tree.
13012674e26cSHermès Bélusca-Maïto *
13022674e26cSHermès Bélusca-Maïto * @param[in] HalName
13032674e26cSHermès Bélusca-Maïto * Descriptive name of the HAL.
13042674e26cSHermès Bélusca-Maïto *
13052674e26cSHermès Bélusca-Maïto * @param[in] RawResourceList
13062674e26cSHermès Bélusca-Maïto * List of raw (bus specific) resources which should be claimed
13072674e26cSHermès Bélusca-Maïto * for the HAL.
13082674e26cSHermès Bélusca-Maïto *
13092674e26cSHermès Bélusca-Maïto * @param[in] TranslatedResourceList
13102674e26cSHermès Bélusca-Maïto * List of translated (system wide) resources which should be claimed
13112674e26cSHermès Bélusca-Maïto * for the HAL.
13122674e26cSHermès Bélusca-Maïto *
13132674e26cSHermès Bélusca-Maïto * @param[in] ResourceListSize
13142674e26cSHermès Bélusca-Maïto * Size in bytes of the raw and translated resource lists.
1315c2c66affSColin Finck * Both lists have the same size.
13162674e26cSHermès Bélusca-Maïto *
13172674e26cSHermès Bélusca-Maïto * @return A status code.
13182674e26cSHermès Bélusca-Maïto **/
13192674e26cSHermès Bélusca-Maïto NTSTATUS
13202674e26cSHermès Bélusca-Maïto NTAPI
IoReportHalResourceUsage(_In_ PUNICODE_STRING HalName,_In_ PCM_RESOURCE_LIST RawResourceList,_In_ PCM_RESOURCE_LIST TranslatedResourceList,_In_ ULONG ResourceListSize)13212674e26cSHermès Bélusca-Maïto IoReportHalResourceUsage(
13222674e26cSHermès Bélusca-Maïto _In_ PUNICODE_STRING HalName,
13232674e26cSHermès Bélusca-Maïto _In_ PCM_RESOURCE_LIST RawResourceList,
13242674e26cSHermès Bélusca-Maïto _In_ PCM_RESOURCE_LIST TranslatedResourceList,
13252674e26cSHermès Bélusca-Maïto _In_ ULONG ResourceListSize)
1326c2c66affSColin Finck {
13272674e26cSHermès Bélusca-Maïto NTSTATUS Status;
1328c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
1329c2c66affSColin Finck UNICODE_STRING Name;
1330c2c66affSColin Finck ULONG Disposition;
13312674e26cSHermès Bélusca-Maïto HANDLE ResourceMapKey;
1332c2c66affSColin Finck HANDLE HalKey;
1333c2c66affSColin Finck HANDLE DescriptionKey;
1334c2c66affSColin Finck
13352674e26cSHermès Bélusca-Maïto /* Open/Create 'RESOURCEMAP' key */
13362674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
1337c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
1338c2c66affSColin Finck &Name,
1339c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
1340c2c66affSColin Finck 0,
1341c2c66affSColin Finck NULL);
13422674e26cSHermès Bélusca-Maïto Status = ZwCreateKey(&ResourceMapKey,
1343c2c66affSColin Finck KEY_ALL_ACCESS,
1344c2c66affSColin Finck &ObjectAttributes,
1345c2c66affSColin Finck 0,
1346c2c66affSColin Finck NULL,
1347c2c66affSColin Finck REG_OPTION_VOLATILE,
1348c2c66affSColin Finck &Disposition);
1349c2c66affSColin Finck if (!NT_SUCCESS(Status))
13502674e26cSHermès Bélusca-Maïto return Status;
1351c2c66affSColin Finck
1352c2c66affSColin Finck /* Open/Create 'Hardware Abstraction Layer' key */
13532674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, L"Hardware Abstraction Layer");
1354c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
1355c2c66affSColin Finck &Name,
1356c2c66affSColin Finck OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
13572674e26cSHermès Bélusca-Maïto ResourceMapKey,
1358c2c66affSColin Finck NULL);
1359c2c66affSColin Finck Status = ZwCreateKey(&HalKey,
1360c2c66affSColin Finck KEY_ALL_ACCESS,
1361c2c66affSColin Finck &ObjectAttributes,
1362c2c66affSColin Finck 0,
1363c2c66affSColin Finck NULL,
1364c2c66affSColin Finck REG_OPTION_VOLATILE,
1365c2c66affSColin Finck &Disposition);
13662674e26cSHermès Bélusca-Maïto ZwClose(ResourceMapKey);
1367c2c66affSColin Finck if (!NT_SUCCESS(Status))
13682674e26cSHermès Bélusca-Maïto return Status;
1369c2c66affSColin Finck
13702674e26cSHermès Bélusca-Maïto /* Create 'HalName' key */
1371c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
13722674e26cSHermès Bélusca-Maïto HalName,
1373c2c66affSColin Finck OBJ_CASE_INSENSITIVE,
1374c2c66affSColin Finck HalKey,
1375c2c66affSColin Finck NULL);
1376c2c66affSColin Finck Status = ZwCreateKey(&DescriptionKey,
1377c2c66affSColin Finck KEY_ALL_ACCESS,
1378c2c66affSColin Finck &ObjectAttributes,
1379c2c66affSColin Finck 0,
1380c2c66affSColin Finck NULL,
1381c2c66affSColin Finck REG_OPTION_VOLATILE,
1382c2c66affSColin Finck &Disposition);
1383c2c66affSColin Finck ZwClose(HalKey);
1384c2c66affSColin Finck if (!NT_SUCCESS(Status))
13852674e26cSHermès Bélusca-Maïto return Status;
1386c2c66affSColin Finck
13872674e26cSHermès Bélusca-Maïto /* Add '.Raw' value */
13882674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, L".Raw");
1389c2c66affSColin Finck Status = ZwSetValueKey(DescriptionKey,
1390c2c66affSColin Finck &Name,
1391c2c66affSColin Finck 0,
1392c2c66affSColin Finck REG_RESOURCE_LIST,
13932674e26cSHermès Bélusca-Maïto RawResourceList,
13942674e26cSHermès Bélusca-Maïto ResourceListSize);
1395c2c66affSColin Finck if (!NT_SUCCESS(Status))
1396c2c66affSColin Finck {
1397c2c66affSColin Finck ZwClose(DescriptionKey);
13982674e26cSHermès Bélusca-Maïto return Status;
1399c2c66affSColin Finck }
1400c2c66affSColin Finck
14012674e26cSHermès Bélusca-Maïto /* Add '.Translated' value */
14022674e26cSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, L".Translated");
1403c2c66affSColin Finck Status = ZwSetValueKey(DescriptionKey,
1404c2c66affSColin Finck &Name,
1405c2c66affSColin Finck 0,
1406c2c66affSColin Finck REG_RESOURCE_LIST,
14072674e26cSHermès Bélusca-Maïto TranslatedResourceList,
14082674e26cSHermès Bélusca-Maïto ResourceListSize);
1409c2c66affSColin Finck ZwClose(DescriptionKey);
1410c2c66affSColin Finck
14112674e26cSHermès Bélusca-Maïto return Status;
1412c2c66affSColin Finck }
1413c2c66affSColin Finck
1414c2c66affSColin Finck /* EOF */
1415