[ros-diffs] [tkreuzer] 56460: [WIN32K] Rewrite SURFACE_AllocSurface(), which now does the part of the former SURFACE_bSetBitmapBits() as well. This is to allocate the bits for a bitmap directly with the SURFAC...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Tue May 1 12:14:11 UTC 2012


Author: tkreuzer
Date: Tue May  1 12:14:10 2012
New Revision: 56460

URL: http://svn.reactos.org/svn/reactos?rev=56460&view=rev
Log:
[WIN32K]
Rewrite SURFACE_AllocSurface(), which now does the part of the former SURFACE_bSetBitmapBits() as well. This is to allocate the bits for a bitmap directly with the SURFACE object in one allocation. Also don't use kernel mode sections anymore by default, but paged pool memory.

Modified:
    trunk/reactos/win32ss/gdi/eng/surface.c
    trunk/reactos/win32ss/gdi/eng/surface.h
    trunk/reactos/win32ss/gdi/ntgdi/bitblt.c
    trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c

Modified: trunk/reactos/win32ss/gdi/eng/surface.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/surface.c?rev=56460&r1=56459&r2=56460&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/surface.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/surface.c [iso-8859-1] Tue May  1 12:14:10 2012
@@ -15,7 +15,7 @@
 #define NDEBUG
 #include <debug.h>
 
-ULONG giUniqueSurface = 0;
+LONG giUniqueSurface = 0;
 
 UCHAR
 gajBitsPerFormat[11] =
@@ -34,7 +34,9 @@
 };
 
 
-ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
+ULONG
+FASTCALL
+BitmapFormat(ULONG cBits, ULONG iCompression)
 {
     switch (iCompression)
     {
@@ -107,15 +109,10 @@
                 ASSERT(FALSE);
             }
         }
-        else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
-        {
-            /* HACK: Free RLE decompressed bits */
-            EngFreeMem(pvBits);
-        }
-        else
-        {
-            /* There should be nothing to free */
-            ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
+        else if (psurf->SurfObj.fjBitmap & BMF_POOLALLOC)
+        {
+            /* Free a pool allocation */
+            ExFreePool(pvBits);
         }
     }
 
@@ -132,126 +129,162 @@
 PSURFACE
 NTAPI
 SURFACE_AllocSurface(
-    IN USHORT iType,
-    IN ULONG cx,
-    IN ULONG cy,
-    IN ULONG iFormat)
-{
+    _In_ USHORT iType,
+    _In_ ULONG cx,
+    _In_ ULONG cy,
+    _In_ ULONG iFormat,
+    _In_ ULONG fjBitmap,
+    _In_opt_ ULONG cjWidth,
+    _In_opt_ PVOID pvBits)
+{
+    ULONG cBitsPixel, cjBits, cjObject;
     PSURFACE psurf;
     SURFOBJ *pso;
+    PVOID pvSection;
+
+    ASSERT(!pvBits || (iType == STYPE_BITMAP));
+    ASSERT(pvBits || !(fjBitmap & BMF_DONT_FREE));
+    ASSERT(!pvBits || !(fjBitmap & BMF_SINGLEALLOC));
 
     /* Verify format */
-    if (iFormat < BMF_1BPP || iFormat > BMF_PNG)
+    if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
     {
         DPRINT1("Invalid bitmap format: %ld\n", iFormat);
         return NULL;
     }
 
+    /* Get bits per pixel from the format */
+    cBitsPixel = gajBitsPerFormat[iFormat];
+
+    /* Are bits and a width in bytes given? */
+    if (pvBits && cjWidth)
+    {
+        /* Align the width (Windows compatibility, drivers expect that) */
+        cjWidth = WIDTH_BYTES_ALIGN32((cjWidth << 3) / cBitsPixel, cBitsPixel);
+    }
+    else
+    {
+        /* Calculate width from the bitmap width in pixels */
+        cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
+    }
+
+    /* Calculate the bitmap size in bytes */
+    cjBits = cjWidth * cy;
+
+    /* Check if we need an extra large object */
+    if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
+        !(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION))
+    {
+        /* Allocate an object large enough to hold the bits */
+        cjObject = sizeof(SURFACE) + cjBits;
+    }
+    else
+    {
+        /* Otherwise just allocate the SURFACE structure */
+        cjObject = sizeof(SURFACE);
+    }
+
+    /* Check for arithmetic overflow */
+    if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE)))
+    {
+        /* Fail! */
+        return NULL;
+    }
+
     /* Allocate a SURFACE object */
-    psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, sizeof(SURFACE));
-
-    if (psurf)
-    {
-        /* Initialize the basic fields */
-        pso = &psurf->SurfObj;
-        pso->hsurf = psurf->BaseObject.hHmgr;
-        pso->sizlBitmap.cx = cx;
-        pso->sizlBitmap.cy = cy;
-        pso->iBitmapFormat = iFormat;
-        pso->iType = iType;
-        pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface);
-
-        /* Assign a default palette and increment its reference count */
-        psurf->ppal = appalSurfaceDefault[iFormat];
-        GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
-    }
-
-    return psurf;
-}
-
-BOOL
-NTAPI
-SURFACE_bSetBitmapBits(
-    IN PSURFACE psurf,
-    IN ULONG fjBitmap,
-    IN ULONG ulWidth,
-    IN PVOID pvBits OPTIONAL)
-{
-    SURFOBJ *pso = &psurf->SurfObj;
-    PVOID pvSection;
-    UCHAR cBitsPixel;
-
-    /* Only bitmaps can have bits */
-    ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
-
-    /* Get bits per pixel from the format */
-    cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
-
-    /* Is a width in bytes given? */
-    if (ulWidth)
-    {
-        /* Align the width (Windows compatibility, drivers expect that) */
-        ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel);
-    }
-	else
-	{
-        /* Calculate width from the bitmap width in pixels */
-        ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel);
-	}
-
-    /* Calculate the bitmap size in bytes */
-    pso->cjBits = ulWidth * pso->sizlBitmap.cy;
-
-    /* Did the caller provide bits? */
-    if (pvBits)
-    {
-        /* Yes, so let him free it */
-        fjBitmap |= BMF_DONT_FREE;
-    }
-    else if (pso->cjBits)
-    {
-        /* We must allocate memory, check what kind */
-        if (fjBitmap & BMF_USERMEM)
+    psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, cjObject);
+    if (!psurf)
+    {
+        return NULL;
+    }
+
+    /* Initialize the basic fields */
+    pso = &psurf->SurfObj;
+    pso->hsurf = psurf->BaseObject.hHmgr;
+    pso->sizlBitmap.cx = cx;
+    pso->sizlBitmap.cy = cy;
+    pso->iBitmapFormat = iFormat;
+    pso->iType = iType;
+    pso->fjBitmap = (USHORT)fjBitmap;
+    pso->iUniq = InterlockedIncrement(&giUniqueSurface);
+    pso->cjBits = cjBits;
+
+    /* Check if we need a bitmap buffer */
+    if (iType == STYPE_BITMAP)
+    {
+        /* Check if we got one or if we need to allocate one */
+        if (pvBits != NULL)
+        {
+            /* Use the caller provided buffer */
+            pso->pvBits = pvBits;
+        }
+        else if (fjBitmap & BMF_USERMEM)
         {
             /* User mode memory was requested */
-            pvBits = EngAllocUserMem(pso->cjBits, 0);
+            pso->pvBits = EngAllocUserMem(cjBits, 0);
+
+            /* Check for failure */
+            if (!pso->pvBits)
+            {
+                GDIOBJ_vDeleteObject(&psurf->BaseObject);
+                return NULL;
+            }
+        }
+        else if (fjBitmap & BMF_KMSECTION)
+        {
+            /* Use a kernel mode section */
+            pso->pvBits = EngAllocSectionMem(&pvSection,
+                                             (fjBitmap & BMF_NOZEROINIT) ?
+                                                 0 : FL_ZERO_MEMORY,
+                                             cjBits, TAG_DIB);
+
+            /* Check for failure */
+            if (!pso->pvBits)
+            {
+                GDIOBJ_vDeleteObject(&psurf->BaseObject);
+                return NULL;
+            }
+
+            /* Free the section already, but keep the mapping */
+            EngFreeSectionMem(pvSection, NULL);
         }
         else
         {
-            /* Use a kernel mode section */
-            fjBitmap |= BMF_KMSECTION;
-            pvBits = EngAllocSectionMem(&pvSection,
-                                        (fjBitmap & BMF_NOZEROINIT) ?
-                                                0 : FL_ZERO_MEMORY,
-                                        pso->cjBits, TAG_DIB);
-
-            /* Free the section already, but keep the mapping */
-            if (pvBits) EngFreeSectionMem(pvSection, NULL);
-        }
-
-        /* Check for failure */
-        if (!pvBits) return FALSE;
-    }
-
-    /* Set pvBits, pvScan0 and lDelta */
-    pso->pvBits = pvBits;
+            /* Buffer is after the object */
+            pso->pvBits = psurf + 1;
+
+            /* Zero the buffer, except requested otherwise */
+            if (!(fjBitmap & BMF_NOZEROINIT))
+            {
+                RtlZeroMemory(pso->pvBits, cjBits);
+            }
+        }
+    }
+    else
+    {
+        /* There are no bitmap bits */
+        pso->pvBits = NULL;
+    }
+
+    /* Set pvScan0 and lDelta */
     if (fjBitmap & BMF_TOPDOWN)
     {
         /* Topdown is the normal way */
         pso->pvScan0 = pso->pvBits;
-        pso->lDelta = ulWidth;
+        pso->lDelta = cjWidth;
     }
     else
     {
         /* Inversed bitmap (bottom up) */
-        pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
-        pso->lDelta = -(LONG)ulWidth;
-    }
-
-    pso->fjBitmap = (USHORT)fjBitmap;
-
-    /* Success */
-    return TRUE;
+        pso->pvScan0 = ((PCHAR)pso->pvBits + pso->cjBits - cjWidth);
+        pso->lDelta = -(LONG)cjWidth;
+    }
+
+    /* Assign a default palette and increment its reference count */
+    psurf->ppal = appalSurfaceDefault[iFormat];
+    GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
+
+    return psurf;
 }
 
 HBITMAP
