Fix bugs in pen implementation:
- Do not use the x coordinate to adjust styles, instead they start where the lines start
- Don't leak allocated styles
- Make sure the PEN fields are initialized correctly, even for BRUSHES, so that the destructor can do it's cleanup work
- Fix numerous parameter checks
gdi32_apitest:pen now shows 0 failures!

svn path=/trunk/; revision=70388
This commit is contained in:
Timo Kreuzer 2015-12-17 22:05:06 +00:00
parent 0f8f2f51ce
commit fd01add9cf
3 changed files with 61 additions and 22 deletions

View file

@ -49,13 +49,13 @@ HandleStyles(
{ {
if (deltax > deltay) if (deltax > deltay)
{ {
offStyle = (x - Translate->x) % pebo->pbrush->ulStyleSize; offStyle = (- Translate->x) % pebo->pbrush->ulStyleSize;
diStyle = dx; diStyle = dx;
lStyleMax = x; lStyleMax = x;
} }
else else
{ {
offStyle = (y - Translate->y) % pebo->pbrush->ulStyleSize; offStyle = (- Translate->y) % pebo->pbrush->ulStyleSize;
diStyle = dy; diStyle = dy;
lStyleMax = y; lStyleMax = y;
} }

View file

@ -45,6 +45,11 @@ BRUSH::BRUSH(
this->ulSurfTime = 0; this->ulSurfTime = 0;
this->pvRBrush = NULL; this->pvRBrush = NULL;
this->hdev = NULL; this->hdev = NULL;
/* FIXME: should be done only in PEN constructor,
but our destructor needs it! */
this->dwStyleCount = 0;
this->pStyle = NULL;
} }
BRUSH::~BRUSH( BRUSH::~BRUSH(
@ -63,6 +68,12 @@ BRUSH::~BRUSH(
GreSetBitmapOwner(this->hbmPattern, BASEOBJECT::OWNER::POWNED); GreSetBitmapOwner(this->hbmPattern, BASEOBJECT::OWNER::POWNED);
GreDeleteObject(this->hbmPattern); GreDeleteObject(this->hbmPattern);
} }
/* Delete styles */
if ((this->pStyle != NULL) && !(this->flAttrs & BR_IS_DEFAULTSTYLE))
{
ExFreePoolWithTag(this->pStyle, GDITAG_PENSTYLE);
}
} }
VOID VOID

View file

@ -128,7 +128,7 @@ IntGdiExtCreatePen(
pbrushPen->iBrushStyle = ulBrushStyle; pbrushPen->iBrushStyle = ulBrushStyle;
// FIXME: Copy the bitmap first ? // FIXME: Copy the bitmap first ?
pbrushPen->hbmClient = (HANDLE)ulClientHatch; pbrushPen->hbmClient = (HANDLE)ulClientHatch;
pbrushPen->dwStyleCount = dwStyleCount; pbrushPen->dwStyleCount = 0;
pbrushPen->pStyle = NULL; pbrushPen->pStyle = NULL;
pbrushPen->ulStyleSize = 0; pbrushPen->ulStyleSize = 0;
@ -152,31 +152,31 @@ IntGdiExtCreatePen(
break; break;
case PS_ALTERNATE: case PS_ALTERNATE:
pbrushPen->flAttrs |= BR_IS_SOLID; pbrushPen->flAttrs |= BR_IS_SOLID | BR_IS_DEFAULTSTYLE;
pbrushPen->pStyle = aulStyleAlternate; pbrushPen->pStyle = aulStyleAlternate;
pbrushPen->dwStyleCount = _countof(aulStyleAlternate); pbrushPen->dwStyleCount = _countof(aulStyleAlternate);
break; break;
case PS_DOT: case PS_DOT:
pbrushPen->flAttrs |= BR_IS_SOLID; pbrushPen->flAttrs |= BR_IS_SOLID | BR_IS_DEFAULTSTYLE;
pbrushPen->pStyle = aulStyleDot; pbrushPen->pStyle = aulStyleDot;
pbrushPen->dwStyleCount = _countof(aulStyleDot); pbrushPen->dwStyleCount = _countof(aulStyleDot);
break; break;
case PS_DASH: case PS_DASH:
pbrushPen->flAttrs |= BR_IS_SOLID; pbrushPen->flAttrs |= BR_IS_SOLID | BR_IS_DEFAULTSTYLE;
pbrushPen->pStyle = aulStyleDash; pbrushPen->pStyle = aulStyleDash;
pbrushPen->dwStyleCount = _countof(aulStyleDash); pbrushPen->dwStyleCount = _countof(aulStyleDash);
break; break;
case PS_DASHDOT: case PS_DASHDOT:
pbrushPen->flAttrs |= BR_IS_SOLID; pbrushPen->flAttrs |= BR_IS_SOLID | BR_IS_DEFAULTSTYLE;
pbrushPen->pStyle = aulStyleDashDot; pbrushPen->pStyle = aulStyleDashDot;
pbrushPen->dwStyleCount = _countof(aulStyleDashDot); pbrushPen->dwStyleCount = _countof(aulStyleDashDot);
break; break;
case PS_DASHDOTDOT: case PS_DASHDOTDOT:
pbrushPen->flAttrs |= BR_IS_SOLID; pbrushPen->flAttrs |= BR_IS_SOLID | BR_IS_DEFAULTSTYLE;
pbrushPen->pStyle = aulStyleDashDotDot; pbrushPen->pStyle = aulStyleDashDotDot;
pbrushPen->dwStyleCount = _countof(aulStyleDashDotDot); pbrushPen->dwStyleCount = _countof(aulStyleDashDotDot);
break; break;
@ -186,14 +186,6 @@ IntGdiExtCreatePen(
break; break;
case PS_USERSTYLE: case PS_USERSTYLE:
if ((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC)
{
/* FIXME: PS_USERSTYLE workaround */
DPRINT1("PS_COSMETIC | PS_USERSTYLE not handled\n");
pbrushPen->flAttrs |= BR_IS_SOLID;
break;
}
else
{ {
UINT i; UINT i;
BOOL has_neg = FALSE, all_zero = TRUE; BOOL has_neg = FALSE, all_zero = TRUE;
@ -228,6 +220,8 @@ IntGdiExtCreatePen(
} }
} }
NT_ASSERT((pbrushPen->dwStyleCount == 0) || (pbrushPen->pStyle != NULL));
PEN_UnlockPen(pbrushPen); PEN_UnlockPen(pbrushPen);
return hPen; return hPen;
@ -295,8 +289,9 @@ PEN_GetObject(PBRUSH pbrushPen, INT cbCount, PLOGPEN pBuffer)
} }
else else
{ {
// FIXME: Can we trust in dwStyleCount being <= 16? DWORD dwStyleCount = (pbrushPen->flAttrs & BR_IS_DEFAULTSTYLE) ?
cbRetCount = sizeof(EXTLOGPEN) - sizeof(DWORD) + pbrushPen->dwStyleCount * sizeof(DWORD); 0 : pbrushPen->dwStyleCount;
cbRetCount = sizeof(EXTLOGPEN) - sizeof(DWORD) + dwStyleCount * sizeof(DWORD);
if (pBuffer) if (pBuffer)
{ {
ULONG i; ULONG i;
@ -308,8 +303,8 @@ PEN_GetObject(PBRUSH pbrushPen, INT cbCount, PLOGPEN pBuffer)
pExtLogPen->elpBrushStyle = pbrushPen->iBrushStyle; pExtLogPen->elpBrushStyle = pbrushPen->iBrushStyle;
pExtLogPen->elpColor = pbrushPen->BrushAttr.lbColor; pExtLogPen->elpColor = pbrushPen->BrushAttr.lbColor;
pExtLogPen->elpHatch = (ULONG_PTR)pbrushPen->hbmClient; pExtLogPen->elpHatch = (ULONG_PTR)pbrushPen->hbmClient;
pExtLogPen->elpNumEntries = pbrushPen->dwStyleCount; pExtLogPen->elpNumEntries = dwStyleCount;
for (i = 0; i < pExtLogPen->elpNumEntries; i++) for (i = 0; i < dwStyleCount; i++)
{ {
pExtLogPen->elpStyleEntry[i] = pbrushPen->pStyle[i]; pExtLogPen->elpStyleEntry[i] = pbrushPen->pStyle[i];
} }
@ -375,6 +370,39 @@ NtGdiExtCreatePen(
return 0; return 0;
} }
if (((dwPenStyle & PS_TYPE_MASK) == PS_COSMETIC) &&
(ulBrushStyle != BS_SOLID))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (((dwPenStyle & PS_STYLE_MASK) == PS_NULL) ||
(ulBrushStyle == BS_NULL))
{
return StockObjects[NULL_PEN];
}
if ((ulBrushStyle == BS_PATTERN) ||
(ulBrushStyle == BS_DIBPATTERN) ||
(ulBrushStyle == BS_DIBPATTERNPT))
{
ulColor = 0;
}
else if ((ulBrushStyle != BS_SOLID) &&
(ulBrushStyle != BS_HATCHED))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if ((dwPenStyle & PS_STYLE_MASK) != PS_USERSTYLE)
{
dwStyleCount = 0;
pUnsafeStyle = NULL;
}
if (dwStyleCount > 0) if (dwStyleCount > 0)
{ {
if (pUnsafeStyle == NULL) if (pUnsafeStyle == NULL)
@ -395,8 +423,8 @@ NtGdiExtCreatePen(
{ {
ProbeForRead(pUnsafeStyle, dwStyleCount * sizeof(DWORD), 1); ProbeForRead(pUnsafeStyle, dwStyleCount * sizeof(DWORD), 1);
RtlCopyMemory(pSafeStyle, RtlCopyMemory(pSafeStyle,
pUnsafeStyle, pUnsafeStyle,
dwStyleCount * sizeof(DWORD)); dwStyleCount * sizeof(DWORD));
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {