mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[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.
This commit is contained in:
parent
2183e65c17
commit
e616a456c0
2 changed files with 79 additions and 25 deletions
|
@ -98,7 +98,7 @@ IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
|
||||||
PWCHAR IdBuffer, OriginalIdBuffer;
|
PWCHAR IdBuffer, OriginalIdBuffer;
|
||||||
|
|
||||||
/* Open the device instance key */
|
/* Open the device instance key */
|
||||||
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey);
|
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
|
||||||
if (Status != STATUS_SUCCESS)
|
if (Status != STATUS_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -800,7 +800,7 @@ IopStartDevice(
|
||||||
IopStartAndEnumerateDevice(DeviceNode);
|
IopStartAndEnumerateDevice(DeviceNode);
|
||||||
|
|
||||||
/* FIX: Should be done in new device instance code */
|
/* 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))
|
if (!NT_SUCCESS(Status))
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
|
||||||
|
@ -817,7 +817,7 @@ IopStartDevice(
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
|
||||||
RtlInitUnicodeString(&KeyName, L"ActiveService");
|
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:
|
ByeBye:
|
||||||
|
@ -873,7 +873,7 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
else
|
else
|
||||||
DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Set 'Capabilities' value */
|
/* Set 'Capabilities' value */
|
||||||
|
@ -1067,7 +1067,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||||
|
|
||||||
if (!PhysicalDeviceObject)
|
if (!PhysicalDeviceObject)
|
||||||
{
|
{
|
||||||
FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length;
|
FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL);
|
||||||
FullServiceName.Length = 0;
|
FullServiceName.Length = 0;
|
||||||
FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
|
FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
|
||||||
if (!FullServiceName.Buffer)
|
if (!FullServiceName.Buffer)
|
||||||
|
@ -1078,6 +1078,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||||
|
|
||||||
RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
|
RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
|
||||||
RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
|
RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
|
||||||
|
RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
|
||||||
|
|
||||||
Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath);
|
Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1097,7 +1098,9 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||||
return Status;
|
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)
|
if (!Node->ServiceName.Buffer)
|
||||||
{
|
{
|
||||||
ZwClose(InstanceHandle);
|
ZwClose(InstanceHandle);
|
||||||
|
@ -1106,39 +1109,39 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node->ServiceName.MaximumLength = ServiceName1->Length;
|
RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
|
||||||
Node->ServiceName.Length = 0;
|
|
||||||
|
|
||||||
RtlAppendUnicodeStringToString(&Node->ServiceName, ServiceName1);
|
|
||||||
|
|
||||||
if (ServiceName)
|
if (ServiceName)
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&KeyName, L"Service");
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&KeyName, L"Legacy");
|
RtlInitUnicodeString(&KeyName, L"Legacy");
|
||||||
|
|
||||||
LegacyValue = 1;
|
LegacyValue = 1;
|
||||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&KeyName, L"Class");
|
RtlInitUnicodeString(&KeyName, L"Class");
|
||||||
|
RtlInitUnicodeString(&ClassName, L"LegacyDriver");
|
||||||
RtlInitUnicodeString(&ClassName, L"LegacyDriver\0");
|
|
||||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
|
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&KeyName, L"ClassGUID");
|
RtlInitUnicodeString(&KeyName, L"ClassGUID");
|
||||||
|
RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
|
||||||
RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}\0");
|
|
||||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
|
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
|
||||||
if (NT_SUCCESS(Status))
|
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");
|
RtlInitUnicodeString(&KeyName, L"DeviceDesc");
|
||||||
|
|
||||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
|
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
|
* 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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
|
DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
|
||||||
|
@ -2719,10 +2722,7 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode,
|
||||||
DeviceCaps.RawDeviceOK)
|
DeviceCaps.RawDeviceOK)
|
||||||
{
|
{
|
||||||
DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
|
DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
|
||||||
|
RtlInitEmptyUnicodeString(&DeviceNode->ServiceName, NULL, 0);
|
||||||
DeviceNode->ServiceName.Length = 0;
|
|
||||||
DeviceNode->ServiceName.MaximumLength = 0;
|
|
||||||
DeviceNode->ServiceName.Buffer = NULL;
|
|
||||||
}
|
}
|
||||||
else if (ClassGUID.Length != 0)
|
else if (ClassGUID.Length != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,15 +173,17 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE InstanceKey;
|
HANDLE InstanceKey;
|
||||||
ULONG RequiredLength;
|
ULONG RequiredLength;
|
||||||
UNICODE_STRING ValueName, ServiceName;
|
UNICODE_STRING ValueName, ServiceLongName, ServiceName;
|
||||||
WCHAR HardwareId[256];
|
WCHAR HardwareId[256];
|
||||||
PWCHAR IfString;
|
PWCHAR IfString;
|
||||||
ULONG IdLength;
|
ULONG IdLength;
|
||||||
|
ULONG LegacyValue;
|
||||||
|
|
||||||
DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
|
DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
|
||||||
DeviceObject, DeviceObject ? *DeviceObject : NULL);
|
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 the interface type is unknown, treat it as internal */
|
||||||
if (LegacyBusType == InterfaceTypeUndefined)
|
if (LegacyBusType == InterfaceTypeUndefined)
|
||||||
|
@ -194,6 +196,42 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
if (!IfString)
|
if (!IfString)
|
||||||
return STATUS_INVALID_PARAMETER;
|
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 */
|
/* We use the caller's PDO if they supplied one */
|
||||||
if (DeviceObject && *DeviceObject)
|
if (DeviceObject && *DeviceObject)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +256,6 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
Pdo,
|
Pdo,
|
||||||
NULL,
|
NULL,
|
||||||
&DeviceNode);
|
&DeviceNode);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
|
DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
|
||||||
|
@ -252,6 +289,23 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return 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 */
|
/* Add DETECTEDInterfaceType\DriverName */
|
||||||
IdLength = 0;
|
IdLength = 0;
|
||||||
IdLength += swprintf(&HardwareId[IdLength],
|
IdLength += swprintf(&HardwareId[IdLength],
|
||||||
|
|
Loading…
Reference in a new issue