diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 1f089defff3..5a68aa63f2a 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -55,16 +55,18 @@ static inline DC *get_dc_obj( HDC hdc ) DC *dc = GDI_GetObjPtr( hdc, 0 ); if (!dc) return NULL; - if ((dc->header.type != OBJ_DC) && - (dc->header.type != OBJ_MEMDC) && - (dc->header.type != OBJ_METADC) && - (dc->header.type != OBJ_ENHMETADC)) + switch (GetObjectType( hdc )) { + case OBJ_DC: + case OBJ_MEMDC: + case OBJ_METADC: + case OBJ_ENHMETADC: + return dc; + default: GDI_ReleaseObj( hdc ); SetLastError( ERROR_INVALID_HANDLE ); - dc = NULL; + return NULL; } - return dc; } diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index bd4c90644b8..57a4d189252 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -435,7 +435,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ TRACE("(%p)\n", hdc ); if (!(dc = get_dc_ptr( hdc ))) return NULL; - if (dc->header.type != OBJ_ENHMETADC) + if (GetObjectType( hdc ) != OBJ_ENHMETADC) { release_dc_ptr( dc ); return NULL; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 5b79526e858..9c926d420eb 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -65,7 +65,6 @@ struct hdc_list typedef struct tagGDIOBJHDR { - WORD type; /* object type (one of the OBJ_* constants) */ WORD system : 1; /* system object flag */ WORD deleted : 1; /* whether DeleteObject has been called on this object */ DWORD selcount; /* number of times the object is selected in a DC */ diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 9da5533c896..0cd182a8665 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -38,12 +38,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); -#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16)) +#define FIRST_GDI_HANDLE 16 +#define MAX_GDI_HANDLES 16384 -#define GDI_HEAP_SIZE 0xffe0 +struct gdi_handle_entry +{ + GDIOBJHDR *obj; /* pointer to the object-specific data */ + WORD type; /* object type (one of the OBJ_* constants) */ +}; +static struct gdi_handle_entry gdi_handles[MAX_GDI_HANDLES]; +static int next_gdi_handle; +static LONG debug_count; HMODULE gdi32_module = 0; +static inline HGDIOBJ entry_to_handle( struct gdi_handle_entry *entry ) +{ + unsigned int idx = entry - gdi_handles + FIRST_GDI_HANDLE; + return ULongToHandle( idx << 2 ); +} + +static inline struct gdi_handle_entry *handle_entry( HGDIOBJ handle ) +{ + unsigned int idx = (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE; + + if (idx < MAX_GDI_HANDLES && gdi_handles[idx].type) return &gdi_handles[idx]; + return NULL; +} + /*********************************************************************** * GDI stock objects */ @@ -600,22 +622,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) return TRUE; } -#define FIRST_GDI_HANDLE 16 -#define MAX_GDI_HANDLES ((GDI_HEAP_SIZE >> 2) - FIRST_GDI_HANDLE) -static GDIOBJHDR *gdi_handles[MAX_GDI_HANDLES]; -static int next_gdi_handle; -static LONG debug_count; - -static inline HGDIOBJ index_to_handle( int index ) -{ - return ULongToHandle( (index + FIRST_GDI_HANDLE) << 2); -} - -static inline int handle_to_index( HGDIOBJ handle ) -{ - return (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE; -} - static const char *gdi_obj_type( unsigned type ) { switch ( type ) @@ -640,21 +646,21 @@ static const char *gdi_obj_type( unsigned type ) static void dump_gdi_objects( void ) { - int i; + struct gdi_handle_entry *entry; TRACE( "%u objects:\n", MAX_GDI_HANDLES ); EnterCriticalSection( &gdi_section ); - for (i = 0; i < MAX_GDI_HANDLES; i++) + for (entry = gdi_handles; entry < gdi_handles + MAX_GDI_HANDLES; entry++) { - if (!gdi_handles[i]) + if (!entry->type) { - TRACE( "index %d handle %p FREE\n", i, index_to_handle( i )); + TRACE( "handle %p FREE\n", entry_to_handle( entry )); continue; } TRACE( "handle %p obj %p type %s selcount %u deleted %u\n", - index_to_handle( i ), gdi_handles[i], gdi_obj_type( gdi_handles[i]->type ), - gdi_handles[i]->selcount, gdi_handles[i]->deleted ); + entry_to_handle( entry ), entry->obj, gdi_obj_type( entry->type ), + entry->obj->selcount, entry->obj->deleted ); } LeaveCriticalSection( &gdi_section ); } @@ -666,10 +672,13 @@ static void dump_gdi_objects( void ) */ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) { + struct gdi_handle_entry *entry; + HGDIOBJ ret; int i; + assert( type ); /* type 0 is reserved to mark free entries */ + /* initialize the object header */ - obj->type = type; obj->system = 0; obj->deleted = 0; obj->selcount = 0; @@ -678,9 +687,9 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs EnterCriticalSection( &gdi_section ); for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++) - if (!gdi_handles[i]) goto found; + if (!gdi_handles[i].type) goto found; for (i = 0; i <= next_gdi_handle; i++) - if (!gdi_handles[i]) goto found; + if (!gdi_handles[i].type) goto found; LeaveCriticalSection( &gdi_section ); ERR( "out of GDI object handles, expect a crash\n" ); @@ -688,13 +697,15 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs return 0; found: - gdi_handles[i] = obj; + entry = &gdi_handles[i]; + entry->obj = obj; + entry->type = type; next_gdi_handle = i; + ret = entry_to_handle( entry ); LeaveCriticalSection( &gdi_section ); - TRACE( "allocated %s %p %u/%u\n", - gdi_obj_type(type), index_to_handle( i ), + TRACE( "allocated %s %p %u/%u\n", gdi_obj_type(type), ret, InterlockedIncrement( &debug_count ), MAX_GDI_HANDLES ); - return index_to_handle( i ); + return ret; } @@ -706,20 +717,20 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs void *free_gdi_handle( HGDIOBJ handle ) { GDIOBJHDR *object = NULL; - int i = handle_to_index( handle ); + struct gdi_handle_entry *entry; - if (i >= 0 && i < MAX_GDI_HANDLES) + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) { - EnterCriticalSection( &gdi_section ); - object = gdi_handles[i]; - gdi_handles[i] = NULL; - LeaveCriticalSection( &gdi_section ); + TRACE( "freed %s %p %u/%u\n", gdi_obj_type( entry->type ), handle, + InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES ); + object = entry->obj; + entry->type = 0; } + LeaveCriticalSection( &gdi_section ); + if (object) { - TRACE( "freed %s %p %u/%u\n", gdi_obj_type( object->type ), handle, - InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES ); - object->type = 0; /* mark it as invalid */ object->funcs = NULL; } return object; @@ -736,14 +747,13 @@ void *free_gdi_handle( HGDIOBJ handle ) void *GDI_GetObjPtr( HGDIOBJ handle, WORD type ) { GDIOBJHDR *ptr = NULL; - int i = handle_to_index( handle ); + struct gdi_handle_entry *entry; EnterCriticalSection( &gdi_section ); - if (i >= 0 && i < MAX_GDI_HANDLES) + if ((entry = handle_entry( handle ))) { - ptr = gdi_handles[i]; - if (ptr && type && ptr->type != type) ptr = NULL; + if (!type || entry->type == type) ptr = entry->obj; } if (!ptr) @@ -995,17 +1005,15 @@ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ) */ DWORD WINAPI GetObjectType( HGDIOBJ handle ) { - GDIOBJHDR * ptr; - DWORD result; + struct gdi_handle_entry *entry; + DWORD result = 0; + + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) result = entry->type; + LeaveCriticalSection( &gdi_section ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) - { - SetLastError( ERROR_INVALID_HANDLE ); - return 0; - } - result = ptr->type; - GDI_ReleaseObj( handle ); TRACE("%p -> %u\n", handle, result ); + if (!result) SetLastError( ERROR_INVALID_HANDLE ); return result; } diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index f75637c1a7a..03cd22ce003 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -390,7 +390,7 @@ static DC *MFDRV_CloseMetaFile( HDC hdc ) TRACE("(%p)\n", hdc ); if (!(dc = get_dc_ptr( hdc ))) return NULL; - if (dc->header.type != OBJ_METADC) + if (GetObjectType( hdc ) != OBJ_METADC) { release_dc_ptr( dc ); return NULL; diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 6695ee9ddb5..94c3933fe4a 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -236,7 +236,7 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ) struct brush_pattern *pattern; PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectPen ); - switch (pen->header.type) + switch (GetObjectType( handle )) { case OBJ_PEN: pattern = NULL; @@ -293,7 +293,7 @@ static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ) if (!pen) return 0; - switch (pen->header.type) + switch (GetObjectType( handle )) { case OBJ_PEN: {