Store real parameters registry key in DEVICEMAP\VIDEO
authorHervé Poussineau <hpoussin@reactos.org>
Thu, 1 Jun 2006 21:45:50 +0000 (21:45 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Thu, 1 Jun 2006 21:45:50 +0000 (21:45 +0000)
Use it in win32k when loading and storing settings (SetupDevMode and IntChangeDisplaySettings)

svn path=/trunk/; revision=22169

reactos/drivers/video/videoprt/videoprt.c
reactos/subsystems/win32/win32k/objects/dc.c

index e6c8510..63d5708 100644 (file)
@@ -130,6 +130,94 @@ IntVideoPortDeferredRoutine(
    ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
 }
 
+NTSTATUS
+IntCreateRegistryPath(
+   IN PCUNICODE_STRING DriverRegistryPath,
+   OUT PUNICODE_STRING DeviceRegistryPath)
+{
+   static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
+   static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
+   static WCHAR ControlSet[] = L"CONTROLSET";
+   static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
+   static WCHAR Insert2[] = L"\\Device0";
+   LPWSTR ProfilePath = NULL;
+   BOOLEAN Valid;
+   PWCHAR AfterControlSet;
+
+   Valid = (0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem,
+                          wcslen(RegistryMachineSystem)));
+   {
+      AfterControlSet = DriverRegistryPath->Buffer + wcslen(RegistryMachineSystem);
+      if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet)))
+      {
+         AfterControlSet += wcslen(CurrentControlSet);
+      }
+      else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet)))
+      {
+         AfterControlSet += wcslen(ControlSet);
+         while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet)
+         {
+            AfterControlSet++;
+         }
+         Valid = (L'\\' == *AfterControlSet);
+         AfterControlSet++;
+      }
+      else
+      {
+         Valid = FALSE;
+      }
+   }
+
+   if (Valid)
+   {
+      ProfilePath = ExAllocatePoolWithTag(PagedPool,
+                                          (wcslen(DriverRegistryPath->Buffer) +
+                                           wcslen(Insert1) + wcslen(Insert2) + 1) * sizeof(WCHAR),
+                                          TAG_VIDEO_PORT);
+      if (NULL != ProfilePath)
+      {
+         wcsncpy(ProfilePath, DriverRegistryPath->Buffer, AfterControlSet - DriverRegistryPath->Buffer);
+         wcscpy(ProfilePath + (AfterControlSet - DriverRegistryPath->Buffer), Insert1);
+         wcscat(ProfilePath, AfterControlSet);
+         wcscat(ProfilePath, Insert2);
+
+         Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ProfilePath));
+      }
+      else
+      {
+         Valid = FALSE;
+      }
+   }
+   else
+   {
+      DPRINT1("Unparsable registry path %wZ", DriverRegistryPath);
+   }
+
+   if (Valid)
+   {
+      RtlInitUnicodeString(DeviceRegistryPath, ProfilePath);
+   }
+   else
+   {
+      if (ProfilePath)
+         ExFreePoolWithTag(ProfilePath, TAG_VIDEO_PORT);
+
+      DeviceRegistryPath->Length =
+      DeviceRegistryPath->MaximumLength =
+         DriverRegistryPath->Length + (9 * sizeof(WCHAR));
+      DeviceRegistryPath->Length -= sizeof(WCHAR);
+      DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(
+         NonPagedPool,
+         DeviceRegistryPath->MaximumLength,
+         TAG_VIDEO_PORT);
+      if (!DeviceRegistryPath->Buffer)
+         return STATUS_NO_MEMORY;
+      swprintf(DeviceRegistryPath->Buffer, L"%s\\Device0",
+         DriverRegistryPath->Buffer);
+   }
+   return STATUS_SUCCESS;
+}
+
 NTSTATUS NTAPI
 IntVideoPortCreateAdapterDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
@@ -203,16 +291,20 @@ IntVideoPortCreateAdapterDeviceObject(
    DeviceExtension->FunctionalDeviceObject = *DeviceObject;
    DeviceExtension->DriverExtension = DriverExtension;
 
-   DeviceExtension->RegistryPath.Length =
-   DeviceExtension->RegistryPath.MaximumLength =
-      DriverExtension->RegistryPath.Length + (9 * sizeof(WCHAR));
-   DeviceExtension->RegistryPath.Length -= sizeof(WCHAR);
-   DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(
-      NonPagedPool,
-      DeviceExtension->RegistryPath.MaximumLength,
-      TAG_VIDEO_PORT);
-   swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
-      DriverExtension->RegistryPath.Buffer);
+   /*
+    * Get the registry path associated with this driver.
+    */
+
+   Status = IntCreateRegistryPath(
+      &DriverExtension->RegistryPath,
+      &DeviceExtension->RegistryPath);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("IntCreateRegistryPath() call failed with status 0x%08x\n", Status);
+      IoDeleteDevice(*DeviceObject);
+      *DeviceObject = NULL;
+      return Status;
+   }
 
    if (PhysicalDeviceObject != NULL)
    {
index 384c122..4fa56e2 100644 (file)
@@ -265,14 +265,14 @@ NtGdiCreateCompatibleDC(HDC hDC)
   return hNewDC;
 }
 
-static BOOL FASTCALL
+static BOOLEAN FASTCALL
 GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
 {
   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
   WCHAR DeviceNameBuffer[20];
   NTSTATUS Status;
 
-  swprintf(DeviceNameBuffer, L"\\Device\\Video%d", DisplayNumber);
+  swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber);
   RtlInitUnicodeString(RegistryPath, NULL);
   RtlZeroMemory(QueryTable, sizeof(QueryTable));
   QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
@@ -286,11 +286,11 @@ GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
                                   NULL);
   if (! NT_SUCCESS(Status))
     {
-      DPRINT1("No \\Device\\Video%d value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
+      DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
       return FALSE;
     }
 
-  DPRINT("RegistryPath %S\n", RegistryPath->Buffer);
+  DPRINT("RegistryPath %wZ\n", RegistryPath);
 
   return TRUE;
 }
@@ -381,104 +381,49 @@ DevModeCallback(IN PWSTR ValueName,
 static BOOL FASTCALL
 SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
 {
-  static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
-  static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
-  static WCHAR ControlSet[] = L"CONTROLSET";
-  static WCHAR Insert[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
   UNICODE_STRING RegistryPath;
-  BOOL Valid;
-  PWCHAR AfterControlSet;
-  PWCHAR ProfilePath;
   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
   NTSTATUS Status;
+  BOOLEAN Valid = TRUE;
 
-  if (! GetRegistryPath(&RegistryPath, DisplayNumber))
+  if (!GetRegistryPath(&RegistryPath, DisplayNumber))
     {
       DPRINT("GetRegistryPath failed\n");
       return FALSE;
     }
 
-  Valid = (0 == _wcsnicmp(RegistryPath.Buffer, RegistryMachineSystem,
-                          wcslen(RegistryMachineSystem)));
-  if (Valid)
+  RtlZeroMemory(QueryTable, sizeof(QueryTable));
+  QueryTable[0].QueryRoutine = DevModeCallback;
+  QueryTable[0].Flags = 0;
+  QueryTable[0].Name = NULL;
+  QueryTable[0].EntryContext = NULL;
+  QueryTable[0].DefaultType = REG_NONE;
+  QueryTable[0].DefaultData = NULL;
+  QueryTable[0].DefaultLength = 0;
+
+  Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+                                  RegistryPath.Buffer,
+                                  QueryTable,
+                                  DevMode,
+                                  NULL);
+  if (! NT_SUCCESS(Status))
     {
-      AfterControlSet = RegistryPath.Buffer + wcslen(RegistryMachineSystem);
-      if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet)))
-        {
-          AfterControlSet += wcslen(CurrentControlSet);
-        }
-      else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet)))
-        {
-          AfterControlSet += wcslen(ControlSet);
-          while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet)
-            {
-              AfterControlSet++;
-            }
-          Valid = (L'\\' == *AfterControlSet);
-          AfterControlSet++;
-        }
-      else
-        {
-          Valid = FALSE;
-        }
+      DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n",
+             &RegistryPath, Status);
+      Valid = FALSE;
     }
-
-  if (Valid)
+  else
     {
-      ProfilePath = ExAllocatePoolWithTag(PagedPool,
-                                          (wcslen(RegistryPath.Buffer) +
-                                           wcslen(Insert) + 1) * sizeof(WCHAR),
-                                          TAG_DC);
-      if (NULL != ProfilePath)
-        {
-          wcsncpy(ProfilePath, RegistryPath.Buffer, AfterControlSet - RegistryPath.Buffer);
-          wcscpy(ProfilePath + (AfterControlSet - RegistryPath.Buffer), Insert);
-          wcscat(ProfilePath, AfterControlSet);
-
-          RtlZeroMemory(QueryTable, sizeof(QueryTable));
-          QueryTable[0].QueryRoutine = DevModeCallback;
-          QueryTable[0].Flags = 0;
-          QueryTable[0].Name = NULL;
-          QueryTable[0].EntryContext = NULL;
-          QueryTable[0].DefaultType = REG_NONE;
-          QueryTable[0].DefaultData = NULL;
-          QueryTable[0].DefaultLength = 0;
-
-          Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-                                          ProfilePath,
-                                          QueryTable,
-                                          DevMode,
-                                          NULL);
-          if (! NT_SUCCESS(Status))
-            {
-              DPRINT("RtlQueryRegistryValues for %S failed with status 0x%08x\n",
-                     ProfilePath, Status);
-              Valid = FALSE;
-            }
-          else
-            {
-              DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
-                     DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
-                     DevMode->dmPelsWidth, DevMode->dmPelsHeight);
-              if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
-                  || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
-                {
-                  DPRINT("Not all required devmode members are set\n");
-                  Valid = FALSE;
-                }
-            }
-
-          ExFreePool(ProfilePath);
-        }
-      else
+      DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
+             DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
+             DevMode->dmPelsWidth, DevMode->dmPelsHeight);
+      if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
+          || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
         {
+          DPRINT("Not all required devmode members are set\n");
           Valid = FALSE;
         }
     }
-  else
-    {
-      DPRINT1("Unparsable registry path %S in DEVICEMAP\\VIDEO0", RegistryPath.Buffer);
-    }
 
   RtlFreeUnicodeString(&RegistryPath);
 
@@ -2734,6 +2679,137 @@ IntEnumDisplaySettings(
 
   return TRUE;
 }
+
+static NTSTATUS FASTCALL
+GetVideoDeviceName(
+  OUT PUNICODE_STRING VideoDeviceName,
+  IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */
+{
+  UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\");
+  UNICODE_STRING ObjectName;
+  UNICODE_STRING KernelModeName = { 0, };
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  USHORT LastSlash;
+  ULONG Length;
+  HANDLE LinkHandle = NULL;
+  NTSTATUS Status;
+
+  RtlInitUnicodeString(VideoDeviceName, NULL);
+
+  /* Get device name (DisplayDevice is "\.\xxx") */
+  for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+  {
+    if (DisplayDevice->Buffer[LastSlash - 1] == L'\\')
+      break;
+  }
+
+  if (LastSlash == 0)
+  {
+    DPRINT1("Invalid device name '%wZ'\n", DisplayDevice);
+    Status = STATUS_OBJECT_NAME_INVALID;
+    goto cleanup;
+  }
+  ObjectName = *DisplayDevice;
+  ObjectName.Length -= LastSlash * sizeof(WCHAR);
+  ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+  ObjectName.Buffer += LastSlash;
+
+  /* Create "\??\xxx" (ex: "\??\DISPLAY1") */
+  KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL);
+  KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                KernelModeName.MaximumLength,
+                                                TAG_DC);
+  if (!KernelModeName.Buffer)
+  {
+    Status = STATUS_NO_MEMORY;
+    goto cleanup;
+  }
+  RtlCopyUnicodeString(&KernelModeName, &Prefix);
+  Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
+  if (!NT_SUCCESS(Status))
+    goto cleanup;
+
+  /* Open \??\xxx (ex: "\??\DISPLAY1") */
+  InitializeObjectAttributes(&ObjectAttributes,
+                             &KernelModeName,
+                             OBJ_KERNEL_HANDLE,
+                             NULL,
+                             NULL);
+  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
+                                    GENERIC_READ,
+                                    &ObjectAttributes);
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
+    Status = STATUS_NO_SUCH_DEVICE;
+    goto cleanup;
+  }
+
+  Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length);
+  if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+  {
+    DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
+    Status = STATUS_NO_SUCH_DEVICE;
+    goto cleanup;
+  }
+  VideoDeviceName->MaximumLength = Length;
+  VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool,
+                                                  VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL),
+                                                  TAG_DC);
+  if (!VideoDeviceName->Buffer)
+  {
+    Status = STATUS_NO_MEMORY;
+    goto cleanup;
+  }
+  Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL);
+  VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
+    Status = STATUS_NO_SUCH_DEVICE;
+    goto cleanup;
+  }
+  Status = STATUS_SUCCESS;
+
+cleanup:
+  if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer)
+    ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC);
+  if (KernelModeName.Buffer)
+    ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC);
+  if (LinkHandle)
+    ZwClose(LinkHandle);
+  return Status;
+}
+
+static NTSTATUS FASTCALL
+GetVideoRegistryKey(
+  OUT PUNICODE_STRING RegistryPath,
+  IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */
+{
+  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+  NTSTATUS Status;
+
+  RtlInitUnicodeString(RegistryPath, NULL);
+  RtlZeroMemory(QueryTable, sizeof(QueryTable));
+  QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
+  QueryTable[0].Name = DeviceName->Buffer;
+  QueryTable[0].EntryContext = RegistryPath;
+
+  Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+                                  L"VIDEO",
+                                  QueryTable,
+                                  NULL,
+                                  NULL);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status);
+      return STATUS_NO_SUCH_DEVICE;
+    }
+
+  DPRINT("RegistryPath %wZ\n", RegistryPath);
+  return STATUS_SUCCESS;
+}
+
 LONG
 FASTCALL
 IntChangeDisplaySettings(
@@ -2827,13 +2903,8 @@ IntChangeDisplaySettings(
   if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
   {
 
-    UNICODE_STRING ObjectName;
-    UNICODE_STRING KernelModeName;
-    WCHAR KernelModeNameBuffer[256];
+    UNICODE_STRING DeviceName;
     UNICODE_STRING RegistryKey;
-    WCHAR RegistryKeyBuffer[512];
-    PDEVICE_OBJECT DeviceObject;
-    ULONG LastSlash;
     OBJECT_ATTRIBUTES ObjectAttributes;
     HANDLE DevInstRegKey;
     ULONG NewValue;
@@ -2842,76 +2913,31 @@ IntChangeDisplaySettings(
 
     dwflags &= ~CDS_UPDATEREGISTRY;
 
-    /* Get device name (pDeviceName is "\.\xxx") */
-    for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+    Status = GetVideoDeviceName(&DeviceName, pDeviceName);
+    if (!NT_SUCCESS(Status))
     {
-      if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
-        break;
+      DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status);
+      return DISP_CHANGE_FAILED;
     }
-
-    if (LastSlash == 0) return DISP_CHANGE_RESTART;
-    ObjectName = *pDeviceName;
-    ObjectName.Length -= LastSlash * sizeof(WCHAR);
-    ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
-    ObjectName.Buffer += LastSlash;
-
-    KernelModeName.Length = 0;
-    KernelModeName.MaximumLength = sizeof(KernelModeNameBuffer);
-    KernelModeName.Buffer = KernelModeNameBuffer;
-
-    /* Open \??\xxx (ex: "\??\DISPLAY1") */
-    Status = RtlAppendUnicodeToString(&KernelModeName, L"\\??\\");
-
-    if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
-    Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
-
-    if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
-    Status = ObReferenceObjectByName(
-      &KernelModeName,
-      OBJ_CASE_INSENSITIVE,
-      NULL,
-      0,
-      IoDeviceObjectType,
-      KernelMode,
-      NULL,
-      (PVOID*)&DeviceObject);
-
-    if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
-    /* Get associated driver name (ex: "VBE") */
-    for (LastSlash = DeviceObject->DriverObject->DriverName.Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+    Status = GetVideoRegistryKey(&RegistryKey, &DeviceName);
+    if (!NT_SUCCESS(Status))
     {
-      if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
-        break;
+      DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status);
+      ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
+      return DISP_CHANGE_FAILED;
     }
-
-    if (LastSlash == 0) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
-    ObjectName = DeviceObject->DriverObject->DriverName;
-    ObjectName.Length -= LastSlash * sizeof(WCHAR);
-    ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
-    ObjectName.Buffer += LastSlash;
-
-    RegistryKey.Length = 0;
-    RegistryKey.MaximumLength = sizeof(RegistryKeyBuffer);
-    RegistryKey.Buffer = RegistryKeyBuffer;
-
-    /* Open registry key */
-    Status = RtlAppendUnicodeToString(&RegistryKey,
-      L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\");
-
-    if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
-    Status = RtlAppendUnicodeStringToString(&RegistryKey, &ObjectName);
-
-    if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
-    Status = RtlAppendUnicodeToString(&RegistryKey,
-      L"\\Device0");
-
-    if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+    ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
 
     InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
       OBJ_CASE_INSENSITIVE, NULL, NULL);
     Status = ZwOpenKey(&DevInstRegKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes);
-    ObDereferenceObject(DeviceObject);
-    if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+    if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status);
+      ExFreePoolWithTag(RegistryKey.Buffer, TAG_DC);
+      return DISP_CHANGE_FAILED;
+    }
+    ExFreePoolWithTag(RegistryKey.Buffer, TAG_DC);
 
     /* Update needed fields */
     if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)