From d7702b47f9294f935bd57a8ddc9cb973916b18b5 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 26 Jul 2005 12:22:55 +0000 Subject: [PATCH] removed some MmCopyTo/FromCaller calls from win32k's GDI svn path=/trunk/; revision=16738 --- reactos/subsys/win32k/objects/brush.c | 54 ++++- reactos/subsys/win32k/objects/cliprgn.c | 31 ++- reactos/subsys/win32k/objects/coord.c | 272 ++++++++++++++++++----- reactos/subsys/win32k/objects/dc.c | 100 ++++++++- reactos/subsys/win32k/objects/fillshap.c | 130 +++++++++-- reactos/subsys/win32k/objects/line.c | 203 +++++++++++++++-- reactos/subsys/win32k/objects/pen.c | 16 +- reactos/subsys/win32k/objects/print.c | 71 +++++- reactos/subsys/win32k/objects/rect.c | 150 ++++++++++--- reactos/subsys/win32k/objects/region.c | 243 +++++++++++++++++--- 10 files changed, 1092 insertions(+), 178 deletions(-) diff --git a/reactos/subsys/win32k/objects/brush.c b/reactos/subsys/win32k/objects/brush.c index b8d6803862a..0c89d915288 100644 --- a/reactos/subsys/win32k/objects/brush.c +++ b/reactos/subsys/win32k/objects/brush.c @@ -563,7 +563,7 @@ NtGdiCreateDIBBrush( CONST VOID *PackedDIB) { BITMAPINFO *SafeBitmapInfoAndData; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; HBRUSH hBrush; SafeBitmapInfoAndData = EngAllocMem(0, BitmapInfoSize, 0); @@ -573,10 +573,24 @@ NtGdiCreateDIBBrush( return NULL; } - Status = MmCopyFromCaller(SafeBitmapInfoAndData, BitmapInfoAndData, - BitmapInfoSize); + _SEH_TRY + { + ProbeForRead(BitmapInfoAndData, + BitmapInfoSize, + 1); + RtlCopyMemory(SafeBitmapInfoAndData, + BitmapInfoAndData, + BitmapInfoSize); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) { + EngFreeMem(SafeBitmapInfoAndData); SetLastNtError(Status); return 0; } @@ -632,11 +646,23 @@ NtGdiSetBrushOrgEx(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point) if (Point != NULL) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; POINT SafePoint; SafePoint.x = dc->w.brushOrgX; SafePoint.y = dc->w.brushOrgY; - Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT)); + _SEH_TRY + { + ProbeForWrite(Point, + sizeof(POINT), + 1); + *Point = SafePoint; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -661,7 +687,7 @@ NtGdiPolyPatBlt( ULONG Reserved) { PPATRECT rb = NULL; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; if (cRects > 0) @@ -672,7 +698,21 @@ NtGdiPolyPatBlt( SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - Status = MmCopyFromCaller(rb, pRects, sizeof(PATRECT) * cRects); + _SEH_TRY + { + ProbeForRead(pRects, + cRects * sizeof(PATRECT), + 1); + RtlCopyMemory(rb, + pRects, + cRects * sizeof(PATRECT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) { ExFreePool(rb); diff --git a/reactos/subsys/win32k/objects/cliprgn.c b/reactos/subsys/win32k/objects/cliprgn.c index 8990b2b082c..599318f0428 100644 --- a/reactos/subsys/win32k/objects/cliprgn.c +++ b/reactos/subsys/win32k/objects/cliprgn.c @@ -192,7 +192,19 @@ int STDCALL NtGdiGetClipBox(HDC hDC, Ret = IntGdiGetClipBox(hDC, &Saferect); - Status = MmCopyToCaller(rc, &Saferect, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(rc, + sizeof(RECT), + 1); + *rc = Saferect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { @@ -341,7 +353,7 @@ BOOL STDCALL NtGdiPtVisible(HDC hDC, BOOL STDCALL NtGdiRectVisible(HDC hDC, CONST PRECT UnsafeRect) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PROSRGNDATA Rgn; PDC dc = DC_LockDc(hDC); BOOL Result = FALSE; @@ -353,10 +365,23 @@ BOOL STDCALL NtGdiRectVisible(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(UnsafeRect, + sizeof(RECT), + 1); + Rect = *UnsafeRect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); + SetLastNtError(Status); return FALSE; } diff --git a/reactos/subsys/win32k/objects/coord.c b/reactos/subsys/win32k/objects/coord.c index b0e94d53968..612ff02999c 100644 --- a/reactos/subsys/win32k/objects/coord.c +++ b/reactos/subsys/win32k/objects/coord.c @@ -63,17 +63,29 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult, { XFORM xformTemp; XFORM xform1, xform2; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; - - Status = MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) ); - if(!NT_SUCCESS(Status)) + _SEH_TRY { - SetLastNtError(Status); - return FALSE; + ProbeForWrite(UnsafeXFormResult, + sizeof(XFORM), + 1); + ProbeForRead(Unsafexform1, + sizeof(XFORM), + 1); + ProbeForRead(Unsafexform2, + sizeof(XFORM), + 1); + xform1 = *Unsafexform1; + xform2 = *Unsafexform2; } - Status = MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) ); + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -83,7 +95,17 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult, Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2); /* Copy the result to xformResult */ - Status = MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) ); + _SEH_TRY + { + /* pointer was already probed! */ + *UnsafeXFormResult = xformTemp; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -131,7 +153,7 @@ NtGdiDPtoLP(HDC hDC, int Count) { PDC dc; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; LPPOINT Points; ULONG Size; @@ -159,7 +181,21 @@ NtGdiDPtoLP(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(Points, UnsafePoints, Size); + _SEH_TRY + { + ProbeForWrite(UnsafePoints, + Size, + 1); + RtlCopyMemory(Points, + UnsafePoints, + Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -170,7 +206,19 @@ NtGdiDPtoLP(HDC hDC, IntDPtoLP(dc, Points, Count); - Status = MmCopyToCaller(UnsafePoints, Points, Size); + _SEH_TRY + { + /* pointer was already probed! */ + RtlCopyMemory(UnsafePoints, + Points, + Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -218,7 +266,7 @@ NtGdiGetWorldTransform(HDC hDC, LPXFORM XForm) { PDC dc; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; dc = DC_LockDc ( hDC ); if (!dc) @@ -233,7 +281,18 @@ NtGdiGetWorldTransform(HDC hDC, return FALSE; } - Status = MmCopyToCaller(XForm, &dc->w.xformWorld2Wnd, sizeof(XFORM)); + _SEH_TRY + { + ProbeForWrite(XForm, + sizeof(XFORM), + 1); + *XForm = dc->w.xformWorld2Wnd; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; DC_UnlockDc(dc); return NT_SUCCESS(Status); @@ -280,7 +339,7 @@ BOOL STDCALL NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) { PDC dc; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; LPPOINT Points; ULONG Size; @@ -308,7 +367,21 @@ NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) return FALSE; } - Status = MmCopyFromCaller(Points, UnsafePoints, Size); + _SEH_TRY + { + ProbeForWrite(UnsafePoints, + Size, + 1); + RtlCopyMemory(Points, + UnsafePoints, + Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -319,7 +392,19 @@ NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) IntLPtoDP(dc, Points, Count); - Status = MmCopyToCaller(UnsafePoints, Points, Size); + _SEH_TRY + { + /* pointer was already probed! */ + RtlCopyMemory(UnsafePoints, + Points, + Size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -341,7 +426,7 @@ NtGdiModifyWorldTransform(HDC hDC, { PDC dc; XFORM SafeXForm; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; dc = DC_LockDc(hDC); if (!dc) @@ -357,7 +442,19 @@ NtGdiModifyWorldTransform(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(&SafeXForm, UnsafeXForm, sizeof(XFORM)); + _SEH_TRY + { + ProbeForRead(UnsafeXForm, + sizeof(XFORM), + 1); + SafeXForm = *UnsafeXForm; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -403,8 +500,7 @@ NtGdiOffsetViewportOrgEx(HDC hDC, LPPOINT UnsafePoint) { PDC dc; - POINT Point; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; dc = DC_LockDc ( hDC ); if(!dc) @@ -415,9 +511,20 @@ NtGdiOffsetViewportOrgEx(HDC hDC, if (UnsafePoint) { - Point.x = dc->vportOrgX; - Point.y = dc->vportOrgY; - Status = MmCopyToCaller(UnsafePoint, &Point, sizeof(POINT)); + _SEH_TRY + { + ProbeForWrite(UnsafePoint, + sizeof(POINT), + 1); + UnsafePoint->x = dc->vportOrgX; + UnsafePoint->y = dc->vportOrgY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if ( !NT_SUCCESS(Status) ) { SetLastNtError(Status); @@ -452,13 +559,22 @@ NtGdiOffsetWindowOrgEx(HDC hDC, if (Point) { - POINT SafePoint; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForWrite(Point, + sizeof(POINT), + 1); + Point->x = dc->wndOrgX; + Point->y = dc->wndOrgY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - SafePoint.x = dc->wndOrgX; - SafePoint.y = dc->wndOrgY; - - Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -594,13 +710,22 @@ NtGdiSetViewportExtEx(HDC hDC, if (Size) { - SIZE SafeSize; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; - SafeSize.cx = dc->vportExtX; - SafeSize.cy = dc->vportExtY; + _SEH_TRY + { + ProbeForWrite(Size, + sizeof(SIZE), + 1); + Size->cx = dc->vportExtX; + Size->cy = dc->vportExtY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -636,13 +761,22 @@ NtGdiSetViewportOrgEx(HDC hDC, if (Point) { - POINT SafePoint; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForWrite(Point, + sizeof(POINT), + 1); + Point->x = dc->vportOrgX; + Point->y = dc->vportOrgY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - SafePoint.x = dc->vportOrgX; - SafePoint.y = dc->vportOrgY; - - Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -690,13 +824,22 @@ NtGdiSetWindowExtEx(HDC hDC, if (Size) { - SIZE SafeSize; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForWrite(Size, + sizeof(SIZE), + 1); + Size->cx = dc->wndExtX; + Size->cy = dc->wndExtY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - SafeSize.cx = dc->wndExtX; - SafeSize.cy = dc->wndExtY; - - Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -732,13 +875,22 @@ NtGdiSetWindowOrgEx(HDC hDC, if (Point) { - POINT SafePoint; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForWrite(Point, + sizeof(POINT), + 1); + Point->x = dc->wndOrgX; + Point->y = dc->wndOrgY; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - SafePoint.x = dc->wndOrgX; - SafePoint.y = dc->wndOrgY; - - Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -762,7 +914,7 @@ NtGdiSetWorldTransform(HDC hDC, CONST LPXFORM XForm) { PDC dc; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; dc = DC_LockDc (hDC); if ( !dc ) @@ -785,7 +937,19 @@ NtGdiSetWorldTransform(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(&dc->w.xformWorld2Wnd, XForm, sizeof(XFORM)); + _SEH_TRY + { + ProbeForRead(XForm, + sizeof(XFORM), + 1); + dc->w.xformWorld2Wnd = *XForm; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 676dc2d8d1b..e436def9dd3 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -69,7 +69,7 @@ VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \ } \ BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \ { \ - NTSTATUS Status; \ + NTSTATUS Status = STATUS_SUCCESS; \ type Safept; \ PDC dc; \ if(!pt) \ @@ -84,7 +84,18 @@ BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \ } \ Int##FuncName( dc, &Safept); \ DC_UnlockDc(dc); \ - Status = MmCopyToCaller(pt, &Safept, sizeof( type )); \ + _SEH_TRY \ + { \ + ProbeForWrite(pt, \ + sizeof( type ), \ + 1); \ + *pt = Safept; \ + } \ + _SEH_HANDLE \ + { \ + Status = _SEH_GetExceptionCode(); \ + } \ + _SEH_END; \ if(!NT_SUCCESS(Status)) \ { \ SetLastNtError(Status); \ @@ -830,11 +841,25 @@ NtGdiCreateDC(PUNICODE_STRING Driver, UNICODE_STRING SafeDriver, SafeDevice; DEVMODEW SafeInitData; HDC Ret; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; if(InitData) { - Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW)); + _SEH_TRY + { + ProbeForRead(InitData, + sizeof(DEVMODEW), + 1); + RtlCopyMemory(&SafeInitData, + InitData, + sizeof(DEVMODEW)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -878,11 +903,24 @@ NtGdiCreateIC(PUNICODE_STRING Driver, UNICODE_STRING SafeDriver, SafeDevice; DEVMODEW SafeInitData; HDC Ret; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; if(InitData) { - Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW)); + _SEH_TRY + { + ProbeForRead(InitData, + sizeof(DEVMODEW), + 1); + RtlCopyMemory(&SafeInitData, + InitData, + sizeof(DEVMODEW)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -1076,7 +1114,7 @@ NtGdiGetDCOrgEx(HDC hDC, LPPOINT Point) BOOL Ret; DC *dc; POINT SafePoint; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; if(!Point) { @@ -1093,7 +1131,19 @@ NtGdiGetDCOrgEx(HDC hDC, LPPOINT Point) Ret = IntGdiGetDCOrgEx(dc, &SafePoint); - Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT)); + _SEH_TRY + { + ProbeForWrite(Point, + sizeof(POINT), + 1); + *Point = SafePoint; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -1621,12 +1671,30 @@ NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer) { INT Ret; LPVOID SafeBuf; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; if (count <= 0) { return 0; } + + _SEH_TRY + { + ProbeForWrite(buffer, + count, + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return 0; + } SafeBuf = ExAllocatePoolWithTag(PagedPool, count, TAG_GDIOBJ); if(!SafeBuf) @@ -1637,7 +1705,19 @@ NtGdiGetObject(HANDLE handle, INT count, LPVOID buffer) Ret = IntGdiGetObject(handle, count, SafeBuf); - Status = MmCopyToCaller(buffer, SafeBuf, count); + _SEH_TRY + { + /* pointer already probed! */ + RtlCopyMemory(buffer, + SafeBuf, + count); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + ExFreePool(SafeBuf); if(!NT_SUCCESS(Status)) { diff --git a/reactos/subsys/win32k/objects/fillshap.c b/reactos/subsys/win32k/objects/fillshap.c index 8cfea2c5833..8c6a557abb5 100644 --- a/reactos/subsys/win32k/objects/fillshap.c +++ b/reactos/subsys/win32k/objects/fillshap.c @@ -845,7 +845,7 @@ NtGdiPolygon(HDC hDC, { DC *dc; LPPOINT Safept; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = FALSE; if ( Count < 2 ) @@ -853,6 +853,24 @@ NtGdiPolygon(HDC hDC, SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } + + _SEH_TRY + { + ProbeForRead(UnsafePoints, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } dc = DC_LockDc(hDC); if(!dc) @@ -870,7 +888,19 @@ NtGdiPolygon(HDC hDC, SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); else { - Status = MmCopyFromCaller(Safept, UnsafePoints, sizeof(POINT) * Count); + _SEH_TRY + { + /* pointer was already probed! */ + RtlCopyMemory(Safept, + UnsafePoints, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) SetLastNtError(Status); else @@ -913,6 +943,28 @@ NtGdiPolyPolygon(HDC hDC, if(Count > 0) { + _SEH_TRY + { + ProbeForRead(Points, + Count * sizeof(POINT), + 1); + ProbeForRead(PolyCounts, + Count * sizeof(INT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, (sizeof(POINT) + sizeof(INT)) * Count, TAG_SHAPE); if(!Safept) { @@ -922,16 +974,23 @@ NtGdiPolyPolygon(HDC hDC, } SafePolyPoints = (LPINT)&Safept[Count]; - - Status = MmCopyFromCaller(Safept, Points, sizeof(POINT) * Count); - if(!NT_SUCCESS(Status)) + + _SEH_TRY { - DC_UnlockDc(dc); - ExFreePool(Safept); - SetLastNtError(Status); - return FALSE; + /* pointers already probed! */ + RtlCopyMemory(Safept, + Points, + Count * sizeof(POINT)); + RtlCopyMemory(SafePolyPoints, + PolyCounts, + Count * sizeof(INT)); } - Status = MmCopyFromCaller(SafePolyPoints, PolyCounts, sizeof(INT) * Count); + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -1520,7 +1579,7 @@ NtGdiGradientFill( PTRIVERTEX SafeVertex; PVOID SafeMesh; ULONG SizeMesh; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; dc = DC_LockDc(hdc); if(!dc) @@ -1555,6 +1614,28 @@ NtGdiGradientFill( SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } + + _SEH_TRY + { + ProbeForRead(pVertex, + uVertex * sizeof(TRIVERTEX), + 1); + ProbeForRead(pMesh, + SizeMesh, + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastWin32Error(Status); + return FALSE; + } if(!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE))) { @@ -1562,16 +1643,25 @@ NtGdiGradientFill( SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - Status = MmCopyFromCaller(SafeVertex, pVertex, uVertex * sizeof(TRIVERTEX)); - if(!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - ExFreePool(SafeVertex); - SetLastNtError(Status); - return FALSE; - } + SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex); - Status = MmCopyFromCaller(SafeMesh, pMesh, SizeMesh); + + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(SafeVertex, + pVertex, + uVertex * sizeof(TRIVERTEX)); + RtlCopyMemory(SafeMesh, + pMesh, + SizeMesh); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); diff --git a/reactos/subsys/win32k/objects/line.c b/reactos/subsys/win32k/objects/line.c index 0d7f1f67eb2..754a788d933 100644 --- a/reactos/subsys/win32k/objects/line.c +++ b/reactos/subsys/win32k/objects/line.c @@ -503,7 +503,7 @@ NtGdiMoveToEx(HDC hDC, { DC *dc; POINT SafePoint; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -521,7 +521,19 @@ NtGdiMoveToEx(HDC hDC, if(Point) { - Status = MmCopyFromCaller(&SafePoint, Point, sizeof(POINT)); + _SEH_TRY + { + ProbeForRead(Point, + sizeof(POINT), + 1); + SafePoint = *Point; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -544,7 +556,7 @@ NtGdiPolyBezier(HDC hDC, { DC *dc; LPPOINT Safept; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -562,6 +574,25 @@ NtGdiPolyBezier(HDC hDC, if(Count > 0) { + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_BEZIER); if(!Safept) { @@ -570,7 +601,19 @@ NtGdiPolyBezier(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(Safept, pt, sizeof(POINT) * Count); + _SEH_TRY + { + /* pointers were already probed */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -601,7 +644,7 @@ NtGdiPolyBezierTo(HDC hDC, { DC *dc; LPPOINT Safept; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -619,6 +662,25 @@ NtGdiPolyBezierTo(HDC hDC, if(Count > 0) { + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_BEZIER); if(!Safept) { @@ -627,7 +689,19 @@ NtGdiPolyBezierTo(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(Safept, pt, sizeof(POINT) * Count); + _SEH_TRY + { + /* pointers were already probed */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -669,7 +743,7 @@ NtGdiPolyline(HDC hDC, { DC *dc; LPPOINT Safept; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -687,6 +761,25 @@ NtGdiPolyline(HDC hDC, if(Count >= 2) { + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE); if(!Safept) { @@ -695,7 +788,19 @@ NtGdiPolyline(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(Safept, pt, sizeof(POINT) * Count); + _SEH_TRY + { + /* pointers were already probed */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -726,7 +831,7 @@ NtGdiPolylineTo(HDC hDC, { DC *dc; LPPOINT Safept; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -744,6 +849,25 @@ NtGdiPolylineTo(HDC hDC, if(Count > 0) { + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE); if(!Safept) { @@ -752,7 +876,19 @@ NtGdiPolylineTo(HDC hDC, return FALSE; } - Status = MmCopyFromCaller(Safept, pt, sizeof(POINT) * Count); + _SEH_TRY + { + /* pointers were already probed */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); @@ -785,7 +921,7 @@ NtGdiPolyPolyline(HDC hDC, DC *dc; LPPOINT Safept; LPDWORD SafePolyPoints; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; dc = DC_LockDc(hDC); @@ -803,6 +939,28 @@ NtGdiPolyPolyline(HDC hDC, if(Count > 0) { + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + ProbeForRead(PolyPoints, + Count * sizeof(DWORD), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(dc); + SetLastNtError(Status); + return FALSE; + } + Safept = ExAllocatePoolWithTag(PagedPool, (sizeof(POINT) + sizeof(DWORD)) * Count, TAG_SHAPE); if(!Safept) { @@ -812,16 +970,23 @@ NtGdiPolyPolyline(HDC hDC, } SafePolyPoints = (LPDWORD)&Safept[Count]; - - Status = MmCopyFromCaller(Safept, pt, sizeof(POINT) * Count); - if(!NT_SUCCESS(Status)) + + _SEH_TRY { - DC_UnlockDc(dc); - ExFreePool(Safept); - SetLastNtError(Status); - return FALSE; + /* pointers were already probed */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + RtlCopyMemory(SafePolyPoints, + PolyPoints, + Count * sizeof(DWORD)); } - Status = MmCopyFromCaller(SafePolyPoints, PolyPoints, sizeof(DWORD) * Count); + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if(!NT_SUCCESS(Status)) { DC_UnlockDc(dc); diff --git a/reactos/subsys/win32k/objects/pen.c b/reactos/subsys/win32k/objects/pen.c index 90383c0ef39..c634f6d9f50 100644 --- a/reactos/subsys/win32k/objects/pen.c +++ b/reactos/subsys/win32k/objects/pen.c @@ -97,9 +97,21 @@ HPEN STDCALL NtGdiCreatePenIndirect(CONST PLOGPEN LogPen) { LOGPEN SafeLogPen; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForRead(LogPen, + sizeof(LOGPEN), + 1); + SafeLogPen = *LogPen; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - Status = MmCopyFromCaller(&SafeLogPen, LogPen, sizeof(LOGPEN)); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); diff --git a/reactos/subsys/win32k/objects/print.c b/reactos/subsys/win32k/objects/print.c index bd4a0ba2362..8f328318029 100644 --- a/reactos/subsys/win32k/objects/print.c +++ b/reactos/subsys/win32k/objects/print.c @@ -154,7 +154,7 @@ NtGdiExtEscape( PDC pDC = DC_LockDc(hDC); LPVOID SafeInData = NULL; LPVOID SafeOutData = NULL; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; INT Result; if ( pDC == NULL ) @@ -170,6 +170,25 @@ NtGdiExtEscape( if ( InSize && UnsafeInData ) { + _SEH_TRY + { + ProbeForRead(UnsafeInData, + InSize, + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DC_UnlockDc(pDC); + SetLastNtError(Status); + return -1; + } + SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, TAG_PRINT ); if ( !SafeInData ) { @@ -177,7 +196,20 @@ NtGdiExtEscape( SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return -1; } - Status = MmCopyFromCaller ( SafeInData, UnsafeInData, InSize ); + + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(SafeInData, + UnsafeInData, + InSize); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if ( !NT_SUCCESS(Status) ) { ExFreePool ( SafeInData ); @@ -189,13 +221,32 @@ NtGdiExtEscape( if ( OutSize && UnsafeOutData ) { + _SEH_TRY + { + ProbeForWrite(UnsafeOutData, + OutSize, + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + goto freeout; + } + SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, TAG_PRINT ); if ( !SafeOutData ) { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); +freeout: if ( SafeInData ) ExFreePool ( SafeInData ); DC_UnlockDc(pDC); - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return -1; } } @@ -209,7 +260,19 @@ NtGdiExtEscape( if ( SafeOutData ) { - Status = MmCopyToCaller ( UnsafeOutData, SafeOutData, OutSize ); + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(UnsafeOutData, + SafeOutData, + OutSize); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + ExFreePool ( SafeOutData ); if ( !NT_SUCCESS(Status) ) { diff --git a/reactos/subsys/win32k/objects/rect.c b/reactos/subsys/win32k/objects/rect.c index 1d6289ac093..4ebda5b6dc1 100644 --- a/reactos/subsys/win32k/objects/rect.c +++ b/reactos/subsys/win32k/objects/rect.c @@ -35,11 +35,23 @@ BOOL STDCALL NtGdiSetEmptyRect(PRECT UnsafeRect) { RECT Rect; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; IntGdiSetEmptyRect(&Rect); - Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(UnsafeRect, + sizeof(RECT), + 1); + *UnsafeRect = Rect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -59,9 +71,20 @@ BOOL STDCALL NtGdiIsEmptyRect(const RECT* UnsafeRect) { RECT Rect; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; - Status = MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(UnsafeRect, + sizeof(RECT), + 1); + Rect = *UnsafeRect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -84,9 +107,20 @@ BOOL STDCALL NtGdiOffsetRect(LPRECT UnsafeRect, INT x, INT y) { RECT Rect; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; - Status = MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(UnsafeRect, + sizeof(RECT), + 1); + Rect = *UnsafeRect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -95,7 +129,18 @@ NtGdiOffsetRect(LPRECT UnsafeRect, INT x, INT y) IntGdiOffsetRect(&Rect, x, y); - Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(UnsafeRect, + sizeof(RECT), + 1); + *UnsafeRect = Rect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -142,16 +187,25 @@ BOOL STDCALL NtGdiUnionRect(PRECT UnsafeDest, const RECT* UnsafeSrc1, const RECT* UnsafeSrc2) { RECT Dest, Src1, Src2; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; - Status = MmCopyFromCaller(&Src1, UnsafeSrc1, sizeof(RECT)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return FALSE; - } - Status = MmCopyFromCaller(&Src2, UnsafeSrc2, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(UnsafeSrc1, + sizeof(RECT), + 1); + ProbeForRead(UnsafeSrc2, + sizeof(RECT), + 1); + Src1 = *UnsafeSrc1; + Src2 = *UnsafeSrc2; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -162,7 +216,18 @@ NtGdiUnionRect(PRECT UnsafeDest, const RECT* UnsafeSrc1, const RECT* UnsafeSrc2) if (Ret) { - Status = MmCopyToCaller(UnsafeDest, &Dest, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(UnsafeDest, + sizeof(RECT), + 1); + *UnsafeDest = Dest; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -186,11 +251,22 @@ BOOL STDCALL NtGdiSetRect(PRECT UnsafeRect, INT left, INT top, INT right, INT bottom) { RECT Rect; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; IntGdiSetRect(&Rect, left, top, right, bottom); - Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(UnsafeRect, + sizeof(RECT), + 1); + *UnsafeRect = Rect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -223,16 +299,25 @@ BOOL STDCALL NtGdiIntersectRect(PRECT UnsafeDest, const RECT* UnsafeSrc1, const RECT* UnsafeSrc2) { RECT Dest, Src1, Src2; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOL Ret; - Status = MmCopyFromCaller(&Src1, UnsafeSrc1, sizeof(RECT)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return FALSE; - } - Status = MmCopyFromCaller(&Src2, UnsafeSrc2, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(UnsafeSrc1, + sizeof(RECT), + 1); + ProbeForRead(UnsafeSrc2, + sizeof(RECT), + 1); + Src1 = *UnsafeSrc1; + Src2 = *UnsafeSrc2; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -243,7 +328,18 @@ NtGdiIntersectRect(PRECT UnsafeDest, const RECT* UnsafeSrc1, const RECT* UnsafeS if (Ret) { - Status = MmCopyToCaller(UnsafeDest, &Dest, sizeof(RECT)); + _SEH_TRY + { + ProbeForWrite(UnsafeDest, + sizeof(RECT), + 1); + *UnsafeDest = Dest; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (! NT_SUCCESS(Status)) { SetLastNtError(Status); diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index 31418c04591..0b39ef1a146 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -2029,9 +2029,20 @@ STDCALL NtGdiCreateEllipticRgnIndirect(CONST PRECT Rect) { RECT SafeRect; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; - Status = MmCopyFromCaller(&SafeRect, Rect, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(Rect, + sizeof(RECT), + 1); + SafeRect = *Rect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -2063,9 +2074,20 @@ HRGN STDCALL NtGdiCreateRectRgnIndirect(CONST PRECT rc) { RECT SafeRc; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; - Status = MmCopyFromCaller(&SafeRc, rc, sizeof(RECT)); + _SEH_TRY + { + ProbeForRead(rc, + sizeof(RECT), + 1); + SafeRc = *rc; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { return(NULL); @@ -2229,9 +2251,9 @@ NtGdiExtCreateRegion(CONST XFORM *Xform, CONST RGNDATA *RgnData) { HRGN hRgn; - RGNDATA SafeRgnData; PROSRGNDATA Region; - NTSTATUS Status; + DWORD nCount = 0; + NTSTATUS Status = STATUS_SUCCESS; if (Count < FIELD_OFFSET(RGNDATA, Buffer)) { @@ -2239,14 +2261,30 @@ NtGdiExtCreateRegion(CONST XFORM *Xform, return NULL; } - Status = MmCopyFromCaller(&SafeRgnData, RgnData, min(Count, sizeof(RGNDATA))); + _SEH_TRY + { + ProbeForRead(RgnData, + Count, + 1); + nCount = RgnData->rdh.nCount; + if((Count - FIELD_OFFSET(RGNDATA, Buffer)) / sizeof(RECT) < nCount) + { + Status = STATUS_INVALID_PARAMETER; + _SEH_LEAVE; + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { - SetLastWin32Error(ERROR_INVALID_PARAMETER); + SetLastNtError(Status); return NULL; } - hRgn = RGNDATA_AllocRgn(SafeRgnData.rdh.nCount); + hRgn = RGNDATA_AllocRgn(nCount); if (hRgn == NULL) { SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); @@ -2260,10 +2298,20 @@ NtGdiExtCreateRegion(CONST XFORM *Xform, return FALSE; } - RtlCopyMemory(&Region->rdh, &SafeRgnData, FIELD_OFFSET(RGNDATA, Buffer)); - - Status = MmCopyFromCaller(Region->Buffer, RgnData->Buffer, - Count - FIELD_OFFSET(RGNDATA, Buffer)); + _SEH_TRY + { + RtlCopyMemory(&Region->rdh, + RgnData, + FIELD_OFFSET(RGNDATA, Buffer)); + RtlCopyMemory(Region->Buffer, + RgnData->Buffer, + Count - FIELD_OFFSET(RGNDATA, Buffer)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -2354,6 +2402,7 @@ NtGdiGetRgnBox(HRGN hRgn, PROSRGNDATA Rgn; RECT SafeRect; DWORD ret; + NTSTATUS Status = STATUS_SUCCESS; if (!(Rgn = RGNDATA_LockRgn(hRgn))) { @@ -2367,7 +2416,19 @@ NtGdiGetRgnBox(HRGN hRgn, return ret; } - if (!NT_SUCCESS(MmCopyToCaller(pRect, &SafeRect, sizeof(RECT)))) + _SEH_TRY + { + ProbeForWrite(pRect, + sizeof(RECT), + 1); + *pRect = SafeRect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) { return ERROR; } @@ -2576,15 +2637,30 @@ NtGdiRectInRegion(HRGN hRgn, PROSRGNDATA Rgn; RECT rc; BOOL Ret; + NTSTATUS Status = STATUS_SUCCESS; if(!(Rgn = RGNDATA_LockRgn(hRgn))) { return ERROR; } - if (!NT_SUCCESS(MmCopyFromCaller(&rc, unsaferc, sizeof(RECT)))) + _SEH_TRY + { + ProbeForRead(unsaferc, + sizeof(RECT), + 1); + rc = *unsaferc; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) { RGNDATA_UnlockRgn(Rgn); + SetLastNtError(Status); DPRINT1("NtGdiRectInRegion: bogus rc\n"); return ERROR; } @@ -2635,17 +2711,31 @@ NtGdiUnionRectWithRgn(HRGN hDest, CONST PRECT UnsafeRect) { RECT SafeRect; PROSRGNDATA Rgn; + NTSTATUS Status = STATUS_SUCCESS; if(!(Rgn = (PROSRGNDATA)RGNDATA_LockRgn(hDest))) { SetLastWin32Error(ERROR_INVALID_HANDLE); return NULL; } + + _SEH_TRY + { + ProbeForRead(UnsafeRect, + sizeof(RECT), + 1); + SafeRect = *UnsafeRect; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - if (! NT_SUCCESS(MmCopyFromCaller(&SafeRect, UnsafeRect, sizeof(RECT)))) + if (! NT_SUCCESS(Status)) { RGNDATA_UnlockRgn(Rgn); - SetLastWin32Error(ERROR_INVALID_PARAMETER); + SetLastNtError(Status); return NULL; } @@ -2668,6 +2758,7 @@ DWORD STDCALL NtGdiGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata) { DWORD size; PROSRGNDATA obj = RGNDATA_LockRgn( hrgn ); + NTSTATUS Status = STATUS_SUCCESS; if(!obj) return 0; @@ -2681,16 +2772,31 @@ DWORD STDCALL NtGdiGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata) else /* user requested buffer size with rgndata NULL */ return size + sizeof(RGNDATAHEADER); } - - //first we copy the header then we copy buffer - if( !NT_SUCCESS( MmCopyToCaller( rgndata, obj, sizeof( RGNDATAHEADER )))){ - RGNDATA_UnlockRgn( obj ); - return 0; - } - if( !NT_SUCCESS( MmCopyToCaller( (char*)rgndata+sizeof( RGNDATAHEADER ), obj->Buffer, size ))){ - RGNDATA_UnlockRgn( obj ); - return 0; - } + + _SEH_TRY + { + ProbeForWrite(rgndata, + count, + 1); + RtlCopyMemory(rgndata, + obj, + sizeof(RGNDATAHEADER)); + RtlCopyMemory((PVOID)((ULONG_PTR)rgndata + (ULONG_PTR)sizeof(RGNDATAHEADER)), + obj->Buffer, + size); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + RGNDATA_UnlockRgn( obj ); + return 0; + } RGNDATA_UnlockRgn( obj ); return size + sizeof(RGNDATAHEADER); @@ -3291,7 +3397,7 @@ NtGdiCreatePolygonRgn(CONST PPOINT pt, INT PolyFillMode) { POINT *SafePoints; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; HRGN hRgn; @@ -3329,6 +3435,24 @@ NtGdiCreatePolygonRgn(CONST PPOINT pt, RGNDATA_UnlockRgn(rgn); return hRgn; } + + _SEH_TRY + { + ProbeForRead(pt, + Count * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return (HRGN)0; + } if (!(SafePoints = ExAllocatePoolWithTag(PagedPool, Count * sizeof(POINT), TAG_REGION))) { @@ -3336,7 +3460,18 @@ NtGdiCreatePolygonRgn(CONST PPOINT pt, return (HRGN)0; } - Status = MmCopyFromCaller(SafePoints, pt, Count * sizeof(POINT)); + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(SafePoints, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { ExFreePool(SafePoints); @@ -3361,7 +3496,7 @@ NtGdiCreatePolyPolygonRgn(CONST PPOINT pt, INT *SafePolyCounts; INT nPoints, nEmpty, nInvalid, i; HRGN hRgn; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; if (pt == NULL || PolyCounts == NULL || Count == 0 || (PolyFillMode != WINDING && PolyFillMode != ALTERNATE)) @@ -3369,6 +3504,27 @@ NtGdiCreatePolyPolygonRgn(CONST PPOINT pt, /* Windows doesn't set a last error here */ return (HRGN)0; } + + _SEH_TRY + { + ProbeForRead(PolyCounts, + Count * sizeof(INT), + 1); + ProbeForRead(pt, + nPoints * sizeof(POINT), + 1); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return (HRGN)0; + } if (!(SafePolyCounts = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_REGION))) { @@ -3376,7 +3532,19 @@ NtGdiCreatePolyPolygonRgn(CONST PPOINT pt, return (HRGN)0; } - Status = MmCopyFromCaller(SafePolyCounts, PolyCounts, Count * sizeof(INT)); + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(SafePolyCounts, + PolyCounts, + Count * sizeof(INT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) { ExFreePool(SafePolyCounts); @@ -3423,7 +3591,18 @@ NtGdiCreatePolyPolygonRgn(CONST PPOINT pt, return (HRGN)0; } - Status = MmCopyFromCaller(Safept, pt, nPoints * sizeof(POINT)); + _SEH_TRY + { + /* pointers were already probed! */ + RtlCopyMemory(Safept, + pt, + Count * sizeof(POINT)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; if (!NT_SUCCESS(Status)) { ExFreePool(Safept);