~ximion/listaller/master

1 by ximion
1
(* ***** BEGIN LICENSE BLOCK *****
2
 * Version: MPL 1.1
3
 *
4
 * The contents of this file are subject to the Mozilla Public License Version
5
 * 1.1 (the "License"); you may not use this file except in compliance with
6
 * the License. You may obtain a copy of the License at
7
 * http://www.mozilla.org/MPL/
8
 *
9
 * Software distributed under the License is distributed on an "AS IS" basis,
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
 * for the specific language governing rights and limitations under the
12
 * License.
13
 *
14
 * The Original Code is TurboPower Abbrevia
15
 *
16
 * The Initial Developer of the Original Code is
17
 * TurboPower Software
18
 *
19
 * Portions created by the Initial Developer are Copyright (C) 1997-2002
20
 * the Initial Developer. All Rights Reserved.
21
 *
22
 * Contributor(s):
23
 *
24
 * ***** END LICENSE BLOCK ***** *)
25
26
{*********************************************************}
27
{* ABBREVIA: AbFciFdi.pas 3.05                           *}
28
{*********************************************************}
29
{* ABBREVIA: Cabinet DLL wrapper                         *}
30
{* Based on info from the FCI/FDI Library Description,   *}
31
{* included in the Microsoft Cabinet SDK                 *}
32
{*********************************************************}
33
34
unit AbFciFdi;
35
36
{$mode delphi}
37
38
interface
39
40
uses
41
  typesarchive, //!! MVC for BOOL
42
  dynlibs, // loadlibrary
43
{$ifdef mswindows}
44
  Windows,
45
{$endif}  
46
  SysUtils, Classes;
47
48
const
49
  CabinetDLL  = 'cabinet.dll';
50
  cpuUnknown  = -1;
51
  cpu80286    = 0;
52
  cpu80386    = 1;
53
  cpuDefault  = cpuUnknown;
54
55
56
type
57
  {FDI errors}
58
  FDIError =
59
    (FDIError_None,            FDIError_Cabinet_Not_Found,
60
     FDIError_Not_A_Cabinet,   FDIError_Unknown_Cabinet_Version,
61
     FDIError_Corrupt_Cabinet, FDIError_Alloc_Fail,
62
     FDIError_Bad_Compr_Type,  FDIError_MDI_Fail,
63
     FDIError_Target_File,     FDIError_Reserve_Mismatch,
64
     FDIError_Wrong_Cabinet,   FDIError_User_Abort);
65
66
  {FCI errors}
67
  FCIError =
68
    (FCIError_NONE,      FCIError_Open_SRC,
69
     FCIError_Read_SRC,  FCIError_Alloc_Fail,
70
     FCIError_Temp_File, FCIError_Bad_Compr_Type,
71
     FCIError_Cab_File,  FCIError_User_Abort,
72
     FCIERRor_MCI_Fail);
73
74
  {FDI notifications}
75
  FDINotificationType =
76
    (FDINT_Cabinet_Info, FDINT_Partial_File,
77
     FDINT_Copy_File,    FDINT_Close_File_Info,
78
     FDINT_Next_Cabinet, FDINT_Enumerate);
79
80
  {FDI/FCI error structure}
81
  PCabErrorRecord = ^CabErrorRecord;
82
  CabErrorRecord  = record
83
    ErrorCode     : Integer;
84
    ErrorType     : Integer;
85
    ErrorPresent  : Boolean;
86
  end;
87
88
  {FDI cabinet information structure}
89
  PFDICabInfo = ^FDICabInfo;
90
  FDICabInfo  = record
91
    cbCabinet : Longint;
92
    cFolders  : Word;
93
    cFiles    : Word;
94
    setID     : Word;
95
    iCabinet  : Word;
96
    fReserve  : BOOL;
97
    hasprev   : BOOL;
98
    hasnext   : BOOL;
99
  end;
100
101
  {FCI cabinet information structure}
102
  PFCICabInfo = ^FCICabInfo;
103
  FCICabInfo  = record
104
    cb                    : Longint;
105
    cbFolderThresh        : Longint;
106
    cbReserveCFHeader     : Integer;
107
    cbReserveCFFolder     : Integer;
108
    cbReserveCFData       : Integer;
109
    iCab                  : Integer;
110
    iDisk                 : Integer;
111
    fFailOnIncompressible : Integer;
112
    setID                 : Word;
113
    szDisk                : array[0..255] of Char;
114
    szCab                 : array[0..255] of Char;
115
    szCabPath             : array[0..255] of Char;
116
  end;
