mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
[NTOSKRNL]
- Fix certain scenarios in which a device node can have a NULL instance path which causes registry corruption when we try to write registry keys for that device node - Create the 'Control' subkey and add the ActiveService value inside it - Fix a memory leak - TODO: Fill AllocConfig and FilteredConfigVector svn path=/trunk/; revision=46659
This commit is contained in:
parent
623bc96350
commit
b121447744
|
@ -60,6 +60,11 @@ NTSTATUS
|
|||
IopUpdateResourceMapForPnPDevice(
|
||||
IN PDEVICE_NODE DeviceNode);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
|
||||
OUT PHANDLE Handle);
|
||||
|
||||
PDEVICE_NODE
|
||||
FASTCALL
|
||||
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
|
||||
|
@ -141,6 +146,9 @@ IopStartDevice(
|
|||
IO_STACK_LOCATION Stack;
|
||||
ULONG RequiredLength;
|
||||
NTSTATUS Status;
|
||||
HANDLE InstanceHandle, ControlHandle;
|
||||
UNICODE_STRING KeyName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
||||
DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n");
|
||||
|
@ -215,9 +223,32 @@ IopStartDevice(
|
|||
}
|
||||
}
|
||||
|
||||
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
RtlInitUnicodeString(&KeyName, L"Control");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
InstanceHandle,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwClose(InstanceHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&KeyName, L"ActiveService");
|
||||
Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
|
||||
|
||||
ZwClose(ControlHandle);
|
||||
ZwClose(InstanceHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -372,6 +403,8 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
|||
KIRQL OldIrql;
|
||||
UNICODE_STRING FullServiceName;
|
||||
UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
|
||||
UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
|
||||
HANDLE TempHandle;
|
||||
|
||||
DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
|
||||
ParentNode, PhysicalDeviceObject, ServiceName);
|
||||
|
@ -384,24 +417,24 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
|||
|
||||
RtlZeroMemory(Node, sizeof(DEVICE_NODE));
|
||||
|
||||
if (!ServiceName)
|
||||
ServiceName = &UnknownDeviceName;
|
||||
|
||||
if (!PhysicalDeviceObject)
|
||||
{
|
||||
if (ServiceName)
|
||||
FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length;
|
||||
FullServiceName.Length = 0;
|
||||
FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
|
||||
if (!FullServiceName.Buffer)
|
||||
{
|
||||
FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length;
|
||||
FullServiceName.Length = 0;
|
||||
FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
|
||||
if (!FullServiceName.Buffer)
|
||||
{
|
||||
ExFreePool(Node);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
|
||||
RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
|
||||
ExFreePool(Node);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = PnpRootCreateDevice(ServiceName ? &FullServiceName : NULL, &PhysicalDeviceObject);
|
||||
RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
|
||||
RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
|
||||
|
||||
Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject, &Node->InstancePath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status);
|
||||
|
@ -409,6 +442,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Create the device key for legacy drivers */
|
||||
Status = IopCreateDeviceKeyPath(&Node->InstancePath, &TempHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
ZwClose(TempHandle);
|
||||
|
||||
ExFreePool(FullServiceName.Buffer);
|
||||
|
||||
/* This is for drivers passed on the command line to ntoskrnl.exe */
|
||||
IopDeviceNodeSetFlag(Node, DNF_STARTED);
|
||||
IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER);
|
||||
|
@ -873,6 +913,7 @@ IopSetDeviceInstanceData(HANDLE InstanceKey,
|
|||
ULONG ResCount;
|
||||
ULONG ListSize, ResultLength;
|
||||
NTSTATUS Status;
|
||||
HANDLE ControlHandle;
|
||||
|
||||
DPRINT("IopSetDeviceInstanceData() called\n");
|
||||
|
||||
|
@ -946,9 +987,21 @@ IopSetDeviceInstanceData(HANDLE InstanceKey,
|
|||
sizeof(DefaultConfigFlags));
|
||||
}
|
||||
|
||||
/* Create the 'Control' key */
|
||||
RtlInitUnicodeString(&KeyName, L"Control");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
InstanceKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ControlHandle, 0, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
ZwClose(ControlHandle);
|
||||
|
||||
DPRINT("IopSetDeviceInstanceData() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
|
|
@ -161,7 +161,8 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
|||
{
|
||||
/* Create the PDO */
|
||||
Status = PnpRootCreateDevice(&ServiceName,
|
||||
&Pdo);
|
||||
&Pdo,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status);
|
||||
|
|
|
@ -131,30 +131,25 @@ LocateChildDevice(
|
|||
NTSTATUS
|
||||
PnpRootCreateDevice(
|
||||
IN PUNICODE_STRING ServiceName,
|
||||
IN PDEVICE_OBJECT *PhysicalDeviceObject)
|
||||
OUT PDEVICE_OBJECT *PhysicalDeviceObject,
|
||||
OUT OPTIONAL PUNICODE_STRING FullInstancePath)
|
||||
{
|
||||
PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
UNICODE_STRING UnknownServiceName = RTL_CONSTANT_STRING(L"LEGACY_UNKNOWN");
|
||||
PUNICODE_STRING LocalServiceName;
|
||||
PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
WCHAR DevicePath[MAX_PATH + 1];
|
||||
WCHAR InstancePath[5];
|
||||
PPNPROOT_DEVICE Device = NULL;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
|
||||
|
||||
DeviceExtension = PnpRootDeviceObject->DeviceExtension;
|
||||
KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
|
||||
|
||||
if (ServiceName)
|
||||
LocalServiceName = ServiceName;
|
||||
else
|
||||
LocalServiceName = &UnknownServiceName;
|
||||
|
||||
DPRINT("Creating a PnP root device for service '%wZ'\n", LocalServiceName);
|
||||
DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
|
||||
|
||||
/* Search for a free instance ID */
|
||||
_snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, LocalServiceName);
|
||||
_snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName);
|
||||
for (i = 0; i < 9999; i++)
|
||||
{
|
||||
_snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i);
|
||||
|
@ -164,7 +159,7 @@ PnpRootCreateDevice(
|
|||
}
|
||||
if (i == 9999)
|
||||
{
|
||||
DPRINT1("Too much legacy devices reported for service '%wZ'\n", &LocalServiceName);
|
||||
DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName);
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -189,6 +184,22 @@ PnpRootCreateDevice(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (FullInstancePath)
|
||||
{
|
||||
FullInstancePath->MaximumLength = Device->DeviceID.Length + PathSep.Length + Device->InstanceID.Length;
|
||||
FullInstancePath->Length = 0;
|
||||
FullInstancePath->Buffer = ExAllocatePool(PagedPool, FullInstancePath->MaximumLength);
|
||||
if (!FullInstancePath->Buffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
RtlAppendUnicodeStringToString(FullInstancePath, &Device->DeviceID);
|
||||
RtlAppendUnicodeStringToString(FullInstancePath, &PathSep);
|
||||
RtlAppendUnicodeStringToString(FullInstancePath, &Device->InstanceID);
|
||||
}
|
||||
|
||||
/* Initialize a device object */
|
||||
Status = IoCreateDevice(
|
||||
PnpRootDeviceObject->DriverObject,
|
||||
|
|
Loading…
Reference in a new issue