From 68d19b9552ad7b24671124e20d78ae801b9931ae Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 27 Jan 2009 16:30:43 +0100 Subject: [PATCH] gdi32: Don't hold the GDI lock while calling the GetObjectA/W methods for GDI objects. --- dlls/gdi32/bitmap.c | 22 ++++++++------- dlls/gdi32/brush.c | 19 +++++++------ dlls/gdi32/font.c | 40 ++++++++++++++++----------- dlls/gdi32/gdi_private.h | 4 +-- dlls/gdi32/gdiobj.c | 17 +++++++----- dlls/gdi32/palette.c | 18 ++++++++----- dlls/gdi32/pen.c | 58 +++++++++++++++++++--------------------- 7 files changed, 100 insertions(+), 78 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 6d47d6356c..585be63587 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -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; } diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 8c74c0a61a..6d41a2061a 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -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; + BRUSHOBJ *brush = GDI_GetObjPtr( handle, BRUSH_MAGIC ); - if( !buffer ) - return sizeof(brush->logbrush); - - 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; } diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 0ba9a4ece9..057fb2d440 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -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; } diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9cb379646b..450ce9a2ca 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -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 ); }; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 080632af54..3351f951e7 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -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; } diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c index 35f6f71f48..62debc1a75 100644 --- a/dlls/gdi32/palette.c +++ b/dlls/gdi32/palette.c @@ -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; } diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 385570d87f..6298e3c1bc 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -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; }