Charles Davis : gdi32/enhmfdrv: When blitting, don' t crash if the source is NULL.

Alexandre Julliard julliard at winehq.org
Mon Nov 23 08:49:55 CST 2009


Module: wine
Branch: master
Commit: b6f841eaca4d02a209a3b06d4c04bd137849aa41
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b6f841eaca4d02a209a3b06d4c04bd137849aa41

Author: Charles Davis <cdavis at mymail.mines.edu>
Date:   Sun Nov 22 13:25:38 2009 -0700

gdi32/enhmfdrv: When blitting, don't crash if the source is NULL.

---

 dlls/gdi32/enhmfdrv/bitblt.c |  117 +++++++++++++++++++++++++++--------------
 1 files changed, 77 insertions(+), 40 deletions(-)

diff --git a/dlls/gdi32/enhmfdrv/bitblt.c b/dlls/gdi32/enhmfdrv/bitblt.c
index 1a84c32..e5c80f6 100644
--- a/dlls/gdi32/enhmfdrv/bitblt.c
+++ b/dlls/gdi32/enhmfdrv/bitblt.c
@@ -79,10 +79,14 @@ static BOOL EMFDRV_BitBlockTransfer(
     UINT bitsSize;
     UINT size;
     BITMAP  BM;
-    WORD nBPP;
+    WORD nBPP = 0;
     LPBITMAPINFOHEADER lpBmiH;
+    BOOL useSrc;
     EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc;
-    HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
+    HBITMAP hBitmap = NULL;
+
+    useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
+    if (!physDevSrc && useSrc) return FALSE;
 
     if (emrType == EMR_BITBLT)
         emrSize = sizeof(EMRBITBLT);
@@ -91,16 +95,25 @@ static BOOL EMFDRV_BitBlockTransfer(
     else
         return FALSE;
 
-    if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
-        return FALSE;
+    if(useSrc)
+    {
+        hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);
 
-    nBPP = BM.bmPlanes * BM.bmBitsPixel;
-    if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
+        if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
+            return FALSE;
 
-    bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
-    bmiSize = sizeof(BITMAPINFOHEADER) + 
-        (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
-    size = emrSize + bmiSize + bitsSize;
+        nBPP = BM.bmPlanes * BM.bmBitsPixel;
+        if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
+        bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
+        bmiSize = sizeof(BITMAPINFOHEADER) +
+            (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
+    }
+    else
+    {
+        bitsSize = bmiSize = 0;
+    }
+
+   size = emrSize + bmiSize + bitsSize;
 
     pEMR = HeapAlloc(GetProcessHeap(), 0, size);
     if (!pEMR) return FALSE;
@@ -119,12 +132,28 @@ static BOOL EMFDRV_BitBlockTransfer(
     pEMR->dwRop = rop;
     pEMR->xSrc = xSrc;
     pEMR->ySrc = ySrc;
-    GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc);
-    pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
-    pEMR->iUsageSrc = DIB_RGB_COLORS;
-    pEMR->offBmiSrc = emrSize;
+    if (useSrc)
+    {
+        GetWorldTransform(physDevSrc->hdc, &pEMR->xformSrc);
+        pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
+        pEMR->iUsageSrc = DIB_RGB_COLORS;
+        pEMR->offBmiSrc = emrSize;
+        pEMR->offBitsSrc = emrSize + bmiSize;
+    }
+    else
+    {
+        pEMR->xformSrc.eM11 = 1.0;  /** FIXME:           */
+        pEMR->xformSrc.eM12 = 0.0;  /** Setting default  */
+        pEMR->xformSrc.eM21 = 0.0;  /** value.           */
+        pEMR->xformSrc.eM22 = 1.0;  /** Where should we  */
+        pEMR->xformSrc.eDx = 0.0;   /** get that info    */
+        pEMR->xformSrc.eDy = 0.0;   /** ????             */
+        pEMR->crBkColorSrc = 0;
+        pEMR->iUsageSrc = 0;
+        pEMR->offBmiSrc = 0;
+        pEMR->offBitsSrc = 0;
+    }
     pEMR->cbBmiSrc = bmiSize;
-    pEMR->offBitsSrc = emrSize + bmiSize;
     pEMR->cbBitsSrc = bitsSize;
     if (emrType == EMR_STRETCHBLT) 
     {
@@ -133,34 +162,42 @@ static BOOL EMFDRV_BitBlockTransfer(
         pEMRStretch->cySrc = heightSrc;
     }
 
-    /* Initialize BITMAPINFO structure */
-    lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
-
-    lpBmiH->biSize = sizeof(BITMAPINFOHEADER); 
-    lpBmiH->biWidth =  BM.bmWidth;
-    lpBmiH->biHeight = BM.bmHeight;
-    lpBmiH->biPlanes = BM.bmPlanes;
-    lpBmiH->biBitCount = nBPP;
-    /* Assume the bitmap isn't compressed and set the BI_RGB flag. */
-    lpBmiH->biCompression = BI_RGB;
-    lpBmiH->biSizeImage = bitsSize;
-    lpBmiH->biYPelsPerMeter = 0;
-    lpBmiH->biXPelsPerMeter = 0;
-    lpBmiH->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
-    /* Set biClrImportant to 0, indicating that all of the 
-       device colors are important. */
-    lpBmiH->biClrImportant = 0; 
-
-    /* Initialize bitmap bits */
-    if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
-                  (BYTE*)pEMR + pEMR->offBitsSrc,
-                  (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
+    if (useSrc)
+    {
+        /* Initialize BITMAPINFO structure */
+        lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);
+
+        lpBmiH->biSize = sizeof(BITMAPINFOHEADER);
+        lpBmiH->biWidth =  BM.bmWidth;
+        lpBmiH->biHeight = BM.bmHeight;
+        lpBmiH->biPlanes = BM.bmPlanes;
+        lpBmiH->biBitCount = nBPP;
+        /* Assume the bitmap isn't compressed and set the BI_RGB flag. */
+        lpBmiH->biCompression = BI_RGB;
+        lpBmiH->biSizeImage = bitsSize;
+        lpBmiH->biYPelsPerMeter = 0;
+        lpBmiH->biXPelsPerMeter = 0;
+        lpBmiH->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
+        /* Set biClrImportant to 0, indicating that all of the
+           device colors are important. */
+        lpBmiH->biClrImportant = 0;
+
+        /* Initialize bitmap bits */
+        if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
+                      (BYTE*)pEMR + pEMR->offBitsSrc,
+                      (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
+        {
+            ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
+            if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
+        }
+        else
+            ret = FALSE;
+    }
+    else
     {
         ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
         if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
-    } 
-    else
-        ret = FALSE;
+    }
 
     HeapFree( GetProcessHeap(), 0, pEMR);
     return ret;




More information about the wine-cvs mailing list