-/* $Id: pnpmgr.c,v 1.36 2004/10/11 18:36:20 navaraf Exp $
+/* $Id: pnpmgr.c,v 1.42 2004/10/22 18:34:11 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
#endif // DEFINE_GUID
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
ULONG Length;
PVOID Data;
+ PWSTR Ptr;
- DPRINT("IoGetDeviceProperty called\n");
+ DPRINT("IoGetDeviceProperty(%x %d)\n", DeviceObject, DeviceProperty);
if (DeviceNode == NULL)
return STATUS_INVALID_DEVICE_REQUEST;
case DevicePropertyDriverKeyName:
case DevicePropertyManufacturer:
case DevicePropertyFriendlyName:
+ case DevicePropertyHardwareID:
+ case DevicePropertyCompatibleIDs:
+ case DevicePropertyDeviceDescription:
+ case DevicePropertyLocationInformation:
{
LPWSTR RegistryPropertyName, KeyNameBuffer;
UNICODE_STRING KeyName, ValueName;
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;
default:
RegistryPropertyName = NULL; break;
}
KeyNameBuffer = ExAllocatePool(PagedPool,
(49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+
+ DPRINT1("KeyNameBuffer: %x, value %S\n",
+ KeyNameBuffer, RegistryPropertyName);
+
if (KeyNameBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
wcscat(KeyNameBuffer, DeviceNode->InstancePath.Buffer);
-
RtlInitUnicodeString(&KeyName, KeyNameBuffer);
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
}
case DevicePropertyBootConfiguration:
+ Length = 0;
+ if (DeviceNode->BootResourceList->Count != 0)
+ {
+ Length = sizeof(CM_RESOURCE_LIST) +
+ ((DeviceNode->BootResourceList->Count - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+ }
+ Data = &DeviceNode->BootResourceList;
+ break;
+
+ /* FIXME: use a translated boot configuration instead */
case DevicePropertyBootConfigurationTranslated:
- case DevicePropertyCompatibleIDs:
- case DevicePropertyDeviceDescription:
- case DevicePropertyEnumeratorName:
- case DevicePropertyHardwareID:
- case DevicePropertyLocationInformation:
+ Length = 0;
+ if (DeviceNode->BootResourceList->Count != 0)
+ {
+ Length = sizeof(CM_RESOURCE_LIST) +
+ ((DeviceNode->BootResourceList->Count - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+ }
+ Data = &DeviceNode->BootResourceList;
+ break;
+
+ case DevicePropertyEnumeratorName:
+ Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
+ if (Ptr != NULL)
+ {
+ Length = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)DeviceNode->InstancePath.Buffer) + sizeof(WCHAR);
+ }
+ else
+ {
+ Length = 0;
+ Data = NULL;
+ }
+
case DevicePropertyPhysicalDeviceObjectName:
return STATUS_NOT_IMPLEMENTED;
return STATUS_BUFFER_TOO_SMALL;
RtlCopyMemory(PropertyBuffer, Data, Length);
+ /* Terminate the string */
+ if (DeviceProperty == DevicePropertyEnumeratorName)
+ {
+ Ptr = (PWSTR)PropertyBuffer;
+ Ptr[(Length / sizeof(WCHAR)) - 1] = 0;
+ }
+
return STATUS_SUCCESS;
}
ExFreePool(DeviceNode->CmResourceList);
}
- if (DeviceNode->BootResourcesList)
+ if (DeviceNode->BootResourceList)
{
- ExFreePool(DeviceNode->BootResourcesList);
+ ExFreePool(DeviceNode->BootResourceList);
}
if (DeviceNode->ResourceRequirementsList)
ExFreePool(DeviceNode->ResourceRequirementsList);
}
- RtlFreeUnicodeString(&DeviceNode->DeviceID);
-
- RtlFreeUnicodeString(&DeviceNode->InstanceID);
-
- RtlFreeUnicodeString(&DeviceNode->HardwareIDs);
-
- RtlFreeUnicodeString(&DeviceNode->CompatibleIDs);
-
- RtlFreeUnicodeString(&DeviceNode->DeviceText);
-
- RtlFreeUnicodeString(&DeviceNode->DeviceTextLocation);
-
if (DeviceNode->BusInformation)
{
ExFreePool(DeviceNode->BusInformation);
KeInitializeEvent(
&Event,
- NotificationEvent,
- FALSE);
-
- /* PNP IRPs are always initialized with a status code of
- STATUS_NOT_IMPLEMENTED */
- IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
- IoStatusBlock->Information = 0;
+ NotificationEvent,
+ FALSE);
Irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP,
TopDeviceObject,
- NULL,
- 0,
- NULL,
- &Event,
- IoStatusBlock);
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ IoStatusBlock);
+
+ /* PNP IRPs are always initialized with a status code of
+ STATUS_NOT_IMPLEMENTED */
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MinorFunction = MinorFunction;
static NTSTATUS
-IopCreateDeviceKeyPath(PWSTR Path)
+IopCreateDeviceKeyPath(PWSTR Path,
+ PHANDLE Handle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR KeyBuffer[MAX_PATH];
PWCHAR Current;
PWCHAR Next;
+ *Handle = NULL;
+
if (_wcsnicmp(Path, L"\\Registry\\", 10) != 0)
{
return STATUS_INVALID_PARAMETER;
Current = wcschr (Current, '\\') + 1;
Current = wcschr (Current, '\\') + 1;
- do
- {
+ while (TRUE)
+ {
Next = wcschr (Current, '\\');
if (Next == NULL)
{
return Status;
}
- NtClose (KeyHandle);
-
- if (Next != NULL)
+ if (Next == NULL)
{
+ *Handle = KeyHandle;
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ NtClose (KeyHandle);
*Next = L'\\';
}
Current = Next + 1;
}
- while (Next != NULL);
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+IopSetDeviceInstanceData(HANDLE InstanceKey,
+ PDEVICE_NODE DeviceNode)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ HANDLE LogConfKey;
+ ULONG ResCount;
+ ULONG ListSize;
+ NTSTATUS Status;
+
+ DPRINT("IopSetDeviceInstanceData() called\n");
+
+ /* Create the 'LogConf' key */
+ RtlInitUnicodeString(&KeyName,
+ L"LogConf");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ InstanceKey,
+ NULL);
+ Status = NtCreateKey(&LogConfKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Set 'BootConfig' value */
+ if (DeviceNode->BootResourceList != NULL)
+ {
+ ResCount = DeviceNode->BootResourceList->Count;
+ if (ResCount != 0)
+ {
+ ListSize = sizeof(CM_RESOURCE_LIST) +
+ ((ResCount - 1) * sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
+
+ RtlInitUnicodeString(&KeyName,
+ L"BootConfig");
+ Status = NtSetValueKey(LogConfKey,
+ &KeyName,
+ 0,
+ REG_RESOURCE_LIST,
+ &DeviceNode->BootResourceList,
+ ListSize);
+ }
+ }
+
+ /* Set 'BasicConfigVector' value */
+ if (DeviceNode->ResourceRequirementsList != NULL &&
+ DeviceNode->ResourceRequirementsList->ListSize != 0)
+ {
+ RtlInitUnicodeString(&KeyName,
+ L"BasicConfigVector");
+ Status = NtSetValueKey(LogConfKey,
+ &KeyName,
+ 0,
+ REG_RESOURCE_REQUIREMENTS_LIST,
+ &DeviceNode->ResourceRequirementsList,
+ DeviceNode->ResourceRequirementsList->ListSize);
+ }
+
+ NtClose(LogConfKey);
+ }
+
+ DPRINT("IopSetDeviceInstanceData() done\n");
return STATUS_SUCCESS;
}
PWSTR Ptr;
USHORT Length;
USHORT TotalLength;
+ HANDLE InstanceKey = NULL;
+ UNICODE_STRING ValueName;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
DPRINT("PDO %x\n", DeviceNode->Pdo);
&Stack);
if (NT_SUCCESS(Status))
{
- RtlInitUnicodeString(
- &DeviceNode->DeviceID,
- (PWSTR)IoStatusBlock.Information);
+ /* Copy the device id string */
+ wcscpy(InstancePath, (PWSTR)IoStatusBlock.Information);
/*
* FIXME: Check for valid characters, if there is invalid characters
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->DeviceID, NULL);
}
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
&Stack);
if (NT_SUCCESS(Status))
{
- RtlInitUnicodeString(
- &DeviceNode->InstanceID,
- (PWSTR)IoStatusBlock.Information);
+ /* Append the instance id string */
+ wcscat(InstancePath, L"\\");
+ wcscat(InstancePath, (PWSTR)IoStatusBlock.Information);
/*
* FIXME: Check for valid characters, if there is invalid characters
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->InstanceID, NULL);
+ }
+
+ Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
+ if (NT_SUCCESS(Status))
+ {
+ }
+ else
+ {
+ }
+
+ if (!DeviceNode->CapabilityFlags->UniqueID)
+ {
+ DPRINT("Instance ID is not unique\n");
+ /* FIXME: Add information from parent bus driver to InstancePath */
+ }
+
+ if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool))
+ {
+ DPRINT("No resources\n");
+ /* FIXME: Cleanup and disable device */
+ }
+
+ DPRINT1("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
+
+ /*
+ * Create registry key for the instance id, if it doesn't exist yet
+ */
+ KeyBuffer = ExAllocatePool(
+ PagedPool,
+ (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+ wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
+ Status = IopCreateDeviceKeyPath(KeyBuffer,
+ &InstanceKey);
+ ExFreePool(KeyBuffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
+ }
+
+
+ if (DeviceNode->CapabilityFlags != NULL)
+ {
+ /* Set 'Capabilities' value */
+ RtlInitUnicodeString(&ValueName,
+ L"Capabilities");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ (PVOID)((ULONG_PTR)&DeviceNode->CapabilityFlags + 4),
+ sizeof(ULONG));
+
+ /* Set 'UINumber' value */
+ if (DeviceNode->CapabilityFlags->UINumber != (ULONG)-1)
+ {
+ RtlInitUnicodeString(&ValueName,
+ L"UINumber");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ &DeviceNode->CapabilityFlags->UINumber,
+ sizeof(ULONG));
+ }
}
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
DPRINT("TotalLength: %hu\n", TotalLength);
DPRINT("\n");
- DeviceNode->HardwareIDs.Length = TotalLength * sizeof(WCHAR);
- DeviceNode->HardwareIDs.MaximumLength = DeviceNode->HardwareIDs.Length + sizeof(WCHAR);
- DeviceNode->HardwareIDs.Buffer = (PWSTR)IoStatusBlock.Information;
+ RtlInitUnicodeString(&ValueName,
+ L"HardwareID");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_MULTI_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (TotalLength + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+ }
}
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->HardwareIDs, NULL);
}
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
DPRINT("TotalLength: %hu\n", TotalLength);
DPRINT("\n");
- DeviceNode->CompatibleIDs.Length = TotalLength * sizeof(WCHAR);
- DeviceNode->CompatibleIDs.MaximumLength = DeviceNode->CompatibleIDs.Length + sizeof(WCHAR);
- DeviceNode->CompatibleIDs.Buffer = (PWSTR)IoStatusBlock.Information;
+ RtlInitUnicodeString(&ValueName,
+ L"CompatibleIDs");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_MULTI_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (TotalLength + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+ }
}
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->CompatibleIDs, NULL);
}
- Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
- if (NT_SUCCESS(Status))
- {
- }
- else
- {
- }
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
&Stack);
if (NT_SUCCESS(Status))
{
- RtlInitUnicodeString(
- &DeviceNode->DeviceText,
- (PWSTR)IoStatusBlock.Information);
+ RtlInitUnicodeString(&ValueName,
+ L"DeviceDesc");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+ }
}
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->DeviceText, NULL);
}
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
&Stack);
if (NT_SUCCESS(Status))
{
- RtlInitUnicodeString(
- &DeviceNode->DeviceTextLocation,
- (PWSTR)IoStatusBlock.Information);
+ DPRINT("LocationInformation: %S\n", (PWSTR)IoStatusBlock.Information);
+ RtlInitUnicodeString(&ValueName,
+ L"LocationInformation");
+ Status = NtSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (wcslen((PWSTR)IoStatusBlock.Information) + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+ }
}
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- RtlInitUnicodeString(&DeviceNode->DeviceTextLocation, NULL);
}
DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
NULL);
if (NT_SUCCESS(Status))
{
- DeviceNode->BootResourcesList =
+ DeviceNode->BootResourceList =
(PCM_RESOURCE_LIST)IoStatusBlock.Information;
DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
}
else
{
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
- DeviceNode->BootResourcesList = NULL;
+ DeviceNode->BootResourceList = NULL;
}
DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
DeviceNode->ResourceRequirementsList = NULL;
}
- /*
- * Assemble the instance path for the device
- */
- wcscpy(InstancePath, DeviceNode->DeviceID.Buffer);
- wcscat(InstancePath, L"\\");
- wcscat(InstancePath, DeviceNode->InstanceID.Buffer);
-
- if (!DeviceNode->CapabilityFlags->UniqueID)
+ if (InstanceKey != NULL)
{
- DPRINT("Instance ID is not unique\n");
- /* FIXME: Add information from parent bus driver to InstancePath */
+ IopSetDeviceInstanceData(InstanceKey, DeviceNode);
}
- if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool))
- {
- DPRINT("No resources\n");
- /* FIXME: Cleanup and disable device */
- }
-
- DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
-
- /*
- * Create registry key for the instance id, if it doesn't exist yet
- */
+ NtClose(InstanceKey);
- KeyBuffer = ExAllocatePool(
- PagedPool,
- (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
- wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
- wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
- IopCreateDeviceKeyPath(KeyBuffer);
- ExFreePool(KeyBuffer);
DeviceNode->Flags |= DNF_PROCESSED;
return STATUS_SUCCESS;