Commit 68d19b95 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Don't hold the GDI lock while calling the GetObjectA/W methods for GDI objects.

parent 9ff44b81
......@@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc );
static INT BITMAP_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL BITMAP_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs bitmap_funcs =
......@@ -670,33 +670,37 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
/***********************************************************************
* BITMAP_GetObject
*/
static INT BITMAP_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
BITMAPOBJ *bmp = obj;
INT ret;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, BITMAP_MAGIC );
if( !buffer ) return sizeof(BITMAP);
if (count < sizeof(BITMAP)) return 0;
if (!bmp) return 0;
if (bmp->dib)
if (!buffer) ret = sizeof(BITMAP);
else if (count < sizeof(BITMAP)) ret = 0;
else if (bmp->dib)
{
if (count >= sizeof(DIBSECTION))
{
memcpy( buffer, bmp->dib, sizeof(DIBSECTION) );
return sizeof(DIBSECTION);
ret = sizeof(DIBSECTION);
}
else /* if (count >= sizeof(BITMAP)) */
{
DIBSECTION *dib = bmp->dib;
memcpy( buffer, &dib->dsBm, sizeof(BITMAP) );
return sizeof(BITMAP);
ret = sizeof(BITMAP);
}
}
else
{
memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) );
((BITMAP *) buffer)->bmBits = NULL;
return sizeof(BITMAP);
ret = sizeof(BITMAP);
}
GDI_ReleaseObj( handle );
return ret;
}
......
......@@ -43,7 +43,7 @@ typedef struct
#define NB_HATCH_STYLES 6
static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc );
static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL BRUSH_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs brush_funcs =
......@@ -426,15 +426,18 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
/***********************************************************************
* BRUSH_GetObject
*/
static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
BRUSHOBJ *brush = obj;
if( !buffer )
return sizeof(brush->logbrush);
BRUSHOBJ *brush = GDI_GetObjPtr( handle, BRUSH_MAGIC );
if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
memcpy( buffer, &brush->logbrush, count );
if (!brush) return 0;
if (buffer)
{
if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
memcpy( buffer, &brush->logbrush, count );
}
else count = sizeof(brush->logbrush);
GDI_ReleaseObj( handle );
return count;
}
......
......@@ -87,8 +87,8 @@ static inline INT INTERNAL_YWSTODS(DC *dc, INT height)
}
static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc );
static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT FONT_GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer );
static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL FONT_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs font_funcs =
......@@ -514,30 +514,38 @@ static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc )
/***********************************************************************
* FONT_GetObjectA
*/
static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT FONT_GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer )
{
FONTOBJ *font = obj;
FONTOBJ *font = GDI_GetObjPtr( handle, FONT_MAGIC );
LOGFONTA lfA;
if(!buffer)
return sizeof(lfA);
FONT_LogFontWToA( &font->logfont, &lfA );
if (count > sizeof(lfA)) count = sizeof(lfA);
memcpy( buffer, &lfA, count );
if (!font) return 0;
if (buffer)
{
FONT_LogFontWToA( &font->logfont, &lfA );
if (count > sizeof(lfA)) count = sizeof(lfA);
memcpy( buffer, &lfA, count );
}
else count = sizeof(lfA);
GDI_ReleaseObj( handle );
return count;
}
/***********************************************************************
* FONT_GetObjectW
*/
static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
{
FONTOBJ *font = obj;
if(!buffer)
return sizeof(LOGFONTW);
if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
memcpy( buffer, &font->logfont, count );
FONTOBJ *font = GDI_GetObjPtr( handle, FONT_MAGIC );
if (!font) return 0;
if (buffer)
{
if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
memcpy( buffer, &font->logfont, count );
}
else count = sizeof(LOGFONTW);
GDI_ReleaseObj( handle );
return count;
}
......
......@@ -72,8 +72,8 @@ typedef struct {
struct gdi_obj_funcs
{
HGDIOBJ (*pSelectObject)( HGDIOBJ handle, HDC hdc );
INT (*pGetObjectA)( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
INT (*pGetObjectW)( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
INT (*pGetObjectA)( HGDIOBJ handle, INT count, LPVOID buffer );
INT (*pGetObjectW)( HGDIOBJ handle, INT count, LPVOID buffer );
BOOL (*pUnrealizeObject)( HGDIOBJ handle );
BOOL (*pDeleteObject)( HGDIOBJ handle );
};
......
......@@ -956,18 +956,21 @@ HGDIOBJ WINAPI GetStockObject( INT obj )
*/
INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer )
{
const struct gdi_obj_funcs *funcs;
GDIOBJHDR * ptr;
INT result = 0;
TRACE("%p %d %p\n", handle, count, buffer );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
funcs = ptr->funcs;
GDI_ReleaseObj( handle );
if (ptr->funcs && ptr->funcs->pGetObjectA)
result = ptr->funcs->pGetObjectA( handle, ptr, count, buffer );
if (funcs && funcs->pGetObjectA)
result = funcs->pGetObjectA( handle, count, buffer );
else
SetLastError( ERROR_INVALID_HANDLE );
GDI_ReleaseObj( handle );
return result;
}
......@@ -976,18 +979,20 @@ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer )
*/
INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
{
const struct gdi_obj_funcs *funcs;
GDIOBJHDR * ptr;
INT result = 0;
TRACE("%p %d %p\n", handle, count, buffer );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
funcs = ptr->funcs;
GDI_ReleaseObj( handle );
if (ptr->funcs && ptr->funcs->pGetObjectW)
result = ptr->funcs->pGetObjectW( handle, ptr, count, buffer );
if (funcs && funcs->pGetObjectW)
result = funcs->pGetObjectW( handle, count, buffer );
else
SetLastError( ERROR_INVALID_HANDLE );
GDI_ReleaseObj( handle );
return result;
}
......
......@@ -45,7 +45,7 @@ typedef struct tagPALETTEOBJ
LOGPALETTE logpalette; /* _MUST_ be the last field */
} PALETTEOBJ;
static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle );
static BOOL PALETTE_DeleteObject( HGDIOBJ handle );
......@@ -630,15 +630,19 @@ COLORREF WINAPI GetNearestColor(
/***********************************************************************
* PALETTE_GetObject
*/
static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
PALETTEOBJ *palette = obj;
PALETTEOBJ *palette = GDI_GetObjPtr( handle, PALETTE_MAGIC );
if( !buffer )
return sizeof(WORD);
if (!palette) return 0;
if (count > sizeof(WORD)) count = sizeof(WORD);
memcpy( buffer, &palette->logpalette.palNumEntries, count );
if (buffer)
{
if (count > sizeof(WORD)) count = sizeof(WORD);
memcpy( buffer, &palette->logpalette.palNumEntries, count );
}
else count = sizeof(WORD);
GDI_ReleaseObj( handle );
return count;
}
......
......@@ -42,7 +42,7 @@ typedef struct
static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc );
static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
static BOOL PEN_DeleteObject( HGDIOBJ handle );
static const struct gdi_obj_funcs pen_funcs =
......@@ -266,9 +266,12 @@ static BOOL PEN_DeleteObject( HGDIOBJ handle )
/***********************************************************************
* PEN_GetObject
*/
static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
{
PENOBJ *pen = obj;
PENOBJ *pen = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
INT ret = 0;
if (!pen) return 0;
switch (GDIMAGIC(pen->header.wMagic))
{
......@@ -276,41 +279,36 @@ static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
{
LOGPEN *lp;
if (!buffer) return sizeof(LOGPEN);
if (count < sizeof(LOGPEN)) return 0;
if ((pen->logpen.elpPenStyle & PS_STYLE_MASK) == PS_NULL &&
count == sizeof(EXTLOGPEN))
if (!buffer) ret = sizeof(LOGPEN);
else if (count < sizeof(LOGPEN)) ret = 0;
else if ((pen->logpen.elpPenStyle & PS_STYLE_MASK) == PS_NULL && count == sizeof(EXTLOGPEN))
{
EXTLOGPEN *elp = buffer;
*elp = pen->logpen;
elp->elpWidth = 0;
return sizeof(EXTLOGPEN);
ret = sizeof(EXTLOGPEN);
}
lp = buffer;
lp->lopnStyle = pen->logpen.elpPenStyle;
lp->lopnColor = pen->logpen.elpColor;
lp->lopnWidth.x = pen->logpen.elpWidth;
lp->lopnWidth.y = 0;
return sizeof(LOGPEN);
else
{
lp = buffer;
lp->lopnStyle = pen->logpen.elpPenStyle;
lp->lopnColor = pen->logpen.elpColor;
lp->lopnWidth.x = pen->logpen.elpWidth;
lp->lopnWidth.y = 0;
ret = sizeof(LOGPEN);
}
break;
}
case EXT_PEN_MAGIC:
{
INT size = sizeof(EXTLOGPEN) + pen->logpen.elpNumEntries * sizeof(DWORD) - sizeof(pen->logpen.elpStyleEntry);
if (!buffer) return size;
if (count < size) return 0;
memcpy(buffer, &pen->logpen, size);
return size;
}
default:
ret = sizeof(EXTLOGPEN) + pen->logpen.elpNumEntries * sizeof(DWORD) - sizeof(pen->logpen.elpStyleEntry);
if (buffer)
{
if (count < ret) ret = 0;
else memcpy(buffer, &pen->logpen, ret);
}
break;
}
assert(0);
return 0;
GDI_ReleaseObj( handle );
return ret;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment