FIX: Crash when copy files to GIO file system

This commit is contained in:
Alexander Koblov 2026-02-19 18:30:08 +03:00
commit 1419f3aaac
5 changed files with 43 additions and 54 deletions

View file

@ -60,34 +60,30 @@ begin
for AIndex:= 0 to FFiles.Count - 1 do
begin
AFile:= FFiles[AIndex];
SourceFile:= TGioFileLinkProperty(AFile.LinkProperty).Item;
SourceFile:= TGioLinkProperty(AFile.LinkProperty).Item;
AInfo:= g_file_query_info(SourceFile, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nil, nil);
if Assigned(AInfo) then
try
AInfo:= g_file_query_info(SourceFile, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nil, nil);
if Assigned(AInfo) then
try
APath:= g_file_info_get_attribute_byte_string(AInfo, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH);
mbForceDirectory(ExtractFileDir(APath));
APath:= g_file_info_get_attribute_byte_string(AInfo, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH);
mbForceDirectory(ExtractFileDir(APath));
TargetFile:= GioNewFile(APAth);
try
if not g_file_move(SourceFile, TargetFile, G_FILE_COPY_NOFOLLOW_SYMLINKS or G_FILE_COPY_ALL_METADATA or G_FILE_COPY_NO_FALLBACK_FOR_MOVE, nil, nil, nil, @AError) then
begin
if Assigned(AError) then
try
if MessageDlg(AError^.message, mtError, [mbAbort, mbIgnore], 0, mbAbort) = mrAbort then
Break;
finally
FreeAndNil(AError);
end;
TargetFile:= GioNewFile(APath);
try
if not g_file_move(SourceFile, TargetFile, G_FILE_COPY_NOFOLLOW_SYMLINKS or G_FILE_COPY_ALL_METADATA or G_FILE_COPY_NO_FALLBACK_FOR_MOVE, nil, nil, nil, @AError) then
begin
if Assigned(AError) then
try
if MessageDlg(AError^.message, mtError, [mbAbort, mbIgnore], 0, mbAbort) = mrAbort then
Break;
finally
FreeAndNil(AError);
end;
finally
g_object_unref(PGObject(TargetFile));
end;
finally
g_object_unref(AInfo);
g_object_unref(PGObject(TargetFile));
end;
finally
g_object_unref(PGObject(SourceFile));
g_object_unref(AInfo);
end;
end;
Reload(PathDelim);
@ -201,12 +197,7 @@ begin
begin
AVariant:= TFileVariantProperty.Create(AVariantProperties[AIndex]);
if AFile.LinkProperty is TGioFileLinkProperty then
AGFile:= TGioFileLinkProperty(AFile.LinkProperty).Item
else begin
AGFile:= GioNewFile(AFile.FullPath);
end;
AGFile:= GioNewFile(AFile);
AInfo:= g_file_query_info(AGFile, 'trash::*', G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nil, nil);
if Assigned(AInfo) then
begin

View file

@ -105,7 +105,6 @@ end;
function TGioDeleteOperation.ProcessFile(aFile: TFile): Boolean;
var
AGFile: PGFile;
FileName: String;
bRetry: Boolean;
sMessage, sQuestion: String;
@ -143,9 +142,7 @@ begin
//if FileIsReadOnly(aFile.Attributes) then
// mbFileSetReadOnly(FileName, False);
AGFile:= TGioFileLinkProperty(aFile.LinkProperty).Item;
Result:= g_file_delete(AGFile, nil, nil);
g_object_unref(PGObject(AGFile));
Result:= g_file_delete(TGioLinkProperty(aFile.LinkProperty).Item, nil, nil);
if Result then
begin // success

View file

@ -140,7 +140,7 @@ begin
ModificationTimeProperty := TFileModificationDateTimeProperty.Create;
CreationTimeProperty := TFileCreationDateTimeProperty.Create;
LastAccessTimeProperty := TFileLastAccessDateTimeProperty.Create;
LinkProperty := TGioFileLinkProperty.Create;
LinkProperty := TGioLinkProperty.Create;
OwnerProperty := TFileOwnerProperty.Create;
TypeProperty := TFileTypeProperty.Create;
CommentProperty := TFileCommentProperty.Create;
@ -159,7 +159,7 @@ var
begin
Result:= CreateFile(APath);
Result.Name:= g_file_info_get_name(AFileInfo);
TGioFileLinkProperty(Result.LinkProperty).Item:= AFile;
TGioLinkProperty(Result.LinkProperty).Item:= AFile;
Result.Attributes:= g_file_info_get_attribute_uint32(AFileInfo, FILE_ATTRIBUTE_UNIX_MODE);
AFileTime.sec:= Int64(g_file_info_get_attribute_uint64(AFileInfo, FILE_ATTRIBUTE_TIME_MODIFIED));
AFileTime.nanosec:= Int64(g_file_info_get_attribute_uint32(AFileInfo, FILE_ATTRIBUTE_TIME_MODIFIED_USEC)) * 1000;

View file

@ -23,9 +23,9 @@ type
TUpdateStatisticsFunction = procedure(var NewStatistics: TFileSourceCopyOperationStatistics) of object;
TCopyMoveFileFunction = function(source: PGFile; destination: PGFile; flags: TGFileCopyFlags; cancellable: PGCancellable; progress_callback: TGFileProgressCallback; progress_callback_data: gpointer; error: PPGError): gboolean; cdecl;
{ TGioFileLinkProperty }
{ TGioLinkProperty }
TGioFileLinkProperty = class(TFileLinkProperty)
TGioLinkProperty = class(TFileLinkProperty)
private
FItem: PGFile;
public
@ -118,6 +118,7 @@ type
procedure ShowError(AError: PGError);
procedure FreeAndNil(var AError: PGError); overload;
function GioNewFile(AFile: TFile): PGFile; overload;
procedure FillAndCount(Files: TFiles; CountDirs: Boolean; out NewFiles: TFiles;
out FilesCount: Int64; out FilesSize: Int64);
@ -134,6 +135,15 @@ begin
g_error_free(AError);
end;
function GioNewFile(AFile: TFile): PGFile;
begin
if AFile.LinkProperty is TGioLinkProperty then
Result:= g_file_dup(TGioLinkProperty(AFile.LinkProperty).Item)
else begin
Result:= uGio.GioNewFile(AFile.FullPath);
end;
end;
procedure FillAndCount(Files: TFiles; CountDirs: Boolean; out NewFiles: TFiles;
out FilesCount: Int64; out FilesSize: Int64);
var
@ -257,29 +267,29 @@ begin
end;
end;
{ TGioFileLinkProperty }
{ TGioLinkProperty }
destructor TGioFileLinkProperty.Destroy;
destructor TGioLinkProperty.Destroy;
begin
inherited Destroy;
if Assigned(FItem) then g_object_unref(PGObject(FItem));
end;
function TGioFileLinkProperty.Clone: TFileLinkProperty;
function TGioLinkProperty.Clone: TFileLinkProperty;
begin
Result := TGioFileLinkProperty.Create;
Result := TGioLinkProperty.Create;
CloneTo(Result);
end;
procedure TGioFileLinkProperty.CloneTo(FileProperty: TFileProperty);
procedure TGioLinkProperty.CloneTo(FileProperty: TFileProperty);
begin
if Assigned(FileProperty) then
begin
inherited CloneTo(FileProperty);
if FileProperty is TGioFileLinkProperty then
if (FileProperty is TGioLinkProperty) and Assigned(FItem) then
begin
TGioFileLinkProperty(FileProperty).FItem := g_file_dup(Self.FItem);
TGioLinkProperty(FileProperty).FItem := g_file_dup(Self.FItem);
end;
end;
end;
@ -445,11 +455,7 @@ var
begin
NodeData := aNode.Data as TFileTreeNodeData;
if aNode.TheFile.LinkProperty is TGioFileLinkProperty then
SourceFile:= TGioFileLinkProperty(aNode.TheFile.LinkProperty).Item
else begin
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
end;
SourceFile:= GioNewFile(aNode.TheFile);
TargetFile:= GioNewFile(AbsoluteTargetFileName);
try
// If some files will not be moved then source directory cannot be deleted.
@ -533,11 +539,7 @@ begin
FOldDoneBytes:= FStatistics.DoneBytes;
FCancel:= g_cancellable_new();
if aNode.TheFile.LinkProperty is TGioFileLinkProperty then
SourceFile:= TGioFileLinkProperty(aNode.TheFile.LinkProperty).Item
else begin
SourceFile:= GioNewFile(aNode.TheFile.FullPath);
end;
SourceFile:= GioNewFile(aNode.TheFile);
TargetFile:= GioNewFile(AbsoluteTargetFileName);
try

View file

@ -142,7 +142,7 @@ var
begin
Result := sfprSuccess;
AGFile:= TGioFileLinkProperty(aFile.LinkProperty).Item;
AGFile:= TGioLinkProperty(aFile.LinkProperty).Item;
case aTemplateProperty.GetID of
fpName:
if (aTemplateProperty as TFileNameProperty).Value <> aFile.Name then
@ -207,7 +207,6 @@ begin
else
raise Exception.Create('Trying to set unsupported property');
end;
g_object_unref(PGObject(AGFile));
end;
end.