Explorar o código

Add TExtractionWizardPage.AddEx. Todo: test & doc. Also some other minor tweaks.

Left the lack of password support as an internal implementation detail of Extract7ZipArchiveRedir.
Martijn Laan hai 3 meses
pai
achega
9f4ec000ec

+ 1 - 0
Projects/Src/Compiler.ScriptClasses.pas

@@ -567,6 +567,7 @@ begin
     RegisterProperty('AbortedByUser', 'Boolean', iptr);
     RegisterProperty('AbortedByUser', 'Boolean', iptr);
     RegisterProperty('ShowArchiveInsteadOfFile', 'Boolean', iptrw);
     RegisterProperty('ShowArchiveInsteadOfFile', 'Boolean', iptrw);
     RegisterMethod('procedure Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean)');
     RegisterMethod('procedure Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean)');
+    RegisterMethod('procedure AddEx(const ArchiveFileName, DestDir, Password: String; const FullPaths: Boolean)');
     RegisterMethod('procedure Clear');
     RegisterMethod('procedure Clear');
     RegisterMethod('procedure Extract');
     RegisterMethod('procedure Extract');
     RegisterMethod('procedure Show'); { Without this TOutputProgressWizardPage's Show will be called }
     RegisterMethod('procedure Show'); { Without this TOutputProgressWizardPage's Show will be called }

+ 8 - 3
Projects/Src/Compression.SevenZipDecoder.pas

@@ -16,7 +16,7 @@ type
   TOnExtractionProgress = function(const ArchiveName, FileName: string; const Progress, ProgressMax: Int64): Boolean of object;
   TOnExtractionProgress = function(const ArchiveName, FileName: string; const Progress, ProgressMax: Int64): Boolean of object;
 
 
 procedure Extract7ZipArchiveRedir(const DisableFsRedir: Boolean;
 procedure Extract7ZipArchiveRedir(const DisableFsRedir: Boolean;
-  const ArchiveFileName, DestDir: String; const FullPaths: Boolean;
+  const ArchiveFileName, DestDir, Password: String; const FullPaths: Boolean;
   const OnExtractionProgress: TOnExtractionProgress);
   const OnExtractionProgress: TOnExtractionProgress);
 
 
 implementation
 implementation
@@ -279,7 +279,7 @@ begin
 end;
 end;
 
 
 procedure Extract7ZipArchiveRedir(const DisableFsRedir: Boolean;
 procedure Extract7ZipArchiveRedir(const DisableFsRedir: Boolean;
-  const ArchiveFileName, DestDir: String; const FullPaths: Boolean;
+  const ArchiveFileName, DestDir, Password: String; const FullPaths: Boolean;
   const OnExtractionProgress: TOnExtractionProgress);
   const OnExtractionProgress: TOnExtractionProgress);
 begin
 begin
   if ArchiveFileName = '' then
   if ArchiveFileName = '' then
@@ -289,8 +289,13 @@ begin
 
 
   LogFmt('Extracting 7-Zip archive %s to %s. Full paths? %s', [ArchiveFileName, DestDir, SYesNo[FullPaths]]);
   LogFmt('Extracting 7-Zip archive %s to %s. Full paths? %s', [ArchiveFileName, DestDir, SYesNo[FullPaths]]);
 
 
-  if not ForceDirectories(DisableFsRedir, DestDir) then
+  if Password <> '' then begin
+    Log('ERROR: Password not supported by built-in extraction'); { Just like 7zMain.c }
+    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-2']))
+  end else if not ForceDirectories(DisableFsRedir, DestDir) then begin
+    Log('ERROR: Failed to create destination directory'); { Just like 7zMain.c }
     raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-1']));
     raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-1']));
+  end;
 
 
   State.DisableFsRedir := DisableFsRedir;
   State.DisableFsRedir := DisableFsRedir;
   State.ExpandedArchiveFileName := PathExpand(ArchiveFileName);
   State.ExpandedArchiveFileName := PathExpand(ArchiveFileName);

+ 29 - 26
Projects/Src/Compression.SevenZipDllDecoder.pas

@@ -371,31 +371,11 @@ begin
 end;
 end;
 
 
 function TArchiveExtractCallback.SetOperationResult(opRes: TNOperationResult): HRESULT;
 function TArchiveExtractCallback.SetOperationResult(opRes: TNOperationResult): HRESULT;
-
-  function OperationResultToString(const opRes: TNOperationResult): String;
-  begin
-    case opRes of
-      kOK: Result := 'OK';
-      kUnsupportedMethod: Result := 'Unsupported method';
-      kDataError: Result := 'Data error';
-      kCRCError: Result := 'CRC error';
-      kUnavailable: Result := 'Unavailable';
-      kUnexpectedEnd: Result := 'Unexpected end';
-      kDataAfterEnd: Result := 'Data after end';
-      kIsNotArc: Result := 'Is not an archive';
-      kHeadersError: Result := 'Headers error';
-      kWrongPassword: Result := 'Wrong password';
-    else
-      Result := Format('Unknown result %d', [Ord(opRes)]);
-    end;
-  end;
-
 begin
 begin
   { From IArchive.h: Can now can close the file, set attributes, timestamps and security information }
   { From IArchive.h: Can now can close the file, set attributes, timestamps and security information }
   try
   try
     if opRes <> kOK then begin
     if opRes <> kOK then begin
       FOpRes := opRes;
       FOpRes := opRes;
-      LogFmt('ERROR: %s', [OperationResultToString(opRes)]);  { Just like 7zMain.c }
       Result := E_FAIL;
       Result := E_FAIL;
     end else begin
     end else begin
       if (FCurrent.ExpandedPath <> '') and FCurrent.HasAttrib and
       if (FCurrent.ExpandedPath <> '') and FCurrent.HasAttrib and
@@ -487,6 +467,24 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
       InternalError('ExtractArchive: Unknown ArchiveFileName extension');
       InternalError('ExtractArchive: Unknown ArchiveFileName extension');
   end;
   end;
 
 
+  function OperationResultToString(const opRes: TNOperationResult): String;
+  begin
+    case opRes of
+      kOK: Result := 'OK';
+      kUnsupportedMethod: Result := 'Unsupported method';
+      kDataError: Result := 'Data error';
+      kCRCError: Result := 'CRC error';
+      kUnavailable: Result := 'Unavailable';
+      kUnexpectedEnd: Result := 'Unexpected end';
+      kDataAfterEnd: Result := 'Data after end';
+      kIsNotArc: Result := 'Is not an archive';
+      kHeadersError: Result := 'Headers error';
+      kWrongPassword: Result := 'Wrong password';
+    else
+      Result := Format('Unknown result %d', [Ord(opRes)]);
+    end;
+  end;
+
 begin
 begin
   if not IsExtractArchiveRedirAvailable then
   if not IsExtractArchiveRedirAvailable then
     InternalError('ExtractArchive: 7z(xa).dll not loaded');
     InternalError('ExtractArchive: 7z(xa).dll not loaded');
@@ -500,16 +498,20 @@ begin
 
 
   { CreateObject }
   { CreateObject }
   var InArchive: IInArchive;
   var InArchive: IInArchive;
-  if CreateSevenZipObject(clsid, IInArchive, InArchive) <> S_OK then
-    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['Cannot get class object'])); { From Client7z.cpp }
+  if CreateSevenZipObject(clsid, IInArchive, InArchive) <> S_OK then begin
+    Log('ERROR: Cannot get class object'); { Just like 7zMain.c and Client7z.cpp }
+    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-1']));
+  end;
 
 
   { Open }
   { Open }
   const InStream: IInStream =
   const InStream: IInStream =
     TInStream.Create(TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead));
     TInStream.Create(TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead));
   var ScanSize: Int64 := 1 shl 23; { From Client7z.cpp }
   var ScanSize: Int64 := 1 shl 23; { From Client7z.cpp }
   const OpenCallback: IArchiveOpenCallback = TArchiveOpenCallback.Create(Password);
   const OpenCallback: IArchiveOpenCallback = TArchiveOpenCallback.Create(Password);
-  if InArchive.Open(InStream, @ScanSize, OpenCallback) <> S_OK then
-    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['Cannot open file as archive'])); { From Client7z.cpp }
+  if InArchive.Open(InStream, @ScanSize, OpenCallback) <> S_OK then begin
+    Log('ERROR: Cannot open file as archive'); { Just like 7zMain.c and Client7z.cpp }
+    raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, ['-2']));
+  end;
 
 
   { Extract }
   { Extract }
   const ExtractCallback: IArchiveExtractCallback =
   const ExtractCallback: IArchiveExtractCallback =
@@ -520,9 +522,10 @@ begin
     raise Exception.Create(SetupMessages[msgErrorExtractionAborted])
     raise Exception.Create(SetupMessages[msgErrorExtractionAborted])
   else begin
   else begin
     var OpRes := (ExtractCallback as TArchiveExtractCallback).OpRes;
     var OpRes := (ExtractCallback as TArchiveExtractCallback).OpRes;
-    if OpRes <> kOK then
+    if OpRes <> kOK then begin
+      LogFmt('ERROR: %s', [OperationResultToString(opRes)]); { Just like 7zMain.c }
       raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Ord(OpRes).ToString]))
       raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Ord(OpRes).ToString]))
-    else if Res <> S_OK then
+    end else if Res <> S_OK then
       raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Format('%s %s', [Win32ErrorString(Res), IntToHexStr8(Res)])]));
       raise Exception.Create(FmtSetupMessage(msgErrorExtractionFailed, [Format('%s %s', [Win32ErrorString(Res), IntToHexStr8(Res)])]));
   end;
   end;
 
 

+ 11 - 4
Projects/Src/Setup.ScriptDlg.pas

@@ -204,7 +204,7 @@ type
   end;
   end;
   
   
   TArchive = class
   TArchive = class
-    FileName, DestDir: String;
+    FileName, DestDir, Password: String;
     FullPaths: Boolean;
     FullPaths: Boolean;
   end;
   end;
   TArchives = TObjectList<TArchive>;
   TArchives = TObjectList<TArchive>;
@@ -224,6 +224,7 @@ type
       destructor Destroy; override;
       destructor Destroy; override;
       procedure Initialize; override;
       procedure Initialize; override;
       procedure Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
       procedure Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
+      procedure AddEx(const ArchiveFileName, DestDir, Password: String; const FullPaths: Boolean);
       procedure Clear;
       procedure Clear;
       procedure Extract;
       procedure Extract;
       property OnExtractionProgress: TOnExtractionProgress write FOnExtractionProgress;
       property OnExtractionProgress: TOnExtractionProgress write FOnExtractionProgress;
@@ -1167,9 +1168,15 @@ end;
 
 
 procedure TExtractionWizardPage.Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
 procedure TExtractionWizardPage.Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
 begin
 begin
-  var A := TArchive.Create;
+  AddEx(ArchiveFileName, DestDir, '', FullPaths);
+end;
+
+procedure TExtractionWizardPage.AddEx(const ArchiveFileName, DestDir, Password: String; const FullPaths: Boolean);
+begin
+  const A = TArchive.Create;
   A.FileName := ArchiveFileName;
   A.FileName := ArchiveFileName;
   A.DestDir := DestDir;
   A.DestDir := DestDir;
+  A.Password := Password;
   A.FullPaths := FullPaths;
   A.FullPaths := FullPaths;
   FArchives.Add(A);
   FArchives.Add(A);
 end;
 end;
@@ -1192,9 +1199,9 @@ begin
   for var A in FArchives do begin
   for var A in FArchives do begin
     { Don't need to set DownloadTemporaryFileOrExtractArchiveProcessMessages before extraction since we already process messages ourselves }
     { Don't need to set DownloadTemporaryFileOrExtractArchiveProcessMessages before extraction since we already process messages ourselves }
     if ExtractArchiveRedirAvailable then
     if ExtractArchiveRedirAvailable then
-      ExtractArchiveRedir(ScriptFuncDisableFsRedir, A.FileName, A.DestDir, '', A.FullPaths, InternalOnExtractionProgress)
+      ExtractArchiveRedir(ScriptFuncDisableFsRedir, A.FileName, A.DestDir, A.Password, A.FullPaths, InternalOnExtractionProgress)
     else
     else
-      Extract7ZipArchiveRedir(ScriptFuncDisableFsRedir, A.FileName, A.DestDir, A.FullPaths, InternalOnExtractionProgress);
+      Extract7ZipArchiveRedir(ScriptFuncDisableFsRedir, A.FileName, A.DestDir, A.Password, A.FullPaths, InternalOnExtractionProgress);
   end;
   end;
 end;
 end;
 
 

+ 1 - 1
Projects/Src/Setup.ScriptFunc.pas

@@ -1786,7 +1786,7 @@ var
     end);
     end);
     RegisterScriptFunc('EXTRACT7ZIPARCHIVE', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
     RegisterScriptFunc('EXTRACT7ZIPARCHIVE', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
     begin
     begin
-      Extract7ZipArchiveRedir(ScriptFuncDisableFsRedir, Stack.GetString(PStart), Stack.GetString(PStart-1), Stack.GetBool(PStart-2), TOnExtractionProgress(Stack.GetProc(PStart-3, Caller)));
+      Extract7ZipArchiveRedir(ScriptFuncDisableFsRedir, Stack.GetString(PStart), Stack.GetString(PStart-1), '', Stack.GetBool(PStart-2), TOnExtractionProgress(Stack.GetProc(PStart-3, Caller)));
     end);
     end);
     RegisterScriptFunc('INIT7ZIPLIBRARY', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
     RegisterScriptFunc('INIT7ZIPLIBRARY', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
     begin
     begin