117
118
  {FDI notification structure}
119
  PFDINotification = ^FDINotification;
120
  FDINotification  = record
121
    cb       : Longint;
122
    psz1     : PChar;
123
    psz2     : PChar;
124
    psz3     : PChar;
125
    pv       : Pointer;
126
    hf       : Integer;
127
    date     : Word;
128
    time     : Word;
129
    attribs  : Word;
130
    setID    : Word;
131
    iCabinet : Word;
132
    iFolder  : Word;
133
    fdie     : FDIERROR;
134
  end;
135
136
  {misc defines}
137
  HFDI    = Pointer;
138
  HFCI    = Pointer;
139
  FARPROC = Pointer;
140
141
142
{== Cabinet DLL routine prototypes ==========================================}
143
type
144
  TFDICreate =
145
    function (pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
146
      pfnseek : FARPROC; cpuType  : Integer; pError : PCabErrorRecord) : HFDI;
147
      cdecl;
148
{----------------------------------------------------------------------------}
149
  TFDIIsCabinet =
150
    function(hfdi : HFDI; hf : Integer; pfdici : PFDICabInfo) : Boolean;
151
      cdecl;
152
{----------------------------------------------------------------------------}
153
  TFDICopy =
154
    function(hfdi : HFDI; pszCabinet, pszCabPath : PChar;
155
      flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : Boolean;
156
      cdecl;
157
{----------------------------------------------------------------------------}
158
  TFDIDestroy =
159
    function(hfdi : HFDI) : Boolean;
160
      cdecl;
161
{----------------------------------------------------------------------------}
162
  TFCICreate =
163
    function(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree,
164
      pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete,
165
      pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI;
166
      cdecl;
167
{----------------------------------------------------------------------------}
168
  TFCIAddFile =
169
    function(hfci : HFCI; pszFilePath, pszFileName : PChar;
170
      fExecute : Boolean; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
171
      typeCompress : Word) : Boolean;
172
      cdecl;
173
{----------------------------------------------------------------------------}
174
  TFCIFlushCabinet =
175
    function(hfci : HFCI; fGetNextCab : Boolean;
176
      pfnfcignc, pfnfcis : FARPROC) : Boolean;
177
      cdecl;
178
{----------------------------------------------------------------------------}
179
  TFCIFlushFolder =
180
    function(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : Boolean;
181
      cdecl;
182
{----------------------------------------------------------------------------}
183
  TFCIDestroy =
184
    function(hfci : HFCI) : Boolean;
185
      cdecl;
186
187
188
{== DLL routine wrappers ====================================================}
189
function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,
190
  pfnwrite, pfnclose, pfnseek : FARPROC;
191
  cpuType  : Integer; pError : PCabErrorRecord) : HFDI;
192
  {returns an FDI context for opening an existing cabinet}
193
  {  pfnalloc - heap allocation callback function }
194
  {  pfnfree  -  heap deallocation callback function }
195
  {  pfnopen  -  open file callback function }
196
  {  pfnwrite - write file callback function }
197
  {  pfnclose - close file callback function }
198
  {  pfnseek  - reposition file pointer callback function }
199
  {  cpuType  -  -1: unknown, 0: 80286, 1: 80386 }
200
  {  pError   -  pointer to error record }
201
{----------------------------------------------------------------------------}
202
function FDIIsCabinet(hfdi : HFDI; hf : Integer;
203
  pfdici : PFDICabInfo) : Boolean;
204
  {checks cabinet file for validity}
205
  {  hfdi   - FDI context }
206
  {  hf     - cabinet file handle }
207
  {  pfdici - pointer to FDI cabinet info structure }
208
{----------------------------------------------------------------------------}
209
function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PChar;
210
  flags : Integer; pfnfdin, pfnfdid : FARPROC;
211
  Archive : Pointer) : Boolean;
212
  {enumerates every file in the cabinet.  The callback function}
213
  {should indicate whether or not to extract a given file}
214
  {  hfdi       - FDI context }
215
  {  pszCabinet - cabinet file name }
216
  {  pszCabPath - cabinet file path }
217
  {  flags      - currently not used }
218
  {  pfnfdin    - FDI notifaction callback function }
219
  {  pfnfdid    - decryption callback (currently not used)}
220
  {  Archive    - the calling TAbCabArchive instance }
221
{----------------------------------------------------------------------------}
222
function FDIDestroy(hfdi : HFDI) : Boolean;
223
  {releases FDI context and frees resources}
224
  {  hfdi - FDI context }
225
{----------------------------------------------------------------------------}
226
function FCICreate(pError : PCabErrorRecord;
227
  pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
228
  pfnseek, pfndelete, pfnfcigtf : FARPROC;
229
  pccab : PFCICabInfo; Archive : Pointer) : HFCI;
230
  {creates a new cabinet file and returns the FCI context}
231
  {  pError    - pointer to error record }
232
  {  pfnfcifp  - callback notification when file has been placed in cabinet }
233
  {  pfnalloc  - callback function to allocate memory }
234
  {  pfnfree   - callback function to free memory }
235
  {  pfnopen   - callback function to open a file }
236
  {  pfnwrite  - callback function to write to a file }
237
  {  pfnclose  - callback function to close a file }
238
  {  pfnseek   - callback function to reposition file pointer }
239
  {  pfndelete - callback function to delete a file }
240
  {  pfnfcigtf - callback function to obtain temp filename }
241
  {  pccab     - pointer to FCI cabinet infor structure }
242
  {  Archive   - the calling TAbCabArchive instance }
243
{----------------------------------------------------------------------------}
244
function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PChar;
245
  fExecute : Boolean; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
246
  typeCompress : Word) : Boolean;
