[ros-diffs] [gedmurphy] 29326: - partial rewrite of NtGdiGetDIBitsInternal - wrap all usermode read/writes in seh - make it more compatible with XP. We now pass all current GetDIBits tests and win32k tests

gedmurphy at svn.reactos.org gedmurphy at svn.reactos.org
Mon Oct 1 13:53:32 CEST 2007


Author: gedmurphy
Date: Mon Oct  1 15:53:31 2007
New Revision: 29326

URL: http://svn.reactos.org/svn/reactos?rev=29326&view=rev
Log:
- partial rewrite of NtGdiGetDIBitsInternal
- wrap all usermode read/writes in seh
- make it more compatible with XP. We now pass all current GetDIBits tests and win32k tests

Modified:
    trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
    trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c

Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/dibobj.c?rev=29326&r1=29325&r2=29326&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dibobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dibobj.c Mon Oct  1 15:53:31 2007
@@ -435,6 +435,7 @@
     return ret;
 }
 
+
 /* Converts a device-dependent bitmap to a DIB */
 INT STDCALL
 NtGdiGetDIBitsInternal(HDC hDC,
@@ -447,156 +448,134 @@
                        UINT MaxBits,
                        UINT MaxInfo)
 {
-    BITMAPOBJ *BitmapObj;
-    SURFOBJ *DestSurfObj;
-    XLATEOBJ *XlateObj;
-    HBITMAP DestBitmap;
-    SIZEL DestSize;
-    HPALETTE hSourcePalette;
-    HPALETTE hDestPalette;
-    PPALGDI SourcePalette;
-    PPALGDI DestPalette;
-    ULONG SourcePaletteType;
-    ULONG DestPaletteType;
     PDC Dc;
-    POINTL SourcePoint;
-    RECTL DestRect;
+    BITMAPOBJ *BitmapObj = NULL;
+    HBITMAP hDestBitmap = NULL;
+    HPALETTE hSourcePalette = NULL;
+    HPALETTE hDestPalette = NULL;
+    PPALGDI SourcePalette = NULL;
+    PPALGDI DestPalette = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
     ULONG Result = 0;
-    ULONG Index;
+    BOOL bPaletteMatch = FALSE;
+
+    DPRINT("Entered NtGdiGetDIBitsInternal()\n");
 
     /* Get handle for the palette in DC. */
     Dc = DC_LockDc(hDC);
-    if (Dc == NULL)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
-        return 0;
-    }
+    if (Dc == NULL) return 0;
     if (Dc->IsIC)
     {
         DC_UnlockDc(Dc);
         return 0;
     }
-
+    /* Source palette obtained from the windows hdc */
     hSourcePalette = Dc->w.hPalette;
-    hDestPalette = Dc->w.hPalette; // unsure of this (Ged)
     DC_UnlockDc(Dc);
 
-    /* Get pointer to the source bitmap object. */
+    /* don't do anything if we fail this */
+    if (Usage != DIB_RGB_COLORS && Usage != DIB_PAL_COLORS)
+        return 0;
+
+    /* Get a pointer to the source bitmap object */
     BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
     if (BitmapObj == NULL)
