[WIN32SS] Add extra logging to failed SURFACE_AllocSurface calls. CORE-13036
[reactos.git] / reactos / win32ss / gdi / eng / surface.c
index 3513a2d..9bce837 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
  * PURPOSE:           GDI Driver Surace Functions
- * FILE:              subsys/win32k/eng/surface.c
+ * FILE:              win32ss/gdi/eng/surface.c
  * PROGRAMERS:        Jason Filby
  *                    Timo Kreuzer
  * TESTING TO BE DONE:
@@ -120,6 +120,7 @@ SURFACE_AllocSurface(
     _In_ ULONG iFormat,
     _In_ ULONG fjBitmap,
     _In_opt_ ULONG cjWidth,
+    _In_opt_ ULONG cjBufSize,
     _In_opt_ PVOID pvBits)
 {
     ULONG cBitsPixel, cjBits, cjObject;
@@ -127,7 +128,9 @@ SURFACE_AllocSurface(
     SURFOBJ *pso;
     PVOID pvSection;
 
-    ASSERT(!pvBits || (iType == STYPE_BITMAP));
+    NT_ASSERT(!pvBits || (iType == STYPE_BITMAP));
+    NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0));
+    NT_ASSERT((LONG)cy > 0);
 
     /* Verify format */
     if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
@@ -151,8 +154,35 @@ SURFACE_AllocSurface(
         cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
     }
 
-    /* Calculate the bitmap size in bytes */
-    cjBits = cjWidth * cy;
+    /* Is this an uncompressed format? */
+    if (iFormat <= BMF_32BPP)
+    {
+        /* Calculate the correct bitmap size in bytes */
+        if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits)))
+        {
+            DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n",
+                    cjWidth, cy);
+            return NULL;
+        }
+
+        /* Did we get a buffer and size? */
+        if ((pvBits != NULL) && (cjBufSize != 0))
+        {
+            /* Make sure the buffer is large enough */
+            if (cjBufSize < cjBits)
+            {
+                DPRINT1("Buffer is too small, required: %lu, got %lu\n",
+                        cjBits, cjBufSize);
+                return NULL;
+            }
+        }
+    }
+    else
+    {
+        /* Compressed format, use the provided size */
+        NT_ASSERT(cjBufSize != 0);
+        cjBits = cjBufSize;
+    }
 
     /* Check if we need an extra large object */
     if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
@@ -168,9 +198,10 @@ SURFACE_AllocSurface(
     }
 
     /* Check for arithmetic overflow */
-    if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE)))
+    if (cjObject < sizeof(SURFACE))
     {
         /* Fail! */
+        DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits);
         return NULL;
     }
 
@@ -289,10 +320,12 @@ EngCreateBitmap(
                                  iFormat,
                                  fl,
                                  lWidth,
+                                 0,
                                  pvBits);
     if (!psurf)
     {
-        DPRINT1("SURFACE_AllocSurface failed.\n");
+        DPRINT1("SURFACE_AllocSurface failed. (STYPE_BITMAP, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu, fl=%lu, lWidth=%ld, pvBits=0x%p)\n",
+                sizl.cx, sizl.cy, iFormat, fl, lWidth, pvBits);
         return NULL;
     }
 
@@ -327,10 +360,12 @@ EngCreateDeviceBitmap(
                                  iFormat,
                                  0,
                                  0,
+                                 0,
                                  NULL);
     if (!psurf)
     {
-        DPRINT1("SURFACE_AllocSurface failed.\n");
+        DPRINT1("SURFACE_AllocSurface failed. (STYPE_DEVBITMAP, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu)\n",
+                sizl.cx, sizl.cy, iFormat);
         return NULL;
     }
 
@@ -365,10 +400,12 @@ EngCreateDeviceSurface(
                                  iFormat,
                                  0,
                                  0,
+                                 0,
                                  NULL);
     if (!psurf)
     {
-        DPRINT1("SURFACE_AllocSurface failed.\n");
+        DPRINT1("SURFACE_AllocSurface failed. (STYPE_DEVICE, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu)\n",
+                sizl.cx, sizl.cy, iFormat);
         return NULL;
     }
 
@@ -572,12 +609,15 @@ EngLockSurface(
     return psurf ? &psurf->SurfObj : NULL;
 }
 
-VOID
+__kernel_entry
+NTSTATUS
 APIENTRY
-NtGdiEngUnlockSurface(IN SURFOBJ *pso)
+NtGdiEngUnlockSurface(
+    _In_ SURFOBJ *pso)
 {
     UNIMPLEMENTED;
     ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 VOID