Avoid using .NET File operations during restore as they normalize paths.
This commit is contained in:
@@ -811,7 +811,7 @@ namespace Duplicati.Library.Main.Operation.Restore
|
||||
List<BlockRequest> verified_blocks = [];
|
||||
|
||||
// Check if the file exists
|
||||
if (File.Exists(file.TargetPath))
|
||||
if (await restoreDestination.FileExists(file.TargetPath, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
filehasher.Initialize();
|
||||
try
|
||||
@@ -867,17 +867,19 @@ namespace Duplicati.Library.Main.Operation.Restore
|
||||
if (filehasher.Hash != null && Convert.ToBase64String(filehasher.Hash) == file.Hash)
|
||||
{
|
||||
// Truncate the file if it is larger than the expected size.
|
||||
FileInfo fi = new(file.TargetPath);
|
||||
if (file.Length < fi.Length)
|
||||
var currentLength = await restoreDestination.GetFileLength(file.TargetPath, cancellationToken).ConfigureAwait(false);
|
||||
if (file.Length < currentLength)
|
||||
{
|
||||
if (options.Dryrun)
|
||||
{
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "DryrunRestore", @$"Would have truncated ""{file.TargetPath}"" from {fi.Length} to {file.Length}");
|
||||
Logging.Log.WriteDryrunMessage(LOGTAG, "DryrunRestore", @$"Would have truncated ""{file.TargetPath}"" from {currentLength} to {file.Length}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reopen file with write permission
|
||||
fi.IsReadOnly = false; // The metadata handler will revert this back later.
|
||||
// The metadata handler will revert this back later.
|
||||
if (await restoreDestination.HasReadOnlyAttribute(file.TargetPath, cancellationToken).ConfigureAwait(false))
|
||||
await restoreDestination.ClearReadOnlyAttribute(file.TargetPath, cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
using var f = await restoreDestination.OpenWrite(file.TargetPath, cancellationToken).ConfigureAwait(false);
|
||||
@@ -931,15 +933,14 @@ namespace Duplicati.Library.Main.Operation.Restore
|
||||
List<BlockRequest> missing_blocks = [];
|
||||
List<BlockRequest> verified_blocks = [];
|
||||
|
||||
// Check if the file exists
|
||||
if (File.Exists(file.OriginalPath))
|
||||
// Check if the file exists (ignore if this was a remote source)
|
||||
if (SystemIO.IO_OS.FileExists(file.OriginalPath))
|
||||
{
|
||||
filehasher.Initialize();
|
||||
|
||||
// Open both files, as the target file is still being read to produce the overall file hash, if all the blocks are present across both the target and original files.
|
||||
// Note: The original file is the source file on the local system (not within the restore destination),
|
||||
// so we use File.OpenRead directly instead of restoreDestination.OpenRead
|
||||
using var f_original = File.OpenRead(file.OriginalPath);
|
||||
using var f_original = SystemIO.IO_OS.FileOpenRead(file.OriginalPath);
|
||||
using var f_target = options.Dryrun ?
|
||||
(await restoreDestination.FileExists(file.TargetPath, cancellationToken).ConfigureAwait(false) ?
|
||||
await restoreDestination.OpenRead(file.TargetPath, cancellationToken).ConfigureAwait(false) :
|
||||
|
||||
Reference in New Issue
Block a user