Author: cgutman
Date: Fri Apr 2 05:47:14 2010
New Revision: 46659
URL:
http://svn.reactos.org/svn/reactos?rev=46659&view=rev
Log:
[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
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Fri Apr 2 05:47:14 2010
@@ -60,6 +60,11 @@
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 @@
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,8 +223,31 @@
}
}
+ 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 @@
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,30 +417,37 @@
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)
- {
- ExFreePool(Node);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
- RtlAppendUnicodeStringToString(&FullServiceName, ServiceName);
- }
-
- Status = PnpRootCreateDevice(ServiceName ? &FullServiceName : NULL,
&PhysicalDeviceObject);
+ 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);
+
+ Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject,
&Node->InstancePath);
if (!NT_SUCCESS(Status))
{
DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status);
ExFreePool(Node);
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);
@@ -873,6 +913,7 @@
ULONG ResCount;
ULONG ListSize, ResultLength;
NTSTATUS Status;
+ HANDLE ControlHandle;
DPRINT("IopSetDeviceInstanceData() called\n");
@@ -946,9 +987,21 @@
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
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnprepo…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] Fri Apr 2 05:47:14 2010
@@ -161,7 +161,8 @@
{
/* Create the PDO */
Status = PnpRootCreateDevice(&ServiceName,
- &Pdo);
+ &Pdo,
+ NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status);
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] Fri Apr 2 05:47:14 2010
@@ -131,30 +131,25 @@
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 @@
}
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;
}
@@ -187,6 +182,22 @@
{
Status = STATUS_NO_MEMORY;
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 */