https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e616a456c0ccce598e0a0…
commit e616a456c0ccce598e0a065004988bea47079463
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Apr 22 16:31:53 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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],