📄 iorsrce.c
字号:
PULONG Bus,
BOOLEAN KeyIsRoot)
{
NTSTATUS Status;
ULONG BusLoop;
UNICODE_STRING SubRootRegName;
UNICODE_STRING BusString;
UNICODE_STRING SubBusString;
ULONG LenBasicInformation = 0;
ULONG LenFullInformation;
ULONG LenKeyFullInformation;
ULONG LenKey;
HANDLE SubRootKeyHandle;
PKEY_FULL_INFORMATION FullInformation;
PKEY_BASIC_INFORMATION BasicInformation = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
PKEY_VALUE_FULL_INFORMATION BusInformation[3] = {NULL, NULL, NULL};
/* How much buffer space */
Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation);
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW)
return Status;
/* Allocate it */
FullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);
if(!FullInformation)
return STATUS_NO_MEMORY;
/* Get the Information */
Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, FullInformation, LenFullInformation, &LenFullInformation);
/* Everything was fine */
if (NT_SUCCESS(Status))
{
/* Buffer needed for all the keys under this one */
LenBasicInformation = FullInformation->MaxNameLen + sizeof(KEY_BASIC_INFORMATION);
/* Allocate it */
BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE);
}
/* Deallocate the old Buffer */
ExFreePool(FullInformation);
/* Try to find a Bus */
for (BusLoop = 0; NT_SUCCESS(Status); BusLoop++)
{
/* Bus parameter was passed and number was matched */
if ((Query->BusNumber) && (*(Query->BusNumber)) == *Bus) break;
/* Enumerate the Key */
Status = ZwEnumerateKey(
RootKeyHandle,
BusLoop,
KeyBasicInformation,
BasicInformation,
LenBasicInformation,
&LenKey);
/* Everything enumerated */
if (!NT_SUCCESS(Status)) break;
/* What Bus are we going to go down? (only check if this is a Root Key) */
if (KeyIsRoot)
{
if (wcsncmp(BasicInformation->Name, L"MultifunctionAdapter", BasicInformation->NameLength / 2) &&
wcsncmp(BasicInformation->Name, L"EisaAdapter", BasicInformation->NameLength / 2) &&
wcsncmp(BasicInformation->Name, L"TcAdapter", BasicInformation->NameLength / 2))
{
/* Nothing found, check next */
continue;
}
}
/* Enumerate the Bus. */
BusString.Buffer = BasicInformation->Name;
BusString.Length = (USHORT)BasicInformation->NameLength;
BusString.MaximumLength = (USHORT)BasicInformation->NameLength;
/* Open a handle to the Root Registry Key */
InitializeObjectAttributes(
&ObjectAttributes,
&BusString,
OBJ_CASE_INSENSITIVE,
RootKeyHandle,
NULL);
Status = ZwOpenKey(&SubRootKeyHandle, KEY_READ, &ObjectAttributes);
/* Go on if we can't */
if (!NT_SUCCESS(Status)) continue;
/* Key opened. Create the path */
SubRootRegName = RootKey;
RtlAppendUnicodeToString(&SubRootRegName, L"\\");
RtlAppendUnicodeStringToString(&SubRootRegName, &BusString);
if (!KeyIsRoot)
{
/* Parsing a SubBus-key */
int SubBusLoop;
PWSTR Strings[3] = {
L"Identifier",
L"Configuration Data",
L"Component Information"};
for (SubBusLoop = 0; SubBusLoop < 3; SubBusLoop++)
{
/* Identifier String First */
RtlInitUnicodeString(&SubBusString, Strings[SubBusLoop]);
/* How much buffer space */
ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation);
/* Allocate it */
BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);
/* Get the Information */
Status = ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, BusInformation[SubBusLoop], LenKeyFullInformation, &LenKeyFullInformation);
}
if (NT_SUCCESS(Status))
{
/* Do we have something */
if (BusInformation[1] != NULL &&
BusInformation[1]->DataLength != 0 &&
/* Does it match what we want? */
(((PCM_FULL_RESOURCE_DESCRIPTOR)((ULONG_PTR)BusInformation[1] + BusInformation[1]->DataOffset))->InterfaceType == *(Query->BusType)))
{
/* Found a bus */
(*Bus)++;
/* Is it the bus we wanted */
if (Query->BusNumber == NULL || *(Query->BusNumber) == *Bus)
{
/* If we don't want Controller Information, we're done... call the callback */
if (Query->ControllerType == NULL)
{
Status = Query->CalloutRoutine(
Query->Context,
&SubRootRegName,
*(Query->BusType),
*Bus,
BusInformation,
0,
0,
NULL,
0,
0,
NULL);
} else {
/* We want Controller Info...get it */
Status = IopQueryDeviceDescription(Query, SubRootRegName, RootKeyHandle, *Bus, (PKEY_VALUE_FULL_INFORMATION*)BusInformation);
}
}
}
}
/* Free the allocated memory */
for (SubBusLoop = 0; SubBusLoop < 3; SubBusLoop++)
{
if (BusInformation[SubBusLoop])
{
ExFreePool(BusInformation[SubBusLoop]);
BusInformation[SubBusLoop] = NULL;
}
}
/* Exit the Loop if we found the bus */
if (Query->BusNumber != NULL && *(Query->BusNumber) == *Bus)
{
ZwClose(SubRootKeyHandle);
SubRootKeyHandle = NULL;
continue;
}
}
/* Enumerate the buses below us recursively if we haven't found the bus yet */
Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot);
/* Everything enumerated */
if (Status == STATUS_NO_MORE_ENTRIES) Status = STATUS_SUCCESS;
ZwClose(SubRootKeyHandle);
SubRootKeyHandle = NULL;
}
/* Free the last remaining Allocated Memory */
if (BasicInformation)
ExFreePool(BasicInformation);
return Status;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
PCONFIGURATION_INFORMATION STDCALL
IoGetConfigurationInformation(VOID)
{
return(&_SystemConfigurationInformation);
}
/*
* @unimplemented
*/
NTSTATUS STDCALL
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
PDRIVER_OBJECT DriverObject,
PCM_RESOURCE_LIST DriverList,
ULONG DriverListSize,
PDEVICE_OBJECT DeviceObject,
PCM_RESOURCE_LIST DeviceList,
ULONG DeviceListSize,
BOOLEAN OverrideConflict,
PBOOLEAN ConflictDetected)
/*
* FUNCTION: Reports hardware resources in the
* \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
* loaded driver cannot attempt to use the same resources.
* ARGUMENTS:
* DriverClassName - The class of driver under which the resource
* information should be stored.
* DriverObject - The driver object that was input to the
* DriverEntry.
* DriverList - Resources that claimed for the driver rather than
* per-device.
* DriverListSize - Size in bytes of the DriverList.
* DeviceObject - The device object for which resources should be
* claimed.
* DeviceList - List of resources which should be claimed for the
* device.
* DeviceListSize - Size of the per-device resource list in bytes.
* OverrideConflict - True if the resources should be cliamed
* even if a conflict is found.
* ConflictDetected - Points to a variable that receives TRUE if
* a conflict is detected with another driver.
*/
{
UNIMPLEMENTED;
*ConflictDetected = FALSE;
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/
NTSTATUS STDCALL
IoAssignResources(PUNICODE_STRING RegistryPath,
PUNICODE_STRING DriverClassName,
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT DeviceObject,
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
PCM_RESOURCE_LIST* AllocatedResources)
{
UNIMPLEMENTED;
return(STATUS_NOT_IMPLEMENTED);
}
/*
* FUNCTION:
* Reads and returns Hardware information from the appropriate hardware registry key.
*
* ARGUMENTS:
* BusType - MCA, ISA, EISA...specifies the Bus Type
* BusNumber - Which bus of above should be queried
* ControllerType - Specifices the Controller Type
* ControllerNumber - Which of the controllers to query.
* CalloutRoutine - Which function to call for each valid query.
* Context - Value to pass to the callback.
*
* RETURNS:
* Status
*
* STATUS:
* @implemented
*/
NTSTATUS NTAPI
IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL,
PULONG BusNumber OPTIONAL,
PCONFIGURATION_TYPE ControllerType OPTIONAL,
PULONG ControllerNumber OPTIONAL,
PCONFIGURATION_TYPE PeripheralType OPTIONAL,
PULONG PeripheralNumber OPTIONAL,
PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
PVOID Context)
{
NTSTATUS Status;
ULONG BusLoopNumber = -1; /* Root Bus */
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING RootRegKey;
HANDLE RootRegHandle;
WCHAR RootRegString[] = L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
IO_QUERY Query;
/* Set up the String */
RootRegKey.Length = 0;
RootRegKey.MaximumLength = 2048;
RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
RtlAppendUnicodeToString(&RootRegKey, RootRegString);
/* Open a handle to the Root Registry Key */
InitializeObjectAttributes(
&ObjectAttributes,
&RootRegKey,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&RootRegHandle, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Use a helper function to loop though this key and get the info */
Query.BusType = BusType;
Query.BusNumber = BusNumber;
Query.ControllerType = ControllerType;
Query.ControllerNumber = ControllerNumber;
Query.PeripheralType = PeripheralType;
Query.PeripheralNumber = PeripheralNumber;
Query.CalloutRoutine = CalloutRoutine;
Query.Context = Context;
Status = IopQueryBusDescription(&Query, RootRegKey, RootRegHandle, &BusLoopNumber, TRUE);
/* Close registry */
ZwClose(RootRegHandle);
}
/* Free Memory */
ExFreePool(RootRegKey.Buffer);
return Status;
}
/*
* @implemented
*/
NTSTATUS STDCALL
IoReportHalResourceUsage(PUNICODE_STRING HalDescription,
PCM_RESOURCE_LIST RawList,
PCM_RESOURCE_LIST TranslatedList,
ULONG ListSize)
/*
* FUNCTION:
* Reports hardware resources of the HAL in the
* \Registry\Machine\Hardware\ResourceMap tree.
* ARGUMENTS:
* HalDescription: Descriptive name of the HAL.
* RawList: List of raw (bus specific) resources which should be
* claimed for the HAL.
* TranslatedList: List of translated (system wide) resources which
* should be claimed for the HAL.
* ListSize: Size in bytes of the raw and translated resource lists.
* Both lists have the same size.
* RETURNS:
* Status.
*/
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
ULONG Disposition;
NTSTATUS Status;
HANDLE ResourcemapKey;
HANDLE HalKey;
HANDLE DescriptionKey;
/* Open/Create 'RESOURCEMAP' key. */
RtlInitUnicodeString(&Name,
L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
0,
NULL);
Status = ZwCreateKey(&ResourcemapKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
&Disposition);
if (!NT_SUCCESS(Status))
return(Status);
/* Open/Create 'Hardware Abstraction Layer' key */
RtlInitUnicodeString(&Name,
L"Hardware Abstraction Layer");
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
ResourcemapKey,
NULL);
Status = ZwCreateKey(&HalKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
&Disposition);
ZwClose(ResourcemapKey);
if (!NT_SUCCESS(Status))
return(Status);
/* Create 'HalDescription' key */
InitializeObjectAttributes(&ObjectAttributes,
HalDescription,
OBJ_CASE_INSENSITIVE,
HalKey,
NULL);
Status = ZwCreateKey(&DescriptionKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
&Disposition);
ZwClose(HalKey);
if (!NT_SUCCESS(Status))
return(Status);
/* Add '.Raw' value. */
RtlInitUnicodeString(&Name,
L".Raw");
Status = ZwSetValueKey(DescriptionKey,
&Name,
0,
REG_RESOURCE_LIST,
RawList,
ListSize);
if (!NT_SUCCESS(Status))
{
ZwClose(DescriptionKey);
return(Status);
}
/* Add '.Translated' value. */
RtlInitUnicodeString(&Name,
L".Translated");
Status = ZwSetValueKey(DescriptionKey,
&Name,
0,
REG_RESOURCE_LIST,
TranslatedList,
ListSize);
ZwClose(DescriptionKey);
return(Status);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -