1 | //**************************************************************
|
---|
2 | // *
|
---|
3 | // TIECache * // *
|
---|
4 | // For Delphi 5, 6, 7, 2005, 2006 *
|
---|
5 | // Freeware Component *
|
---|
6 | // by *
|
---|
7 | // Per Lindsø Larsen *
|
---|
8 | // per.lindsoe@larsen.dk *
|
---|
9 | // *
|
---|
10 | // Contributions: *
|
---|
11 | // Christian Lovis for lib dynamic linking *
|
---|
12 | // {christian.lovis@dim.hcuge.ch] *
|
---|
13 | // Eran Bodankin (bsalsa) bsalsa@gmail.com *
|
---|
14 | // - D2005 update *
|
---|
15 | // *
|
---|
16 | // Updated versions: *
|
---|
17 | // http://www.bsalsa.com *
|
---|
18 | //**************************************************************
|
---|
19 |
|
---|
20 | {*******************************************************************************}
|
---|
21 | {LICENSE:
|
---|
22 | THIS SOFTWARE IS PROVIDED TO YOU "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
---|
23 | EITHER EXPRESSED OR IMPLIED INCLUDING BUT NOT LIMITED TO THE APPLIED
|
---|
24 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
---|
25 | YOU ASSUME THE ENTIRE RISK AS TO THE ACCURACY AND THE USE OF THE SOFTWARE
|
---|
26 | AND ALL OTHER RISK ARISING OUT OF THE USE OR PERFORMANCE OF THIS SOFTWARE
|
---|
27 | AND DOCUMENTATION. BSALSA PRODUCTIONS DOES NOT WARRANT THAT THE SOFTWARE IS ERROR-FREE
|
---|
28 | OR WILL OPERATE WITHOUT INTERRUPTION. THE SOFTWARE IS NOT DESIGNED, INTENDED
|
---|
29 | OR LICENSED FOR USE IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE CONTROLS,
|
---|
30 | INCLUDING WITHOUT LIMITATION, THE DESIGN, CONSTRUCTION, MAINTENANCE OR
|
---|
31 | OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS,
|
---|
32 | AIR TRAFFIC CONTROL, AND LIFE SUPPORT OR WEAPONS SYSTEMS. BSALSA PRODUCTIONS SPECIFICALLY
|
---|
33 | DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR SUCH PURPOSE.
|
---|
34 |
|
---|
35 | You may use, change or modify the component under 4 conditions:
|
---|
36 | 1. In your website, add a link to "http://www.bsalsa.com"
|
---|
37 | 2. In your application, add credits to "Embedded Web Browser"
|
---|
38 | 3. Mail me (bsalsa@gmail.com) any code change in the unit
|
---|
39 | for the benefit of the other users.
|
---|
40 | 4. Please consider donation in our web site!
|
---|
41 | {*******************************************************************************}
|
---|
42 |
|
---|
43 | unit IECache;
|
---|
44 |
|
---|
45 | interface
|
---|
46 |
|
---|
47 | {$I EWB.inc}
|
---|
48 |
|
---|
49 | uses
|
---|
50 | WinInet, Windows, Messages, SysUtils, Classes, IeConst;
|
---|
51 |
|
---|
52 | type
|
---|
53 | PInternetCacheTimeStamps = ^TInternetCacheTimeStamps;
|
---|
54 | TInternetCacheTimeStamps = record
|
---|
55 | ftExpires: TFileTime;
|
---|
56 | ftLastModified: TFileTime;
|
---|
57 | end;
|
---|
58 | PInternetCacheGroupInfo = ^TInternetCacheGroupInfo;
|
---|
59 | TInternetCacheGroupInfo = record
|
---|
60 | dwGroupSize: DWORD;
|
---|
61 | dwGroupFlags: DWORD;
|
---|
62 | dwGroupType: DWORD;
|
---|
63 | dwDiskUsage: DWORD;
|
---|
64 | dwDiskQuota: DWORD;
|
---|
65 | dwOwnerStorage: array[0..GROUP_OWNER_STORAGE_SIZE - 1] of DWORD;
|
---|
66 | szGroupName: array[0..GROUPNAME_MAX_LENGTH - 1] of AnsiChar;
|
---|
67 | end;
|
---|
68 | TEntryInfo = record
|
---|
69 | SourceUrlName: string;
|
---|
70 | LocalFileName: string;
|
---|
71 | EntryType: DWORD;
|
---|
72 | UseCount: DWORD;
|
---|
73 | HitRate: DWORD;
|
---|
74 | FSize: DWORD;
|
---|
75 | LastModifiedTime: TDateTime;
|
---|
76 | ExpireTime: TDateTime;
|
---|
77 | LastAccessTime: TDateTime;
|
---|
78 | LastSyncTime: TDateTime;
|
---|
79 | HeaderInfo: string;
|
---|
80 | FileExtension: string;
|
---|
81 | ExemptDelta: DWORD;
|
---|
82 | end;
|
---|
83 | TGroupInfo = record
|
---|
84 | DiskUsage: DWORD;
|
---|
85 | DiskQuota: DWORD;
|
---|
86 | OwnerStorage: array[0..GROUP_OWNER_STORAGE_SIZE - 1] of DWORD;
|
---|
87 | GroupName: string;
|
---|
88 | end;
|
---|
89 | TContent = record
|
---|
90 | Buffer: Pointer;
|
---|
91 | BufferLength: Integer;
|
---|
92 | end;
|
---|
93 | TFilterOption = (NORMAL_ENTRY,
|
---|
94 | STABLE_ENTRY,
|
---|
95 | STICKY_ENTRY,
|
---|
96 | COOKIE_ENTRY,
|
---|
97 | URLHISTORY_ENTRY,
|
---|
98 | TRACK_OFFLINE_ENTRY,
|
---|
99 | TRACK_ONLINE_ENTRY,
|
---|
100 | SPARSE_ENTRY,
|
---|
101 | OCX_ENTRY);
|
---|
102 | TFilterOptions = set of TFilterOption;
|
---|
103 | TOnEntryEvent = procedure(Sender: TObject; var Cancel: Boolean) of object;
|
---|
104 | TOnGroupEvent = procedure(Sender: TObject; GroupID: GROUPID; var Cancel: Boolean) of object;
|
---|
105 | TSearchPattern = (spAll, spCookies, spHistory, spUrl);
|
---|
106 |
|
---|
107 | TIECache = class(TComponent)
|
---|
108 | private
|
---|
109 | FSearchPattern: TSearchPattern;
|
---|
110 | FOnEntry: TOnEntryEvent;
|
---|
111 | FOnGroup: TOnGroupEvent;
|
---|
112 | GrpHandle: THandle;
|
---|
113 | H: THandle;
|
---|
114 | FCancel: Boolean;
|
---|
115 | FFilterOptions: TFilterOptions;
|
---|
116 | FFilterOptionValue: Cardinal;
|
---|
117 | procedure SetFilterOptions(const Value: TFilterOptions);
|
---|
118 | procedure UpdateFilterOptionValue;
|
---|
119 | procedure GetEntryValues(Info: PInternetCacheEntryInfo);
|
---|
120 | procedure ClearEntryValues;
|
---|
121 | protected { Protected declarations }
|
---|
122 | public
|
---|
123 | GroupInfo: TGroupInfo;
|
---|
124 | EntryInfo: TEntryInfo;
|
---|
125 | Content: TContent;
|
---|
126 | constructor Create(AOwner: TComponent); override;
|
---|
127 | function AddUrlToGroup(GroupID: INT64; URL: string): DWORD;
|
---|
128 | function CloseFindEntry: BOOL;
|
---|
129 | function CopyFileToCache(URL, FileName: string; CacheType: DWORD; Expire: TDateTime): DWORD;
|
---|
130 | // function CopyFileToCache(UrlName, FileName: Pchar): string;
|
---|
131 | function CreateEntry(URL, FileExtension: string; ExpectedFileSize: DWORD; var FName: string): DWORD;
|
---|
132 | function CreateGroup: INT64;
|
---|
133 | function DeleteEntry(URL: string): DWORD;
|
---|
134 | function DeleteGroup(GroupID: INT64): DWORD;
|
---|
135 | function FindFirstEntry(GroupID: INT64): DWORD;
|
---|
136 | function FindFirstGroup(var GroupID: Int64): DWORD;
|
---|
137 | function FindNextEntry: DWORD;
|
---|
138 | function FindNextGroup(var GroupID: Int64): BOOL;
|
---|
139 | function GetEntryContent(URL: string): DWORD;
|
---|
140 | function GetEntryInfo(URL: string): DWORD;
|
---|
141 | function GetGroupInfo(GroupID: INT64): DWORD;
|
---|
142 | function getLibraryFound: Boolean;
|
---|
143 | function RemoveUrlFromGroup(GroupID: INT64; URL: string): DWORD;
|
---|
144 | function RetrieveGroups: DWORD;
|
---|
145 | function SetEntryInfo(URL: string): DWORD;
|
---|
146 | function SetGroupInfo(GroupID: INT64): DWORD;
|
---|
147 | procedure ClearAllEntries;
|
---|
148 | procedure RetrieveEntries(GroupID: INT64);
|
---|
149 | { Public declarations }
|
---|
150 | published
|
---|
151 | property FilterOptions: TFilterOptions read FFilterOptions write SetFilterOptions;
|
---|
152 | property LibraryFound: Boolean read getLibraryFound;
|
---|
153 | property OnEntry: TOnEntryEvent read FOnEntry write FOnEntry;
|
---|
154 | property OnGroup: TOnGroupEvent read FOnGroup write FOnGroup;
|
---|
155 | property SearchPattern: TSearchpattern read FSearchpattern write FSearchPattern;
|
---|
156 | { Published declarations }
|
---|
157 | end;
|
---|
158 |
|
---|
159 | implementation
|
---|
160 |
|
---|
161 | type
|
---|
162 |
|
---|
163 | TFindFirstUrlCacheGroup =
|
---|
164 | function(dwFlags, dwFilter: DWORD;
|
---|
165 | lpSearchCondition: Pointer; dwSearchCondition: DWORD;
|
---|
166 | var Group: Int64; lpReserved: Pointer): THandle; stdcall;
|
---|
167 |
|
---|
168 | TFindNextUrlCacheGroup =
|
---|
169 | function(hFind: THandle; var GroupID: Int64; lpReserved: Pointer): BOOL; stdcall;
|
---|
170 |
|
---|
171 | TSetUrlCacheGroupAttribute =
|
---|
172 | function(gid: Int64; dwFlags, dwAttributes: DWORD; var lpGroupInfo: TInternetCacheGroupInfo;
|
---|
173 | lpReserved: Pointer): BOOL; stdcall;
|
---|
174 |
|
---|
175 | TGetUrlCacheGroupAttribute =
|
---|
176 | function(gid: Int64; dwFlags, dwAttributes: DWORD;
|
---|
177 | var GroupInfo: TInternetCacheGroupInfo; var dwGroupInfo: DWORD; lpReserved: Pointer): BOOL; stdcall;
|
---|
178 |
|
---|
179 | var
|
---|
180 | FindFirstUrlCacheGroup: tFindFirstUrlCacheGroup;
|
---|
181 | FindNextUrlCacheGroup: tFindNextUrlCacheGroup;
|
---|
182 | GetUrlCacheGroupAttribute: tGetUrlCacheGroupAttribute;
|
---|
183 | SetUrlCacheGroupAttribute: tSetUrlCacheGroupAttribute;
|
---|
184 | winInetLibFound: Boolean;
|
---|
185 |
|
---|
186 | const
|
---|
187 | winetdll = 'wininet.dll';
|
---|
188 |
|
---|
189 | //====Accessories===============================================================
|
---|
190 |
|
---|
191 | function InitializeWinInet: Boolean;
|
---|
192 | var
|
---|
193 | fPointer: tFarProc;
|
---|
194 | hInst: tHandle;
|
---|
195 | begin
|
---|
196 | if winInetLibFound then
|
---|
197 | Result := true
|
---|
198 | else
|
---|
199 | begin
|
---|
200 | Result := False;
|
---|
201 | hInst := loadLibrary(winetdll);
|
---|
202 | if hInst > 0 then
|
---|
203 | try
|
---|
204 | fPointer := getProcAddress(hInst, 'FindFirstUrlCacheGroup');
|
---|
205 | if fPointer <> nil then
|
---|
206 | begin
|
---|
207 | FindFirstUrlCacheGroup := tFindFirstUrlCacheGroup(fPointer);
|
---|
208 | fPointer := getProcAddress(hInst, 'FindNextUrlCacheGroup');
|
---|
209 | if fPointer <> nil then
|
---|
210 | begin
|
---|
211 | FindNextUrlCacheGroup := tFindNextUrlCacheGroup(fPointer);
|
---|
212 | fPointer := getProcAddress(hInst, 'GetUrlCacheGroupAttributeA');
|
---|
213 | if fPointer <> nil then
|
---|
214 | begin
|
---|
215 | GetUrlCacheGroupAttribute := tGetUrlCacheGroupAttribute(fPointer);
|
---|
216 | fPointer := getProcAddress(hInst, 'SetUrlCacheGroupAttributeA');
|
---|
217 | if fPointer <> nil then
|
---|
218 | begin
|
---|
219 | SetUrlCacheGroupAttribute := tSetUrlCacheGroupAttribute(fPointer);
|
---|
220 | fPointer := getProcAddress(hInst, 'FindFirstUrlCacheEntryExA');
|
---|
221 | if fPointer <> nil then
|
---|
222 | Result := true;
|
---|
223 | end; // SetUrlCacheGroupAttribute
|
---|
224 | end; // GetUrlCacheGroupAttribute
|
---|
225 | end; // FindNextUrlCacheGroup
|
---|
226 | end; // FindFirstUrlCacheGroup
|
---|
227 | except
|
---|
228 | end; // loadLib
|
---|
229 | winInetLibFound := Result;
|
---|
230 | end;
|
---|
231 | end;
|
---|
232 |
|
---|
233 | function FileTimeToDateTime(Ft: TFileTime): TDateTime;
|
---|
234 | var
|
---|
235 | St: TSystemTime;
|
---|
236 | lft: TFileTime;
|
---|
237 | begin
|
---|
238 | Result := 0;
|
---|
239 | try
|
---|
240 | if FileTimeToLocalFiletime(Ft, lft) then
|
---|
241 | if FileTimeToSyStemTime(lft, st) then
|
---|
242 | Result := SystemTimeTODateTime(st);
|
---|
243 | except
|
---|
244 | end;
|
---|
245 | end;
|
---|
246 |
|
---|
247 | function DateTimeToFileTime(Dt: TDateTime): TFileTime;
|
---|
248 | var
|
---|
249 | St: TSystemTime;
|
---|
250 | lft: TFileTime;
|
---|
251 | begin
|
---|
252 | try
|
---|
253 | DateTimeToSystemTime(Dt, ST);
|
---|
254 | if SystemTimeToFileTime(st, lft) then
|
---|
255 | LocalFileTimeToFileTime(lft, Result);
|
---|
256 | except
|
---|
257 | Result.dwLowDateTime := 0;
|
---|
258 | Result.dwHighDateTime := 0;
|
---|
259 | end;
|
---|
260 | end;
|
---|
261 |
|
---|
262 | //====IE Cache==================================================================
|
---|
263 |
|
---|
264 | constructor TIECache.Create(AOwner: TComponent);
|
---|
265 | begin
|
---|
266 | inherited;
|
---|
267 | Content.Buffer := nil;
|
---|
268 | ClearEntryValues;
|
---|
269 | // Identical to URLCACHE_FIND_DEFAULT_FILTER
|
---|
270 | FFilterOptions := [NORMAL_ENTRY, COOKIE_ENTRY, URLHISTORY_ENTRY,
|
---|
271 | TRACK_OFFLINE_ENTRY, TRACK_ONLINE_ENTRY, STICKY_ENTRY];
|
---|
272 | end;
|
---|
273 |
|
---|
274 | function TIECache.getLibraryFound: Boolean;
|
---|
275 | begin
|
---|
276 | Result := InitializeWinInet;
|
---|
277 | end;
|
---|
278 |
|
---|
279 | function TIECache.RemoveUrlFromGroup(GroupID: INT64; URL: string): DWORD;
|
---|
280 | begin
|
---|
281 | Result := S_OK;
|
---|
282 | if not InitializeWinInet then
|
---|
283 | begin
|
---|
284 | Result := ERROR_FILE_NOT_FOUND;
|
---|
285 | Exit;
|
---|
286 | end;
|
---|
287 | if not SetUrlCacheEntryGroup(Pchar(URL), INTERNET_CACHE_GROUP_REMOVE, GroupID, nil, 0, nil)
|
---|
288 | then
|
---|
289 | Result := GetLastError;
|
---|
290 | end;
|
---|
291 |
|
---|
292 | function TIECache.AddUrlToGroup(GroupID: INT64; URL: string): DWORD;
|
---|
293 | begin
|
---|
294 | Result := S_OK;
|
---|
295 | if not InitializeWinInet then
|
---|
296 | begin
|
---|
297 | Result := ERROR_FILE_NOT_FOUND;
|
---|
298 | Exit;
|
---|
299 | end;
|
---|
300 | if not SetUrlCacheEntryGroup(Pchar(URL), INTERNET_CACHE_GROUP_ADD, GroupID, nil, 0, nil)
|
---|
301 | then
|
---|
302 | Result := GetLastError;
|
---|
303 | end;
|
---|
304 |
|
---|
305 | function TIECache.CopyFileToCache(URL, FileName: string; CacheType: DWORD; Expire: TDateTime): DWORD;
|
---|
306 | var
|
---|
307 | FName: string;
|
---|
308 | Ext: string;
|
---|
309 | F: file of Byte;
|
---|
310 | Size: DWORD;
|
---|
311 | begin
|
---|
312 | if not InitializeWinInet then
|
---|
313 | begin
|
---|
314 | Result := ERROR_FILE_NOT_FOUND;
|
---|
315 | Exit;
|
---|
316 | end;
|
---|
317 | if not FileExists(FileName) then
|
---|
318 | begin
|
---|
319 | Result := ERROR_FILE_NOT_FOUND;
|
---|
320 | Exit;
|
---|
321 | end;
|
---|
322 | AssignFile(F, FileName);
|
---|
323 | Reset(F);
|
---|
324 | Size := FileSize(F);
|
---|
325 | CloseFile(F);
|
---|
326 | Ext := ExtractFileExt(FileName);
|
---|
327 | Ext := Copy(Ext, 2, Length(ext));
|
---|
328 | Result := CreateEntry(URL, Ext, Size, FName);
|
---|
329 | if Result <> S_OK then
|
---|
330 | Exit;
|
---|
331 | if not windows.copyfile(PChar(FileName), Pchar(FName), False) then
|
---|
332 | begin
|
---|
333 | Result := GetLastError;
|
---|
334 | Exit;
|
---|
335 | end;
|
---|
336 | if not CommitUrlCacheEntry(Pchar(URL), Pchar(Fname), DateTimeToFileTime(Expire), DateTimeToFileTime(now), CacheType, nil, 0, Pchar(Ext), 0)
|
---|
337 | then
|
---|
338 | Result := GetLastError;
|
---|
339 | end;
|
---|
340 |
|
---|
341 | function TIECache.CreateEntry(URL, FileExtension: string; ExpectedFileSize: DWORD; var FName: string): DWORD;
|
---|
342 | var
|
---|
343 | PC: array[0..MAX_PATH] of Char;
|
---|
344 | begin
|
---|
345 | PC := '';
|
---|
346 | Result := S_OK;
|
---|
347 | if not InitializeWinInet then
|
---|
348 | begin
|
---|
349 | Result := ERROR_FILE_NOT_FOUND;
|
---|
350 | Exit;
|
---|
351 | end;
|
---|
352 | if not CreateUrlCacheEntry(Pchar(URL), ExpectedFileSize, Pchar(FileExtension), PC, 0) then
|
---|
353 | Result := GetLastError
|
---|
354 | else
|
---|
355 | FName := StrPas(PC);
|
---|
356 | end;
|
---|
357 |
|
---|
358 | function TIECache.GetGroupInfo(GroupID: INT64): DWORD;
|
---|
359 | var
|
---|
360 | info: TInternetCacheGroupInfo;
|
---|
361 | dw: DWORD;
|
---|
362 | begin
|
---|
363 | Result := S_OK;
|
---|
364 | if not InitializeWinInet then
|
---|
365 | begin
|
---|
366 | Result := ERROR_FILE_NOT_FOUND;
|
---|
367 | Exit;
|
---|
368 | end;
|
---|
369 | dw := SizeOf(TInternetCacheGroupInfo);
|
---|
370 | if not GetUrlCacheGroupAttribute(GroupID, 0, CACHEGROUP_ATTRIBUTE_GET_ALL, info, dw, nil)
|
---|
371 | then
|
---|
372 | Result := GetLastError
|
---|
373 | else
|
---|
374 | with GroupInfo do
|
---|
375 | begin
|
---|
376 | DiskUsage := info.dwDiskUsage;
|
---|
377 | DiskQuota := info.dwDiskQuota;
|
---|
378 | Move(info.dwOwnerStorage, OwnerStorage, Sizeof(OwnerStorage));
|
---|
379 | GroupName := string(info.szGroupName);
|
---|
380 | end;
|
---|
381 | end;
|
---|
382 |
|
---|
383 | function TIECache.SetGroupInfo(GroupID: INT64): DWORD;
|
---|
384 | var
|
---|
385 | info: TInternetCacheGroupInfo;
|
---|
386 | begin
|
---|
387 | Result := S_OK;
|
---|
388 | if not InitializeWinInet then
|
---|
389 | begin
|
---|
390 | Result := ERROR_FILE_NOT_FOUND;
|
---|
391 | Exit;
|
---|
392 | end;
|
---|
393 | info.dwGroupSize := SizeOf(Info);
|
---|
394 | info.dwGroupFlags := CACHEGROUP_FLAG_NONPURGEABLE;
|
---|
395 | info.dwGroupType := CACHEGROUP_TYPE_INVALID;
|
---|
396 | info.dwDiskQuota := GroupInfo.DiskQuota;
|
---|
397 | move(GroupInfo.OwnerStorage, info.dwOwnerStorage, Sizeof(info.dwOwnerStorage));
|
---|
398 | move(GroupInfo.Groupname[1], info.szGroupName[0], length(GroupInfo.Groupname));
|
---|
399 | if not SetUrlCacheGroupAttribute(GroupID, 0, CACHEGROUP_READWRITE_MASK, info, nil) then
|
---|
400 | Result := GetLastError;
|
---|
401 | end;
|
---|
402 |
|
---|
403 | function TIECache.CreateGroup: INT64;
|
---|
404 | begin
|
---|
405 | if not InitializeWinInet then
|
---|
406 | begin
|
---|
407 | Result := ERROR_FILE_NOT_FOUND;
|
---|
408 | Exit;
|
---|
409 | end;
|
---|
410 | Result := CreateUrlCacheGroup(0, nil);
|
---|
411 | end;
|
---|
412 |
|
---|
413 | function TIECache.DeleteGroup(GroupID: INT64): DWORD;
|
---|
414 | begin
|
---|
415 | Result := S_OK;
|
---|
416 | if not InitializeWinInet then
|
---|
417 | begin
|
---|
418 | Result := ERROR_FILE_NOT_FOUND;
|
---|
419 | Exit;
|
---|
420 | end;
|
---|
421 | if not DeleteUrlCacheGroup(GroupID, CACHEGROUP_FLAG_FLUSHURL_ONDELETE, nil) then
|
---|
422 | Result := GetLastError;
|
---|
423 | end;
|
---|
424 |
|
---|
425 | function TIECache.SetEntryInfo(URL: string): DWORD;
|
---|
426 | var
|
---|
427 | Info: TInternetCacheEntryInfo;
|
---|
428 | FC: DWORD;
|
---|
429 | begin
|
---|
430 | Result := S_OK;
|
---|
431 | if not InitializeWinInet then
|
---|
432 | begin
|
---|
433 | Result := ERROR_FILE_NOT_FOUND;
|
---|
434 | Exit;
|
---|
435 | end;
|
---|
436 | FC := CACHE_ENTRY_ATTRIBUTE_FC +
|
---|
437 | CACHE_ENTRY_HITRATE_FC +
|
---|
438 | CACHE_ENTRY_MODTIME_FC +
|
---|
439 | CACHE_ENTRY_EXPTIME_FC +
|
---|
440 | CACHE_ENTRY_ACCTIME_FC +
|
---|
441 | CACHE_ENTRY_SYNCTIME_FC +
|
---|
442 | CACHE_ENTRY_EXEMPT_DELTA_FC;
|
---|
443 | with Info do
|
---|
444 | begin
|
---|
445 | CacheEntryType := EntryInfo.EntryType;
|
---|
446 | dwHitRate := EntryInfo.HitRate;
|
---|
447 | LastModifiedTime := DateTimeToFileTime(EntryInfo.LastModifiedTime);
|
---|
448 | ExpireTime := DateTimeToFileTime(EntryInfo.ExpireTime);
|
---|
449 | LastAccessTime := DateTimeToFileTime(EntryInfo.LastAccessTime);
|
---|
450 | LastSyncTime := DateTimeToFileTime(EntryInfo.LastSyncTime);
|
---|
451 | dwReserved := EntryInfo.ExemptDelta;
|
---|
452 | end;
|
---|
453 | if not SetUrlCacheEntryInfo(Pchar(URL), Info, FC) then
|
---|
454 | Result := GetLastError;
|
---|
455 | end;
|
---|
456 |
|
---|
457 | function TIECache.GetEntryInfo(URL: string): DWORD;
|
---|
458 | var
|
---|
459 | D: DWORD;
|
---|
460 | T: PInternetCacheEntryInfo;
|
---|
461 | begin
|
---|
462 | Result := S_OK;
|
---|
463 | if not InitializeWinInet then
|
---|
464 | begin
|
---|
465 | Result := ERROR_FILE_NOT_FOUND;
|
---|
466 | Exit;
|
---|
467 | end;
|
---|
468 | if (D <= 0) or (not GetUrlCacheEntryInfoEx(Pchar(URL), nil, @D, nil, nil, nil, 0)) then
|
---|
469 | begin
|
---|
470 | // (PChar(SysErrorMessage(GetLastError)));
|
---|
471 | // https objects are not stored in cache
|
---|
472 | Result := GetLastError();
|
---|
473 | end
|
---|
474 | else
|
---|
475 | begin
|
---|
476 | GetMem(T, D);
|
---|
477 | try
|
---|
478 | if GetUrlCacheEntryInfoEx(Pchar(URL), T, @D, nil, nil, nil, 0)
|
---|
479 | then
|
---|
480 | GetEntryValues(t)
|
---|
481 | else
|
---|
482 | Result := GetLastError;
|
---|
483 | finally
|
---|
484 | FreeMem(T, D);
|
---|
485 | end;
|
---|
486 | end;
|
---|
487 | end;
|
---|
488 |
|
---|
489 | function TIECache.GetEntryContent(URL: string): DWORD;
|
---|
490 | var
|
---|
491 | HR: THandle;
|
---|
492 | D: Cardinal;
|
---|
493 | T: PInternetCacheEntryInfo;
|
---|
494 | begin
|
---|
495 | Result := S_OK;
|
---|
496 | if not InitializeWinInet then
|
---|
497 | begin
|
---|
498 | Result := ERROR_FILE_NOT_FOUND;
|
---|
499 | Exit;
|
---|
500 | end;
|
---|
501 | D := 0;
|
---|
502 | T := nil;
|
---|
503 | RetrieveUrlCacheEntryStream(PChar(URL), T^, D, TRUE, 0);
|
---|
504 | Getmem(T, D);
|
---|
505 | try
|
---|
506 | HR := THandle(RetrieveUrlCacheEntryStream(PChar(URL), T^, D, TRUE, 0));
|
---|
507 | if HR <> 0 then
|
---|
508 | begin
|
---|
509 | Content.BufferLength := T^.dwSizeLow + 1;
|
---|
510 | GetEntryValues(T);
|
---|
511 | Getmem(Content.Buffer, Content.BufferLength);
|
---|
512 | Fillchar(Content.Buffer^, Content.BufferLength, #0);
|
---|
513 | if not ReadUrlCacheEntryStream(Hr, 0, Content.Buffer, T^.DwSizeLow, 0)
|
---|
514 | then
|
---|
515 | Result := GetLastError;
|
---|
516 | end;
|
---|
517 | finally
|
---|
518 | FreeMem(T, D);
|
---|
519 | end;
|
---|
520 | UnLockUrlCacheEntryStream(HR, 0);
|
---|
521 | end;
|
---|
522 |
|
---|
523 | function TIECache.FindNextGroup(var GroupID: Int64): BOOL;
|
---|
524 | begin
|
---|
525 | if not InitializeWinInet then
|
---|
526 | begin
|
---|
527 | Result := False;
|
---|
528 | Exit;
|
---|
529 | end;
|
---|
530 | Result := FindNextUrlCacheGroup(GrpHandle, GroupID, nil);
|
---|
531 | GetGroupInfo(GroupID);
|
---|
532 | end;
|
---|
533 |
|
---|
534 | function TIECache.FindFirstGroup(var GroupID: Int64): DWORD;
|
---|
535 | begin
|
---|
536 | if not InitializeWinInet then
|
---|
537 | begin
|
---|
538 | Result := ERROR_FILE_NOT_FOUND;
|
---|
539 | Exit;
|
---|
540 | end;
|
---|
541 | GrpHandle := FindFirstUrlCacheGroup(0, 0, nil, 0, GroupID, nil);
|
---|
542 | if GrpHandle <> 0 then
|
---|
543 | Result := S_OK
|
---|
544 | else
|
---|
545 | Result := GetLastError;
|
---|
546 | if Result = S_OK then
|
---|
547 | GetGroupInfo(GroupID);
|
---|
548 | end;
|
---|
549 |
|
---|
550 | function TIECache.RetrieveGroups: DWORD;
|
---|
551 | var
|
---|
552 | GroupID: INT64;
|
---|
553 | Res: DWORD;
|
---|
554 | NewGroup, Cancel: Boolean;
|
---|
555 | begin
|
---|
556 | Result := S_OK;
|
---|
557 | if not InitializeWinInet then
|
---|
558 | begin
|
---|
559 | Result := ERROR_FILE_NOT_FOUND;
|
---|
560 | Exit;
|
---|
561 | end;
|
---|
562 | Cancel := False;
|
---|
563 | NewGroup := True;
|
---|
564 | Res := FindFirstGroup(GroupID);
|
---|
565 | if Res = S_OK then
|
---|
566 | begin
|
---|
567 | GetGroupInfo(GroupID);
|
---|
568 | if Assigned(FOngroup) then
|
---|
569 | FOnGroup(self, GroupID, FCancel);
|
---|
570 | while not Cancel and NewGroup do
|
---|
571 | begin
|
---|
572 | NewGroup := FindNextGroup(GroupID);
|
---|
573 | GetGroupInfo(GroupID);
|
---|
574 | if Assigned(FOngroup) and NewGroup then
|
---|
575 | FOnGroup(self, GroupID, Cancel);
|
---|
576 | end;
|
---|
577 | end
|
---|
578 | else
|
---|
579 | Result := GetLastError;
|
---|
580 | end;
|
---|
581 |
|
---|
582 | function TIECache.DeleteEntry(URL: string): DWORD;
|
---|
583 | begin
|
---|
584 | Result := S_OK;
|
---|
585 | if not InitializeWinInet then Exit;
|
---|
586 | if not DeleteUrlCacheEntry(PChar(URL)) then
|
---|
587 | Result := GetLastError
|
---|
588 | else
|
---|
589 | ClearEntryValues;
|
---|
590 | end;
|
---|
591 |
|
---|
592 | procedure TIECache.ClearAllEntries;
|
---|
593 | var
|
---|
594 | HR: DWord;
|
---|
595 | begin
|
---|
596 | if not InitializeWinInet then Exit;
|
---|
597 | if FindFirstEntry(0) = S_OK then
|
---|
598 | begin
|
---|
599 | repeat
|
---|
600 | DeleteEntry(EntryInfo.SourceUrlName);
|
---|
601 | HR := FindNextEntry;
|
---|
602 | until HR = ERROR_NO_MORE_ITEMS;
|
---|
603 | end;
|
---|
604 | FindCloseUrlCache(H);
|
---|
605 | end;
|
---|
606 |
|
---|
607 | procedure TIECache.ClearEntryValues;
|
---|
608 | begin
|
---|
609 | if not InitializeWinInet then Exit;
|
---|
610 | Content.Buffer := nil;
|
---|
611 | Content.BufferLength := 0;
|
---|
612 | with EntryInfo do
|
---|
613 | begin
|
---|
614 | SourceUrlName := '';
|
---|
615 | LocalFileName := '';
|
---|
616 | EntryType := 0;
|
---|
617 | UseCount := 0;
|
---|
618 | Hitrate := 0;
|
---|
619 | LastModifiedTime := 0;
|
---|
620 | ExpireTime := 0;
|
---|
621 | LastAccessTime := 0;
|
---|
622 | LastSyncTime := 0;
|
---|
623 | FileExtension := '';
|
---|
624 | FSize := 0;
|
---|
625 | HeaderInfo := '';
|
---|
626 | ExemptDelta := 0;
|
---|
627 | end;
|
---|
628 | end;
|
---|
629 |
|
---|
630 | procedure TIECache.GetEntryValues(Info: PInternetCacheEntryInfo);
|
---|
631 | begin
|
---|
632 | if not InitializeWinInet then Exit;
|
---|
633 | with entryInfo do
|
---|
634 | begin
|
---|
635 | SourceUrlName := info^.lpszSourceUrlName;
|
---|
636 | LocalFileName := info^.lpszLocalFileName;
|
---|
637 | EntryType := info^.CacheEntryType;
|
---|
638 | UseCount := info^.dwUseCount;
|
---|
639 | Hitrate := info^.dwHitRate;
|
---|
640 | LastModifiedTime := FileTimeToDateTime(info^.LastModifiedTime);
|
---|
641 | ExpireTime := FileTimeToDateTime(info^.ExpireTime);
|
---|
642 | LastAccessTime := FileTimeToDateTime(info^.LastAccessTime);
|
---|
643 | LastSyncTime := FileTimeToDateTime(info^.LastSyncTime);
|
---|
644 | FileExtension := info^.lpszFileExtension;
|
---|
645 | FSize := (info^.dwSizeHigh shl 32) + info^.dwSizeLow;
|
---|
646 | HeaderInfo := StrPas(PChar(info^.lpHeaderInfo));
|
---|
647 | ExemptDelta := info^.dwReserved;
|
---|
648 | end;
|
---|
649 | end;
|
---|
650 |
|
---|
651 | function TIECache.FindFirstEntry(GroupID: INT64): DWORD;
|
---|
652 | const
|
---|
653 | Pattern: array[TSearchPattern] of PChar = (nil, 'Cookie:', 'Visited:', '');
|
---|
654 | var
|
---|
655 | T: PInternetCacheEntryInfo;
|
---|
656 | D: DWORD;
|
---|
657 | begin
|
---|
658 | Result := S_OK;
|
---|
659 | if not InitializeWinInet then
|
---|
660 | begin
|
---|
661 | Result := ERROR_FILE_NOT_FOUND;
|
---|
662 | Exit;
|
---|
663 | end;
|
---|
664 | H := 0;
|
---|
665 | D := 0;
|
---|
666 | FindFirstUrlCacheEntryEx(Pattern[SearchPattern], 0, FFilterOptionValue, GroupID, nil, @D, nil, nil, nil);
|
---|
667 | GetMem(T, D);
|
---|
668 | try
|
---|
669 | H := FindFirstUrlCacheEntryEx(Pattern[SearchPattern], 0, FFilterOptionValue, GroupID, T, @D, nil, nil, nil);
|
---|
670 | if (H = 0) then
|
---|
671 | Result := GetLastError
|
---|
672 | else
|
---|
673 | GetEntryValues(T);
|
---|
674 | finally
|
---|
675 | FreeMem(T, D)
|
---|
676 | end;
|
---|
677 | end;
|
---|
678 |
|
---|
679 | function TIECache.FindNextEntry: DWORD;
|
---|
680 | var
|
---|
681 | T: PInternetCacheEntryInfo;
|
---|
682 | D: DWORD;
|
---|
683 | begin
|
---|
684 | Result := S_OK;
|
---|
685 | if not InitializeWinInet then
|
---|
686 | begin
|
---|
687 | Result := ERROR_FILE_NOT_FOUND;
|
---|
688 | Exit;
|
---|
689 | end;
|
---|
690 | D := 0;
|
---|
691 | FindNextUrlCacheEntryEx(H, nil, @D, nil, nil, nil);
|
---|
692 | GetMem(T, D);
|
---|
693 | try
|
---|
694 | if not FindNextUrlCacheEntryEx(H, T, @D, nil, nil, nil)
|
---|
695 | then
|
---|
696 | Result := GetLastError
|
---|
697 | else
|
---|
698 | GetEntryValues(T);
|
---|
699 | finally
|
---|
700 | FreeMem(T, D)
|
---|
701 | end;
|
---|
702 | end;
|
---|
703 |
|
---|
704 | procedure TIECache.RetrieveEntries(GroupID: INT64);
|
---|
705 | var
|
---|
706 | HR: DWORD;
|
---|
707 | begin
|
---|
708 | if not InitializeWinInet then Exit;
|
---|
709 | FCancel := False;
|
---|
710 | HR := FindFirstEntry(GroupID);
|
---|
711 | if (HR = S_OK) then
|
---|
712 | begin
|
---|
713 | if Assigned(FOnEntry) then
|
---|
714 | with EntryInfo do
|
---|
715 | FOnEntry(self, FCancel);
|
---|
716 | while (HR = S_OK) and not FCancel do
|
---|
717 | begin
|
---|
718 | HR := FindNextEntry;
|
---|
719 | if (HR = S_OK) and Assigned(FOnEntry) then
|
---|
720 | with EntryInfo do
|
---|
721 | FOnEntry(self, FCancel);
|
---|
722 | end;
|
---|
723 | end;
|
---|
724 | FindCloseUrlCache(H);
|
---|
725 | end;
|
---|
726 |
|
---|
727 | function TIECache.CloseFindEntry: BOOL;
|
---|
728 | begin
|
---|
729 | if not InitializeWinInet then
|
---|
730 | begin
|
---|
731 | Result := False;
|
---|
732 | Exit;
|
---|
733 | end;
|
---|
734 | Result := FindCloseUrlCache(H);
|
---|
735 | end;
|
---|
736 |
|
---|
737 | procedure TIECache.SetFilterOptions(const Value: TFilterOptions);
|
---|
738 | begin
|
---|
739 | FFilterOptions := Value;
|
---|
740 | UpdateFilterOptionValue;
|
---|
741 | end;
|
---|
742 |
|
---|
743 | procedure TIECache.UpdateFilterOptionValue;
|
---|
744 | const
|
---|
745 | AcardFilterOptionValues: array[TFilterOption] of Cardinal = (
|
---|
746 | $00000001, $00000002, $00000004, $00100000, $00200000,
|
---|
747 | $00000010, $00000020, $00010000, $00020000);
|
---|
748 | var
|
---|
749 | i: TFilterOption;
|
---|
750 | begin
|
---|
751 | FFilterOptionValue := 0;
|
---|
752 | if (FFilterOptions <> []) then
|
---|
753 | for i := Low(TFilterOption) to High(TFilterOption) do
|
---|
754 | if (i in FFilterOptions) then
|
---|
755 | Inc(FFilterOptionValue, AcardFilterOptionValues[i]);
|
---|
756 | end;
|
---|
757 |
|
---|
758 | initialization
|
---|
759 | wininetLibFound := InitializeWinInet;
|
---|
760 |
|
---|
761 | end.
|
---|