Author: hpoussin
Date: Mon Jun 4 13:15:04 2007
New Revision: 26988
URL:
http://svn.reactos.org/svn/reactos?rev=26988&view=rev
Log:
Rewrite pnproot:
- Don't create multiple devices with the same pnp id (Root\UNKNOWN\0000)
- Use RtlQueryRegistryValues to read multiple registry values
- Keep devices list in memory instead of always reading the registry
- Support
IRP_MN_QUERY_DEVICE_TEXT/IRP_MN_QUERY_ID/IRP_MN_QUERY_BUS_INFORMATION/IRP_MN_FILTER_RESOURCE_REQUIREMENTS
- Better error handling
- ...
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c Mon Jun 4 13:15:04 2007
@@ -5,6 +5,7 @@
* PURPOSE: PnP manager root device
*
* PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
+ * Copyright 2007 Hervé Poussineau (hpoussin(a)reactos.org)
*/
/* INCLUDES ******************************************************************/
@@ -25,19 +26,18 @@
LIST_ENTRY ListEntry;
// Physical Device Object of device
PDEVICE_OBJECT Pdo;
- // Service name
- UNICODE_STRING ServiceName;
// Device ID
UNICODE_STRING DeviceID;
// Instance ID
UNICODE_STRING InstanceID;
// Device description
UNICODE_STRING DeviceDescription;
- // Boot resource list
- PCM_FULL_RESOURCE_DESCRIPTOR BootResourceList;
- SIZE_T BootResourceListSize;
// Resource requirement list
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList;
+ ULONG ResourceRequirementsListSize;
+ // Associated resource list
+ PCM_RESOURCE_LIST ResourceList;
+ ULONG ResourceListSize;
} PNPROOT_DEVICE, *PPNPROOT_DEVICE;
typedef enum
@@ -49,39 +49,26 @@
dsSurpriseRemoved
} PNPROOT_DEVICE_STATE;
-
-#include <pshpack1.h>
-
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;
} PNPROOT_COMMON_DEVICE_EXTENSION, *PPNPROOT_COMMON_DEVICE_EXTENSION;
-
/* Physical Device Object device extension for a child device */
typedef struct _PNPROOT_PDO_DEVICE_EXTENSION
{
// Common device data
PNPROOT_COMMON_DEVICE_EXTENSION Common;
- // Device
- PPNPROOT_DEVICE Device;
+ // Informations about the device
+ PPNPROOT_DEVICE DeviceInfo;
} PNPROOT_PDO_DEVICE_EXTENSION, *PPNPROOT_PDO_DEVICE_EXTENSION;
-
-/* Functional Device Object device extension for the PCI driver device object */
+/* Physical Device Object device extension for the Root bus 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
@@ -91,43 +78,110 @@
// Number of (not removed) devices in device list
ULONG DeviceListCount;
// Lock for namespace device list
- // FIXME: Use fast mutex instead?
- KSPIN_LOCK DeviceListLock;
+ KGUARDED_MUTEX DeviceListLock;
} PNPROOT_FDO_DEVICE_EXTENSION, *PPNPROOT_FDO_DEVICE_EXTENSION;
-#include <poppack.h>
-
-
-
-PDEVICE_OBJECT PnpRootDeviceObject;
-
+typedef struct _BUFFER
+{
+ PVOID *Buffer;
+ PULONG Length;
+} BUFFER, *PBUFFER;
+
+static PDEVICE_OBJECT PnpRootDeviceObject = NULL;
/* FUNCTIONS *****************************************************************/
-/* Physical Device Object routines */
-
+static NTSTATUS
+LocateChildDevice(
+ IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
+ IN PCWSTR DeviceId,
+ IN PCWSTR InstanceId,
+ OUT PPNPROOT_DEVICE* ChildDevice)
+{
+ PPNPROOT_DEVICE Device;
+ UNICODE_STRING DeviceIdU, InstanceIdU;
+
+ RtlInitUnicodeString(&DeviceIdU, DeviceId);
+ RtlInitUnicodeString(&InstanceIdU, InstanceId);
+
+ LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE,
ListEntry)
+ {
+ if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE)
+ && RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
+ {
+ *ChildDevice = Device;
+ return STATUS_SUCCESS;
+ }
+ }
+
+ return STATUS_NO_SUCH_DEVICE;
+}
+
+/* Creates a new PnP device for a legacy driver */
NTSTATUS
PnpRootCreateDevice(
- PUNICODE_STRING ServiceName,
- PDEVICE_OBJECT *PhysicalDeviceObject)
-{
+ IN PUNICODE_STRING ServiceName,
+ IN PDEVICE_OBJECT *PhysicalDeviceObject)
+{
+ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
+ UNICODE_STRING UnknownServiceName = RTL_CONSTANT_STRING(L"UNKNOWN");
+ PUNICODE_STRING LocalServiceName;
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
- PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
- PPNPROOT_DEVICE Device;
+ WCHAR DevicePath[MAX_PATH + 1];
+ WCHAR InstancePath[5];
+ PPNPROOT_DEVICE Device = NULL;
NTSTATUS Status;
-
- /* This function should be obsoleted soon */
-
- DPRINT("Called\n");
-
- DeviceExtension =
(PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
-
- Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE),
TAG_PNP_ROOT);
+ ULONG i;
+
+ DeviceExtension = PnpRootDeviceObject->DeviceExtension;
+ KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
+
+ if (ServiceName)
+ LocalServiceName = ServiceName;
+ else
+ LocalServiceName = &UnknownServiceName;
+
+ DPRINT("Creating a PnP root device for service '%wZ'\n",
LocalServiceName);
+
+ /* Search for a free instance ID */
+ _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\LEGACY_%wZ",
REGSTR_KEY_ROOTENUM, LocalServiceName);
+ for (i = 0; i < 9999; i++)
+ {
+ _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu",
i);
+ Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device);
+ if (Status == STATUS_NO_SUCH_DEVICE)
+ break;
+ }
+ if (i > 9999)
+ {
+ DPRINT1("Too much legacy devices reported for service '%wZ'\n",
&LocalServiceName);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ /* FIXME: save the new device to registry? */
+
+ /* Initialize a PNPROOT_DEVICE structure */
+ Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
if (!Device)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
-
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+ RtlZeroMemory(Device, sizeof(Device));
+ if (!RtlCreateUnicodeString(&Device->DeviceID, DevicePath))
+ {
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+ if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
+ {
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ /* Initialize a device object */
Status = IoCreateDevice(
PnpRootDeviceObject->DriverObject,
sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
@@ -136,564 +190,198 @@
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
&Device->Pdo);
- if (!NT_SUCCESS(Status)) {
- DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
- ExFreePool(Device);
- return Status;
- }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ PdoDeviceExtension =
(PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
+ RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
+ PdoDeviceExtension->Common.IsFDO = FALSE;
+ PdoDeviceExtension->DeviceInfo = Device;
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
- //Device->Pdo->Flags |= DO_POWER_PAGABLE;
-
- PdoDeviceExtension =
(PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
-
- RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
-
- PdoDeviceExtension->Common.IsFDO = FALSE;
-
- PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
-
- PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
-
- ExInterlockedInsertTailList(
+ InsertTailList(
&DeviceExtension->DeviceListHead,
- &Device->ListEntry,
- &DeviceExtension->DeviceListLock);
-
- DeviceExtension->DeviceListCount++;
+ &Device->ListEntry);
+ DeviceExtension->DeviceListCount++;
*PhysicalDeviceObject = Device->Pdo;
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-PdoQueryId(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-{
- PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
- UNICODE_STRING String;
- NTSTATUS Status;
-
- DPRINT("Called\n");
-
- DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-// Irp->IoStatus.Information = 0;
-
+ DPRINT("Created PDO %p (%wZ\\%wZ)\n", *PhysicalDeviceObject,
&Device->DeviceID, &Device->InstanceID);
+ Device = NULL;
Status = STATUS_SUCCESS;
- RtlInitUnicodeString(&String, NULL);
-
- switch (IrpSp->Parameters.QueryId.IdType) {
- case BusQueryDeviceID:
- if (DeviceExtension->Device)
- Status = RtlDuplicateUnicodeString(TRUE,
- &DeviceExtension->Device->DeviceID,
- &String);
- else
- Status = RtlCreateUnicodeString(&String, ENUM_NAME_ROOT
L"\\LEGACY_UNKNOWN");
-
- DPRINT("DeviceID: %wZ\n", &String);
-
- Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
- break;
-
- case BusQueryHardwareIDs:
- case BusQueryCompatibleIDs:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- case BusQueryInstanceID:
- if (DeviceExtension->Device)
- Status = RtlDuplicateUnicodeString(TRUE,
- &DeviceExtension->Device->InstanceID,
- &String);
- else
- Status = RtlCreateUnicodeString(&String, L"0000");
-
- DPRINT("InstanceID: %S\n", String.Buffer);
-
- Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
- break;
-
- case BusQueryDeviceSerialNumber:
- default:
- Status = STATUS_NOT_IMPLEMENTED;
- }
-
+cleanup:
+ KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
+ if (Device)
+ {
+ if (Device->Pdo)
+ IoDeleteDevice(Device->Pdo);
+ RtlFreeUnicodeString(&Device->DeviceID);
+ RtlFreeUnicodeString(&Device->InstanceID);
+ ExFreePoolWithTag(Device, TAG_PNP_ROOT);
+ }
return Status;
}
-
-NTSTATUS
-PdoQueryResources(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-{
- PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
- PCM_RESOURCE_LIST ResourceList;
- ULONG ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
-
- DPRINT("Called\n");
-
- DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (!DeviceExtension->Device || DeviceExtension->Device->BootResourceList ==
NULL)
- {
- /* Create an empty resource list */
- ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
- if (ResourceList == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- ResourceList->Count = 0;
-
- Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
- }
- else
- {
- /* Copy existing resource list */
- ResourceList = ExAllocatePool(PagedPool,
- FIELD_OFFSET(CM_RESOURCE_LIST, List) +
DeviceExtension->Device->BootResourceListSize);
- if (ResourceList == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- ResourceList->Count = 1;
- RtlCopyMemory(
- &ResourceList->List,
- DeviceExtension->Device->BootResourceList,
- DeviceExtension->Device->BootResourceListSize);
- 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->Device ||
DeviceExtension->Device->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->Device->ResourceRequirementsList->ListSize);
- if (ResourceList == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlCopyMemory(
- ResourceList,
- DeviceExtension->Device->ResourceRequirementsList,
- DeviceExtension->Device->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)
+static NTSTATUS STDCALL
+ForwardIrpAndWaitCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ if (Irp->PendingReturned)
+ KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static NTSTATUS
+ForwardIrpAndWait(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ ASSERT(((PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
+ LowerDevice =
((PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
+
+ ASSERT(LowerDevice);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+
+ DPRINT("Calling lower device %p [%wZ]\n", LowerDevice,
&LowerDevice->DriverObject->DriverName);
+ IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ if (NT_SUCCESS(Status))
+ Status = Irp->IoStatus.Status;
+ }
+
+ return Status;
+}
+
+static NTSTATUS NTAPI
+QueryStringCallback(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext)
+{
+ PUNICODE_STRING String = (PUNICODE_STRING)EntryContext;
+
+ if (ValueType != REG_SZ || ValueLength == 0 || ValueLength % sizeof(WCHAR) != 0)
+ return STATUS_SUCCESS;
+
+ String->Buffer = ExAllocatePoolWithTag(PagedPool, ValueLength, TAG_PNP_ROOT);
+ if (String->Buffer == NULL)
+ return STATUS_NO_MEMORY;
+ String->Length = String->MaximumLength = ValueLength;
+ RtlCopyMemory(String->Buffer, ValueData, ValueLength);
+ if (ValueLength > 0 && String->Buffer[ValueLength / sizeof(WCHAR) - 1] ==
L'\0')
+ String->Length -= sizeof(WCHAR);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS NTAPI
+QueryBinaryValueCallback(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext)
+{
+ PBUFFER Buffer = (PBUFFER)EntryContext;
+ PVOID BinaryValue;
+
+ if (ValueLength == 0)
+ {
+ *Buffer->Buffer = NULL;
+ return STATUS_SUCCESS;
+ }
+
+ BinaryValue = ExAllocatePoolWithTag(PagedPool, ValueLength, TAG_PNP_ROOT);
+ if (BinaryValue == NULL)
+ return STATUS_NO_MEMORY;
+ RtlCopyMemory(BinaryValue, ValueData, ValueLength);
+ *Buffer->Buffer = BinaryValue;
+ if (Buffer->Length) *Buffer->Length = ValueLength;
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+EnumerateDevices(
+ IN PDEVICE_OBJECT DeviceObject)
{
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_CAPABILITIES DeviceCapabilities;
-
- DPRINT("Called\n");
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PKEY_BASIC_INFORMATION KeyInfo = NULL, SubKeyInfo = NULL;
+ UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\"
REGSTR_PATH_SYSTEMENUM "\\" REGSTR_KEY_ROOTENUM);
+ UNICODE_STRING SubKeyName;
+ WCHAR DevicePath[MAX_PATH + 1];
+ RTL_QUERY_REGISTRY_TABLE QueryTable[4];
+ PPNPROOT_DEVICE Device = NULL;
+ HANDLE KeyHandle = INVALID_HANDLE_VALUE;
+ HANDLE SubKeyHandle = INVALID_HANDLE_VALUE;
+ HANDLE DeviceKeyHandle = INVALID_HANDLE_VALUE;
+ ULONG BufferSize;
+ ULONG ResultSize;
+ ULONG Index1, Index2;
+ BUFFER Buffer1, Buffer2;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ DPRINT("EnumerateDevices(FDO %p)\n", DeviceObject);
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:
- * DeviceObject = Pointer to physical device object of the child device
- * Irp = Pointer to IRP that should be handled
- * RETURNS:
- * Status
- */
-NTSTATUS
-PnpRootPdoPnpControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
-
- DPRINT("Called\n");
-
- Status = Irp->IoStatus.Status;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpSp->MinorFunction) {
-#if 0
- case IRP_MN_QUERY_BUS_INFORMATION:
- break;
-
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- /* FIXME: Handle for TargetDeviceRelation */
- break;
-#endif
-
- case IRP_MN_QUERY_ID:
- Status = PdoQueryId(DeviceObject, Irp, IrpSp);
- 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_CAPABILITIES:
- Status = PnpRootPdoQueryCapabilities(DeviceObject, Irp, IrpSp);
- break;
-
- case IRP_MN_START_DEVICE:
- case IRP_MN_QUERY_STOP_DEVICE:
- case IRP_MN_CANCEL_STOP_DEVICE:
- case IRP_MN_STOP_DEVICE:
- 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;
-
- default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
- break;
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- DPRINT("Leaving. Status 0x%X\n", Status);
-
- return Status;
-}
-
-
-/*
- * FUNCTION: Handle power management IRPs for the child device
- * ARGUMENTS:
- * DeviceObject = Pointer to physical device object of the child device
- * Irp = Pointer to IRP that should be handled
- * RETURNS:
- * Status
- */
-NTSTATUS
-PnpRootPdoPowerControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
-
- DPRINT("Called\n");
-
- Status = Irp->IoStatus.Status;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpSp->MinorFunction) {
- default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- DPRINT("Leaving. Status 0x%X\n", Status);
-
- return Status;
-}
-
-
-/* Functional Device Object routines */
-
-static NTSTATUS
-PnpRootReadRegistryBinary(
- IN PWSTR KeyName,
- IN PWSTR ValueKeyName,
- OUT PVOID* Buffer,
- OUT SIZE_T* BufferSize OPTIONAL)
-{
- 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);
-
+ KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
+
+ BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH + 1) * sizeof(WCHAR);
+ KeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
+ if (!KeyInfo)
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+ SubKeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
+ if (!SubKeyInfo)
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
InitializeObjectAttributes(
&ObjectAttributes,
- &KeyNameU,
+ &KeyName,
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_NO_MEMORY;
- }
-
- Status = ZwQueryValueKey(
- KeyHandle,
- &ValueKeyNameU,
- KeyValuePartialInformation,
- Data, DataSize,
- &DataSize);
- if (NT_SUCCESS(Status))
- {
- *Buffer = ExAllocatePoolWithTag(PagedPool, Data->DataLength, TAG_PNP_ROOT);
- if (BufferSize) *BufferSize = Data->DataLength;
- if (!*Buffer)
- {
- DPRINT("ExAllocatePoolWithTag() failed\n", Status);
- ExFreePoolWithTag(Data, TAG_PNP_ROOT);
- ZwClose(KeyHandle);
- return STATUS_NO_MEMORY;
- }
-
- RtlCopyMemory(
- *Buffer,
- Data->Data,
- Data->DataLength);
- break;
- }
- }
-
- if (Data)
- ExFreePoolWithTag(Data, TAG_PNP_ROOT);
- ZwClose(KeyHandle);
-
- return Status;
-}
-
-NTSTATUS
-PnpRootFdoReadDeviceInfo(
- PPNPROOT_DEVICE Device)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- PUNICODE_STRING DeviceDesc;
- WCHAR KeyName[MAX_PATH];
- NTSTATUS Status;
-
- DPRINT("Called\n");
-
- /* Retrieve configuration from Enum key */
-
- DeviceDesc = &Device->DeviceDescription;
-
- wcscpy(KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
- wcscat(KeyName, ENUM_NAME_ROOT);
- wcscat(KeyName, L"\\");
- wcscat(KeyName, Device->ServiceName.Buffer);
- wcscat(KeyName, L"\\");
- wcscat(KeyName, Device->InstanceID.Buffer);
-
- DPRINT("KeyName %S\n", KeyName);
-
- /* 1. Read informations in instance key */
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
-
- RtlInitUnicodeString(DeviceDesc, NULL);
-
- QueryTable[0].Name = L"DeviceDesc";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].EntryContext = DeviceDesc;
-
- Status = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- KeyName,
- QueryTable,
NULL,
NULL);
- DPRINT("RtlQueryRegistryValues() returned status 0x%08lx\n", Status);
-
- if (!NT_SUCCESS(Status))
- {
- Device->DeviceDescription.Buffer = NULL;
- }
-
- 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,
- NULL);
-
- DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status);
-
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: */
- }
-
- Status = PnpRootReadRegistryBinary(
- KeyName,
- L"BootConfig",
- (PVOID*)&Device->BootResourceList,
- &Device->BootResourceListSize);
-
- DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status);
-
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: */
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-PnpRootFdoEnumerateDevices(
- PDEVICE_OBJECT DeviceObject)
-{
- PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
- 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, SubKeyHandle;
- ULONG BufferSize;
- ULONG ResultSize;
- NTSTATUS Status;
- ULONG Index1, Index2;
-
- DPRINT("Called\n");
-
- DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
- KeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
- if (!KeyInfo)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- SubKeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
- if (!SubKeyInfo)
- {
- ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- InitializeObjectAttributes(
- &ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
Status = ZwOpenKey(&KeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- 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
- drivers are passed on the command line */
-// DeviceExtension->DeviceListCount = 0;
+ DPRINT("ZwOpenKey(%wZ) failed with status 0x%08lx\n", &KeyName,
Status);
+ goto cleanup;
+ }
/* 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(
@@ -703,30 +391,35 @@
KeyInfo,
BufferSize,
&ResultSize);
- if (!NT_SUCCESS(Status))
+ if (Status == STATUS_NO_MORE_ENTRIES)
{
- DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
- break;
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
+ goto cleanup;
}
/* Terminate the string */
KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
-
+
/* Open the key */
RtlInitUnicodeString(&SubKeyName, KeyInfo->Name);
InitializeObjectAttributes(
- &SubKeyAttributes,
+ &ObjectAttributes,
&SubKeyName,
0, /* Attributes */
KeyHandle,
NULL); /* Security descriptor */
- Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS,
&SubKeyAttributes);
+ Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
+ DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
break;
}
-
+
/* Enumerate the sub-keys */
Index2 = 0;
while (TRUE)
@@ -738,125 +431,190 @@
SubKeyInfo,
BufferSize,
&ResultSize);
- if (!NT_SUCCESS(Status))
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ break;
+ else if (!NT_SUCCESS(Status))
{
- DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
+ DPRINT("ZwEnumerateKey() failed with 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)
+
+ _snwprintf(
+ DevicePath,
+ sizeof(DevicePath) / sizeof(WCHAR),
+ L"%s\\%s", REGSTR_KEY_ROOTENUM, KeyInfo->Name);
+ DPRINT("Found device %S\\%s!\n", DevicePath, SubKeyInfo->Name);
+ if (LocateChildDevice(DeviceExtension, DevicePath, SubKeyInfo->Name,
&Device) == STATUS_NO_SUCH_DEVICE)
{
- /* FIXME: */
- DPRINT("ExAllocatePoolWithTag() failed\n");
- break;
+ /* Create a PPNPROOT_DEVICE object, and add if in the list of known devices */
+ Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool,
sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
+ if (!Device)
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+ RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
+
+ /* Fill device ID and instance ID */
+ if (!RtlCreateUnicodeString(&Device->DeviceID, DevicePath))
+ {
+ DPRINT("RtlCreateUnicodeString() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ if (!RtlCreateUnicodeString(&Device->InstanceID, SubKeyInfo->Name))
+ {
+ DPRINT("RtlCreateUnicodeString() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+
+ /* Open registry key to fill other informations */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &Device->InstanceID,
+ 0, /* Attributes */
+ SubKeyHandle,
+ NULL); /* Security descriptor */
+ Status = ZwOpenKey(&DeviceKeyHandle, KEY_READ, &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ break;
+ }
+
+ /* Fill other informations */
+ Buffer1.Buffer = (PVOID *)&Device->ResourceRequirementsList;
+ Buffer1.Length = NULL;
+ Buffer2.Buffer = (PVOID *)&Device->ResourceList;
+ Buffer2.Length = &Device->ResourceListSize;
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
+ QueryTable[0].QueryRoutine = QueryStringCallback;
+ QueryTable[0].Name = L"DeviceDesc";
+ QueryTable[0].EntryContext = &Device->DeviceDescription;
+ QueryTable[1].Flags = RTL_QUERY_REGISTRY_SUBKEY;
+ QueryTable[1].Name = L"LogConf";
+ QueryTable[2].QueryRoutine = QueryBinaryValueCallback;
+ QueryTable[2].Name = L"BasicConfigVector";
+ QueryTable[2].EntryContext = &Buffer1;
+ QueryTable[2].QueryRoutine = QueryBinaryValueCallback;
+ QueryTable[2].Name = L"BootConfig";
+ QueryTable[2].EntryContext = &Buffer2;
+
+ Status = RtlQueryRegistryValues(
+ RTL_REGISTRY_HANDLE,
+ (PCWSTR)DeviceKeyHandle,
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlQueryRegistryValues() failed with status 0x%08lx\n",
Status);
+ break;
+ }
+
+ ZwClose(DeviceKeyHandle);
+ DeviceKeyHandle = INVALID_HANDLE_VALUE;
+
+ /* Insert the newly created device into the list */
+ InsertTailList(
+ &DeviceExtension->DeviceListHead,
+ &Device->ListEntry);
+ DeviceExtension->DeviceListCount++;
+ Device = NULL;
}
- RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));
-
- if (!RtlCreateUnicodeString(&Device->ServiceName, KeyInfo->Name))
- {
- /* FIXME: */
- DPRINT("RtlCreateUnicodeString() failed\n");
- }
-
- wcscpy(Buffer, ENUM_NAME_ROOT);
- wcscat(Buffer, L"\\");
- wcscat(Buffer, KeyInfo->Name);
-
- if (!RtlCreateUnicodeString(&Device->DeviceID, Buffer))
- {
- /* FIXME: */
- DPRINT("RtlCreateUnicodeString() failed\n");
- }
-
- DPRINT("Got entry: %S\n", Device->DeviceID.Buffer);
-
- if (!RtlCreateUnicodeString(
- &Device->InstanceID,
- SubKeyInfo->Name))
- {
- /* FIXME: */
- DPRINT("RtlCreateUnicodeString() failed\n");
- }
-
- Status = PnpRootFdoReadDeviceInfo(Device);
- if (!NT_SUCCESS(Status))
- {
- /* FIXME */
- DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n",
Status);
- }
-
- ExInterlockedInsertTailList(
- &DeviceExtension->DeviceListHead,
- &Device->ListEntry,
- &DeviceExtension->DeviceListLock);
-
- DeviceExtension->DeviceListCount++;
-
Index2++;
}
-
+
ZwClose(SubKeyHandle);
+ SubKeyHandle = INVALID_HANDLE_VALUE;
Index1++;
}
- ZwClose(KeyHandle);
-
+cleanup:
+ if (Device)
+ {
+ /* We have a device that has not been added to device list. We need to clean it up
*/
+ /* FIXME */
+ ExFreePoolWithTag(Device, TAG_PNP_ROOT);
+ }
+ if (DeviceKeyHandle != INVALID_HANDLE_VALUE)
+ ZwClose(DeviceKeyHandle);
+ if (SubKeyHandle != INVALID_HANDLE_VALUE)
+ ZwClose(SubKeyHandle);
+ if (KeyHandle != INVALID_HANDLE_VALUE)
+ ZwClose(KeyHandle);
ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-PnpRootQueryBusRelations(
+ KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
+ return Status;
+}
+
+/* FUNCTION: Handle IRP_MN_QUERY_DEVICE_RELATIONS IRPs for the root bus device object
+ * ARGUMENTS:
+ * DeviceObject = Pointer to functional device object of the root bus driver
+ * Irp = Pointer to IRP that should be handled
+ * RETURNS:
+ * Status
+ */
+static NTSTATUS
+PnpRootQueryDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION IrpSp)
+ IN PIRP Irp)
{
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_RELATIONS Relations;
- PPNPROOT_DEVICE Device;
+ PDEVICE_RELATIONS Relations = NULL, OtherRelations =
(PDEVICE_RELATIONS)Irp->IoStatus.Information;
+ PPNPROOT_DEVICE Device = NULL;
+ ULONG Size;
NTSTATUS Status;
- ULONG Size;
- ULONG i;
-
- DPRINT("Called\n");
-
- Status = PnpRootFdoEnumerateDevices(DeviceObject);
+
+ DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
+
+ Status = EnumerateDevices(DeviceObject);
if (!NT_SUCCESS(Status))
+ {
+ DPRINT("EnumerateDevices() failed with status 0x%08lx\n", Status);
return Status;
+ }
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- if (Irp->IoStatus.Information)
- {
- /* 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);
-
+ Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) *
DeviceExtension->DeviceListCount;
+ if (OtherRelations)
+ {
+ /* Another bus driver has already created a DEVICE_RELATIONS
+ * structure so we must merge this structure with our own */
+
+ Size += sizeof(PDEVICE_OBJECT) * OtherRelations->Count;
+ }
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
if (!Relations)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Relations->Count = DeviceExtension->DeviceListCount;
-
- i = 0;
- LIST_FOR_EACH(Device,&DeviceExtension->DeviceListHead,PNPROOT_DEVICE, ListEntry)
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ goto cleanup;
+ }
+ RtlZeroMemory(Relations, Size);
+ if (OtherRelations)
+ {
+ Relations->Count = OtherRelations->Count;
+ RtlCopyMemory(Relations->Objects, OtherRelations->Objects,
sizeof(PDEVICE_OBJECT) * OtherRelations->Count);
+ }
+
+ KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
+ LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE,
ListEntry)
{
if (!Device->Pdo)
{
/* Create a physical device object for the
- device as it does not already have one */
+ * device as it does not already have one */
Status = IoCreateDevice(
DeviceObject->DriverObject,
sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
@@ -867,88 +625,45 @@
&Device->Pdo);
if (!NT_SUCCESS(Status))
{
- DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
- ExFreePool(Relations);
- return Status;
+ DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
+ break;
}
- DPRINT("Created PDO 0x%p\n", Device->Pdo);
+ PdoDeviceExtension =
(PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
+ RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
+ PdoDeviceExtension->Common.IsFDO = FALSE;
+ PdoDeviceExtension->DeviceInfo = Device;
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
- //Device->Pdo->Flags |= DO_POWER_PAGABLE;
-
- PdoDeviceExtension =
(PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
-
- RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));
-
- PdoDeviceExtension->Common.IsFDO = FALSE;
-
- PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
-
- PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
-
- PdoDeviceExtension->Device = Device;
-
- DPRINT("DeviceID: %wZ PDO %p\n",
- &PdoDeviceExtension->Device->DeviceID,
- Device->Pdo);
-
- DPRINT("InstanceID: %wZ PDO %p\n",
- &PdoDeviceExtension->Device->InstanceID,
- Device->Pdo);
-
- DPRINT("ResourceRequirementsList: %p PDO %p\n",
- PdoDeviceExtension->Device->ResourceRequirementsList,
- Device->Pdo);
}
/* Reference the physical device object. The PnP manager
will dereference it again when it is no longer needed */
ObReferenceObject(Device->Pdo);
- Relations->Objects[i] = Device->Pdo;
-
- i++;
- }
-
- if (NT_SUCCESS(Status))
- {
- Irp->IoStatus.Information = (ULONG_PTR)Relations;
- }
- else
- {
- Irp->IoStatus.Information = 0;
+ Relations->Objects[Relations->Count++] = Device->Pdo;
+ }
+ KeReleaseGuardedMutex(&DeviceExtension->DeviceListLock);
+
+ Irp->IoStatus.Information = (ULONG_PTR)Relations;
+
+cleanup:
+ if (!NT_SUCCESS(Status))
+ {
+ if (OtherRelations)
+ ExFreePool(OtherRelations);
+ if (Relations)
+ ExFreePool(Relations);
+ if (Device && Device->Pdo)
+ {
+ IoDeleteDevice(Device->Pdo);
+ Device->Pdo = NULL;
+ }
}
return Status;
}
-
-
-NTSTATUS
-PnpRootQueryDeviceRelations(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION IrpSp)
-{
- NTSTATUS Status;
-
- DPRINT("Called\n");
-
- switch (IrpSp->Parameters.QueryDeviceRelations.Type) {
- case BusRelations:
- Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
- break;
-
- default:
- Status = STATUS_NOT_IMPLEMENTED;
- }
-
- return Status;
-}
-
/*
* FUNCTION: Handle Plug and Play IRPs for the root bus device object
@@ -958,8 +673,7 @@
* RETURNS:
* Status
*/
-NTSTATUS
-STDCALL
+static NTSTATUS
PnpRootFdoPnpControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
@@ -968,84 +682,417 @@
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
- DPRINT("Called\n");
-
DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
Status = Irp->IoStatus.Status;
-
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- switch (IrpSp->MinorFunction) {
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
- break;
-
- case IRP_MN_START_DEVICE:
- DeviceExtension->State = dsStarted;
- Status = STATUS_SUCCESS;
- break;
-
- case IRP_MN_STOP_DEVICE:
- /* Root device cannot be stopped */
- Status = STATUS_UNSUCCESSFUL;
- break;
-
- default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- if (Status != STATUS_PENDING) {
+ switch (IrpSp->MinorFunction)
+ {
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
+ Status = PnpRootQueryDeviceRelations(DeviceObject, Irp);
+ break;
+
+ case IRP_MN_START_DEVICE:
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ Status = ForwardIrpAndWait(DeviceObject, Irp);
+ if (NT_SUCCESS(Status))
+ DeviceExtension->State = dsStarted;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_STOP_DEVICE:
+ DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
+ /* Root device cannot be stopped */
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+
+ default:
+ DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n",
IrpSp->MinorFunction);
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ if (Status != STATUS_PENDING)
+ {
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- DPRINT("Leaving. Status 0x%X\n", Status);
-
return Status;
}
+static NTSTATUS
+PdoQueryDeviceRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ //PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_RELATIONS Relations;
+ DEVICE_RELATION_TYPE RelationType;
+ NTSTATUS Status = Irp->IoStatus.Status;
+
+ //DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ RelationType = IrpSp->Parameters.QueryDeviceRelations.Type;
+
+ switch (RelationType)
+ {
+ /* FIXME: remove */
+ case BusRelations:
+ {
+ if (IoGetAttachedDevice(DeviceObject) != DeviceObject)
+ {
+ /* We're not alone in the stack */
+ PDEVICE_NODE DeviceNode;
+ DeviceNode =
IopGetDeviceNode(IopGetDeviceNode(DeviceObject)->PhysicalDeviceObject);
+ DPRINT1("Device stack for '%wZ' (%wZ) is misbehaving ; shouldn't
receive IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n",
+ &DeviceNode->InstancePath, &DeviceNode->ServiceName);
+ }
+ break;
+ }
+
+ case TargetDeviceRelation:
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS /
TargetDeviceRelation\n");
+ Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
+ if (!Relations)
+ {
+ DPRINT("ExAllocatePoolWithTag() failed\n");
+ Status = STATUS_NO_MEMORY;
+ }
+ else
+ {
+ ObReferenceObject(DeviceObject);
+ Relations->Count = 1;
+ Relations->Objects[0] = DeviceObject;
+ Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = (ULONG_PTR)Relations;
+ }
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / unknown relation type
0x%lx\n", RelationType);
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+PdoQueryCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_CAPABILITIES DeviceCapabilities;
+
+ DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
+
+ if (DeviceCapabilities->Version != 1)
+ return STATUS_REVISION_MISMATCH;
+
+ DeviceCapabilities->UniqueID = TRUE;
+ /* FIXME: Fill other fields */
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+PdoQueryResources(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
+ PCM_RESOURCE_LIST ResourceList;
+
+ DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (DeviceExtension->DeviceInfo->ResourceList == NULL)
+ {
+ /* Create an empty resource list */
+ ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
+ if (!ResourceList)
+ return STATUS_NO_MEMORY;
+
+ ResourceList->Count = 0;
+
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+ }
+ else
+ {
+ /* Copy existing resource requirement list */
+ ResourceList = ExAllocatePool(
+ PagedPool,
+ FIELD_OFFSET(CM_RESOURCE_LIST, List) +
DeviceExtension->DeviceInfo->ResourceListSize);
+ if (!ResourceList)
+ return STATUS_NO_MEMORY;
+
+ ResourceList->Count = 1;
+ RtlCopyMemory(
+ &ResourceList->List,
+ DeviceExtension->DeviceInfo->ResourceList,
+ DeviceExtension->DeviceInfo->ResourceListSize);
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+PdoQueryResourceRequirements(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
+ PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
+ ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
+
+ DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (DeviceExtension->DeviceInfo->ResourceRequirementsList == NULL)
+ {
+ /* Create an empty resource list */
+ ResourceList = ExAllocatePool(PagedPool, ResourceListSize);
+ if (!ResourceList)
+ return STATUS_NO_MEMORY;
+
+ RtlZeroMemory(ResourceList, ResourceListSize);
+ ResourceList->ListSize = ResourceListSize;
+
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+ }
+ else
+ {
+ /* Copy existing resource requirement list */
+ ResourceList = ExAllocatePool(PagedPool,
DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
+ if (!ResourceList)
+ return STATUS_NO_MEMORY;
+
+ RtlCopyMemory(
+ ResourceList,
+ DeviceExtension->DeviceInfo->ResourceRequirementsList,
+ DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize);
+ Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+PdoQueryDeviceText(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
+ DEVICE_TEXT_TYPE DeviceTextType;
+ NTSTATUS Status = Irp->IoStatus.Status;
+
+ DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceTextType = IrpSp->Parameters.QueryDeviceText.DeviceTextType;
+
+ switch (DeviceTextType)
+ {
+ case DeviceTextDescription:
+ {
+ UNICODE_STRING String;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
+
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+ &DeviceExtension->DeviceInfo->DeviceDescription,
+ &String);
+ Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
+ break;
+ }
+
+ case DeviceTextLocationInformation:
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT /
DeviceTextLocationInformation\n");
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown query id type
0x%lx\n", DeviceTextType);
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+PdoQueryId(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
+ BUS_QUERY_ID_TYPE IdType;
+ NTSTATUS Status = Irp->IoStatus.Status;
+
+ DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ IdType = IrpSp->Parameters.QueryId.IdType;
+
+ switch (IdType)
+ {
+ case BusQueryDeviceID:
+ {
+ UNICODE_STRING String;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+ &DeviceExtension->DeviceInfo->DeviceID,
+ &String);
+ Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
+ break;
+ }
+
+ case BusQueryHardwareIDs:
+ case BusQueryCompatibleIDs:
+ {
+ /* Optional, do nothing */
+ break;
+ }
+
+ case BusQueryInstanceID:
+ {
+ UNICODE_STRING String;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+ &DeviceExtension->DeviceInfo->InstanceID,
+ &String);
+ Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n",
IdType);
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+PdoQueryBusInformation(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PPNP_BUS_INFORMATION BusInfo;
+ NTSTATUS Status;
+
+ BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePoolWithTag(PagedPool,
sizeof(PNP_BUS_INFORMATION), TAG_PNP_ROOT);
+ if (!BusInfo)
+ Status = STATUS_NO_MEMORY;
+ else
+ {
+ RtlCopyMemory(
+ &BusInfo->BusTypeGuid,
+ &GUID_BUS_TYPE_INTERNAL,
+ sizeof(BusInfo->BusTypeGuid));
+ BusInfo->LegacyBusType = PNPBus;
+ /* We're the only root bus enumerator on the computer */
+ BusInfo->BusNumber = 0;
+ Irp->IoStatus.Information = (ULONG_PTR)BusInfo;
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
+}
/*
- * FUNCTION: Handle power management IRPs for the root bus device object
+ * FUNCTION: Handle Plug and Play IRPs for the child device
* ARGUMENTS:
- * DeviceObject = Pointer to functional device object of the root bus driver
+ * DeviceObject = Pointer to physical device object of the child device
* Irp = Pointer to IRP that should be handled
* RETURNS:
* Status
*/
-NTSTATUS
-STDCALL
-PnpRootFdoPowerControl(
+static NTSTATUS
+PnpRootPdoPnpControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
- DPRINT("Called\n");
-
+ DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Status = Irp->IoStatus.Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- switch (IrpSp->MinorFunction) {
- default:
- DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- if (Status != STATUS_PENDING) {
+ switch (IrpSp->MinorFunction)
+ {
+ case IRP_MN_START_DEVICE: /* 0x00 */
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
+ Status = PdoQueryDeviceRelations(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
+ Status = PdoQueryCapabilities(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_QUERY_RESOURCES: /* 0x0a */
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
+ Status = PdoQueryResources(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+ Status = PdoQueryResourceRequirements(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+ Status = PdoQueryDeviceText(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
+ DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+ break;
+
+ case IRP_MN_QUERY_ID: /* 0x13 */
+ Status = PdoQueryId(DeviceObject, Irp, IrpSp);
+ break;
+
+ case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
+ Status = PdoQueryBusInformation(DeviceObject, Irp, IrpSp);
+ break;
+
+ default:
+ DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n",
IrpSp->MinorFunction);
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ if (Status != STATUS_PENDING)
+ {
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- DPRINT("Leaving. Status 0x%X\n", Status);
-
return Status;
}
-
/*
* FUNCTION: Handle Plug and Play IRPs
@@ -1055,8 +1102,7 @@
* RETURNS:
* Status
*/
-NTSTATUS
-STDCALL
+static NTSTATUS NTAPI
PnpRootPnpControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
@@ -1066,49 +1112,13 @@
DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- DPRINT("DeviceObject 0x%p DeviceExtension 0x%p IsFDO %d\n",
- DeviceObject,
- DeviceExtension,
- DeviceExtension->IsFDO);
-
- if (DeviceExtension->IsFDO) {
+ if (DeviceExtension->IsFDO)
Status = PnpRootFdoPnpControl(DeviceObject, Irp);
- } else {
+ else
Status = PnpRootPdoPnpControl(DeviceObject, Irp);
- }
return Status;
}
-
-
-/*
- * FUNCTION: Handle power management IRPs
- * ARGUMENTS:
- * DeviceObject = Pointer to PDO or FDO
- * Irp = Pointer to IRP that should be handled
- * RETURNS:
- * Status
- */
-NTSTATUS
-STDCALL
-PnpRootPowerControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
-
- DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceExtension->IsFDO) {
- Status = PnpRootFdoPowerControl(DeviceObject, Irp);
- } else {
- Status = PnpRootPdoPowerControl(DeviceObject, Irp);
- }
-
- return Status;
-}
-
NTSTATUS
STDCALL
@@ -1119,7 +1129,14 @@
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
- DPRINT("Called\n");
+ DPRINT("PnpRootAddDevice(DriverObject %p, Pdo %p)\n", DriverObject,
PhysicalDeviceObject);
+
+ if (!PhysicalDeviceObject)
+ {
+ DPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
Status = IoCreateDevice(
DriverObject,
@@ -1129,59 +1146,50 @@
FILE_DEVICE_SECURE_OPEN,
TRUE,
&PnpRootDeviceObject);
- if (!NT_SUCCESS(Status)) {
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
+ DPRINT("Created FDO %p\n", PnpRootDeviceObject);
DeviceExtension =
(PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;
-
RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));
DeviceExtension->Common.IsFDO = TRUE;
-
DeviceExtension->State = dsStopped;
-
- DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(
+ InitializeListHead(&DeviceExtension->DeviceListHead);
+ DeviceExtension->DeviceListCount = 0;
+ KeInitializeGuardedMutex(&DeviceExtension->DeviceListLock);
+
+ Status = IoAttachDeviceToDeviceStackSafe(
PnpRootDeviceObject,
- PhysicalDeviceObject);
-
- if (!PnpRootDeviceObject) {
- CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject);
+ PhysicalDeviceObject,
+ &DeviceExtension->Ldo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n",
Status);
KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
- if (!PhysicalDeviceObject) {
- CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
-
- InitializeListHead(&DeviceExtension->DeviceListHead);
-
- DeviceExtension->DeviceListCount = 0;
-
- KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
-
PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;
-
DPRINT("Done AddDevice()\n");
return STATUS_SUCCESS;
}
-
-NTSTATUS
-STDCALL
+NTSTATUS NTAPI
PnpRootDriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
- DPRINT("Called\n");
+ DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath);
+
+ DriverObject->DriverExtension->AddDevice = PnpRootAddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
- DriverObject->MajorFunction[IRP_MJ_POWER] = PnpRootPowerControl;
- DriverObject->DriverExtension->AddDevice = PnpRootAddDevice;
+ //DriverObject->MajorFunction[IRP_MJ_POWER] = PnpRootPowerControl;
return STATUS_SUCCESS;
}