mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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
|
||||
);
|
||||
|
||||
VOID
|
||||
PiSetDevNodeText(
|
||||
_In_ PDEVICE_NODE DeviceNode,
|
||||
_In_ HANDLE InstanceKey);
|
||||
|
||||
//
|
||||
// Initialization Routines
|
||||
//
|
||||
|
@ -1381,6 +1386,13 @@ PiIrpQueryDeviceRelations(
|
|||
_In_ PDEVICE_NODE DeviceNode,
|
||||
_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
|
||||
PiIrpQueryPnPDeviceState(
|
||||
_In_ PDEVICE_NODE DeviceNode,
|
||||
|
|
|
@ -1081,34 +1081,123 @@ IopQueryCompatibleIds(PDEVICE_NODE DeviceNode,
|
|||
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
|
||||
NTSTATUS
|
||||
PiInitializeDevNode(
|
||||
_In_ PDEVICE_NODE DeviceNode)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PWSTR DeviceDescription;
|
||||
PWSTR LocationInformation;
|
||||
IO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
ULONG RequiredLength;
|
||||
LCID LocaleId;
|
||||
HANDLE InstanceKey = NULL;
|
||||
UNICODE_STRING ValueName;
|
||||
UNICODE_STRING InstancePathU;
|
||||
PDEVICE_OBJECT OldDeviceObject;
|
||||
|
||||
DPRINT("PiProcessNewDevNode(%p)\n", DeviceNode);
|
||||
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
|
||||
* return STATUS_SUCCESS.
|
||||
|
@ -1163,86 +1252,8 @@ PiInitializeDevNode(
|
|||
|
||||
DeviceNode->Flags |= DNF_IDS_QUERIED;
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
|
||||
|
||||
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);
|
||||
}
|
||||
// Set the device's DeviceDesc and LocationInformation fields
|
||||
PiSetDevNodeText(DeviceNode, InstanceKey);
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
|
||||
|
||||
|
|
|
@ -196,6 +196,37 @@ PiIrpQueryDeviceRelations(
|
|||
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)
|
||||
NTSTATUS
|
||||
PiIrpQueryPnPDeviceState(
|
||||
|
|
|
@ -294,6 +294,9 @@ IoReportDetectedDevice(
|
|||
return Status;
|
||||
}
|
||||
|
||||
// Set the device's DeviceDesc and LocationInformation fields
|
||||
PiSetDevNodeText(DeviceNode, InstanceKey);
|
||||
|
||||
/* Assign the resources to the device node */
|
||||
DeviceNode->BootResources = ResourceList;
|
||||
DeviceNode->ResourceRequirements = ResourceRequirements;
|
||||
|
|
Loading…
Reference in a new issue