- 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

@ -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;
} }
/* /*