Jeffrey Morlan (mrnobo1024 at yahoo.com) - Fix ModifyWorldTransform multiplies. See bug 3314.

svn path=/trunk/; revision=34078
This commit is contained in:
James Tabor 2008-06-25 11:47:12 +00:00
parent 93bd1eebe6
commit b7525df85d

View file

@ -68,6 +68,7 @@ IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1, LPXFORM xform1,
LPXFORM xform2) LPXFORM xform2)
{ {
XFORM xformTemp;
/* Check for illegal parameters */ /* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2) if (!XFormResult || !xform1 || !xform2)
{ {
@ -76,12 +77,13 @@ IntGdiCombineTransform(LPXFORM XFormResult,
/* Create the result in a temporary XFORM, since xformResult may be /* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */ * equal to xform1 or xform2 */
XFormResult->eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21; xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
XFormResult->eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22; xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
XFormResult->eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21; xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
XFormResult->eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22; xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
XFormResult->eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx; xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
XFormResult->eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy; xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
*XFormResult = xformTemp;
return TRUE; return TRUE;
} }
@ -90,9 +92,6 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
LPXFORM Unsafexform1, LPXFORM Unsafexform1,
LPXFORM Unsafexform2) LPXFORM Unsafexform2)
{ {
XFORM xformTemp;
XFORM xform1 = {0}, xform2 = {0};
NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret; BOOL Ret;
_SEH_TRY _SEH_TRY
@ -106,41 +105,14 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
ProbeForRead(Unsafexform2, ProbeForRead(Unsafexform2,
sizeof(XFORM), sizeof(XFORM),
1); 1);
xform1 = *Unsafexform1; Ret = IntGdiCombineTransform(UnsafeXFormResult, Unsafexform1, Unsafexform2);
xform2 = *Unsafexform2;
} }
_SEH_HANDLE _SEH_HANDLE
{ {
Status = _SEH_GetExceptionCode(); Ret = FALSE;
} }
_SEH_END; _SEH_END;
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
/* Copy the result to xformResult */
_SEH_TRY
{
/* pointer was already probed! */
*UnsafeXFormResult = xformTemp;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return Ret; return Ret;
} }
@ -185,7 +157,7 @@ IntGdiModifyWorldTransform(PDC pDc,
CONST LPXFORM lpXForm, CONST LPXFORM lpXForm,
DWORD Mode) DWORD Mode)
{ {
ASSERT(pDc && lpXForm); ASSERT(pDc);
switch(Mode) switch(Mode)
{ {
@ -211,7 +183,6 @@ IntGdiModifyWorldTransform(PDC pDc,
break; break;
default: default:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
DC_UpdateXforms(pDc); DC_UpdateXforms(pDc);
@ -418,13 +389,7 @@ NtGdiModifyWorldTransform(HDC hDC,
{ {
PDC dc; PDC dc;
XFORM SafeXForm; XFORM SafeXForm;
BOOL Ret = FALSE; BOOL Ret = TRUE;
if (!UnsafeXForm)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
@ -433,6 +398,10 @@ NtGdiModifyWorldTransform(HDC hDC,
return FALSE; return FALSE;
} }
// The xform is permitted to be NULL for MWT_IDENTITY.
// However, if it is not NULL, then it must be valid even though it is not used.
if (UnsafeXForm != NULL || Mode != MWT_IDENTITY)
{
_SEH_TRY _SEH_TRY
{ {
ProbeForRead(UnsafeXForm, sizeof(XFORM), 1); ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
@ -440,12 +409,13 @@ NtGdiModifyWorldTransform(HDC hDC,
} }
_SEH_HANDLE _SEH_HANDLE
{ {
SetLastNtError(_SEH_GetExceptionCode()); Ret = FALSE;
} }
_SEH_END; _SEH_END;
}
// Safe to handle kernel mode data. // Safe to handle kernel mode data.
Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode); if (Ret) Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
DC_UnlockDc(dc); DC_UnlockDc(dc);
return Ret; return Ret;
} }