|
|
/*
* glheap.h * * Implementation of global and local heaps * * Copyright (C) 1994 Microsoft Corporation */
#ifndef __GLHEAP_H_
#define __GLHEAP_H_
#ifdef __cplusplus
extern "C" { #endif
/* Windows 95 Implementation -------------------------------------------------- */
#ifdef CHICAGO
#define GH_POINTERS_VALID
typedef DWORD GHNAME, * PGHNAME, ** PPGHNAME; typedef DWORD GHID, * PGHID, ** PPGHID; typedef struct GHDR GHDR, * PGHDR, ** PPGHDR; typedef struct GH GH, * PGH, ** PPGH; typedef PGH _HGH; typedef HANDLE _HLH;
struct GHDR { PGHDR pghdrNext; // Pointer to next heap
HANDLE hHeap; // Handle to the heap
GHNAME ghname; // Name of the heap
GHID ghidRoot; // Client root heap block
ULONG cRef; // Number of active clients
};
struct GH { HANDLE hHeap; // Handle to the heap
HANDLE hMutex; // Handle to mutex for this heap
PGHDR pghdr; // Pointer to the heap header block
#ifdef DEBUG
UINT cMutex; // Mutex entry count
#endif
};
__inline void HeapFreeZ(HANDLE hHeap, LPVOID pv) { if (pv) HeapFree(hHeap, 0, pv); }
_HGH _GH_Open(BOOL fCreate, GHNAME ghname, DWORD dwMaxHeap); void _GH_Close(_HGH hgh); #define _GH_GetRoot(hgh) ((hgh)->pghdr->ghidRoot)
#define _GH_SetRoot(hgh, ghid) ((hgh)->pghdr->ghidRoot = (ghid))
#define _GH_GetName(hgh) ((hgh)->pghdr->ghname)
#define _GH_GetPv(hgh, ghid) ((LPVOID)(ghid))
#define _GH_GetId(hgh, pv) ((GHID)(pv))
#define _GH_GetSize(hgh, ghid) HeapSize((hgh)->hHeap, 0, (LPVOID)(ghid))
#define _GH_Alloc(hgh, cb) ((GHID)HeapAlloc((hgh)->hHeap, 0, cb))
#define _GH_Realloc(hgh, ghid, cb) ((GHID)HeapReAlloc((hgh)->hHeap, 0, (LPVOID)(ghid), cb))
#define _GH_Free(hgh, ghid) HeapFreeZ((hgh)->hHeap, (LPVOID)(ghid))
#ifdef DEBUG
BOOL _GH_WaitForMutex(_HGH hgh, ULONG ulTimeout); void _GH_ReleaseMutex(_HGH hgh); #else
#define _GH_WaitForMutex(hgh, ulT) GH_WaitForSingleObject(hgh->hMutex, ulT)
#ifdef __cplusplus
#define _GH_ReleaseMutex(hgh) ::ReleaseMutex((hgh)->hMutex)
#else
#define _GH_ReleaseMutex(hgh) ReleaseMutex((hgh)->hMutex)
#endif
#endif
#define _LH_Open(dwMaxHeap) HeapCreate(0, 0, dwMaxHeap)
#define _LH_Close(hlh) HeapDestroy(hlh)
#define _LH_Alloc(hlh, cb) HeapAlloc(hlh, 0, cb)
#define _LH_Realloc(hlh, pv, cb) HeapReAlloc(hlh, 0, pv, cb)
#define _LH_GetSize(hlh, pv) HeapSize(hlh, 0, pv)
#define _LH_Free(hlh, pv) HeapFreeZ(hlh, pv)
#endif
/* Win16 Implementation ---------------------------------------------------- */
#ifdef WIN16
#define GH_POINTERS_VALID
typedef __segment HPH, * PHPH, ** PPHPH; typedef DWORD HPID, * PHPID, ** PPHPID; typedef DWORD GHNAME, * PGHNAME, ** PPGHNAME; typedef HPID GHID, * PGHID, ** PPGHID; typedef HPH _HGH; typedef HPH _HLH;
typedef struct HP { HPH hphRoot; // Pointer to root heap
HPH hphPrev; // Pointer to the previous heap (fShared)
HPH hphNext; // Pointer to next heap (fShared)
HPH hphChild; // Pointer to extended heaps
BOOL fShared; // TRUE if heap is shared across processes
GHNAME ghname; // Name of the shared heap (fShared)
GHID ghidRoot; // Client root heap block
DWORD dwCurHeap; // Current size of the heap
DWORD dwMaxHeap; // Maximum size of the heap
UINT cRef; // Number of active clients
UINT cbHeap; // Size of this heap
UINT cbFree; // Maximum contiguous free bytes in heap
} HP, * PHP;
#define HphToPhp(hph) ((PHP)((ULONG)(hph) << 16))
#define HP_CREATE 0x0001
#define HP_SHARED 0x0002
HPH HP_Open(UINT uiFlags, GHNAME ghname, DWORD dwMaxHeap); void HP_Close(HPH hph); HPID HP_Alloc(HPH hph, UINT cb); HPID HP_Realloc(HPH hph, HPID hpid, UINT cb); void HP_Free(HPH hph, HPID hpid); #define HP_GetSize(hgh, hpid) (*((UINT *)(hpid) - 2))
#define _GH_Open(fCreate, ghname, dwMaxHeap) \
HP_Open(HP_SHARED | !!(fCreate), ghname, dwMaxHeap) #define _GH_Close(hgh) HP_Close(hgh)
#define _GH_GetRoot(hgh) (HphToPhp(hgh)->ghidRoot)
#define _GH_SetRoot(hgh, ghid) (HphToPhp(hgh)->ghidRoot = (ghid))
#define _GH_GetName(hgh) (HphToPhp(hgh)->ghname)
#define _GH_GetPv(hgh, ghid) ((LPVOID)(ghid))
#define _GH_GetId(hgh, pv) ((GHID)(pv))
#define _GH_GetSize(hgh, ghid) HP_GetSize(hgh, ghid)
#define _GH_Alloc(hgh, cb) ((GHID)HP_Alloc(hgh, cb))
#define _GH_Realloc(hgh, ghid, cb) ((GHID)HP_Realloc(hgh, ghid, cb))
#define _GH_Free(hgh, ghid) HP_Free(hgh, ghid)
#define _GH_WaitForMutex(hgh, ul) (TRUE)
#define _GH_ReleaseMutex(hgh)
#define HeapFreeZ(hHeap, pv) \
if (pv) \ HeapFree(hHeap, 0, pv);
#define _LH_Open(dwMaxHeap) HeapCreate(0, 0, dwMaxHeap)
#define _LH_Close(_hlh) HeapDestroy(_hlh)
#define _LH_Alloc(_hlh, cb) HeapAlloc(_hlh, 0, cb)
#define _LH_Realloc(_hlh, pv, cb) HeapReAlloc(_hlh, 0, pv, cb)
#define _LH_GetSize(_hlh, pv) HeapSize(_hlh, 0, pv)
#define _LH_Free(_hlh, pv) HeapFreeZ(_hlh, pv)
#endif
/* NT Implementation ------------------------------------------------------- */
#if defined(WIN32) && !defined(CHICAGO) && !defined(MAC)
typedef DWORD GHNAME, * PGHNAME, ** PPGHNAME; typedef DWORD GHID, * PGHID, ** PPGHID; typedef struct GROOT GROOT, * PGROOT, ** PPGROOT; typedef struct GH GH, * PGH, ** PPGH; typedef PGH _HGH; typedef HANDLE _HLH;
struct GROOT { DWORD dwBLK; // Block header
GHNAME ghname; // Name of the heap
GHID ghidRoot; // Client root heap block
DWORD dwCurHeap; // Current size of the heap
DWORD dwMaxHeap; // Maximum size of the heap
WORD rgcbFree[1]; // Maximum contiguous free bytes per page
};
struct GH { PGROOT pgroot; // Pointer to the first byte of the heap
HANDLE hMutex; // Handle to public mutex for this heap
HANDLE hMutexHeap; // Handle to private mutex for this heap
HANDLE hMapping; // Handle to file mapping object
};
typedef struct GH_SECURITY_ATTRIBUTES { SECURITY_ATTRIBUTES sa; BYTE rgbSd[SECURITY_DESCRIPTOR_MIN_LENGTH]; } GH_SECURITY_ATTRIBUTES, * PGH_SECURITY_ATTRIBUTES;
BOOL GH_InitializeSecurityAttributes(PGH_SECURITY_ATTRIBUTES pghsa);
__inline void HeapFreeZ(HANDLE hHeap, LPVOID pv) { if (pv) HeapFree(hHeap, 0, pv); }
BOOL _GH_WaitForMutex(_HGH hgh, ULONG ulTimeout); _HGH _GH_Open(BOOL fCreate, GHNAME ghname, DWORD dwMaxHeap); void _GH_Close(_HGH hgh); GHID _GH_Alloc(_HGH hgh, UINT cb); GHID _GH_Realloc(_HGH hgh, GHID ghid, UINT cb); void _GH_Free(_HGH hgh, GHID ghid);
#define _GH_GetPv(hgh, ghid) ((LPVOID)((BYTE *)(hgh)->pgroot + (ghid)))
#define _GH_GetId(hgh, pv) ((BYTE *)(pv) - (BYTE *)(hgh)->pgroot)
#define _GH_GetSize(hgh, ghid) ((UINT)*((WORD *)_GH_GetPv(hgh, ghid) - 2))
#define _GH_GetRoot(hgh) ((hgh)->pgroot->ghidRoot)
#define _GH_SetRoot(hgh, ghid) ((hgh)->pgroot->ghidRoot = (ghid))
#define _GH_GetName(hgh) ((hgh)->pgroot->ghname)
#define _GH_WaitForMutex(hgh, ul) GH_WaitForSingleObject((hgh)->hMutex, ul)
#ifdef __cplusplus
#define _GH_ReleaseMutex(hgh) ::ReleaseMutex((hgh)->hMutex)
#else
#define _GH_ReleaseMutex(hgh) ReleaseMutex((hgh)->hMutex)
#endif /* __cplusplus */
#define _LH_Open(dwMaxHeap) HeapCreate(0, 0, dwMaxHeap)
#define _LH_Close(_hlh) HeapDestroy(_hlh)
#define _LH_Alloc(_hlh, cb) HeapAlloc(_hlh, 0, cb)
#define _LH_Realloc(_hlh, pv, cb) HeapReAlloc(_hlh, 0, pv, cb)
#define _LH_GetSize(_hlh, pv) HeapSize(_hlh, 0, pv)
#define _LH_Free(_hlh, pv) HeapFreeZ(_hlh, pv)
#endif /* WIN32 */
/* Mac Implementation ------------------------------------------------------ */
#ifdef MAC
#define GH_POINTERS_VALID
typedef DWORD GHNAME, * PGHNAME, ** PPGHNAME; typedef DWORD GHID, * PGHID, ** PPGHID; typedef struct GROOT GROOT, * PGROOT, ** PPGROOT; typedef struct GH GH, * PGH, ** PPGH; typedef PGH _HGH; typedef HANDLE _HLH;
struct GROOT { GHID ghidRoot; // Root heap block
GHNAME ghname; // Name of the heap
DWORD dwCurHeap; // Current size of the heap
DWORD dwMaxHeap; // Maximum size of the heap
PGROOT next; // Pointer to next shared heap
};
struct GH { LPMALLOC lpMalloc; // OLE shared heap allocator (IMalloc interface)
PGROOT pgroot; // Pointer to the first byte of the heap
};
#define _GH_GetRoot(hgh) ((hgh)->pgroot->ghidRoot)
#define _GH_SetRoot(hgh, ghid) ((hgh)->pgroot->ghidRoot = (ghid))
#define _GH_GetName(hgh) ((hgh)->pgroot->ghname)
#define _GH_WaitForMutex(hgh, ul) (TRUE)
#define _GH_ReleaseMutex(hgh)
#define _GH_GetPv(hgh, ghid) ((LPVOID)(ghid))
#define _GH_GetId(hgh, pv) ((GHID)(pv))
#define _GH_Close(hgh) ((void)0)
_HGH _GH_Open(BOOL fCreate, GHNAME ghname, DWORD dwMaxHeap);
__inline GHID _GH_Alloc(_HGH hgh, UINT cb) { #ifdef __cplusplus
return((GHID)hgh->lpMalloc->Alloc(cb)); #else
return((GHID)hgh->lpMalloc->lpVtbl->Alloc(hgh->lpMalloc, cb)); #endif
}
__inline GHID _GH_Realloc(_HGH hgh, GHID ghid, UINT cb) { #ifdef __cplusplus
return((GHID)hgh->lpMalloc->Realloc((LPVOID)ghid, cb)); #else
return((GHID)hgh->lpMalloc->lpVtbl->Realloc(hgh->lpMalloc, (LPVOID)ghid, cb)); #endif
}
__inline UINT _GH_GetSize(_HGH hgh, GHID ghid) { #ifdef __cplusplus
return((UINT)hgh->lpMalloc->GetSize((PVOID)ghid)); #else
return((UINT)hgh->lpMalloc->lpVtbl->GetSize(hgh->lpMalloc, (PVOID)ghid)); #endif
}
__inline void _GH_Free(_HGH hgh, GHID ghid) { #ifdef __cplusplus
hgh->lpMalloc->Free((LPVOID)ghid); #else
hgh->lpMalloc->lpVtbl->Free(hgh->lpMalloc, (LPVOID)ghid); #endif
}
// -----------
__inline LPVOID _LH_Open(DWORD dwMaxHeap) { LPMALLOC lpMalloc; (void) CoGetMalloc(MEMCTX_TASK, &lpMalloc); return (void *)lpMalloc; }
#define _LH_Close(hlh) ((void)0)
__inline LPVOID _LH_Alloc(LPMALLOC hlh, UINT cb) { #ifdef __cplusplus
return((hlh)->Alloc(cb)); #else
return((hlh)->lpVtbl->Alloc(hlh, cb)); #endif
}
__inline LPVOID _LH_Realloc(LPMALLOC hlh, LPVOID pv, UINT cb) { #ifdef __cplusplus
return(hlh->Realloc(pv, cb)); #else
return(hlh->lpVtbl->Realloc(hlh, pv, cb)); #endif
}
__inline UINT _LH_GetSize(LPMALLOC hlh, LPVOID pv) { #ifdef __cplusplus
return((UINT)hlh->GetSize(pv)); #else
return((UINT)hlh->lpVtbl->GetSize(hlh, pv)); #endif
}
__inline void _LH_Free(LPMALLOC hlh, LPVOID pv) { #ifdef __cplusplus
hlh->Free(pv); #else
hlh->lpVtbl->Free(hlh, pv); #endif
}
#endif /* MAC */
/* DOS Implementation ------------------------------------------------------ */
#ifdef DOS
typedef DWORD GHID, * PGHID, ** PPGHID; typedef LPMALLOC _HLH;
__inline LPVOID _LH_Alloc(_HLH hlh, UINT cb) { #ifdef __cplusplus
return((hlh)->Alloc(cb)); #else
return((hlh)->lpVtbl->Alloc(hlh, cb)); #endif
}
__inline LPVOID _LH_Realloc(_HLH hlh, LPVOID pv, UINT cb) { #ifdef __cplusplus
return(hlh->Realloc(pv, cb)); #else
return(hlh->lpVtbl->Realloc(hlh, pv, cb)); #endif
}
__inline void _LH_Free(_HLH hlh, LPVOID pv) { #ifdef __cplusplus
hlh->Free(pv); #else
hlh->lpVtbl->Free(hlh, pv); #endif
}
__inline UINT _LH_GetSize(_HLH hlh, LPVOID pv) { #ifdef __cplusplus
return((UINT)hlh->GetSize(pv)); #else
return((UINT)hlh->lpVtbl->GetSize(hlh, pv)); #endif
}
#endif
// LH External API ------------------------------------------------------------
#if defined(DEBUG) && (defined(WIN16) || defined(WIN32))
#define IFHEAPNAME(x) x
typedef struct LH * HLH;
HLH WINAPI LH_Open(DWORD dwMaxHeap); void WINAPI LH_Close(HLH hlh); LPVOID WINAPI LH_Alloc(HLH hlh, UINT cb); LPVOID WINAPI LH_Realloc(HLH hlh, LPVOID pv, UINT cb); UINT WINAPI LH_GetSize(HLH hlh, LPVOID pv); void WINAPI LH_Free(HLH hlh, LPVOID pv); BOOL #ifdef MAC
WINAPI #endif
LH_DidAlloc(HLH hlh, LPVOID pv);
void __cdecl LH_SetHeapNameFn(HLH hlh, TCHAR *pszFormat, ...); void __cdecl LH_SetNameFn(HLH hlh, LPVOID pv, TCHAR *pszFormat, ...);
TCHAR * LH_GetName(HLH hlh, LPVOID pv);
#else
#define IFHEAPNAME(x) 0
typedef _HLH HLH;
#define LH_Open(dwMaxHeap) _LH_Open(dwMaxHeap)
#define LH_Close(hlh) _LH_Close(hlh)
#define LH_Alloc(hlh, cb) _LH_Alloc(hlh, cb)
#define LH_Realloc(hlh, pv, cb) _LH_Realloc(hlh, pv, cb)
#define LH_GetSize(hlh, pv) _LH_GetSize(hlh, pv)
#define LH_Free(hlh, pv) _LH_Free(hlh, pv)
#endif
#define LH_SetHeapName(hlh,psz) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz))
#define LH_SetHeapName1(hlh,psz,a1) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz,a1))
#define LH_SetHeapName2(hlh,psz,a1,a2) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz,a1,a2))
#define LH_SetHeapName3(hlh,psz,a1,a2,a3) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz,a1,a2,a3))
#define LH_SetHeapName4(hlh,psz,a1,a2,a3,a4) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz,a1,a2,a3,a4))
#define LH_SetHeapName5(hlh,psz,a1,a2,a3,a4,a5) IFHEAPNAME(LH_SetHeapNameFn(hlh,psz,a1,a2,a3,a4,a5))
#define LH_SetName(hlh,pv,psz) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz))
#define LH_SetName1(hlh,pv,psz,a1) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz,a1))
#define LH_SetName2(hlh,pv,psz,a1,a2) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz,a1,a2))
#define LH_SetName3(hlh,pv,psz,a1,a2,a3) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz,a1,a2,a3))
#define LH_SetName4(hlh,pv,psz,a1,a2,a3,a4) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz,a1,a2,a3,a4))
#define LH_SetName5(hlh,pv,psz,a1,a2,a3,a4,a5) IFHEAPNAME(LH_SetNameFn(hlh,pv,psz,a1,a2,a3,a4,a5))
// GH External API ------------------------------------------------------------
#if !defined(DOS)
typedef _HGH HGH;
#define GH_Open(fCreate, ghname, dwMaxHeap) _GH_Open(fCreate, ghname, \
dwMaxHeap) #define GH_Close(hgh) _GH_Close(hgh)
#define GH_GetRoot(hgh) _GH_GetRoot(hgh)
#define GH_SetRoot(hgh, ghid) _GH_SetRoot(hgh, ghid)
#define GH_GetName(hgh) _GH_GetName(hgh)
#define GH_GetPv(hgh, ghid) _GH_GetPv(hgh, ghid)
#define GH_GetId(hgh, pv) _GH_GetId(hgh, pv)
#define GH_GetSize(hgh, ghid) _GH_GetSize(hgh, ghid)
#define GH_Alloc(hgh, cb) _GH_Alloc(hgh, cb)
#define GH_Realloc(hgh, ghid, cb) _GH_Realloc(hgh, ghid, cb)
#define GH_Free(hgh, ghid) _GH_Free(hgh, ghid)
#define GH_WaitForMutex(hgh, ulT) _GH_WaitForMutex(hgh, ulT)
#define GH_ReleaseMutex(hgh) _GH_ReleaseMutex(hgh)
#define GH_GetObjectName(pszName, ghname, bTag) _GH_GetObjectName(pszName, \
ghname, bTag); #define GH_WaitForSingleObject(hMutex, ulTO) _GH_WaitForSingleObject(hMutex,\
ulTO) #endif
#ifdef WIN32
#define GH_NAME_CCH 17
#define GH_NAME_MUTEX_1 '*' /* reserved for internal use */
#define GH_NAME_MUTEX_2 '+' /* reserved for internal use */
#define GH_NAME_MUTEX_3 '^'
#define GH_NAME_FILE_MAPPING '!'
void _GH_GetObjectName(CHAR *pszName, GHNAME ghname, BYTE bTag);
BOOL _GH_WaitForSingleObject(HANDLE hMutex, ULONG ulTimeout); #endif
// ----------------------------------------------------------------------------
#ifdef __cplusplus
} #endif
#endif // __GLHEAP_H_
|