diff options
Diffstat (limited to 'private/oleutest/balls/client/tmarshal/stream.cxx')
-rw-r--r-- | private/oleutest/balls/client/tmarshal/stream.cxx | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/private/oleutest/balls/client/tmarshal/stream.cxx b/private/oleutest/balls/client/tmarshal/stream.cxx new file mode 100644 index 000000000..5c6f34717 --- /dev/null +++ b/private/oleutest/balls/client/tmarshal/stream.cxx @@ -0,0 +1,315 @@ +//+------------------------------------------------------------------- +// +// File: stream.cxx +// +// Contents: Stream interface on flat File. +// +// Classes: CStreamOnFile +// +// Macros: DEFINE_INTERFACE_XMIT_ROUTINES +// +// History: 08-08-95 Rickhi Created +// +//-------------------------------------------------------------------- +#include <ole2.h> +#include <stream.hxx> + + +CStreamOnFile::CStreamOnFile(const WCHAR *pwszFileName, SCODE &sc, BOOL fRead) : + _clRefs(1), + _hFile(NULL), + _lOffset(0), + _cSize(0), + _cbData(0), + _fRead(fRead) +{ + _pbData = new BYTE[2048]; // should be big enough + if (!_pbData) + { + sc = E_OUTOFMEMORY; + return; + } + + _cbData = 2048; + + // open the file. + DWORD fdwCreate = (_fRead) ? OPEN_EXISTING : CREATE_ALWAYS; + + + _hFile = CreateFileW(pwszFileName, + GENERIC_READ | GENERIC_WRITE, // fdwAccess + FILE_SHARE_READ | FILE_SHARE_WRITE, // fdwShareMode + NULL, // lpsaSecurity + fdwCreate, // creation options + FILE_ATTRIBUTE_NORMAL, // attributes & flags + NULL // hTemplateFile + ); + + if (_hFile == INVALID_HANDLE_VALUE) + { + sc = HRESULT_FROM_WIN32(GetLastError()); + return; + } + + // read the file into the memory block + DWORD cbRead = 0; + if (_fRead && ! ReadFile(_hFile, + _pbData, + _cbData, + &cbRead, + NULL)) + { + sc = HRESULT_FROM_WIN32(GetLastError()); + return; + } + + if (_fRead) + { + _cSize = _cbData; + } + + sc = S_OK; +} + +CStreamOnFile::~CStreamOnFile(void) +{ + if (_hFile) + { + if (!_fRead) + { + // write the data to the file + DWORD cbWritten = 0; + if (!WriteFile(_hFile, + _pbData, + _cbData, + &cbWritten, + NULL)) + { + SCODE sc = HRESULT_FROM_WIN32(GetLastError()); + } + } + + CloseHandle(_hFile); + } +} + + + +STDMETHODIMP CStreamOnFile::QueryInterface( + REFIID iidInterface, + void FAR* FAR* ppvObj) +{ + HRESULT hresult = S_OK; + + // We only support IUnknown and IStream + if (IsEqualIID(iidInterface, IID_IUnknown) || + IsEqualIID(iidInterface, IID_IStream)) + { + *ppvObj = this; + AddRef(); + } + else + { + *ppvObj = NULL; + hresult = E_NOINTERFACE; + } + + return hresult; +} + +STDMETHODIMP_(ULONG) CStreamOnFile::AddRef(void) +{ + InterlockedIncrement(&_clRefs); + return _clRefs; +} + +STDMETHODIMP_(ULONG) CStreamOnFile::Release(void) +{ + if (InterlockedDecrement(&_clRefs) == 0) + { + delete this; + return 0; + } + + return _clRefs; +} + +STDMETHODIMP CStreamOnFile::Read( + VOID HUGEP* pv, + ULONG cb, + ULONG FAR* pcbRead) +{ + HRESULT hresult = S_OK; + + if (pcbRead) + { + *pcbRead = 0L; + } + + if ((LONG)cb + _lOffset > _cSize) + { + cb = _cSize - _lOffset; + hresult = STG_E_READFAULT; + } + + memcpy(pv, _pbData + _lOffset, (size_t) cb); + _lOffset += cb; + + if (pcbRead != NULL) + { + *pcbRead = cb; + } + + return hresult; +} + +STDMETHODIMP CStreamOnFile::Write( + VOID const HUGEP* pv, + ULONG cbToWrite, + ULONG FAR* pcbWritten) +{ + HRESULT hresult = S_OK; + + if (pcbWritten) + { + *pcbWritten = 0L; + } + + if (cbToWrite + _lOffset > _cbData) + { + return E_OUTOFMEMORY; + } + + // copy in the new data + memcpy(_pbData + _lOffset, pv, (size_t) cbToWrite); + _lOffset += cbToWrite; + + if (pcbWritten != NULL) + { + *pcbWritten = cbToWrite; + } + + // We assume maxium size of buffer is the size to send on the network. + if (_cSize < _lOffset) + { + _cSize = _lOffset; + } + + return hresult; +} + + + +STDMETHODIMP CStreamOnFile::Seek( + LARGE_INTEGER dlibMoveIN, + DWORD dwOrigin, + ULARGE_INTEGER FAR* plibNewPosition) +{ + HRESULT hresult = S_OK; + + LONG dlibMove = dlibMoveIN.LowPart; + ULONG cbNewPos = dlibMove; + + switch(dwOrigin) + { + case STREAM_SEEK_SET: + + if (dlibMove >= 0) + { + _lOffset = dlibMove; + } + else + { + hresult = STG_E_SEEKERROR; + } + break; + + case STREAM_SEEK_CUR: + + if (!(dlibMove < 0 && (-dlibMove > _lOffset))) + { + _lOffset += (ULONG) dlibMove; + } + else + { + hresult = STG_E_SEEKERROR; + } + break; + + case STREAM_SEEK_END: + + if (!(dlibMove < 0 && ((ULONG) -dlibMove) > _cbData)) + { + _lOffset = _cbData + dlibMove; + } + else + { + hresult = STG_E_SEEKERROR; + } + break; + + default: + + hresult = STG_E_SEEKERROR; + } + + if (plibNewPosition != NULL) + { + ULISet32(*plibNewPosition, _lOffset); + } + + return hresult; +} + +STDMETHODIMP CStreamOnFile::SetSize(ULARGE_INTEGER cb) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CStreamOnFile::CopyTo( + IStream FAR* pstm, + ULARGE_INTEGER cb, + ULARGE_INTEGER FAR* pcbRead, + ULARGE_INTEGER FAR* pcbWritten) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CStreamOnFile::Commit(DWORD grfCommitFlags) +{ + return NOERROR; +} + +STDMETHODIMP CStreamOnFile::Revert(void) +{ + return NOERROR; +} + +STDMETHODIMP CStreamOnFile::LockRegion( + ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, + DWORD dwLockType) +{ + return STG_E_INVALIDFUNCTION; +} + +STDMETHODIMP CStreamOnFile::UnlockRegion( + ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, + DWORD dwLockType) +{ + return STG_E_INVALIDFUNCTION; +} + +STDMETHODIMP CStreamOnFile::Stat( + STATSTG FAR* pstatstg, + DWORD statflag) +{ + memset(pstatstg, 0, sizeof(STATSTG)); + return E_NOTIMPL; +} + +STDMETHODIMP CStreamOnFile::Clone(IStream FAR * FAR *ppstm) +{ + return E_NOTIMPL; +} |