user32: Load libpng in DllMain.
libpng is currently loaded on the first attempt to access a PNG icon or cursor. That creates a race condition that can deadlock the loader in certain circumstances if LoadIcon or LoadCursor is called while the loader lock is held, e.g. from a DllMain. Signed-off-by: Tim Clem <tclem@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dd37c3c4a0
commit
b4333216a7
|
@ -111,21 +111,6 @@ static int get_display_bpp(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
|
||||||
|
|
||||||
static const struct png_funcs *png_funcs;
|
|
||||||
|
|
||||||
static BOOL WINAPI load_libpng( INIT_ONCE *once, void *param, void **context )
|
|
||||||
{
|
|
||||||
__wine_init_unix_lib( user32_module, DLL_PROCESS_ATTACH, NULL, &png_funcs );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL have_libpng(void)
|
|
||||||
{
|
|
||||||
return InitOnceExecuteOnce( &init_once, load_libpng, NULL, NULL ) && png_funcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HICON alloc_icon_handle( BOOL is_ani, UINT num_steps )
|
static HICON alloc_icon_handle( BOOL is_ani, UINT num_steps )
|
||||||
{
|
{
|
||||||
struct cursoricon_object *obj;
|
struct cursoricon_object *obj;
|
||||||
|
@ -571,7 +556,7 @@ static BOOL CURSORICON_GetResIconEntry( LPCVOID dir, DWORD size, int n,
|
||||||
*width = icon->bWidth;
|
*width = icon->bWidth;
|
||||||
*height = icon->bHeight;
|
*height = icon->bHeight;
|
||||||
*bits = resdir->idEntries[n].wBitCount;
|
*bits = resdir->idEntries[n].wBitCount;
|
||||||
if (!*width && !*height && have_libpng()) *width = *height = 256;
|
if (!*width && !*height && png_funcs) *width = *height = 256;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +689,7 @@ static BOOL CURSORICON_GetFileEntry( LPCVOID dir, DWORD size, int n,
|
||||||
|
|
||||||
if (info->biSize == PNG_SIGN)
|
if (info->biSize == PNG_SIGN)
|
||||||
{
|
{
|
||||||
if (have_libpng()) return png_funcs->get_png_info(info, size, width, height, bits);
|
if (png_funcs) return png_funcs->get_png_info(info, size, width, height, bits);
|
||||||
*width = *height = *bits = 0;
|
*width = *height = *bits = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -858,7 +843,7 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE
|
||||||
{
|
{
|
||||||
BITMAPINFO *bmi_png;
|
BITMAPINFO *bmi_png;
|
||||||
|
|
||||||
if (!have_libpng()) return 0;
|
if (!png_funcs) return 0;
|
||||||
bmi_png = png_funcs->load_png( (const char *)bmi, &maxsize );
|
bmi_png = png_funcs->load_png( (const char *)bmi, &maxsize );
|
||||||
if (bmi_png)
|
if (bmi_png)
|
||||||
{
|
{
|
||||||
|
|
|
@ -293,7 +293,7 @@ static BITMAPINFO * CDECL load_png(const char *png_data, DWORD *size)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct png_funcs png_funcs =
|
static const struct png_funcs funcs =
|
||||||
{
|
{
|
||||||
get_png_info,
|
get_png_info,
|
||||||
load_png
|
load_png
|
||||||
|
@ -335,7 +335,7 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p
|
||||||
LOAD_FUNCPTR(png_set_read_fn);
|
LOAD_FUNCPTR(png_set_read_fn);
|
||||||
#undef LOAD_FUNCPTR
|
#undef LOAD_FUNCPTR
|
||||||
|
|
||||||
*(const struct png_funcs **)ptr_out = &png_funcs;
|
*(const struct png_funcs **)ptr_out = &funcs;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ static HPALETTE hPrimaryPalette;
|
||||||
|
|
||||||
static DWORD exiting_thread_id;
|
static DWORD exiting_thread_id;
|
||||||
|
|
||||||
|
const struct png_funcs *png_funcs = NULL;
|
||||||
|
|
||||||
extern void WDML_NotifyThreadDetach(void);
|
extern void WDML_NotifyThreadDetach(void);
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
@ -332,6 +334,7 @@ static BOOL process_attach(void)
|
||||||
palette_init();
|
palette_init();
|
||||||
|
|
||||||
keyboard_init();
|
keyboard_init();
|
||||||
|
__wine_init_unix_lib( user32_module, DLL_PROCESS_ATTACH, NULL, &png_funcs );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,6 +380,9 @@ struct png_funcs
|
||||||
BITMAPINFO * (CDECL *load_png)(const char *png_data, DWORD *size);
|
BITMAPINFO * (CDECL *load_png)(const char *png_data, DWORD *size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* May be NULL if libpng cannot be loaded. */
|
||||||
|
extern const struct png_funcs *png_funcs DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Mingw's assert() imports MessageBoxA and gets confused by user32 exporting it */
|
/* Mingw's assert() imports MessageBoxA and gets confused by user32 exporting it */
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#undef assert
|
#undef assert
|
||||||
|
|
Loading…
Reference in New Issue