|
|
//
// smblock.h
//
#ifndef SMBLOCK_H
#define SMBLOCK_H
#include "private.h"
#include "cicmutex.h"
#define SZSHAREDFILEMAP __TEXT("SFM.")
#define SZSHAREDMUTEX __TEXT("MUTEX.")
class CSharedHeap9x;
//////////////////////////////////////////////////////////////////////////////
//
// instead of wsprintf
//
//////////////////////////////////////////////////////////////////////////////
#define ONEDWORDCCHFORSETNAME 9
__inline BOOL SetName(TCHAR *pszDst, UINT cchDst, const TCHAR *pszSrc, DWORD dw) { TCHAR *psz; StringCchCopy(pszDst, cchDst, pszSrc); psz = pszDst + lstrlen(pszDst);
if (cchDst < (UINT)(psz - pszDst)/sizeof(TCHAR) + ONEDWORDCCHFORSETNAME) { Assert(0); return FALSE; }
while (dw) { *psz = 'A' + ((char)dw & 0x0F); dw >>= 4; psz++; }
*psz = '\0'; return TRUE; }
__inline BOOL SetName2(TCHAR *pszDst, UINT cchDst, const TCHAR *pszSrc, DWORD dw, DWORD dw2, DWORD dw3 = 0) { TCHAR *psz; StringCchCopy(pszDst, cchDst, pszSrc); psz = pszDst + lstrlen(pszDst);
if (cchDst < (UINT)(psz - pszDst)/sizeof(TCHAR) + ONEDWORDCCHFORSETNAME * 2 + (dw3 ? ONEDWORDCCHFORSETNAME : 0)) { Assert(0); return FALSE; } while (dw) { *psz = 'A' + ((char)dw & 0x0F); dw >>= 4; psz++; }
*psz = '.'; psz++;
while (dw2) { *psz = 'A' + ((char)dw2 & 0x0F); dw2 >>= 4; psz++; }
if (dw3) { *psz = '.'; psz++;
while (dw3) { *psz = 'A' + ((char)dw3 & 0x0F); dw3 >>= 4; psz++; } }
*psz = '\0'; return TRUE; }
//////////////////////////////////////////////////////////////////////////////
//
// func
//
//////////////////////////////////////////////////////////////////////////////
CSharedHeap *EnsureSharedHeap(SYSTHREAD *psfn); void DestroySharedHeap(SYSTHREAD *psfn); CSharedBlock *EnsureSharedBlockForThread(SYSTHREAD *psfn, DWORD dwThreadId); void DestroySharedBlocks(SYSTHREAD *psfn);
//////////////////////////////////////////////////////////////////////////////
//
// CSharedBlock
//
//////////////////////////////////////////////////////////////////////////////
class CSharedBlock { public: CSharedBlock(const char *pszPrefix, DWORD dwThread) { _pszPrefix = pszPrefix; _dwThread = dwThread; }
virtual ~CSharedBlock() { _mutex.Uninit(); }
virtual HRESULT Init(SECURITY_DESCRIPTOR *pSecDes, ULONG ulSize, ULONG ulCommitSize, void *pvBase, BOOL fCreate, BOOL *pfAlreadyExists = NULL) = 0; virtual HRESULT Commit(ULONG ulNewSize) = 0; virtual HRESULT Reset() = 0;
void *GetBase() {return _pvBase;} virtual void *GetPtr(ULONG ulOffset) = 0; virtual void *GetPtrFromBlockId(ULONG ulBlockId) = 0; virtual BOOL IsValidPtr(void *pv) = 0;
ULONG GetOffset(void *pv) { return (ULONG)((BYTE *)pv - (BYTE *)_pvBase); }
ULONG GetCommitSize() { return _ulCommitSize; }
ULONG GetInitCommitSize() { return _ulInitCommitSize; } DWORD GetThreadId() { return _dwThread; }
CCicMutex *GetMutex() { return &_mutex; }
protected: void *_pvBase; ULONG _ulCommitSize; ULONG _ulInitCommitSize; CCicMutex _mutex; DWORD _dwThread; const char *_pszPrefix; };
//////////////////////////////////////////////////////////////////////////////
//
// CSharedBlockNT
//
//////////////////////////////////////////////////////////////////////////////
class CSharedBlockNT : public CSharedBlock { public: CSharedBlockNT(const char *pszPrefix, DWORD dwThread, BOOL fUseUniqueName); ~CSharedBlockNT();
HRESULT Init(SECURITY_DESCRIPTOR *pSecDes, ULONG ulSize, ULONG ulCommitSize, void *pvBase, BOOL fCreate, BOOL *pfAlreadyExists);
HRESULT Commit(ULONG ulNewSize); HRESULT Reset();
void *GetPtrFromBlockId(ULONG ulBlockId);
void *GetPtr(ULONG ulOffset) { return (void *)(((BYTE *)_pvBase) + ulOffset); } BOOL IsValidPtr(void *pv) { if (pv < _pvBase) return FALSE;
if (pv > (BYTE *)_pvBase + _ulCommitSize) return FALSE;
return TRUE; }
private: HANDLE _hfm; BOOL _fUseUniqueName; };
//////////////////////////////////////////////////////////////////////////////
//
// CSharedBlock9x
//
//////////////////////////////////////////////////////////////////////////////
#ifndef _WIN64
class CSharedBlock9x : public CSharedBlock { public: CSharedBlock9x(const char *pszPrefix, DWORD dwThread); ~CSharedBlock9x();
HRESULT Init(SECURITY_DESCRIPTOR *pSecDes, ULONG ulSize, ULONG ulCommitSize, void *pvBase, BOOL fCreate, BOOL *pfAlreadyExists);
HRESULT Commit(ULONG ulNewSize); HRESULT Reset();
void *GetPtrFromBlockId(ULONG ulOffset) { Assert(ulOffset >= 0x80000000); return (void *)ulOffset; }
void *GetPtr(ULONG ulOffset) { return (void *)(((BYTE *)_pvBase) + ulOffset); }
private: friend CSharedHeap9x; BOOL IsValidPtr(void *pv) { if (!_hsheap || !pv) return FALSE; // return HeapValid(_hsheap, 0, pv);
return TRUE; } HANDLE _hsheap; }; #endif // !_WIN64
//////////////////////////////////////////////////////////////////////////////
//
// CShraedHeap
//
//////////////////////////////////////////////////////////////////////////////
#define BLK_FREE 0x01
class CSharedHeap { public: CSharedHeap(DWORD dwThread); ~CSharedHeap();
HRESULT Init(SECURITY_DESCRIPTOR *pSecDes, ULONG ulSize, ULONG ulCommitSize);
void *Alloc(ULONG ulSize); #ifdef LATER
void *Realloc(void *pv, ULONG ulSize); #endif
BOOL Free(void *pv);
ULONG GetBlockId(void *pv) { #ifndef _WIN64
if (!IsOnNT()) return (ULONG)pv; #endif
return _psb->GetOffset(pv); }
CSharedBlock *GetBlock() { return _psb; }
static BOOL IsValidBlock(CSharedBlock *psb, void *pv);
typedef struct tag_HEAPHDR { ULONG ulList; ULONG ulSize; } HEAPHDR;
private: void InitHeap(ULONG ulInitSize);
typedef struct tag_BLOCKHDR { ULONG ulPrev; ULONG ulNext; ULONG ulSize; ULONG ulFlags; ULONG u[4];
ULONG GetSize() { return ulSize; }
void SetSize(ULONG ulNewSize) { Assert(!(ulNewSize & 0x001f)); ulSize = ulNewSize; }
void SetFree(BOOL fFree) { if (fFree) ulFlags |= BLK_FREE; else ulFlags &= ~BLK_FREE; }
BOOL IsFree() { return (ulFlags & BLK_FREE) ? TRUE : FALSE; }
void *GetPtr() { BYTE *pb = (BYTE *)this; return pb + sizeof(tag_BLOCKHDR); }
} BLOCKHDR;
void MergeFreeBlock(BLOCKHDR *pbhdr);
#ifdef DEBUG
void _dbg_HeapCheck(); #else
void _dbg_HeapCheck() {}; #endif
CSharedBlock *_psb; DWORD _dwThread; };
#endif // SMBLOCK_H
|