My first commit!

NtGdiExtTextOut:
- Unlock dc if failed
- Copy string from usermode using MmCopyFromCaller

svn path=/trunk/; revision=25352
This commit is contained in:
Timo Kreuzer 2007-01-07 21:18:34 +00:00
parent c6aab9a0e3
commit c582ada859

View file

@ -1564,7 +1564,7 @@ NtGdiExtTextOut(
INT YStart, INT YStart,
UINT fuOptions, UINT fuOptions,
CONST RECT *lprc, CONST RECT *lprc,
LPCWSTR String, LPCWSTR UnsafeString,
UINT Count, UINT Count,
CONST INT *UnsafeDx) CONST INT *UnsafeDx)
{ {
@ -1610,6 +1610,7 @@ NtGdiExtTextOut(
INT *Dx = NULL; INT *Dx = NULL;
POINT Start; POINT Start;
BOOL DoBreak = FALSE; BOOL DoBreak = FALSE;
LPCWSTR String, SafeString = NULL;
// TODO: Write test-cases to exactly match real Windows in different // TODO: Write test-cases to exactly match real Windows in different
// bad parameters (e.g. does Windows check the DC or the RECT first?). // bad parameters (e.g. does Windows check the DC or the RECT first?).
@ -1626,12 +1627,34 @@ NtGdiExtTextOut(
return TRUE; return TRUE;
} }
/* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
goto fail;
}
if (Count > 0)
{
SafeString = ExAllocatePoolWithTag(PagedPool, Count * sizeof(WCHAR), TAG_GDITEXT);
if (!SafeString)
{
goto fail;
}
Status = MmCopyFromCaller(SafeString, UnsafeString, Count * sizeof(WCHAR));
if (! NT_SUCCESS(Status))
{
goto fail;
}
}
String = SafeString;
if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED))) if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
{ {
// At least one of the two flags were specified. Copy lprc. Once. // At least one of the two flags were specified. Copy lprc. Once.
Status = MmCopyFromCaller(&SpecifiedDestRect, lprc, sizeof(RECT)); Status = MmCopyFromCaller(&SpecifiedDestRect, lprc, sizeof(RECT));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@ -1994,7 +2017,7 @@ NtGdiExtTextOut(
{ {
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
FT_Done_Glyph(realglyph); FT_Done_Glyph(realglyph);
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto fail;
} }
SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
@ -2071,6 +2094,10 @@ NtGdiExtTextOut(
} }
BRUSHOBJ_UnlockBrush(BrushFg); BRUSHOBJ_UnlockBrush(BrushFg);
NtGdiDeleteObject(hBrushFg); NtGdiDeleteObject(hBrushFg);
if (NULL != SafeString)
{
ExFreePool((void*)SafeString);
}
if (NULL != Dx) if (NULL != Dx)
{ {
ExFreePool(Dx); ExFreePool(Dx);
@ -2097,6 +2124,10 @@ fail:
BRUSHOBJ_UnlockBrush(BrushFg); BRUSHOBJ_UnlockBrush(BrushFg);
NtGdiDeleteObject(hBrushFg); NtGdiDeleteObject(hBrushFg);
} }
if (NULL != SafeString)
{
ExFreePool((void*)SafeString);
}
if (NULL != Dx) if (NULL != Dx)
{ {
ExFreePool(Dx); ExFreePool(Dx);