windowscodecs: Add locking to StreamOnMemory.
This commit is contained in:
parent
8f6d268ee4
commit
40d48e674e
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue