[ros-diffs] [cgutman] 46659: [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

cgutman at svn.reactos.org cgutman at svn.reactos.org
Fri Apr 2 05:47:14 CEST 2010


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.c?rev=46659&r1=46658&r2=46659&view=diff
==============================================================================
--- 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/pnpreport.c?rev=46659&r1=46658&r2=46659&view=diff
==============================================================================
--- 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.c?rev=46659&r1=46658&r2=46659&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list