diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 9d490e2b482..44283968d0c 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -60,6 +60,11 @@ NTSTATUS IopUpdateResourceMapForPnPDevice( IN PDEVICE_NODE DeviceNode); +NTSTATUS +NTAPI +IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, + OUT PHANDLE Handle); + PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) @@ -141,6 +146,9 @@ IopStartDevice( IO_STACK_LOCATION Stack; ULONG RequiredLength; NTSTATUS Status; + HANDLE InstanceHandle, ControlHandle; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n"); @@ -215,9 +223,32 @@ IopStartDevice( } } + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceHandle); + if (!NT_SUCCESS(Status)) + return Status; + + RtlInitUnicodeString(&KeyName, L"Control"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + InstanceHandle, + NULL); + Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + if (!NT_SUCCESS(Status)) + { + ZwClose(InstanceHandle); + return Status; + } + + RtlInitUnicodeString(&KeyName, L"ActiveService"); + Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length); + if (NT_SUCCESS(Status)) IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + ZwClose(ControlHandle); + ZwClose(InstanceHandle); + return Status; } @@ -372,6 +403,8 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, KIRQL OldIrql; UNICODE_STRING FullServiceName; UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_"); + UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN"); + HANDLE TempHandle; DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n", ParentNode, PhysicalDeviceObject, ServiceName); @@ -384,24 +417,24 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, RtlZeroMemory(Node, sizeof(DEVICE_NODE)); + if (!ServiceName) + ServiceName = &UnknownDeviceName; + if (!PhysicalDeviceObject) { - if (ServiceName) + FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length; + FullServiceName.Length = 0; + FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); + if (!FullServiceName.Buffer) { - FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length; - FullServiceName.Length = 0; - FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); - if (!FullServiceName.Buffer) - { - ExFreePool(Node); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); - RtlAppendUnicodeStringToString(&FullServiceName, ServiceName); + ExFreePool(Node); + return STATUS_INSUFFICIENT_RESOURCES; } - Status = PnpRootCreateDevice(ServiceName ? &FullServiceName : NULL, &PhysicalDeviceObject); + RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); + RtlAppendUnicodeStringToString(&FullServiceName, ServiceName); + + Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject, &Node->InstancePath); if (!NT_SUCCESS(Status)) { DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status); @@ -409,6 +442,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, return Status; } + /* Create the device key for legacy drivers */ + Status = IopCreateDeviceKeyPath(&Node->InstancePath, &TempHandle); + if (NT_SUCCESS(Status)) + ZwClose(TempHandle); + + ExFreePool(FullServiceName.Buffer); + /* This is for drivers passed on the command line to ntoskrnl.exe */ IopDeviceNodeSetFlag(Node, DNF_STARTED); IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER); @@ -873,6 +913,7 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, ULONG ResCount; ULONG ListSize, ResultLength; NTSTATUS Status; + HANDLE ControlHandle; DPRINT("IopSetDeviceInstanceData() called\n"); @@ -946,9 +987,21 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, sizeof(DefaultConfigFlags)); } + /* Create the 'Control' key */ + RtlInitUnicodeString(&KeyName, L"Control"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + InstanceKey, + NULL); + Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + + if (NT_SUCCESS(Status)) + ZwClose(ControlHandle); + DPRINT("IopSetDeviceInstanceData() done\n"); - return STATUS_SUCCESS; + return Status; } BOOLEAN diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpreport.c b/reactos/ntoskrnl/io/pnpmgr/pnpreport.c index 13e74148a83..c75e566b0d4 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpreport.c @@ -161,7 +161,8 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, { /* Create the PDO */ Status = PnpRootCreateDevice(&ServiceName, - &Pdo); + &Pdo, + NULL); if (!NT_SUCCESS(Status)) { DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status); diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index c622cba2e8b..a5fa2a04f0c 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -131,30 +131,25 @@ LocateChildDevice( NTSTATUS PnpRootCreateDevice( IN PUNICODE_STRING ServiceName, - IN PDEVICE_OBJECT *PhysicalDeviceObject) + OUT PDEVICE_OBJECT *PhysicalDeviceObject, + OUT OPTIONAL PUNICODE_STRING FullInstancePath) { PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension; - UNICODE_STRING UnknownServiceName = RTL_CONSTANT_STRING(L"LEGACY_UNKNOWN"); - PUNICODE_STRING LocalServiceName; PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension; WCHAR DevicePath[MAX_PATH + 1]; WCHAR InstancePath[5]; PPNPROOT_DEVICE Device = NULL; NTSTATUS Status; ULONG i; + UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); DeviceExtension = PnpRootDeviceObject->DeviceExtension; KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock); - if (ServiceName) - LocalServiceName = ServiceName; - else - LocalServiceName = &UnknownServiceName; - - DPRINT("Creating a PnP root device for service '%wZ'\n", LocalServiceName); + DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName); /* Search for a free instance ID */ - _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, LocalServiceName); + _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName); for (i = 0; i < 9999; i++) { _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i); @@ -164,7 +159,7 @@ PnpRootCreateDevice( } if (i == 9999) { - DPRINT1("Too much legacy devices reported for service '%wZ'\n", &LocalServiceName); + DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } @@ -189,6 +184,22 @@ PnpRootCreateDevice( goto cleanup; } + if (FullInstancePath) + { + FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length; + FullInstancePath->Length = 0; + FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength); + if (!FullInstancePath->Buffer) + { + Status = STATUS_NO_MEMORY; + goto cleanup; + } + + RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID); + RtlAppendUnicodeStringToString(FullInstancePath, &PathSep); + RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID); + } + /* Initialize a device object */ Status = IoCreateDevice( PnpRootDeviceObject->DriverObject,