Make sure we don't hold the GDI lock when loading drivers.
This commit is contained in:
parent
181e3d8614
commit
658cdb4412
|
@ -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 );
|
||||
|
|
38
objects/dc.c
38
objects/dc.c
|
@ -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);
|
||||
GDI_CheckNotLock();
|
||||
|
||||
if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (origDC) GDI_ReleaseObj( hdc );
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
int i;
|
||||
TEXTMETRICA tm;
|
||||
HDC hdc;
|
||||
static int done;
|
||||
|
||||
hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
|
||||
if (done) return;
|
||||
done = 1;
|
||||
hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
|
||||
|
||||
hOldFont = (HFONT)SelectObject(hdc, handle);
|
||||
|
||||
GetTextMetricsA(hdc, lptm);
|
||||
|
||||
SelectObject(hdc, hOldFont);
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,6 +578,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))
|
||||
|
|
Loading…
Reference in New Issue