Implement DC_hSelectFont, use it from NtGdiSelectFont and GdiFlushUserBatch. Make sure plfnt is != NULL before dereferencing it in "TEXTOBJ_LockText"

svn path=/trunk/; revision=58109
This commit is contained in:
Timo Kreuzer 2013-01-04 11:02:43 +00:00
parent fd43db5558
commit a65f18771b
4 changed files with 97 additions and 83 deletions

View file

@ -525,6 +525,85 @@ NtGdiSelectClipPath(
return success;
}
HFONT
NTAPI
DC_hSelectFont(
_In_ PDC pdc,
_In_ HFONT hlfntNew)
{
PLFONT plfntNew;
HFONT hlfntOld;
// Legacy crap that will die with font engine rewrite
if (!NT_SUCCESS(TextIntRealizeFont(hlfntNew, NULL)))
{
return NULL;
}
/* Get the current selected font */
hlfntOld = pdc->dclevel.plfnt->BaseObject.hHmgr;
/* Check if a new font should be selected */
if (hlfntNew != hlfntOld)
{
/* Lock the new font */
plfntNew = LFONT_ShareLockFont(hlfntNew);
if (plfntNew)
{
/* Success, dereference the old font */
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
/* Select the new font */
pdc->dclevel.plfnt = plfntNew;
pdc->pdcattr->hlfntNew = hlfntNew;
/* Update dirty flags */
pdc->pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
else
{
/* Failed, restore old, return NULL */
pdc->pdcattr->hlfntNew = hlfntOld;
hlfntOld = NULL;
}
}
return hlfntOld;
}
HFONT
APIENTRY
NtGdiSelectFont(
_In_ HDC hdc,
_In_ HFONT hfont)
{
HFONT hfontOld;
PDC pdc;
/* Check parameters */
if ((hdc == NULL) || (hfont == NULL))
{
return NULL;
}
/* Lock the DC */
pdc = DC_LockDc(hdc);
if (!pdc)
{
return NULL;
}
/* Call the internal function */
hfontOld = DC_hSelectFont(pdc, hfont);
/* Unlock the DC */
DC_UnlockDc(pdc);
/* Return the previously selected font */
return hfontOld;
}
HANDLE
APIENTRY
NtGdiGetDCObject(HDC hDC, INT ObjectType)

View file

@ -395,50 +395,6 @@ RealizeFontInit(HFONT hFont)
return pTextObj;
}
HFONT
FASTCALL
GreSelectFont( HDC hDC, HFONT hFont)
{
PDC pdc;
PDC_ATTR pdcattr;
PTEXTOBJ pOrgFnt, pNewFnt = NULL;
HFONT hOrgFont = NULL;
if (!hDC || !hFont) return NULL;
pdc = DC_LockDc(hDC);
if (!pdc)
{
return NULL;
}
if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
{
/* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(hFont);
pdcattr = pdc->pdcattr;
pOrgFnt = pdc->dclevel.plfnt;
if (pOrgFnt)
{
hOrgFont = pOrgFnt->BaseObject.hHmgr;
}
else
{
hOrgFont = pdcattr->hlfntNew;
}
if (pdc->dclevel.plfnt) LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject);
pdc->dclevel.plfnt = pNewFnt;
pdc->hlfntCur = hFont;
pdcattr->hlfntNew = hFont;
pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
DC_UnlockDc(pdc);
return hOrgFont;
}
/** Functions ******************************************************************/
@ -1122,17 +1078,5 @@ NtGdiHfontCreate(
return hNewFont;
}
/*
* @implemented
*/
HFONT
APIENTRY
NtGdiSelectFont(
IN HDC hDC,
IN HFONT hFont)
{
return GreSelectFont(hDC, hFont);
}
/* EOF */

View file

@ -66,7 +66,6 @@ ULONG
FASTCALL
GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
{
BOOL Hit = FALSE;
ULONG Cmd = 0, Size = 0;
PDC_ATTR pdcattr = NULL;
@ -82,27 +81,25 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Hit = TRUE;
DPRINT1("WARNING! GdiBatch Fault!\n");
_SEH2_YIELD(return 0;)
}
_SEH2_END;
if (Hit)
{
DPRINT1("WARNING! GdiBatch Fault!\n");
return 0;
}
// FYI! The thread is approaching the end of sunset.
switch(Cmd)
{
case GdiBCPatBlt: // Highest pri first!
case GdiBCPatBlt:
break;
case GdiBCPolyPatBlt:
break;
case GdiBCTextOut:
break;
case GdiBCExtTextOut:
break;
case GdiBCSetBrushOrg:
{
PGDIBSSETBRHORG pgSBO;
@ -112,40 +109,31 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y);
break;
}
case GdiBCExtSelClipRgn:
break;
case GdiBCSelObj:
{
PGDIBSOBJECT pgO;
PTEXTOBJ pNewFnt = NULL;
if (!dc) break;
pgO = (PGDIBSOBJECT) pHdr;
if (NT_SUCCESS(TextIntRealizeFont((HFONT)pgO->hgdiobj,NULL)))
{
/* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj);
if (dc->dclevel.plfnt) LFONT_ShareUnlockFont(dc->dclevel.plfnt);
if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject);
dc->dclevel.plfnt = pNewFnt;
dc->hlfntCur = pgO->hgdiobj;
pdcattr->hlfntNew = pgO->hgdiobj;
pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
DC_hSelectFont(dc, (HFONT)pgO->hgdiobj);
break;
}
case GdiBCDelRgn:
DPRINT("Delete Region Object!\n");
/* Fall through */
case GdiBCDelObj:
{
PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
GreDeleteObject( pgO->hgdiobj );
break;
}
default:
break;
}

View file

@ -85,8 +85,11 @@ FORCEINLINE
TEXTOBJ_LockText(HFONT hfont)
{
PLFONT plfnt = LFONT_ShareLockFont(hfont);
KeEnterCriticalRegion();
ExAcquirePushLockExclusive(&plfnt->lock);
if (plfnt != 0)
{
KeEnterCriticalRegion();
ExAcquirePushLockExclusive(&plfnt->lock);
}
return plfnt;
}