From 320306b3100883800cb3a235dfb0499c88054f6a Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 26 Jan 2015 22:11:34 +0000 Subject: [PATCH] [WIN32K] Fix major bug in EngModifySurface: when pvScan0 and lDelta are passed, the surface is converted to type STYPE_BITMAP. pvBits is calculated accordingly and surface flags are updated according to flSurface parameter. Fixes crash with Intel 810 graphic drivers. Thanks to Julio Carchi for testing/helping with debugging. CORE-7821 #resolve svn path=/trunk/; revision=66094 --- reactos/win32ss/gdi/eng/surface.c | 50 +++++++++++++++++++++++++++++-- reactos/win32ss/gdi/eng/surface.h | 3 +- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/reactos/win32ss/gdi/eng/surface.c b/reactos/win32ss/gdi/eng/surface.c index 4f34a616898..2185cf34b66 100644 --- a/reactos/win32ss/gdi/eng/surface.c +++ b/reactos/win32ss/gdi/eng/surface.c @@ -452,8 +452,6 @@ EngModifySurface( ppdev = (PDEVOBJ*)hdev; pso = &psurf->SurfObj; pso->dhsurf = dhsurf; - pso->lDelta = lDelta; - pso->pvScan0 = pvScan0; /* Associate the hdev */ pso->hdev = hdev; @@ -468,6 +466,54 @@ EngModifySurface( SURFACE_vSetPalette(psurf, ppal); PALETTE_ShareUnlockPalette(ppal); + /* Check if the caller passed bitmap bits */ + if ((pvScan0 != NULL) && (lDelta != 0)) + { + /* Update the fields */ + pso->pvScan0 = pvScan0; + pso->lDelta = lDelta; + + /* This is a bitmap now! */ + pso->iType = STYPE_BITMAP; + + /* Check memory layout */ + if (lDelta > 0) + { + /* Topdown is the normal way */ + pso->cjBits = lDelta * pso->sizlBitmap.cy; + pso->pvBits = pso->pvScan0; + pso->fjBitmap |= BMF_TOPDOWN; + } + else + { + /* Inversed bitmap (bottom up) */ + pso->cjBits = (-lDelta) * pso->sizlBitmap.cy; + pso->pvBits = (PCHAR)pso->pvScan0 - pso->cjBits - lDelta; + pso->fjBitmap &= ~BMF_TOPDOWN; + } + + /* Update surface flags */ + if (flSurface & MS_NOTSYSTEMMEMORY) + pso->fjBitmap |= BMF_NOTSYSMEM; + else + pso->fjBitmap &= ~BMF_NOTSYSMEM; + if (flSurface & MS_SHAREDACCESS) + psurf->flags |= SHAREACCESS_SURFACE; + else + psurf->flags &= ~SHAREACCESS_SURFACE; + } + else + { + /* Set bits to NULL */ + pso->pvBits = NULL; + pso->pvScan0 = NULL; + pso->lDelta = 0; + + /* Set appropriate surface type */ + if (pso->iType != STYPE_DEVICE) + pso->iType = STYPE_DEVBITMAP; + } + SURFACE_ShareUnlockSurface(psurf); return TRUE; diff --git a/reactos/win32ss/gdi/eng/surface.h b/reactos/win32ss/gdi/eng/surface.h index 99c70e723c8..355eb7bf8c2 100644 --- a/reactos/win32ss/gdi/eng/surface.h +++ b/reactos/win32ss/gdi/eng/surface.h @@ -49,7 +49,7 @@ enum _SURFACEFLAGS //#define HOOK_FILLPATH 0x00000040 //#define HOOK_STROKEANDFILLPATH 0x00000080 //#define HOOK_LINETO 0x00000100 -//#define SHAREACCESS_SURFACE 0x00000200 + SHAREACCESS_SURFACE = 0x00000200, //#define HOOK_COPYBITS 0x00000400 //#define REDIRECTION_SURFACE 0x00000800 // ? //#define HOOK_MOVEPANNING 0x00000800 @@ -82,7 +82,6 @@ enum _SURFACEFLAGS }; #define BMF_POOLALLOC 0x100 -#define PDEV_SURFACE 0x80000000 /* Internal interface */