[GDI32]
authorJérôme Gardou <jerome.gardou@reactos.org>
Wed, 10 Oct 2012 23:05:38 +0000 (23:05 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Wed, 10 Oct 2012 23:05:38 +0000 (23:05 +0000)
 - Assume that the provided buffer size is maximal in GetDIBits
[WIN32K]
 - Probe buffer before writing to it
 - Fail DIB Section creation if palette creation failed

svn path=/trunk/; revision=57535

reactos/win32ss/gdi/gdi32/objects/bitmap.c
reactos/win32ss/gdi/ntgdi/dibobj.c

index fad330f..00be190 100644 (file)
@@ -13,7 +13,7 @@
  * 11/16/1999 (RJJ) lifted from wine
  */
 
-INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
+INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse, BOOL max)
 {
     unsigned int colors, size, masks = 0;
 
@@ -26,7 +26,7 @@ INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
     }
     else  /* assume BITMAPINFOHEADER */
     {
-        colors = info->bmiHeader.biClrUsed;
+        colors = max ? 1 << info->bmiHeader.biBitCount : info->bmiHeader.biClrUsed;
         if (colors > 256) colors = 256;
         if (!colors && (info->bmiHeader.biBitCount <= 8))
             colors = 1 << info->bmiHeader.biBitCount;
@@ -409,7 +409,8 @@ GetDIBits(
     }
 
     cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
-    cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage);
+    /* Caller must provide maximum size possible */
+    cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage, TRUE);
 
     if ( lpvBits )
     {
index e729622..65dea06 100644 (file)
@@ -1038,7 +1038,7 @@ NtGdiGetDIBitsInternal(
     _SEH2_TRY
     {
         /* Probe and copy the BITMAPINFO */
-        ProbeForWrite(pbmiUser, cjMaxInfo, 1);
+        ProbeForRead(pbmiUser, cjMaxInfo, 1);
         RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1082,7 +1082,8 @@ NtGdiGetDIBitsInternal(
         /* Use SEH to copy back to user mode */
         _SEH2_TRY
         {
-            /* Buffer is already probed, copy the data back */
+            /* Copy the data back */
+            ProbeForWrite(pbmiUser, cjMaxInfo, 1); 
             RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1551,7 +1552,7 @@ DIB_CreateDIBSection(
     HBITMAP res = 0;
     SURFACE *bmp = NULL;
     void *mapBits = NULL;
-    PPALETTE ppalDIB;
+    PPALETTE ppalDIB = NULL;
 
     // Fill BITMAP32 structure with DIB data
     CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
@@ -1685,15 +1686,10 @@ DIB_CreateDIBSection(
 
     /* Create a palette for the DIB */
     ppalDIB = CreateDIBPalette(bmi, dc, usage);
-    if (ppalDIB)
-    {
-        SURFACE_vSetPalette(bmp, ppalDIB);
-        PALETTE_ShareUnlockPalette(ppalDIB);
-    }
 
     // Clean up in case of errors
 cleanup:
-    if (!res || !bmp || !bm.bmBits)
+    if (!res || !bmp || !bm.bmBits || !ppalDIB)
     {
         DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
         if (bm.bmBits)
@@ -1709,17 +1705,28 @@ cleanup:
         }
 
         if (bmp)
+        {
+            SURFACE_ShareUnlockSurface(bmp);
             bmp = NULL;
+        }
 
         if (res)
         {
             GreDeleteObject(res);
             res = 0;
         }
+        
+        if(ppalDIB)
+        {
+            PALETTE_ShareUnlockPalette(ppalDIB);
+        }
     }
 
     if (bmp)
     {
+        /* If we're here, everything went fine */
+        SURFACE_vSetPalette(bmp, ppalDIB);
+        PALETTE_ShareUnlockPalette(ppalDIB);
         SURFACE_ShareUnlockSurface(bmp);
     }