/****************************************************************************** Copyright (c) 1999-2000 Microsoft Corporation Module Name: MPC_streams.h Abstract: This file includes and defines things for handling streams. Revision History: Davide Massarenti (Dmassare) 07/10/2000 created ******************************************************************************/ #if !defined(__INCLUDED___MPC___STREAMS_H___) #define __INCLUDED___MPC___STREAMS_H___ #include #include #include ///////////////////////////////////////////////////////////////////////// namespace MPC { // // Some forward declarations... // class CComHGLOBAL; //////////////////// // // Non-abstract class, meant to provide a do-nothing stub for real stream implementations. // class BaseStream : public IStream { public: ///////////////////////////////////////////////////////////////////////////// // // ISequentialStream Interface // STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead ); STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten ); ///////////////////////////////////////////////////////////////////////////// // // IStream Interface // STDMETHOD(Seek )( /*[in]*/ LARGE_INTEGER libMove , /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition ); STDMETHOD(SetSize)( /*[in]*/ ULARGE_INTEGER libNewSize ); STDMETHOD(CopyTo)( /*[in]*/ IStream* pstm, /*[in]*/ ULARGE_INTEGER cb, /*[out]*/ ULARGE_INTEGER *pcbRead, /*[out]*/ ULARGE_INTEGER *pcbWritten ); STDMETHOD(Commit)( /*[in]*/ DWORD grfCommitFlags ); STDMETHOD(Revert)( ); STDMETHOD(LockRegion )( /*[in]*/ ULARGE_INTEGER libOffset, /*[in]*/ ULARGE_INTEGER cb, /*[in]*/ DWORD dwLockType ); STDMETHOD(UnlockRegion)( /*[in]*/ ULARGE_INTEGER libOffset, /*[in]*/ ULARGE_INTEGER cb, /*[in]*/ DWORD dwLockType ); STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag); STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm ); static HRESULT TransferData( /*[in]*/ IStream* src, /*[in]*/ IStream* dst, /*[in]*/ ULONG ulCount = -1, /*[out]*/ ULONG *ulDone = NULL ); }; // // Class that wraps files around an IStream interface. // class ATL_NO_VTABLE FileStream : // Hungarian: hpcfs public CComObjectRootEx, public BaseStream { MPC::wstring m_szFile; DWORD m_dwDesiredAccess; DWORD m_dwDisposition; DWORD m_dwSharing; HANDLE m_hfFile; bool m_fDeleteOnRelease; public: BEGIN_COM_MAP(FileStream) COM_INTERFACE_ENTRY(IStream) COM_INTERFACE_ENTRY(ISequentialStream) END_COM_MAP() FileStream(); virtual ~FileStream(); HRESULT Close(); HRESULT Init ( /*[in]*/ LPCWSTR szFile, /*[in]*/ DWORD dwDesiredAccess, /*[in]*/ DWORD dwDisposition, /*[in]*/ DWORD dwSharing, /*[in]*/ HANDLE hfFile = NULL ); HRESULT InitForRead ( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL ); HRESULT InitForReadWrite( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL ); HRESULT InitForWrite ( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL ); HRESULT DeleteOnRelease( /*[in]*/ bool fFlag = true ); ///////////////////////////////////////////////////////////////////////////// // // ISequentialStream Interface // STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead ); STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten ); ///////////////////////////////////////////////////////////////////////////// // // IStream Interface // STDMETHOD(Seek)( /*[in]*/ LARGE_INTEGER libMove, /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition ); STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag); STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm ); }; // // Class that encrypts/decrypts data on-the-fly. // class ATL_NO_VTABLE EncryptedStream : // Hungarian: hpcefs public CComObjectRootEx, public BaseStream { CComPtr m_pStream; HCRYPTPROV m_hCryptProv; HCRYPTKEY m_hKey; HCRYPTHASH m_hHash; BYTE m_rgDecrypted[512]; DWORD m_dwDecryptedPos; DWORD m_dwDecryptedLen; public: BEGIN_COM_MAP(EncryptedStream) COM_INTERFACE_ENTRY(IStream) COM_INTERFACE_ENTRY(ISequentialStream) END_COM_MAP() EncryptedStream(); virtual ~EncryptedStream(); HRESULT Close(); HRESULT Init( /*[in]*/ IStream* pStream, /*[in]*/ LPCWSTR szPassword ); HRESULT Init( /*[in]*/ IStream* pStream, /*[in]*/ HCRYPTKEY hKey ); ///////////////////////////////////////////////////////////////////////////// // // ISequentialStream Interface // STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead ); STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten ); ///////////////////////////////////////////////////////////////////////////// // // IStream Interface // STDMETHOD(Seek)( /*[in]*/ LARGE_INTEGER libMove, /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition ); STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag); STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm ); }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class Serializer // Hungarian: stream { DWORD m_dwFlags; public: virtual ~Serializer() {}; virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ) = 0; virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ) = 0; virtual void put_Flags( /*[in]*/ DWORD dwFlags ) { m_dwFlags = dwFlags; } virtual DWORD get_Flags( ) { return m_dwFlags; } //////////////////////////////////////// // // We cannot rely on the compiler finding the right method, // since all these types map to VOID*, so the last one wins... // inline HRESULT HWND_read ( /*[out]*/ HWND& val ) { return read ( &val, sizeof(val) ); } inline HRESULT HWND_write( /*[in] */ const HWND& val ) { return write( &val, sizeof(val) ); } //////////////////////////////////////////////////////////////////////////////// // // Specialization of In/Out operators for various data types. // inline HRESULT operator>>( /*[out]*/ bool& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const bool& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ VARIANT_BOOL& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const VARIANT_BOOL& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ int& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const int& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ long& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const long& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ DWORD& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const DWORD& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ DATE& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const DATE& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ SYSTEMTIME& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const SYSTEMTIME& val ) { return write( &val, sizeof(val) ); } inline HRESULT operator>>( /*[out]*/ CLSID& val ) { return read ( &val, sizeof(val) ); } inline HRESULT operator<<( /*[in] */ const CLSID& val ) { return write( &val, sizeof(val) ); } HRESULT operator>>( /*[out]*/ MPC::string& val ); HRESULT operator<<( /*[in] */ const MPC::string& val ); HRESULT operator>>( /*[out]*/ MPC::wstring& val ); HRESULT operator<<( /*[in] */ const MPC::wstring& val ); HRESULT operator>>( /*[out]*/ CComBSTR& val ); HRESULT operator<<( /*[in] */ const CComBSTR& val ); HRESULT operator>>( /*[out]*/ CComHGLOBAL& val ); HRESULT operator<<( /*[in] */ const CComHGLOBAL& val ); HRESULT operator>>( /*[out]*/ CComPtr& val ); HRESULT operator<<( /*[in] */ IStream* val ); }; //////////////////////////////////////// class Serializer_File : public Serializer { HANDLE m_hfFile; ////////////////////////////////////////////////////////////////// public: Serializer_File( /*[in]*/ HANDLE hfFile ); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); }; //////////////////////////////////////// class Serializer_Text : public Serializer { MPC::Serializer& m_stream; public: Serializer_Text( /*[in]*/ Serializer& stream ) : m_stream( stream ) {} virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); }; //////////////////////////////////////// class Serializer_Http : public Serializer { HINTERNET m_hReq; public: Serializer_Http( HINTERNET hReq ); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); }; //////////////////////////////////////// class Serializer_Fake : public Serializer { DWORD m_dwSize; public: Serializer_Fake(); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); ///////////////////////////////////////////////////////////////////////////// // // Additional methods. // DWORD GetSize(); }; //////////////////////////////////////// class Serializer_Memory : public Serializer { HANDLE m_hHeap; BYTE* m_pData; DWORD m_dwAllocated; DWORD m_dwSize; bool m_fFixed; DWORD m_dwCursor_Write; DWORD m_dwCursor_Read; ////////////////////////////////////////////////////////////////// HRESULT Alloc( /*[in]*/ DWORD dwSize ); ////////////////////////////////////////////////////////////////// public: Serializer_Memory( HANDLE hHeap=NULL ); virtual ~Serializer_Memory(); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); ///////////////////////////////////////////////////////////////////////////// // // Additional methods. // void Reset (); void Rewind(); bool IsEOR(); bool IsEOW(); DWORD GetAvailableForRead (); DWORD GetAvailableForWrite(); HRESULT SetSize( /*[in]*/ DWORD dwSize ); DWORD GetSize( ); BYTE* GetData( ); }; //////////////////////////////////////// class Serializer_IStream : public Serializer { CComPtr m_stream; ////////////////////////////////////////////////////////////////// public: Serializer_IStream( /*[in]*/ IStream* stream = NULL ); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); ///////////////////////////////////////////////////////////////////////////// // // Additional methods. // HRESULT Reset ( ); HRESULT GetStream( /*[out]*/ IStream* *pVal ); }; //////////////////////////////////////// class Serializer_Buffering : public Serializer { static const int MODE_READ = 1; static const int MODE_WRITE = -1; MPC::Serializer& m_stream; BYTE m_rgTransitBuffer[1024]; DWORD m_dwAvailable; DWORD m_dwPos; int m_iMode; ////////////////////////////////////////////////////////////////// public: Serializer_Buffering( /*[in]*/ Serializer& stream ); virtual ~Serializer_Buffering(); virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ); virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ); ///////////////////////////////////////////////////////////////////////////// // // Additional methods. // HRESULT Reset(); HRESULT Flush(); }; //////////////////////////////////////////////////////////////////////////////// // // Specialization for lists. // template HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::list<_Ty, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator>> std::list" ); HRESULT hr; DWORD dwCount; val.clear(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount); while(dwCount--) { _Ty value; __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> value); val.push_back( value ); } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } template HRESULT operator<<( /*[in]*/ Serializer& stream, /*[in]*/ const std::list<_Ty, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator<< std::list" ); HRESULT hr; DWORD dwCount = val.size(); std::list<_Ty, _A>::iterator it = val.begin(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount); while(dwCount--) { __MPC_EXIT_IF_METHOD_FAILS(hr, stream << (*it++)); } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } //////////////////////////////////////////////////////////////////////////////// // // Specialization for maps. // template HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::map<_K, _Ty, _Pr, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator>> std::map" ); HRESULT hr; DWORD dwCount; val.clear(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount); while(dwCount--) { _K key; __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> key); { _Ty value; __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> value); val[key] = value; } } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } template HRESULT operator<<( /*[in]*/ Serializer& stream, /*[out]*/ const std::map<_K, _Ty, _Pr, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator<< std::map" ); HRESULT hr; DWORD dwCount = val.size(); std::map<_K, _Ty, _Pr, _A>::iterator it = val.begin(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount); while(dwCount--) { __MPC_EXIT_IF_METHOD_FAILS(hr, stream << it ->first ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << (it++)->second); } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } //////////////////////////////////////////////////////////////////////////////// // // Specialization for sets. // template HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::set<_K, _Pr, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator>> std::map" ); HRESULT hr; DWORD dwCount; val.clear(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount); while(dwCount--) { _K key; __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> key); val.insert( key ); } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } template HRESULT operator<<( /*[in]*/ Serializer& stream, /*[out]*/ const std::set<_K, _Pr, _A>& val ) { __MPC_FUNC_ENTRY( COMMONID, "operator<< std::map" ); HRESULT hr; DWORD dwCount = val.size(); std::set<_K, _Pr, _A>::iterator it = val.begin(); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount); while(dwCount--) { __MPC_EXIT_IF_METHOD_FAILS(hr, stream << *it++); } hr = S_OK; __MPC_FUNC_CLEANUP; __MPC_FUNC_EXIT(hr); } }; // namespace ///////////////////////////////////////////////////////////////////////// #endif // !defined(__INCLUDED___MPC___STREAMS_H___)