Path normalization

Path separators are converted to \ which is Windows & Linux compatible, overwriting the Path.Combine separator (which would be host dependant)
This commit is contained in:
Marcelo C.
2025-01-10 12:05:40 -03:00
parent f598b478f9
commit a1263cd48c
@@ -102,7 +102,7 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
NTStatus status;
object fileHandle;
FileStatus fileStatus;
status = _smbFileStore.CreateFile(out fileHandle, out fileStatus, Path.Combine(_connectionParameters.Path, fileName),
status = _smbFileStore.CreateFile(out fileHandle, out fileStatus, NormalizeSlashes(Path.Combine(_connectionParameters.Path, fileName)),
AccessMask.GENERIC_WRITE | AccessMask.DELETE | AccessMask.SYNCHRONIZE,
FileAttributes.Normal,
ShareAccess.None,
@@ -145,15 +145,15 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
try
{
// Normalize path separators to forward slashes and trim any trailing separators
string normalizedPath = path.Replace('\\', '/').TrimEnd('/');
string linuxNormalizedPath = path.Replace('/', '\\').TrimEnd('\\');
string currentPath = "";
foreach (string part in normalizedPath.Split('/', StringSplitOptions.RemoveEmptyEntries))
foreach (string part in linuxNormalizedPath.Split('\\', StringSplitOptions.RemoveEmptyEntries))
{
if (string.IsNullOrWhiteSpace(part) || part == ".")
continue;
currentPath = currentPath.Length == 0 ? part : $"{currentPath}/{part}";
currentPath = currentPath.Length == 0 ? part : $"{currentPath}\\{part}";
object? fileHandle = null;
try
{
@@ -208,7 +208,7 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
var status = _smbFileStore.CreateFile(
out directoryHandle,
out fileStatus,
_connectionParameters.Path,
NormalizeSlashes(_connectionParameters.Path),
AccessMask.GENERIC_READ,
FileAttributes.Directory,
ShareAccess.Read | ShareAccess.Write,
@@ -220,7 +220,7 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
if (status == NTStatus.STATUS_OBJECT_PATH_NOT_FOUND || status == NTStatus.STATUS_OBJECT_NAME_NOT_FOUND)
throw new FolderMissingException();
else
throw new UserInformationException($"{LC.L("Failed to open directory")} {_connectionParameters.Path} with status {status.ToString()}","DirectoryOpenError");
throw new UserInformationException($"{LC.L("Failed to open directory")} { NormalizeSlashes(_connectionParameters.Path)} with status {status.ToString()}","DirectoryOpenError");
List<QueryDirectoryFileInformation> fileList;
status = _smbFileStore.QueryDirectory(
@@ -279,7 +279,7 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
object? fileHandle;
FileStatus fileStatus;
NTStatus status = _smbFileStore.CreateFile(out fileHandle, out fileStatus,
Path.Combine(_connectionParameters.Path, filename), // This is where the file name is concatenated with the path
NormalizeSlashes(Path.Combine(_connectionParameters.Path, filename)),
AccessMask.GENERIC_READ | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.Read,
CreateDisposition.FILE_OPEN,
CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
@@ -341,7 +341,7 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
object fileHandle;
FileStatus fileStatus;
NTStatus status = _smbFileStore.CreateFile(out fileHandle, out fileStatus,
Path.Combine(_connectionParameters.Path, filename), // This is where the file name is concatenated with the path
NormalizeSlashes(Path.Combine(_connectionParameters.Path, filename)),
AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE,
FileAttributes.Normal, ShareAccess.None,
CreateDisposition.FILE_SUPERSEDE,
@@ -383,6 +383,18 @@ public class SMBShareConnection : IDisposable, IAsyncDisposable
_semaphore.Release();
}
}
/// <summary>
/// Normalizes paths to use backslashes (for Windows shares compatibility) and removes trailing slashes.
///
/// Samba deals with \ and / in paths, but Windows shares require backslashes.
/// </summary>
/// <param name="path">Path to be normalized</param>
/// <returns></returns>
private string NormalizeSlashes(string path)
{
return path.Replace('/', '\\').TrimEnd('\\');
}
/// <summary>
/// Synchronously dispose the resources.