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.
189 lines
5.0 KiB
189 lines
5.0 KiB
#pragma once
|
|
|
|
#include "lhport.h"
|
|
#include "pshpack8.h"
|
|
|
|
class CPositionIndependentBlob;
|
|
|
|
template <typename T>
|
|
class CFunction
|
|
{
|
|
public:
|
|
union
|
|
{
|
|
T * pfn;
|
|
ULONGLONG ull;
|
|
};
|
|
};
|
|
|
|
typedef void (__stdcall * PFN_GROW_FUNCTION)(CPositionIndependentBlob * This);
|
|
|
|
class CPositionIndependentOperatorNew
|
|
{
|
|
public:
|
|
void * operator new(size_t n, CPositionIndependentBlob * Container);
|
|
};
|
|
|
|
|
|
//
|
|
// aka position independent heap, with support for persistance to disk
|
|
//
|
|
class CPositionIndependentBlob : public CPositionIndependentOperatorNew
|
|
{
|
|
public:
|
|
//protected:
|
|
void OutOfMemory();
|
|
|
|
public:
|
|
|
|
static void ThrowWin32Error(DWORD);
|
|
|
|
BOOL IsPagefileMapping();
|
|
|
|
union
|
|
{
|
|
ULONGLONG ll;
|
|
CPositionIndependentBlob * m_Container;
|
|
};
|
|
|
|
CPositionIndependentBlob();
|
|
~CPositionIndependentBlob();
|
|
|
|
BOOL Write(HANDLE FileHandle, ULONGLONG Offset);
|
|
BOOL Read(HANDLE FileHandle, ULONGLONG Offset);
|
|
|
|
void GetBounds(const BYTE * Bounds[2]);
|
|
void IsInBlob(const BYTE * Pointer, ULONG Size, BOOL * IsInBlob);
|
|
|
|
class CBlock
|
|
{
|
|
public:
|
|
CBlock() : m_Offset(0), m_Size(0) { }
|
|
|
|
ULONG m_Offset;
|
|
ULONG m_Size;
|
|
|
|
bool operator==(const CBlock & x) const
|
|
{
|
|
if (this == &x)
|
|
return true;
|
|
if (m_Offset != x.m_Offset)
|
|
return false;
|
|
if (m_Size != x.m_Size)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
typedef std::pair<ULONG, ULONG> CPair;
|
|
class CLessThanByOffset
|
|
{
|
|
public:
|
|
bool operator()(const CBlock & x, const CBlock & y) const
|
|
{
|
|
return CPair(x.m_Offset, x.m_Size) < CPair(y.m_Offset, y.m_Size);
|
|
}
|
|
};
|
|
|
|
class CLessThanBySize
|
|
{
|
|
public:
|
|
bool operator()(const CBlock & x, const CBlock & y) const
|
|
{
|
|
return CPair(x.m_Size, x.m_Offset) < CPair(y.m_Size, y.m_Offset);
|
|
}
|
|
};
|
|
|
|
static bool Neighbors(const CBlock & x, const CBlock & y)
|
|
{
|
|
if (y.m_Offset + y.m_Size == x.m_Offset)
|
|
return true;
|
|
if (x.m_Offset + x.m_Size == y.m_Offset)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool Neighbors(const CBlock & x) const
|
|
{
|
|
return Neighbors(*this, x);
|
|
}
|
|
};
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
ULONG m_HeaderSize;
|
|
ULONG m_HeaderVersion;
|
|
|
|
ULONG m_BitsInPointer;
|
|
BYTE m_IsBigEndian;
|
|
BYTE m_Spare1[3];
|
|
|
|
union
|
|
{
|
|
ULONGLONG ll;
|
|
HANDLE m_FileHandle;
|
|
};
|
|
union
|
|
{
|
|
ULONGLONG ll;
|
|
HANDLE m_FileMapping;
|
|
};
|
|
ULONGLONG m_FileOffset;
|
|
|
|
union
|
|
{
|
|
ULONGLONG m_Base;
|
|
PBYTE m_BasePointer;
|
|
};
|
|
|
|
ULONG m_AllocatedSize;
|
|
ULONG m_UsedSize;
|
|
ULONG m_FreeSize;
|
|
|
|
ULONG m_OffsetToFreeBlocks;
|
|
ULONG m_NumberOfFreeBlocks;
|
|
CBlock m_MostRecentlyFreedBlock;
|
|
};
|
|
BYTE Page[0x2000];
|
|
};
|
|
|
|
typedef std::set<CBlock, CBlock::CLessThanByOffset> CBlockByOffsetSet;
|
|
typedef std::set<CBlock, CBlock::CLessThanBySize> CBlockBySizeSet;
|
|
|
|
ULONG m_PendingFreeBySize;
|
|
CBlockByOffsetSet m_FreeBlocksSortedByOffset;
|
|
CBlockBySizeSet m_FreeBlocksSortedBySize;
|
|
CBlockByOffsetSet m_InUseBlocksSortedByOffset;
|
|
|
|
PBYTE GetBasePointer();
|
|
void Alloc(ULONG NumberOfBytes, ULONG * Offset);
|
|
void Alloc(CPositionIndependentBlob * Container, ULONG NumberOfBytes, ULONG * Offset);
|
|
void Free(const BYTE * Pointer);
|
|
void Reserve(ULONG Bytes, ULONG Blocks) { /* UNDONE */ }
|
|
void Grow(ULONG);
|
|
|
|
void RecalculateBlocksBySize(); // protected
|
|
|
|
void (CPositionIndependentBlob::*m_pmfCompact)();
|
|
|
|
void * OperatorNew(SIZE_T NumberOfBytes)
|
|
{
|
|
void * Pointer = 0;
|
|
ULONG Offset = 0;
|
|
Alloc(static_cast<ULONG>(NumberOfBytes), &Offset);
|
|
OffsetToPointer(Offset, &Pointer);
|
|
return Pointer;
|
|
}
|
|
|
|
//PBYTE OffsetToPointer(ULONG Offset) { return m_BasePointer + Offset; }
|
|
//template <typename T> void OffsetToPointer(ULONG Offset, T * & Pointer) { Pointer = reinterpret_cast<T*>(m_Base + static_cast<SIZE_T>(Offset)); }
|
|
template <typename T> void OffsetToPointer(ULONG Offset, T * * Pointer) { *Pointer = reinterpret_cast<T*>(m_Base + static_cast<SIZE_T>(Offset)); }
|
|
|
|
template <typename T>
|
|
ULONG PointerToOffset(const T * Pointer)
|
|
{
|
|
return static_cast<ULONG>(reinterpret_cast<PBYTE>(Pointer) - m_BasePointer);
|
|
}
|
|
};
|
|
#include "poppack.h"
|