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.c... ============================================================================== --- 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?re... ============================================================================== --- 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.c... ============================================================================== --- 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?r... ============================================================================== --- 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;