X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fntoskrnl%2Fio%2Fpnproot.c;h=d4c24fdc669b21470bbb0fe64d5f7ea11dacfaa4;hp=a934c2eaffc9434bf1ac81cfea942afa3dfebc32;hb=10e6548a78c91c83dc4d7e45c44920c0644f1c50;hpb=49f967d0ed6f9eba6f10735ed80f3d106c82c314 diff --git a/reactos/ntoskrnl/io/pnproot.c b/reactos/ntoskrnl/io/pnproot.c index a934c2eaffc..d4c24fdc669 100644 --- a/reactos/ntoskrnl/io/pnproot.c +++ b/reactos/ntoskrnl/io/pnproot.c @@ -1,21 +1,15 @@ -/* $Id: pnproot.c,v 1.19 2003/12/30 18:52:04 fireball Exp $ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/io/pnproot.c + * PURPOSE: PnP manager root device * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/io/pnpmgr/pnproot.c - * PURPOSE: PnP manager root device - * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * UPDATE HISTORY: - * 16/04/2001 CSH Created + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) */ /* INCLUDES ******************************************************************/ -#include -#include -#include -#include - +#include #define NDEBUG #include @@ -25,7 +19,8 @@ /* DATA **********************************************************************/ -typedef struct _PNPROOT_DEVICE { +typedef struct _PNPROOT_DEVICE +{ // Entry on device list LIST_ENTRY ListEntry; // Physical Device Object of device @@ -38,9 +33,12 @@ typedef struct _PNPROOT_DEVICE { UNICODE_STRING InstanceID; // Device description UNICODE_STRING DeviceDescription; + // Resource requirement list + PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; } PNPROOT_DEVICE, *PPNPROOT_DEVICE; -typedef enum { +typedef enum +{ dsStopped, dsStarted, dsPaused, @@ -49,23 +47,8 @@ typedef enum { } PNPROOT_DEVICE_STATE; -#if defined(__GNUC__) - -typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION -{ - // Pointer to device object, this device extension is associated with - PDEVICE_OBJECT DeviceObject; - // Wether this device extension is for an FDO or PDO - BOOLEAN IsFDO; - // Wether the device is removed - BOOLEAN Removed; - // Current device power state for the device - DEVICE_POWER_STATE DevicePowerState; -} __attribute((packed)) PNPROOT_COMMON_DEVICE_EXTENSION, *PPNPROOT_COMMON_DEVICE_EXTENSION; - -#elif defined(_MSC_VER) - #include + typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION { // Pointer to device object, this device extension is associated with @@ -77,14 +60,7 @@ typedef struct _PNPROOT_COMMON_DEVICE_EXTENSION // Current device power state for the device DEVICE_POWER_STATE DevicePowerState; } PNPROOT_COMMON_DEVICE_EXTENSION, *PPNPROOT_COMMON_DEVICE_EXTENSION; -#include -#else -#error Unknown compiler for structure packing -#endif - - -#if defined(__GNUC__) /* Physical Device Object device extension for a child device */ typedef struct _PNPROOT_PDO_DEVICE_EXTENSION @@ -95,53 +71,13 @@ typedef struct _PNPROOT_PDO_DEVICE_EXTENSION UNICODE_STRING DeviceID; // Instance ID UNICODE_STRING InstanceID; -} __attribute((packed)) PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION; - -#elif defined(_MSC_VER) - -#include -typedef struct _PNPROOT_PDO_DEVICE_EXTENSION -{ - // Common device data - PNPROOT_COMMON_DEVICE_EXTENSION Common; - // Device ID - UNICODE_STRING DeviceID; - // Instance ID - UNICODE_STRING InstanceID; + // Resource requirement list + PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; } PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION; -#include - -#else -#error Unknown compiler for structure packing -#endif - -#if defined(__GNUC__) /* Functional Device Object device extension for the PCI driver device object */ typedef struct _PNPROOT_FDO_DEVICE_EXTENSION -{ - // Common device data - PNPROOT_COMMON_DEVICE_EXTENSION Common; - // Physical Device Object - PDEVICE_OBJECT Pdo; - // Lower device object - PDEVICE_OBJECT Ldo; - // Current state of the driver - PNPROOT_DEVICE_STATE State; - // Namespace device list - LIST_ENTRY DeviceListHead; - // Number of (not removed) devices in device list - ULONG DeviceListCount; - // Lock for namespace device list - // FIXME: Use fast mutex instead? - KSPIN_LOCK DeviceListLock; -} __attribute((packed)) PNPROOT_FDO_DEVICE_EXTENSION, *PPNPROOT_FDO_DEVICE_EXTENSION; - -#elif defined(_MSC_VER) - -#include -typedef struct _PNPROOT_FDO_DEVICE_EXTENSION { // Common device data PNPROOT_COMMON_DEVICE_EXTENSION Common; @@ -159,11 +95,8 @@ typedef struct _PNPROOT_FDO_DEVICE_EXTENSION // FIXME: Use fast mutex instead? KSPIN_LOCK DeviceListLock; } PNPROOT_FDO_DEVICE_EXTENSION, *PPNPROOT_FDO_DEVICE_EXTENSION; -#include -#else -#error Unknown compiler for structure packing -#endif +#include @@ -189,7 +122,7 @@ PnpRootCreateDevice( DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension; - Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE)); + Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT); if (!Device) return STATUS_INSUFFICIENT_RESOURCES; @@ -200,7 +133,7 @@ PnpRootCreateDevice( sizeof(PNPROOT_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_CONTROLLER, - 0, + FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &Device->Pdo); if (!NT_SUCCESS(Status)) { @@ -225,23 +158,21 @@ PnpRootCreateDevice( PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; - if (!IopCreateUnicodeString( + if (!RtlCreateUnicodeString( &PdoDeviceExtension->DeviceID, ENUM_NAME_ROOT \ - L"\\LEGACY_UNKNOWN", - PagedPool)) + L"\\LEGACY_UNKNOWN")) { /* FIXME: */ - DPRINT("IopCreateUnicodeString() failed\n"); + DPRINT("RtlCreateUnicodeString() failed\n"); } - if (!IopCreateUnicodeString( + if (!RtlCreateUnicodeString( &PdoDeviceExtension->InstanceID, - L"0000", - PagedPool)) + L"0000")) { /* FIXME: */ - DPRINT("IopCreateUnicodeString() failed\n"); + DPRINT("RtlCreateUnicodeString() failed\n"); } ExInterlockedInsertTailList( @@ -279,12 +210,11 @@ PdoQueryId( switch (IrpSp->Parameters.QueryId.IdType) { case BusQueryDeviceID: - Status = IopCreateUnicodeString( - &String, - DeviceExtension->DeviceID.Buffer, - PagedPool); + Status = RtlDuplicateUnicodeString(TRUE, + &DeviceExtension->DeviceID, + &String); - DPRINT("DeviceID: %S\n", String.Buffer); + DPRINT("DeviceID: %wZ\n", &String); Irp->IoStatus.Information = (ULONG_PTR)String.Buffer; break; @@ -295,10 +225,9 @@ PdoQueryId( break; case BusQueryInstanceID: - Status = IopCreateUnicodeString( - &String, - DeviceExtension->InstanceID.Buffer, - PagedPool); + Status = RtlDuplicateUnicodeString(TRUE, + &DeviceExtension->InstanceID, + &String); DPRINT("InstanceID: %S\n", String.Buffer); @@ -315,9 +244,94 @@ PdoQueryId( NTSTATUS -PnpRootPdoPnpControl( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) +PdoQueryResources( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PCM_RESOURCE_LIST ResourceList; + ULONG ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); + + ResourceList = ExAllocatePool(PagedPool, ResourceListSize); + if (ResourceList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + ResourceList->Count = 0; + + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + + return STATUS_SUCCESS; +} + + +NTSTATUS +PdoQueryResourceRequirements( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension; + PIO_RESOURCE_REQUIREMENTS_LIST ResourceList; + ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List); + + DPRINT("Called\n"); + + DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (DeviceExtension->ResourceRequirementsList == NULL) + { + /* Create an empty resource list */ + ResourceList = ExAllocatePool(PagedPool, ResourceListSize); + if (ResourceList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory(ResourceList, ResourceListSize); + ResourceList->ListSize = ResourceListSize; + + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + } + else + { + /* Copy existing resource requirement list */ + ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceRequirementsList->ListSize); + if (ResourceList == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlCopyMemory( + ResourceList, + DeviceExtension->ResourceRequirementsList, + DeviceExtension->ResourceRequirementsList->ListSize); + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + } + + return STATUS_SUCCESS; +} + + +static NTSTATUS +PnpRootPdoQueryCapabilities( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; + PDEVICE_CAPABILITIES DeviceCapabilities; + + DPRINT("Called\n"); + + DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities; + + if (DeviceCapabilities->Version != 1) + return STATUS_UNSUCCESSFUL; + + DeviceCapabilities->UniqueID = TRUE; + /* FIXME: Fill other fields */ + + return STATUS_SUCCESS; +} + + /* * FUNCTION: Handle Plug and Play IRPs for the child device * ARGUMENTS: @@ -326,6 +340,10 @@ PnpRootPdoPnpControl( * RETURNS: * Status */ +NTSTATUS +PnpRootPdoPnpControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; @@ -338,65 +356,41 @@ PnpRootPdoPnpControl( switch (IrpSp->MinorFunction) { #if 0 - case IRP_MN_CANCEL_REMOVE_DEVICE: - break; - - case IRP_MN_CANCEL_STOP_DEVICE: - break; - - case IRP_MN_DEVICE_USAGE_NOTIFICATION: - break; - - case IRP_MN_EJECT: - break; - case IRP_MN_QUERY_BUS_INFORMATION: break; - case IRP_MN_QUERY_CAPABILITIES: - break; - case IRP_MN_QUERY_DEVICE_RELATIONS: - /* FIXME: Possibly handle for RemovalRelations */ - break; - - case IRP_MN_QUERY_DEVICE_TEXT: + /* FIXME: Handle for TargetDeviceRelation */ break; #endif + case IRP_MN_QUERY_ID: Status = PdoQueryId(DeviceObject, Irp, IrpSp); break; -#if 0 - case IRP_MN_QUERY_PNP_DEVICE_STATE: - break; - - case IRP_MN_QUERY_REMOVE_DEVICE: - break; case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: + Status = PdoQueryResourceRequirements(DeviceObject, Irp, IrpSp); break; case IRP_MN_QUERY_RESOURCES: + Status = PdoQueryResources(DeviceObject, Irp, IrpSp); break; - case IRP_MN_QUERY_STOP_DEVICE: - break; - - case IRP_MN_REMOVE_DEVICE: - break; - - case IRP_MN_SET_LOCK: + case IRP_MN_QUERY_CAPABILITIES: + Status = PnpRootPdoQueryCapabilities(DeviceObject, Irp, IrpSp); break; case IRP_MN_START_DEVICE: - break; - + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_STOP_DEVICE: - break; - + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + case IRP_MN_REMOVE_DEVICE: case IRP_MN_SURPRISE_REMOVAL: + Status = STATUS_SUCCESS; break; -#endif + default: DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); break; @@ -410,10 +404,7 @@ PnpRootPdoPnpControl( return Status; } -NTSTATUS -PnpRootPdoPowerControl( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) + /* * FUNCTION: Handle power management IRPs for the child device * ARGUMENTS: @@ -422,6 +413,10 @@ PnpRootPdoPowerControl( * RETURNS: * Status */ +NTSTATUS +PnpRootPdoPowerControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; @@ -435,6 +430,7 @@ PnpRootPdoPowerControl( switch (IrpSp->MinorFunction) { default: DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); + Status = STATUS_NOT_IMPLEMENTED; break; } @@ -449,6 +445,96 @@ PnpRootPdoPowerControl( /* Functional Device Object routines */ +static NTSTATUS +PnpRootReadRegistryBinary( + IN PWSTR KeyName, + IN PWSTR ValueKeyName, + OUT PVOID* Buffer) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyNameU; + UNICODE_STRING ValueKeyNameU; + KEY_VALUE_PARTIAL_INFORMATION Size; + PKEY_VALUE_PARTIAL_INFORMATION Data = NULL; + ULONG DataSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION); + HANDLE KeyHandle; + NTSTATUS Status; + + DPRINT("Called\n"); + + RtlInitUnicodeString(&KeyNameU, KeyName); + RtlInitUnicodeString(&ValueKeyNameU, ValueKeyName); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyNameU, + OBJ_CASE_INSENSITIVE, + NULL, /* Root dir */ + NULL); /* Security descriptor */ + Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = ZwQueryValueKey( + KeyHandle, + &ValueKeyNameU, + KeyValuePartialInformation, + &Size, DataSize, + &DataSize); + if (Status != STATUS_BUFFER_OVERFLOW) + { + DPRINT("ZwQueryValueKey() failed (Status 0x%08lx)\n", Status); + ZwClose(KeyHandle); + return Status; + } + + while (Status == STATUS_BUFFER_OVERFLOW) + { + if (Data) + ExFreePoolWithTag(Data, TAG_PNP_ROOT); + Data = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, DataSize, TAG_PNP_ROOT); + if (!Data) + { + DPRINT("ExAllocatePoolWithTag() failed\n", Status); + ZwClose(KeyHandle); + return Status; + } + + Status = ZwQueryValueKey( + KeyHandle, + &ValueKeyNameU, + KeyValuePartialInformation, + Data, DataSize, + &DataSize); + if (NT_SUCCESS(Status)) + { + *Buffer = ExAllocatePoolWithTag(PagedPool, Data->DataLength, TAG_PNP_ROOT); + if (!*Buffer) + { + DPRINT("ExAllocatePoolWithTag() failed\n", Status); + ExFreePoolWithTag(Data, TAG_PNP_ROOT); + ZwClose(KeyHandle); + return Status; + } + + RtlCopyMemory( + *Buffer, + Data->Data, + Data->DataLength); + break; + } + } + + if (Data) + ExFreePoolWithTag(Data, TAG_PNP_ROOT); + ZwClose(KeyHandle); + + return Status; +} + NTSTATUS PnpRootFdoReadDeviceInfo( PPNPROOT_DEVICE Device) @@ -464,7 +550,8 @@ PnpRootFdoReadDeviceInfo( DeviceDesc = &Device->DeviceDescription; - wcscpy(KeyName, ENUM_NAME_ROOT); + wcscpy(KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); + wcscat(KeyName, ENUM_NAME_ROOT); wcscat(KeyName, L"\\"); wcscat(KeyName, Device->ServiceName.Buffer); wcscat(KeyName, L"\\"); @@ -472,6 +559,7 @@ PnpRootFdoReadDeviceInfo( DPRINT("KeyName %S\n", KeyName); + /* 1. Read informations in instance key */ RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlInitUnicodeString(DeviceDesc, NULL); @@ -481,13 +569,13 @@ PnpRootFdoReadDeviceInfo( QueryTable[0].EntryContext = DeviceDesc; Status = RtlQueryRegistryValues( - RTL_REGISTRY_ENUM, + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, KeyName, QueryTable, NULL, NULL); - DPRINT("RtlQueryRegistryValues() returned status %x\n", Status); + DPRINT("RtlQueryRegistryValues() returned status 0x%08lx\n", Status); if (!NT_SUCCESS(Status)) { @@ -496,6 +584,22 @@ PnpRootFdoReadDeviceInfo( DPRINT("Got device description: %S\n", DeviceDesc->Buffer); + /* 2. Read informations in instance key, LogConf subkey */ + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + wcscat(KeyName, L"\\LogConf"); + + Status = PnpRootReadRegistryBinary( + KeyName, + L"BasicConfigVector", + (PVOID*)&Device->ResourceRequirementsList); + + DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status); + + if (!NT_SUCCESS(Status)) + { + /* FIXME: */ + } + return STATUS_SUCCESS; } @@ -505,32 +609,34 @@ PnpRootFdoEnumerateDevices( PDEVICE_OBJECT DeviceObject) { PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; - OBJECT_ATTRIBUTES ObjectAttributes; - PKEY_BASIC_INFORMATION KeyInfo; - UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes, SubKeyAttributes; + PKEY_BASIC_INFORMATION KeyInfo, SubKeyInfo; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" ENUM_NAME_ROOT); + UNICODE_STRING SubKeyName; PPNPROOT_DEVICE Device; WCHAR Buffer[MAX_PATH]; - HANDLE KeyHandle; + HANDLE KeyHandle, SubKeyHandle; ULONG BufferSize; ULONG ResultSize; NTSTATUS Status; - ULONG Index; + ULONG Index1, Index2; DPRINT("Called\n"); DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR); - KeyInfo = ExAllocatePool(PagedPool, BufferSize); + KeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT); if (!KeyInfo) { return STATUS_INSUFFICIENT_RESOURCES; } - - RtlRosInitUnicodeStringFromLiteral( - &KeyName, - L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" \ - ENUM_NAME_ROOT); + SubKeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT); + if (!SubKeyInfo) + { + ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT); + return STATUS_INSUFFICIENT_RESOURCES; + } InitializeObjectAttributes( &ObjectAttributes, @@ -539,95 +645,140 @@ PnpRootFdoEnumerateDevices( NULL, NULL); - Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); + Status = ZwOpenKey(&KeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { - DPRINT("NtOpenKey() failed (Status %x)\n", Status); - ExFreePool(KeyInfo); + DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status); + ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT); + ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT); return Status; } /* FIXME: Disabled due to still using the old method of auto loading drivers e.g. - there are more entries in the list than found in the registry as some + there are more entries in the list than found in the registry as some drivers are passed on the command line */ // DeviceExtension->DeviceListCount = 0; - Index = 0; - do { + /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as + * KeyHandle. We'll first do a first enumeration to have first level keys, + * and an inner one to have the real devices list. + */ + Index1 = 0; + + while (TRUE) + { Status = ZwEnumerateKey( KeyHandle, - Index, + Index1, KeyBasicInformation, KeyInfo, BufferSize, &ResultSize); if (!NT_SUCCESS(Status)) { - DPRINT("ZwEnumerateKey() (Status %x)\n", Status); + DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status); break; } /* Terminate the string */ KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0; - - Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE)); - if (!Device) + + /* Open the key */ + RtlInitUnicodeString(&SubKeyName, KeyInfo->Name); + InitializeObjectAttributes( + &SubKeyAttributes, + &SubKeyName, + 0, /* Attributes */ + KeyHandle, + NULL); /* Security descriptor */ + Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS, &SubKeyAttributes); + if (!NT_SUCCESS(Status)) { - /* FIXME: */ + DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status); break; } - - RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE)); - - if (!IopCreateUnicodeString(&Device->ServiceName, KeyInfo->Name, PagedPool)) + + /* Enumerate the sub-keys */ + Index2 = 0; + while (TRUE) { - /* FIXME: */ - DPRINT("IopCreateUnicodeString() failed\n"); - } + Status = ZwEnumerateKey( + SubKeyHandle, + Index2, + KeyBasicInformation, + SubKeyInfo, + BufferSize, + &ResultSize); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status); + break; + } + + /* Terminate the string */ + SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0; + + Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT); + if (!Device) + { + /* FIXME: */ + DPRINT("ExAllocatePoolWithTag() failed\n"); + break; + } - wcscpy(Buffer, ENUM_NAME_ROOT); - wcscat(Buffer, L"\\"); - wcscat(Buffer, KeyInfo->Name); + RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE)); - if (!IopCreateUnicodeString(&Device->DeviceID, Buffer, PagedPool)) - { - /* FIXME: */ - DPRINT("IopCreateUnicodeString() failed\n"); - } + if (!RtlCreateUnicodeString(&Device->ServiceName, KeyInfo->Name)) + { + /* FIXME: */ + DPRINT("RtlCreateUnicodeString() failed\n"); + } - DPRINT("Got entry: %S\n", Device->DeviceID.Buffer); + wcscpy(Buffer, ENUM_NAME_ROOT); + wcscat(Buffer, L"\\"); + wcscat(Buffer, KeyInfo->Name); - if (!IopCreateUnicodeString( - &Device->InstanceID, - L"0000", - PagedPool)) - { - /* FIXME: */ - DPRINT("IopCreateUnicodeString() failed\n"); - } + if (!RtlCreateUnicodeString(&Device->DeviceID, Buffer)) + { + /* FIXME: */ + DPRINT("RtlCreateUnicodeString() failed\n"); + } - Status = PnpRootFdoReadDeviceInfo(Device); - if (!NT_SUCCESS(Status)) - { - DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status); - /* FIXME: */ - } + DPRINT("Got entry: %S\n", Device->DeviceID.Buffer); - ExInterlockedInsertTailList( - &DeviceExtension->DeviceListHead, - &Device->ListEntry, - &DeviceExtension->DeviceListLock); + if (!RtlCreateUnicodeString( + &Device->InstanceID, + SubKeyInfo->Name)) + { + /* FIXME: */ + DPRINT("RtlCreateUnicodeString() failed\n"); + } - DeviceExtension->DeviceListCount++; + Status = PnpRootFdoReadDeviceInfo(Device); + if (!NT_SUCCESS(Status)) + { + /* FIXME */ + DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n", Status); + } - Index++; - } while (TRUE); + ExInterlockedInsertTailList( + &DeviceExtension->DeviceListHead, + &Device->ListEntry, + &DeviceExtension->DeviceListLock); - DPRINT("Entries found: %d\n", Index); + DeviceExtension->DeviceListCount++; + + Index2++; + } + + ZwClose(SubKeyHandle); + Index1++; + } - NtClose(KeyHandle); + ZwClose(KeyHandle); - ExFreePool(KeyInfo); + ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT); + ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT); return STATUS_SUCCESS; } @@ -642,7 +793,6 @@ PnpRootQueryBusRelations( PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension; PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; PDEVICE_RELATIONS Relations; - PLIST_ENTRY CurrentEntry; PPNPROOT_DEVICE Device; NTSTATUS Status; ULONG Size; @@ -658,12 +808,12 @@ PnpRootQueryBusRelations( if (Irp->IoStatus.Information) { - /* FIXME: Another bus driver has already created a DEVICE_RELATIONS + /* FIXME: Another bus driver has already created a DEVICE_RELATIONS structure so we must merge this structure with our own */ } Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) * - (DeviceExtension->DeviceListCount - 1); + (DeviceExtension->DeviceListCount - 1); Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size); if (!Relations) @@ -672,11 +822,8 @@ PnpRootQueryBusRelations( Relations->Count = DeviceExtension->DeviceListCount; i = 0; - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) + LIST_FOR_EACH(Device,&DeviceExtension->DeviceListHead,PNPROOT_DEVICE, ListEntry) { - Device = CONTAINING_RECORD(CurrentEntry, PNPROOT_DEVICE, ListEntry); - if (!Device->Pdo) { /* Create a physical device object for the @@ -686,7 +833,7 @@ PnpRootQueryBusRelations( sizeof(PNPROOT_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_CONTROLLER, - 0, + FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &Device->Pdo); if (!NT_SUCCESS(Status)) @@ -696,7 +843,7 @@ PnpRootQueryBusRelations( return Status; } - DPRINT("Created PDO %x\n", Device->Pdo); + DPRINT("Created PDO 0x%p\n", Device->Pdo); Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; @@ -714,28 +861,53 @@ PnpRootQueryBusRelations( PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0; - if (!IopCreateUnicodeString( + if (!RtlCreateUnicodeString( &PdoDeviceExtension->DeviceID, - Device->DeviceID.Buffer, - PagedPool)) + Device->DeviceID.Buffer)) { DPRINT("Insufficient resources\n"); /* FIXME: */ } - DPRINT("DeviceID: %S PDO %x\n", - PdoDeviceExtension->DeviceID.Buffer, + DPRINT("DeviceID: %wZ PDO %p\n", + &PdoDeviceExtension->DeviceID, Device->Pdo); - if (!IopCreateUnicodeString( + if (!RtlCreateUnicodeString( &PdoDeviceExtension->InstanceID, - Device->InstanceID.Buffer, - PagedPool)) + Device->InstanceID.Buffer)) { DPRINT("Insufficient resources\n"); /* FIXME: */ } + DPRINT("InstanceID: %wZ PDO %p\n", + &PdoDeviceExtension->InstanceID, + Device->Pdo); + + if (Device->ResourceRequirementsList != NULL) + { + PdoDeviceExtension->ResourceRequirementsList = ExAllocatePoolWithTag( + PagedPool, + Device->ResourceRequirementsList->ListSize, + TAG_PNP_ROOT); + if (PdoDeviceExtension->ResourceRequirementsList) + { + RtlCopyMemory( + PdoDeviceExtension->ResourceRequirementsList, + Device->ResourceRequirementsList, + Device->ResourceRequirementsList->ListSize); + } + else + { + /* FIXME */ + DPRINT("ExAllocatePoolWithTag() failed\n"); + } + } + + DPRINT("ResourceRequirementsList: %p PDO %p\n", + PdoDeviceExtension->ResourceRequirementsList, + Device->Pdo); } /* Reference the physical device object. The PnP manager @@ -745,8 +917,6 @@ PnpRootQueryBusRelations( Relations->Objects[i] = Device->Pdo; i++; - - CurrentEntry = CurrentEntry->Flink; } if (NT_SUCCESS(Status)) @@ -785,11 +955,6 @@ PnpRootQueryDeviceRelations( } -NTSTATUS -STDCALL -PnpRootFdoPnpControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) /* * FUNCTION: Handle Plug and Play IRPs for the root bus device object * ARGUMENTS: @@ -798,6 +963,11 @@ PnpRootFdoPnpControl( * RETURNS: * Status */ +NTSTATUS +STDCALL +PnpRootFdoPnpControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; PIO_STACK_LOCATION IrpSp; @@ -843,11 +1013,6 @@ PnpRootFdoPnpControl( } -NTSTATUS -STDCALL -PnpRootFdoPowerControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) /* * FUNCTION: Handle power management IRPs for the root bus device object * ARGUMENTS: @@ -856,6 +1021,11 @@ PnpRootFdoPowerControl( * RETURNS: * Status */ +NTSTATUS +STDCALL +PnpRootFdoPowerControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; @@ -882,11 +1052,6 @@ PnpRootFdoPowerControl( } -NTSTATUS -STDCALL -PnpRootPnpControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) /* * FUNCTION: Handle Plug and Play IRPs * ARGUMENTS: @@ -895,13 +1060,18 @@ PnpRootPnpControl( * RETURNS: * Status */ +NTSTATUS +STDCALL +PnpRootPnpControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - DPRINT("DeviceObject %x DeviceExtension %x IsFDO %d\n", + DPRINT("DeviceObject 0x%p DeviceExtension 0x%p IsFDO %d\n", DeviceObject, DeviceExtension, DeviceExtension->IsFDO); @@ -916,11 +1086,6 @@ PnpRootPnpControl( } -NTSTATUS -STDCALL -PnpRootPowerControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) /* * FUNCTION: Handle power management IRPs * ARGUMENTS: @@ -929,6 +1094,11 @@ PnpRootPowerControl( * RETURNS: * Status */ +NTSTATUS +STDCALL +PnpRootPowerControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; @@ -965,8 +1135,7 @@ PnpRootAddDevice( TRUE, &PnpRootDeviceObject); if (!NT_SUCCESS(Status)) { - CPRINT("IoCreateDevice() failed with status 0x%X\n", Status); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); } DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension; @@ -982,13 +1151,13 @@ PnpRootAddDevice( PhysicalDeviceObject); if (!PnpRootDeviceObject) { - CPRINT("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject); + KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); } if (!PhysicalDeviceObject) { - CPRINT("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject); + KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); } InitializeListHead(&DeviceExtension->DeviceListHead);