247
  {adds a file to the cabinet}
248
  {  hfci         - FCI context }
249
  {  pszFilePath  - full pathname of file being added }
250
  {  pszFileName  - just the file name }
251
  {  fExecute     - flag to indicate if file is executable }
252
  {  pfnfcignc    - callback function to obtain next cabinet info }
253
  {  pfnfcis      - callback function to relay progress }
254
  {  pfnfcigoi    - callback function to open file and get attributes }
255
  {  typeCompress - compression type to use }
256
{----------------------------------------------------------------------------}
257
function FCIFlushCabinet(hfci : HFCI; fGetNextCab : Boolean;
258
  pfnfcignc, pfnfcis : FARPROC) : Boolean;
259
  {writes current cabinet file out to disk and optionally starts a new one}
260
  {  hfci        - FCI context }
261
  {  fGetNextCab - flag indicating whether to start a new cabinet }
262
  {  pfnfcignc   - callback function to obtain next cabinet info }
263
  {  pfnfcis     - callback function to relay progress }
264
{----------------------------------------------------------------------------}
265
function FCIFlushFolder(hfci : HFCI;
266
  pfnfcignc, pfnfcis : FARPROC) : Boolean;
267
  {close current compression block and start a new one}
268
  {  hfci      - FCI context }
269
  {  pfnfcignc - callback function to obtain next cabinet info }
270
  {  pfnfcis   - callback function to relay progress }
271
{----------------------------------------------------------------------------}
272
function FCIDestroy(hfci : HFCI) : Boolean;
273
  {releases FCI context and frees resources}
274
  {  hfdi - FDI context }
275
{----------------------------------------------------------------------------}
276
277
278
implementation
279
280
uses
281
  AbExcept,
282
  AbConst;
283
284
285
var
286
  CabDLLLoaded        : Boolean;
287
  CabDLLHandle        : THandle;
288
  FDICreateProc       : TFDICreate;
289
  FDIIsCabinetProc    : TFDIIsCabinet;
290
  FDICopyProc         : TFDICopy;
291
  FDIDestroyProc      : TFDIDestroy;
292
  FCICreateProc       : TFCICreate;
293
  FCIAddFileProc      : TFCIAddFile;
294
  FCIFlushCabinetProc : TFCIFlushCabinet;
295
  FCIFlushFolderProc  : TFCIFlushFolder;
296
  FCIDestroyProc      : TFCIDestroy;
297
298
299
{============================================================================}
300
procedure LoadCabinetDLL;
301
begin
302
  if CabDllLoaded then
303
    Exit;
304
//  CabDllHandle := LoadLibrary(CabinetDLL);
305
  if (CabDllHandle = 0) then
306
    raise EAbNoCabinetDLL.Create;
307
{$ifdef MSWINDOWS}
308
  @FDICreateProc := GetProcAddress(CabDllHandle, 'FDICreate');
309
  @FDIIsCabinetProc := GetProcAddress(CabDllHandle, 'FDIIsCabinet');
310
  @FDICopyProc := GetProcAddress(CabDllHandle, 'FDICopy');
311
  @FDIDestroyProc := GetProcAddress(CabDllHandle, 'FDIDestroy');
312
  @FCICreateProc := GetProcAddress(CabDllHandle, 'FCICreate');
313
  @FCIAddFileProc := GetProcAddress(CabDllHandle, 'FCIAddFile');
