123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- #pragma once
- #ifndef __SimpleStream_h__
- #define __SimpleStream_h__
- /////////////////////////////////////////////////////////////////////////////
- // SimpleStream.h : Declaration of the CTCSimpleStreamImpl class.
- /////////////////////////////////////////////////////////////////////////////
- // Description: A class that implements an object that supports the IStream
- // interface and, therefore, also ISequentialStream. The implementation is
- // very simple in that the stream is a fixed size (non-growable), and is
- // implemented on a specified pointer.
- //
- // This object provides an implementation of the IStream interface that is
- // imlemented on a fixed, non-growable, memory block.
- //
- // Note: This implementation does *not* provide any thread synchronization.
- // It also does not keep track of any of the time fields. The Stat method
- // will always return the current time for all of the time fields.
- //
- class ATL_NO_VTABLE CTCSimpleStreamImpl :
- public IStream,
- public CComObjectRoot
- {
- /////////////////////////////////////////////////////////////////////////////
- // Interface Map
- public:
- BEGIN_COM_MAP(CTCSimpleStreamImpl)
- COM_INTERFACE_ENTRY(IStream)
- COM_INTERFACE_ENTRY(ISequentialStream)
- END_COM_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // Construction
- public:
- ///////////////////////////////////////////////////////////////////////////
- CTCSimpleStreamImpl() :
- m_pbBegin(NULL),
- m_pbPosition(NULL),
- m_pbEnd(NULL)
- {
- }
- ///////////////////////////////////////////////////////////////////////////
- void Init(ULONG cbData, void* pvData)
- {
- assert(!m_pbBegin && !m_pbPosition && !m_pbEnd);
- assert(cbData);
- assert(pvData);
- assert(!IsBadReadPtr(pvData, cbData));
- m_pbBegin = m_pbPosition = reinterpret_cast<BYTE*>(pvData);
- m_pbEnd = m_pbBegin + cbData;
- }
- /////////////////////////////////////////////////////////////////////////////
- // ISequentialStream Interface Methods
- public:
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- assert(!IsBadWritePtr(pv, cb));
- assert(!pcbRead || !IsBadWritePtr(pcbRead, sizeof(*pcbRead)));
- // Compute the number of bytes that can be read
- ULONG nMax = m_pbEnd - m_pbPosition;
- nMax = min(nMax, cb);
- // Copy the maximum number of bytes to the specified buffer
- assert(!IsBadReadPtr(m_pbPosition, nMax));
- CopyMemory(pv, m_pbPosition, nMax);
- // Update the current position
- m_pbPosition += nMax;
- // Return the number of bytes read, if requested
- if (pcbRead)
- *pcbRead = nMax;
- // Indicate success
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Write(const void* pv, ULONG cb, ULONG* pcbWritten)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- assert(!IsBadReadPtr(pv, cb));
- assert(!pcbWritten || !IsBadWritePtr(pcbWritten, sizeof(*pcbWritten)));
- // Compute the number of bytes that can be written
- ULONG nMax = m_pbEnd - m_pbPosition;
- nMax = min(nMax, cb);
- // Copy the maximum number of bytes from the specified buffer
- assert(!IsBadWritePtr(m_pbPosition, nMax));
- CopyMemory(m_pbPosition, pv, nMax);
- // Update the current position
- m_pbPosition += nMax;
- // Return the number of bytes written, if requested
- if (pcbWritten)
- *pcbWritten = nMax;
- // Indicate success
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IStream Interface Methods
- public:
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
- ULARGE_INTEGER* plibNewPosition)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- assert(!plibNewPosition || !IsBadWritePtr(plibNewPosition,
- sizeof(*plibNewPosition)));
- // Clear the specified [out] parameter, if not NULL
- if (plibNewPosition)
- TCZeroMemory(plibNewPosition);
- switch (dwOrigin)
- {
- case STREAM_SEEK_SET:
- {
- // Validate the position pointer as unsigned and in 32-bit range
- if (0 != dlibMove.HighPart)
- return STG_E_INVALIDFUNCTION;
- // Compute the new position
- BYTE* pbNewPosition = m_pbBegin + dlibMove.LowPart;
- if (m_pbBegin > pbNewPosition || pbNewPosition > m_pbEnd)
- return STG_E_INVALIDFUNCTION;
- m_pbPosition = pbNewPosition;
- break;
- }
- case STREAM_SEEK_CUR:
- {
- // Validate the position pointer as signed and in 32-bit range
- if (0 != dlibMove.HighPart && -1 != dlibMove.HighPart)
- return STG_E_INVALIDFUNCTION;
- // Compute the new position
- BYTE* pbNewPosition = m_pbPosition + LONG(dlibMove.LowPart);
- if (m_pbBegin > pbNewPosition || pbNewPosition > m_pbEnd)
- return STG_E_INVALIDFUNCTION;
- m_pbPosition = pbNewPosition;
- break;
- }
- case STREAM_SEEK_END:
- {
- // Validate the position pointer as signed and in 32-bit range
- if (0 != dlibMove.HighPart && -1 != dlibMove.HighPart)
- return STG_E_INVALIDFUNCTION;
- // Compute the new position
- BYTE* pbNewPosition = m_pbEnd + LONG(dlibMove.LowPart);
- if (m_pbBegin > pbNewPosition || pbNewPosition > m_pbEnd)
- return STG_E_INVALIDFUNCTION;
- m_pbPosition = pbNewPosition;
- break;
- }
- default:
- return STG_E_INVALIDFUNCTION;
- }
- // Return the new position, if requested
- if (plibNewPosition)
- plibNewPosition->LowPart = m_pbPosition - m_pbBegin;
- // Indicate success
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- // Validate the specified size as in 32-bit range
- if (0 != libNewSize.HighPart)
- return STG_E_MEDIUMFULL;
- // This stream can only shrink, never grow
- if (libNewSize.LowPart > (m_pbEnd - m_pbBegin))
- return STG_E_MEDIUMFULL;
- // Set the new size of the stream
- m_pbEnd = m_pbBegin + libNewSize.LowPart;
- m_pbPosition = min(m_pbPosition, m_pbEnd);
- // Indicate success
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP CopyTo(IStream* pstm, ULARGE_INTEGER cb,
- ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- // Initialize the [out] parameters
- if (pcbRead)
- TCZeroMemory(pcbRead);
- if (pcbWritten)
- TCZeroMemory(pcbWritten);
- // Ensure that the specified stream pointer is valid
- IStreamPtr spstm;
- RETURN_FAILED(TCSafeQI(pstm, &spstm));
- // Compute the number of bytes that can be copied
- ULONG nMax = m_pbEnd - m_pbPosition;
- nMax = min(nMax, cb.LowPart);
- // Copy from the current seek pointer, the maximum number of bytes
- ULONG cbWritten;
- RETURN_FAILED(spstm->Write(m_pbPosition, nMax, &cbWritten));
- // Update the current position
- m_pbPosition += cbWritten;
- // Return the number of bytes read, if requested
- if (pcbRead)
- pcbRead->LowPart = cbWritten;
- // Return the number of bytes written, if requested
- if (pcbWritten)
- pcbWritten->LowPart = cbWritten;
- // Indicate success
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Commit(DWORD grfCommitFlags)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- UNUSED(grfCommitFlags);
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Revert(void)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset,
- ULARGE_INTEGER cb, DWORD dwLockType)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- UNUSED(libOffset);
- UNUSED(cb);
- UNUSED(dwLockType);
- return STG_E_INVALIDFUNCTION;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset,
- ULARGE_INTEGER cb, DWORD dwLockType)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- UNUSED(libOffset);
- UNUSED(cb);
- UNUSED(dwLockType);
- return STG_E_INVALIDFUNCTION;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Stat(STATSTG* pstatstg, DWORD grfStatFlag)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- UNUSED(grfStatFlag);
- // Initialize the specified structures
- TCZeroMemory(pstatstg);
- // Uset the current time for all time fields
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- // Populate the fields of the specified structure
- pstatstg->pwcsName = NULL;
- pstatstg->type = STGTY_STREAM;
- pstatstg->cbSize.HighPart = 0;
- pstatstg->cbSize.LowPart = m_pbEnd - m_pbBegin;
- pstatstg->mtime = ft;
- pstatstg->ctime = ft;
- pstatstg->atime = ft;
- pstatstg->grfMode = STGM_READWRITE | STGM_SHARE_DENY_NONE;
- pstatstg->grfLocksSupported = 0;
- pstatstg->clsid = CLSID_NULL;
- // Indicate success
- return S_OK;
- }
- ///////////////////////////////////////////////////////////////////////////
- STDMETHODIMP Clone(IStream** ppstm)
- {
- assert(m_pbBegin && m_pbPosition && m_pbEnd);
- // Initialize the [out] parameter
- CLEAROUT(ppstm, (IStream*)NULL);
- // Do not support this function
- return STG_E_INSUFFICIENTMEMORY;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Data Members
- protected:
- BYTE* m_pbBegin;
- BYTE* m_pbEnd;
- BYTE* m_pbPosition;
- };
- /////////////////////////////////////////////////////////////////////////////
- // CTCSimpleStream
- typedef CComObjectGlobal<CTCSimpleStreamImpl> TCSimpleStream;
- /////////////////////////////////////////////////////////////////////////////
- #endif // !__SimpleStream_h__
|