[WIN32SS] Do not try to call DevModes when it is NULL (mirror drivers). Patch by...
[reactos.git] / reactos / win32ss / gdi / eng / ldevobj.c
index 4320fe9..c7fd3be 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS Win32k subsystem
  * PURPOSE:          Support for logical devices
- * FILE:             subsystems/win32/win32k/eng/ldevobj.c
+ * FILE:             win32ss/gdi/eng/ldevobj.c
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
@@ -18,7 +18,7 @@ DBG_DEFAULT_CHANNEL(EngLDev);
 /** Globals *******************************************************************/
 
 static HSEMAPHORE ghsemLDEVList;
-static LDEVOBJ *gpldevHead = NULL;
+static LIST_ENTRY gleLdevListHead;
 static LDEVOBJ *gpldevWin32k = NULL;
 
 
@@ -31,6 +31,9 @@ InitLDEVImpl(VOID)
 {
     ULONG cbSize;
 
+    /* Initialize the LDEV list head */
+    InitializeListHead(&gleLdevListHead);
+
     /* Initialize the loader lock */
     ghsemLDEVList = EngCreateSemaphore();
     if (!ghsemLDEVList)
@@ -50,8 +53,8 @@ InitLDEVImpl(VOID)
     }
 
     /* Initialize the LDEVOBJ for win32k */
-    gpldevWin32k->pldevNext = NULL;
-    gpldevWin32k->pldevPrev = NULL;
+    gpldevWin32k->leLink.Flink = NULL;
+    gpldevWin32k->leLink.Blink = NULL;
     gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY;
     gpldevWin32k->cRefs = 1;
     gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION;
@@ -119,6 +122,12 @@ LDEVOBJ_pdmiGetModes(
 
     TRACE("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
 
+    /* Mirror drivers may omit this function */
+    if (!pldev->pfn.GetModes)
+    {
+        return NULL;
+    }
+
     /* Call the driver to get the required size */
     cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
     if (!cbSize)
@@ -186,7 +195,6 @@ LDEVOBJ_bLoadImage(
     Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
                                     pDriverInfo,
                                     sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-
     if (!NT_SUCCESS(Status))
     {
         ERR("Failed to load a GDI driver: '%wZ', Status = 0x%lx\n",
@@ -290,6 +298,7 @@ LDEVOBJ_pvFindImageProcAddress(
     pExportDir = pldev->pGdiDriverInfo->ExportSectionPointer;
     if (!pExportDir)
     {
+        ERR("LDEVOBJ_pvFindImageProcAddress: no export section found\n");
         return NULL;
     }
 
@@ -321,6 +330,7 @@ EngLoadImageEx(
     _In_ ULONG ldevtype)
 {
     WCHAR acwBuffer[MAX_PATH];
+    PLIST_ENTRY pleLink;
     PLDEVOBJ pldev;
     UNICODE_STRING strDriverName;
     SIZE_T cwcLength;
@@ -369,14 +379,17 @@ EngLoadImageEx(
     EngAcquireSemaphore(ghsemLDEVList);
 
     /* Search the List of LDEVS for the driver name */
-    for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
+    for (pleLink = gleLdevListHead.Flink;
+         pleLink != &gleLdevListHead;
+         pleLink = pleLink->Flink)
     {
+        pldev = CONTAINING_RECORD(pleLink, LDEVOBJ, leLink);
+
         /* Check if the ldev is associated with a file */
         if (pldev->pGdiDriverInfo)
         {
-            ERR("Driver Name %wZ\n", &strDriverName);
             /* Check for match (case insensative) */
-            if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
+            if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, TRUE))
             {
                 /* Image found in LDEV list */
                 break;
@@ -385,7 +398,7 @@ EngLoadImageEx(
     }
 
     /* Did we find one? */
-    if (!pldev)
+    if (pleLink == &gleLdevListHead)
     {
         /* No, allocate a new LDEVOBJ */
         pldev = LDEVOBJ_AllocLDEV(ldevtype);
@@ -421,9 +434,7 @@ EngLoadImageEx(
         }
 
         /* Insert the LDEV into the global list */
-        pldev->pldevPrev = NULL;
-        pldev->pldevNext = gpldevHead;
-        gpldevHead = pldev;
+        InsertHeadList(&gleLdevListHead, &pldev->leLink);
     }
 
     /* Increase ref count */
@@ -457,7 +468,7 @@ EngUnloadImage(
     PLDEVOBJ pldev = (PLDEVOBJ)hModule;
 
     /* Make sure the LDEV is in the list */
-    ASSERT(pldev->pldevPrev || pldev->pldevNext);
+    ASSERT((pldev->leLink.Flink != NULL) &&  (pldev->leLink.Blink != NULL));
 
     /* Lock loader */
     EngAcquireSemaphore(ghsemLDEVList);
@@ -469,10 +480,7 @@ EngUnloadImage(
     if (pldev->cRefs == 0)
     {
         /* Remove ldev from the list */
-        if (pldev->pldevPrev)
-            pldev->pldevPrev->pldevNext = pldev->pldevNext;
-        if (pldev->pldevNext)
-            pldev->pldevNext->pldevPrev = pldev->pldevPrev;
+        RemoveEntryList(&pldev->leLink);
 
         /* Unload the image and free the LDEV */
         LDEVOBJ_vUnloadImage(pldev);