[WIN32K/GDI32]

- rewrite GetObject again :)
- simplify and fix FontGetObject
- remove some pointless code

svn path=/trunk/; revision=56407
This commit is contained in:
Timo Kreuzer 2012-04-24 14:49:09 +00:00
parent d8580d250c
commit e4b20ac135
4 changed files with 98 additions and 145 deletions

View file

@ -422,7 +422,7 @@ GetCurrentObject(
_In_ HDC hdc,
_In_ UINT uObjectType)
{
PDC_ATTR pdcattr;
PDC_ATTR pdcattr = NULL;
/* Check if this is a user mode object */
if ((uObjectType == OBJ_PEN) ||
@ -762,45 +762,102 @@ GetDCOrg(
return(MAKELONG(Pt.x, Pt.y));
}
ULONG
/*
* @implemented
*/
int
WINAPI
GetFontObjectW(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer)
GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
{
ENUMLOGFONTEXDVW elfedvW;
ULONG cbResult, cbMaxSize;
DWORD dwType;
INT cbResult = 0;
/* Check if size only is requested */
if (!lpBuffer) return sizeof(LOGFONTW);
/* Fixup handles with upper 16 bits masked */
hGdiObj = GdiFixUpHandle(hGdiObj);
/* Check for size 0 */
if (cbSize == 0)
/* Get the object type */
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
/* Check what kind of object we have */
switch (dwType)
{
/* Windows does not SetLastError() */
return 0;
case GDI_OBJECT_TYPE_PEN:
if (!lpBuffer) return sizeof(LOGPEN);
break;
case GDI_OBJECT_TYPE_BRUSH:
if (!lpBuffer || !cbSize) return sizeof(LOGBRUSH);
break;
case GDI_OBJECT_TYPE_BITMAP:
if (!lpBuffer) return sizeof(BITMAP);
break;
case GDI_OBJECT_TYPE_PALETTE:
if (!lpBuffer) return sizeof(WORD);
break;
case GDI_OBJECT_TYPE_FONT:
if (!lpBuffer) return sizeof(LOGFONTW);
break;
case GDI_OBJECT_TYPE_EXTPEN:
/* we don't know the size, ask win32k */
break;
case GDI_OBJECT_TYPE_COLORSPACE:
if ((cbSize < 328) || !lpBuffer)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
break;
case GDI_OBJECT_TYPE_DC:
case GDI_OBJECT_TYPE_REGION:
case GDI_OBJECT_TYPE_EMF:
case GDI_OBJECT_TYPE_METAFILE:
case GDI_OBJECT_TYPE_ENHMETAFILE:
SetLastError(ERROR_INVALID_HANDLE);
default:
return 0;
}
/* Call win32k to get the logfont (widechar) */
cbResult = NtGdiExtGetObjectW(hfont, sizeof(ENUMLOGFONTEXDVW), &elfedvW);
/* Call win32k */
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
/* Handle error */
if (cbResult == 0)
{
return 0;
if (!GdiIsHandleValid(hGdiObj))
{
if ((dwType == GDI_OBJECT_TYPE_PEN) ||
(dwType == GDI_OBJECT_TYPE_EXTPEN) ||
(dwType == GDI_OBJECT_TYPE_BRUSH) ||
(dwType == GDI_OBJECT_TYPE_COLORSPACE))
{
SetLastError(ERROR_INVALID_PARAMETER);
}
}
else
{
if ((dwType == GDI_OBJECT_TYPE_PEN) ||
(dwType == GDI_OBJECT_TYPE_BRUSH) ||
(dwType == GDI_OBJECT_TYPE_COLORSPACE) ||
( (dwType == GDI_OBJECT_TYPE_EXTPEN) &&
( (cbSize >= sizeof(EXTLOGPEN)) || (cbSize == 0) ) ) ||
( (dwType == GDI_OBJECT_TYPE_BITMAP) && (cbSize >= sizeof(BITMAP)) ))
{
SetLastError(ERROR_NOACCESS);
}
}
}
/* Calculate the maximum size according to number of axes */
cbMaxSize = FIELD_OFFSET(ENUMLOGFONTEXDVW,
elfDesignVector.dvValues[elfedvW.elfDesignVector.dvNumAxes]);
/* Don't copy more than the maximum */
if (cbSize > cbMaxSize) cbSize = cbMaxSize;
if (cbSize > cbResult) cbSize = cbResult;
/* Copy the number of bytes requested */
memcpy(lpBuffer, &elfedvW, cbSize);
/* Return the number of bytes copied */
return cbSize;
return cbResult;
}
ULONG
WINAPI
GetFontObjectA(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer)
@ -843,84 +900,6 @@ GetFontObjectA(HGDIOBJ hfont, ULONG cbSize, LPVOID lpBuffer)
return cbSize;
}
/*
* @implemented
*/
int
WINAPI
GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
{
DWORD dwType;
INT cbResult = 0;
hGdiObj = GdiFixUpHandle(hGdiObj);
/* Get the object type */
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
/* Check what kind of object we have */
switch(dwType)
{
case GDI_OBJECT_TYPE_PEN:
if (!lpBuffer) return sizeof(LOGPEN);
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_BRUSH:
if (!lpBuffer) return sizeof(LOGBRUSH);
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_BITMAP:
if (!lpBuffer) return sizeof(BITMAP);
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_PALETTE:
if (!lpBuffer) return sizeof(WORD);
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_FONT:
return GetFontObjectW(hGdiObj, cbSize, lpBuffer);
case GDI_OBJECT_TYPE_EXTPEN:
/* we don't know the size, ask win32k */
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
{
if (!GdiIsHandleValid(hGdiObj))
SetLastError(ERROR_INVALID_PARAMETER);
else if (cbSize == 0)
SetLastError(ERROR_NOACCESS);
}
return cbResult;
case GDI_OBJECT_TYPE_COLORSPACE:
if ((cbSize < 328) || !lpBuffer)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
cbResult = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
if (cbResult == 0)
SetLastError(ERROR_INVALID_PARAMETER);
return cbResult;
case GDI_OBJECT_TYPE_DC:
case GDI_OBJECT_TYPE_REGION:
case GDI_OBJECT_TYPE_EMF:
case GDI_OBJECT_TYPE_METAFILE:
case GDI_OBJECT_TYPE_ENHMETAFILE:
SetLastError(ERROR_INVALID_HANDLE);
default:
return 0;
}
return 0;
}
/*
* @implemented

View file

@ -260,43 +260,23 @@ GreGetCharacterPlacementW(
}
#endif
INT
ULONG
FASTCALL
FontGetObject(PTEXTOBJ TFont, INT cjBuffer, PVOID pvBuffer)
FontGetObject(PTEXTOBJ plfont, ULONG cjBuffer, PVOID pvBuffer)
{
ULONG cjMaxSize;
ENUMLOGFONTEXDVW *plf = &plfont->logfont;
/* If buffer is NULL, only the size is requested */
if (pvBuffer == NULL) return sizeof(LOGFONTW);
switch (cjBuffer)
{
case sizeof(ENUMLOGFONTEXDVW):
RtlCopyMemory(pvBuffer,
&TFont->logfont,
sizeof(ENUMLOGFONTEXDVW));
break;
/* Calculate the maximum size according to number of axes */
cjMaxSize = FIELD_OFFSET(ENUMLOGFONTEXDVW,
elfDesignVector.dvValues[plf->elfDesignVector.dvNumAxes]);
case sizeof(ENUMLOGFONTEXW):
RtlCopyMemory(pvBuffer,
&TFont->logfont.elfEnumLogfontEx,
sizeof(ENUMLOGFONTEXW));
break;
if (cjBuffer > cjMaxSize) cjBuffer = cjMaxSize;
case sizeof(EXTLOGFONTW):
case sizeof(ENUMLOGFONTW):
RtlCopyMemory((LPENUMLOGFONTW) pvBuffer,
&TFont->logfont.elfEnumLogfontEx.elfLogFont,
sizeof(ENUMLOGFONTW));
break;
case sizeof(LOGFONTW):
RtlCopyMemory((LPLOGFONTW) pvBuffer,
&TFont->logfont.elfEnumLogfontEx.elfLogFont,
sizeof(LOGFONTW));
break;
default:
EngSetLastError(ERROR_BUFFER_OVERFLOW);
return 0;
}
RtlCopyMemory(pvBuffer, plf, cjBuffer);
return cjBuffer;
}

