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
This commit is contained in:
Timo Kreuzer 2007-04-23 15:32:04 +00:00
parent a3c8ac67d5
commit a21f8262bf
5 changed files with 87 additions and 72 deletions

View file

@ -47,6 +47,8 @@ INT STDCALL PALETTE_SetMapping(PALOBJ* palPtr, UINT uStart, UINT uNum, BOO
#endif #endif
INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color);
INT FASTCALL PALETTE_GetObject(PPALGDI pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer);
PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID);
#endif /* _WIN32K_PALETTE_H */ #endif /* _WIN32K_PALETTE_H */

View file

@ -1561,19 +1561,25 @@ BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
INT STDCALL INT STDCALL
BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer) BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer)
{ {
if( buffer == NULL ) return sizeof(BITMAP); if ((UINT)Count < sizeof(BITMAP)) return 0;
if (Count < sizeof(BITMAP)) return 0; if( buffer == NULL )
{
if ((UINT)Count < sizeof(DIBSECTION))
{
return sizeof(BITMAP);
}
return sizeof(DIBSECTION);
}
if(bmp->dib) if(bmp->dib)
{ {
if((UINT)Count < sizeof(DIBSECTION))
if(Count < (INT) sizeof(DIBSECTION))
{ {
if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP); Count = sizeof(BITMAP);
} }
else else
{ {
if (Count > (INT) sizeof(DIBSECTION)) Count = sizeof(DIBSECTION); Count = sizeof(DIBSECTION);
} }
memcpy(buffer, bmp->dib, Count); memcpy(buffer, bmp->dib, Count);
return Count; return Count;
@ -1581,7 +1587,8 @@ BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer)
else else
{ {
BITMAP Bitmap; BITMAP Bitmap;
if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP);
Count = sizeof(BITMAP);
Bitmap.bmType = 0; Bitmap.bmType = 0;
Bitmap.bmWidth = bmp->SurfObj.sizlBitmap.cx; Bitmap.bmWidth = bmp->SurfObj.sizlBitmap.cx;
Bitmap.bmHeight = bmp->SurfObj.sizlBitmap.cy; Bitmap.bmHeight = bmp->SurfObj.sizlBitmap.cy;

View file

@ -53,8 +53,8 @@ INT FASTCALL
BRUSH_GetObject (PGDIBRUSHOBJ BrushObject, INT Count, LPLOGBRUSH Buffer) BRUSH_GetObject (PGDIBRUSHOBJ BrushObject, INT Count, LPLOGBRUSH Buffer)
{ {
if( Buffer == NULL ) return sizeof(BRUSHOBJ); if( Buffer == NULL ) return sizeof(BRUSHOBJ);
if (Count < sizeof(BRUSHOBJ)) return 0; if (Count == 0) return 0;
if (Count > sizeof(BRUSHOBJ)) Count = sizeof(BRUSHOBJ); if ((UINT)Count < sizeof(BRUSHOBJ)) return 0;
/* Set colour */ /* Set colour */
Buffer->lbColor = BrushObject->BrushAttr.lbColor; Buffer->lbColor = BrushObject->BrushAttr.lbColor;

View file

@ -1755,123 +1755,117 @@ DC_GET_VAL( INT, NtGdiGetPolyFillMode, w.polyFillMode )
INT FASTCALL INT FASTCALL
IntGdiGetObject(HANDLE Handle, INT Count, LPVOID Buffer) IntGdiGetObject(HANDLE Handle, INT cbCount, LPVOID lpBuffer)
{ {
PVOID GdiObject; PVOID pGdiObject;
INT Result = 0; INT Result = 0;
DWORD ObjectType; DWORD dwObjectType;
GdiObject = GDIOBJ_LockObj(GdiHandleTable, Handle, GDI_OBJECT_TYPE_DONTCARE); pGdiObject = GDIOBJ_LockObj(GdiHandleTable, Handle, GDI_OBJECT_TYPE_DONTCARE);
if (NULL == GdiObject) if (!pGdiObject)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
ObjectType = GDIOBJ_GetObjectType(Handle); dwObjectType = GDIOBJ_GetObjectType(Handle);
switch (ObjectType) switch (dwObjectType)
{ {
case GDI_OBJECT_TYPE_PEN: 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; break;
case GDI_OBJECT_TYPE_BRUSH: case GDI_OBJECT_TYPE_BRUSH:
Result = BRUSH_GetObject((PGDIBRUSHOBJ ) GdiObject, Count, (LPLOGBRUSH)Buffer); Result = BRUSH_GetObject((PGDIBRUSHOBJ ) pGdiObject, cbCount, (LPLOGBRUSH)lpBuffer);
break; break;
case GDI_OBJECT_TYPE_BITMAP: case GDI_OBJECT_TYPE_BITMAP:
Result = BITMAP_GetObject((BITMAPOBJ *) GdiObject, Count, Buffer); Result = BITMAP_GetObject((BITMAPOBJ *) pGdiObject, cbCount, lpBuffer);
break; break;
case GDI_OBJECT_TYPE_FONT: case GDI_OBJECT_TYPE_FONT:
Result = FontGetObject((PTEXTOBJ) GdiObject, Count, Buffer); Result = FontGetObject((PTEXTOBJ) pGdiObject, cbCount, lpBuffer);
#if 0 #if 0
// Fix the LOGFONT structure for the stock fonts // Fix the LOGFONT structure for the stock fonts
if (FIRST_STOCK_HANDLE <= Handle && Handle <= LAST_STOCK_HANDLE) if (FIRST_STOCK_HANDLE <= Handle && Handle <= LAST_STOCK_HANDLE)
{ {
FixStockFontSizeW(Handle, Count, Buffer); FixStockFontSizeW(Handle, cbCount, lpBuffer);
} }
#endif #endif
break; break;
#if 0
case GDI_OBJECT_TYPE_PALETTE: case GDI_OBJECT_TYPE_PALETTE:
Result = PALETTE_GetObject((PALETTEOBJ *) GdiObject, Count, Buffer); Result = PALETTE_GetObject((PPALGDI) pGdiObject, cbCount, lpBuffer);
break; break;
#endif
default: default:
DPRINT1("GDI object type 0x%08x not implemented\n", ObjectType); DPRINT1("GDI object type 0x%08x not implemented\n", dwObjectType);
break; break;
} }
GDIOBJ_UnlockObjByPtr(GdiHandleTable, GdiObject); GDIOBJ_UnlockObjByPtr(GdiHandleTable, pGdiObject);
return Result; return Result;
} }
INT STDCALL INT STDCALL
NtGdiExtGetObjectW(HANDLE handle, INT count, LPVOID buffer) NtGdiExtGetObjectW(HANDLE hGdiObj, INT cbCount, LPVOID lpUnsafeBuf)
{ {
INT Ret = 0; LPVOID lpSafeBuf;
LPVOID SafeBuf;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
INT RetCount = 0; INT RetCount = 0;
/* From Wine: GetObject does not SetLastError() on a null object */ /* From Wine: GetObject does not SetLastError() on a null object */
if (!handle) return Ret; if (!hGdiObj)
RetCount = IntGdiGetObject(handle, 0, NULL);
if ((count <= 0) || (!buffer))
{ {
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)) if(!NT_SUCCESS(Status))
{ {
SetLastNtError(Status); SetLastNtError(Status);
return Ret; return 0;
} }
if ((RetCount) && (count)) return RetCount;
{
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;
} }

View file

@ -339,4 +339,16 @@ INT STDCALL PALETTE_SetMapping(PALOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapO
} }
#endif #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 */ /* EOF */