Source code of Windows XP (NT5)
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.

226 lines
7.3 KiB

  1. #if !defined( _MEMSTM_H_ )
  2. #define _MEMSTM_H_
  3. class CMarshalMemStm;
  4. class CMarshalMemBytes;
  5. // function prototypes
  6. STDAPI_(LPSTREAM) CreateMemStm(DWORD cb, LPHANDLE phMem);
  7. STDAPI_(LPLOCKBYTES) CreateMemLockBytes(DWORD cb, LPHANDLE phMem);
  8. // CMemStm is a stream implementation on top of global shared memory MEMSTM
  9. //
  10. // CMemStm
  11. // +---------+
  12. // + pvtf + Shared memory
  13. // +---------+ +--------------+
  14. // + m_pMem +-->|cb |
  15. // +---------+ |cRef |
  16. // |hGlobal |--->+--------------+
  17. // +--------------+ | Actual Data |
  18. // CMemStm MEMSTM +--------------+
  19. //
  20. struct MEMSTM
  21. {
  22. DWORD cb; // Size of buf[]
  23. DWORD cRef; // See below
  24. BYTE buf[4]; // The data
  25. };
  26. // cRef counts all CMemStm pointers to this MEMSTM plus the number of times
  27. // a hMem handle to MEMSTM had been returned
  28. class CMemStm : public IStream
  29. {
  30. public:
  31. CMemStm() { m_hMem = NULL; m_pData = NULL; m_pos = 0; m_refs = 0; }
  32. ~CMemStm() {}
  33. STDMETHOD(QueryInterface) (REFIID iidInterface, void * * ppvObj);
  34. STDMETHOD_(ULONG,AddRef) (void);
  35. STDMETHOD_(ULONG,Release) (void);
  36. STDMETHOD(Read) (VOID HUGEP* pv, ULONG cb, ULONG *pcbRead);
  37. STDMETHOD(Write) (VOID const HUGEP* pv, ULONG cb, ULONG *pcbWritten);
  38. STDMETHOD(Seek) (LARGE_INTEGER dlibMove,
  39. DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);
  40. STDMETHOD(SetSize) (ULARGE_INTEGER cb);
  41. STDMETHOD(CopyTo) (IStream *pstm, ULARGE_INTEGER cb,
  42. ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
  43. STDMETHOD(Commit) (DWORD grfCommitFlags);
  44. STDMETHOD(Revert) (void);
  45. STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  46. DWORD dwLockType);
  47. STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  48. DWORD dwLockType);
  49. STDMETHOD(Stat) (STATSTG *pstatstg, DWORD statflag);
  50. STDMETHOD(Clone)(IStream **ppstm);
  51. static CMemStm *Create(HANDLE hMem);
  52. private:
  53. ULONG m_refs; // Number of references to this CmemStm
  54. ULONG m_pos; // Seek pointer for Read/Write
  55. HANDLE m_hMem; // Memory Handle passed on creation
  56. MEMSTM * m_pData; // Pointer to that memroy
  57. friend class CMarshalMemStm;
  58. };
  59. // CMemBytes is an ILockBytes implementation on top of global shared
  60. // memory MEMBYTES
  61. //
  62. // CMemBytes
  63. // +---------+
  64. // + pvtf + Shared memory
  65. // +---------+ +--------------+
  66. // + m_pData +-->| cb |
  67. // +---------+ | cRef |
  68. // | hGlobal |--->+-------------+
  69. // +--------------+ | Actual data |
  70. // CMemBytes MEMBYTES +-------------+
  71. //
  72. struct MEMBYTES // Bookeeping info in shared memory
  73. {
  74. DWORD cRef; // See below
  75. DWORD cb; // Size of hGlobal
  76. HANDLE hGlobal; // The data
  77. BOOL fDeleteOnRelease;
  78. };
  79. #define LOCKBYTE_SIG (0x0046574A)
  80. // cRef counts all CMemBytes pointers to this MEMBYTES.
  81. // It and fDeleteOnRelease control the GlobalFreeing of the hGlobal.
  82. class CMemBytes : public ILockBytes
  83. {
  84. public:
  85. CMemBytes() {m_hMem = NULL; m_pData = NULL; m_refs = 0;}
  86. ~CMemBytes() {}
  87. STDMETHOD(QueryInterface) (REFIID iidInterface, void **ppvObj);
  88. STDMETHOD_(ULONG,AddRef) (void);
  89. STDMETHOD_(ULONG,Release) (void);
  90. STDMETHOD(ReadAt) (ULARGE_INTEGER ulOffset, VOID HUGEP *pv, ULONG cb,
  91. ULONG *pcbRead);
  92. STDMETHOD(WriteAt) (ULARGE_INTEGER ulOffset, VOID const HUGEP *pv,
  93. ULONG cb, ULONG *pcbWritten);
  94. STDMETHOD(Flush) (void);
  95. STDMETHOD(SetSize) (ULARGE_INTEGER cb);
  96. STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  97. DWORD dwLockType);
  98. STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  99. DWORD dwLockType);
  100. STDMETHOD(Stat) (STATSTG *pstatstg, DWORD statflag);
  101. static CMemBytes *Create(HANDLE hMem);
  102. private:
  103. DWORD m_dwSig; // Signature indicating this is our
  104. // implementation of ILockBytes: LOCKBYTE_SIG
  105. ULONG m_refs; // Normal reference count
  106. HANDLE m_hMem; // Handle for bookeeping info (MEMBYTES)
  107. MEMBYTES * m_pData; // Pointer to that memroy
  108. // friend GetHGlobalFromILockBytes(LPLOCKBYTES, HGLOBAL *);
  109. friend class CMarshalMemBytes;
  110. };
  111. // CMarshalMemStm can Marshal, Unmarshal CMemStm. It is impletented as
  112. // a seperate object accessible from CMemStm, CMemBytes: QueryIntreface of
  113. // IMarshal on CMemStm's IStream will return an IMarshal pointer to
  114. // CMarshalMemStm, but QueryInterface of IStream on that IMarshal will
  115. // fail.
  116. //
  117. // Also QueryInterface of IUnknown on IMarshal will not return the same value
  118. // As QueryInterface of IUnkown on the original IStream.
  119. //
  120. class CMarshalMemStm : public IMarshal
  121. {
  122. public:
  123. CMarshalMemStm() {m_pMemStm = NULL; m_refs = 0; }
  124. ~CMarshalMemStm() {}
  125. STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj);
  126. STDMETHOD_(ULONG,AddRef) (void);
  127. STDMETHOD_(ULONG,Release) (void);
  128. STDMETHOD(GetUnmarshalClass)(THIS_ REFIID riid, LPVOID pv,
  129. DWORD dwDestContext, LPVOID pvDestContext,
  130. DWORD mshlflags, LPCLSID pCid);
  131. STDMETHOD(GetMarshalSizeMax)(THIS_ REFIID riid, LPVOID pv,
  132. DWORD dwDestContext, LPVOID pvDestContext,
  133. DWORD mshlflags, LPDWORD pSize);
  134. STDMETHOD(MarshalInterface)(THIS_ IStream * pStm, REFIID riid,
  135. LPVOID pv, DWORD dwDestContext, LPVOID pvDestContext,
  136. DWORD mshlflags);
  137. STDMETHOD(UnmarshalInterface)(THIS_ IStream * pStm, REFIID riid,
  138. LPVOID * ppv);
  139. STDMETHOD(ReleaseMarshalData)(THIS_ IStream * pStm);
  140. STDMETHOD(DisconnectObject)(THIS_ DWORD dwReserved);
  141. static CMarshalMemStm * Create(CMemStm *pMemStm);
  142. private:
  143. ULONG m_refs; // Number of references to this CmemStm
  144. CMemStm * m_pMemStm; // Pointer to object [Un]Marshalled
  145. CLSID m_clsid; // Class of object pointed by pUnk
  146. };
  147. // CMarshalMemBytes can Marshal, Unmarshal CMemBytes. It is impletented as
  148. // a seperate object accessible from CMemBytes, CMemBytes: QueryIntreface of
  149. // IMarshal on CMemBytes's ILocBytes will return an IMarshal pointer to
  150. // CMarshalMemBytes, but QueryInterface of ILockBytes on that IMarshal will
  151. // fail.
  152. //
  153. // Also QueryInterface of IUnknown on IMarshal will not return the same value
  154. // as QueryInterface of IUnknown on the original ILockBytes.
  155. //
  156. class CMarshalMemBytes : public IMarshal
  157. {
  158. public:
  159. CMarshalMemBytes() {m_pMemBytes = NULL; m_refs = 0;}
  160. ~CMarshalMemBytes() {}
  161. STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj);
  162. STDMETHOD_(ULONG,AddRef) (void);
  163. STDMETHOD_(ULONG,Release) (void);
  164. STDMETHOD(GetUnmarshalClass)(THIS_ REFIID riid, LPVOID pv,
  165. DWORD dwDestContext, LPVOID pvDestContext,
  166. DWORD mshlflags, LPCLSID pCid);
  167. STDMETHOD(GetMarshalSizeMax)(THIS_ REFIID riid, LPVOID pv,
  168. DWORD dwDestContext, LPVOID pvDestContext,
  169. DWORD mshlflags, LPDWORD pSize);
  170. STDMETHOD(MarshalInterface)(THIS_ IStream * pStm, REFIID riid,
  171. LPVOID pv, DWORD dwDestContext, LPVOID pvDestContext,
  172. DWORD mshlflags);
  173. STDMETHOD(UnmarshalInterface)(THIS_ IStream * pStm, REFIID riid,
  174. LPVOID * ppv);
  175. STDMETHOD(ReleaseMarshalData)(THIS_ IStream * pStm);
  176. STDMETHOD(DisconnectObject)(THIS_ DWORD dwReserved);
  177. static CMarshalMemBytes* Create(CMemBytes *pMemBytes);
  178. private:
  179. ULONG m_refs; // Number of references to this CMemBytes
  180. CMemBytes *m_pMemBytes; // Pointer to object [Un]Marshalled
  181. CLSID m_clsid; // Class of object pointed by pUnk
  182. };
  183. #endif // _MEMSTM_H_