-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathIP2Loc_DBInterface.pas
222 lines (193 loc) · 6.02 KB
/
IP2Loc_DBInterface.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
////////////////////////////////////////////////
// Unit : IP2Loc_DBInterface.pas //
// Version : 1.1 beta //
// Date : August 2014 //
// Translator: Benbaha Abdelkrim AKA DeadC0der //
// Email : [email protected] //
// License : Included :) //
////////////////////////////////////////////////
unit IP2Loc_DBInterface;
interface
uses Windows,SysUtils;
type
TIP2Location_mem_type =(IP2LOCATION_FILE_IO,IP2LOCATION_CACHE_MEMORY,IP2LOCATION_SHARED_MEMORY);
Tin6_addr_local = record
case integer of
0:(addr8 :array [0..15] of byte);
1:(addr16 :array [0..8] of byte);
end;
function IP2Location_readIPv6Address(handle:integer;position:Cardinal):Tin6_addr_local;
function IP2Location_read32(handle:integer;position:Cardinal):Cardinal;
function IP2Location_read8(handle:integer;position:Cardinal):Byte;
function IP2Location_readStr(handle:integer;position:Cardinal):PChar;
function IP2Location_readFloat(handle:integer;position:Cardinal):Single;
function IP2Location_DB_set_file_io():Cardinal;
function IP2Location_DB_set_memory_cache(filehandle:integer):integer;
function IP2Location_DB_set_shared_memory(filehandle:integer):integer;
function IP2Location_DB_close(filehandle:integer):integer;
procedure IP2Location_DB_del_shm();
implementation
const
IP2LOCATION_SHM ='/IP2location_Shm';
{$IFDEF POSIX}
MAP_ADDR =4194500608;
{$ENDIF}
var
DB_access_type:TIP2Location_mem_type=IP2LOCATION_FILE_IO;
cache_shm_ptr :pointer;
shm_fd :integer;
function IP2Location_DB_Load_to_mem(filehandle:integer;memory:pointer;size:int64):integer;
begin
result:=0;
if filehandle = -1 then begin result:=-1 ; exit; end;
FileSeek(filehandle,0,0);
if FileRead(filehandle,memory^,size)=0 then result:=-1;
end;
//Description: set the DB access method as memory cache and read the file into cache
function IP2Location_DB_set_memory_cache(filehandle:integer):integer;
var _size:integer;
begin
DB_access_type:=IP2LOCATION_FILE_IO;
result:=-1;
_size:=GetFileSize(filehandle,nil);
if (filehandle<>-1) and (_size<>-1) then
begin
cache_shm_ptr:=AllocMem(_size);
if assigned(cache_shm_ptr) and (IP2Location_DB_Load_to_mem(filehandle,cache_shm_ptr,_size)<>-1) then
begin
result:=0;
DB_access_type:=IP2LOCATION_CACHE_MEMORY;
end;
end;
end;
//Description: set the DB access method as shared memory
function IP2Location_DB_set_shared_memory(filehandle:integer):integer;
var
_size:integer;
DB_Loaded:boolean;
begin
DB_access_type:=IP2LOCATION_FILE_IO;
result:=-1;
_size:=GetFileSize(filehandle,nil);
if (filehandle <>-1) and (_size<>-1) then
begin
shm_fd:=CreateFileMapping(
INVALID_HANDLE_VALUE,
nil,
PAGE_READWRITE,
0,
_size+1,
PChar(IP2LOCATION_SHM));
DB_loaded := (GetLastError = ERROR_ALREADY_EXISTS);
if shm_fd <>0 then
cache_shm_ptr := MapViewOfFile(
shm_fd,
FILE_MAP_WRITE,
0,
0,
0)else exit;
if not(DB_Loaded) and (IP2Location_DB_Load_to_mem(filehandle,cache_shm_ptr,_size)<>-1) then
begin
DB_access_type := IP2LOCATION_SHARED_MEMORY;
result:=0;
end
else
begin
UnmapViewOfFile(cache_shm_ptr);
CloseHandle(shm_fd);
end;
end;
end;
//Close the corresponding memory, based on the opened option.
function IP2Location_DB_close(filehandle:integer):integer;
begin
if filehandle<>0 then CloseHandle(filehandle);
if assigned(cache_shm_ptr) then
case DB_access_type of
IP2LOCATION_CACHE_MEMORY : FreeMem(cache_shm_ptr);
IP2LOCATION_SHARED_MEMORY: begin UnmapViewOfFile(cache_shm_ptr);CloseHandle(shm_fd);end;
end;
DB_access_type := IP2LOCATION_FILE_IO;
result:=0;
end;
function IP2Location_read8(handle:integer;position:Cardinal):byte;
begin
result:=0;
if (DB_access_type = IP2LOCATION_FILE_IO) and (handle <> 0) then
begin
FileSeek(handle,position-1,0);
FileRead(handle,result,1);
end
else
result:=PByteArray(cache_shm_ptr)^[position-1];
end;
function IP2Location_read32(handle:integer;position:cardinal):cardinal;
var byte1,byte2,byte3,byte4:Byte;
begin
if (DB_access_type = IP2LOCATION_FILE_IO) and (handle <> 0) then
begin
FileSeek(handle,position-1,0);
FileRead(handle,byte1,1);
FileRead(handle,byte2,1);
FileRead(handle,byte3,1);
FileRead(handle,byte4,1);
end
else
begin
byte1:=PByteArray(cache_shm_ptr)^[position-1];
byte2:=PByteArray(cache_shm_ptr)^[position];
byte3:=PByteArray(cache_shm_ptr)^[position+1];
byte4:=PByteArray(cache_shm_ptr)^[position+2];
end;
result:= (byte4 shl 24) or (byte3 shl 16) or (byte2 shl 8) or byte1;
end;
function IP2Location_readStr(handle:integer;position:cardinal):PChar;
var _size:byte;P_In:PAnsiChar;
begin
result:='';
if (DB_access_type = IP2LOCATION_FILE_IO) and (handle <> 0) then
begin
FileSeek(handle,position,0);
FileRead(handle,_size,1);
Result:=AllocMem(_size+1);
FileRead(handle,result^,_size);
end
else
begin
_size:=PByteArray(cache_shm_ptr)^[position];
Result:=AllocMem(_size+1);
CopyMemory(result,@PByteArray(cache_shm_ptr)^[position+1],_size);
end;
{$IFDEF UNICODE}
P_IN :=PAnsiChar(Result);
Result:=AllocMem(StrLen(P_IN)*2+2);
MultiByteToWideChar(CP_UTF8,0,P_IN,StrLen(P_IN),Result,StrLen(P_IN));
{$ENDIF}
end;
function IP2Location_readFloat(handle:integer;position:cardinal):single;
begin
result:=0.0;
if (DB_access_type = IP2LOCATION_FILE_IO) and (handle <> 0) then
begin
FileSeek(handle,position-1,0);
FileRead(handle,result,4);
end
else
CopyMemory(@result,@PByteArray(cache_shm_ptr)^[position-1],4);
end;
procedure IP2Location_DB_del_shm();
begin
{$IFDEF POSIX}
{$ENDIF}
end;
function IP2Location_readIPv6Address(handle:integer;position:Cardinal):Tin6_addr_local;
var i:integer;
begin
with result do
for i:=0 to 15 do
addr8[i]:=IP2Location_read8(handle, position + (15-i));
end;
function IP2Location_DB_set_file_io():Cardinal;
begin
end;
end.