From a21f8262bfdc8825499656fd247e72d109ab1c02 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 23 Apr 2007 15:32:04 +0000 Subject: [PATCH] GetObject rewrite part 2 (NtGdiExtGetObjectW, ...) - hanlde GDI_OBJECT_TYPE_EXTPEN - PALETTEOBJ* -> PPALGDI - fix return value of BITMAP_GetObject & BRUSH_GetObject - implement PALETTE_GetObject - handle cases where the buffer gets filled partly svn path=/trunk/; revision=26474 --- .../subsystems/win32/win32k/include/palette.h | 2 + .../subsystems/win32/win32k/objects/bitmaps.c | 21 ++- .../subsystems/win32/win32k/objects/brush.c | 4 +- reactos/subsystems/win32/win32k/objects/dc.c | 120 +++++++++--------- .../subsystems/win32/win32k/objects/palobj.c | 12 ++ 5 files changed, 87 insertions(+), 72 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/palette.h b/reactos/subsystems/win32/win32k/include/palette.h index bf6086f93d6..8430d648961 100644 --- a/reactos/subsystems/win32/win32k/include/palette.h +++ b/reactos/subsystems/win32/win32k/include/palette.h @@ -47,6 +47,8 @@ INT STDCALL PALETTE_SetMapping(PALOBJ* palPtr, UINT uStart, UINT uNum, BOO #endif INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); +INT FASTCALL PALETTE_GetObject(PPALGDI pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer); + PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); #endif /* _WIN32K_PALETTE_H */ diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index ae716a44f4d..3ee09901fdb 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -1561,19 +1561,25 @@ BITMAPOBJ_CopyBitmap(HBITMAP hBitmap) INT STDCALL BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer) { - if( buffer == NULL ) return sizeof(BITMAP); - if (Count < sizeof(BITMAP)) return 0; + if ((UINT)Count < sizeof(BITMAP)) return 0; + if( buffer == NULL ) + { + if ((UINT)Count < sizeof(DIBSECTION)) + { + return sizeof(BITMAP); + } + return sizeof(DIBSECTION); + } if(bmp->dib) { - - if(Count < (INT) sizeof(DIBSECTION)) + if((UINT)Count < sizeof(DIBSECTION)) { - if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP); + Count = sizeof(BITMAP); } else { - if (Count > (INT) sizeof(DIBSECTION)) Count = sizeof(DIBSECTION); + Count = sizeof(DIBSECTION); } memcpy(buffer, bmp->dib, Count); return Count; @@ -1581,7 +1587,8 @@ BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer) else { BITMAP Bitmap; - if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP); + + Count = sizeof(BITMAP); Bitmap.bmType = 0; Bitmap.bmWidth = bmp->SurfObj.sizlBitmap.cx; Bitmap.bmHeight = bmp->SurfObj.sizlBitmap.cy; diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index c2ba778561f..3c1675fc3e4 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -53,8 +53,8 @@ INT FASTCALL BRUSH_GetObject (PGDIBRUSHOBJ BrushObject, INT Count, LPLOGBRUSH Buffer) { if( Buffer == NULL ) return sizeof(BRUSHOBJ); - if (Count < sizeof(BRUSHOBJ)) return 0; - if (Count > sizeof(BRUSHOBJ)) Count = sizeof(BRUSHOBJ); + if (Count == 0) return 0; + if ((UINT)Count < sizeof(BRUSHOBJ)) return 0; /* Set colour */ Buffer->lbColor = BrushObject->BrushAttr.lbColor; diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 5747dd21dae..88e0a528226 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -1755,123 +1755,117 @@ DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode ) INT FASTCALL -IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) +IntGdiGetObject(HANDLE Handle, INT cbCount, LPVOID lpBuffer) { - PVOID GdiObject; + PVOID pGdiObject; INT Result = 0; - DWORD ObjectType; + DWORD dwObjectType; - GdiObject = GDIOBJ_LockObj(GdiHandleTable, Handle, GDI_OBJECT_TYPE_DONTCARE); - if (NULL == GdiObject) + pGdiObject = GDIOBJ_LockObj(GdiHandleTable, Handle, GDI_OBJECT_TYPE_DONTCARE); + if (!pGdiObject) { SetLastWin32Error(ERROR_INVALID_HANDLE); return 0; } - ObjectType = GDIOBJ_GetObjectType(Handle); - switch (ObjectType) + dwObjectType = GDIOBJ_GetObjectType(Handle); + switch (dwObjectType) { - case GDI_OBJECT_TYPE_PEN: - Result = PEN_GetObject((PGDIBRUSHOBJ) GdiObject, Count, (PLOGPEN) Buffer); // IntGdiCreatePenIndirect + case GDI_OBJECT_TYPE_EXTPEN: + Result = PEN_GetObject((PGDIBRUSHOBJ) pGdiObject, cbCount, (PLOGPEN) lpBuffer); // IntGdiCreatePenIndirect break; case GDI_OBJECT_TYPE_BRUSH: - Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (LPLOGBRUSH)Buffer); + Result = BRUSH_GetObject((PGDIBRUSHOBJ ) pGdiObject, cbCount, (LPLOGBRUSH)lpBuffer); break; case GDI_OBJECT_TYPE_BITMAP: - Result = BITMAP_GetObject((BITMAPOBJ *) GdiObject, Count, Buffer); + Result = BITMAP_GetObject((BITMAPOBJ *) pGdiObject, cbCount, lpBuffer); break; case GDI_OBJECT_TYPE_FONT: - Result = FontGetObject((PTEXTOBJ) GdiObject, Count, Buffer); + Result = FontGetObject((PTEXTOBJ) pGdiObject, cbCount, lpBuffer); #if 0 // Fix the LOGFONT structure for the stock fonts if (FIRST_STOCK_HANDLE <= Handle && Handle <= LAST_STOCK_HANDLE) { - FixStockFontSizeW(Handle, Count, Buffer); + FixStockFontSizeW(Handle, cbCount, lpBuffer); } #endif break; -#if 0 + case GDI_OBJECT_TYPE_PALETTE: - Result = PALETTE_GetObject((PALETTEOBJ *) GdiObject, Count, Buffer); + Result = PALETTE_GetObject((PPALGDI) pGdiObject, cbCount, lpBuffer); break; -#endif + default: - DPRINT1("GDI object type 0x%08x not implemented\n", ObjectType); + DPRINT1("GDI object type 0x%08x not implemented\n", dwObjectType); break; } - GDIOBJ_UnlockObjByPtr(GdiHandleTable, GdiObject); + GDIOBJ_UnlockObjByPtr(GdiHandleTable, pGdiObject); return Result; } INT STDCALL -NtGdiExtGetObjectW(HANDLE handle, INT count, LPVOID buffer) +NtGdiExtGetObjectW(HANDLE hGdiObj, INT cbCount, LPVOID lpUnsafeBuf) { - INT Ret = 0; - LPVOID SafeBuf; + LPVOID lpSafeBuf; NTSTATUS Status = STATUS_SUCCESS; INT RetCount = 0; /* From Wine: GetObject does not SetLastError() on a null object */ - if (!handle) return Ret; - - RetCount = IntGdiGetObject(handle, 0, NULL); - if ((count <= 0) || (!buffer)) + if (!hGdiObj) { - return RetCount; + return 0; } - _SEH_TRY + if (!lpUnsafeBuf) { - ProbeForWrite(buffer, count, 1); + return IntGdiGetObject(hGdiObj, 0, NULL); } - _SEH_HANDLE + + if (!cbCount) { - Status = _SEH_GetExceptionCode(); + return 0; } - _SEH_END; + + RetCount = IntGdiGetObject(hGdiObj, cbCount, NULL); + if ((UINT)cbCount > RetCount) + { + cbCount = RetCount; + } + lpSafeBuf = ExAllocatePoolWithTag(PagedPool, RetCount, TAG_GDIOBJ); + if(!lpSafeBuf) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + RetCount = IntGdiGetObject(hGdiObj, cbCount, lpSafeBuf); + if (RetCount) + { + _SEH_TRY + { + ProbeForWrite(lpUnsafeBuf, cbCount, 1); + RtlCopyMemory(lpUnsafeBuf, lpSafeBuf, cbCount); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + + ExFreePool(lpSafeBuf); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); - return Ret; + return 0; } - if ((RetCount) && (count)) - { - SafeBuf = ExAllocatePoolWithTag(PagedPool, count, TAG_GDIOBJ); - if(!SafeBuf) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return Ret; - } - Ret = IntGdiGetObject(handle, count, SafeBuf); - - _SEH_TRY - { - /* pointer already probed! */ - RtlCopyMemory(buffer, SafeBuf, count); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - ExFreePool(SafeBuf); - - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return 0; - } - } - - return Ret; + return RetCount; } diff --git a/reactos/subsystems/win32/win32k/objects/palobj.c b/reactos/subsystems/win32/win32k/objects/palobj.c index 41f07257104..6d1382ae8f5 100644 --- a/reactos/subsystems/win32/win32k/objects/palobj.c +++ b/reactos/subsystems/win32/win32k/objects/palobj.c @@ -339,4 +339,16 @@ INT STDCALL PALETTE_SetMapping(PALOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapO } #endif +INT FASTCALL +PALETTE_GetObject(PPALGDI pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer) +{ + if (!lpBuffer) + { + return sizeof(WORD); + } + if ((UINT)cbCount < sizeof(WORD)) return 0; + *((WORD*)lpBuffer) = (WORD)pGdiObject->NumColors; + return sizeof(WORD); +} + /* EOF */