314
  @FCIFlushCabinetProc := GetProcAddress(CabDllHandle, 'FCIFlushCabinet');
315
  @FCIFlushFolderProc := GetProcAddress(CabDllHandle, 'FCIFlushFolder');
316
  @FCIDestroyProc := GetProcAddress(CabDllHandle, 'FCIDestroy');
317
  CabDllLoaded := True;
318
{$endif}
319
end;
320
{----------------------------------------------------------------------------}
321
function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,
322
  pfnwrite, pfnclose, pfnseek : FARPROC;
323
  cpuType  : Integer; pError : PCabErrorRecord) : HFDI;
324
begin
325
  LoadCabinetDLL;
326
  if Assigned(FDICreateProc) then
327
    Result := FDICreateProc(pfnalloc, pfnfree, pfnopen, pfnread,
328
      pfnwrite, pfnclose, pfnseek, cpuType, pError)
329
  else
330
    Result := nil;
331
end;
332
{----------------------------------------------------------------------------}
333
function FDIIsCabinet(hfdi : HFDI; hf : Integer;
334
  pfdici : PFDICabInfo) : Boolean;
335
begin
336
  LoadCabinetDLL;
337
  if Assigned(FDIIsCabinetProc) then
338
    Result := FDIIsCabinetProc(hfdi, hf, pfdici)
339
  else
340
    Result := False;
341
end;
342
{----------------------------------------------------------------------------}
343
function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PChar;
344
  flags : Integer; pfnfdin, pfnfdid : FARPROC;
345
  Archive : Pointer) : Boolean;
346
begin
347
  LoadCabinetDLL;
348
  if Assigned(FDICopyProc) then
349
    Result := FDICopyProc(hfdi, pszCabinet, pszCabPath, flags,
350
      pfnfdin, pfnfdid, Archive)
351
  else
352
    Result := False;
353
end;
354
{----------------------------------------------------------------------------}
355
function FDIDestroy(hfdi : HFDI) : Boolean;
356
begin
357
  LoadCabinetDLL;
358
  if Assigned(FDIDestroyProc) then
359
    Result := FDIDestroyProc(hfdi)
360
  else
361
    Result := False;
362
end;
363
{----------------------------------------------------------------------------}
364
function FCICreate(pError : PCabErrorRecord;
365
  pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
366
  pfnseek, pfndelete, pfnfcigtf : FARPROC;
367
  pccab : PFCICabInfo; Archive : Pointer) : HFCI;
368
begin
369
  LoadCabinetDLL;
370
  if Assigned(FCICreateProc) then
371
    Result := FCICreateProc(pError, pfnfcifp, pfnalloc, pfnfree, pfnopen,
372
      pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf,
373
      pccab, Archive)
374
  else
375
    Result := nil;
376
end;
377
{----------------------------------------------------------------------------}
378
function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PChar;
379
  fExecute : Boolean; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
380
  typeCompress : Word) : Boolean;
381
begin
382
  LoadCabinetDLL;
383
  if Assigned(FCIAddFileProc) then
384
    Result := FCIAddFileProc(hfci, pszFilePath, pszFileName,
385
      fExecute, pfnfcignc, pfnfcis, pfnfcigoi, typeCompress)
386
  else
387
    Result := False;
388
end;
389
{----------------------------------------------------------------------------}
390
function FCIFlushCabinet(hfci : HFCI; fGetNextCab : Boolean;
391
  pfnfcignc, pfnfcis : FARPROC) : Boolean;
392
begin
393
  LoadCabinetDLL;
394
  if Assigned(FCIFlushCabinetProc) then
395
    Result := FCIFlushCabinetProc(hfci, fGetNextCab, pfnfcignc, pfnfcis)
396
  else
397
    Result := False;
398
end;
399
{----------------------------------------------------------------------------}
400
function FCIFlushFolder(hfci : HFCI;
401
  pfnfcignc, pfnfcis : FARPROC) : Boolean;
402
begin
403
  LoadCabinetDLL;
404
  if Assigned(FCIFlushFolderProc) then
405
    Result := FCIFlushFolderProc(hfci, pfnfcignc, pfnfcis)
406
  else
407
    Result := False;
408
end;
409
{----------------------------------------------------------------------------}
410
function FCIDestroy(hfci : HFCI) : Boolean;
411
begin
412
  LoadCabinetDLL;
413
  if Assigned(FCIDestroyProc) then
414
    Result := FCIDestroyProc(hfci)
415
  else
416
    Result := False;
417
end;
418
{----------------------------------------------------------------------------}
419
initialization
420
  CabDllLoaded := False;
421
422
end.