From 0f7616a007edaa1d19c4672a4fd390c072b1eba6 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 13 Dec 2009 14:32:58 +0100 Subject: Error system transformation to GError Note that most coreworkers are broken at the moment. --- UCoreWorkers.pas | 406 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 242 insertions(+), 164 deletions(-) (limited to 'UCoreWorkers.pas') diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas index 6eabc1e..72dd60f 100644 --- a/UCoreWorkers.pas +++ b/UCoreWorkers.pas @@ -26,6 +26,7 @@ type TVFSCallbackThread = class(TThread) private FThreadID: __pthread_t; FCopyProgressFunc: TEngineProgressFunc; + // * TODO: move to Create() ? procedure PrepareExecute; // Call this right after thread has been started public AEngine: TPanelEngine; @@ -143,7 +144,7 @@ type TVFSCallbackThread = class(TThread) TOpenDirThread = class(TVFSCallbackThread) private - function ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): integer; + function ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): boolean; protected procedure Execute; override; public @@ -151,10 +152,11 @@ type TVFSCallbackThread = class(TThread) ASelItem: string; AAutoFallBack: boolean; ADirList: TList; - ChDirResult, ListingResult, VFSOpenResult: integer; Finished, CancelIt: boolean; RunningTime: Int64; AFullPath, AHighlightItem: string; + ChDirResult, ListingResult, VFSOpenResult: boolean; + ChDirError, ListingError, VFSOpenError: PGError; constructor Create; destructor Destroy; override; end; @@ -167,6 +169,7 @@ type TVFSCallbackThread = class(TThread) URI: string; Finished: boolean; OpenResult: boolean; + OpenError: PGError; constructor Create; destructor Destroy; override; end; @@ -349,16 +352,17 @@ begin password_save^ := VFS_PASSWORD_SAVE_NEVER; end; -function vfs_progress_callback(position, max: guint64; user_data: Pointer): gboolean; cdecl; +// Keep in sync with uVFSprototypes.pas/TVFSProgressCallback +function vfs_copy_progress_callback(position: guint64; error: PGError; user_data: Pointer): gboolean; cdecl; begin // DebugMsg(['VFSCopyCallBackFunc called (iPos = ', iPos, ', iMax = ', iMax, ')']); Result := True; if not Assigned(user_data) then Exit; if Assigned(TVFSCallbackThread(user_data).FCopyProgressFunc) then try - Result := TVFSCallbackThread(user_data).FCopyProgressFunc(user_data, position); + Result := TVFSCallbackThread(user_data).FCopyProgressFunc(user_data, position, error); except - on E: Exception do DebugMsg(['*** Exception raised in vfs_progress_callback(position=', position, ', max=', max, ', user_data=', user_data, '): (', E.ClassName, '): ', E.Message]); + on E: Exception do DebugMsg(['*** Exception raised in vfs_copy_progress_callback(position=', position, ', user_data=', user_data, '): (', E.ClassName, '): ', E.Message]); end; end; @@ -729,19 +733,23 @@ end; procedure DeleteFilesWorker(SenderThread: TWorkerThread); var SkipAll: boolean; + // Return False to break the operation function HandleDelete(AFileRec: PDataItemSL): boolean; - var Res, Response: integer; + var Response: integer; + Res: boolean; + Error: PGError; begin Result := True; + Error := nil; // DebugMsg(['Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); if AFileRec^.DataItem^.IsDir and AFileRec^.Stage1 and (not AFileRec^.DataItem^.IsLnk) then Exit; - Res := SenderThread.Engine.Remove(String(AFileRec^.DataItem^.FName)); + Res := SenderThread.Engine.Remove(String(AFileRec^.DataItem^.FName), @Error); // DebugMsg(['Result : ', Res]); - if Res <> 0 then + if not Res then if SkipAll then Result := True else begin Response := SenderThread.ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), - Format(LANGCouldNotBeDeletedS, [GetErrorString(Res)])); + Format(LANGCouldNotBeDeletedS, [Error^.message])); case Response of 1 : Result := True; 3 : begin @@ -752,6 +760,8 @@ var SkipAll: boolean; else Result := False; end; end; + if Error <> nil then + g_error_free(Error); end; var i: longint; @@ -766,7 +776,9 @@ begin with SenderThread do begin CurrPath := IncludeTrailingPathDelimiter(Engine.Path); PrepareJobFilesFromPanel(AList, False); - if Engine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); + // * TODO: catch the error + if not Engine.ChangeDir(CurrPath, nil) then + DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); libc_chdir('/'); SetProgress1Params(AList.Count); @@ -814,7 +826,9 @@ begin for i := AList.Count - 1 downto 0 do FreeDataItem(PDataItemSL(AList[i])); AList.Clear; AList.Free; - if Engine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); + // * TODO: catch the error + if not Engine.ChangeDir(CurrPath, nil) then + DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); end; SenderThread.FDoneThread := True; end; @@ -825,8 +839,8 @@ end; (********************************************************************************************************************************) (********************************************************************************************************************************) - // Return False to break the process - function CopyFilesWorker_ProgressFunc(Sender: Pointer; BytesDone: Int64): boolean; cdecl; + // Keep in sync with UEngines.pas/TEngineProgressFunc + function CopyFilesWorker_ProgressFunc(Sender: Pointer; BytesDone: Int64; Error: PGError): boolean; cdecl; begin Result := True; // DebugMsg(['*** CopyFilesWorker: ProgressFunc called (Sender=', QWord(Sender), ', BytesDone=', BytesDone, ')']); @@ -872,7 +886,8 @@ end; if ErrorType <> 1 then s3 := StrToUTF8(FileName) else s3 := ''; - case ShowDirDeleteDialog(3, s, s3, GetErrorString(ErrorNum), s2) of + // * TODO: fix error string + case ShowDirDeleteDialog(3, s, s3, 'ahoj' { GetErrorString(ErrorNum)} , s2) of 0, 252 : begin // Cancel button, Escape Result := False; CancelIt; @@ -908,25 +923,28 @@ var DefResponse: integer; // Global variables for this function // Returns True if file was successfully copied, if not, the file will be deleted in LocalCopyFile function ManualCopyFile(SourceFile, DestFile: string; Append: boolean): boolean; var fsrc, fdst: TEngineFileDes; - Error, BSize: integer; + BSize: integer; Buffer: Pointer; BytesDone, BytesRead, BytesWritten: Int64; Res: boolean; + Error: PGError; begin DebugMsg(['ManualCopyFile: ', SourceFile, ' ---> ', DestFile]); with SenderThread do begin Result := False; - Error := 0; - fsrc := SrcEngine.OpenFile(SourceFile, omRead, Error); - if Error <> 0 then begin - CopyFilesWorker_ErrorFunc(SenderThread, 2, Error, SourceFile); // Cannot open source file + Error := nil; + fsrc := SrcEngine.OpenFile(SourceFile, omRead, @Error); + if fsrc = nil then begin + // * TODO: set real error, also free it + CopyFilesWorker_ErrorFunc(SenderThread, 2, 1 { Error }, SourceFile); // Cannot open source file Exit; end; - if Append then fdst := DestEngine.OpenFile(DestFile, omAppend, Error) - else fdst := DestEngine.OpenFile(DestFile, omWrite, Error); - if Error <> 0 then begin - SrcEngine.CloseFile(fsrc); - CopyFilesWorker_ErrorFunc(SenderThread, 3, Error, SourceFile); // Cannot open target file + if Append then fdst := DestEngine.OpenFile(DestFile, omAppend, @Error) + else fdst := DestEngine.OpenFile(DestFile, omWrite, @Error); + if fdst = nil then begin + // * TODO: set real error, also free it + SrcEngine.CloseFile(fsrc, nil); + CopyFilesWorker_ErrorFunc(SenderThread, 3, 1 { Error }, SourceFile); // Cannot open target file Exit; end; @@ -944,27 +962,32 @@ var DefResponse: integer; // Global variables for this function BytesWritten := 0; repeat - BytesRead := SrcEngine.ReadFile(fsrc, Buffer, BSize, Error); - if (BytesRead = 0) and (Error <> 0) then - Res := CopyFilesWorker_ErrorFunc(SenderThread, 6, Error, SourceFile); // Cannot read from source file + BytesRead := SrcEngine.ReadFile(fsrc, Buffer, BSize, @Error); + if (BytesRead = 0) and (Error <> nil) then + // * TODO: set real error, also free it + Res := CopyFilesWorker_ErrorFunc(SenderThread, 6, 1 { Error }, SourceFile); // Cannot read from source file if BytesRead > 0 then begin - BytesWritten := DestEngine.WriteFile(fdst, Buffer, BytesRead, Error); + Error := nil; + BytesWritten := DestEngine.WriteFile(fdst, Buffer, BytesRead, @Error); if (BytesWritten < BytesRead) then - Res := CopyFilesWorker_ErrorFunc(SenderThread, 7, Error, DestFile); // Cannot write to source file + // * TODO: set real error, also free it + Res := CopyFilesWorker_ErrorFunc(SenderThread, 7, 1 { Error }, DestFile); // Cannot write to source file end; Inc(BytesDone, BytesRead); - if not CopyFilesWorker_ProgressFunc(SenderThread, BytesDone) then begin + if not CopyFilesWorker_ProgressFunc(SenderThread, BytesDone, nil) then begin Res := False; Break; end; until (BytesRead = 0) or (BytesWritten < BytesRead); libc_free(Buffer); - if DestEngine.CloseFile(fdst) <> 0 then begin + // * TODO: set real error, also free it + if not DestEngine.CloseFile(fdst, nil) then begin CopyFilesWorker_ErrorFunc(SenderThread, 4, errno, DestFile); // Cannot close target file Exit; end; - if SrcEngine.CloseFile(fsrc) <> 0 then begin + // * TODO: set real error, also free it + if not SrcEngine.CloseFile(fsrc, nil) then begin CopyFilesWorker_ErrorFunc(SenderThread, 5, errno, SourceFile); // Cannot close source file Exit; end; @@ -984,21 +1007,21 @@ var DefResponse: integer; // Global variables for this function // local -> local if (SrcEngine is TLocalTreeEngine) and (DestEngine is TLocalTreeEngine) - then Result := DestEngine.CopyFileIn(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ProgressFunc, @CopyFilesWorker_ErrorFunc, Append) + then Result := DestEngine.CopyFileIn(SourceFile, DestFile, Append, @CopyFilesWorker_ProgressFunc, SenderThread) else // from local engine to VFS engine if (SrcEngine is TLocalTreeEngine) and (DestEngine is TVFSEngine) then begin AEngine := DestEngine; - Result := (DestEngine as TVFSEngine).CopyFileInEx(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ErrorFunc, Append); + Result := (DestEngine as TVFSEngine).CopyFileInEx(SourceFile, DestFile, Append); end else // from VFS engine to local (most common use) if (SrcEngine is TVFSEngine) and (DestEngine is TLocalTreeEngine) then begin AEngine := SrcEngine; - Result := (SrcEngine as TVFSEngine).CopyFileOutEx(SenderThread, SourceFile, DestFile, @CopyFilesWorker_ErrorFunc, Append); + Result := (SrcEngine as TVFSEngine).CopyFileOutEx(SourceFile, DestFile, Append); end // VFS to VFS (not supported yet) @@ -1011,11 +1034,14 @@ var DefResponse: integer; // Global variables for this function // Copy OK? (check size, otherwise delete target file) if (not Append) and (not Result) then begin - DataSrc := SrcEngine.GetFileInfo(SourceFile, False, True); + // * TODO: check error + DataSrc := SrcEngine.GetFileInfo(SourceFile, False, True, nil); if DataSrc = nil then Exit; - DataDest := DestEngine.GetFileInfo(DestFile, False, True); + // * TODO: check error + DataDest := DestEngine.GetFileInfo(DestFile, False, True, nil); if (DataDest <> nil) and (DataSrc^.Size <> DataDest^.Size) then - DestEngine.Remove(DestFile); + // * TODO: check error + DestEngine.Remove(DestFile, nil); FreeDataItem(DataSrc); FreeDataItem(DataDest); end; @@ -1066,41 +1092,47 @@ var DefResponse: integer; // Global variables for this function if DataItem^.IsLnk then begin // Explicit copy the file if ParamBool3 or (not IsOnSameFS(String(DataItem^.FName), ExtractFileDir(Dst))) then begin - ErrorKind := DestEngine.MakeSymLink(Dst, String(DataItem^.LnkPointTo)); - if ErrorKind <> 0 then Result := ERRCreateLink; + // * TODO: check error + ErrorKind := Ord(DestEngine.MakeSymLink(Dst, String(DataItem^.LnkPointTo), nil)); +// if ErrorKind <> 0 then Result := ERRCreateLink; if not ParamBool3 then begin - ErrorKind := SrcEngine.Remove(String(DataItem^.FName)); - if ErrorKind <> 0 then Result := ERRRemove; + // * TODO: check error + ErrorKind := Ord(SrcEngine.Remove(String(DataItem^.FName), nil)); +// if ErrorKind <> 0 then Result := ERRRemove; end; end else begin // Move the file - ErrorKind := DestEngine.RenameFile(String(DataItem^.FName), Dst); - if ErrorKind <> 0 then Result := ERRCopyMove; + // * TODO: check error + ErrorKind := Ord(DestEngine.RenameFile(String(DataItem^.FName), Dst, nil)); +// if ErrorKind <> 0 then Result := ERRCopyMove; end; end else // is not link if ParamBool3 then begin // Copy mode if LocalCopyFile(String(DataItem^.FName), Dst, Append) then begin if IsOnRO and ConfClearReadOnlyAttr and (DataItem^.Mode and S_IWUSR = 0) then DataItem^.Mode := DataItem^.Mode or S_IWUSR; - DestEngine.Chmod(Dst, DataItem^.Mode); - DestEngine.Chown(Dst, DataItem^.UID, DataItem^.GID); - DestEngine.ChangeTimes(Dst, DataItem^.mtime, DataItem^.atime); + // * TODO: check error + DestEngine.Chmod(Dst, DataItem^.Mode, nil); + DestEngine.Chown(Dst, DataItem^.UID, DataItem^.GID, nil); + DestEngine.ChangeTimes(Dst, DataItem^.mtime, DataItem^.atime, nil); end; end else // Move mode if IsOnSameFS(String(DataItem^.FName), ExtractFileDir(Dst)) then begin if TwoSameFiles(String(DataItem^.FName), Dst, True) and (not TwoSameFiles(String(DataItem^.FName), Dst, False)) then begin DebugMsg(['*** Activating double-rename due to renaming on case-insensitive FS']); - ErrorKind := DestEngine.RenameFile(String(DataItem^.FName), Dst + '_tcmd'); - if ErrorKind = 0 then ErrorKind := DestEngine.RenameFile(Dst + '_tcmd', Dst); - end else ErrorKind := DestEngine.RenameFile(String(DataItem^.FName), Dst); - if ErrorKind <> 0 then Result := ERRCopyMove; + // * TODO: check error + ErrorKind := Ord(DestEngine.RenameFile(String(DataItem^.FName), Dst + '_tcmd', nil)); + if ErrorKind = 0 then ErrorKind := Ord(DestEngine.RenameFile(Dst + '_tcmd', Dst, nil)); + end else ErrorKind := Ord(DestEngine.RenameFile(String(DataItem^.FName), Dst, nil)); +// if ErrorKind <> 0 then Result := ERRCopyMove; end else begin if LocalCopyFile(String(DataItem^.FName), Dst, Append) then begin if IsOnRO and ConfClearReadOnlyAttr and (DataItem^.Mode and S_IWUSR = 0) then DataItem^.Mode := DataItem^.Mode or S_IWUSR; - DestEngine.Chmod(Dst, DataItem^.Mode); - DestEngine.Chown(Dst, DataItem^.UID, DataItem^.GID); - DestEngine.ChangeTimes(Dst, DataItem^.mtime, DataItem^.atime); + // * TODO: check error + DestEngine.Chmod(Dst, DataItem^.Mode, nil); + DestEngine.Chown(Dst, DataItem^.UID, DataItem^.GID, nil); + DestEngine.ChangeTimes(Dst, DataItem^.mtime, DataItem^.atime, nil); if not Cancelled then begin - ErrorKind := SrcEngine.Remove(String(DataItem^.FName)); - if ErrorKind <> 0 then Result := ERRRemove; + ErrorKind := Ord(SrcEngine.Remove(String(DataItem^.FName), nil)); +// if ErrorKind <> 0 then Result := ERRRemove; end; end; end; @@ -1126,10 +1158,11 @@ var DefResponse: integer; // Global variables for this function if (not AFileRec^.Stage1) and (ParamBool3 or ((not ParamBool3) and (not AFileRec^.ForceMove))) then with AFileRec^ do begin if IsOnRO and ConfClearReadOnlyAttr and (DataItem^.Mode and S_IWUSR = 0) then DataItem^.Mode := DataItem^.Mode or S_IWUSR; - DestEngine.Chmod(NewFilePath, DataItem^.Mode); - DestEngine.Chown(NewFilePath, DataItem^.UID, DataItem^.GID); - DestEngine.ChangeTimes(NewFilePath, DataItem^.mtime, DataItem^.atime); - if not ParamBool3 then SrcEngine.Remove(String(DataItem^.FName)); // Remove directory + // * TODO: check error + DestEngine.Chmod(NewFilePath, DataItem^.Mode, nil); + DestEngine.Chown(NewFilePath, DataItem^.UID, DataItem^.GID, nil); + DestEngine.ChangeTimes(NewFilePath, DataItem^.mtime, DataItem^.atime, nil); + if not ParamBool3 then SrcEngine.Remove(String(DataItem^.FName), nil); // Remove directory Exit; end; @@ -1142,28 +1175,33 @@ var DefResponse: integer; // Global variables for this function TwoSameFiles(ExcludeTrailingPathDelimiter(string(AFileRec^.DataItem^.FName)), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), False)) then begin DebugMsg(['*** Activating double-rename due to renaming on case-insensitive FS']); - ErrorKind := DestEngine.RenameFile(string(AFileRec^.DataItem^.FName), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd'); - if ErrorKind = 0 then ErrorKind := DestEngine.RenameFile(ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd', ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination))); - end else ErrorKind := DestEngine.RenameFile(string(AFileRec^.DataItem^.FName), string(AFileRec^.ADestination)); - if ErrorKind <> 0 then Res := ERRCopyMove - else Res := 0; + // * TODO: check error + ErrorKind := Ord(DestEngine.RenameFile(string(AFileRec^.DataItem^.FName), ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd', nil)); + if ErrorKind = 0 then ErrorKind := ord(DestEngine.RenameFile(ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)) + '_tcmd', ExcludeTrailingPathDelimiter(string(AFileRec^.ADestination)), nil)); + end else ErrorKind := Ord(DestEngine.RenameFile(string(AFileRec^.DataItem^.FName), string(AFileRec^.ADestination), nil)); +{ if ErrorKind <> 0 then Res := ERRCopyMove + else Res := 0; } end else if not DestEngine.DirectoryExists(NewFilePath, False) then begin - ErrorKind := DestEngine.MakeDir(NewFilePath); - if ErrorKind <> 0 then Res := ERRMkDir - else Res := 0; + // * TODO: check error + ErrorKind := Ord(DestEngine.MakeDir(NewFilePath, nil)); +{ if ErrorKind <> 0 then Res := ERRMkDir + else Res := 0; } end; end else begin // not a directory - if not DestEngine.DirectoryExists(ExtractFileDir(NewFilePath), False) then DestEngine.MakeDir(ExtractFileDir(NewFilePath)); + if not DestEngine.DirectoryExists(ExtractFileDir(NewFilePath), False) then + // * TODO: check error + DestEngine.MakeDir(ExtractFileDir(NewFilePath), nil); SetProgress1Params(AFileRec^.DataItem^.Size + Ord(AFileRec^.DataItem^.Size = 0)); if AFileRec^.DataItem^.Size <= 1 then ParamFloat2 := 1 else ParamFloat2 := 100 / (AFileRec^.DataItem^.Size - 1); - CopyFilesWorker_ProgressFunc(SenderThread, 0); + CopyFilesWorker_ProgressFunc(SenderThread, 0, nil); Res := 0; if DestEngine.FileExists(NewFilePath, False) and (not (not ParamBool3 and (not TwoSameFiles(NewFilePath, AFileRec^.DataItem^.FName, False)) and TwoSameFiles(NewFilePath, AFileRec^.DataItem^.FName, True))) then begin Response := DefResponse; - Item := DestEngine.GetFileInfo(NewFilePath, False, True); + // * TODO: check error + Item := DestEngine.GetFileInfo(NewFilePath, False, True, nil); if Item = nil then begin DebugMsg(['Something went terribly wrong during copy - Item := DestEngine.GetFileInfoSL(NewFilePath) == NULL!']); Result := False; @@ -1201,16 +1239,19 @@ var DefResponse: integer; // Global variables for this function // Remove destination file if exists and should be overwritten if (Response in [1, 2]) or ((Response = 5) and (Item^.mtime < AFileRec^.DataItem^.mtime)) then begin - r := DestEngine.Remove(NewFilePath); + // * TODO: check error + r := ord(DestEngine.Remove(NewFilePath, nil)); while r <> 0 do begin + // * TODO: check error Res := ShowDirDeleteDialog(1, LANGTheFile, StrToUTF8(String(NewFilePath)), - Format(LANGCouldNotBeDeletedS, [GetErrorString(r)]), LANGCopyError); + Format(LANGCouldNotBeDeletedS, ['ahoj' {GetErrorString(r)}]), LANGCopyError); case Res of 1: begin Result := True; Exit; end; - 2: r := DestEngine.Remove(NewFilePath); + // * TODO: check error + 2: r := Ord(DestEngine.Remove(NewFilePath, nil)); 0, 124, 255: begin Result := False; Exit; @@ -1226,7 +1267,8 @@ var DefResponse: integer; // Global variables for this function if (Res <> 0) and (not SkipAll) then begin if ParamBool3 then cap := LANGCopy else cap := LANGMove; - case Res of + // * TODO: port to GError +{ case Res of ERRCreateLink: begin s1 := LANGTheSymbolicLink; if ErrorKind = 0 then s3 := LANGCouldNotBeCreated else @@ -1250,7 +1292,7 @@ var DefResponse: integer; // Global variables for this function if ErrorKind = 0 then s3 := '' else s3 := GetErrorString(ErrorKind); end; - end; + end; } Response := ShowDirDeleteDialog(1, s1, StrToUTF8(String(NewFilePath)), s3, cap); case Response of 1 : Result := True; // Skip @@ -1396,9 +1438,9 @@ begin if List.Count > 0 then begin StartPassed := True; if SrcEngine is TVFSEngine then - StartPassed := StartPassed and (SrcEngine as TVFSEngine).StartCopyOperation(SenderThread, @CopyFilesWorker_ErrorFunc, @vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_progress_callback, SenderThread); + StartPassed := StartPassed and (SrcEngine as TVFSEngine).StartCopyOperation(@vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_copy_progress_callback, SenderThread); if DestEngine is TVFSEngine then - StartPassed := StartPassed and (DestEngine as TVFSEngine).StartCopyOperation(SenderThread, @CopyFilesWorker_ErrorFunc, @vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_progress_callback, SenderThread); + StartPassed := StartPassed and (DestEngine as TVFSEngine).StartCopyOperation(@vfs_ask_question_callback, @vfs_ask_password_callback, @vfs_copy_progress_callback, SenderThread); if StartPassed then for i := 0 to List.Count - 1 do begin @@ -1442,9 +1484,9 @@ begin // We need to ensure these to be called in case of error if SrcEngine is TVFSEngine then - (SrcEngine as TVFSEngine).StopCopyOperation(SenderThread, @CopyFilesWorker_ErrorFunc); + (SrcEngine as TVFSEngine).StopCopyOperation(@vfs_copy_progress_callback, SenderThread); if DestEngine is TVFSEngine then - (DestEngine as TVFSEngine).StopCopyOperation(SenderThread, @CopyFilesWorker_ErrorFunc); + (DestEngine as TVFSEngine).StopCopyOperation(@vfs_copy_progress_callback, SenderThread); end; // Free the objects @@ -1452,9 +1494,13 @@ begin for i := List.Count - 1 downto 0 do FreeDataItem(PDataItemSL(List[i])); List.Clear; List.Free; - if DestEngine.ChangeDir(SaveDestPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); + // * TODO: check error + if not DestEngine.ChangeDir(SaveDestPath, nil) then + DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); if SaveSrcPath <> '' then CurrPath := SaveSrcPath; - if SrcEngine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); + // * TODO: check error + if not SrcEngine.ChangeDir(CurrPath, nil) then + DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour might occur.']); end; SenderThread.FDoneThread := True; DebugMsg(['(II) CopyFilesWorker: finished']); @@ -1474,12 +1520,13 @@ procedure MergeFilesWorker(SenderThread: TWorkerThread); // ParamInt64 = TargetSize var FD: TEngineFileDes; - Error, Count, MergeBlockSize: integer; + Count, MergeBlockSize: integer; Buffer: Pointer; CurrentCRC: LongWord; PrivateCancel: boolean; SizeDone: Int64; TargetName: string; + Error: PGError; function PasteFile(FName: string): boolean; @@ -1493,21 +1540,26 @@ var FD: TEngineFileDes; else UpdateCaption1(Format(LANGFromS, [StrToUTF8(FName)])); UpdateProgress1(0, '0 %'); CommitGUIUpdate; - Stat := Engine.GetFileInfo(FName, True, True); + // * TODO: check error + Stat := Engine.GetFileInfo(FName, True, True, nil); if not Assigned(Stat) then Exit; SetProgress1Params(Stat^.Size); FreeDataItem(Stat); - FDR := Engine.OpenFile(FName, omRead, Error); - if Error <> 0 then Exit; + // * TODO: check error + Error := nil; + FDR := Engine.OpenFile(FName, omRead, @Error); + if FDR = nil then Exit; repeat - Count := Engine.ReadFile(FDR, Buffer, MergeBlockSize, Error); - if Error <> 0 then begin - Engine.CloseFile(FD); + // * TODO: check error + Count := Engine.ReadFile(FDR, Buffer, MergeBlockSize, @Error); + if Error <> nil then begin + Engine.CloseFile(FD, nil); Exit; end; - wCount := Engine.WriteFile(FD, Buffer, Count, Error); - if (Error <> 0) or (Count <> wCount) then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileWritingFileSS, [ExtractFileName(TargetName), GetErrorString(Error)]); + // * TODO: check error + wCount := Engine.WriteFile(FD, Buffer, Count, @Error); + if (Error <> nil) or (Count <> wCount) then begin + FCancelMessage := Format(LANGAnErrorOccuredWhileWritingFileSS, [ExtractFileName(TargetName), Error^.message]); FShowCancelMessage := True; PrivateCancel := True; Result := True; // Fake this to don't show next disc dialog @@ -1519,7 +1571,8 @@ var FD: TEngineFileDes; if ParamBool1 then UpdateProgress2(SizeDone, Format('%d %%', [Trunc(SizeDone / FProgress2Max * 100)])); CommitGUIUpdate; until (Count < MergeBlockSize) or Cancelled; - Engine.CloseFile(FDR); + // * TODO: set real error, also free it + Engine.CloseFile(FDR, nil); end; Result := True; end; @@ -1541,15 +1594,17 @@ begin if Engine.FileExists(TargetName, False) then if ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [StrToUTF8(TargetName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes then begin - Error := Engine.Remove(TargetName); + // * TODO: check error +{ Error := Ord(Engine.Remove(TargetName, nil)); if Error <> 0 then begin FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(ExtractFileName(TargetName)), GetErrorString(Error)]); FShowCancelMessage := True; Exit; - end; + end; } end else Exit; - Stat := Engine.GetFileInfo(ParamString2, True, True); + // * TODO: check error + Stat := Engine.GetFileInfo(ParamString2, True, True, nil); if Assigned(Stat) then MergeBlockSize := ComputeBlockSize(Stat^.Size) else MergeBlockSize := 65536*4; FreeDataItem(Stat); @@ -1561,9 +1616,10 @@ begin FShowCancelMessage := True; Exit; end; - FD := Engine.OpenFile(TargetName, omWrite, Error); - if Error <> 0 then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(TargetName), GetErrorString(Error)]); + // * TODO: check error + FD := Engine.OpenFile(TargetName, omWrite, @Error); + if Error <> nil then begin + FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(TargetName), Error^.message]); FShowCancelMessage := True; libc_free(Buffer); Exit; @@ -1600,7 +1656,8 @@ begin CurrFile := ''; end; until (SizeDone = ParamInt64) or Cancelled or PrivateCancel {or ((not b) and (not HasInitialCRC))} or (CurrFile = ''); - if (not ParamBool1) and HasFinalCRC then Engine.RenameFile(TargetName, IncludeTrailingPathDelimiter(ExtractFilePath(TargetName)) + TargetFinalName); + // * TODO: check error + if (not ParamBool1) and HasFinalCRC then Engine.RenameFile(TargetName, IncludeTrailingPathDelimiter(ExtractFilePath(TargetName)) + TargetFinalName, nil); if Cancelled and (not PrivateCancel) then begin FCancelMessage := LANGUserCancelled; FShowCancelMessage := True; @@ -1611,7 +1668,8 @@ begin then ShowMessageBox(Format(LANGMergeOfSSucceeded, [StrToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK) else ShowMessageBox(LANGWarningCreatedFileFailsCRCCheck, [mbOK], mbWarning, mbNone, mbOK); end else ShowMessageBox(Format(LANGMergeOfSSucceeded_NoCRCFileAvailable, [StrToUTF8(ExtractFileName(TargetFinalName))]), [mbOK], mbInfo, mbNone, mbOK); - Engine.CloseFile(FD); + // * TODO: set real error, also free it + Engine.CloseFile(FD, nil); end; libc_free(Buffer); SenderThread.FDoneThread := True; @@ -1630,7 +1688,7 @@ procedure SplitFilesWorker(SenderThread: TWorkerThread); const SplitBlockSize = 65536*4; var FD: TEngineFileDes; - Error: integer; + Error: PGError; FileCRC: LongWord; Buffer: Pointer; PrivateCancel: boolean; @@ -1645,9 +1703,10 @@ var FD: TEngineFileDes; Result := False; Written := 0; with SenderThread do begin - FDW := Engine.OpenFile(TargetFile, omWrite, Error); + // * TODO: check error + FDW := Engine.OpenFile(TargetFile, omWrite, @Error); DebugMsg(['-- Opening file ', ExtractFileName(TargetFile), ', PartSize = ', PartSize]); - if Error <> 0 then Exit; + if Error <> nil then Exit; if ParamInt64 > 0 then begin UpdateCaption2(Format(LANGToS, [StrToUTF8(TargetFile)])); SetProgress1Params(PartSize); @@ -1655,30 +1714,37 @@ var FD: TEngineFileDes; end else UpdateCaption1(Format(LANGToS, [StrToUTF8(TargetFile)])); CommitGUIUpdate; repeat - DebugMsg(['Seek to ', Engine.FileSeek(FD, SizeDone + Written, Error), ', Written = ', Written]); + // * TODO: check error + DebugMsg(['Seek to ', Engine.FileSeek(FD, SizeDone + Written, @Error), ', Written = ', Written]); if Written + SplitBlockSize > PartSize then bl := PartSize - Written else bl := SplitBlockSize; - Count := Engine.ReadFile(FD, Buffer, bl, Error); - if (Error <> 0) or (Count <> bl) then begin - Engine.CloseFile(FDW); - DebugMsg(['Read Error: ', GetErrorString(Error), ', Count = ', Count, ', bl = ', bl]); - if (Count <> bl) and (Error = 0) then Error := EIO; + // * TODO: check error + Count := Engine.ReadFile(FD, Buffer, bl, @Error); + if (Error <> nil) or (Count <> bl) then begin + // * TODO: set real error, also free it + Engine.CloseFile(FDW, nil); + DebugMsg(['Read Error: ', Error^.message, ', Count = ', Count, ', bl = ', bl]); +// if (Count <> bl) and (Error = 0) then Error := EIO; Exit; end; - wCount := Engine.WriteFile(FDW, Buffer, Count, Error); + // * TODO: check error + wCount := Engine.WriteFile(FDW, Buffer, Count, @Error); Inc(Written, wCount); FileCRC := CRC32(FileCRC, Buffer, wCount); - if (Error <> 0) or (Count <> wCount) then begin - Engine.CloseFile(FDW); - DebugMsg(['Write Error: ', GetErrorString(Error), ', Count = ', Count, ', wCount = ', wCount]); - if (wCount <> Count) and (Error = 0) then Error := ENOSPC; + if (Error <> nil) or (Count <> wCount) then begin + // * TODO: set real error, also free it + Engine.CloseFile(FDW, nil); + // * TODO: check error + DebugMsg(['Write Error: ', Error^.message, ', Count = ', Count, ', wCount = ', wCount]); +// if (wCount <> Count) and (Error = 0) then Error := ENOSPC; Exit; end; UpdateProgress1(FProgress1Pos + wCount, Format('%d %%', [Trunc((FProgress1Pos + wCount) / FProgress1Max * 100)])); if ParamInt64 > 0 then UpdateProgress2(FProgress2Pos + wCount, Format('%d %%', [Trunc((FProgress2Pos + wCount) / FProgress2Max * 100)])); CommitGUIUpdate; until (Written = PartSize) or Cancelled or PrivateCancel; - Engine.CloseFile(FDW); + // * TODO: set real error, also free it + Engine.CloseFile(FDW, nil); end; DebugMsg(['-- Closing file ', ExtractFileName(TargetFile), ', PartSize = ', PartSize, ', Written = ', Written]); Result := True; @@ -1721,7 +1787,8 @@ var i: integer; xx: string; begin with SenderThread do begin - Stat := Engine.GetFileInfo(ParamString1, True, True); + // * TODO: check error + Stat := Engine.GetFileInfo(ParamString1, True, True, nil); if not Assigned(Stat) then begin FCancelMessage := Format(LANGCannotOpenFileS, [StrToUTF8(ParamString1)]); FShowCancelMessage := True; @@ -1746,9 +1813,10 @@ begin FShowCancelMessage := True; Exit; end; - FD := Engine.OpenFile(ParamString1, omRead, Error); - if Error <> 0 then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ParamString1), GetErrorString(Error)]); + // * TODO: check error + FD := Engine.OpenFile(ParamString1, omRead, @Error); + if Error <> nil then begin + FCancelMessage := Format(LANGAnErrorOccuredWhileOpeningFileSS, [StrToUTF8(ParamString1), Error^.message]); libc_free(Buffer); Exit; end; @@ -1777,7 +1845,8 @@ begin for i := List.Count - 1 downto 0 do FreeDataItem(PDataItem(List[i])); List.Clear; - Error := Engine.GetListing(List, FilePath, ConfShowDotFiles, False, False); + // * TODO: check error +{ Error := Engine.GetListing(List, FilePath, ConfShowDotFiles, False, False, nil); if (Error = 0) and (List.Count > 0) then begin st := ''; if List.Count < 6 then begin @@ -1790,19 +1859,20 @@ begin Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + string(PDataItem(List[i])^.FName)); if Error <> 0 then ShowMessageBox(Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath)) + string(PDataItem(List[i])^.FDisplayName), GetErrorString(Error)]), [mbOK], mbError, mbNone, mbOK); end; - end; + end; } except end; // Test for target file existence if Engine.FileExists(IncludeTrailingPathDelimiter(FilePath) + FileName, False) then begin b := ShowMessageBox(Format(LANGTheTargetFileSAlreadyExistsDoYouWantToOverwriteIt, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName)]), [mbYes, mbNo], mbQuestion, mbNone, mbNo) = mbYes; if b then begin - Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + FileName); + // * TODO: check error +{ Error := Engine.Remove(IncludeTrailingPathDelimiter(FilePath) + FileName); if Error <> 0 then begin FCancelMessage := Format(LANGTheTargetFileSCannotBeRemovedS, [StrToUTF8(IncludeTrailingPathDelimiter(FilePath) + FileName), GetErrorString(Error)]); FShowCancelMessage := True; PrivateCancel := True; Break; - end; + end; } end else begin PrivateCancel := True; Break; @@ -1815,7 +1885,7 @@ begin if (CurrSize >= 512) and (TDF >= CurrSize) then begin b := WriteSplitPart(IncludeTrailingPathDelimiter(FilePath) + FileName, CurrSize, ws); if (not b) and (ParamInt64 > 0) then begin - FCancelMessage := Format(LANGAnErrorOccuredWhileOperationS, [GetErrorString(Error)]); + FCancelMessage := Format(LANGAnErrorOccuredWhileOperationS, [Error^.message]); FShowCancelMessage := True; PrivateCancel := True; Break; @@ -1845,14 +1915,15 @@ begin Engine.GetFileSystemInfo(FilePath, x, TDF, xx); if (TDF < 512) and (not NewDiskQuestion) then Break; until (TDF >= 512) or PrivateCancel or Cancelled; - if WriteCRCFile(Engine, IncludeTrailingPathDelimiter(FilePath) + FileName, OriginalFName, SizeDone, FileCRC) + if WriteCRCFile(ProgressForm, Engine, IncludeTrailingPathDelimiter(FilePath) + FileName, OriginalFName, SizeDone, FileCRC) then ShowMessageBox(Format(LANGSplitOfSSucceeded, [StrToUTF8(OriginalFName)]), [mbOK], mbInfo, mbNone, mbOK) else begin FCancelMessage := Format(LANGSplitOfSFailed, [StrToUTF8(OriginalFName)]); FShowCancelMessage := True; end; end; - Engine.CloseFile(FD); + // * TODO: set real error, also free it + Engine.CloseFile(FD, nil); end; if List.Count > 0 then for i := List.Count - 1 downto 0 do @@ -1874,7 +1945,8 @@ procedure ChmodFilesWorker(SenderThread: TWorkerThread); var SkipAll: boolean; function HandleChmod(AFileRec: PDataItemSL): boolean; - var Res, Response: integer; + var Response: integer; + Res: boolean; begin Result := True; with SenderThread do begin @@ -1882,13 +1954,15 @@ var SkipAll: boolean; if AFileRec^.DataItem^.IsDir and ParamBool1 and AFileRec^.Stage1 and (not AFileRec^.DataItem^.IsLnk) then Exit; if (not AFileRec^.DataItem^.IsDir) and ParamBool1 and (ParamInt1 = 1) then Exit; // Directories only if AFileRec^.DataItem^.IsDir and ParamBool1 and (ParamInt1 = 2) then Exit; // Files only - Res := Engine.Chmod(String(AFileRec^.DataItem^.FName), ParamCardinal1); + // * TODO: check error + Res := Engine.Chmod(String(AFileRec^.DataItem^.FName), ParamCardinal1, nil); // DebugMsg(['Result : ', Res]); - if Res <> 0 then + if not Res then if SkipAll then Result := True else begin + // * TODO: check error Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), Format(LANGCouldNotBeChmoddedS, - [GetErrorString(Res)]), LANGDialogChangePermissions); + ['ahoj' {GetErrorString(Res)}]), LANGDialogChangePermissions); case Response of 1 : Result := True; 3 : begin @@ -1953,20 +2027,23 @@ procedure ChownFilesWorker(SenderThread: TWorkerThread); var SkipAll: boolean; function HandleChown(AFileRec: PDataItemSL): boolean; - var Res, Response: integer; + var Response: integer; + Res: boolean; begin Result := True; with SenderThread do begin // DebugMsg(['Chown Debug: IsDir: ', AFileRec^.IsDir, ', Stage1: ', AFileRec^.Stage1, ', IsLnk: ', AFileRec^.IsLnk, '; Result = ', AFileRec^.IsDir and AFileRec^.Stage1 and (not AFileRec^.IsLnk)]); if (AFileRec^.DataItem^.IsDir and ParamBool1 and AFileRec^.Stage1 and (not AFileRec^.DataItem^.IsLnk)) or ((not AFileRec^.DataItem^.IsDir) and ParamBool1) then Exit; - Res := Engine.Chown(String(AFileRec^.DataItem^.FName), ParamCardinal1, ParamCardinal2); + // * TODO: check error + Res := Engine.Chown(String(AFileRec^.DataItem^.FName), ParamCardinal1, ParamCardinal2, nil); // DebugMsg(['Result : ', Res]); - if Res <> 0 then + if not Res then if SkipAll then Result := True else begin + // * TODO: check error Response := ShowDirDeleteDialog(1, LANGTheFileDirectory, String(AFileRec^.DataItem^.FDisplayName), Format(LANGCouldNotBeChownedS, - [GetErrorString(Res)]), LANGDialogChangeOwner); + ['ahoj' {GetErrorString(Res)}]), LANGDialogChangeOwner); case Response of 1 : Result := True; 3 : begin @@ -2060,19 +2137,28 @@ begin FreeOnTerminate := False; Finished := False; CancelIt := False; - ChDirResult := 0; - ListingResult := 0; - VFSOpenResult := 0; + ChDirResult := False; + ListingResult := False; + VFSOpenResult := False; + ChDirError := nil; + ListingError := nil; + VFSOpenError := nil; RunningTime := 0; end; destructor TOpenDirThread.Destroy; begin + if VFSOpenError <> nil then + g_error_free(VFSOpenError); + if ChDirError <> nil then + g_error_free(ChDirError); + if ListingError <> nil then + g_error_free(ListingError); inherited Destroy; end; (********************************************************************************************************************************) -function TOpenDirThread.ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): integer; +function TOpenDirThread.ChangeDir(Engine: TPanelEngine; Path: string; var SelItem: string; const AutoFallBack: boolean): boolean; procedure GoUp(var NewPath: string); var x: integer; @@ -2087,8 +2173,8 @@ function TOpenDirThread.ChangeDir(Engine: TPanelEngine; Path: string; var SelIte end; var APath: string; - Error : integer; begin + Result := False; try APath := Engine.Path; if Path = '..' then GoUp(APath) @@ -2102,28 +2188,19 @@ begin end; // AutoFallback loop - if Engine is TVFSEngine - then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self) - else Error := Engine.ChangeDir(APath); - - while AutoFallback and (Error <> 0) and (APath <> '/') do begin - GoUp(APath); + repeat if Engine is TVFSEngine - then Error := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self) - else Error := Engine.ChangeDir(APath); - end; - // Going on... - if Error <> 0 then begin - Result := Error; - DebugMsg(['*** UCore.ChangeDir: error during Engine.ChangeDir: ', GetErrorString(Error)]); - Exit; - end; - Engine.Path := APath; - Result := 0; + then Result := (Engine as TVFSEngine).ChangeDirEx(APath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self, @ChDirError) + else Result := Engine.ChangeDir(APath, @ChDirError); + if not Result then + GoUp(APath); + until Result or (not AutoFallback) or (Length(APath) <= 1); + if Result then + Engine.Path := APath; except on E: Exception do begin + Result := False; DebugMsg(['*** Exception raised in UCore.ChangeDir (', E.ClassName, '): ', E.Message]); - Result := 1; end; end; end; @@ -2143,13 +2220,13 @@ begin xEngine.SavePath := AEngine.Path; // AEngine must be set here since VFSOpenEx callbacks will reference it AEngine := xEngine; - VFSOpenResult := (AEngine as TVFSEngine).VFSOpenEx(AFullPath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self); - end else VFSOpenResult := 0; + VFSOpenResult := (AEngine as TVFSEngine).VFSOpenEx(AFullPath, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self, @VFSOpenError); + end else VFSOpenResult := True; - if (VFSOpenResult = 0) and (not CancelIt) then begin + if VFSOpenResult and (not CancelIt) then begin ChDirResult := ChangeDir(AEngine, APath, ASelItem, AAutoFallBack); - if (ChDirResult = 0) and (not CancelIt) then - ListingResult := AEngine.GetListing(ADirList, AEngine.GetPath, ConfShowDotFiles, True, False); + if ChDirResult and (not CancelIt) then + ListingResult := AEngine.GetListing(ADirList, AEngine.GetPath, ConfShowDotFiles, True, False, @ListingError); end; except on E: Exception do DebugMsg(['*** Exception raised in TOpenDirThread.Execute (', E.ClassName, '): ', E.Message]); @@ -2171,6 +2248,7 @@ begin FreeOnTerminate := False; Finished := False; OpenResult := False; + OpenError := nil; end; destructor TOpenConnectionThread.Destroy; @@ -2182,7 +2260,7 @@ procedure TOpenConnectionThread.Execute; begin PrepareExecute; try - OpenResult := (AEngine as TVFSEngine).VFSOpenURI(URI, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self); + OpenResult := (AEngine as TVFSEngine).VFSOpenURI(URI, @vfs_ask_question_callback, @vfs_ask_password_callback, nil, Self, @OpenError); finally Finished := True; end; -- cgit v1.2.3