mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NTOS:PNP] Let pnproot only report already detected devices
Ignore devices which have DeviceReported=1 in instance key and not DeviceReported=1 in Control key. CORE-17874
This commit is contained in:
parent
d380e9777c
commit
0358fcf9e4
1 changed files with 145 additions and 26 deletions
|
@ -94,7 +94,7 @@ LocateChildDevice(
|
||||||
IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
|
IN PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension,
|
||||||
IN PCUNICODE_STRING DeviceId,
|
IN PCUNICODE_STRING DeviceId,
|
||||||
IN PCWSTR InstanceId,
|
IN PCWSTR InstanceId,
|
||||||
OUT PPNPROOT_DEVICE* ChildDevice)
|
OUT PPNPROOT_DEVICE* ChildDevice OPTIONAL)
|
||||||
{
|
{
|
||||||
PPNPROOT_DEVICE Device;
|
PPNPROOT_DEVICE Device;
|
||||||
UNICODE_STRING InstanceIdU;
|
UNICODE_STRING InstanceIdU;
|
||||||
|
@ -116,7 +116,8 @@ LocateChildDevice(
|
||||||
RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
|
RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
|
||||||
{
|
{
|
||||||
/* They do, so set the pointer and return success */
|
/* They do, so set the pointer and return success */
|
||||||
*ChildDevice = Device;
|
if (ChildDevice)
|
||||||
|
*ChildDevice = Device;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,26 +262,23 @@ tryagain:
|
||||||
QueryTable,
|
QueryTable,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
|
||||||
{
|
{
|
||||||
for (NextInstance = 0; NextInstance <= 9999; NextInstance++)
|
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
|
||||||
{
|
Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
|
||||||
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
|
if (Status == STATUS_NO_SUCH_DEVICE)
|
||||||
Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, &Device);
|
break;
|
||||||
if (Status == STATUS_NO_SUCH_DEVICE)
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NextInstance > 9999)
|
if (NextInstance > 9999)
|
||||||
{
|
{
|
||||||
DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
|
DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName);
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
|
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance);
|
||||||
Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, &Device);
|
Status = LocateChildDevice(DeviceExtension, &Device->DeviceID, InstancePath, NULL);
|
||||||
if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
|
if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999)
|
||||||
{
|
{
|
||||||
DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
|
DPRINT1("NextInstance value is corrupt! (%lu)\n", NextInstance);
|
||||||
|
@ -554,6 +552,114 @@ cleanup:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
IopShouldProcessDevice(
|
||||||
|
IN HANDLE SubKey,
|
||||||
|
IN PCWSTR InstanceID)
|
||||||
|
{
|
||||||
|
UNICODE_STRING DeviceReportedValue = RTL_CONSTANT_STRING(L"DeviceReported");
|
||||||
|
UNICODE_STRING Control = RTL_CONSTANT_STRING(L"Control");
|
||||||
|
UNICODE_STRING InstanceIDU;
|
||||||
|
PKEY_VALUE_FULL_INFORMATION pKeyValueFullInformation;
|
||||||
|
HANDLE InstanceKey, ControlKey;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
ULONG Size, DeviceReported, ResultLength;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Size = 128;
|
||||||
|
pKeyValueFullInformation = ExAllocatePool(PagedPool, Size);
|
||||||
|
if (!pKeyValueFullInformation)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Open Instance key */
|
||||||
|
RtlInitUnicodeString(&InstanceIDU, InstanceID);
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&InstanceIDU,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
SubKey,
|
||||||
|
NULL);
|
||||||
|
Status = ZwOpenKey(&InstanceKey,
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read 'DeviceReported' Key */
|
||||||
|
Status = ZwQueryValueKey(InstanceKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
|
||||||
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
|
{
|
||||||
|
ZwClose(InstanceKey);
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
DPRINT("No 'DeviceReported' value\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ZwClose(InstanceKey);
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
|
||||||
|
{
|
||||||
|
ZwClose(InstanceKey);
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
|
||||||
|
/* FIXME: Check DeviceReported value? */
|
||||||
|
ASSERT(DeviceReported == 1);
|
||||||
|
|
||||||
|
/* Open Control key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&Control,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
InstanceKey,
|
||||||
|
NULL);
|
||||||
|
Status = ZwOpenKey(&ControlKey,
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&ObjectAttributes);
|
||||||
|
ZwClose(InstanceKey);
|
||||||
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
|
{
|
||||||
|
DPRINT("No 'Control' key\n");
|
||||||
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read 'DeviceReported' Key */
|
||||||
|
Status = ZwQueryValueKey(ControlKey, &DeviceReportedValue, KeyValueFullInformation, pKeyValueFullInformation, Size, &ResultLength);
|
||||||
|
ZwClose(ControlKey);
|
||||||
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
|
{
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
DPRINT("No 'DeviceReported' value\n");
|
||||||
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
if (pKeyValueFullInformation->Type != REG_DWORD || pKeyValueFullInformation->DataLength != sizeof(DeviceReported))
|
||||||
|
{
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
RtlCopyMemory(&DeviceReported, (PVOID)((ULONG_PTR)pKeyValueFullInformation + pKeyValueFullInformation->DataOffset), sizeof(DeviceReported));
|
||||||
|
/* FIXME: Check DeviceReported value? */
|
||||||
|
ASSERT(DeviceReported == 1);
|
||||||
|
|
||||||
|
ExFreePool(pKeyValueFullInformation);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
EnumerateDevices(
|
EnumerateDevices(
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
@ -725,17 +831,30 @@ EnumerateDevices(
|
||||||
RtlAppendUnicodeToString(&DevicePath, REGSTR_KEY_ROOTENUM L"\\");
|
RtlAppendUnicodeToString(&DevicePath, REGSTR_KEY_ROOTENUM L"\\");
|
||||||
RtlAppendUnicodeStringToString(&DevicePath, &SubKeyName);
|
RtlAppendUnicodeStringToString(&DevicePath, &SubKeyName);
|
||||||
DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
|
DPRINT("Found device %wZ\\%S!\n", &DevicePath, SubKeyInfo->Name);
|
||||||
Status = CreateDeviceFromRegistry(DeviceExtension,
|
|
||||||
&DevicePath,
|
|
||||||
SubKeyInfo->Name,
|
|
||||||
SubKeyHandle);
|
|
||||||
|
|
||||||
/* If CreateDeviceFromRegistry didn't take ownership and zero this,
|
Status = IopShouldProcessDevice(SubKeyHandle, SubKeyInfo->Name);
|
||||||
* we need to free it
|
if (NT_SUCCESS(Status))
|
||||||
*/
|
{
|
||||||
RtlFreeUnicodeString(&DevicePath);
|
Status = CreateDeviceFromRegistry(DeviceExtension,
|
||||||
|
&DevicePath,
|
||||||
|
SubKeyInfo->Name,
|
||||||
|
SubKeyHandle);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
/* If CreateDeviceFromRegistry didn't take ownership and zero this,
|
||||||
|
* we need to free it
|
||||||
|
*/
|
||||||
|
RtlFreeUnicodeString(&DevicePath);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Status == STATUS_NO_SUCH_DEVICE)
|
||||||
|
{
|
||||||
|
DPRINT("Skipping device %wZ\\%S (not reported yet)\n", &DevicePath, SubKeyInfo->Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue