https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e616a456c0ccce598e0a06...
commit e616a456c0ccce598e0a065004988bea47079463 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sun Apr 22 16:31:53 2018 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Apr 22 16:52:45 2018 +0200
[NTOSKRNL] Minor PnP enhancements.
- For non-PnP devices reported to the PnP manager through the IoReportDetectedDevice() function, store the corresponding service/driver name and (non-)legacy information inside their HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\ entries. - Drivers flagged as "DRVO_BUILTIN_DRIVER" (basically, only those created via a IoCreateDriver() call) have their "Service" name that contain "\Driver", which should be stripped before being used in building e.g. the corresponding "DETECTEDxxx" PnP compatible IDs. CORE-14247
- Use explicit REG_OPTION_NON_VOLATILE flag where needed in the IopCreateDeviceKeyPath() calls. - Save NULL-terminated REG-SZ string properties in the enumeration tree for each device enumerated inside \Enum\Root. - Always use upcased key name for the "LEGACY_***" elements in \Enum\Root. - Add a default "ConfigFlags" value for the legacy elements. - Simplify few parts of code. --- ntoskrnl/io/pnpmgr/pnpmgr.c | 44 +++++++++++++++---------------- ntoskrnl/io/pnpmgr/pnpreport.c | 60 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 25 deletions(-)
diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 3337495ae0..62ad7a253f 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -98,7 +98,7 @@ IopInstallCriticalDevice(PDEVICE_NODE DeviceNode) PWCHAR IdBuffer, OriginalIdBuffer;
/* Open the device instance key */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey); if (Status != STATUS_SUCCESS) return;
@@ -800,7 +800,7 @@ IopStartDevice( IopStartAndEnumerateDevice(DeviceNode);
/* FIX: Should be done in new device instance code */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceHandle); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceHandle); if (!NT_SUCCESS(Status)) goto ByeBye;
@@ -817,7 +817,7 @@ IopStartDevice( goto ByeBye;
RtlInitUnicodeString(&KeyName, L"ActiveService"); - Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length); + Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length + sizeof(UNICODE_NULL)); // }
ByeBye: @@ -873,7 +873,7 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, else DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
- Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey); if (NT_SUCCESS(Status)) { /* Set 'Capabilities' value */ @@ -1067,7 +1067,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
if (!PhysicalDeviceObject) { - FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length; + FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL); FullServiceName.Length = 0; FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); if (!FullServiceName.Buffer) @@ -1078,6 +1078,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1); + RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath); if (!NT_SUCCESS(Status)) @@ -1097,7 +1098,9 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, return Status; }
- Node->ServiceName.Buffer = ExAllocatePool(PagedPool, ServiceName1->Length); + Node->ServiceName.MaximumLength = ServiceName1->Length + sizeof(UNICODE_NULL); + Node->ServiceName.Length = 0; + Node->ServiceName.Buffer = ExAllocatePool(PagedPool, Node->ServiceName.MaximumLength); if (!Node->ServiceName.Buffer) { ZwClose(InstanceHandle); @@ -1106,39 +1109,39 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, return Status; }
- Node->ServiceName.MaximumLength = ServiceName1->Length; - Node->ServiceName.Length = 0; - - RtlAppendUnicodeStringToString(&Node->ServiceName, ServiceName1); + RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
if (ServiceName) { RtlInitUnicodeString(&KeyName, L"Service"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL)); }
if (NT_SUCCESS(Status)) { RtlInitUnicodeString(&KeyName, L"Legacy"); - LegacyValue = 1; Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + + RtlInitUnicodeString(&KeyName, L"ConfigFlags"); + LegacyValue = 0; + ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + if (NT_SUCCESS(Status)) { RtlInitUnicodeString(&KeyName, L"Class"); - - RtlInitUnicodeString(&ClassName, L"LegacyDriver\0"); + RtlInitUnicodeString(&ClassName, L"LegacyDriver"); Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL)); if (NT_SUCCESS(Status)) { RtlInitUnicodeString(&KeyName, L"ClassGUID"); - - RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}\0"); + RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}"); Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL)); if (NT_SUCCESS(Status)) { + // FIXME: Retrieve the real "description" by looking at the "DisplayName" string + // of the corresponding CurrentControlSet\Services\xxx entry for this driver. RtlInitUnicodeString(&KeyName, L"DeviceDesc"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL)); } } @@ -2244,7 +2247,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, /* * Create registry key for the instance id, if it doesn't exist yet */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create the instance key! (Status %lx)\n", Status); @@ -2719,10 +2722,7 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, DeviceCaps.RawDeviceOK) { DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName); - - DeviceNode->ServiceName.Length = 0; - DeviceNode->ServiceName.MaximumLength = 0; - DeviceNode->ServiceName.Buffer = NULL; + RtlInitEmptyUnicodeString(&DeviceNode->ServiceName, NULL, 0); } else if (ClassGUID.Length != 0) { diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 0d6943b927..00b3547cce 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -173,15 +173,17 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, NTSTATUS Status; HANDLE InstanceKey; ULONG RequiredLength; - UNICODE_STRING ValueName, ServiceName; + UNICODE_STRING ValueName, ServiceLongName, ServiceName; WCHAR HardwareId[256]; PWCHAR IfString; ULONG IdLength; + ULONG LegacyValue;
DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n", DeviceObject, DeviceObject ? *DeviceObject : NULL);
- ServiceName = DriverObject->DriverExtension->ServiceKeyName; + ServiceLongName = DriverObject->DriverExtension->ServiceKeyName; + ServiceName = ServiceLongName;
/* If the interface type is unknown, treat it as internal */ if (LegacyBusType == InterfaceTypeUndefined) @@ -194,6 +196,42 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, if (!IfString) return STATUS_INVALID_PARAMETER;
+ /* + * Drivers that have been created via a direct IoCreateDriver() call + * have their ServiceKeyName set to \Driver\DriverName. We need to + * strip everything up to the last path separator and keep what remains. + */ + if (DriverObject->Flags & DRVO_BUILTIN_DRIVER) + { + /* + * Find the last path separator. + * NOTE: Since ServiceName is not necessarily NULL-terminated, + * we cannot use wcsrchr(). + */ + if (ServiceName.Buffer && ServiceName.Length >= sizeof(WCHAR)) + { + ValueName.Length = 1; + ValueName.Buffer = ServiceName.Buffer + (ServiceName.Length / sizeof(WCHAR)) - 1; + + while ((ValueName.Buffer > ServiceName.Buffer) && (*ValueName.Buffer != L'\')) + { + --ValueName.Buffer; + ++ValueName.Length; + } + if (*ValueName.Buffer == L'\') + { + ++ValueName.Buffer; + --ValueName.Length; + } + ValueName.Length *= sizeof(WCHAR); + + /* Shorten the string */ + ServiceName.MaximumLength -= (ServiceName.Length - ValueName.Length); + ServiceName.Length = ValueName.Length; + ServiceName.Buffer = ValueName.Buffer; + } + } + /* We use the caller's PDO if they supplied one */ if (DeviceObject && *DeviceObject) { @@ -218,7 +256,6 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, Pdo, NULL, &DeviceNode); - if (!NT_SUCCESS(Status)) { DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status); @@ -252,6 +289,23 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, if (!NT_SUCCESS(Status)) return Status;
+ /* Save the driver name */ + RtlInitUnicodeString(&ValueName, L"Service"); + Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_SZ, ServiceLongName.Buffer, ServiceLongName.Length + sizeof(UNICODE_NULL)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write the Service name value: 0x%x\n", Status); + } + + /* Report as non-legacy driver */ + RtlInitUnicodeString(&ValueName, L"Legacy"); + LegacyValue = 0; + Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to write the Legacy value: 0x%x\n", Status); + } + /* Add DETECTEDInterfaceType\DriverName */ IdLength = 0; IdLength += swprintf(&HardwareId[IdLength],