Author: sir_richard
Date: Sat May 29 01:03:27 2010
New Revision: 47388
URL:
http://svn.reactos.org/svn/reactos?rev=47388&view=rev
Log:
[NTOS]: Re-implement IoGetDeviceProperty. Main changes are usage of existing (and new)
helper functions for registry/IRP access, much better factored code, correct
implementation of DevicePropertyPhysicalDeviceObjectName, fixed implementation of
DevicePropertyBootConfigurationTranslated and DevicePropertyBootConfiguration (do not
crash the system anymore), and support for more device properties.
[NTOS]: Fix caller of IoGetDeviceProperty in pnpres.c to work with new function behavior
(which matches WDK documentation and test cases).
[NTOS]: Implement helper function PnpBusTypeGuidGet, should be used later in other PnP
code, but now used only for this patch.
[NTOS]: Implement helper function PnpDetermineResourceListSize, ditto. N.B. Current
IopCalculateResourceListSize function is broken and callers should use this one instead.
[NTOS]: Implement helper function PpIrpQueryCapabilities, should be used later in device
node code, but now only used for this patch.
[NTOS]: Implement helper function PnpDeviceObjectToDeviceInstance, ditto.
Main purpose of this patch is to unblock the new PCIx driver.
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sat May 29 01:03:27 2010
@@ -3003,6 +3003,241 @@
/* PUBLIC FUNCTIONS **********************************************************/
+NTSTATUS
+NTAPI
+PnpBusTypeGuidGet(IN USHORT Index,
+ IN LPGUID BusTypeGuid)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* Acquire the lock */
+ ExAcquireFastMutex(&PnpBusTypeGuidList->Lock);
+
+ /* Validate size */
+ if (Index < PnpBusTypeGuidList->GuidCount)
+ {
+ /* Copy the data */
+ RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index],
sizeof(GUID));
+ }
+ else
+ {
+ /* Failure path */
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* Release lock and return status */
+ ExReleaseFastMutex(&PnpBusTypeGuidList->Lock);
+ return Index;
+}
+
+NTSTATUS
+NTAPI
+PpIrpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
+ OUT PDEVICE_CAPABILITIES DeviceCaps)
+{
+ PAGED_CODE();
+ PVOID Dummy;
+ IO_STACK_LOCATION Stack;
+
+ /* Set up the Header */
+ RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
+ DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES);
+ DeviceCaps->Version = 1;
+ DeviceCaps->Address = -1;
+ DeviceCaps->UINumber = -1;
+
+ /* Set up the Stack */
+ RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_QUERY_CAPABILITIES;
+ Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
+
+ /* Send the IRP */
+ return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+}
+
+NTSTATUS
+NTAPI
+PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject,
+ IN PHANDLE DeviceInstanceHandle,
+ IN ACCESS_MASK DesiredAccess)
+{
+ NTSTATUS Status;
+ HANDLE KeyHandle;
+ PDEVICE_NODE DeviceNode;
+ UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
+ PAGED_CODE();
+
+ /* Open the enum key */
+ Status = IopOpenRegistryKeyEx(&KeyHandle,
+ NULL,
+ &KeyName,
+ KEY_READ);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Make sure we have an instance path */
+ DeviceNode = IopGetDeviceNode(DeviceObject);
+ if ((DeviceNode) && (DeviceNode->InstancePath.Length))
+ {
+ /* Get the instance key */
+ Status = IopOpenRegistryKeyEx(DeviceInstanceHandle,
+ KeyHandle,
+ &DeviceNode->InstancePath,
+ DesiredAccess);
+ }
+ else
+ {
+ /* Fail */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /* Close the handle and return status */
+ ZwClose(KeyHandle);
+ return Status;
+}
+
+ULONG
+NTAPI
+PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
+{
+ ULONG FinalSize, PartialSize, EntrySize, i, j;
+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+
+ /* If we don't have one, that's easy */
+ if (!ResourceList) return 0;
+
+ /* Start with the minimum size possible */
+ FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
+
+ /* Loop each full descriptor */
+ FullDescriptor = ResourceList->List;
+ for (i = 0; i < ResourceList->Count; i++)
+ {
+ /* Start with the minimum size possible */
+ PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
+ FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors);
+
+ /* Loop each partial descriptor */
+ PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
+ for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++)
+ {
+ /* Start with the minimum size possible */
+ EntrySize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+
+ /* Check if there is extra data */
+ if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
+ {
+ /* Add that data */
+ EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize;
+ }
+
+ /* The size of partial descriptors is bigger */
+ PartialSize += EntrySize;
+
+ /* Go to the next partial descriptor */
+ PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize);
+ }
+
+ /* The size of full descriptors is bigger */
+ FinalSize += PartialSize;
+
+ /* Go to the next full descriptor */
+ FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize);
+ }
+
+ /* Return the final size */
+ return FinalSize;
+}
+
+NTSTATUS
+NTAPI
+PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG ValueType,
+ IN PWSTR ValueName,
+ IN PWSTR KeyName,
+ OUT PVOID Buffer,
+ IN PULONG BufferLength)
+{
+ NTSTATUS Status;
+ HANDLE KeyHandle, SubHandle;
+ UNICODE_STRING KeyString;
+ PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL;
+ ULONG Length;
+ PAGED_CODE();
+
+ /* Find the instance key */
+ Status = PnpDeviceObjectToDeviceInstance(DeviceObject, &KeyHandle, KEY_READ);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check for name given by caller */
+ if (KeyName)
+ {
+ /* Open this key */
+ RtlInitUnicodeString(&KeyString, KeyName);
+ Status = IopOpenRegistryKeyEx(&SubHandle,
+ KeyHandle,
+ &KeyString,
+ KEY_READ);
+ if (NT_SUCCESS(Status))
+ {
+ /* And use this handle instead */
+ ZwClose(KeyHandle);
+ KeyHandle = SubHandle;
+ }
+ }
+
+ /* Check if sub-key handle succeeded (or no-op if no key name given) */
+ if (NT_SUCCESS(Status))
+ {
+ /* Now get the size of the property */
+ Status = IopGetRegistryValue(KeyHandle,
+ ValueName,
+ &KeyValueInfo);
+ }
+
+ /* Close the key */
+ ZwClose(KeyHandle);
+ }
+
+ /* Fail if any of the registry operations failed */
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check how much data we have to copy */
+ Length = KeyValueInfo->DataLength;
+ if (*BufferLength >= Length)
+ {
+ /* Check for a match in the value type */
+ if (KeyValueInfo->Type == ValueType)
+ {
+ /* Copy the data */
+ RtlCopyMemory(Buffer,
+ (PVOID)((ULONG_PTR)KeyValueInfo +
+ KeyValueInfo->DataOffset),
+ Length);
+ }
+ else
+ {
+ /* Invalid registry property type, fail */
+ Status = STATUS_INVALID_PARAMETER_2;
+ }
+ }
+ else
+ {
+ /* Buffer is too small to hold data */
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Return the required buffer length, free the buffer, and return status */
+ *BufferLength = Length;
+ ExFreePool(KeyValueInfo);
+ return Status;
+}
+
+#define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; break;}
+#define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;}
+#define PIP_UNIMPLEMENTED() {UNIMPLEMENTED; while(TRUE); break;}
+
/*
* @implemented
*/
@@ -3016,281 +3251,205 @@
{
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
DEVICE_CAPABILITIES DeviceCaps;
- ULONG Length;
+ ULONG ReturnLength = 0, Length = 0, ValueType;
+ PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
PVOID Data = NULL;
- PWSTR Ptr;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_BUFFER_TOO_SMALL;
+ GUID BusTypeGuid;
POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
- ULONG RequiredLength, ObjectNameInfoLength;
-
DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
+ /* Assume failure */
*ResultLength = 0;
- if (DeviceNode == NULL)
- return STATUS_INVALID_DEVICE_REQUEST;
-
+ /* Only PDOs can call this */
+ if (!DeviceNode) return STATUS_INVALID_DEVICE_REQUEST;
+
+ /* Handle all properties */
switch (DeviceProperty)
{
- case DevicePropertyBusNumber:
- Length = sizeof(ULONG);
- Data = &DeviceNode->ChildBusNumber;
- break;
-
- /* Complete, untested */
- case DevicePropertyBusTypeGuid:
- /* Sanity check */
- if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
- (DeviceNode->ChildBusTypeIndex < PnpBusTypeGuidList->GuidCount))
+ case DevicePropertyBusTypeGuid:
+
+ /* Get the GUID from the internal cache */
+ Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex,
&BusTypeGuid);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
+
+ case DevicePropertyLegacyBusType:
+
+ /* Validate correct interface type */
+ if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA(sizeof(INTERFACE_TYPE),
&DeviceNode->ChildInterfaceType);
+
+ case DevicePropertyBusNumber:
+
+ /* Validate correct bus number */
+ if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
+
+ case DevicePropertyEnumeratorName:
+
+ /* Get the instance path */
+ DeviceInstanceName = DeviceNode->InstancePath.Buffer;
+
+ /* Sanity checks */
+ ASSERT((BufferLength & 1) == 0);
+ ASSERT(DeviceInstanceName != NULL);
+
+ /* Get the name from the path */
+ EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
+ ASSERT(EnumeratorNameEnd);
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * 2,
+ &DeviceNode->ChildBusNumber);
+
+ case DevicePropertyAddress:
+
+ /* Query the device caps */
+ Status = PpIrpQueryCapabilities(DeviceObject, &DeviceCaps);
+ if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
+
+ case DevicePropertyBootConfigurationTranslated:
+
+ /* Validate we have resources */
+ if (!DeviceNode->BootResources)
+// if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
+ {
+ /* No resources will still fake success, but with 0 bytes */
+ *ResultLength = 0;
+ return STATUS_SUCCESS;
+ }
+
+ /* This is the format of the returned data */
+ PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources),
// FIXFIX: Should use BootResourcesTranslated
+ DeviceNode->BootResources); // FIXFIX: Should use
BootResourcesTranslated
+
+ case DevicePropertyPhysicalDeviceObjectName:
+
+ /* Sanity check for Unicode-sized string */
+ ASSERT((BufferLength & 1) == 0);
+
+ /* Allocate name buffer */
+ Length = BufferLength + sizeof(OBJECT_NAME_INFORMATION);
+ ObjectNameInfo = ExAllocatePool(PagedPool, Length);
+ if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Query the PDO name */
+ Status = ObQueryNameString(DeviceObject,
+ ObjectNameInfo,
+ Length,
+ ResultLength);
+ if (Status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ /* It's up to the caller to try again */
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Return if successful */
+ if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
+ ObjectNameInfo->Name.Buffer);
+
+ /* Let the caller know how big the name is */
+ *ResultLength -= sizeof(OBJECT_NAME_INFORMATION);
+ break;
+
+ /* Handle the registry-based properties */
+ case DevicePropertyUINumber:
+ PIP_REGISTRY_DATA(REGSTR_VAL_UI_NUMBER, REG_DWORD);
+ case DevicePropertyLocationInformation:
+ PIP_REGISTRY_DATA(REGSTR_VAL_LOCATION_INFORMATION, REG_SZ);
+ case DevicePropertyDeviceDescription:
+ PIP_REGISTRY_DATA(REGSTR_VAL_DEVDESC, REG_SZ);
+ case DevicePropertyHardwareID:
+ PIP_REGISTRY_DATA(REGSTR_VAL_HARDWAREID, REG_MULTI_SZ);
+ case DevicePropertyCompatibleIDs:
+ PIP_REGISTRY_DATA(REGSTR_VAL_COMPATIBLEIDS, REG_MULTI_SZ);
+ case DevicePropertyBootConfiguration:
+ PIP_REGISTRY_DATA(REGSTR_VAL_BOOTCONFIG, REG_RESOURCE_LIST);
+ case DevicePropertyClassName:
+ PIP_REGISTRY_DATA(REGSTR_VAL_CLASS, REG_SZ);
+ case DevicePropertyClassGuid:
+ PIP_REGISTRY_DATA(REGSTR_VAL_CLASSGUID, REG_SZ);
+ case DevicePropertyDriverKeyName:
+ PIP_REGISTRY_DATA(REGSTR_VAL_DRIVER, REG_SZ);
+ case DevicePropertyManufacturer:
+ PIP_REGISTRY_DATA(REGSTR_VAL_MFG, REG_SZ);
+ case DevicePropertyFriendlyName:
+ PIP_REGISTRY_DATA(REGSTR_VAL_FRIENDLYNAME, REG_SZ);
+ case DevicePropertyContainerID:
+ //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
+ PIP_UNIMPLEMENTED();
+ case DevicePropertyRemovalPolicy:
+ PIP_UNIMPLEMENTED();
+ case DevicePropertyInstallState:
+ PIP_UNIMPLEMENTED();
+ case DevicePropertyResourceRequirements:
+ PIP_UNIMPLEMENTED();
+ case DevicePropertyAllocatedResources:
+ PIP_UNIMPLEMENTED();
+ default:
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Having a registry value name implies registry data */
+ if (ValueName)
+ {
+ /* We know up-front how much data to expect */
+ *ResultLength = BufferLength;
+
+ /* Go get the data, use the LogConf subkey if necessary */
+ Status = PiGetDeviceRegistryProperty(DeviceObject,
+ ValueType,
+ ValueName,
+ (DeviceProperty ==
+ DevicePropertyBootConfiguration) ?
+ L"LogConf": NULL,
+ PropertyBuffer,
+ ResultLength);
+ }
+ else if (NT_SUCCESS(Status))
+ {
+ /* We know up-front how much data to expect, check the caller's buffer */
+ *ResultLength = ReturnLength;
+ if (ReturnLength <= BufferLength)
{
- /* Return the GUID */
- *ResultLength = sizeof(GUID);
-
- /* Check if the buffer given was large enough */
- if (BufferLength < *ResultLength)
+ /* Buffer is all good, copy the data */
+ RtlCopyMemory(PropertyBuffer, Data, ReturnLength);
+
+ /* Check for properties that require a null-terminated string */
+ if ((DeviceProperty == DevicePropertyEnumeratorName) ||
+ (DeviceProperty == DevicePropertyPhysicalDeviceObjectName))
{
- return STATUS_BUFFER_TOO_SMALL;
+ /* Terminate the string */
+ ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL;
}
-
- /* Copy the GUID */
- RtlCopyMemory(PropertyBuffer,
- &(PnpBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
- sizeof(GUID));
- return STATUS_SUCCESS;
+
+ /* This is the success path */
+ Status = STATUS_SUCCESS;
}
else
{
- return STATUS_OBJECT_NAME_NOT_FOUND;
+ /* Failure path */
+ Status = STATUS_BUFFER_TOO_SMALL;
}
- break;
-
- case DevicePropertyLegacyBusType:
- Length = sizeof(INTERFACE_TYPE);
- Data = &DeviceNode->ChildInterfaceType;
- break;
-
- case DevicePropertyAddress:
- /* Query the device caps */
- Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
- if (NT_SUCCESS(Status) && (DeviceCaps.Address != MAXULONG))
- {
- /* Return length */
- *ResultLength = sizeof(ULONG);
-
- /* Check if the buffer given was large enough */
- if (BufferLength < *ResultLength)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- /* Return address */
- *(PULONG)PropertyBuffer = DeviceCaps.Address;
- return STATUS_SUCCESS;
- }
- else
- {
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
- break;
-
-// case DevicePropertyUINumber:
-// if (DeviceNode->CapabilityFlags == NULL)
-// return STATUS_INVALID_DEVICE_REQUEST;
-// Length = sizeof(ULONG);
-// Data = &DeviceNode->CapabilityFlags->UINumber;
-// break;
-
- case DevicePropertyClassName:
- case DevicePropertyClassGuid:
- case DevicePropertyDriverKeyName:
- case DevicePropertyManufacturer:
- case DevicePropertyFriendlyName:
- case DevicePropertyHardwareID:
- case DevicePropertyCompatibleIDs:
- case DevicePropertyDeviceDescription:
- case DevicePropertyLocationInformation:
- case DevicePropertyUINumber:
- {
- LPCWSTR RegistryPropertyName;
- UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
- UNICODE_STRING ValueName;
- KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
- ULONG ValueInformationLength;
- HANDLE KeyHandle, EnumRootHandle;
- NTSTATUS Status;
-
- switch (DeviceProperty)
- {
- case DevicePropertyClassName:
- RegistryPropertyName = L"Class"; break;
- case DevicePropertyClassGuid:
- RegistryPropertyName = L"ClassGuid"; break;
- case DevicePropertyDriverKeyName:
- RegistryPropertyName = L"Driver"; break;
- case DevicePropertyManufacturer:
- RegistryPropertyName = L"Mfg"; break;
- case DevicePropertyFriendlyName:
- RegistryPropertyName = L"FriendlyName"; break;
- case DevicePropertyHardwareID:
- RegistryPropertyName = L"HardwareID"; break;
- case DevicePropertyCompatibleIDs:
- RegistryPropertyName = L"CompatibleIDs"; break;
- case DevicePropertyDeviceDescription:
- RegistryPropertyName = L"DeviceDesc"; break;
- case DevicePropertyLocationInformation:
- RegistryPropertyName = L"LocationInformation"; break;
- case DevicePropertyUINumber:
- RegistryPropertyName = L"UINumber"; break;
- default:
- /* Should not happen */
- ASSERT(FALSE);
- return STATUS_UNSUCCESSFUL;
- }
-
- DPRINT("Registry property %S\n", RegistryPropertyName);
-
- /* Open Enum key */
- Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL,
- &EnumRoot, KEY_READ);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
- return Status;
- }
-
- /* Open instance key */
- Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle,
- &DeviceNode->InstancePath, KEY_READ);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Error opening InstancePath, Status=0x%08x\n",
Status);
- ZwClose(EnumRootHandle);
- return Status;
- }
-
- /* Allocate buffer to read as much data as required by the caller */
- ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
- Data[0]) + BufferLength;
- ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
- if (!ValueInformation)
- {
- ZwClose(KeyHandle);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Read the value */
- RtlInitUnicodeString(&ValueName, RegistryPropertyName);
- Status = ZwQueryValueKey(KeyHandle, &ValueName,
- KeyValuePartialInformation, ValueInformation,
- ValueInformationLength,
- &ValueInformationLength);
- ZwClose(KeyHandle);
-
- /* Return data */
- *ResultLength = ValueInformation->DataLength;
-
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(ValueInformation);
- if (Status == STATUS_BUFFER_OVERFLOW)
- return STATUS_BUFFER_TOO_SMALL;
- DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status,
*ResultLength);
- return Status;
- }
-
- /* FIXME: Verify the value (NULL-terminated, correct format). */
- RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
- ValueInformation->DataLength);
- ExFreePool(ValueInformation);
-
- return STATUS_SUCCESS;
- }
-
- case DevicePropertyBootConfiguration:
- Length = 0;
- if (DeviceNode->BootResources->Count != 0)
- {
- Length = IopCalculateResourceListSize(DeviceNode->BootResources);
- }
- Data = DeviceNode->BootResources;
- break;
-
- /* FIXME: use a translated boot configuration instead */
- case DevicePropertyBootConfigurationTranslated:
- Length = 0;
- if (DeviceNode->BootResources->Count != 0)
- {
- Length = IopCalculateResourceListSize(DeviceNode->BootResources);
- }
- Data = DeviceNode->BootResources;
- break;
-
- case DevicePropertyEnumeratorName:
- /* A buffer overflow can't happen here, since InstancePath
- * always contains the enumerator name followed by \\ */
- Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
- ASSERT(Ptr);
- Length = (Ptr - DeviceNode->InstancePath.Buffer) * sizeof(WCHAR);
- Data = DeviceNode->InstancePath.Buffer;
- break;
-
- case DevicePropertyPhysicalDeviceObjectName:
- Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject,
- NULL,
- 0,
- &RequiredLength);
- if (Status == STATUS_SUCCESS)
- {
- Length = 0;
- Data = L"";
- }
- else if (Status == STATUS_INFO_LENGTH_MISMATCH)
- {
- ObjectNameInfoLength = RequiredLength;
- ObjectNameInfo = ExAllocatePool(PagedPool, ObjectNameInfoLength);
- if (!ObjectNameInfo)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject,
- ObjectNameInfo,
- ObjectNameInfoLength,
- &RequiredLength);
- if (NT_SUCCESS(Status))
- {
- Length = ObjectNameInfo->Name.Length;
- Data = ObjectNameInfo->Name.Buffer;
- }
- else
- return Status;
- }
- else
- return Status;
- break;
-
- default:
- return STATUS_INVALID_PARAMETER_2;
- }
-
- /* Prepare returned values */
- *ResultLength = Length;
- if (BufferLength < Length)
- {
- if (ObjectNameInfo != NULL)
- ExFreePool(ObjectNameInfo);
-
- return STATUS_BUFFER_TOO_SMALL;
- }
- RtlCopyMemory(PropertyBuffer, Data, Length);
-
- /* NULL terminate the string (if required) */
- if (DeviceProperty == DevicePropertyEnumeratorName ||
- DeviceProperty == DevicePropertyPhysicalDeviceObjectName)
- ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- if (ObjectNameInfo != NULL)
- ExFreePool(ObjectNameInfo);
-
- return STATUS_SUCCESS;
+ }
+
+ /* Free any allocation we may have made, and return the status code */
+ if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
+ return Status;
}
/*
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c [iso-8859-1] Sat May 29 01:03:27 2010
@@ -634,25 +634,37 @@
if (DeviceNode->ResourceList)
{
- WCHAR NameBuff[256];
+ PWCHAR DeviceName = NULL;
UNICODE_STRING NameU;
UNICODE_STRING Suffix;
- ULONG OldLength;
+ ULONG OldLength = 0;
ASSERT(DeviceNode->ResourceListTranslated);
-
- NameU.Buffer = NameBuff;
- NameU.Length = 0;
- NameU.MaximumLength = 256 * sizeof(WCHAR);
Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
DevicePropertyPhysicalDeviceObjectName,
- NameU.MaximumLength,
- NameU.Buffer,
+ 0,
+ NULL,
&OldLength);
- ASSERT(Status == STATUS_SUCCESS);
-
- NameU.Length = (USHORT)OldLength;
+ if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL))
+ {
+ DeviceName = ExAllocatePool(NonPagedPool, OldLength);
+ ASSERT(DeviceName);
+
+ IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
+ DevicePropertyPhysicalDeviceObjectName,
+ OldLength,
+ DeviceName,
+ &OldLength);
+
+ RtlInitUnicodeString(&NameU, DeviceName);
+ }
+ else
+ {
+ /* Some failure */
+ ASSERT(!NT_SUCCESS(Status));
+ return Status;
+ }
RtlInitUnicodeString(&Suffix, L".Raw");
RtlAppendUnicodeStringToString(&NameU, &Suffix);
@@ -682,6 +694,8 @@
DeviceNode->ResourceListTranslated,
IopCalculateResourceListSize(DeviceNode->ResourceListTranslated));
ZwClose(PnpMgrLevel2);
+ ASSERT(DeviceName);
+ ExFreePool(DeviceName);
if (!NT_SUCCESS(Status))
return Status;
}