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