Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

585 lines
20 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. MPC_streams.h
  5. Abstract:
  6. This file includes and defines things for handling streams.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 07/10/2000
  9. created
  10. ******************************************************************************/
  11. #if !defined(__INCLUDED___MPC___STREAMS_H___)
  12. #define __INCLUDED___MPC___STREAMS_H___
  13. #include <MPC_main.h>
  14. #include <MPC_COM.h>
  15. #include <set>
  16. /////////////////////////////////////////////////////////////////////////
  17. namespace MPC
  18. {
  19. //
  20. // Some forward declarations...
  21. //
  22. class CComHGLOBAL;
  23. ////////////////////
  24. //
  25. // Non-abstract class, meant to provide a do-nothing stub for real stream implementations.
  26. //
  27. class BaseStream : public IStream
  28. {
  29. public:
  30. /////////////////////////////////////////////////////////////////////////////
  31. //
  32. // ISequentialStream Interface
  33. //
  34. STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead );
  35. STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten );
  36. /////////////////////////////////////////////////////////////////////////////
  37. //
  38. // IStream Interface
  39. //
  40. STDMETHOD(Seek )( /*[in]*/ LARGE_INTEGER libMove , /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition );
  41. STDMETHOD(SetSize)( /*[in]*/ ULARGE_INTEGER libNewSize );
  42. STDMETHOD(CopyTo)( /*[in]*/ IStream* pstm, /*[in]*/ ULARGE_INTEGER cb, /*[out]*/ ULARGE_INTEGER *pcbRead, /*[out]*/ ULARGE_INTEGER *pcbWritten );
  43. STDMETHOD(Commit)( /*[in]*/ DWORD grfCommitFlags );
  44. STDMETHOD(Revert)( );
  45. STDMETHOD(LockRegion )( /*[in]*/ ULARGE_INTEGER libOffset, /*[in]*/ ULARGE_INTEGER cb, /*[in]*/ DWORD dwLockType );
  46. STDMETHOD(UnlockRegion)( /*[in]*/ ULARGE_INTEGER libOffset, /*[in]*/ ULARGE_INTEGER cb, /*[in]*/ DWORD dwLockType );
  47. STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag);
  48. STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm );
  49. static HRESULT TransferData( /*[in]*/ IStream* src, /*[in]*/ IStream* dst, /*[in]*/ ULONG ulCount = -1, /*[out]*/ ULONG *ulDone = NULL );
  50. };
  51. //
  52. // Class that wraps files around an IStream interface.
  53. //
  54. class ATL_NO_VTABLE FileStream : // Hungarian: hpcfs
  55. public CComObjectRootEx<MPC::CComSafeMultiThreadModel>,
  56. public BaseStream
  57. {
  58. MPC::wstring m_szFile;
  59. DWORD m_dwDesiredAccess;
  60. DWORD m_dwDisposition;
  61. DWORD m_dwSharing;
  62. HANDLE m_hfFile;
  63. bool m_fDeleteOnRelease;
  64. public:
  65. BEGIN_COM_MAP(FileStream)
  66. COM_INTERFACE_ENTRY(IStream)
  67. COM_INTERFACE_ENTRY(ISequentialStream)
  68. END_COM_MAP()
  69. FileStream();
  70. virtual ~FileStream();
  71. HRESULT Close();
  72. HRESULT Init ( /*[in]*/ LPCWSTR szFile, /*[in]*/ DWORD dwDesiredAccess, /*[in]*/ DWORD dwDisposition, /*[in]*/ DWORD dwSharing, /*[in]*/ HANDLE hfFile = NULL );
  73. HRESULT InitForRead ( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL );
  74. HRESULT InitForReadWrite( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL );
  75. HRESULT InitForWrite ( /*[in]*/ LPCWSTR szFile, /*[in]*/ HANDLE hfFile = NULL );
  76. HRESULT DeleteOnRelease( /*[in]*/ bool fFlag = true );
  77. /////////////////////////////////////////////////////////////////////////////
  78. //
  79. // ISequentialStream Interface
  80. //
  81. STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead );
  82. STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten );
  83. /////////////////////////////////////////////////////////////////////////////
  84. //
  85. // IStream Interface
  86. //
  87. STDMETHOD(Seek)( /*[in]*/ LARGE_INTEGER libMove, /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition );
  88. STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag);
  89. STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm );
  90. };
  91. //
  92. // Class that encrypts/decrypts data on-the-fly.
  93. //
  94. class ATL_NO_VTABLE EncryptedStream : // Hungarian: hpcefs
  95. public CComObjectRootEx<MPC::CComSafeMultiThreadModel>,
  96. public BaseStream
  97. {
  98. CComPtr<IStream> m_pStream;
  99. HCRYPTPROV m_hCryptProv;
  100. HCRYPTKEY m_hKey;
  101. HCRYPTHASH m_hHash;
  102. BYTE m_rgDecrypted[512];
  103. DWORD m_dwDecryptedPos;
  104. DWORD m_dwDecryptedLen;
  105. public:
  106. BEGIN_COM_MAP(EncryptedStream)
  107. COM_INTERFACE_ENTRY(IStream)
  108. COM_INTERFACE_ENTRY(ISequentialStream)
  109. END_COM_MAP()
  110. EncryptedStream();
  111. virtual ~EncryptedStream();
  112. HRESULT Close();
  113. HRESULT Init( /*[in]*/ IStream* pStream, /*[in]*/ LPCWSTR szPassword );
  114. HRESULT Init( /*[in]*/ IStream* pStream, /*[in]*/ HCRYPTKEY hKey );
  115. /////////////////////////////////////////////////////////////////////////////
  116. //
  117. // ISequentialStream Interface
  118. //
  119. STDMETHOD(Read )( /*[out]*/ void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbRead );
  120. STDMETHOD(Write)( /*[in] */ const void* pv, /*[in]*/ ULONG cb, /*[out]*/ ULONG *pcbWritten );
  121. /////////////////////////////////////////////////////////////////////////////
  122. //
  123. // IStream Interface
  124. //
  125. STDMETHOD(Seek)( /*[in]*/ LARGE_INTEGER libMove, /*[in]*/ DWORD dwOrigin, /*[out]*/ ULARGE_INTEGER *plibNewPosition );
  126. STDMETHOD(Stat)( /*[out]*/ STATSTG *pstatstg, /*[in]*/ DWORD grfStatFlag);
  127. STDMETHOD(Clone)( /*[out]*/ IStream* *ppstm );
  128. };
  129. ////////////////////////////////////////////////////////////////////////////////
  130. ////////////////////////////////////////////////////////////////////////////////
  131. ////////////////////////////////////////////////////////////////////////////////
  132. class Serializer // Hungarian: stream
  133. {
  134. DWORD m_dwFlags;
  135. public:
  136. virtual ~Serializer() {};
  137. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL ) = 0;
  138. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen ) = 0;
  139. virtual void put_Flags( /*[in]*/ DWORD dwFlags ) { m_dwFlags = dwFlags; }
  140. virtual DWORD get_Flags( ) { return m_dwFlags; }
  141. ////////////////////////////////////////
  142. //
  143. // We cannot rely on the compiler finding the right method,
  144. // since all these types map to VOID*, so the last one wins...
  145. //
  146. inline HRESULT HWND_read ( /*[out]*/ HWND& val ) { return read ( &val, sizeof(val) ); }
  147. inline HRESULT HWND_write( /*[in] */ const HWND& val ) { return write( &val, sizeof(val) ); }
  148. ////////////////////////////////////////////////////////////////////////////////
  149. //
  150. // Specialization of In/Out operators for various data types.
  151. //
  152. inline HRESULT operator>>( /*[out]*/ bool& val ) { return read ( &val, sizeof(val) ); }
  153. inline HRESULT operator<<( /*[in] */ const bool& val ) { return write( &val, sizeof(val) ); }
  154. inline HRESULT operator>>( /*[out]*/ VARIANT_BOOL& val ) { return read ( &val, sizeof(val) ); }
  155. inline HRESULT operator<<( /*[in] */ const VARIANT_BOOL& val ) { return write( &val, sizeof(val) ); }
  156. inline HRESULT operator>>( /*[out]*/ int& val ) { return read ( &val, sizeof(val) ); }
  157. inline HRESULT operator<<( /*[in] */ const int& val ) { return write( &val, sizeof(val) ); }
  158. inline HRESULT operator>>( /*[out]*/ long& val ) { return read ( &val, sizeof(val) ); }
  159. inline HRESULT operator<<( /*[in] */ const long& val ) { return write( &val, sizeof(val) ); }
  160. inline HRESULT operator>>( /*[out]*/ DWORD& val ) { return read ( &val, sizeof(val) ); }
  161. inline HRESULT operator<<( /*[in] */ const DWORD& val ) { return write( &val, sizeof(val) ); }
  162. inline HRESULT operator>>( /*[out]*/ DATE& val ) { return read ( &val, sizeof(val) ); }
  163. inline HRESULT operator<<( /*[in] */ const DATE& val ) { return write( &val, sizeof(val) ); }
  164. inline HRESULT operator>>( /*[out]*/ SYSTEMTIME& val ) { return read ( &val, sizeof(val) ); }
  165. inline HRESULT operator<<( /*[in] */ const SYSTEMTIME& val ) { return write( &val, sizeof(val) ); }
  166. inline HRESULT operator>>( /*[out]*/ CLSID& val ) { return read ( &val, sizeof(val) ); }
  167. inline HRESULT operator<<( /*[in] */ const CLSID& val ) { return write( &val, sizeof(val) ); }
  168. HRESULT operator>>( /*[out]*/ MPC::string& val );
  169. HRESULT operator<<( /*[in] */ const MPC::string& val );
  170. HRESULT operator>>( /*[out]*/ MPC::wstring& val );
  171. HRESULT operator<<( /*[in] */ const MPC::wstring& val );
  172. HRESULT operator>>( /*[out]*/ CComBSTR& val );
  173. HRESULT operator<<( /*[in] */ const CComBSTR& val );
  174. HRESULT operator>>( /*[out]*/ CComHGLOBAL& val );
  175. HRESULT operator<<( /*[in] */ const CComHGLOBAL& val );
  176. HRESULT operator>>( /*[out]*/ CComPtr<IStream>& val );
  177. HRESULT operator<<( /*[in] */ IStream* val );
  178. };
  179. ////////////////////////////////////////
  180. class Serializer_File : public Serializer
  181. {
  182. HANDLE m_hfFile;
  183. //////////////////////////////////////////////////////////////////
  184. public:
  185. Serializer_File( /*[in]*/ HANDLE hfFile );
  186. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  187. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  188. };
  189. ////////////////////////////////////////
  190. class Serializer_Text : public Serializer
  191. {
  192. MPC::Serializer& m_stream;
  193. public:
  194. Serializer_Text( /*[in]*/ Serializer& stream ) : m_stream( stream ) {}
  195. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  196. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  197. };
  198. ////////////////////////////////////////
  199. class Serializer_Http : public Serializer
  200. {
  201. HINTERNET m_hReq;
  202. public:
  203. Serializer_Http( HINTERNET hReq );
  204. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  205. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  206. };
  207. ////////////////////////////////////////
  208. class Serializer_Fake : public Serializer
  209. {
  210. DWORD m_dwSize;
  211. public:
  212. Serializer_Fake();
  213. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  214. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  215. /////////////////////////////////////////////////////////////////////////////
  216. //
  217. // Additional methods.
  218. //
  219. DWORD GetSize();
  220. };
  221. ////////////////////////////////////////
  222. class Serializer_Memory : public Serializer
  223. {
  224. HANDLE m_hHeap;
  225. BYTE* m_pData;
  226. DWORD m_dwAllocated;
  227. DWORD m_dwSize;
  228. bool m_fFixed;
  229. DWORD m_dwCursor_Write;
  230. DWORD m_dwCursor_Read;
  231. //////////////////////////////////////////////////////////////////
  232. HRESULT Alloc( /*[in]*/ DWORD dwSize );
  233. //////////////////////////////////////////////////////////////////
  234. public:
  235. Serializer_Memory( HANDLE hHeap=NULL );
  236. virtual ~Serializer_Memory();
  237. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  238. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  239. /////////////////////////////////////////////////////////////////////////////
  240. //
  241. // Additional methods.
  242. //
  243. void Reset ();
  244. void Rewind();
  245. bool IsEOR();
  246. bool IsEOW();
  247. DWORD GetAvailableForRead ();
  248. DWORD GetAvailableForWrite();
  249. HRESULT SetSize( /*[in]*/ DWORD dwSize );
  250. DWORD GetSize( );
  251. BYTE* GetData( );
  252. };
  253. ////////////////////////////////////////
  254. class Serializer_IStream : public Serializer
  255. {
  256. CComPtr<IStream> m_stream;
  257. //////////////////////////////////////////////////////////////////
  258. public:
  259. Serializer_IStream( /*[in]*/ IStream* stream = NULL );
  260. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  261. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  262. /////////////////////////////////////////////////////////////////////////////
  263. //
  264. // Additional methods.
  265. //
  266. HRESULT Reset ( );
  267. HRESULT GetStream( /*[out]*/ IStream* *pVal );
  268. };
  269. ////////////////////////////////////////
  270. class Serializer_Buffering : public Serializer
  271. {
  272. static const int MODE_READ = 1;
  273. static const int MODE_WRITE = -1;
  274. MPC::Serializer& m_stream;
  275. BYTE m_rgTransitBuffer[1024];
  276. DWORD m_dwAvailable;
  277. DWORD m_dwPos;
  278. int m_iMode;
  279. //////////////////////////////////////////////////////////////////
  280. public:
  281. Serializer_Buffering( /*[in]*/ Serializer& stream );
  282. virtual ~Serializer_Buffering();
  283. virtual HRESULT read ( /*[in]*/ void* pBuf, /*[in]*/ DWORD dwLen, /*[out]*/ DWORD* dwRead = NULL );
  284. virtual HRESULT write( /*[in]*/ const void* pBuf, /*[in]*/ DWORD dwLen );
  285. /////////////////////////////////////////////////////////////////////////////
  286. //
  287. // Additional methods.
  288. //
  289. HRESULT Reset();
  290. HRESULT Flush();
  291. };
  292. ////////////////////////////////////////////////////////////////////////////////
  293. //
  294. // Specialization for lists.
  295. //
  296. template <class _Ty, class _A> HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::list<_Ty, _A>& val )
  297. {
  298. __MPC_FUNC_ENTRY( COMMONID, "operator>> std::list" );
  299. HRESULT hr;
  300. DWORD dwCount;
  301. val.clear();
  302. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount);
  303. while(dwCount--)
  304. {
  305. _Ty value;
  306. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> value);
  307. val.push_back( value );
  308. }
  309. hr = S_OK;
  310. __MPC_FUNC_CLEANUP;
  311. __MPC_FUNC_EXIT(hr);
  312. }
  313. template <class _Ty, class _A> HRESULT operator<<( /*[in]*/ Serializer& stream, /*[in]*/ const std::list<_Ty, _A>& val )
  314. {
  315. __MPC_FUNC_ENTRY( COMMONID, "operator<< std::list" );
  316. HRESULT hr;
  317. DWORD dwCount = val.size();
  318. std::list<_Ty, _A>::iterator it = val.begin();
  319. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount);
  320. while(dwCount--)
  321. {
  322. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << (*it++));
  323. }
  324. hr = S_OK;
  325. __MPC_FUNC_CLEANUP;
  326. __MPC_FUNC_EXIT(hr);
  327. }
  328. ////////////////////////////////////////////////////////////////////////////////
  329. //
  330. // Specialization for maps.
  331. //
  332. template <class _K, class _Ty, class _Pr, class _A> HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::map<_K, _Ty, _Pr, _A>& val )
  333. {
  334. __MPC_FUNC_ENTRY( COMMONID, "operator>> std::map" );
  335. HRESULT hr;
  336. DWORD dwCount;
  337. val.clear();
  338. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount);
  339. while(dwCount--)
  340. {
  341. _K key;
  342. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> key);
  343. {
  344. _Ty value;
  345. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> value);
  346. val[key] = value;
  347. }
  348. }
  349. hr = S_OK;
  350. __MPC_FUNC_CLEANUP;
  351. __MPC_FUNC_EXIT(hr);
  352. }
  353. template <class _K, class _Ty, class _Pr, class _A> HRESULT operator<<( /*[in]*/ Serializer& stream, /*[out]*/ const std::map<_K, _Ty, _Pr, _A>& val )
  354. {
  355. __MPC_FUNC_ENTRY( COMMONID, "operator<< std::map" );
  356. HRESULT hr;
  357. DWORD dwCount = val.size();
  358. std::map<_K, _Ty, _Pr, _A>::iterator it = val.begin();
  359. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount);
  360. while(dwCount--)
  361. {
  362. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << it ->first );
  363. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << (it++)->second);
  364. }
  365. hr = S_OK;
  366. __MPC_FUNC_CLEANUP;
  367. __MPC_FUNC_EXIT(hr);
  368. }
  369. ////////////////////////////////////////////////////////////////////////////////
  370. //
  371. // Specialization for sets.
  372. //
  373. template <class _K, class _Pr, class _A> HRESULT operator>>( /*[in]*/ Serializer& stream, /*[out]*/ std::set<_K, _Pr, _A>& val )
  374. {
  375. __MPC_FUNC_ENTRY( COMMONID, "operator>> std::map" );
  376. HRESULT hr;
  377. DWORD dwCount;
  378. val.clear();
  379. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> dwCount);
  380. while(dwCount--)
  381. {
  382. _K key;
  383. __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> key);
  384. val.insert( key );
  385. }
  386. hr = S_OK;
  387. __MPC_FUNC_CLEANUP;
  388. __MPC_FUNC_EXIT(hr);
  389. }
  390. template <class _K, class _Pr, class _A> HRESULT operator<<( /*[in]*/ Serializer& stream, /*[out]*/ const std::set<_K, _Pr, _A>& val )
  391. {
  392. __MPC_FUNC_ENTRY( COMMONID, "operator<< std::map" );
  393. HRESULT hr;
  394. DWORD dwCount = val.size();
  395. std::set<_K, _Pr, _A>::iterator it = val.begin();
  396. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << dwCount);
  397. while(dwCount--)
  398. {
  399. __MPC_EXIT_IF_METHOD_FAILS(hr, stream << *it++);
  400. }
  401. hr = S_OK;
  402. __MPC_FUNC_CLEANUP;
  403. __MPC_FUNC_EXIT(hr);
  404. }
  405. }; // namespace
  406. /////////////////////////////////////////////////////////////////////////
  407. #endif // !defined(__INCLUDED___MPC___STREAMS_H___)