unzipdll.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. {
  2. $Id$
  3. }
  4. unit UnzipDLL;
  5. {$IFDEF VIRTUALPASCAL}
  6. {$Cdecl+,AlignRec-,OrgName+}
  7. {$ELSE}
  8. {$IFDEF FPC}
  9. {$PACKRECORDS 1}
  10. {$ENDIF}
  11. {$ENDIF}
  12. interface
  13. const
  14. UnzipErr: longint = 0;
  15. type
  16. TArgV = array [0..1024] of PChar;
  17. PArgV = ^TArgV;
  18. TCharArray = array [1..1024*1024] of char;
  19. PCharArray = ^TCharArray;
  20. TFileUnzipEx = function (SourceZipFile, TargetDirectory,
  21. FileSpecs: PChar): integer;
  22. function DllFileUnzipEx (SourceZipFile, TargetDirectory,
  23. FileSpecs: PChar): integer;
  24. const
  25. FileUnzipEx: TFileUnzipEx = @DllFileUnzipEx;
  26. (* Returns non-zero result on success. *)
  27. implementation
  28. uses
  29. {$IFDEF OS2}
  30. {$IFDEF FPC}
  31. DosCalls,
  32. {$ELSE FPC}
  33. {$IFDEF VirtualPascal}
  34. OS2Base,
  35. {$ELSE VirtualPascal}
  36. BseDos,
  37. {$ENDIF VirtualPascal}
  38. {$ENDIF FPC}
  39. {$ELSE}
  40. {$IFDEF WIN32}
  41. Windows,
  42. {$ENDIF WIN32}
  43. {$ENDIF OS2}
  44. Unzip, Dos;
  45. type
  46. UzpMainFunc = function (ArgC: longint; var ArgV: TArgV): longint; cdecl;
  47. const
  48. {$IFDEF OS2}
  49. AllFiles: string [1] = '*';
  50. {$ELSE}
  51. {$IFDEF WIN32}
  52. AllFiles: string [3] = '*.*';
  53. {$ENDIF}
  54. {$ENDIF}
  55. {$IFDEF OS2}
  56. LibPath = 'LIBPATH';
  57. {$ELSE}
  58. LibPath = 'PATH';
  59. {$ENDIF}
  60. UzpMainOrd = 4;
  61. DLLName: string [8] = 'UNZIP32'#0;
  62. UzpMain: UzpMainFunc = nil;
  63. QuiteOpt: array [1..4] of char = '-qq'#0;
  64. OverOpt: array [1..3] of char = '-o'#0;
  65. CaseInsOpt: array [1..3] of char = '-C'#0;
  66. ExDirOpt: array [1..3] of char = '-d'#0;
  67. OptCount = 4;
  68. var
  69. DLLHandle: longint;
  70. OldExit: pointer;
  71. C: char;
  72. function DLLInit: boolean;
  73. var
  74. {$IFDEF OS2}
  75. ErrPath: array [0..259] of char;
  76. {$ENDIF}
  77. DLLPath: PathStr;
  78. Dir: DirStr;
  79. Name: NameStr;
  80. Ext: ExtStr;
  81. begin
  82. DLLInit := false;
  83. FSplit (FExpand (ParamStr (0)), Dir, Name, Ext);
  84. DLLPath := Dir + DLLName;
  85. Insert ('.DLL', DLLPath, byte (DLLPath [0]));
  86. {$IFDEF OS2}
  87. if (DosLoadModule (@ErrPath, SizeOf (ErrPath), @DLLPath [1], DLLHandle) <> 0)
  88. and (DosLoadModule (@ErrPath, SizeOf (ErrPath), @DLLName [1], DLLHandle) <> 0)
  89. then
  90. begin
  91. if ErrPath [0] <> #0 then
  92. begin
  93. Write (#13#10'Error while loading module ');
  94. WriteLn (PChar (@ErrPath));
  95. end;
  96. {$IFDEF FPC}
  97. end else DLLInit := DosQueryProcAddr (DLLHandle, UzpMainOrd, nil, pointer (UzpMain)) = 0;
  98. {$ELSE}
  99. end else DLLInit := DosQueryProcAddr (DLLHandle, UzpMainOrd, nil, @UzpMain) = 0;
  100. {$ENDIF}
  101. {$ELSE}
  102. {$IFDEF WIN32}
  103. DLLHandle := LoadLibrary (@DLLPath [1]);
  104. if DLLHandle = 0 then DLLHandle := LoadLibrary (@DLLName [1]);
  105. if DLLHandle = 0 then WriteLn (#13#10'Error while loading DLL.') else
  106. begin
  107. (* UzpMain := UzpMainFunc (GetProcAddress (DLLHandle, 'UzpMain'));
  108. *)
  109. UzpMain := UzpMainFunc (GetProcAddress (DLLHandle, 'Unz_Unzip'));
  110. DLLInit := Assigned (UzpMain);
  111. end;
  112. {$ENDIF}
  113. {$ENDIF}
  114. end;
  115. procedure NewExit;
  116. begin
  117. ExitProc := OldExit;
  118. {$IFDEF OS2}
  119. DosFreeModule (DLLHandle);
  120. {$ELSE}
  121. {$IFDEF WIN32}
  122. FreeLibrary (DLLHandle);
  123. {$ENDIF}
  124. {$ENDIF}
  125. end;
  126. function DllFileUnzipEx (SourceZipFile, TargetDirectory,
  127. FileSpecs: PChar): integer;
  128. var
  129. I, FCount, ArgC: longint;
  130. ArgV: TArgV;
  131. P: PChar;
  132. StrLen: array [Succ (OptCount)..1024] of longint;
  133. begin
  134. ArgV [0] := @DLLName;
  135. ArgV [1] := @QuiteOpt;
  136. ArgV [2] := @OverOpt;
  137. ArgV [3] := @CaseInsOpt;
  138. ArgV [4] := SourceZipFile;
  139. FCount := 0;
  140. if FileSpecs^ <> #0 then
  141. begin
  142. P := FileSpecs;
  143. I := 0;
  144. repeat
  145. case FileSpecs^ of
  146. '"': begin
  147. Inc (FileSpecs);
  148. repeat Inc (I) until (FileSpecs^ = '"') or (FileSpecs^ = #0);
  149. Inc (FileSpecs);
  150. Inc (I);
  151. end;
  152. '''': begin
  153. Inc (FileSpecs);
  154. repeat Inc (I) until (FileSpecs^ = '''') or (FileSpecs^ = #0);
  155. Inc (FileSpecs);
  156. Inc (I);
  157. end;
  158. #0, ' ', #9: begin
  159. Inc (I);
  160. Inc (FCount);
  161. GetMem (ArgV [OptCount + FCount], I);
  162. Move (P^, ArgV [OptCount + FCount]^, Pred (I));
  163. PCharArray (ArgV [OptCount + FCount])^ [I] := #0;
  164. StrLen [OptCount + FCount] := I;
  165. while (FileSpecs^ = #9) or (FileSpecs^ = ' ') do Inc (FileSpecs);
  166. P := FileSpecs;
  167. I := 0;
  168. end;
  169. else
  170. begin
  171. Inc (I);
  172. Inc (FileSpecs);
  173. end;
  174. end;
  175. until (FileSpecs^ = #0) and (I = 0);
  176. end else
  177. begin
  178. FCount := 1;
  179. StrLen [OptCount + FCount] := Succ (byte (AllFiles [0]));
  180. GetMem (ArgV [OptCount + FCount], StrLen [OptCount + FCount]);
  181. Move (AllFiles [1], ArgV [OptCount + FCount]^, StrLen [OptCount + FCount]);
  182. end;
  183. ArgC := Succ (FCount + OptCount);
  184. ArgV [ArgC] := @ExDirOpt;
  185. Inc (ArgC);
  186. ArgV [ArgC] := TargetDirectory;
  187. Inc (ArgC);
  188. ArgV [ArgC] := @ExDirOpt [3]; (* contains #0 *)
  189. UnzipErr := UzpMain (ArgC, ArgV);
  190. if UnzipErr <> 0 then DllFileUnzipEx := 0 else DllFileUnzipEx := FCount;
  191. for I := 1 to FCount do FreeMem (ArgV [I + OptCount], StrLen [I + OptCount]);
  192. end;
  193. begin
  194. if DLLInit then
  195. begin
  196. OldExit := ExitProc;
  197. ExitProc := @NewExit;
  198. end else
  199. begin
  200. WriteLn (#13#10'Dynamic library UNZIP32.DLL from InfoZip is needed to install.');
  201. WriteLn ('This library could not be found on your system, however.');
  202. WriteLn ('Please, download the library, either from the location where you found');
  203. WriteLn ('this installer, or from any FTP archive carrying InfoZip programs.');
  204. WriteLn ('If you have this DLL on your disk, please, check your configuration (' + LIBPATH + ').');
  205. WriteLn (#13#10'If you want to try unpacking the files with internal unpacking routine,');
  206. WriteLn ('answer the following question with Y. However, this might not work correctly');
  207. WriteLn ('under some conditions (e.g. for long names and drives not supporting them).');
  208. Write (#13#10'Do you want to continue now (y/N)? ');
  209. ReadLn (C);
  210. if UpCase (C) = 'Y' then FileUnzipEx := TFileUnzipEx (@Unzip.FileUnzipEx) else Halt (255);
  211. end;
  212. end.
  213. {
  214. $Log$
  215. Revision 1.3 2000-11-26 19:02:19 hajny
  216. * little enhancement
  217. Revision 1.2 2000/10/18 20:14:32 hajny
  218. * FPC compatibility issues
  219. Revision 1.1 2000/07/13 06:30:22 michael
  220. + Initial import
  221. Revision 1.5 2000/06/18 18:27:32 hajny
  222. + archive validity checking, progress indicator, better error checking
  223. Revision 1.4 2000/06/13 16:21:36 hajny
  224. * Win32 support corrected/completed
  225. Revision 1.3 2000/03/05 17:57:08 hajny
  226. + added support for Win32 (untested)
  227. Revision 1.2 1999/06/10 07:28:29 hajny
  228. * compilable with TP again
  229. Revision 1.1 1999/02/19 16:45:26 peter
  230. * moved to fpinst/ directory
  231. + makefile
  232. }