- Reapply fixed IoGetDeviceProperty() patch from 31467.

- Reformat the code.

svn path=/trunk/; revision=31515
This commit is contained in:
Aleksey Bragin 2007-12-31 13:22:52 +00:00
parent bd85b22ea9
commit ad4f47ec96

View file

@ -321,6 +321,8 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty); DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
*ResultLength = 0;
if (DeviceNode == NULL) if (DeviceNode == NULL)
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
@ -405,12 +407,13 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
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);
UNICODE_STRING ValueName;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
KEY_VALUE_PARTIAL_INFORMATION *ValueInformation; KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
ULONG ValueInformationLength; ULONG ValueInformationLength;
HANDLE KeyHandle; HANDLE KeyHandle, EnumRootHandle;
NTSTATUS Status; NTSTATUS Status;
switch (DeviceProperty) switch (DeviceProperty)
@ -436,47 +439,58 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
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\\");
wcscat(KeyNameBuffer, DeviceNode->InstancePath.Buffer);
RtlInitUnicodeString(&KeyName, KeyNameBuffer);
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
ExFreePool(KeyNameBuffer);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status);
return Status; return Status;
}
RtlInitUnicodeString(&ValueName, RegistryPropertyName); /* Allocate buffer to read as much data as required by the caller */
ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
Data[0]) + BufferLength; Data[0]) + BufferLength;
ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength); ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
if (ValueInformation == NULL) if (!ValueInformation)
{ {
ZwClose(KeyHandle); ZwClose(KeyHandle);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
/* Read the value */
RtlInitUnicodeString(&ValueName, RegistryPropertyName);
Status = ZwQueryValueKey(KeyHandle, &ValueName, Status = ZwQueryValueKey(KeyHandle, &ValueName,
KeyValuePartialInformation, ValueInformation, KeyValuePartialInformation, ValueInformation,
ValueInformationLength, ValueInformationLength,
&ValueInformationLength); &ValueInformationLength);
*ResultLength = ValueInformation->DataLength;
ZwClose(KeyHandle); ZwClose(KeyHandle);
/* Return data */
*ResultLength = ValueInformation->DataLength;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Problem: Status=%0x08x, ResultLength = %d\n", Status, *ResultLength);
ExFreePool(ValueInformation); ExFreePool(ValueInformation);
if (Status == STATUS_BUFFER_OVERFLOW) if (Status == STATUS_BUFFER_OVERFLOW)
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
@ -485,7 +499,6 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
} }
/* FIXME: Verify the value (NULL-terminated, correct format). */ /* FIXME: Verify the value (NULL-terminated, correct format). */
RtlCopyMemory(PropertyBuffer, ValueInformation->Data, RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
ValueInformation->DataLength); ValueInformation->DataLength);
ExFreePool(ValueInformation); ExFreePool(ValueInformation);
@ -513,21 +526,17 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
break; break;
case DevicePropertyEnumeratorName: case DevicePropertyEnumeratorName:
/* A buffer overflow can't happen here, since InstancePath
* always contains the enumerator name followed by \\ */
Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\'); Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
if (Ptr != NULL) ASSERT(Ptr);
{ Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
Length = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)DeviceNode->InstancePath.Buffer) + sizeof(WCHAR);
Data = DeviceNode->InstancePath.Buffer; Data = DeviceNode->InstancePath.Buffer;
}
else
{
Length = 0;
Data = NULL;
}
break; break;
case DevicePropertyPhysicalDeviceObjectName: case DevicePropertyPhysicalDeviceObjectName:
Length = DeviceNode->InstancePath.Length + sizeof(WCHAR); /* InstancePath buffer is NULL terminated, so we can do this */
Length = DeviceNode->InstancePath.MaximumLength;
Data = DeviceNode->InstancePath.Buffer; Data = DeviceNode->InstancePath.Buffer;
break; break;
@ -535,18 +544,15 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
return STATUS_INVALID_PARAMETER_2; return STATUS_INVALID_PARAMETER_2;
} }
/* Prepare returned values */
*ResultLength = Length; *ResultLength = Length;
if (BufferLength < Length) if (BufferLength < Length)
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
RtlCopyMemory(PropertyBuffer, Data, Length); RtlCopyMemory(PropertyBuffer, Data, Length);
/* Terminate the string */ /* NULL terminate the string (if required) */
if (DeviceProperty == DevicePropertyEnumeratorName if (DeviceProperty == DevicePropertyEnumeratorName)
|| DeviceProperty == DevicePropertyPhysicalDeviceObjectName) ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
{
Ptr = (PWSTR)PropertyBuffer;
Ptr[(Length / sizeof(WCHAR)) - 1] = 0;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }