Commit 658cdb44 authored by Alexandre Julliard's avatar Alexandre Julliard

Make sure we don't hold the GDI lock when loading drivers.

parent 181e3d86
......@@ -527,6 +527,7 @@ extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj );
extern BOOL GDI_FreeObject( HGDIOBJ, void *obj );
extern void *GDI_GetObjPtr( HGDIOBJ, WORD );
extern void GDI_ReleaseObj( HGDIOBJ );
extern void GDI_CheckNotLock(void);
extern const DC_FUNCTIONS *DRIVER_load_driver( LPCSTR name );
extern const DC_FUNCTIONS *DRIVER_get_driver( const DC_FUNCTIONS *funcs );
......
......@@ -551,6 +551,8 @@ HDC WINAPI CreateDCA( LPCSTR driver, LPCSTR device, LPCSTR output,
const DC_FUNCTIONS *funcs;
char buf[300];
GDI_CheckNotLock();
if (!device || !DRIVER_GetDriverName( device, buf, sizeof(buf) ))
strcpy(buf, driver);
......@@ -654,23 +656,24 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
DC *dc, *origDC;
const DC_FUNCTIONS *funcs;
if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = DRIVER_get_driver(origDC->funcs);
else funcs = DRIVER_load_driver( "DISPLAY" );
GDI_CheckNotLock();
if (!funcs)
if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
{
if (origDC) GDI_ReleaseObj( hdc );
return 0;
funcs = origDC->funcs;
GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */
funcs = DRIVER_get_driver( funcs );
}
else funcs = DRIVER_load_driver( "DISPLAY" );
if (!funcs) return 0;
if (!(dc = DC_AllocDC( funcs )))
{
DRIVER_release_driver( funcs );
if (origDC) GDI_ReleaseObj( hdc );
return 0;
}
TRACE("(%04x): returning %04x\n",
hdc, dc->hSelf );
......@@ -681,16 +684,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
/* Copy the driver-specific physical device info into
* the new DC. The driver may use this read-only info
* while creating the compatible DC below. */
if (origDC)
dc->physDev = origDC->physDev;
if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev;
if (dc->funcs->pCreateDC &&
!dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
{
WARN("creation aborted by device\n");
GDI_FreeObject( dc->hSelf, dc );
DRIVER_release_driver( funcs );
if (origDC) GDI_ReleaseObj( hdc );
DRIVER_release_driver( funcs );
return 0;
}
......@@ -715,11 +717,15 @@ BOOL16 WINAPI DeleteDC16( HDC16 hdc )
*/
BOOL WINAPI DeleteDC( HDC hdc )
{
DC * dc = GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
const DC_FUNCTIONS *funcs = NULL;
DC * dc;
TRACE("%04x\n", hdc );
GDI_CheckNotLock();
if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
/* Call hook procedure to check whether is it OK to delete this DC */
if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY)))
{
......@@ -749,8 +755,8 @@ BOOL WINAPI DeleteDC( HDC hdc )
SelectObject( hdc, GetStockObject(BLACK_PEN) );
SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
funcs = dc->funcs;
if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
DRIVER_release_driver( dc->funcs );
}
if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
......@@ -760,7 +766,9 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk );
PATH_DestroyGdiPath(&dc->path);
return GDI_FreeObject( hdc, dc );
GDI_FreeObject( hdc, dc );
if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
return TRUE;
}
......
......@@ -160,14 +160,18 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
if(!dc) return FALSE;
if(dc->funcs->pStretchDIBits)
heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
heightDst, xSrc, ySrc, widthSrc,
heightSrc, bits, info, wUsage,
dwRop);
else { /* use StretchBlt */
{
heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
heightDst, xSrc, ySrc, widthSrc,
heightSrc, bits, info, wUsage, dwRop);
GDI_ReleaseObj( hdc );
}
else /* use StretchBlt */
{
HBITMAP hBitmap, hOldBitmap;
HDC hdcMem;
GDI_ReleaseObj( hdc );
hdcMem = CreateCompatibleDC( hdc );
if (info->bmiHeader.biCompression == BI_RLE4 ||
info->bmiHeader.biCompression == BI_RLE8) {
......@@ -212,7 +216,6 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
DeleteDC( hdcMem );
DeleteObject( hBitmap );
}
GDI_ReleaseObj( hdc );
return heightSrc;
}
......
......@@ -271,6 +271,9 @@ static void ReadFontInformation(
RegCloseKey(hkey);
}
static int stock_font_height[STOCK_LAST+1];
static int stock_font_width[STOCK_LAST+1];
/***********************************************************************
* Because the stock fonts have their structure initialized with
* a height of 0 to keep them independent of mapping mode, simply
......@@ -278,20 +281,26 @@ static void ReadFontInformation(
* These "FixStockFontSizeXXX()" methods will get the correct
* size for the fonts.
*/
static void GetFontMetrics(HFONT handle, LPTEXTMETRICA lptm)
static void init_stock_fonts_metrics(void)
{
HDC hdc;
HFONT hOldFont;
hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
hOldFont = (HFONT)SelectObject(hdc, handle);
GetTextMetricsA(hdc, lptm);
int i;
TEXTMETRICA tm;
HDC hdc;
static int done;
SelectObject(hdc, hOldFont);
if (done) return;
done = 1;
hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
DeleteDC(hdc);
for (i = 0; i <= STOCK_LAST; i++)
{
if (GetObjectType( GetStockObject(i) ) != OBJ_FONT) continue;
SelectObject( hdc, GetStockObject(i) );
GetTextMetricsA( hdc, &tm );
stock_font_height[i] = tm.tmHeight;
stock_font_width[i] = tm.tmAveCharWidth;
}
DeleteDC(hdc);
}
static inline void FixStockFontSize16(
......@@ -299,7 +308,6 @@ static inline void FixStockFontSize16(
INT16 count,
LPVOID buffer)
{
TEXTMETRICA tm;
LOGFONT16* pLogFont = (LOGFONT16*)buffer;
/*
......@@ -309,10 +317,8 @@ static inline void FixStockFontSize16(
if ( (count >= 2*sizeof(INT16)) &&
(pLogFont->lfHeight == 0) )
{
GetFontMetrics(handle, &tm);
pLogFont->lfHeight = tm.tmHeight;
pLogFont->lfWidth = tm.tmAveCharWidth;
pLogFont->lfHeight = stock_font_height[handle-FIRST_STOCK_HANDLE];
pLogFont->lfWidth = stock_font_width[handle-FIRST_STOCK_HANDLE];
}
}
......@@ -321,7 +327,6 @@ static inline void FixStockFontSizeA(
INT count,
LPVOID buffer)
{
TEXTMETRICA tm;
LOGFONTA* pLogFont = (LOGFONTA*)buffer;
/*
......@@ -331,10 +336,8 @@ static inline void FixStockFontSizeA(
if ( (count >= 2*sizeof(INT)) &&
(pLogFont->lfHeight == 0) )
{
GetFontMetrics(handle, &tm);
pLogFont->lfHeight = tm.tmHeight;
pLogFont->lfWidth = tm.tmAveCharWidth;
pLogFont->lfHeight = stock_font_height[handle-FIRST_STOCK_HANDLE];
pLogFont->lfWidth = stock_font_width[handle-FIRST_STOCK_HANDLE];
}
}
......@@ -576,6 +579,15 @@ void GDI_ReleaseObj( HGDIOBJ handle )
/***********************************************************************
* GDI_CheckNotLock
*/
void GDI_CheckNotLock(void)
{
_CheckNotSysLevel( &GDI_level );
}
/***********************************************************************
* DeleteObject (GDI.69)
* SysDeleteObject (GDI.605)
*/
......@@ -668,6 +680,8 @@ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
TRACE("%04x %d %p\n", handle, count, buffer );
if (!count) return 0;
if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics();
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(GDIMAGIC(ptr->wMagic))
......@@ -710,6 +724,8 @@ INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
TRACE("%08x %d %p\n", handle, count, buffer );
if (!count) return 0;
if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics();
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(GDIMAGIC(ptr->wMagic))
......@@ -766,6 +782,8 @@ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
TRACE("%08x %d %p\n", handle, count, buffer );
if (!count) return 0;
if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics();
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
switch(GDIMAGIC(ptr->wMagic))
......
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