|
@@ -86,7 +86,6 @@ type
|
|
TProgress = record
|
|
TProgress = record
|
|
Current: TCurrent;
|
|
Current: TCurrent;
|
|
Progress, ProgressMax: UInt64;
|
|
Progress, ProgressMax: UInt64;
|
|
- Abort: Boolean;
|
|
|
|
end;
|
|
end;
|
|
TResult = record
|
|
TResult = record
|
|
SavedFatalException: TObject;
|
|
SavedFatalException: TObject;
|
|
@@ -104,6 +103,7 @@ type
|
|
FProgressAndLogQueueLock: TObject;
|
|
FProgressAndLogQueueLock: TObject;
|
|
FProgress: TProgress;
|
|
FProgress: TProgress;
|
|
FLogQueue: TStrings;
|
|
FLogQueue: TStrings;
|
|
|
|
+ FAbort: Boolean;
|
|
FResult: TResult;
|
|
FResult: TResult;
|
|
function GetProperty(const index: UInt32; const propID: PROPID;
|
|
function GetProperty(const index: UInt32; const propID: PROPID;
|
|
const allowedTypes: TVarTypeSet; out value: OleVariant): Boolean; overload;
|
|
const allowedTypes: TVarTypeSet; out value: OleVariant): Boolean; overload;
|
|
@@ -311,10 +311,11 @@ end;
|
|
function TArchiveExtractCallback.SetCompleted(completeValue: PUInt64): HRESULT;
|
|
function TArchiveExtractCallback.SetCompleted(completeValue: PUInt64): HRESULT;
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
|
|
+ if FAbort then
|
|
|
|
+ SysUtils.Abort;
|
|
|
|
+
|
|
System.TMonitor.Enter(FProgressAndLogQueueLock);
|
|
System.TMonitor.Enter(FProgressAndLogQueueLock);
|
|
try
|
|
try
|
|
- if FProgress.Abort then
|
|
|
|
- SysUtils.Abort;
|
|
|
|
FProgress.Progress := completeValue^;
|
|
FProgress.Progress := completeValue^;
|
|
finally
|
|
finally
|
|
System.TMonitor.Exit(FProgressAndLogQueueLock);
|
|
System.TMonitor.Exit(FProgressAndLogQueueLock);
|
|
@@ -380,6 +381,9 @@ function TArchiveExtractCallback.GetStream(index: UInt32;
|
|
out outStream: ISequentialOutStream; askExtractMode: Int32): HRESULT;
|
|
out outStream: ISequentialOutStream; askExtractMode: Int32): HRESULT;
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
|
|
+ if FAbort then
|
|
|
|
+ SysUtils.Abort;
|
|
|
|
+
|
|
var NewCurrent := Default(TCurrent);
|
|
var NewCurrent := Default(TCurrent);
|
|
if askExtractMode = kExtract then begin
|
|
if askExtractMode = kExtract then begin
|
|
var Path: String;
|
|
var Path: String;
|
|
@@ -421,8 +425,6 @@ begin
|
|
end;
|
|
end;
|
|
System.TMonitor.Enter(FProgressAndLogQueueLock);
|
|
System.TMonitor.Enter(FProgressAndLogQueueLock);
|
|
try
|
|
try
|
|
- if FProgress.Abort then
|
|
|
|
- SysUtils.Abort;
|
|
|
|
FProgress.Current := NewCurrent;
|
|
FProgress.Current := NewCurrent;
|
|
if NewCurrent.Path <> '' then
|
|
if NewCurrent.Path <> '' then
|
|
FLogQueue.Append(NewCurrent.Path)
|
|
FLogQueue.Append(NewCurrent.Path)
|
|
@@ -571,11 +573,14 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
|
|
|
|
|
|
procedure HandleProgress(const E: TArchiveExtractCallback);
|
|
procedure HandleProgress(const E: TArchiveExtractCallback);
|
|
begin
|
|
begin
|
|
- var Progress: TArchiveExtractCallback.TProgress;
|
|
|
|
|
|
+ var CurrentPath: String;
|
|
|
|
+ var Progress, ProgressMax: UInt64;
|
|
|
|
|
|
System.TMonitor.Enter(E.FProgressAndLogQueueLock);
|
|
System.TMonitor.Enter(E.FProgressAndLogQueueLock);
|
|
try
|
|
try
|
|
- Progress := E.FProgress;
|
|
|
|
|
|
+ CurrentPath := E.FProgress.Current.Path;
|
|
|
|
+ Progress := E.FProgress.Progress;
|
|
|
|
+ ProgressMax := E.FProgress.ProgressMax;
|
|
for var S in E.FLogQueue do
|
|
for var S in E.FLogQueue do
|
|
LogFmt('- %s', [S]); { Just like 7zMain.c }
|
|
LogFmt('- %s', [S]); { Just like 7zMain.c }
|
|
E.FLogQueue.Clear;
|
|
E.FLogQueue.Clear;
|
|
@@ -583,29 +588,22 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
|
|
System.TMonitor.Exit(E.FProgressAndLogQueueLock);
|
|
System.TMonitor.Exit(E.FProgressAndLogQueueLock);
|
|
end;
|
|
end;
|
|
|
|
|
|
- if Progress.Abort then
|
|
|
|
|
|
+ var Abort := E.FAbort;
|
|
|
|
+ if Abort then
|
|
Exit;
|
|
Exit;
|
|
|
|
|
|
- var Abort := False;
|
|
|
|
-
|
|
|
|
- if (Progress.Current.Path <> '') and Assigned(E.FOnExtractionProgress) then begin
|
|
|
|
|
|
+ if (CurrentPath <> '') and Assigned(E.FOnExtractionProgress) then begin
|
|
{ Calls to HandleProgress are already throttled so here we don't have to worry
|
|
{ Calls to HandleProgress are already throttled so here we don't have to worry
|
|
about calling the script to often }
|
|
about calling the script to often }
|
|
- if not E.FOnExtractionProgress(E.FExtractedArchiveName, Progress.Current.Path, Progress.Progress, Progress.ProgressMax) then
|
|
|
|
|
|
+ if not E.FOnExtractionProgress(E.FExtractedArchiveName, CurrentPath, Progress, ProgressMax) then
|
|
Abort := True;
|
|
Abort := True;
|
|
end;
|
|
end;
|
|
|
|
|
|
if not Abort and DownloadTemporaryFileOrExtractArchiveProcessMessages then
|
|
if not Abort and DownloadTemporaryFileOrExtractArchiveProcessMessages then
|
|
Application.ProcessMessages;
|
|
Application.ProcessMessages;
|
|
|
|
|
|
- if Abort then begin
|
|
|
|
- System.TMonitor.Enter(E.FProgressAndLogQueueLock);
|
|
|
|
- try
|
|
|
|
- E.FProgress.Abort := True;
|
|
|
|
- finally
|
|
|
|
- System.TMonitor.Exit(E.FProgressAndLogQueueLock);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
|
|
+ if Abort then
|
|
|
|
+ E.FAbort := Abort; { Atomic so no lock }
|
|
end;
|
|
end;
|
|
|
|
|
|
function OperationResultToString(const opRes: TNOperationResult): String;
|
|
function OperationResultToString(const opRes: TNOperationResult): String;
|
|
@@ -681,7 +679,7 @@ procedure ExtractArchiveRedir(const DisableFsRedir: Boolean;
|
|
object. Leaking memory isn't ideal, but a use-after-free problem
|
|
object. Leaking memory isn't ideal, but a use-after-free problem
|
|
is worse. Realisitically, though, WaitForSingleObject should never
|
|
is worse. Realisitically, though, WaitForSingleObject should never
|
|
fail if given a valid handle. }
|
|
fail if given a valid handle. }
|
|
- E.FProgress.Abort := True;
|
|
|
|
|
|
+ E.FAbort := True; { Atomic so no lock }
|
|
if WaitForSingleObject(ThreadHandle, INFINITE) <> WAIT_OBJECT_0 then
|
|
if WaitForSingleObject(ThreadHandle, INFINITE) <> WAIT_OBJECT_0 then
|
|
E._AddRef;
|
|
E._AddRef;
|
|
raise;
|
|
raise;
|