Author: tkreuzer
Date: Tue Dec 30 19:38:41 2014
New Revision: 65912
URL:
http://svn.reactos.org/svn/reactos?rev=65912&view=rev
Log:
[WIN32K]
Make sure the PDEV is locked before dereferencing the DC's surface
Modified:
trunk/reactos/win32ss/gdi/ntgdi/bitblt.c
trunk/reactos/win32ss/gdi/ntgdi/dc.h
trunk/reactos/win32ss/gdi/ntgdi/dclife.c
trunk/reactos/win32ss/gdi/ntgdi/drawing.c
trunk/reactos/win32ss/gdi/ntgdi/fillshap.c
trunk/reactos/win32ss/gdi/ntgdi/freetype.c
trunk/reactos/win32ss/gdi/ntgdi/line.c
trunk/reactos/win32ss/gdi/ntgdi/palette.c
trunk/reactos/win32ss/gdi/ntgdi/print.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitblt.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -946,7 +946,7 @@
return TRUE;
}
- /* Update the fill brush, if neccessary */
+ /* Update the fill brush, if necessary */
if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(pdc);
@@ -1036,12 +1036,10 @@
PREGION prgnClip;
XCLIPOBJ xcoClip;
BOOL bResult;
- PSURFACE psurf;
NT_ASSERT((pdc != NULL) && (prgn != NULL));
/* Get the surface */
- psurf = pdc->dclevel.pSurface;
- if (psurf == NULL)
+ if (pdc->dclevel.pSurface == NULL)
{
return TRUE;
}
@@ -1078,7 +1076,7 @@
DC_vPrepareDCsForBlit(pdc, &prgnClip->rdh.rcBound, NULL, NULL);
/* Call the Eng or Drv function */
- bResult = IntEngBitBlt(&psurf->SurfObj,
+ bResult = IntEngBitBlt(&pdc->dclevel.pSurface->SurfObj,
NULL,
NULL,
&xcoClip.ClipObj,
@@ -1103,19 +1101,19 @@
IntGdiFillRgn(
_In_ PDC pdc,
_In_ PREGION prgn,
- _In_ BRUSHOBJ *pbo)
+ _In_ PBRUSH pbrFill)
{
PREGION prgnClip;
XCLIPOBJ xcoClip;
+ EBRUSHOBJ eboFill;
+ BRUSHOBJ *pbo;
BOOL bRet;
- PSURFACE psurf;
DWORD rop2Fg;
MIX mix;
-
NT_ASSERT((pdc != NULL) && (prgn != NULL));
-
- psurf = pdc->dclevel.pSurface;
- if (psurf == NULL)
+ ASSERT_DC_PREPARED(pdc);
+
+ if (pdc->dclevel.pSurface == NULL)
{
return TRUE;
}
@@ -1150,13 +1148,35 @@
rop2Fg = pdc->pdcattr->jROP2;
mix = rop2Fg | (pdc->pdcattr->jBkMode == OPAQUE ? rop2Fg : R2_NOP) << 8;
+ /* Prepare DC for blit */
+ DC_vPrepareDCsForBlit(pdc, &prgnClip->rdh.rcBound, NULL, NULL);
+
+ /* Check if we have a fill brush */
+ if (pbrFill != NULL)
+ {
+ /* Initialize the brush object */
+ /// \todo Check parameters
+ EBRUSHOBJ_vInit(&eboFill, pbrFill, pdc->dclevel.pSurface, 0x00FFFFFF, 0,
NULL);
+ pbo = &eboFill.BrushObject;
+ }
+ else
+ {
+ /* Update the fill brush if needed */
+ if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pdc);
+
+ /* Use the DC brush object */
+ pbo = &pdc->eboFill.BrushObject;
+ }
+
/* Call the internal function */
- bRet = IntEngPaint(&psurf->SurfObj,
+ bRet = IntEngPaint(&pdc->dclevel.pSurface->SurfObj,
&xcoClip.ClipObj,
pbo,
&pdc->pdcattr->ptlBrushOrigin,
mix);
+ DC_vFinishBlit(pdc, NULL);
REGION_Delete(prgnClip);
IntEngFreeClipResources(&xcoClip);
@@ -1170,10 +1190,7 @@
_In_ PDC pdc,
_In_ PREGION prgn)
{
- if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(pdc);
-
- return IntGdiFillRgn(pdc, prgn, &pdc->eboFill.BrushObject);
+ return IntGdiFillRgn(pdc, prgn, NULL);
}
BOOL
@@ -1186,7 +1203,6 @@
PDC pdc;
PREGION prgn;
PBRUSH pbrFill;
- EBRUSHOBJ eboFill;
BOOL bResult;
/* Lock the DC */
@@ -1223,12 +1239,8 @@
return FALSE;
}
- /* Initialize the brush object */
- /// \todo Check parameters
- EBRUSHOBJ_vInit(&eboFill, pbrFill, pdc->dclevel.pSurface, 0x00FFFFFF, 0,
NULL);
-
/* Call the internal function */
- bResult = IntGdiFillRgn(pdc, prgn, &eboFill.BrushObject);
+ bResult = IntGdiFillRgn(pdc, prgn, pbrFill);
/* Cleanup locks */
BRUSH_ShareUnlockBrush(pbrFill);
@@ -1360,6 +1372,7 @@
EBRUSHOBJ_iSetSolidColor(pebo, iOldColor);
pdc->pdcattr->ulDirty_ = ulDirty;
+ /// FIXME: we shouldn't dereference pSurface while the PDEV is not locked!
/* Initialize an XLATEOBJ from the target surface to RGB */
EXLATEOBJ_vInitialize(&exlo,
pdc->dclevel.pSurface->ppal,
@@ -1391,6 +1404,7 @@
PDC pdc;
ULONG ulRGBColor = CLR_INVALID;
POINTL ptlSrc;
+ RECT rcDest;
PSURFACE psurfSrc, psurfDest;
/* Lock the DC */
@@ -1402,8 +1416,7 @@
}
/* Check if the DC has no surface (empty mem or info DC) */
- psurfSrc = pdc->dclevel.pSurface;
- if (psurfSrc == NULL)
+ if (pdc->dclevel.pSurface == NULL)
{
/* Fail! */
goto leave;
@@ -1418,7 +1431,16 @@
ptlSrc.x += pdc->ptlDCOrig.x;
ptlSrc.y += pdc->ptlDCOrig.y;
+ rcDest.left = x;
+ rcDest.top = y;
+ rcDest.right = x + 1;
+ rcDest.bottom = y + 1;
+
+ /* Prepare DC for blit */
+ DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
+
/* Check if the pixel is outside the surface */
+ psurfSrc = pdc->dclevel.pSurface;
if ((ptlSrc.x >= psurfSrc->SurfObj.sizlBitmap.cx) ||
(ptlSrc.y >= psurfSrc->SurfObj.sizlBitmap.cy))
{
@@ -1463,7 +1485,9 @@
}
leave:
+
/* Unlock the DC */
+ DC_vFinishBlit(pdc, NULL);
DC_UnlockDc(pdc);
/* Return the new RGB color or -1 on failure */
Modified: trunk/reactos/win32ss/gdi/ntgdi/dc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dc.h?rev…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dc.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dc.h [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -33,7 +33,10 @@
DC_FULLSCREEN = 0x0800,
DC_IN_CLONEPDEV = 0x1000,
DC_REDIRECTION = 0x2000,
- DC_SHAREACCESS = 0x4000
+ DC_SHAREACCESS = 0x4000,
+#ifdef DBG
+ DC_PREPARED = 0x8000
+#endif
};
typedef enum _DCTYPE
@@ -96,7 +99,7 @@
BASEOBJECT BaseObject;
DHPDEV dhpdev; /* <- PDEVOBJ.hPDev DHPDEV for device. */
- INT dctype;
+ DCTYPE dctype;
INT fs;
PPDEVOBJ ppdev;
PVOID hsem; /* PERESOURCE aka HSEMAPHORE */
@@ -293,4 +296,6 @@
extern _Notnull_ PBRUSH pbrDefaultBrush;
extern _Notnull_ PSURFACE psurfDefaultBitmap;
+#define ASSERT_DC_PREPARED(pdc) NT_ASSERT((pdc)->fs & DC_PREPARED)
+
#endif /* not __WIN32K_DC_H */
Modified: trunk/reactos/win32ss/gdi/ntgdi/dclife.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dclife.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dclife.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dclife.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -504,7 +504,7 @@
DC_vUpdateTextBrush(pdcDest);
/* Lock them in good order */
- if(pdcSrc)
+ if (pdcSrc)
{
if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >=
(ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
@@ -524,7 +524,7 @@
}
else
{
- pdcFirst = pdcDest ;
+ pdcFirst = pdcDest;
prcFirst = rcDest;
pdcSecond = NULL;
prcSecond = NULL;
@@ -537,8 +537,9 @@
if (pdcFirst->dctype == DCTYPE_DIRECT)
{
EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
+
/* Update surface if needed */
- if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
+ if (pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
{
DC_vUpdateDC(pdcFirst);
}
@@ -556,6 +557,10 @@
prcFirst->bottom) ;
}
+#ifdef DBG
+ pdcFirst->fs |= DC_PREPARED;
+#endif
+
if (!pdcSecond)
return;
@@ -565,7 +570,7 @@
EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
/* Update surface if needed */
- if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
+ if (pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
{
DC_vUpdateDC(pdcSecond);
}
@@ -581,6 +586,10 @@
prcSecond->right,
prcSecond->bottom) ;
}
+
+#ifdef DBG
+ pdcSecond->fs |= DC_PREPARED;
+#endif
}
/* Finishes a blit for one or two DCs */
@@ -588,19 +597,25 @@
FASTCALL
DC_vFinishBlit(PDC pdc1, PDC pdc2)
{
- if(pdc1->dctype == DCTYPE_DIRECT)
+ if (pdc1->dctype == DCTYPE_DIRECT)
{
MouseSafetyOnDrawEnd(pdc1->ppdev);
EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
}
-
- if(pdc2)
- {
- if(pdc2->dctype == DCTYPE_DIRECT)
+#ifdef DBG
+ pdc1->fs &= ~DC_PREPARED;
+#endif
+
+ if (pdc2)
+ {
+ if (pdc2->dctype == DCTYPE_DIRECT)
{
MouseSafetyOnDrawEnd(pdc2->ppdev);
EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
}
+#ifdef DBG
+ pdc2->fs &= ~DC_PREPARED;
+#endif
}
}
Modified: trunk/reactos/win32ss/gdi/ntgdi/drawing.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/drawing.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/drawing.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/drawing.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -1255,6 +1255,7 @@
PDC_ATTR pdcattr;
ASSERT(pbrush);
+ ASSERT_DC_PREPARED(dc);
psurf = dc->dclevel.pSurface;
if (psurf == NULL)
Modified: trunk/reactos/win32ss/gdi/ntgdi/fillshap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/fillshap…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/fillshap.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -931,8 +931,7 @@
return TRUE;
}
- psurf = pdc->dclevel.pSurface;
- if(!psurf)
+ if (!pdc->dclevel.pSurface)
{
/* Memory DC with no surface selected */
DC_UnlockDc(pdc);
@@ -962,9 +961,11 @@
ptlDitherOrg.x += pdc->ptlDCOrig.x;
ptlDitherOrg.y += pdc->ptlDCOrig.y;
+ DC_vPrepareDCsForBlit(pdc, &rclExtent, NULL, NULL);
+
+ psurf = pdc->dclevel.pSurface;
+
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
-
- DC_vPrepareDCsForBlit(pdc, &rclExtent, NULL, NULL);
bRet = IntEngGradientFill(&psurf->SurfObj,
&pdc->co.ClipObj,
@@ -1091,37 +1092,38 @@
return TRUE;
}
- psurf = dc->dclevel.pSurface;
- if (!psurf)
+ if (!dc->dclevel.pSurface)
{
Ret = FALSE;
goto cleanup;
}
pdcattr = dc->pdcattr;
-
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(dc);
-
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
Pt.x = XStart;
Pt.y = YStart;
IntLPtoDP(dc, (LPPOINT)&Pt, 1);
+ DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
+
+ /// FIXME: what about prgnVIS? And what about REAL clipping?
if (dc->prgnRao)
{
Ret = REGION_PtInRegion(dc->prgnRao, Pt.x, Pt.y);
if (Ret)
- REGION_GetRgnBox(dc->prgnRao ,(LPRECT)&DestRect);
+ REGION_GetRgnBox(dc->prgnRao, (LPRECT)&DestRect);
else
+ {
+ DC_vFinishBlit(dc, NULL);
goto cleanup;
+ }
}
else
+ {
RECTL_vSetRect(&DestRect, 0, 0, psurf->SurfObj.sizlBitmap.cx,
psurf->SurfObj.sizlBitmap.cy);
-
- DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
+ }
+
+ psurf = dc->dclevel.pSurface;
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
Modified: trunk/reactos/win32ss/gdi/ntgdi/freetype.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/freetype…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -3366,10 +3366,10 @@
BrushOrigin.x = 0;
BrushOrigin.y = 0;
- psurf = dc->dclevel.pSurface;
-
- if(!psurf)
- psurf = psurfDefaultBitmap;
+ if (!dc->dclevel.pSurface)
+ {
+ goto fail;
+ }
if ((fuOptions & ETO_OPAQUE) && lprc)
{
@@ -3388,6 +3388,7 @@
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
DC_vUpdateBackgroundBrush(dc);
+ psurf = dc->dclevel.pSurface;
IntEngBitBlt(
&psurf->SurfObj,
NULL,
@@ -3579,12 +3580,13 @@
/* Lock blit with a dummy rect */
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
+ psurf = dc->dclevel.pSurface;
SurfObj = &psurf->SurfObj ;
EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
- if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ &
DIRTY_BACKGROUND))
+ if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ &
DIRTY_BACKGROUND))
DC_vUpdateBackgroundBrush(dc) ;
if(dc->pdcattr->ulDirty_ & DIRTY_TEXT)
Modified: trunk/reactos/win32ss/gdi/ntgdi/line.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/line.c?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/line.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/line.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -100,6 +100,7 @@
RECTL Bounds;
POINT Points[2];
PDC_ATTR pdcattr = dc->pdcattr;
+ ASSERT_DC_PREPARED(dc);
if (PATH_IsPathOpen(dc->dclevel))
{
@@ -248,8 +249,7 @@
LONG i;
PDC_ATTR pdcattr = dc->pdcattr;
- psurf = dc->dclevel.pSurface;
- if (!psurf)
+ if (!dc->dclevel.pSurface)
{
return FALSE;
}
@@ -258,12 +258,7 @@
return PATH_Polyline(dc, pt, Count);
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
-
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(dc);
-
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
+ psurf = dc->dclevel.pSurface;
/* Get BRUSHOBJ from current pen. */
pbrLine = dc->dclevel.pbrLine;
@@ -411,9 +406,6 @@
rcLockRect.bottom += dc->ptlDCOrig.y;
DC_vPrepareDCsForBlit(dc, &rcLockRect, NULL, NULL);
-
- if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
Ret = IntGdiLineTo(dc, XEnd, YEnd);
Modified: trunk/reactos/win32ss/gdi/ntgdi/palette.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/palette.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/palette.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/palette.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -673,6 +673,7 @@
return CLR_INVALID;
}
+ /// FIXME: shouldn't dereference pSurface while the PDEV is not locked
if(dc->dclevel.pSurface == NULL)
ppal = gppalMono;
else
@@ -731,7 +732,7 @@
PALETTE *ppalSurf, *ppalDC;
pdc = DC_LockDc(hDC);
- if(!pdc)
+ if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
@@ -742,16 +743,17 @@
goto cleanup;
}
- if(pdc->dctype == DCTYPE_DIRECT)
- {
- UNIMPLEMENTED;
- goto cleanup;
- }
-
+ if (pdc->dctype == DCTYPE_DIRECT)
+ {
+ UNIMPLEMENTED;
+ goto cleanup;
+ }
+
+ /// FIXME: shouldn't dereference pSurface while the PDEV is not locked
ppalSurf = pdc->dclevel.pSurface->ppal;
ppalDC = pdc->dclevel.ppal;
- if(!(ppalSurf->flFlags & PAL_INDEXED))
+ if (!(ppalSurf->flFlags & PAL_INDEXED))
{
// FIXME: Set error?
goto cleanup;
@@ -762,7 +764,7 @@
// FIXME: Should we resize ppalSurf if it's too small?
realize = (ppalDC->NumColors < ppalSurf->NumColors) ? ppalDC->NumColors :
ppalSurf->NumColors;
- for(i=0; i<realize; i++)
+ for (i=0; i<realize; i++)
{
InterlockedExchange((LONG*)&ppalSurf->IndexedColors[i],
*(LONG*)&ppalDC->IndexedColors[i]);
}
@@ -993,14 +995,15 @@
return 0;
}
- /* Get the surace from the DC */
+ /* Get the surface from the DC */
psurf = pdc->dclevel.pSurface;
/* Check if we have the default surface */
if (psurf == NULL)
{
/* Use a mono palette */
- if(!bSet) ppal = gppalMono;
+ if (!bSet)
+ ppal = gppalMono;
}
else if (psurf->SurfObj.iType == STYPE_BITMAP)
{
Modified: trunk/reactos/win32ss/gdi/ntgdi/print.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/print.c?…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/print.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/print.c [iso-8859-1] Tue Dec 30 19:38:41 2014
@@ -85,15 +85,19 @@
INT OutSize,
LPSTR OutData)
{
- SURFACE *psurf = dc->dclevel.pSurface;
+ SURFACE *psurf;
INT Result;
- if (!dc->ppdev->DriverFunctions.Escape || !psurf)
+ if ((dc->ppdev->DriverFunctions.Escape == NULL) ||
+ (dc->dclevel.pSurface == NULL))
{
Result = 0;
}
else
{
+ DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
+ psurf = dc->dclevel.pSurface;
+
Result = dc->ppdev->DriverFunctions.Escape(
&psurf->SurfObj,
Escape,
@@ -101,6 +105,8 @@
(PVOID)InData,
OutSize,
(PVOID)OutData );
+
+ DC_vFinishBlit(dc, NULL);
}
return Result;