|
|
// Stream.cpp -- Implementation for class CStream
#include "stdafx.h"
HRESULT CStream::OpenStream(IUnknown *punkOuter, ILockBytes *pLockBytes, DWORD grfMode, IStreamITEx **ppStream ) { CStream *pStream= New CStream(punkOuter);
if (!pStream) { pLockBytes->Release(); return STG_E_INSUFFICIENTMEMORY; }
IStreamITEx *pIStream = NULL; HRESULT hr= pStream->m_ImpIStream.InitOpenStream(pLockBytes, grfMode);
if (hr == NOERROR) { pIStream = (IStreamITEx *) &pStream->m_ImpIStream; pStream->AddRef(); } else delete pStream;
*ppStream= pIStream;
return hr; }
HRESULT CStream::CImpIStream::InitOpenStream(ILockBytes *pLockBytes, DWORD grfMode) { m_pLockBytes = pLockBytes; m_grfMode = grfMode;
// Note: We assume that pLockBytes was AddRef'd before it was given to us.
return NO_ERROR; }
// ISequentialStream methods:
HRESULT __stdcall CStream::CImpIStream::Read (void __RPC_FAR *pv,ULONG cb,ULONG __RPC_FAR *pcbRead) { DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
if (grfAccess != STGM_READ && grfAccess != STGM_READWRITE) return STG_E_ACCESSDENIED; CSyncWith sw(m_cs);
ULONG cbRead = 0;
HRESULT hr = m_pLockBytes->ReadAt(m_ullStreamPosition.Uli(), pv, cb, &cbRead);
m_ullStreamPosition += cbRead;
if (pcbRead) *pcbRead = cbRead;
return hr; }
HRESULT __stdcall CStream::CImpIStream::Write (const void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbWritten ) { DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
if (grfAccess != STGM_WRITE && grfAccess != STGM_READWRITE) return STG_E_ACCESSDENIED; CSyncWith sw(m_cs);
ULONG cbWritten = 0; HRESULT hr = m_pLockBytes->WriteAt(m_ullStreamPosition.Uli(), pv, cb, &cbWritten);
m_ullStreamPosition += cbWritten;
if (pcbWritten) *pcbWritten = cbWritten;
return hr; }
// IStream methods:
HRESULT __stdcall CStream::CImpIStream::Seek (LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER __RPC_FAR *plibNewPosition ) { HRESULT hr = NO_ERROR; CSyncWith sw(m_cs);
STATSTG statstg;
hr = m_pLockBytes->Stat(&statstg, STATFLAG_NONAME);
if (!SUCCEEDED(hr)) return hr;
CULINT ullNewPosition;
switch (dwOrigin) { case STREAM_SEEK_SET:
ullNewPosition = *(ULARGE_INTEGER *) &dlibMove;
break;
case STREAM_SEEK_CUR:
ullNewPosition = m_ullStreamPosition + *(ULARGE_INTEGER *) &dlibMove;
break;
case STREAM_SEEK_END:
ullNewPosition = statstg.cbSize; ullNewPosition += *(ULARGE_INTEGER *) &dlibMove; break;
default:
return STG_E_INVALIDFUNCTION; }
if (ullNewPosition > statstg.cbSize) return STG_E_INVALIDPOINTER;
m_ullStreamPosition = ullNewPosition;
if (plibNewPosition) *plibNewPosition = ullNewPosition.Uli();
return hr; }
HRESULT __stdcall CStream::CImpIStream::SetSize(ULARGE_INTEGER libNewSize) { DWORD grfAccess = m_grfMode & RW_ACCESS_MASK;
if (grfAccess != STGM_WRITE && grfAccess != STGM_READWRITE) return STG_E_ACCESSDENIED; return m_pLockBytes->SetSize(libNewSize); }
HRESULT __stdcall CStream::CImpIStream::CopyTo (IStream __RPC_FAR *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER __RPC_FAR *pcbRead, ULARGE_INTEGER __RPC_FAR *pcbWritten ) { BYTE abBuffer[CB_MAX_COPY_SEGMENT];
CULINT ullRequested, ullRead(0), ullWritten(0);
ullRequested = cb;
HRESULT hr = NO_ERROR;
CSyncWith sw(m_cs);
ULONG ulSegment;
for (; ullRequested.NonZero(); ullRequested -= ulSegment) { ulSegment = CB_MAX_COPY_SEGMENT;
if (ulSegment > ullRequested) ulSegment = ullRequested.Uli().LowPart;
ULONG cbRead = 0;
hr = Read(abBuffer, ulSegment, &cbRead);
ullRead += cbRead;
if (!SUCCEEDED(hr)) break;
ULONG cbWritten = 0;
hr = pstm->Write(abBuffer, ulSegment, &cbWritten); ullWritten += cbWritten;
if (!SUCCEEDED(hr)) break; }
if (pcbRead) *pcbRead = ullRead.Uli();
if (pcbWritten) *pcbWritten = ullWritten.Uli();
return hr; }
HRESULT __stdcall CStream::CImpIStream::Commit(DWORD grfCommitFlags) { return NO_ERROR; }
HRESULT __stdcall CStream::CImpIStream::Revert(void) { RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
return E_NOTIMPL; }
HRESULT __stdcall CStream::CImpIStream::LockRegion (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType ) { return m_pLockBytes->LockRegion(libOffset, cb, dwLockType); }
HRESULT __stdcall CStream::CImpIStream::UnlockRegion (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType ) { return m_pLockBytes->UnlockRegion(libOffset, cb, dwLockType); }
HRESULT __stdcall CStream::CImpIStream::Stat (STATSTG __RPC_FAR *pstatstg, DWORD grfStatFlag) { HRESULT hr = m_pLockBytes->Stat(pstatstg, grfStatFlag);
if (SUCCEEDED(hr)) pstatstg->type = STGTY_STREAM;
return hr; }
HRESULT __stdcall CStream::CImpIStream::Clone (IStream __RPC_FAR *__RPC_FAR *ppstm) { CImpIStream *pStreamNew = NULL;
m_pLockBytes->AddRef(); HRESULT hr = CStream::OpenStream(NULL, m_pLockBytes, m_grfMode, (IStreamITEx **)&pStreamNew );
if (SUCCEEDED(hr)) { pStreamNew->m_ullStreamPosition = m_ullStreamPosition;
*ppstm = (IStream *) pStreamNew; }
return hr; }
HRESULT STDMETHODCALLTYPE CStream::CImpIStream::SetDataSpaceName (const WCHAR *pwcsDataSpaceName) { RonM_ASSERT(FALSE);
return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE CStream::CImpIStream::GetDataSpaceName (WCHAR **ppwcsDataSpaceName) { RonM_ASSERT(FALSE);
return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE CStream::CImpIStream::Flush() { return m_pLockBytes->Flush(); }
|