-/* $Id: pnpmgr.c,v 1.25 2004/03/18 16:43:56 navaraf 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;
}
{
KIRQL OldIrql;
- assert(PopSystemPowerDeviceNode);
+ if (PopSystemPowerDeviceNode)
+ {
+ KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
+ *DeviceObject = PopSystemPowerDeviceNode->Pdo;
+ KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
- KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql);
- *DeviceObject = PopSystemPowerDeviceNode->Pdo;
- KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
+ return STATUS_SUCCESS;
+ }
- return STATUS_SUCCESS;
+ return STATUS_UNSUCCESSFUL;
}
/**********************************************************************
Node->NextSibling = ParentNode->Child;
if (ParentNode->Child != NULL)
{
- ParentNode->Child->PrevSibling = Node;
+ ParentNode->Child->PrevSibling = Node;
}
ParentNode->Child = Node;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
/* Unlink from parent if it exists */
if ((DeviceNode->Parent) && (DeviceNode->Parent->Child == DeviceNode))
- {
- DeviceNode->Parent->Child = DeviceNode->NextSibling;
- }
+ {
+ DeviceNode->Parent->Child = DeviceNode->NextSibling;
+ }
/* Unlink from sibling list */
if (DeviceNode->PrevSibling)
- {
- DeviceNode->PrevSibling->NextSibling = DeviceNode->NextSibling;
- }
+ {
+ DeviceNode->PrevSibling->NextSibling = DeviceNode->NextSibling;
+ }
if (DeviceNode->NextSibling)
- {
- DeviceNode->NextSibling->PrevSibling = DeviceNode->PrevSibling;
- }
+ {
+ DeviceNode->NextSibling->PrevSibling = DeviceNode->PrevSibling;
+ }
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
RtlFreeUnicodeString(&DeviceNode->ServiceName);
if (DeviceNode->CapabilityFlags)
- {
- ExFreePool(DeviceNode->CapabilityFlags);
- }
+ {
+ ExFreePool(DeviceNode->CapabilityFlags);
+ }
if (DeviceNode->CmResourceList)
- {
- ExFreePool(DeviceNode->CmResourceList);
- }
+ {
+ ExFreePool(DeviceNode->CmResourceList);
+ }
if (DeviceNode->BootResourcesList)
- {
- ExFreePool(DeviceNode->BootResourcesList);
- }
+ {
+ ExFreePool(DeviceNode->BootResourcesList);
+ }
if (DeviceNode->ResourceRequirementsList)
- {
- ExFreePool(DeviceNode->ResourceRequirementsList);
- }
+ {
+ ExFreePool(DeviceNode->ResourceRequirementsList);
+ }
RtlFreeUnicodeString(&DeviceNode->DeviceID);
RtlFreeUnicodeString(&DeviceNode->DeviceTextLocation);
if (DeviceNode->BusInformation)
- {
- ExFreePool(DeviceNode->BusInformation);
- }
+ {
+ ExFreePool(DeviceNode->BusInformation);
+ }
ExFreePool(DeviceNode);
sizeof(Stack->Parameters));
}
- Status = IoCallDriver(TopDeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(
+ Status = IoCallDriver(TopDeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(
&Event,
Executive,
- KernelMode,
- FALSE,
- NULL);
+ KernelMode,
+ FALSE,
+ NULL);
Status = IoStatusBlock->Status;
}
PDEVICE_OBJECT Pdo,
PDEVICE_CAPABILITIES *Capabilities)
{
- IO_STATUS_BLOCK IoStatusBlock;
+ IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_CAPABILITIES Caps;
IO_STACK_LOCATION Stack;
NTSTATUS Status;
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;
}
IO_STACK_LOCATION Stack;
NTSTATUS Status;
PWSTR KeyBuffer;
+ PWSTR Ptr;
+ USHORT Length;
+ USHORT TotalLength;
+ HANDLE InstanceKey = NULL;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
DPRINT("PDO %x\n", DeviceNode->Pdo);
{
RtlInitUnicodeString(
&DeviceNode->DeviceID,
- (LPWSTR)IoStatusBlock.Information);
+ (PWSTR)IoStatusBlock.Information);
/*
* FIXME: Check for valid characters, if there is invalid characters
{
RtlInitUnicodeString(
&DeviceNode->InstanceID,
- (LPWSTR)IoStatusBlock.Information);
+ (PWSTR)IoStatusBlock.Information);
/*
* FIXME: Check for valid characters, if there is invalid characters
RtlInitUnicodeString(&DeviceNode->InstanceID, NULL);
}
- /* FIXME: SEND IRP_QUERY_ID.BusQueryHardwareIDs */
- /* FIXME: SEND IRP_QUERY_ID.BusQueryCompatibleIDs */
+ DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
+
+ Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
+ Status = IopInitiatePnpIrp(
+ DeviceNode->Pdo,
+ &IoStatusBlock,
+ IRP_MN_QUERY_ID,
+ &Stack);
+ if (NT_SUCCESS(Status))
+ {
+ /*
+ * FIXME: Check for valid characters, if there is invalid characters
+ * then bugcheck.
+ */
+ TotalLength = 0;
+ Ptr = (PWSTR)IoStatusBlock.Information;
+ DPRINT("Hardware IDs:\n");
+ while (*Ptr)
+ {
+ DPRINT(" %S\n", Ptr);
+ Length = wcslen(Ptr) + 1;
+
+ Ptr += Length;
+ TotalLength += Length;
+ }
+ 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;
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
+ RtlInitUnicodeString(&DeviceNode->HardwareIDs, NULL);
+ }
+
+ DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
+
+ Stack.Parameters.QueryId.IdType = BusQueryCompatibleIDs;
+ Status = IopInitiatePnpIrp(
+ DeviceNode->Pdo,
+ &IoStatusBlock,
+ IRP_MN_QUERY_ID,
+ &Stack);
+ if (NT_SUCCESS(Status))
+ {
+ /*
+ * FIXME: Check for valid characters, if there is invalid characters
+ * then bugcheck.
+ */
+ TotalLength = 0;
+ Ptr = (PWSTR)IoStatusBlock.Information;
+ DPRINT("Compatible IDs:\n");
+ while (*Ptr)
+ {
+ DPRINT(" %S\n", Ptr);
+ Length = wcslen(Ptr) + 1;
+
+ Ptr += Length;
+ TotalLength += Length;
+ }
+ 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;
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
+ RtlInitUnicodeString(&DeviceNode->CompatibleIDs, NULL);
+ }
Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags);
if (NT_SUCCESS(Status))
{
RtlInitUnicodeString(
&DeviceNode->DeviceText,
- (LPWSTR)IoStatusBlock.Information);
+ (PWSTR)IoStatusBlock.Information);
}
else
{
{
RtlInitUnicodeString(
&DeviceNode->DeviceTextLocation,
- (LPWSTR)IoStatusBlock.Information);
+ (PWSTR)IoStatusBlock.Information);
}
else
{
/*
* Create registry key for the instance id, if it doesn't exist yet
- */
+ */
- KeyBuffer = ExAllocatePool(PagedPool, (49 + DeviceNode->InstancePath.Length) * sizeof(WCHAR));
+ KeyBuffer = ExAllocatePool(
+ PagedPool,
+ (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
- wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
- IopCreateDeviceKeyPath(KeyBuffer);
+ wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
+ Status = IopCreateDeviceKeyPath(KeyBuffer,
+ &InstanceKey);
ExFreePool(KeyBuffer);
+
+ if (InstanceKey != NULL)
+ {
+ IopSetDeviceInstanceData(InstanceKey, DeviceNode);
+ NtClose(InstanceKey);
+ }
+
DeviceNode->Flags |= DNF_PROCESSED;
return STATUS_SUCCESS;
!IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) &&
!IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED))
{
- Status = IopInitializeDeviceNodeService(DeviceNode, BootDrivers);
+ PMODULE_OBJECT ModuleObject;
+ PDRIVER_OBJECT DriverObject;
+
+ Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
if (NT_SUCCESS(Status))
{
- IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
- } else
+ Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject);
+ if (NT_SUCCESS(Status))
+ {
+ /* Attach lower level filter drivers. */
+ IopAttachFilterDrivers(DeviceNode, TRUE);
+ /* Initialize the function driver for the device node */
+ Status = IopInitializeDevice(DeviceNode, DriverObject);
+ if (NT_SUCCESS(Status))
+ {
+ IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
+ /* Attach upper level filter drivers. */
+ IopAttachFilterDrivers(DeviceNode, FALSE);
+ }
+ }
+ }
+ else
{
/*
* Don't disable when trying to load only boot drivers
* Parameters
* DeviceNode
* Top device node to start initializing services.
+ *
* BootDrivers
* When set to TRUE, only drivers marked as boot start will
* be loaded. Otherwise, all drivers will be loaded.
NTSTATUS
IopInvalidateDeviceRelations(
- IN PDEVICE_NODE DeviceNode,
- IN DEVICE_RELATION_TYPE Type,
- IN BOOLEAN BootDriver)
+ IN PDEVICE_NODE DeviceNode,
+ IN DEVICE_RELATION_TYPE Type)
{
DEVICETREE_TRAVERSE_CONTEXT Context;
PDEVICE_RELATIONS DeviceRelations;
IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_NODE ChildDeviceNode;
IO_STACK_LOCATION Stack;
+ BOOL BootDrivers;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING LinkName;
+ HANDLE Handle;
NTSTATUS Status;
ULONG i;
return Status;
}
+ /*
+ * Get the state of the system boot. If the \\SystemRoot link isn't
+ * created yet, we will assume that it's possible to load only boot
+ * drivers.
+ */
+
+ RtlInitUnicodeString(&LinkName, L"\\SystemRoot");
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &LinkName,
+ 0,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(
+ &Handle,
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ 0,
+ 0);
+
+ BootDrivers = NT_SUCCESS(Status) ? FALSE : TRUE;
+
+ NtClose(Handle);
+
/*
* Initialize services for discovered children. Only boot drivers will
* be loaded from boot driver!
*/
- Status = IopInitializePnpServices(DeviceNode, BootDriver);
+ Status = IopInitializePnpServices(DeviceNode, BootDrivers);
if (!NT_SUCCESS(Status))
{
DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status);
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;
- IopRootDeviceNode->DriverObject = IopRootDriverObject;
PnpRootDriverEntry(IopRootDriverObject, NULL);
IopRootDriverObject->DriverExtension->AddDevice(
IopRootDriverObject,