View file

@ -1038,15 +1038,9 @@ GreGetObject(
case GDILoObjType_LO_BITMAP_TYPE:
iResult = BITMAP_GetObject(pvObj, cbCount, pvBuffer);
break;
case GDILoObjType_LO_FONT_TYPE:
iResult = FontGetObject(pvObj, cbCount, pvBuffer);
#if 0
// Fix the LOGFONT structure for the stock fonts
if (FIRST_STOCK_HANDLE <= hobj && hobj <= LAST_STOCK_HANDLE)
{
FixStockFontSizeW(hobj, cbCount, pvBuffer);
}
#endif
break;
case GDILoObjType_LO_PALETTE_TYPE:
@ -1096,7 +1090,7 @@ NtGdiExtGetObjectW(
/* Enter SEH for buffer transfer */
_SEH2_TRY
{
// Probe the buffer and copy it
/* Probe the buffer and copy it */
ProbeForWrite(lpBuffer, cbCopyCount, sizeof(WORD));
RtlCopyMemory(lpBuffer, &object, cbCopyCount);
}

View file

@ -88,7 +88,7 @@ BOOL FASTCALL InitFontSupport(VOID);
BOOL FASTCALL IntIsFontRenderingEnabled(VOID);
BOOL FASTCALL IntIsFontRenderingEnabled(VOID);
VOID FASTCALL IntEnableFontRendering(BOOL Enable);
INT FASTCALL FontGetObject(PTEXTOBJ TextObj, INT Count, PVOID Buffer);
ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer);
VOID FASTCALL IntLoadSystemFonts(VOID);
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);