Compression.SevenZipDecoder.pas 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. unit Compression.SevenZipDecoder;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2024 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Interface to the 7-Zip Decoder OBJ in Compression.SevenZipDecoder\7ZipDecode,
  8. used by Setup.
  9. }
  10. interface
  11. procedure SevenZipDecode(const FileName, DestDir: String;
  12. const FullPaths: Boolean);
  13. implementation
  14. uses
  15. Windows, SysUtils, Setup.LoggingFunc;
  16. { Compiled by Visual Studio 2022 using compile.bat
  17. To enable source debugging recompile using compile-bcc32c.bat and turn off the VISUALSTUDIO define below
  18. Note that in a speed test the code produced by bcc32c was about 33% slower }
  19. {$L Src\Compression.SevenZipDecoder\7zDecode\IS7zDec.obj}
  20. {$DEFINE VISUALSTUDIO}
  21. function IS_7zDec(const fileName: PChar; const fullPaths: Bool): Integer; cdecl; external name '_IS_7zDec';
  22. {$IFDEF VISUALSTUDIO}
  23. function __CreateDirectoryW(lpPathName: LPCWSTR;
  24. lpSecurityAttributes: PSecurityAttributes): BOOL; cdecl;
  25. begin
  26. Result := CreateDirectoryW(lpPathName, lpSecurityAttributes);
  27. end;
  28. { Never actually called but still required by the linker }
  29. function __CreateFileA(lpFileName: LPCSTR; dwDesiredAccess, dwShareMode: DWORD;
  30. lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
  31. hTemplateFile: THandle): THandle; cdecl;
  32. begin
  33. Result := CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  34. end;
  35. function __CreateFileW(lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD;
  36. lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD;
  37. hTemplateFile: THandle): THandle; cdecl;
  38. begin
  39. Result := CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  40. end;
  41. function __FileTimeToLocalFileTime(lpFileTime: PFileTime; var lpLocalFileTime: TFileTime): BOOL; cdecl;
  42. begin
  43. Result := FileTimeToLocalFileTime(lpFileTime, lpLocalFileTime);
  44. end;
  45. { Never actually called but still required by the linker }
  46. function __GetFileSize(hFile: THandle; lpFileSizeHigh: Pointer): DWORD; cdecl;
  47. begin
  48. Result := GetFileSize(hFile, lpFileSizeHigh);
  49. end;
  50. function __ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD;
  51. var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; cdecl;
  52. begin
  53. Result := ReadFile(hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  54. end;
  55. function __SetFileAttributesW(lpFileName: LPCWSTR; dwFileAttributes: DWORD): BOOL; cdecl;
  56. begin
  57. Result := SetFileAttributesW(lpFileName, dwFileAttributes);
  58. end;
  59. function __SetFilePointer(hFile: THandle; lDistanceToMove: Longint;
  60. lpDistanceToMoveHigh: Pointer; dwMoveMethod: DWORD): DWORD; cdecl;
  61. begin
  62. Result := SetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod);
  63. end;
  64. function __SetFileTime(hFile: THandle;
  65. lpCreationTime, lpLastAccessTime, lpLastWriteTime: PFileTime): BOOL; cdecl;
  66. begin
  67. Result := SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
  68. end;
  69. function __WriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD;
  70. var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; cdecl;
  71. begin
  72. Result := WriteFile(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  73. end;
  74. function __CloseHandle(hObject: THandle): BOOL; cdecl;
  75. begin
  76. Result := CloseHandle(hObject);
  77. end;
  78. function __GetLastError: DWORD; cdecl;
  79. begin
  80. Result := GetLastError;
  81. end;
  82. function __LocalFree(hMem: HLOCAL): HLOCAL; cdecl;
  83. begin
  84. Result := LocalFree(hMem);
  85. end;
  86. function __FormatMessageA(dwFlags: DWORD; lpSource: Pointer; dwMessageId: DWORD; dwLanguageId: DWORD;
  87. lpBuffer: LPSTR; nSize: DWORD; Arguments: Pointer): DWORD; cdecl;
  88. begin
  89. Result := FormatMessageA(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
  90. end;
  91. function __WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD;
  92. lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR;
  93. cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer; cdecl;
  94. begin
  95. Result := WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cchMultiByte, lpDefaultChar, lpUsedDefaultChar);
  96. end;
  97. //https://github.com/rust-lang/compiler-builtins/issues/403
  98. procedure __allshl; register; external 'ntdll.dll' name '_allshl';
  99. procedure __aullshr; register; external 'ntdll.dll' name '_aullshr';
  100. {$ELSE}
  101. procedure __aullrem; stdcall; external 'ntdll.dll' name '_aullrem';
  102. procedure __aulldiv; stdcall; external 'ntdll.dll' name '_aulldiv';
  103. {$ENDIF}
  104. function _memcpy(dest, src: Pointer; n: Cardinal): Pointer; cdecl;
  105. begin
  106. Move(src^, dest^, n);
  107. Result := dest;
  108. end;
  109. function _memset(dest: Pointer; c: Integer; n: Cardinal): Pointer; cdecl;
  110. begin
  111. FillChar(dest^, n, c);
  112. Result := dest;
  113. end;
  114. function _malloc(size: Cardinal): Pointer; cdecl;
  115. begin
  116. if size <> 0 then
  117. Result := VirtualAlloc(nil, size, MEM_COMMIT, PAGE_READWRITE)
  118. else
  119. Result := nil;
  120. end;
  121. procedure _free(address: Pointer); cdecl;
  122. begin
  123. if Assigned(address) then
  124. VirtualFree(address, 0, MEM_RELEASE);
  125. end;
  126. function _wcscmp(string1, string2: PChar): Integer; cdecl;
  127. begin
  128. Result := StrComp(string1, string2);
  129. end;
  130. function __fputs(str: PAnsiChar; unused: Pointer): Integer; cdecl;
  131. begin
  132. Log(UTF8ToString(str));
  133. Result := 1;
  134. end;
  135. procedure SevenZipDecode(const FileName, DestDir: String;
  136. const FullPaths: Boolean);
  137. begin
  138. var SaveCurDir := GetCurrentDir;
  139. SetCurrentDir(DestDir);
  140. IS_7zDec(PChar(FileName), FullPaths);
  141. SetCurrentDir(SaveCurDir);
  142. end;
  143. end.