mirror of
https://github.com/reactos/reactos.git
synced 2025-06-07 02:10:36 +00:00
[NTOS:PNP] Initialize DeviceDesc and LocationInformation registry fields
for manually reported devices, as it is required by the newdev.dll for installing drivers from INF files CORE-17212 CORE-17398 Co-authored-by: Stanislav Motylkov <x86corez@gmail.com>
This commit is contained in:
parent
880252fd46
commit
0fed07b7e4
4 changed files with 151 additions and 94 deletions
|
@ -753,6 +753,11 @@ PnpRegSzToString(
|
||||||
OUT PUSHORT StringLength OPTIONAL
|
OUT PUSHORT StringLength OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PiSetDevNodeText(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ HANDLE InstanceKey);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialization Routines
|
// Initialization Routines
|
||||||
//
|
//
|
||||||
|
@ -1381,6 +1386,13 @@ PiIrpQueryDeviceRelations(
|
||||||
_In_ PDEVICE_NODE DeviceNode,
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
_In_ DEVICE_RELATION_TYPE Type);
|
_In_ DEVICE_RELATION_TYPE Type);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryDeviceText(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ LCID POINTER_ALIGNMENT LocaleId,
|
||||||
|
_In_ DEVICE_TEXT_TYPE Type,
|
||||||
|
_Out_ PWSTR *DeviceText);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PiIrpQueryPnPDeviceState(
|
PiIrpQueryPnPDeviceState(
|
||||||
_In_ PDEVICE_NODE DeviceNode,
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
|
|
@ -1081,34 +1081,123 @@ IopQueryCompatibleIds(PDEVICE_NODE DeviceNode,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the DeviceNode's DeviceDesc and LocationInformation registry values
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
PiSetDevNodeText(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ HANDLE InstanceKey)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
LCID localeId;
|
||||||
|
|
||||||
|
// Get the Locale ID
|
||||||
|
NTSTATUS status = ZwQueryDefaultLocale(FALSE, &localeId);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwQueryDefaultLocale() failed with status %x\n", status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: write DeviceDesc key if not exists
|
||||||
|
|
||||||
|
UNICODE_STRING valDeviceDesc = RTL_CONSTANT_STRING(L"DeviceDesc");
|
||||||
|
ULONG len;
|
||||||
|
|
||||||
|
status = ZwQueryValueKey(InstanceKey, &valDeviceDesc, KeyValueBasicInformation, NULL, 0, &len);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
PWSTR deviceDesc = NULL;
|
||||||
|
status = PiIrpQueryDeviceText(DeviceNode, localeId, DeviceTextDescription, &deviceDesc);
|
||||||
|
|
||||||
|
if (deviceDesc && deviceDesc[0] != UNICODE_NULL)
|
||||||
|
{
|
||||||
|
status = ZwSetValueKey(InstanceKey,
|
||||||
|
&valDeviceDesc,
|
||||||
|
0,
|
||||||
|
REG_SZ,
|
||||||
|
deviceDesc,
|
||||||
|
((ULONG)wcslen(deviceDesc) + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwSetValueKey() failed (Status %x)\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This key is mandatory, so even if the Irp fails, we still write it
|
||||||
|
UNICODE_STRING unknownDeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
|
||||||
|
DPRINT("Driver didn't return DeviceDesc (status %x)\n", status);
|
||||||
|
|
||||||
|
status = ZwSetValueKey(InstanceKey,
|
||||||
|
&valDeviceDesc,
|
||||||
|
0,
|
||||||
|
REG_SZ,
|
||||||
|
unknownDeviceDesc.Buffer,
|
||||||
|
unknownDeviceDesc.MaximumLength);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwSetValueKey() failed (Status %x)\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceDesc)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(deviceDesc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: LocaltionInformation is overwritten unconditionally
|
||||||
|
|
||||||
|
PWSTR deviceLocationInfo = NULL;
|
||||||
|
status = PiIrpQueryDeviceText(DeviceNode,
|
||||||
|
localeId,
|
||||||
|
DeviceTextLocationInformation,
|
||||||
|
&deviceLocationInfo);
|
||||||
|
|
||||||
|
if (deviceLocationInfo && deviceLocationInfo[0] != UNICODE_NULL)
|
||||||
|
{
|
||||||
|
UNICODE_STRING valLocationInfo = RTL_CONSTANT_STRING(L"LocationInformation");
|
||||||
|
|
||||||
|
status = ZwSetValueKey(InstanceKey,
|
||||||
|
&valLocationInfo,
|
||||||
|
0,
|
||||||
|
REG_SZ,
|
||||||
|
deviceLocationInfo,
|
||||||
|
((ULONG)wcslen(deviceLocationInfo) + 1) * sizeof(WCHAR));
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwSetValueKey() failed (Status %x)\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceLocationInfo)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(deviceLocationInfo, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Driver didn't return LocationInformation (status %x)\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PiInitializeDevNode(
|
PiInitializeDevNode(
|
||||||
_In_ PDEVICE_NODE DeviceNode)
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
PWSTR DeviceDescription;
|
|
||||||
PWSTR LocationInformation;
|
|
||||||
IO_STACK_LOCATION Stack;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG RequiredLength;
|
|
||||||
LCID LocaleId;
|
|
||||||
HANDLE InstanceKey = NULL;
|
HANDLE InstanceKey = NULL;
|
||||||
UNICODE_STRING ValueName;
|
|
||||||
UNICODE_STRING InstancePathU;
|
UNICODE_STRING InstancePathU;
|
||||||
PDEVICE_OBJECT OldDeviceObject;
|
PDEVICE_OBJECT OldDeviceObject;
|
||||||
|
|
||||||
DPRINT("PiProcessNewDevNode(%p)\n", DeviceNode);
|
DPRINT("PiProcessNewDevNode(%p)\n", DeviceNode);
|
||||||
DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
|
DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
|
||||||
|
|
||||||
/* Get Locale ID */
|
|
||||||
Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: For critical errors, cleanup and disable device, but always
|
* FIXME: For critical errors, cleanup and disable device, but always
|
||||||
* return STATUS_SUCCESS.
|
* return STATUS_SUCCESS.
|
||||||
|
@ -1163,86 +1252,8 @@ PiInitializeDevNode(
|
||||||
|
|
||||||
DeviceNode->Flags |= DNF_IDS_QUERIED;
|
DeviceNode->Flags |= DNF_IDS_QUERIED;
|
||||||
|
|
||||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
|
// Set the device's DeviceDesc and LocationInformation fields
|
||||||
|
PiSetDevNodeText(DeviceNode, InstanceKey);
|
||||||
Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
|
|
||||||
Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
|
|
||||||
Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
|
|
||||||
&IoStatusBlock,
|
|
||||||
IRP_MN_QUERY_DEVICE_TEXT,
|
|
||||||
&Stack);
|
|
||||||
DeviceDescription = NT_SUCCESS(Status) ? (PWSTR)IoStatusBlock.Information
|
|
||||||
: NULL;
|
|
||||||
/* This key is mandatory, so even if the Irp fails, we still write it */
|
|
||||||
RtlInitUnicodeString(&ValueName, L"DeviceDesc");
|
|
||||||
if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
||||||
{
|
|
||||||
if (DeviceDescription &&
|
|
||||||
*DeviceDescription != UNICODE_NULL)
|
|
||||||
{
|
|
||||||
/* This key is overriden when a driver is installed. Don't write the
|
|
||||||
* new description if another one already exists */
|
|
||||||
Status = ZwSetValueKey(InstanceKey,
|
|
||||||
&ValueName,
|
|
||||||
0,
|
|
||||||
REG_SZ,
|
|
||||||
DeviceDescription,
|
|
||||||
((ULONG)wcslen(DeviceDescription) + 1) * sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
|
|
||||||
DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
|
|
||||||
|
|
||||||
Status = ZwSetValueKey(InstanceKey,
|
|
||||||
&ValueName,
|
|
||||||
0,
|
|
||||||
REG_SZ,
|
|
||||||
DeviceDesc.Buffer,
|
|
||||||
DeviceDesc.MaximumLength);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceDescription)
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(DeviceDescription, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
|
|
||||||
|
|
||||||
Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
|
|
||||||
Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
|
|
||||||
Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
|
|
||||||
&IoStatusBlock,
|
|
||||||
IRP_MN_QUERY_DEVICE_TEXT,
|
|
||||||
&Stack);
|
|
||||||
if (NT_SUCCESS(Status) && IoStatusBlock.Information)
|
|
||||||
{
|
|
||||||
LocationInformation = (PWSTR)IoStatusBlock.Information;
|
|
||||||
DPRINT("LocationInformation: %S\n", LocationInformation);
|
|
||||||
RtlInitUnicodeString(&ValueName, L"LocationInformation");
|
|
||||||
Status = ZwSetValueKey(InstanceKey,
|
|
||||||
&ValueName,
|
|
||||||
0,
|
|
||||||
REG_SZ,
|
|
||||||
LocationInformation,
|
|
||||||
((ULONG)wcslen(LocationInformation) + 1) * sizeof(WCHAR));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExFreePoolWithTag(LocationInformation, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
|
DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,37 @@ PiIrpQueryDeviceRelations(
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IRP_MN_QUERY_DEVICE_TEXT (0x0C)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryDeviceText(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ LCID POINTER_ALIGNMENT LocaleId,
|
||||||
|
_In_ DEVICE_TEXT_TYPE Type,
|
||||||
|
_Out_ PWSTR *DeviceText)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeUninitialized);
|
||||||
|
|
||||||
|
ULONG_PTR longText;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_QUERY_DEVICE_TEXT,
|
||||||
|
.Parameters.QueryDeviceText.DeviceTextType = Type,
|
||||||
|
.Parameters.QueryDeviceText.LocaleId = LocaleId
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS status;
|
||||||
|
status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longText);
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
*DeviceText = (PVOID)longText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
// IRP_MN_QUERY_PNP_DEVICE_STATE (0x14)
|
// IRP_MN_QUERY_PNP_DEVICE_STATE (0x14)
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PiIrpQueryPnPDeviceState(
|
PiIrpQueryPnPDeviceState(
|
||||||
|
|
|
@ -294,6 +294,9 @@ IoReportDetectedDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the device's DeviceDesc and LocationInformation fields
|
||||||
|
PiSetDevNodeText(DeviceNode, InstanceKey);
|
||||||
|
|
||||||
/* Assign the resources to the device node */
|
/* Assign the resources to the device node */
|
||||||
DeviceNode->BootResources = ResourceList;
|
DeviceNode->BootResources = ResourceList;
|
||||||
DeviceNode->ResourceRequirements = ResourceRequirements;
|
DeviceNode->ResourceRequirements = ResourceRequirements;
|
||||||
|
|
Loading…
Reference in a new issue