windows-nt/Source/XPSP1/NT/com/oleutest/balls/common/memstm.h
2020-09-26 16:20:57 +08:00

227 lines
7.3 KiB
C++

#if !defined( _MEMSTM_H_ )
#define _MEMSTM_H_
class CMarshalMemStm;
class CMarshalMemBytes;
// function prototypes
STDAPI_(LPSTREAM) CreateMemStm(DWORD cb, LPHANDLE phMem);
STDAPI_(LPLOCKBYTES) CreateMemLockBytes(DWORD cb, LPHANDLE phMem);
// CMemStm is a stream implementation on top of global shared memory MEMSTM
//
// CMemStm
// +---------+
// + pvtf + Shared memory
// +---------+ +--------------+
// + m_pMem +-->|cb |
// +---------+ |cRef |
// |hGlobal |--->+--------------+
// +--------------+ | Actual Data |
// CMemStm MEMSTM +--------------+
//
struct MEMSTM
{
DWORD cb; // Size of buf[]
DWORD cRef; // See below
BYTE buf[4]; // The data
};
// cRef counts all CMemStm pointers to this MEMSTM plus the number of times
// a hMem handle to MEMSTM had been returned
class CMemStm : public IStream
{
public:
CMemStm() { m_hMem = NULL; m_pData = NULL; m_pos = 0; m_refs = 0; }
~CMemStm() {}
STDMETHOD(QueryInterface) (REFIID iidInterface, void * * ppvObj);
STDMETHOD_(ULONG,AddRef) (void);
STDMETHOD_(ULONG,Release) (void);
STDMETHOD(Read) (VOID HUGEP* pv, ULONG cb, ULONG *pcbRead);
STDMETHOD(Write) (VOID const HUGEP* pv, ULONG cb, ULONG *pcbWritten);
STDMETHOD(Seek) (LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);
STDMETHOD(SetSize) (ULARGE_INTEGER cb);
STDMETHOD(CopyTo) (IStream *pstm, ULARGE_INTEGER cb,
ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
STDMETHOD(Commit) (DWORD grfCommitFlags);
STDMETHOD(Revert) (void);
STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType);
STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType);
STDMETHOD(Stat) (STATSTG *pstatstg, DWORD statflag);
STDMETHOD(Clone)(IStream **ppstm);
static CMemStm *Create(HANDLE hMem);
private:
ULONG m_refs; // Number of references to this CmemStm
ULONG m_pos; // Seek pointer for Read/Write
HANDLE m_hMem; // Memory Handle passed on creation
MEMSTM * m_pData; // Pointer to that memroy
friend class CMarshalMemStm;
};
// CMemBytes is an ILockBytes implementation on top of global shared
// memory MEMBYTES
//
// CMemBytes
// +---------+
// + pvtf + Shared memory
// +---------+ +--------------+
// + m_pData +-->| cb |
// +---------+ | cRef |
// | hGlobal |--->+-------------+
// +--------------+ | Actual data |
// CMemBytes MEMBYTES +-------------+
//
struct MEMBYTES // Bookeeping info in shared memory
{
DWORD cRef; // See below
DWORD cb; // Size of hGlobal
HANDLE hGlobal; // The data
BOOL fDeleteOnRelease;
};
#define LOCKBYTE_SIG (0x0046574A)
// cRef counts all CMemBytes pointers to this MEMBYTES.
// It and fDeleteOnRelease control the GlobalFreeing of the hGlobal.
class CMemBytes : public ILockBytes
{
public:
CMemBytes() {m_hMem = NULL; m_pData = NULL; m_refs = 0;}
~CMemBytes() {}
STDMETHOD(QueryInterface) (REFIID iidInterface, void **ppvObj);
STDMETHOD_(ULONG,AddRef) (void);
STDMETHOD_(ULONG,Release) (void);
STDMETHOD(ReadAt) (ULARGE_INTEGER ulOffset, VOID HUGEP *pv, ULONG cb,
ULONG *pcbRead);
STDMETHOD(WriteAt) (ULARGE_INTEGER ulOffset, VOID const HUGEP *pv,
ULONG cb, ULONG *pcbWritten);
STDMETHOD(Flush) (void);
STDMETHOD(SetSize) (ULARGE_INTEGER cb);
STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType);
STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType);
STDMETHOD(Stat) (STATSTG *pstatstg, DWORD statflag);
static CMemBytes *Create(HANDLE hMem);
private:
DWORD m_dwSig; // Signature indicating this is our
// implementation of ILockBytes: LOCKBYTE_SIG
ULONG m_refs; // Normal reference count
HANDLE m_hMem; // Handle for bookeeping info (MEMBYTES)
MEMBYTES * m_pData; // Pointer to that memroy
// friend GetHGlobalFromILockBytes(LPLOCKBYTES, HGLOBAL *);
friend class CMarshalMemBytes;
};
// CMarshalMemStm can Marshal, Unmarshal CMemStm. It is impletented as
// a seperate object accessible from CMemStm, CMemBytes: QueryIntreface of
// IMarshal on CMemStm's IStream will return an IMarshal pointer to
// CMarshalMemStm, but QueryInterface of IStream on that IMarshal will
// fail.
//
// Also QueryInterface of IUnknown on IMarshal will not return the same value
// As QueryInterface of IUnkown on the original IStream.
//
class CMarshalMemStm : public IMarshal
{
public:
CMarshalMemStm() {m_pMemStm = NULL; m_refs = 0; }
~CMarshalMemStm() {}
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj);
STDMETHOD_(ULONG,AddRef) (void);
STDMETHOD_(ULONG,Release) (void);
STDMETHOD(GetUnmarshalClass)(THIS_ REFIID riid, LPVOID pv,
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPCLSID pCid);
STDMETHOD(GetMarshalSizeMax)(THIS_ REFIID riid, LPVOID pv,
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPDWORD pSize);
STDMETHOD(MarshalInterface)(THIS_ IStream * pStm, REFIID riid,
LPVOID pv, DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags);
STDMETHOD(UnmarshalInterface)(THIS_ IStream * pStm, REFIID riid,
LPVOID * ppv);
STDMETHOD(ReleaseMarshalData)(THIS_ IStream * pStm);
STDMETHOD(DisconnectObject)(THIS_ DWORD dwReserved);
static CMarshalMemStm * Create(CMemStm *pMemStm);
private:
ULONG m_refs; // Number of references to this CmemStm
CMemStm * m_pMemStm; // Pointer to object [Un]Marshalled
CLSID m_clsid; // Class of object pointed by pUnk
};
// CMarshalMemBytes can Marshal, Unmarshal CMemBytes. It is impletented as
// a seperate object accessible from CMemBytes, CMemBytes: QueryIntreface of
// IMarshal on CMemBytes's ILocBytes will return an IMarshal pointer to
// CMarshalMemBytes, but QueryInterface of ILockBytes on that IMarshal will
// fail.
//
// Also QueryInterface of IUnknown on IMarshal will not return the same value
// as QueryInterface of IUnknown on the original ILockBytes.
//
class CMarshalMemBytes : public IMarshal
{
public:
CMarshalMemBytes() {m_pMemBytes = NULL; m_refs = 0;}
~CMarshalMemBytes() {}
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppvObj);
STDMETHOD_(ULONG,AddRef) (void);
STDMETHOD_(ULONG,Release) (void);
STDMETHOD(GetUnmarshalClass)(THIS_ REFIID riid, LPVOID pv,
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPCLSID pCid);
STDMETHOD(GetMarshalSizeMax)(THIS_ REFIID riid, LPVOID pv,
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPDWORD pSize);
STDMETHOD(MarshalInterface)(THIS_ IStream * pStm, REFIID riid,
LPVOID pv, DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags);
STDMETHOD(UnmarshalInterface)(THIS_ IStream * pStm, REFIID riid,
LPVOID * ppv);
STDMETHOD(ReleaseMarshalData)(THIS_ IStream * pStm);
STDMETHOD(DisconnectObject)(THIS_ DWORD dwReserved);
static CMarshalMemBytes* Create(CMemBytes *pMemBytes);
private:
ULONG m_refs; // Number of references to this CMemBytes
CMemBytes *m_pMemBytes; // Pointer to object [Un]Marshalled
CLSID m_clsid; // Class of object pointed by pUnk
};
#endif // _MEMSTM_H_