Don't hold the GDI lock during accesses to the metafile data.

This commit is contained in:
Alexandre Julliard 2001-08-23 23:37:00 +00:00
parent bf55457f24
commit 8af0eda77a
2 changed files with 36 additions and 131 deletions

View File

@ -72,24 +72,18 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
* EMF_GetEnhMetaHeader
*
* Returns ptr to ENHMETAHEADER associated with HENHMETAFILE
* Should be followed by call to EMF_ReleaseEnhMetaHeader
*/
static ENHMETAHEADER *EMF_GetEnhMetaHeader( HENHMETAFILE hmf )
{
ENHMETAFILEOBJ *metaObj = (ENHMETAFILEOBJ *)GDI_GetObjPtr( hmf,
ENHMETAFILE_MAGIC );
ENHMETAHEADER *ret = NULL;
ENHMETAFILEOBJ *metaObj = (ENHMETAFILEOBJ *)GDI_GetObjPtr( hmf, ENHMETAFILE_MAGIC );
TRACE("hmf %04x -> enhmetaObj %p\n", hmf, metaObj);
return metaObj ? metaObj->emh : NULL;
}
/******************************************************************
* EMF_ReleaseEnhMetaHeader
*
* Releases ENHMETAHEADER associated with HENHMETAFILE
*/
static void EMF_ReleaseEnhMetaHeader( HENHMETAFILE hmf )
{
GDI_ReleaseObj( hmf );
if (metaObj)
{
ret = metaObj->emh;
GDI_ReleaseObj( hmf );
}
return ret;
}
/*****************************************************************************
@ -179,13 +173,9 @@ UINT WINAPI GetEnhMetaFileHeader(
emh = EMF_GetEnhMetaHeader(hmf);
if(!emh) return FALSE;
size = emh->nSize;
if (!buf) {
EMF_ReleaseEnhMetaHeader(hmf);
return size;
}
if (!buf) return size;
size = min(size, bufsize);
memmove(buf, emh, size);
EMF_ReleaseEnhMetaHeader(hmf);
return size;
}
@ -204,21 +194,14 @@ UINT WINAPI GetEnhMetaFileDescriptionA(
WCHAR *descrW;
if(!emh) return FALSE;
if(emh->nDescription == 0 || emh->offDescription == 0) {
EMF_ReleaseEnhMetaHeader(hmf);
return 0;
}
if(emh->nDescription == 0 || emh->offDescription == 0) return 0;
descrW = (WCHAR *) ((char *) emh + emh->offDescription);
len = WideCharToMultiByte( CP_ACP, 0, descrW, emh->nDescription, NULL, 0, NULL, NULL );
if (!buf || !size ) {
EMF_ReleaseEnhMetaHeader(hmf);
return len;
}
if (!buf || !size ) return len;
len = min( size, len );
WideCharToMultiByte( CP_ACP, 0, descrW, emh->nDescription, buf, len, NULL, NULL );
EMF_ReleaseEnhMetaHeader(hmf);
return len;
}
@ -240,18 +223,10 @@ UINT WINAPI GetEnhMetaFileDescriptionW(
LPENHMETAHEADER emh = EMF_GetEnhMetaHeader(hmf);
if(!emh) return FALSE;
if(emh->nDescription == 0 || emh->offDescription == 0) {
EMF_ReleaseEnhMetaHeader(hmf);
return 0;
}
if (!buf || !size ) {
EMF_ReleaseEnhMetaHeader(hmf);
return emh->nDescription;
}
memmove(buf, (char *) emh + emh->offDescription,
min(size,emh->nDescription)*sizeof(WCHAR));
EMF_ReleaseEnhMetaHeader(hmf);
if(emh->nDescription == 0 || emh->offDescription == 0) return 0;
if (!buf || !size ) return emh->nDescription;
memmove(buf, (char *) emh + emh->offDescription, min(size,emh->nDescription)*sizeof(WCHAR));
return min(size, emh->nDescription);
}
@ -283,15 +258,10 @@ UINT WINAPI GetEnhMetaFileBits(
if(!emh) return 0;
size = emh->nBytes;
if( buf == NULL ) {
EMF_ReleaseEnhMetaHeader( hmf );
return size;
}
if( buf == NULL ) return size;
size = min( size, bufsize );
memmove(buf, emh, size);
EMF_ReleaseEnhMetaHeader( hmf );
return size;
}
@ -1537,7 +1507,7 @@ BOOL WINAPI EnumEnhMetaFile(
)
{
BOOL ret;
ENHMETAHEADER *emh, *emhTemp;
ENHMETAHEADER *emh;
ENHMETARECORD *emr;
DWORD offset;
UINT i;
@ -1561,23 +1531,10 @@ BOOL WINAPI EnumEnhMetaFile(
return FALSE;
}
/* Copy the metafile into memory, because we need to avoid deadlock. */
emhTemp = HeapAlloc(GetProcessHeap(), 0, emh->nSize + emh->nBytes);
if(!emhTemp)
{
EMF_ReleaseEnhMetaHeader(hmf);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
memcpy(emhTemp, emh, emh->nSize + emh->nBytes);
emh = emhTemp;
EMF_ReleaseEnhMetaHeader(hmf);
ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HANDLETABLE) * emh->nHandles );
if(!ht)
{
HeapFree(GetProcessHeap(), 0, emhTemp);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
@ -1649,8 +1606,6 @@ BOOL WINAPI EnumEnhMetaFile(
DeleteObject( (ht->objectHandle)[i] );
HeapFree( GetProcessHeap(), 0, ht );
HeapFree(GetProcessHeap(), 0, emhTemp);
return ret;
}
@ -1713,7 +1668,6 @@ HENHMETAFILE WINAPI CopyEnhMetaFileA(
hmfDst = EMF_GetEnhMetaFile( hFile );
CloseHandle( hFile );
}
EMF_ReleaseEnhMetaHeader( hmfSrc );
return hmfDst;
}
@ -1775,26 +1729,16 @@ UINT WINAPI GetEnhMetaFilePaletteEntries( HENHMETAFILE hEmf,
LPPALETTEENTRY lpPe )
{
ENHMETAHEADER* enhHeader = EMF_GetEnhMetaHeader( hEmf );
UINT uReturnValue = GDI_ERROR;
EMF_PaletteCopy infoForCallBack;
TRACE( "(%04x,%d,%p)\n", hEmf, cEntries, lpPe );
/* First check if there are any palettes associated with
this metafile. */
if ( enhHeader->nPalEntries == 0 )
{
/* No palette associated with this enhanced metafile */
uReturnValue = 0;
goto done;
}
if ( enhHeader->nPalEntries == 0 ) return 0;
/* Is the user requesting the number of palettes? */
if ( lpPe == NULL )
{
uReturnValue = (UINT)enhHeader->nPalEntries;
goto done;
}
if ( lpPe == NULL ) return (UINT)enhHeader->nPalEntries;
/* Copy cEntries worth of PALETTEENTRY structs into the buffer */
infoForCallBack.cEntries = cEntries;
@ -1802,25 +1746,17 @@ UINT WINAPI GetEnhMetaFilePaletteEntries( HENHMETAFILE hEmf,
if ( !EnumEnhMetaFile( 0, hEmf, cbEnhPaletteCopy,
&infoForCallBack, NULL ) )
{
goto done;
}
return GDI_ERROR;
/* Verify that the callback executed correctly */
if ( infoForCallBack.lpPe != NULL )
{
/* Callback proc had error! */
ERR( "cbEnhPaletteCopy didn't execute correctly\n" );
goto done;
return GDI_ERROR;
}
uReturnValue = infoForCallBack.cEntries;
done:
EMF_ReleaseEnhMetaHeader( hEmf );
return uReturnValue;
return infoForCallBack.cEntries;
}
/******************************************************************

View File

@ -125,12 +125,17 @@ HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh)
* MF_GetMetaHeader
*
* Returns ptr to METAHEADER associated with HMETAFILE
* Should be followed by call to MF_ReleaseMetaHeader
*/
static METAHEADER *MF_GetMetaHeader( HMETAFILE hmf )
{
METAHEADER *ret = NULL;
METAFILEOBJ * metaObj = (METAFILEOBJ *)GDI_GetObjPtr( hmf, METAFILE_MAGIC );
return metaObj ? metaObj->mh : 0;
if (metaObj)
{
ret = metaObj->mh;
GDI_ReleaseObj( hmf );
}
return ret;
}
/******************************************************************
@ -144,16 +149,6 @@ static METAHEADER *MF_GetMetaHeader16( HMETAFILE16 hmf )
return GlobalLock16(hmf);
}
/******************************************************************
* MF_ReleaseMetaHeader
*
* Releases METAHEADER associated with HMETAFILE
*/
static void MF_ReleaseMetaHeader( HMETAFILE hmf )
{
GDI_ReleaseObj( hmf );
}
/******************************************************************
* MF_ReleaseMetaHeader16
*
@ -415,7 +410,6 @@ HMETAFILE WINAPI CopyMetaFileA(
mh2 = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 );
memcpy( mh2, mh, mh->mtSize * 2 );
}
MF_ReleaseMetaHeader( hSrcMetaFile );
if(lpFilename) { /* disk based metafile */
if((hFile = CreateFileA(lpFilename, GENERIC_WRITE, 0, NULL,
@ -566,11 +560,8 @@ BOOL WINAPI PlayMetaFile(
HMETAFILE hmf /* [in] handle of metafile to render */
)
{
BOOL ret;
METAHEADER *mh = MF_GetMetaHeader( hmf );
ret = MF_PlayMetaFile( hdc, mh );
MF_ReleaseMetaHeader( hmf );
return ret;
return MF_PlayMetaFile( hdc, mh );
}
@ -684,35 +675,15 @@ BOOL WINAPI EnumMetaFile(
HBRUSH hBrush;
HFONT hFont;
TRACE("(%08x,%08x,%p,%p)\n",
hdc, hmf, lpEnumFunc, (void*)lpData);
TRACE("(%08x,%08x,%p,%p)\n", hdc, hmf, lpEnumFunc, (void*)lpData);
if (!mh) return 0;
if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */
mhTemp = MF_LoadDiskBasedMetaFile(mh);
if(!mhTemp)
{
MF_ReleaseMetaHeader(hmf);
return FALSE;
}
mh = mhTemp;
}
else
if(mh->mtType == METAFILE_DISK)
{
/* We need to copy this thing instead of use it directly because we
* have to close the hmf handle for the purpose of avoiding deadlock.
*/
mhTemp = HeapAlloc( GetProcessHeap(), 0, mh->mtHeaderSize + mh->mtSize*2 );
if(!mhTemp)
{
MF_ReleaseMetaHeader(hmf);
return FALSE;
}
memcpy( mhTemp, mh, mh->mtHeaderSize + mh->mtSize*2 );
/* Create a memory-based copy */
if (!(mhTemp = MF_LoadDiskBasedMetaFile(mh))) return FALSE;
mh = mhTemp;
}
MF_ReleaseMetaHeader(hmf);
hmf = 0; /* just in case */
/* save the current pen, brush and font */
hPen = GetCurrentObject(hdc, OBJ_PEN);
hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
@ -751,7 +722,7 @@ BOOL WINAPI EnumMetaFile(
/* free handle table */
HeapFree( GetProcessHeap(), 0, ht);
/* free a copy of metafile */
HeapFree( GetProcessHeap(), 0, mh );
if (mhTemp) HeapFree( GetProcessHeap(), 0, mhTemp );
return result;
}
@ -1334,13 +1305,11 @@ UINT WINAPI GetMetaFileBitsEx(
FIXME("Disk-based metafile?\n");
mfSize = mh->mtSize * 2;
if (!buf) {
MF_ReleaseMetaHeader(hmf);
TRACE("returning size %d\n", mfSize);
return mfSize;
}
if(mfSize > nSize) mfSize = nSize;
memmove(buf, mh, mfSize);
MF_ReleaseMetaHeader(hmf);
return mfSize;
}