@@ -267,7 +300,13 @@
     HBITMAP hbmp;
 
     /* Allocate a surface */
-    psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
+    psurf = SURFACE_AllocSurface(STYPE_BITMAP,
+                                 sizl.cx,
+                                 sizl.cy,
+                                 iFormat,
+                                 fl,
+                                 lWidth,
+                                 pvBits);
     if (!psurf)
     {
         DPRINT1("SURFACE_AllocSurface failed.\n");
@@ -276,15 +315,6 @@
 
     /* Get the handle for the bitmap */
     hbmp = (HBITMAP)psurf->SurfObj.hsurf;
-
-    /* Set the bitmap bits */
-    if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
-    {
-        /* Bail out if that failed */
-        DPRINT1("SURFACE_bSetBitmapBits failed.\n");
-        GDIOBJ_vDeleteObject(&psurf->BaseObject);
-        return NULL;
-    }
 
     /* Set public ownership */
     GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
@@ -308,10 +338,17 @@
     HBITMAP hbmp;
 
     /* Allocate a surface */
-    psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
+    psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP,
+                                 sizl.cx,
+                                 sizl.cy,
+                                 iFormat,
+                                 0,
+                                 0,
+                                 NULL);
     if (!psurf)
     {
-        return 0;
+        DPRINT1("SURFACE_AllocSurface failed.\n");
+        return NULL;
     }
 
     /* Set the device handle */
@@ -339,10 +376,17 @@
     HSURF hsurf;
 
     /* Allocate a surface */
-    psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
+    psurf = SURFACE_AllocSurface(STYPE_DEVICE,
+                                 sizl.cx,
+                                 sizl.cy,
+                                 iFormat,
+                                 0,
+                                 0,
+                                 NULL);
     if (!psurf)
     {
-        return 0;
+        DPRINT1("SURFACE_AllocSurface failed.\n");
+        return NULL;
     }
 
     /* Set the device handle */

Modified: trunk/reactos/win32ss/gdi/eng/surface.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/surface.h?rev=56460&r1=56459&r2=56460&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/surface.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/surface.h [iso-8859-1] Tue May  1 12:14:10 2012
@@ -83,7 +83,8 @@
 
 #define BMF_DONT_FREE 0x100
 #define BMF_RLE_HACK  0x200
-
+#define BMF_SINGLEALLOC 0x400
+#define BMF_POOLALLOC 0x800
 
 /*  Internal interface  */
 
@@ -99,31 +100,30 @@
 #define  SURFACE_ShareUnlockSurface(pBMObj)  \
   GDIOBJ_vDereferenceObject ((POBJ)pBMObj)
 
-BOOL NTAPI SURFACE_Cleanup(PVOID ObjectBody);
-
-PSURFACE
-NTAPI
-SURFACE_AllocSurface(
-    IN USHORT iType,
-    IN ULONG cx,
-    IN ULONG cy,
-    IN ULONG iFormat);
-
-BOOL
-NTAPI
-SURFACE_bSetBitmapBits(
-    IN PSURFACE psurf,
-    IN ULONG fjBitmap,
-    IN ULONG ulWidth,
-    IN PVOID pvBits OPTIONAL);
-
 #define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
 #define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
 
-ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression);
 extern UCHAR gajBitsPerFormat[];
 #define BitsPerFormat(Format) gajBitsPerFormat[Format]
 
 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
 #define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
 
+ULONG
+FASTCALL
+BitmapFormat(ULONG cBits, ULONG iCompression);
+
+BOOL
+NTAPI
+SURFACE_Cleanup(PVOID ObjectBody);
+
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+    _In_ USHORT iType,
+    _In_ ULONG cx,
+    _In_ ULONG cy,
+    _In_ ULONG iFormat,
+    _In_ ULONG fjBitmap,
+    _In_opt_ ULONG cjWidth,
+    _In_opt_ PVOID pvBits);

Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitblt.c?rev=56460&r1=56459&r2=56460&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] Tue May  1 12:14:10 2012
@@ -1160,34 +1160,36 @@
     }
 
     /* Allocate a surface */