-    {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
         return 0;
-    }
-
+
+    /* fill out the BITMAPINFO struct */
     if (Bits == NULL)
     {
-        if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+        _SEH_TRY
         {
-            BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
-            coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
-            coreheader->bcPlanes = 1;
-            coreheader->bcBitCount =  BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
-
-            coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
-
-            if (BitmapObj->SurfObj.lDelta > 0)
-                coreheader->bcHeight = -coreheader->bcHeight;
-
+            if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+            {
+                ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
+
+                BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
+                coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
+                coreheader->bcPlanes = 1;
+                coreheader->bcBitCount =  BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
+                coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
+
+                if (BitmapObj->SurfObj.lDelta > 0)
+                    coreheader->bcHeight = -coreheader->bcHeight;
+            }
+
+            if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+            {
+                ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
+
+                Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
+                Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
+                /* Report negtive height for top-down bitmaps. */
+                if (BitmapObj->SurfObj.lDelta > 0)
+                    Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
+                Info->bmiHeader.biPlanes = 1;
+                Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
+                if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+                {
+                    switch (BitmapObj->SurfObj.iBitmapFormat)
+                    {
+                        case BMF_1BPP:
+                        case BMF_4BPP:
+                        case BMF_8BPP:
+                        case BMF_16BPP:
+                        case BMF_24BPP:
+                        case BMF_32BPP:
+                            Info->bmiHeader.biCompression = BI_RGB;
+                            break;
+                        case BMF_4RLE:
+                            Info->bmiHeader.biCompression = BI_RLE4;
+                            break;
+                        case BMF_8RLE:
+                            Info->bmiHeader.biCompression = BI_RLE8;
+                            break;
+                        case BMF_JPEG:
+                            Info->bmiHeader.biCompression = BI_JPEG;
+                            break;
+                        case BMF_PNG:
+                            Info->bmiHeader.biCompression = BI_PNG;
+                            break;
+                    }
+
+                    Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
+                    Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
+                    Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
+                    Info->bmiHeader.biClrUsed = 0;
+                    Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
+                }
+            }
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END
+
+        if (NT_SUCCESS(Status))
+        {
             Result = BitmapObj->SurfObj.sizlBitmap.cy;
         }
-
-        if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+    }
+    else
+    {
+        SIZEL DestSize;
+        ULONG SourcePaletteType = 0;
+        ULONG DestPaletteType;
+        POINTL SourcePoint;
+        ULONG Index;
+
+        _SEH_TRY
         {
-            Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
-            Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
-            /* Report negtive height for top-down bitmaps. */
-            if (BitmapObj->SurfObj.lDelta > 0)
-                Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
-            Info->bmiHeader.biPlanes = 1;
-            Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
-            if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+            ProbeForRead(Info, sizeof(BITMAPINFO), 1);
+
+            if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat))
             {
-                switch (BitmapObj->SurfObj.iBitmapFormat)
-                {
-                    case BMF_1BPP:
-                    case BMF_4BPP:
-                    case BMF_8BPP:
-                    case BMF_16BPP:
-                    case BMF_24BPP:
-                    case BMF_32BPP:
-                        Info->bmiHeader.biCompression = BI_RGB;
-                        break;
-                    case BMF_4RLE:
-                        Info->bmiHeader.biCompression = BI_RLE4;
-                        break;
-                    case BMF_8RLE:
-                        Info->bmiHeader.biCompression = BI_RLE8;
-                        break;
-                    case BMF_JPEG:
-                        Info->bmiHeader.biCompression = BI_JPEG;
-                        break;
-                    case BMF_PNG:
-                        Info->bmiHeader.biCompression = BI_PNG;
-                        break;
-                }
-
-                Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
-                Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
-                Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
-                Info->bmiHeader.biClrUsed = 0;
-                Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
-                Result = BitmapObj->SurfObj.sizlBitmap.cy;
+                hDestPalette = hSourcePalette;
+                bPaletteMatch = TRUE;
             }
-        }
-    }
-    else
-    {
-        if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
-        {
-            Result = 0;
-        }
-        else
-        {
-            ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
-            DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
-            DestSize.cy = ScanLines;
-
-            DestBitmap = NULL;
-            if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
-            {
-                BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
-
-                DestBitmap = EngCreateBitmap(DestSize,
-                                             DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
-                                             BitmapFormat(coreheader->bcBitCount, BI_RGB),
-                                             0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
-                                             Bits);
-            }
-
-            if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
-            {
-                INT one, two, three;
-
-                one = DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
-                two = ((DestSize.cx * Info->bmiHeader.biBitCount + 31) & ~31) >> 3;
-                three = DestSize.cx * (Info->bmiHeader.biBitCount >> 3);
-
-                DestBitmap = EngCreateBitmap(DestSize,
-                                            /* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
-                                            DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
-                                            BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
-                                            0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
-                                            Bits);
-            }
-
-            if(DestBitmap == NULL)
-            {
-                BITMAPOBJ_UnlockBitmap(BitmapObj);
-                return 0;
-            }
-
-            DestSurfObj = EngLockSurface((HSURF)DestBitmap);
+            else
+                hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
 
             SourcePalette = PALETTE_LockPalette(hSourcePalette);
             /* FIXME - SourcePalette can be NULL!!! Don't assert here! */
@@ -604,10 +583,18 @@
             SourcePaletteType = SourcePalette->Mode;
             PALETTE_UnlockPalette(SourcePalette);
 
-            DestPalette = PALETTE_LockPalette(hDestPalette);
-            /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
-            //ASSERT(DestPalette);
-            DestPaletteType = DestPalette->Mode;
+            if (bPaletteMatch)
+            {
+                DestPalette = PALETTE_LockPalette(hDestPalette);
+                /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
+                DPRINT1("DestPalette : %p\n", DestPalette);
+                ASSERT(DestPalette);
+                DestPaletteType = DestPalette->Mode;
+            }
+            else
+            {
+                DestPalette = SourcePalette;
+            }
 
             /* Copy palette. */
             /* FIXME: This is largely incomplete. */
@@ -631,9 +618,65 @@
                 }
             }
 
-            PALETTE_UnlockPalette(DestPalette);
-
-            XlateObj = IntEngCreateXlate(DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);
+            if (bPaletteMatch)
+                PALETTE_UnlockPalette(DestPalette);
+
+            /* Create the destination bitmap to for the copy operation */
+            if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
+            {
+                _SEH_YIELD(goto cleanup);
+            }
+            else
+            {
+                ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
+                DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
+                DestSize.cy = ScanLines;
+
+                hDestBitmap = NULL;
+
+                ProbeForWrite(Bits, sizeof(BitmapObj->SurfObj.cjBits), 1);
+
+                if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+                {
+                    BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
+
+                    hDestBitmap = EngCreateBitmap(DestSize,
+                                                  DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
+                                                  BitmapFormat(coreheader->bcBitCount, BI_RGB),
+                                                  0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
+                                                  Bits);
+                }
+
+                if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+                {
+                    hDestBitmap = EngCreateBitmap(DestSize,
+                                                  /* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
+                                                  DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
+                                                  BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
+                                                  0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
+                                                  Bits);
+                }
+
+                if (hDestBitmap == NULL)
+                    _SEH_YIELD(goto cleanup);
+            }
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END
+
+        if (NT_SUCCESS(Status))
+        {
+            XLATEOBJ *XlateObj;
+            SURFOBJ *DestSurfObj;
+            RECTL DestRect;
+
+            XlateObj = IntEngCreateXlate(DestPaletteType,
+                                         SourcePaletteType,
+                                         hDestPalette,
+                                         hSourcePalette);
 
             SourcePoint.x = 0;
             SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
@@ -643,6 +686,8 @@
             DestRect.left = 0;
             DestRect.right = DestSize.cx;
             DestRect.bottom = DestSize.cy;
+
+            DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
 
             if (EngCopyBits(DestSurfObj,
                             &BitmapObj->SurfObj,
@@ -659,7 +704,16 @@
         }
     }
 
+cleanup:
+    if (hDestBitmap != NULL)
+        EngDeleteSurface((HSURF)hDestBitmap);
+
+    if (hDestPalette != NULL && bPaletteMatch == FALSE)
+        PALETTE_FreePalette(hDestPalette);
+
     BITMAPOBJ_UnlockBitmap(BitmapObj);
+
+    DPRINT("leaving NtGdiGetDIBitsInternal\n");
 
     return Result;
 }
@@ -1318,14 +1372,18 @@
   // Determine Bits Per Pixel
   bits = bmi->bmiHeader.biBitCount;
 
+  //DPRINT1("%d bits\n", bits);
+
   // Determine paletteType from Bits Per Pixel
   if (bits <= 8)
     {
+        //DPRINT1("8\n");
       *paletteType = PAL_INDEXED;
       RedMask = GreenMask = BlueMask = 0;
     }
   else if(bits < 24)
     {
+        //DPRINT1("24\n");
       *paletteType = PAL_BITFIELDS;
       RedMask = 0xf800;
       GreenMask = 0x07e0;
@@ -1333,6 +1391,7 @@
     }
   else
     {
+        //DPRINT1("else\n");
       *paletteType = PAL_BGR;
       RedMask = 0xff0000;
       GreenMask = 0x00ff00;
@@ -1350,14 +1409,17 @@
 
   if (PAL_INDEXED == *paletteType)
     {
+        //DPRINT1("in\n");
       hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
     }
   else
     {
+        //DPRINT1("out\n");
       hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
                                   (ULONG*) palEntries,
                                   RedMask, GreenMask, BlueMask );
     }
+  //DPRINT1("returning %p\n", hPal);
 
   return hPal;
 }

Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c?rev=29326&r1=29325&r2=29326&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c Mon Oct  1 15:53:31 2007
@@ -1031,7 +1031,8 @@
       GdiHdr->lockline = 0;
    }
 #else
-   InterlockedDecrement((PLONG)&GdiHdr->Locks);
+   if (InterlockedDecrement((PLONG)&GdiHdr->Locks) < 0)
+       DPRINT1("Trying to unlock non-existant object\n");
 #endif
 }
 




More information about the Ros-diffs mailing list