Commit 3caf7204 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

windowscodecs: Add locking to the GIF decoder.

parent c1beb636
...@@ -40,6 +40,7 @@ typedef struct { ...@@ -40,6 +40,7 @@ typedef struct {
LONG ref; LONG ref;
BOOL initialized; BOOL initialized;
GifFileType *gif; GifFileType *gif;
CRITICAL_SECTION lock;
} GifDecoder; } GifDecoder;
typedef struct { typedef struct {
...@@ -302,6 +303,8 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) ...@@ -302,6 +303,8 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface)
if (ref == 0) if (ref == 0)
{ {
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
DGifCloseFile(This->gif); DGifCloseFile(This->gif);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
...@@ -341,9 +344,12 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p ...@@ -341,9 +344,12 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions);
EnterCriticalSection(&This->lock);
if (This->initialized || This->gif) if (This->initialized || This->gif)
{ {
WARN("already initialized\n"); WARN("already initialized\n");
LeaveCriticalSection(&This->lock);
return WINCODEC_ERR_WRONGSTATE; return WINCODEC_ERR_WRONGSTATE;
} }
...@@ -353,16 +359,26 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p ...@@ -353,16 +359,26 @@ static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
/* read all data from the stream */ /* read all data from the stream */
This->gif = DGifOpen((void*)pIStream, _gif_inputfunc); This->gif = DGifOpen((void*)pIStream, _gif_inputfunc);
if (!This->gif) return E_FAIL; if (!This->gif)
{
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
ret = DGifSlurp(This->gif); ret = DGifSlurp(This->gif);
if (ret == GIF_ERROR) return E_FAIL; if (ret == GIF_ERROR)
{
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
/* make sure we don't use the stream after this method returns */ /* make sure we don't use the stream after this method returns */
This->gif->UserData = NULL; This->gif->UserData = NULL;
This->initialized = TRUE; This->initialized = TRUE;
LeaveCriticalSection(&This->lock);
return S_OK; return S_OK;
} }
...@@ -502,6 +518,8 @@ HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) ...@@ -502,6 +518,8 @@ HRESULT GifDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->ref = 1; This->ref = 1;
This->initialized = FALSE; This->initialized = FALSE;
This->gif = NULL; This->gif = NULL;
InitializeCriticalSection(&This->lock);
This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This); IUnknown_Release((IUnknown*)This);
......
...@@ -757,7 +757,7 @@ static struct regsvr_coclass const coclass_list[] = { ...@@ -757,7 +757,7 @@ static struct regsvr_coclass const coclass_list[] = {
"WIC GIF Decoder", "WIC GIF Decoder",
NULL, NULL,
"windowscodecs.dll", "windowscodecs.dll",
"Apartment" "Both"
}, },
{ &CLSID_WICIcoDecoder, { &CLSID_WICIcoDecoder,
"WIC ICO Decoder", "WIC ICO Decoder",
......
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