[WIN32K:NTGDI]
[reactos.git] / reactos / win32ss / gdi / ntgdi / dclife.c
index ffdb0e4..647a1b6 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * PURPOSE:           Functions for creation and destruction of DCs
- * FILE:              subsystem/win32/win32k/objects/dclife.c
+ * FILE:              win32ss/gdi/ntgdi/dclife.c
  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@rectos.org)
  */
 
@@ -17,7 +17,7 @@
 PSURFACE psurfDefaultBitmap = NULL;
 PBRUSH pbrDefaultBrush = NULL;
 
-static const MATRIX    gmxWorldToDeviceDefault =
+const MATRIX gmxWorldToDeviceDefault =
 {
     FLOATOBJ_16, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_16,
@@ -25,7 +25,7 @@ static const MATRIX   gmxWorldToDeviceDefault =
     0, 0, 0x4b
 };
 
-static const MATRIX    gmxDeviceToWorldDefault =
+const MATRIX gmxDeviceToWorldDefault =
 {
     FLOATOBJ_1_16, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_1_16,
@@ -33,7 +33,7 @@ static const MATRIX   gmxDeviceToWorldDefault =
     0, 0, 0x53
 };
 
-static const MATRIX    gmxWorldToPageDefault =
+const MATRIX gmxWorldToPageDefault =
 {
     FLOATOBJ_1, FLOATOBJ_0,
     FLOATOBJ_0, FLOATOBJ_1,
@@ -50,7 +50,7 @@ static const MATRIX   gmxWorldToPageDefault =
 INIT_FUNCTION
 NTSTATUS
 NTAPI
-InitDcImpl()
+InitDcImpl(VOID)
 {
     psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
     if (!psurfDefaultBitmap)
@@ -86,16 +86,17 @@ DC_AllocDcWithHandle(GDILOOBJTYPE eDcObjType)
     /* Set the actual DC type */
     pdc->BaseObject.hHmgr = UlongToHandle(eDcObjType);
 
+    pdc->pdcattr = &pdc->dcattr;
+
     /* Insert the object */
     if (!GDIOBJ_hInsertObject(&pdc->BaseObject, GDI_OBJ_HMGR_POWNED))
     {
+        /// FIXME: this is broken, since the DC is not initialized yet...
         DPRINT1("Could not insert DC into handle table.\n");
         GDIOBJ_vFreeObject(&pdc->BaseObject);
         return NULL;
     }
 
-    pdc->pdcattr = &pdc->dcattr;
-
     return pdc;
 }
 
@@ -177,8 +178,6 @@ DC_vInitDc(
         pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
         pdc->erclClip = pdc->erclBounds;
         pdc->co = gxcoTrivial;
-
-        pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
     }
     else
     {
@@ -388,18 +387,26 @@ DC_vCleanup(PVOID ObjectBody)
     /* Free CLIPOBJ resources */
     IntEngFreeClipResources(&pdc->co);
 
-    PATH_Delete(pdc->dclevel.hPath);
-
+    if (pdc->dclevel.hPath)
+    {
+       DPRINT("DC_vCleanup Path\n");
+       PATH_Delete(pdc->dclevel.hPath);
+       pdc->dclevel.hPath = 0;
+       pdc->dclevel.flPath = 0;
+    }
     if(pdc->dclevel.pSurface)
         SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
 
-    PDEVOBJ_vRelease(pdc->ppdev) ;
+    PDEVOBJ_vRelease(pdc->ppdev);
 }
 
 VOID
 NTAPI
 DC_vSetOwner(PDC pdc, ULONG ulOwner)
 {
+    /* Delete saved DCs */
+    DC_vRestoreDC(pdc, 1);
+
     if (pdc->dclevel.hPath)
     {
         GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
@@ -459,7 +466,7 @@ void
 DC_vUpdateDC(PDC pdc)
 {
     // PREGION VisRgn ;
-    PPDEVOBJ ppdev = pdc->ppdev ;
+    PPDEVOBJ ppdev = pdc->ppdev;
 
     pdc->dhpdev = ppdev->dhpdev;
 
@@ -504,7 +511,7 @@ DC_vPrepareDCsForBlit(
         DC_vUpdateTextBrush(pdcDest);
 
     /* Lock them in good order */
-    if(pdcSrc)
+    if (pdcSrc)
     {
         if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >=
            (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
@@ -524,7 +531,7 @@ DC_vPrepareDCsForBlit(
     }
     else
     {
-        pdcFirst = pdcDest ;
+        pdcFirst = pdcDest;
         prcFirst = rcDest;
         pdcSecond = NULL;
         prcSecond = NULL;
@@ -537,8 +544,9 @@ DC_vPrepareDCsForBlit(
     if (pdcFirst->dctype == DCTYPE_DIRECT)
     {
         EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
+
         /* Update surface if needed */
-        if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
+        if (pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcFirst);
         }
@@ -556,6 +564,10 @@ DC_vPrepareDCsForBlit(
                                prcFirst->bottom) ;
     }
 
+#if DBG
+    pdcFirst->fs |= DC_PREPARED;
+#endif
+
     if (!pdcSecond)
         return;
 
@@ -565,7 +577,7 @@ DC_vPrepareDCsForBlit(
         EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
 
         /* Update surface if needed */
-        if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
+        if (pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcSecond);
         }
@@ -581,6 +593,10 @@ DC_vPrepareDCsForBlit(
                                prcSecond->right,
                                prcSecond->bottom) ;
     }
+
+#if DBG
+    pdcSecond->fs |= DC_PREPARED;
+#endif
 }
 
 /* Finishes a blit for one or two DCs */
@@ -588,19 +604,25 @@ VOID
 FASTCALL
 DC_vFinishBlit(PDC pdc1, PDC pdc2)
 {
-    if(pdc1->dctype == DCTYPE_DIRECT)
+    if (pdc1->dctype == DCTYPE_DIRECT)
     {
         MouseSafetyOnDrawEnd(pdc1->ppdev);
         EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
     }
+#if DBG
+    pdc1->fs &= ~DC_PREPARED;
+#endif
 
-    if(pdc2)
+    if (pdc2)
     {
-        if(pdc2->dctype == DCTYPE_DIRECT)
+        if (pdc2->dctype == DCTYPE_DIRECT)
         {
             MouseSafetyOnDrawEnd(pdc2->ppdev);
             EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
         }
+#if DBG
+        pdc2->fs &= ~DC_PREPARED;
+#endif
     }
 }
 
@@ -656,23 +678,25 @@ GreOpenDCW(
     return hdc;
 }
 
+__kernel_entry
 HDC
 APIENTRY
 NtGdiOpenDCW(
-    PUNICODE_STRING pustrDevice,
-    DEVMODEW *pdmInit,
-    PUNICODE_STRING pustrLogAddr,
-    ULONG iType,
-    BOOL bDisplay,
-    HANDLE hspool,
-    VOID *pDriverInfo2,
-    VOID *pUMdhpdev)
+    _In_opt_ PUNICODE_STRING pustrDevice,
+    _In_ DEVMODEW *pdmInit,
+    _In_ PUNICODE_STRING pustrLogAddr,
+    _In_ ULONG iType,
+    _In_ BOOL bDisplay,
+    _In_opt_ HANDLE hspool,
+    _At_((PUMDHPDEV*)pUMdhpdev, _Out_) PVOID pUMdhpdev)
 {
     UNICODE_STRING ustrDevice;
     WCHAR awcDevice[CCHDEVICENAME];
-    DEVMODEW dmInit;
     PVOID dhpdev;
     HDC hdc;
+    WORD dmSize, dmDriverExtra;
+    DWORD Size;
+    DEVMODEW * _SEH2_VOLATILE pdmAllocated = NULL;
 
     /* Only if a devicename is given, we need any data */
     if (pustrDevice)
@@ -689,11 +713,22 @@ NtGdiOpenDCW(
             /* Copy the string */
             RtlCopyUnicodeString(&ustrDevice, pustrDevice);
 
+            /* Allocate and store pdmAllocated if pdmInit is not NULL */
             if (pdmInit)
             {
-                /* FIXME: could be larger */
                 ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
-                RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+
+                dmSize = pdmInit->dmSize;
+                dmDriverExtra = pdmInit->dmDriverExtra;
+                Size = dmSize + dmDriverExtra;
+                ProbeForRead(pdmInit, Size, 1);
+
+                pdmAllocated = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
+                                                     Size,
+                                                     TAG_DC);
+                RtlCopyMemory(pdmAllocated, pdmInit, Size);
+                pdmAllocated->dmSize = dmSize;
+                pdmAllocated->dmDriverExtra = dmDriverExtra;
             }
 
             if (pUMdhpdev)
@@ -703,6 +738,10 @@ NtGdiOpenDCW(
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
+            if (pdmAllocated)
+            {
+                ExFreePoolWithTag(pdmAllocated, TAG_DC);
+            }
             SetLastNtError(_SEH2_GetExceptionCode());
             _SEH2_YIELD(return NULL);
         }
@@ -726,7 +765,7 @@ NtGdiOpenDCW(
 
     /* Call the internal function */
     hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
-                     pdmInit ? &dmInit : NULL,
+                     pdmAllocated,
                      NULL, // FIXME: pwszLogAddress
                      iType,
                      bDisplay,
@@ -751,6 +790,12 @@ NtGdiOpenDCW(
         _SEH2_END
     }
 
+    /* Free the allocated */
+    if (pdmAllocated)
+    {
+        ExFreePoolWithTag(pdmAllocated, TAG_DC);
+    }
+
     return hdc;
 }
 
@@ -876,11 +921,13 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
         if (!GreDeleteObject(hDC))
         {
             DPRINT1("DC_FreeDC failed\n");
+            return FALSE;
         }
     }
     else
     {
         DPRINT1("Attempted to Delete 0x%p currently being destroyed!!!\n", hDC);
+        return FALSE;
     }
 
     return TRUE;