-/* $Id: pnpmgr.c,v 1.29 2004/06/10 11:00:28 ekohl Exp $
+/* $Id: pnpmgr.c,v 1.37 2004/10/11 19:07:25 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES ******************************************************************/
-#include <ddk/ntddk.h>
-#include <reactos/bugcodes.h>
-#include <internal/io.h>
-#include <internal/po.h>
-#include <internal/ldr.h>
-#include <internal/module.h>
-
+#include <ntoskrnl.h>
#include <ole32/guiddef.h>
-//#include <ddk/pnpfuncs.h>
#ifdef DEFINE_GUID
DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
DPRINT("IoGetDeviceProperty called\n");
- if (DeviceNode == NULL ||
- DeviceNode->BusInformation == NULL ||
- DeviceNode->CapabilityFlags == NULL)
- {
+ if (DeviceNode == NULL)
return STATUS_INVALID_DEVICE_REQUEST;
- }
- /*
- * Used IRPs:
- * IRP_MN_QUERY_ID
- * IRP_MN_QUERY_BUS_INFORMATION
- */
switch (DeviceProperty)
{
case DevicePropertyBusNumber:
+ if (DeviceNode->BusInformation == NULL)
+ return STATUS_INVALID_DEVICE_REQUEST;
Length = sizeof(ULONG);
Data = &DeviceNode->BusInformation->BusNumber;
break;
/* Complete, untested */
case DevicePropertyBusTypeGuid:
+ if (DeviceNode->BusInformation == NULL)
+ return STATUS_INVALID_DEVICE_REQUEST;
*ResultLength = 39 * sizeof(WCHAR);
if (BufferLength < (39 * sizeof(WCHAR)))
return STATUS_BUFFER_TOO_SMALL;
return STATUS_SUCCESS;
case DevicePropertyLegacyBusType:
+ if (DeviceNode->BusInformation == NULL)
+ return STATUS_INVALID_DEVICE_REQUEST;
Length = sizeof(INTERFACE_TYPE);
Data = &DeviceNode->BusInformation->LegacyBusType;
break;
case DevicePropertyAddress:
+ if (DeviceNode->CapabilityFlags == NULL)
+ return STATUS_INVALID_DEVICE_REQUEST;
Length = sizeof(ULONG);
Data = &DeviceNode->CapabilityFlags->Address;
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:
+ {
+ LPWSTR RegistryPropertyName, KeyNameBuffer;
+ UNICODE_STRING KeyName, ValueName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
+ ULONG ValueInformationLength;
+ HANDLE KeyHandle;
+ 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;
+ default:
+ RegistryPropertyName = NULL; break;
+ }
+
+ KeyNameBuffer = ExAllocatePool(PagedPool,
+ (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
+ 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);
+
+ Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
+ ExFreePool(KeyNameBuffer);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RtlInitUnicodeString(&ValueName, RegistryPropertyName);
+ ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
+ Data[0]) + BufferLength;
+ ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
+ if (ValueInformation == NULL)
+ {
+ ZwClose(KeyHandle);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = ZwQueryValueKey(KeyHandle, &ValueName,
+ KeyValuePartialInformation, ValueInformation,
+ ValueInformationLength,
+ &ValueInformationLength);
+ *ResultLength = ValueInformation->DataLength;
+ ZwClose(KeyHandle);
+
+ if (ValueInformation->DataLength > BufferLength)
+ Status = STATUS_BUFFER_TOO_SMALL;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ValueInformation);
+ return Status;
+ }
+
+ /* FIXME: Verify the value (NULL-terminated, correct format). */
+
+ RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
+ ValueInformation->DataLength);
+ ExFreePool(ValueInformation);
+
+ return STATUS_SUCCESS;
+ }
+
case DevicePropertyBootConfiguration:
case DevicePropertyBootConfigurationTranslated:
- case DevicePropertyClassGuid:
- case DevicePropertyClassName:
case DevicePropertyCompatibleIDs:
case DevicePropertyDeviceDescription:
- case DevicePropertyDriverKeyName:
- case DevicePropertyEnumeratorName:
- case DevicePropertyFriendlyName:
+ case DevicePropertyEnumeratorName:
case DevicePropertyHardwareID:
case DevicePropertyLocationInformation:
- case DevicePropertyManufacturer:
case DevicePropertyPhysicalDeviceObjectName:
return STATUS_NOT_IMPLEMENTED;
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE DevInstRegKey)
{
+ static const WCHAR ClassKeyName[] = {
+ '\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',
+ 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t',
+ 'r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\',
+ 'C','l','a','s','s','\\'};
+ LPWSTR KeyNameBuffer;
+ UNICODE_STRING KeyName;
+ ULONG DriverKeyLength;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+
+ if (DevInstKeyType == PLUGPLAY_REGKEY_DRIVER)
+ {
+ Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+ 0, NULL, &DriverKeyLength);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ return Status;
+
+ KeyNameBuffer = ExAllocatePool(PagedPool, DriverKeyLength + sizeof(ClassKeyName));
+ if (KeyNameBuffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlCopyMemory(KeyNameBuffer, ClassKeyName, sizeof(ClassKeyName));
+ Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+ DriverKeyLength, KeyNameBuffer +
+ (sizeof(ClassKeyName) / sizeof(WCHAR)),
+ &DriverKeyLength);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(KeyNameBuffer);
+ return Status;
+ }
+
+ RtlInitUnicodeString(&KeyName, KeyNameBuffer);
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName,
+ OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = ZwOpenKey(DevInstRegKey, DesiredAccess, &ObjectAttributes);
+ ExFreePool(KeyNameBuffer);
+ return Status;
+ }
+
return STATUS_NOT_IMPLEMENTED;
}
VOID
STDCALL
IoRequestDeviceEject(
- IN PDEVICE_OBJECT PhysicalDeviceObject)
+ IN PDEVICE_OBJECT PhysicalDeviceObject
+ )
{
+ UNIMPLEMENTED;
}
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");
+
+ RtlInitUnicodeString(&KeyName,
+ L"CompatibleIDs");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_MULTI_SZ,
+ DeviceNode->CompatibleIDs.Buffer,
+ DeviceNode->CompatibleIDs.MaximumLength);
+
+ RtlInitUnicodeString(&KeyName,
+ L"HardwareID");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_MULTI_SZ,
+ DeviceNode->HardwareIDs.Buffer,
+ DeviceNode->HardwareIDs.MaximumLength);
+
+ /* Set 'DeviceDesc' value */
+ RtlInitUnicodeString(&KeyName,
+ L"DeviceDesc");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_SZ,
+ DeviceNode->DeviceText.Buffer,
+ DeviceNode->DeviceText.MaximumLength);
+
+ /* Set 'LocationInformation' value */
+ DPRINT("LocationInformation: %wZ\n", &DeviceNode->DeviceTextLocation);
+ RtlInitUnicodeString(&KeyName,
+ L"LocationInformation");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_SZ,
+ DeviceNode->DeviceTextLocation.Buffer,
+ DeviceNode->DeviceTextLocation.MaximumLength);
+
+ /* Set 'Capabilities' value */
+ RtlInitUnicodeString(&KeyName,
+ L"Capabilities");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_DWORD,
+ (PVOID)((ULONG_PTR)&DeviceNode->CapabilityFlags + 4),
+ sizeof(ULONG));
+
+ /* Set 'UINumber' value */
+ if (DeviceNode->CapabilityFlags->UINumber != (ULONG)-1)
+ {
+ RtlInitUnicodeString(&KeyName,
+ L"UINumber");
+ Status = NtSetValueKey(InstanceKey,
+ &KeyName,
+ 0,
+ REG_DWORD,
+ &DeviceNode->CapabilityFlags->UINumber,
+ sizeof(ULONG));
+ }
+
+ /* 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->BootResourcesList != NULL)
+ {
+ ResCount = DeviceNode->BootResourcesList->List[0].PartialResourceList.Count;
+ if (ResCount != 0)
+ {
+ ListSize = sizeof(CM_RESOURCE_LIST) +
+ ((ResCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+
+ RtlInitUnicodeString(&KeyName,
+ L"BootConfig");
+ Status = NtSetValueKey(LogConfKey,
+ &KeyName,
+ 0,
+ REG_RESOURCE_LIST,
+ &DeviceNode->BootResourcesList,
+ 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;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
DPRINT("PDO %x\n", DeviceNode->Pdo);
(49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
- IopCreateDeviceKeyPath(KeyBuffer);
+ Status = IopCreateDeviceKeyPath(KeyBuffer,
+ &InstanceKey);
ExFreePool(KeyBuffer);
+
+ if (InstanceKey != NULL)
+ {
+ IopSetDeviceInstanceData(InstanceKey, DeviceNode);
+ NtClose(InstanceKey);
+ }
+
DeviceNode->Flags |= DNF_PROCESSED;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
+
VOID INIT_FUNCTION
PnpInit(VOID)
{
if (!NT_SUCCESS(Status))
{
CPRINT("IoCreateDriverObject() failed\n");
- KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
if (!NT_SUCCESS(Status))
{
CPRINT("IoCreateDevice() failed\n");
- KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode);
if (!NT_SUCCESS(Status))
{
CPRINT("Insufficient resources\n");
- KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;