windowscodecs: Add locking to StreamOnMemory.

This commit is contained in:
Vincent Povirk 2010-04-09 10:53:24 -05:00 committed by Alexandre Julliard
parent 8f6d268ee4
commit 40d48e674e
1 changed files with 39 additions and 13 deletions

View File

@ -41,6 +41,8 @@ typedef struct StreamOnMemory {
BYTE *pbMemory; BYTE *pbMemory;
DWORD dwMemsize; DWORD dwMemsize;
DWORD dwCurPos; DWORD dwCurPos;
CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */
} StreamOnMemory; } StreamOnMemory;
static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface, static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
@ -82,6 +84,8 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
TRACE("(%p) refcount=%u\n", iface, ref); TRACE("(%p) refcount=%u\n", iface, ref);
if (ref == 0) { if (ref == 0) {
This->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return ref; return ref;
@ -96,9 +100,12 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
if (!pv) return E_INVALIDARG; if (!pv) return E_INVALIDARG;
EnterCriticalSection(&This->lock);
uBytesRead = min(cb, This->dwMemsize - This->dwCurPos); uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead); memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
This->dwCurPos += uBytesRead; This->dwCurPos += uBytesRead;
LeaveCriticalSection(&This->lock);
if (pcbRead) *pcbRead = uBytesRead; if (pcbRead) *pcbRead = uBytesRead;
return S_OK; return S_OK;
@ -108,18 +115,26 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
void const *pv, ULONG cb, ULONG *pcbWritten) void const *pv, ULONG cb, ULONG *pcbWritten)
{ {
StreamOnMemory *This = (StreamOnMemory*)iface; StreamOnMemory *This = (StreamOnMemory*)iface;
HRESULT hr;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
if (!pv) return E_INVALIDARG; if (!pv) return E_INVALIDARG;
if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL; EnterCriticalSection(&This->lock);
if (cb) { if (cb > This->dwMemsize - This->dwCurPos) {
memcpy(This->pbMemory + This->dwCurPos, pv, cb); hr = STG_E_MEDIUMFULL;
This->dwCurPos += cb;
} }
if (pcbWritten) *pcbWritten = cb; else {
if (cb) {
memcpy(This->pbMemory + This->dwCurPos, pv, cb);
This->dwCurPos += cb;
hr = S_OK;
}
if (pcbWritten) *pcbWritten = cb;
}
LeaveCriticalSection(&This->lock);
return S_OK; return hr;
} }
static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface, static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
@ -127,20 +142,29 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
{ {
StreamOnMemory *This = (StreamOnMemory*)iface; StreamOnMemory *This = (StreamOnMemory*)iface;
LARGE_INTEGER NewPosition; LARGE_INTEGER NewPosition;
HRESULT hr=S_OK;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
EnterCriticalSection(&This->lock);
if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart; if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart; else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart;
else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart; else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart;
else return E_INVALIDARG; else hr = E_INVALIDARG;
if (NewPosition.u.HighPart) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); if (SUCCEEDED(hr)) {
if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG; if (NewPosition.u.HighPart) hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
if (NewPosition.QuadPart < 0) return E_INVALIDARG; else if (NewPosition.QuadPart > This->dwMemsize) hr = E_INVALIDARG;
This->dwCurPos = NewPosition.u.LowPart; else if (NewPosition.QuadPart < 0) hr = E_INVALIDARG;
}
if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos; if (SUCCEEDED(hr)) {
return S_OK; This->dwCurPos = NewPosition.u.LowPart;
if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
}
LeaveCriticalSection(&This->lock);
return hr;
} }
/* SetSize isn't implemented in the native windowscodecs DLL either */ /* SetSize isn't implemented in the native windowscodecs DLL either */
@ -450,6 +474,8 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
pObject->pbMemory = pbBuffer; pObject->pbMemory = pbBuffer;
pObject->dwMemsize = cbBufferSize; pObject->dwMemsize = cbBufferSize;
pObject->dwCurPos = 0; pObject->dwCurPos = 0;
InitializeCriticalSection(&pObject->lock);
pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock");
This->pStream = (IStream*)pObject; This->pStream = (IStream*)pObject;
return S_OK; return S_OK;