-    psurfDest = SURFACE_AllocSurface(STYPE_BITMAP, 1, 1, BMF_32BPP);
+    psurfDest = SURFACE_AllocSurface(STYPE_BITMAP,
+                                     1,
+                                     1,
+                                     BMF_32BPP,
+                                     BMF_DONT_FREE,
+                                     0,
+                                     &ulRGBColor);
     if (psurfDest)
     {
-        /* Set the bitmap bits */
-        if (SURFACE_bSetBitmapBits(psurfDest, 0, 0, &ulRGBColor))
-        {
-            RECTL rclDest = {0, 0, 1, 1};
-            EXLATEOBJ exlo;
-
-            /* Translate from the source palette to RGB color */
-            EXLATEOBJ_vInitialize(&exlo,
-                                  psurfSrc->ppal,
-                                  &gpalRGB,
-                                  0,
-                                  RGB(0xff,0xff,0xff),
-                                  RGB(0,0,0));
-
-            /* Call the copy bits function */
-            EngCopyBits(&psurfDest->SurfObj,
-                        &psurfSrc->SurfObj,
-                        NULL,
-                        &exlo.xlo,
-                        &rclDest,
-                        &ptlSrc);
-
-            /* Cleanup the XLATEOBJ */
-            EXLATEOBJ_vCleanup(&exlo);
-        }
+        RECTL rclDest = {0, 0, 1, 1};
+        EXLATEOBJ exlo;
+
+        /* Translate from the source palette to RGB color */
+        EXLATEOBJ_vInitialize(&exlo,
+                              psurfSrc->ppal,
+                              &gpalRGB,
+                              0,
+                              RGB(0xff,0xff,0xff),
+                              RGB(0,0,0));
+
+        /* Call the copy bits function */
+        EngCopyBits(&psurfDest->SurfObj,
+                    &psurfSrc->SurfObj,
+                    NULL,
+                    &exlo.xlo,
+                    &rclDest,
+                    &ptlSrc);
+
+        /* Cleanup the XLATEOBJ */
+        EXLATEOBJ_vCleanup(&exlo);
 
         /* Delete the surface */
         GDIOBJ_vDeleteObject(&psurfDest->BaseObject);

Modified: trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c?rev=56460&r1=56459&r2=56460&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] Tue May  1 12:14:10 2012
@@ -56,25 +56,36 @@
 {
     PSURFACE psurf;
     HBITMAP hbmp;
+    PVOID pvCompressedBits;
 
     /* Verify format */
     if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
 
+    /* The infamous RLE hack */
+    if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
+    {
+        pvCompressedBits = pvBits;
+        pvBits = NULL;
+        iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
+    }
+
     /* Allocate a surface */
-    psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
+    psurf = SURFACE_AllocSurface(STYPE_BITMAP,
+                                 nWidth,
+                                 nHeight,
+                                 iFormat,
+                                 fjBitmap,
+                                 cjWidthBytes,
+                                 pvBits);
     if (!psurf)
     {
         DPRINT1("SURFACE_AllocSurface failed.\n");
         return NULL;
     }
 
-    /* Get the handle for the bitmap */
-    hbmp = (HBITMAP)psurf->SurfObj.hsurf;
-
     /* The infamous RLE hack */
-    if (iFormat == BMF_4RLE || iFormat == BMF_8RLE)
-    {
-        PVOID pvCompressedBits;
+    if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
+    {
         SIZEL sizl;
         LONG lDelta;
 
@@ -82,33 +93,16 @@
         sizl.cy = nHeight;
         lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
 
-        pvCompressedBits = pvBits;
-        pvBits = EngAllocMem(FL_ZERO_MEMORY, lDelta * nHeight, TAG_DIB);
-        if (!pvBits)
-        {
-            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            GDIOBJ_vDeleteObject(&psurf->BaseObject);
-            return NULL;
-        }
+        pvBits = psurf->SurfObj.pvBits;
         DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat);
-        fjBitmap |= BMF_RLE_HACK;
-
-        iFormat = iFormat == BMF_4RLE ? BMF_4BPP : BMF_8BPP;
-        psurf->SurfObj.iBitmapFormat = iFormat;
-    }
+        psurf->SurfObj.fjBitmap |= BMF_RLE_HACK;
+    }
+
+    /* Get the handle for the bitmap */
+    hbmp = (HBITMAP)psurf->SurfObj.hsurf;
 
     /* Mark as API bitmap */
     psurf->flags |= (flags | API_BITMAP);
-
-    /* Set the bitmap bits */
-    if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
-    {
-        /* Bail out if that failed */
-        DPRINT1("SURFACE_bSetBitmapBits failed.\n");
-        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        GDIOBJ_vDeleteObject(&psurf->BaseObject);
-        return NULL;
-    }
 
     /* Unlock the surface and return */
     SURFACE_UnlockSurface(psurf);
