forked from pult/libssh2_delphi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHVHeaps.pas
148 lines (125 loc) · 3.37 KB
/
HVHeaps.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
{ HVHeaps.pas } // version: 2020.0615.1000
unit HVHeaps;
//
// https://github.com/pult/dll_load_delay
// https://bitbucket.org/VadimLV/dll_load_delay
// http://hallvards.blogspot.com/2008/03/tdm8-delayloading-of-dlls.html
//
// Simple wrapper classes around the Win32 Heap functions.
// Written by Hallvard Vassbotn (hallvard@falcon.no), January 1999
//
interface
{$IFDEF WIN32}
{$DEFINE MSWINDOWS}
{$ENDIF}
{$IFDEF WIN64}
{$DEFINE MSWINDOWS}
{$ENDIF}
{$IFDEF MSWINDOWS}
{$IFDEF FPC}
{.$WARNINGS OFF}
{.$HINTS OFF}
{$MODE OBJFPC}
//{$MODE DELPHI}
{$H+}
{-DEFINE UNICODE} { optional }
{$B-,R-}
{$Q-}
{$J+}
{$ASSERTIONS OFF}
{$ALIGN 8} // For packed record
{$MINENUMSIZE 1}
{$ELSE !FPC}
{$IFDEF UNICODE}
{$ALIGN 8} // For packed record
{$MINENUMSIZE 1}
//{$IF CompilerVersion >= 25.00}{XE4Up}
// {$ZEROBASEDSTRINGS OFF}
//{$IFEND}
{$ENDIF}
{.$WARN UNSAFE_CODE OFF}
{.$WARN UNSAFE_TYPE OFF}
{.$WARN UNSAFE_CAST OFF}
{$ENDIF !FPC}
uses
Windows
{$IFNDEF FPC}
,Types
{$ENDIF !FPC}
;
type
// The TPrivateHeap class gives basic memory allocation capability
// The benefit of using this class instead of the native GetMem
// and FreeMem routines, is that the memory pages used will
// be seperate from other allocations. This gives reduced
// fragmentation.
TPrivateHeap = class//(TObject)
private
FHandle: THandle;
FAllocationFlags: DWORD;
function GetHandle: THandle;
public
destructor Destroy; override;
function GetMem(var P{: Pointer}; Size: DWORD): Boolean; virtual;
function FreeMem(P: Pointer): Boolean;
function SizeOfMem(P: Pointer): DWORD;
property Handle: THandle read GetHandle;
property AllocationFlags: DWORD read FAllocationFlags write FAllocationFlags;
end;
// The Code Heap adds the feature of allocating readable/writable
// and executable memory blocks. This allows us to have safe
// run-time generated code while not wasting as much memory
// as calls to VirtualAlloc would have caused, while avoiding
// the pitfalls of changing the protection flags of blocks
// allocated with GetMem.
TCodeHeap = class(TPrivateHeap)
public
function GetMem(var P{: Pointer}; Size: DWORD): Boolean; override;
end;
{$ENDIF MSWINDOWS}
implementation
{$IFDEF MSWINDOWS}
{ TPrivateHeap }
destructor TPrivateHeap.Destroy;
begin
if FHandle <> 0 then
begin
Windows.HeapDestroy(FHandle);
FHandle := 0;
end;
inherited;
end;
function TPrivateHeap.FreeMem(P: Pointer): Boolean;
begin
Result := Windows.HeapFree(Handle, 0, P)
end;
function TPrivateHeap.GetHandle: THandle;
begin
if FHandle = 0 then
FHandle := Windows.HeapCreate(0, 0, 0);
Result := FHandle;
end;
function TPrivateHeap.GetMem(var P{: Pointer}; Size: DWORD): Boolean;
begin
Pointer(P) := Windows.HeapAlloc(Handle, FAllocationFlags, Size);
Result := Pointer(P) <> nil;
end;
function TPrivateHeap.SizeOfMem(P: Pointer): DWORD;
begin
Result := Windows.HeapSize(Handle, 0, P);
// HeapSize does not set GetLastError, but returns $FFFFFFFF if it fails
if Result = $FFFFFFFF then
Result := 0;
end;
{ TCodeHeap }
function TCodeHeap.GetMem(var P{: Pointer}; Size: DWORD): Boolean;
var
Dummy: DWORD;
begin
Result := inherited GetMem(P, Size);
if Result then
Result := Windows.VirtualProtect(Pointer(P), Size, PAGE_EXECUTE_READWRITE, @Dummy);
end;
initialization
{$ENDIF MSWINDOWS}
end.