mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in a new issue