@@ -149,8 +143,9 @@
     IN OPTIONAL LPBYTE pUnsafeBits)
 {
     HBITMAP hbmp;
-    ULONG cRealBpp, cjWidthBytes, iFormat;
+    ULONG cRealBpp, cjWidthBytes, iFormat, fjBitmap;
     ULONGLONG cjSize;
+    PSURFACE psurf;
 
     /* Calculate bitmap format and real bits per pixel. */
     iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
@@ -170,12 +165,27 @@
         return NULL;
     }
 
-    /* Call internal function. */
-    hbmp = GreCreateBitmapEx(nWidth, nHeight, 0, iFormat, 0, 0, NULL, DDB_SURFACE);
-
-    if (pUnsafeBits && hbmp)
-    {
-        PSURFACE psurf = SURFACE_ShareLockSurface(hbmp);
+    /* Allocate the surface (but don't set the bits) */
+    psurf = SURFACE_AllocSurface(STYPE_BITMAP,
+                                 nWidth,
+                                 nHeight,
+                                 iFormat,
+                                 fjBitmap,
+                                 0,
+                                 NULL);
+    if (!psurf)
+    {
+        DPRINT1("SURFACE_AllocSurface failed.\n");
+        return NULL;
+    }
+
+    /* Mark as API and DDB bitmap */
+    psurf->flags |= (API_BITMAP | DDB_SURFACE);
+
+    /* Check if we have bits to set */
+    if (pUnsafeBits)
+    {
+        /* Protect with SEH and copy the bits */
         _SEH2_TRY
         {
             ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
@@ -187,9 +197,18 @@
             _SEH2_YIELD(return NULL;)
         }
         _SEH2_END
-
-        SURFACE_ShareUnlockSurface(psurf);
-    }
+    }
+    else
+    {
+        /* Zero the bits */
+        RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
+    }
+
+    /* Get the handle for the bitmap */
+    hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+    /* Unlock the surface */
+    SURFACE_UnlockSurface(psurf);
 
     return hbmp;
 }
@@ -324,7 +343,8 @@
     HBITMAP Bmp;
     PDC Dc;
 
-    if (Width <= 0 || Height <= 0 || (Width * Height) > 0x3FFFFFFF)
+    /* Check parameters */
+    if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
     {
         EngSetLastError(ERROR_INVALID_PARAMETER);
         return NULL;
@@ -351,17 +371,19 @@
     return Bmp;
 }
 
-BOOL APIENTRY
+BOOL
+APIENTRY
 NtGdiGetBitmapDimension(
     HBITMAP hBitmap,
-    LPSIZE Dimension)
+    LPSIZE psizDim)
 {
     PSURFACE psurfBmp;
-    BOOL Ret = TRUE;
+    BOOL bResult = TRUE;
 
     if (hBitmap == NULL)
         return FALSE;
 
+    /* Lock the bitmap */
     psurfBmp = SURFACE_ShareLockSurface(hBitmap);
     if (psurfBmp == NULL)
     {
@@ -369,20 +391,22 @@
         return FALSE;
     }
 
+    /* Use SEH to copy the data to the caller */
     _SEH2_TRY
     {
-        ProbeForWrite(Dimension, sizeof(SIZE), 1);
-        *Dimension = psurfBmp->sizlDim;
+        ProbeForWrite(psizDim, sizeof(SIZE), 1);
+        *psizDim = psurfBmp->sizlDim;
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Ret = FALSE;
+        bResult = FALSE;
     }
     _SEH2_END
 
+    /* Unlock the bitmap */
     SURFACE_ShareUnlockSurface(psurfBmp);
 
-    return Ret;
+    return bResult;
 }
 
 
@@ -580,7 +604,7 @@
                                psurfSrc->SurfObj.sizlBitmap.cy,
                                abs(psurfSrc->SurfObj.lDelta),
                                psurfSrc->SurfObj.iBitmapFormat,
-                               psurfSrc->SurfObj.fjBitmap,
+                               psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
                                psurfSrc->SurfObj.cjBits,
                                NULL,
                                psurfSrc->flags);




More information about the Ros-diffs mailing list