mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Reapply fixed IoGetDeviceProperty() patch from 31467.
- Reformat the code. svn path=/trunk/; revision=31515
This commit is contained in:
parent
bd85b22ea9
commit
ad4f47ec96
1 changed files with 173 additions and 167 deletions
|
@ -312,31 +312,33 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
|
||||||
OUT PVOID PropertyBuffer,
|
OUT PVOID PropertyBuffer,
|
||||||
OUT PULONG ResultLength)
|
OUT PULONG ResultLength)
|
||||||
{
|
{
|
||||||
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
|
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
|
||||||
DEVICE_CAPABILITIES DeviceCaps;
|
DEVICE_CAPABILITIES DeviceCaps;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Data = NULL;
|
PVOID Data = NULL;
|
||||||
PWSTR Ptr;
|
PWSTR Ptr;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
|
DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
|
||||||
|
|
||||||
if (DeviceNode == NULL)
|
*ResultLength = 0;
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
switch (DeviceProperty)
|
if (DeviceNode == NULL)
|
||||||
{
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
case DevicePropertyBusNumber:
|
|
||||||
Length = sizeof(ULONG);
|
|
||||||
Data = &DeviceNode->ChildBusNumber;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Complete, untested */
|
switch (DeviceProperty)
|
||||||
case DevicePropertyBusTypeGuid:
|
{
|
||||||
/* Sanity check */
|
case DevicePropertyBusNumber:
|
||||||
if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
|
Length = sizeof(ULONG);
|
||||||
(DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
|
Data = &DeviceNode->ChildBusNumber;
|
||||||
{
|
break;
|
||||||
|
|
||||||
|
/* Complete, untested */
|
||||||
|
case DevicePropertyBusTypeGuid:
|
||||||
|
/* Sanity check */
|
||||||
|
if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
|
||||||
|
(DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
|
||||||
|
{
|
||||||
/* Return the GUID */
|
/* Return the GUID */
|
||||||
*ResultLength = sizeof(GUID);
|
*ResultLength = sizeof(GUID);
|
||||||
|
|
||||||
|
@ -348,44 +350,44 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
/* Copy the GUID */
|
/* Copy the GUID */
|
||||||
RtlCopyMemory(PropertyBuffer,
|
RtlCopyMemory(PropertyBuffer,
|
||||||
&(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
|
&(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
|
||||||
sizeof(GUID));
|
sizeof(GUID));
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DevicePropertyLegacyBusType:
|
case DevicePropertyLegacyBusType:
|
||||||
Length = sizeof(INTERFACE_TYPE);
|
Length = sizeof(INTERFACE_TYPE);
|
||||||
Data = &DeviceNode->ChildInterfaceType;
|
Data = &DeviceNode->ChildInterfaceType;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DevicePropertyAddress:
|
case DevicePropertyAddress:
|
||||||
/* Query the device caps */
|
/* Query the device caps */
|
||||||
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
|
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
|
||||||
if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
|
if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
|
||||||
{
|
{
|
||||||
/* Return length */
|
/* Return length */
|
||||||
*ResultLength = sizeof(ULONG);
|
*ResultLength = sizeof(ULONG);
|
||||||
|
|
||||||
/* Check if the buffer given was large enough */
|
/* Check if the buffer given was large enough */
|
||||||
if (BufferLength < *ResultLength)
|
if (BufferLength < *ResultLength)
|
||||||
{
|
{
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return address */
|
/* Return address */
|
||||||
*(PULONG)PropertyBuffer = DeviceCaps.Address;
|
*(PULONG)PropertyBuffer = DeviceCaps.Address;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case DevicePropertyUINumber:
|
// case DevicePropertyUINumber:
|
||||||
// if (DeviceNode->CapabilityFlags == NULL)
|
// if (DeviceNode->CapabilityFlags == NULL)
|
||||||
|
@ -394,161 +396,165 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
|
||||||
// Data = &DeviceNode->CapabilityFlags->UINumber;
|
// Data = &DeviceNode->CapabilityFlags->UINumber;
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
case DevicePropertyClassName:
|
case DevicePropertyClassName:
|
||||||
case DevicePropertyClassGuid:
|
case DevicePropertyClassGuid:
|
||||||
case DevicePropertyDriverKeyName:
|
case DevicePropertyDriverKeyName:
|
||||||
case DevicePropertyManufacturer:
|
case DevicePropertyManufacturer:
|
||||||
case DevicePropertyFriendlyName:
|
case DevicePropertyFriendlyName:
|
||||||
case DevicePropertyHardwareID:
|
case DevicePropertyHardwareID:
|
||||||
case DevicePropertyCompatibleIDs:
|
case DevicePropertyCompatibleIDs:
|
||||||
case DevicePropertyDeviceDescription:
|
case DevicePropertyDeviceDescription:
|
||||||
case DevicePropertyLocationInformation:
|
case DevicePropertyLocationInformation:
|
||||||
case DevicePropertyUINumber:
|
case DevicePropertyUINumber:
|
||||||
{
|
{
|
||||||
LPWSTR RegistryPropertyName, KeyNameBuffer;
|
LPCWSTR RegistryPropertyName;
|
||||||
UNICODE_STRING KeyName, ValueName;
|
UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
UNICODE_STRING ValueName;
|
||||||
KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
ULONG ValueInformationLength;
|
KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
|
||||||
HANDLE KeyHandle;
|
ULONG ValueInformationLength;
|
||||||
NTSTATUS Status;
|
HANDLE KeyHandle, EnumRootHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
switch (DeviceProperty)
|
switch (DeviceProperty)
|
||||||
{
|
{
|
||||||
case DevicePropertyClassName:
|
case DevicePropertyClassName:
|
||||||
RegistryPropertyName = L"Class"; break;
|
RegistryPropertyName = L"Class"; break;
|
||||||
case DevicePropertyClassGuid:
|
case DevicePropertyClassGuid:
|
||||||
RegistryPropertyName = L"ClassGuid"; break;
|
RegistryPropertyName = L"ClassGuid"; break;
|
||||||
case DevicePropertyDriverKeyName:
|
case DevicePropertyDriverKeyName:
|
||||||
RegistryPropertyName = L"Driver"; break;
|
RegistryPropertyName = L"Driver"; break;
|
||||||
case DevicePropertyManufacturer:
|
case DevicePropertyManufacturer:
|
||||||
RegistryPropertyName = L"Mfg"; break;
|
RegistryPropertyName = L"Mfg"; break;
|
||||||
case DevicePropertyFriendlyName:
|
case DevicePropertyFriendlyName:
|
||||||
RegistryPropertyName = L"FriendlyName"; break;
|
RegistryPropertyName = L"FriendlyName"; break;
|
||||||
case DevicePropertyHardwareID:
|
case DevicePropertyHardwareID:
|
||||||
RegistryPropertyName = L"HardwareID"; break;
|
RegistryPropertyName = L"HardwareID"; break;
|
||||||
case DevicePropertyCompatibleIDs:
|
case DevicePropertyCompatibleIDs:
|
||||||
RegistryPropertyName = L"CompatibleIDs"; break;
|
RegistryPropertyName = L"CompatibleIDs"; break;
|
||||||
case DevicePropertyDeviceDescription:
|
case DevicePropertyDeviceDescription:
|
||||||
RegistryPropertyName = L"DeviceDesc"; break;
|
RegistryPropertyName = L"DeviceDesc"; break;
|
||||||
case DevicePropertyLocationInformation:
|
case DevicePropertyLocationInformation:
|
||||||
RegistryPropertyName = L"LocationInformation"; break;
|
RegistryPropertyName = L"LocationInformation"; break;
|
||||||
case DevicePropertyUINumber:
|
case DevicePropertyUINumber:
|
||||||
RegistryPropertyName = L"UINumber"; break;
|
RegistryPropertyName = L"UINumber"; break;
|
||||||
default:
|
default:
|
||||||
RegistryPropertyName = NULL; break;
|
/* Should not happen */
|
||||||
}
|
ASSERT(FALSE);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
KeyNameBuffer = ExAllocatePool(PagedPool,
|
DPRINT("Registry property %S\n", RegistryPropertyName);
|
||||||
(49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
|
|
||||||
|
|
||||||
DPRINT("KeyNameBuffer: 0x%p, value %S\n", KeyNameBuffer, RegistryPropertyName);
|
/* Open Enum key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &EnumRoot,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&EnumRootHandle, 0, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (KeyNameBuffer == NULL)
|
/* Open instance key */
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
InitializeObjectAttributes(&ObjectAttributes, &DeviceNode->InstancePath,
|
||||||
|
OBJ_CASE_INSENSITIVE, EnumRootHandle, NULL);
|
||||||
|
|
||||||
wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
|
Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
|
||||||
wcscat(KeyNameBuffer, DeviceNode->InstancePath.Buffer);
|
if (!NT_SUCCESS(Status))
|
||||||
RtlInitUnicodeString(&KeyName, KeyNameBuffer);
|
{
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
|
DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status);
|
||||||
OBJ_CASE_INSENSITIVE, NULL, NULL);
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
|
/* Allocate buffer to read as much data as required by the caller */
|
||||||
ExFreePool(KeyNameBuffer);
|
ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
|
||||||
if (!NT_SUCCESS(Status))
|
Data[0]) + BufferLength;
|
||||||
return Status;
|
ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
|
||||||
|
if (!ValueInformation)
|
||||||
|
{
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&ValueName, RegistryPropertyName);
|
/* Read the value */
|
||||||
ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
|
RtlInitUnicodeString(&ValueName, RegistryPropertyName);
|
||||||
Data[0]) + BufferLength;
|
Status = ZwQueryValueKey(KeyHandle, &ValueName,
|
||||||
ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
|
KeyValuePartialInformation, ValueInformation,
|
||||||
if (ValueInformation == NULL)
|
ValueInformationLength,
|
||||||
{
|
&ValueInformationLength);
|
||||||
ZwClose(KeyHandle);
|
ZwClose(KeyHandle);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(KeyHandle, &ValueName,
|
/* Return data */
|
||||||
KeyValuePartialInformation, ValueInformation,
|
*ResultLength = ValueInformation->DataLength;
|
||||||
ValueInformationLength,
|
|
||||||
&ValueInformationLength);
|
|
||||||
*ResultLength = ValueInformation->DataLength;
|
|
||||||
ZwClose(KeyHandle);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Problem: Status=%0x08x, ResultLength = %d\n", Status, *ResultLength);
|
||||||
|
ExFreePool(ValueInformation);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
else
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Verify the value (NULL-terminated, correct format). */
|
||||||
|
RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
|
||||||
|
ValueInformation->DataLength);
|
||||||
ExFreePool(ValueInformation);
|
ExFreePool(ValueInformation);
|
||||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
else
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Verify the value (NULL-terminated, correct format). */
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
|
case DevicePropertyBootConfiguration:
|
||||||
ValueInformation->DataLength);
|
Length = 0;
|
||||||
ExFreePool(ValueInformation);
|
if (DeviceNode->BootResources->Count != 0)
|
||||||
|
{
|
||||||
|
Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
|
||||||
|
}
|
||||||
|
Data = &DeviceNode->BootResources;
|
||||||
|
break;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
/* FIXME: use a translated boot configuration instead */
|
||||||
}
|
case DevicePropertyBootConfigurationTranslated:
|
||||||
|
Length = 0;
|
||||||
|
if (DeviceNode->BootResources->Count != 0)
|
||||||
|
{
|
||||||
|
Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
|
||||||
|
}
|
||||||
|
Data = &DeviceNode->BootResources;
|
||||||
|
break;
|
||||||
|
|
||||||
case DevicePropertyBootConfiguration:
|
case DevicePropertyEnumeratorName:
|
||||||
Length = 0;
|
/* A buffer overflow can't happen here, since InstancePath
|
||||||
if (DeviceNode->BootResources->Count != 0)
|
* always contains the enumerator name followed by \\ */
|
||||||
{
|
Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
|
||||||
Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
|
ASSERT(Ptr);
|
||||||
}
|
Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
|
||||||
Data = &DeviceNode->BootResources;
|
Data = DeviceNode->InstancePath.Buffer;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* FIXME: use a translated boot configuration instead */
|
case DevicePropertyPhysicalDeviceObjectName:
|
||||||
case DevicePropertyBootConfigurationTranslated:
|
/* InstancePath buffer is NULL terminated, so we can do this */
|
||||||
Length = 0;
|
Length = DeviceNode->InstancePath.MaximumLength;
|
||||||
if (DeviceNode->BootResources->Count != 0)
|
Data = DeviceNode->InstancePath.Buffer;
|
||||||
{
|
break;
|
||||||
Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
|
|
||||||
}
|
|
||||||
Data = &DeviceNode->BootResources;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DevicePropertyEnumeratorName:
|
default:
|
||||||
Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
|
return STATUS_INVALID_PARAMETER_2;
|
||||||
if (Ptr != NULL)
|
}
|
||||||
{
|
|
||||||
Length = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)DeviceNode->InstancePath.Buffer) + sizeof(WCHAR);
|
|
||||||
Data = DeviceNode->InstancePath.Buffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Length = 0;
|
|
||||||
Data = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DevicePropertyPhysicalDeviceObjectName:
|
/* Prepare returned values */
|
||||||
Length = DeviceNode->InstancePath.Length + sizeof(WCHAR);
|
*ResultLength = Length;
|
||||||
Data = DeviceNode->InstancePath.Buffer;
|
if (BufferLength < Length)
|
||||||
break;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
RtlCopyMemory(PropertyBuffer, Data, Length);
|
||||||
|
|
||||||
default:
|
/* NULL terminate the string (if required) */
|
||||||
return STATUS_INVALID_PARAMETER_2;
|
if (DeviceProperty == DevicePropertyEnumeratorName)
|
||||||
}
|
((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
*ResultLength = Length;
|
return STATUS_SUCCESS;
|
||||||
if (BufferLength < Length)
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
RtlCopyMemory(PropertyBuffer, Data, Length);
|
|
||||||
|
|
||||||
/* Terminate the string */
|
|
||||||
if (DeviceProperty == DevicePropertyEnumeratorName
|
|
||||||
|| DeviceProperty == DevicePropertyPhysicalDeviceObjectName)
|
|
||||||
{
|
|
||||||
Ptr = (PWSTR)PropertyBuffer;
|
|
||||||
Ptr[(Length / sizeof(WCHAR)) - 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue