[ros-diffs] [tkreuzer] 56003: [WIN32K] - Check if required driver functions are available in LDEVOBJ_bLoadDriver - Unload the image in EngLoadImageEx instead of in LDEVOBJ_bLoadDriver - Implement PDEVOBJ_vDest...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Sun Mar 4 18:47:10 UTC 2012


Author: tkreuzer
Date: Sun Mar  4 18:47:09 2012
New Revision: 56003

URL: http://svn.reactos.org/svn/reactos?rev=56003&view=rev
Log:
[WIN32K]
- Check if required driver functions are available in LDEVOBJ_bLoadDriver
- Unload the image in EngLoadImageEx instead of in LDEVOBJ_bLoadDriver
- Implement PDEVOBJ_vDestroyPDEV and call if from PDEVOBJ_vRelease
- Check for failure in PDEVOBJ_bEnablePDEV
- Implement PDEVOBJ_CreatePDEV, which does the common PDEV creation tasks for display and font drivers

Modified:
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/ldevobj.c
    branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/pdevobj.c

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/ldevobj.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/ldevobj.c?rev=56003&r1=56002&r2=56003&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/ldevobj.c [iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/ldevobj.c [iso-8859-1] Sun Mar  4 18:47:09 2012
@@ -250,9 +250,6 @@
     if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
     {
         DPRINT1("DrvEnableDriver failed\n");
-
-        /* Unload the image. */
-        LDEVOBJ_vUnloadImage(pldev);
         return FALSE;
     }
 
@@ -263,6 +260,44 @@
     for (i = 0; i < ded.c; i++)
     {
         pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
+    }
+
+    /* Check if the neccessary functions are there */
+    if ((!pldev->pfn.EnablePDEV) ||
+        (!pldev->pfn.CompletePDEV) ||
+        (!pldev->pfn.UnloadFontFile))
+    {
+        DPRINT1("Missing function for gdi driver\n");
+        return FALSE;
+    }
+
+    if (pldev->ldevtype == LDEV_DEVICE_DISPLAY)
+    {
+        if ((!pldev->pfn.AssertMode) ||
+            (!pldev->pfn.EnableSurface) ||
+            (!pldev->pfn.DisableSurface) ||
+            (!pldev->pfn.DisableDriver) ||
+            (!pldev->pfn.DisablePDEV) ||
+            (!pldev->pfn.GetModes))
+        {
+            DPRINT1("Missing function for display driver\n");
+            return FALSE;
+        }
+    }
+    else if (pldev->ldevtype == LDEV_FONT)
+    {
+        if ((!pldev->pfn.LoadFontFile) ||
+            (!pldev->pfn.QueryAdvanceWidths) || // ?
+            (!pldev->pfn.QueryFont) ||
+            (!pldev->pfn.QueryFontCaps) || // ?
+            (!pldev->pfn.QueryFontData) ||
+            (!pldev->pfn.QueryFontFile) ||
+            (!pldev->pfn.QueryFontTree) ||
+            (!pldev->pfn.UnloadFontFile))
+        {
+            DPRINT1("Missing function for font driver\n");
+            return FALSE;
+        }
     }
 
     /* Return success. */
@@ -356,10 +391,7 @@
     RtlAppendUnicodeToString(&strDriverName, pwsz);
 
     /* MSDN says "The driver must include this suffix in the pwszDriver string."
-       But in fact it's optional.
-
-       ms win32k EngLoadImageEx loading .sys file without append .dll
-    */
+       But in fact it's optional. */
     if ( (_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) &&
          (_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0) )
     {
@@ -399,9 +431,9 @@
         /* Load the image */
         if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
         {
+            DPRINT1("LDEVOBJ_bLoadImage failed\n");
             LDEVOBJ_vFreeLDEV(pldev);
             pldev = NULL;
-            DPRINT1("LDEVOBJ_bLoadImage failed\n");
             goto leave;
         }
 
@@ -412,6 +444,9 @@
             if (!LDEVOBJ_bLoadDriver(pldev))
             {
                 DPRINT1("LDEVOBJ_bLoadDriver failed\n");
+
+                /* Unload the image. */
+                LDEVOBJ_vUnloadImage(pldev);
                 LDEVOBJ_vFreeLDEV(pldev);
                 pldev = NULL;
                 goto leave;

Modified: branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/pdevobj.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/pdevobj.c?rev=56003&r1=56002&r2=56003&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/pdevobj.c [iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/subsystems/win32/win32k/eng/pdevobj.c [iso-8859-1] Sun Mar  4 18:47:09 2012
@@ -25,84 +25,75 @@
     return STATUS_SUCCESS;
 }
 
-
-PPDEVOBJ
-PDEVOBJ_AllocPDEV()
-{
-    PPDEVOBJ ppdev;
-
-    ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
-    if (!ppdev)
-        return NULL;
-
-    RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
-
-    ppdev->cPdevRefs = 1;
-
-    return ppdev;
-}
-
 VOID
 NTAPI
-PDEVOBJ_vRelease(PPDEVOBJ ppdev)
-{
+PDEVOBJ_vDestroyPDEV(PPDEVOBJ ppdev)
+{
+    /* Do we have a surface? */
+    if(ppdev->pSurface)
+    {
+        /* Release the surface and let the driver free it */
+        SURFACE_ShareUnlockSurface(ppdev->pSurface);
+        ppdev->pfn.DisableSurface(ppdev->dhpdev);
+    }
+
+    /* Do we have a palette? */
+    if(ppdev->ppalSurf)
+    {
+        PALETTE_ShareUnlockPalette(ppdev->ppalSurf);
+    }
+
+    /* Disable PDEV */
+    ppdev->pfn.DisablePDEV(ppdev->dhpdev);
+
     /* Lock loader */
     EngAcquireSemaphore(ghsemPDEV);
 
-    /* Decrease reference count */
-    --ppdev->cPdevRefs;
-
-    ASSERT(ppdev->cPdevRefs >= 0) ;
-
-    /* Check if references are left */
-    if (ppdev->cPdevRefs == 0)
-    {
-        /* Do we have a surface? */
-        if(ppdev->pSurface)
+    /* Remove it from list */
+    if( ppdev == gppdevList )
+        gppdevList = ppdev->ppdevNext ;
+    else
+    {
+        PPDEVOBJ ppdevCurrent = gppdevList;
+        BOOL found = FALSE ;
+        while (!found && ppdevCurrent->ppdevNext)
         {
-            /* Release the surface and let the driver free it */
-            SURFACE_ShareUnlockSurface(ppdev->pSurface);
-            ppdev->pfn.DisableSurface(ppdev->dhpdev);
+            if (ppdevCurrent->ppdevNext == ppdev)
+                found = TRUE;
+            else
+                ppdevCurrent = ppdevCurrent->ppdevNext ;
         }
-
-        /* Do we have a palette? */
-        if(ppdev->ppalSurf)
-        {
-            PALETTE_ShareUnlockPalette(ppdev->ppalSurf);
-        }
-
-        /* Disable PDEV */
-        ppdev->pfn.DisablePDEV(ppdev->dhpdev);
-
-        /* Remove it from list */
-        if( ppdev == gppdevList )
-            gppdevList = ppdev->ppdevNext ;
-        else
-        {
-            PPDEVOBJ ppdevCurrent = gppdevList;
-            BOOL found = FALSE ;
-            while (!found && ppdevCurrent->ppdevNext)
-            {
-                if (ppdevCurrent->ppdevNext == ppdev)
-                    found = TRUE;
-                else
-                    ppdevCurrent = ppdevCurrent->ppdevNext ;
-            }
-            if(found)
-                ppdevCurrent->ppdevNext = ppdev->ppdevNext;
-        }
-
-        /* Is this the primary one ? */
-        if (ppdev == gppdevPrimary)
-            gppdevPrimary = NULL;
-
-        /* Free it */
-        ExFreePoolWithTag(ppdev, GDITAG_PDEV );
-    }
+        if(found)
+            ppdevCurrent->ppdevNext = ppdev->ppdevNext;
+    }
+
+    /* Is this the primary one ? */
+    if (ppdev == gppdevPrimary)
+        gppdevPrimary = NULL;
 
     /* Unlock loader */
     EngReleaseSemaphore(ghsemPDEV);
 
+    /* Delete device lock semaphore */
+    if (ppdev->hsemDevLock)
+        EngDeleteSemaphore(ppdev->hsemDevLock);
+
+    /* Free it */
+    ExFreePoolWithTag(ppdev, GDITAG_PDEV );
+}
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev)
+{
+    ASSERT(ppdev->cPdevRefs > 0) ;
+
+    /* Decrease reference count */
+    if (InterlockedDecrement(&ppdev->cPdevRefs) == 0)
+    {
+        /* Destroy this PDEV */
+        PDEVOBJ_vDestroyPDEV(ppdev);
+    }
 }
 
 BOOL
@@ -132,6 +123,9 @@
                                   ppdev->pGraphicsDevice->pwszDescription,
                                   ppdev->pGraphicsDevice->DeviceObject);
 
+    /* Check for failure */
+    if (!ppdev->dhpdev) return FALSE;
+
     /* Fix up some values */
     if (ppdev->gdiinfo.ulLogPixelsX == 0)
         ppdev->gdiinfo.ulLogPixelsX = 96;
@@ -148,12 +142,78 @@
 }
 
 VOID
-NTAPI
+FORCEINLINE
 PDEVOBJ_vCompletePDEV(
     PPDEVOBJ ppdev)
 {
     /* Call the drivers DrvCompletePDEV function */
     ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+}
+
+PPDEVOBJ
+NTAPI
+PDEVOBJ_CreatePDEV(
+    PLDEVOBJ pldev)
+{
+    PPDEVOBJ ppdev;
+    LDEVTYPE ldevtype;
+
+    /* Allocate a new PDEVOBJ */
+    ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
+    if (!ppdev)
+    {
+        DPRINT1("failed to allocate a PDEV\n");
+        return FALSE;
+    }
+
+    /* Zero out the structure */
+    RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
+
+    /* Initialize some fields */
+    ppdev->TagSig = 'Pdev';
+    ppdev->cPdevRefs = 1;
+    ppdev->pldev = pldev;
+
+    /* Copy the function table from the LDEVOBJ */
+    ppdev->pfn = ppdev->pldev->pfn;
+
+    /* Allocate the device lock semaphore */
+    ppdev->hsemDevLock = EngCreateSemaphore();
+    if (!ppdev->hsemDevLock)
+    {
+        DPRINT1("Failed to create semaphore\n");
+        ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+        return FALSE;
+    }
+
+    /* Call the drivers DrvEnablePDEV function */
+    if (!PDEVOBJ_bEnablePDEV(ppdev, NULL, NULL))
+    {
+        DPRINT1("Failed to enable PDEV\n");
+        EngDeleteSemaphore(ppdev->hsemDevLock);
+        ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+        return FALSE;
+    }
+
+    /* Set flags based on the LDEV type */
+    ldevtype = pldev->ldevtype;
+    if (ldevtype == LDEV_DEVICE_MIRROR) ppdev->flFlags |= PDEV_CLONE_DEVICE;
+    else if (ldevtype == LDEV_DEVICE_DISPLAY) ppdev->flFlags |= PDEV_DISPLAY;
+    else if (ldevtype == LDEV_DEVICE_PRINTER) ppdev->flFlags |= PDEV_PRINTER;
+    else if (ldevtype == LDEV_DEVICE_META) ppdev->flFlags |= PDEV_META_DEVICE;
+    else if (ldevtype == LDEV_FONT) ppdev->flFlags |= PDEV_FONTDRIVER;
+
+    /* Check if the driver supports fonts */
+    if (ppdev->devinfo.cFonts != 0) ppdev->flFlags |= PDEV_GOTFONTS;
+
+    if (ppdev->pfn.MovePointer) ppdev->flFlags |= PDEV_HARDWARE_POINTER;
+
+    if (ppdev->pvGammaRamp) ppdev->flFlags |= PDEV_GAMMARAMP_TABLE;
+
+    /* Call the drivers DrvCompletePDEV function */
+    PDEVOBJ_vCompletePDEV(ppdev);
+
+    return ppdev;
 }
 
 PSURFACE
@@ -221,15 +281,16 @@
     return NULL;
 }
 
-static
 PPDEVOBJ
-EngpCreatePDEV(
+NTAPI
+EngCreateDisplayPDEV(
     PUNICODE_STRING pustrDeviceName,
     PDEVMODEW pdm)
 {
     PGRAPHICS_DEVICE pGraphicsDevice;
+    PLDEVOBJ pldev;
     PPDEVOBJ ppdev;
-    DPRINT("EngpCreatePDEV(%wZ, %p)\n", pustrDeviceName, pdm);
+    DPRINT("EngCreateDisplayPDEV(%wZ, %p)\n", pustrDeviceName, pdm);
 
     /* Try to find the GRAPHICS_DEVICE */
     if (pustrDeviceName)
@@ -247,14 +308,6 @@
         pGraphicsDevice = gpPrimaryGraphicsDevice;
     }
 
-    /* Allocate a new PDEVOBJ */
-    ppdev = PDEVOBJ_AllocPDEV();
-    if (!ppdev)
-    {
-        DPRINT1("failed to allocate a PDEV\n");
-        return NULL;
-    }
-
     /* If no DEVMODEW is given, ... */
     if (!pdm)
     {
@@ -264,18 +317,23 @@
     }
 
     /* Try to get a diplay driver */
-    ppdev->pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
-    if (!ppdev->pldev)
+    pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
+    if (!pldev)
     {
         DPRINT1("Could not load display driver '%ls', '%s'\n",
                 pGraphicsDevice->pDiplayDrivers,
                 pdm->dmDeviceName);
-        ExFreePoolWithTag(ppdev, GDITAG_PDEV);
         return NULL;
     }
 
-    /* Copy the function table */
-    ppdev->pfn = ppdev->pldev->pfn;
+    /* Create a new PDEVOBJ */
+    ppdev = PDEVOBJ_CreatePDEV(pldev);
+    if (!ppdev)
+    {
+        DPRINT1("failed to allocate a PDEV\n");
+        EngUnloadImage(pldev);
+        return FALSE;
+    }
 
     /* Set MovePointer function */
     ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
@@ -283,28 +341,14 @@
         ppdev->pfnMovePointer = EngMovePointer;
 
     ppdev->pGraphicsDevice = pGraphicsDevice;
-    ppdev->hsemDevLock = EngCreateSemaphore();
     // Should we change the ative mode of pGraphicsDevice ?
     ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ;
 
-    /* FIXME! */
-    ppdev->flFlags = PDEV_DISPLAY;
-
     /* HACK: Don't use the pointer */
     ppdev->Pointer.Exclude.right = -1;
 
-    /* Call the driver to enable the PDEV */
-    if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
-    {
-        DPRINT1("Failed to enable PDEV!\n");
-        ASSERT(FALSE);
-    }
-
     /* FIXME: this must be done in a better way */
     pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
-
-    /* Tell the driver that the PDEV is ready */
-    PDEVOBJ_vCompletePDEV(ppdev);
 
     /* Return the PDEV */
     return ppdev;
@@ -393,7 +437,7 @@
 
     /* 2. Create new PDEV */
     RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
-    ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
+    ppdevTmp = EngCreateDisplayPDEV(&ustrDevice, pdm);
     if (!ppdevTmp)
     {
         DPRINT1("Failed to create a new PDEV\n");
@@ -481,7 +525,7 @@
     if (!ppdev)
     {
         /* No, create a new PDEV */
-        ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
+        ppdev = EngCreateDisplayPDEV(pustrDeviceName, NULL);
         if (ppdev)
         {
             /* Insert the PDEV into the list */




More information about the Ros-diffs mailing list