📄 nexusmm3hook.dpr.svn-base
字号:
{##############################################################################}
{# NexusMM: NexusMM3Hook.dpr 2.00 #}
{# NexusDB Memory Manager: NexusMM3Hook.dpr 3.04 #}
{# Copyright (c) Nexus Database Systems Pty. Ltd. 2003-2005 #}
{# All rights reserved. #}
{##############################################################################}
{# NexusMM: Hook DLL for NexusMM3 #}
{##############################################################################}
{# If this DLL is loaded into a process which uses NexusMM3 before that #}
{# process initializes the MM all allocations/deallocations will be routed #}
{# through the hook functions presented here. #}
{##############################################################################}
{$I nxDefine.inc}
library NexusMM3Hook;
uses
Windows;
const
ReserveBlockBegin = 8;
ReserveBlockEnd = 8;
ReserveBlockTotal = ReserveBlockBegin + ReserveBlockEnd;
MarkerBegin = $AA55AA55;
MarkerEnd = $55AA55AA;
procedure LoadMe; register; begin end;
{===CheckMarkers===============================================================}
procedure CheckMarkers(P: Pointer);
var
Size : Integer;
i : Cardinal;
q : Pointer;
begin
i := Cardinal(p);
Size := PInteger(p)^;
if IsBadReadPtr(Pointer(i), Size) then
RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_NONCONTINUABLE, 0, nil);
Inc(PInteger(p));
if PInteger(p)^ <> Integer(MarkerBegin xor i) then
RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_NONCONTINUABLE, 0, nil);
q := Pointer(i + Cardinal(Size) - ReserveBlockEnd);
if PInteger(q)^ <> Integer(MarkerEnd xor i) then
RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_NONCONTINUABLE, 0, nil);
Inc(PInteger(q));
if PInteger(q)^ <> Integer(i) then
RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_NONCONTINUABLE, 0, nil);
end;
{==============================================================================}
{=== Memory Manager Hooks =====================================================}
{ These functions are called when nxGetMem/nxFreeMem/nxReallocMem are used. }
{ They are also called if nxReplacementMemoryManager is used and GetMem/ }
{ FreeMem/ReallocMem/New/Dispose are called or implicit allocations for }
{ strings and dynamic arrays take place. }
{------------------------------------------------------------------------------}
{ Called before memory for a GetMem call is allocated, change aSize to reserve }
{ additional space }
procedure BeforeGetMem(var aSize: Integer); register;
begin
Inc(aSize, ReserveBlockTotal);
end;
{------------------------------------------------------------------------------}
{ Called after memory for a GetMem call has been allocated, aSize is the size }
{ returned by BeforeGetMem, p is pointing to the allocated memory, if you }
{ modify p, BeforeFreeMem, BeforeReallocMem and BeforeGetAllocSize have to }
{ restore the correct base address }
procedure AfterGetMem(aSize: Integer; var p: Pointer); register;
var
i : Cardinal;
q : Pointer;
begin
i := Cardinal(p);
PInteger(p)^ := aSize;
Inc(PInteger(p));
PInteger(p)^ := Integer(MarkerBegin xor i);
p := Pointer(i + ReserveBlockBegin);
q := Pointer(i + Cardinal(aSize) - ReserveBlockEnd);
PInteger(q)^ := Integer(MarkerEnd xor i);
Inc(PInteger(q));
PInteger(q)^ := Integer(i);
end;
{------------------------------------------------------------------------------}
{ Called before a pointer allocated with GetMem is freed using FreeMem, if }
{ AfterGetMem modified p that modification has to be reversed here }
procedure BeforeFreeMem(var p: Pointer); register;
begin
p := Pointer(Cardinal(p) - ReserveBlockBegin);
CheckMarkers(p);
end;
{------------------------------------------------------------------------------}
procedure BeforeReallocMem(var p: Pointer; var aSize: Integer); register;
{ Called before a pointer allocated with GetMem is reallocated, if }
{ AfterGetMem modified p that modification has to be reversed here, if }
{ BeforeGetMem modifies aSize the same modification has to be done here }
begin
BeforeFreeMem(p);
BeforeGetMem(aSize);
end;
{------------------------------------------------------------------------------}
procedure AfterReallocMem(aSize: Integer; var p: Pointer); register;
{ Called after a pointer has been reallocated. Must leave the pointer in the }
{ same state a freshly allocated (via GetMem) pointer would be }
begin
AfterGetMem(aSize, p);
end;
{------------------------------------------------------------------------------}
procedure BeforeGetAllocSize(var p: Pointer); register;
{ Called before a pointer allocated with GetMem queried for it's size, if }
{ AfterGetMem modified p that modification has to be reversed here }
begin
p := Pointer(Cardinal(p) - ReserveBlockBegin);
CheckMarkers(p);
end;
{------------------------------------------------------------------------------}
procedure AfterGetAllocSize(p: Pointer; var aSize: Integer); register;
{ Called after a pointer allocated by GetMem has been queried for its size, if }
{ BeforeGetMem modified the size, that modification has to be reversed here }
begin
Dec(aSize, ReserveBlockTotal);
end;
{==============================================================================}
{=== Block Pool Hooks =========================================================}
{ These hooks are called for DIRECT (e.g. NOT via the memory pools) }
{ allocations/deallocations on the block pools }
{------------------------------------------------------------------------------}
{ Called after a block has been allocated, the pointer can not be modified }
procedure AfterBlockPoolAlloc(p: Pointer); register;
begin
end;
{------------------------------------------------------------------------------}
{ Called before a block is disposed, the pointer is the same as seen by }
{ AfterBlockPoolAlloc earlier }
procedure BeforeBlockPoolDispose(p: Pointer); register;
begin
end;
{==============================================================================}
{=== Memory Pool Hooks ========================================================}
{ These hooks are called for DIRECT (e.g. NOT via the memory manager) }
{ allocations/deallocations on the memory pools }
{------------------------------------------------------------------------------}
{ Called before the correct pool for the specified size is determined, increase}
{ the size to reserve additional space for use in AfterMemoryPoolAlloc }
procedure BeforeGetPool(var aSize: Integer); register;
begin
Inc(aSize, ReserveBlockTotal);
end;
{------------------------------------------------------------------------------}
{ Called after an item has been allocated from a memory pool, aSize is the }
{ item size of the pool actually used, this is guaranteed to be >= aSize as }
{ returned by BeforeGetPool }
procedure AfterMemoryPoolAlloc(aSize: Integer; var p: Pointer); register;
begin
AfterGetMem(aSize, p);
end;
{------------------------------------------------------------------------------}
{ Called before an item is returned to the memory pool }
procedure BeforeMemoryPoolDispose(var p: Pointer); register;
begin
BeforeFreeMem(p);
end;
{==============================================================================}
exports
LoadMe,
BeforeGetMem,
AfterGetMem,
BeforeFreeMem,
BeforeReallocMem,
AfterReallocMem,
BeforeGetAllocSize,
AfterGetAllocSize,
AfterBlockPoolAlloc,
BeforeBlockPoolDispose,
BeforeGetPool,
AfterMemoryPoolAlloc,
BeforeMemoryPoolDispose;
begin
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -