public SMBItem(FileDirectoryInformation fdi, string parentPath) { Name = fdi.FileName; Path = System.IO.Path.Combine(parentPath, fdi.FileName); IsDirectory = fdi.FileAttributes.HasFlag(FileAttributes.Directory); Size = fdi.EndOfFile; Info = fdi; }
/// <summary> /// Verify FileDirectoryInformation entry /// </summary> private void VerifyFileInformation(FileDirectoryInformation entry, int index, string fileName, FileAttribute fileAttribute, long endOfFile, long allocationSize) { Site.Log.Add(LogEntryKind.Debug, $"Start to verify entry {index}."); VerifyFileCommonDirectoryInformation(entry.FileCommonDirectoryInformation, fileAttribute); Site.Assert.AreEqual(fileName, Encoding.Unicode.GetString(entry.FileName), $"FileName of the entry should be {fileName}."); Site.Assert.AreEqual(endOfFile, entry.FileCommonDirectoryInformation.EndOfFile, "The EndOfFile of the entry should be 0."); Site.Assert.AreEqual(allocationSize, entry.FileCommonDirectoryInformation.AllocationSize, "The AllocationSize of the entry should be 0."); }
public override bool Exists(string path) { if (!path.IsSharePath()) { return(base.Exists(path)); } try { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\""); } NTStatus status = NTStatus.STATUS_SUCCESS; var credential = _credentialProvider.GetSMBCredential(path); using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { var shareName = path.ShareName(); var directoryPath = _fileSystem.Path.GetDirectoryName(path); var fileName = _fileSystem.Path.GetFileName(path); ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); status = fileStore.CreateFile(out object handle, out FileStatus fileStatus, directoryPath, AccessMask.GENERIC_READ, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, string.IsNullOrEmpty(fileName) ? "*" : fileName, FileInformationClass.FileDirectoryInformation); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == fileName) { fileStore.CloseFile(handle); return(true); } } } fileStore.CloseFile(handle); } return(false); } catch { return(false); } }
/// <summary> /// Get Child Node from Path and Smb2-Result. /// </summary> /// <param name="parentNode"></param> /// <param name="info"></param> /// <returns></returns> public static Node GetChild( Node parentNode, FileDirectoryInformation info ) { if (parentNode == null) { throw new ArgumentException("Required parentNode."); } if (info == null) { throw new ArgumentException("Required info."); } var pathSet = PathSet.Parse($@"{parentNode.FullPath}\{info.FileName}"); if (info.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory)) { // Folder var result = NodeFactory.InnerGet( NodeType.Folder, pathSet, parentNode.ParamSet ); result.Created = info.CreationTime; result.Updated = info.LastWriteTime; result.LastAccessed = info.LastAccessTime; return(result); } else { // File var result = NodeFactory.InnerGet( NodeType.File, pathSet, parentNode.ParamSet ); result.Size = info.EndOfFile; result.Created = info.CreationTime; result.Updated = info.LastWriteTime; result.LastAccessed = info.LastAccessTime; return(result); } }
public static IDirectoryInformation CreateDirectoryInformation() { IDirectoryInformation info; string mode = ConfigurationManager.AppSettings["mode"].ToString(); switch (mode.ToUpper()) { case "TEST": info = new MockDirectoryInformation(); break; case "PROD": info = new FileDirectoryInformation(); break; default: new ErrorLoger("Go into app.config and set mode either to PROD or TEST"); throw new Exception("You did something wrong"); } return info; }
public override bool Exists(string path) { if (!path.IsSharePath()) { return(base.Exists(path)); } ISMBFileStore fileStore = null; object handle = null; try { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to determine if {path} exists", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } NTStatus status = NTStatus.STATUS_SUCCESS; var credential = _credentialProvider.GetSMBCredential(path); using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { var shareName = path.ShareName(); var directoryPath = _fileSystem.Path.GetDirectoryName(path).Replace(path.SharePath(), "").RemoveLeadingAndTrailingSeperators(); var fileName = _fileSystem.Path.GetFileName(path); _logger?.LogTrace($"Trying to determine if {{DirectoryPath: {directoryPath}}} {{FileName: {fileName}}} Exists for {{ShareName: {shareName}}}"); fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); AccessMask accessMask = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ; ShareAccess shareAccess = ShareAccess.Read; CreateDisposition disposition = CreateDisposition.FILE_OPEN; CreateOptions createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE; status = fileStore.CreateFile(out handle, out FileStatus fileStatus, directoryPath, accessMask, 0, shareAccess, disposition, createOptions, null); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, string.IsNullOrEmpty(fileName) ? "*" : fileName, FileInformationClass.FileDirectoryInformation); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == fileName) { FileStoreUtilities.CloseFile(fileStore, ref handle); return(true); } } } FileStoreUtilities.CloseFile(fileStore, ref handle); } return(false); } catch (Exception ex) { _logger?.LogTrace(ex, $"Failed to determine if {path} exists."); return(false); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } }
/// <exception cref="SmbLibraryStd.UnsupportedInformationLevelException"></exception> public static FindInformation ToFindInformation(QueryDirectoryFileInformation fileInformation) { if (fileInformation is FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInfo = (FileDirectoryInformation)fileInformation; FindFileDirectoryInfo result = new FindFileDirectoryInfo(); result.FileIndex = fileDirectoryInfo.FileIndex; result.CreationTime = fileDirectoryInfo.CreationTime; result.LastAccessTime = fileDirectoryInfo.LastAccessTime; result.LastWriteTime = fileDirectoryInfo.LastWriteTime; result.LastAttrChangeTime = fileDirectoryInfo.LastWriteTime; result.EndOfFile = fileDirectoryInfo.EndOfFile; result.AllocationSize = fileDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileDirectoryInfo.FileAttributes; result.FileName = fileDirectoryInfo.FileName; return(result); } else if (fileInformation is FileFullDirectoryInformation) { FileFullDirectoryInformation fileFullDirectoryInfo = (FileFullDirectoryInformation)fileInformation; FindFileFullDirectoryInfo result = new FindFileFullDirectoryInfo(); result.FileIndex = fileFullDirectoryInfo.FileIndex; result.CreationTime = fileFullDirectoryInfo.CreationTime; result.LastAccessTime = fileFullDirectoryInfo.LastAccessTime; result.LastWriteTime = fileFullDirectoryInfo.LastWriteTime; result.LastAttrChangeTime = fileFullDirectoryInfo.LastWriteTime; result.EndOfFile = fileFullDirectoryInfo.EndOfFile; result.AllocationSize = fileFullDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileFullDirectoryInfo.FileAttributes; result.EASize = fileFullDirectoryInfo.EaSize; result.FileName = fileFullDirectoryInfo.FileName; return(result); } else if (fileInformation is FileNamesInformation) { FileNamesInformation fileNamesInfo = (FileNamesInformation)fileInformation; FindFileNamesInfo result = new FindFileNamesInfo(); result.FileIndex = fileNamesInfo.FileIndex; result.FileName = fileNamesInfo.FileName; return(result); } else if (fileInformation is FileBothDirectoryInformation) { FileBothDirectoryInformation fileBothDirectoryInfo = (FileBothDirectoryInformation)fileInformation; FindFileBothDirectoryInfo result = new FindFileBothDirectoryInfo(); result.FileIndex = fileBothDirectoryInfo.FileIndex; result.CreationTime = fileBothDirectoryInfo.CreationTime; result.LastAccessTime = fileBothDirectoryInfo.LastAccessTime; result.LastWriteTime = fileBothDirectoryInfo.LastWriteTime; result.LastChangeTime = fileBothDirectoryInfo.LastWriteTime; result.EndOfFile = fileBothDirectoryInfo.EndOfFile; result.AllocationSize = fileBothDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileBothDirectoryInfo.FileAttributes; result.EASize = fileBothDirectoryInfo.EaSize; result.Reserved = fileBothDirectoryInfo.Reserved; result.ShortName = fileBothDirectoryInfo.ShortName; result.FileName = fileBothDirectoryInfo.FileName; return(result); } else if (fileInformation is FileIdFullDirectoryInformation) { FileIdFullDirectoryInformation fileIDFullDirectoryInfo = (FileIdFullDirectoryInformation)fileInformation; FindFileIDFullDirectoryInfo result = new FindFileIDFullDirectoryInfo(); result.FileIndex = fileIDFullDirectoryInfo.FileIndex; result.CreationTime = fileIDFullDirectoryInfo.CreationTime; result.LastAccessTime = fileIDFullDirectoryInfo.LastAccessTime; result.LastWriteTime = fileIDFullDirectoryInfo.LastWriteTime; result.LastAttrChangeTime = fileIDFullDirectoryInfo.LastWriteTime; result.EndOfFile = fileIDFullDirectoryInfo.EndOfFile; result.AllocationSize = fileIDFullDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileIDFullDirectoryInfo.FileAttributes; result.EASize = fileIDFullDirectoryInfo.EaSize; result.Reserved = fileIDFullDirectoryInfo.Reserved; result.FileID = fileIDFullDirectoryInfo.FileId; result.FileName = fileIDFullDirectoryInfo.FileName; return(result); } else if (fileInformation is FileIdBothDirectoryInformation) { FileIdBothDirectoryInformation fileIDBothDirectoryInfo = (FileIdBothDirectoryInformation)fileInformation; FindFileIDBothDirectoryInfo result = new FindFileIDBothDirectoryInfo(); result.FileIndex = fileIDBothDirectoryInfo.FileIndex; result.CreationTime = fileIDBothDirectoryInfo.CreationTime; result.LastAccessTime = fileIDBothDirectoryInfo.LastAccessTime; result.LastWriteTime = fileIDBothDirectoryInfo.LastWriteTime; result.LastChangeTime = fileIDBothDirectoryInfo.LastWriteTime; result.EndOfFile = fileIDBothDirectoryInfo.EndOfFile; result.AllocationSize = fileIDBothDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileIDBothDirectoryInfo.FileAttributes; result.EASize = fileIDBothDirectoryInfo.EaSize; result.Reserved = fileIDBothDirectoryInfo.Reserved1; result.ShortName = fileIDBothDirectoryInfo.ShortName; result.Reserved2 = fileIDBothDirectoryInfo.Reserved2; result.FileID = fileIDBothDirectoryInfo.FileId; result.FileName = fileIDBothDirectoryInfo.FileName; return(result); } else { throw new NotImplementedException(); } }
private IEnumerable <string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption, ISMBCredential credential) { if (!path.IsSharePath()) { return(base.EnumerateFileSystemEntries(path, searchPattern, searchOption)); } if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\""); } NTStatus status = NTStatus.STATUS_SUCCESS; if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); status = fileStore.CreateFile(out object handle, out FileStatus fileStatus, relativePath, AccessMask.GENERIC_READ, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, searchPattern, FileInformationClass.FileDirectoryInformation); List <string> files = new List <string>(); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == "." || fileDirectoryInformation.FileName == ".." || fileDirectoryInformation.FileName == ".DS_Store") { continue; } if (fileDirectoryInformation.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory)) { if (searchOption == SearchOption.AllDirectories) { files.AddRange(EnumerateFileSystemEntries(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName), searchPattern, searchOption, credential)); } } files.Add(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName)); } } fileStore.CloseFile(handle); return(files); } }
public void Delete(string path, bool recursive, ISMBCredential credential) { if (!path.IsSharePath()) { base.Delete(path, recursive); return; } if (recursive) { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\""); } NTStatus status = NTStatus.STATUS_SUCCESS; if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); int attempts = 0; int allowedRetrys = 3; object handle; do { attempts++; status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, AccessMask.GENERIC_READ, 0, ShareAccess.Delete, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); }while (status == NTStatus.STATUS_PENDING && attempts < allowedRetrys); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, "*", FileInformationClass.FileDirectoryInformation); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == "." || fileDirectoryInformation.FileName == ".." || fileDirectoryInformation.FileName == ".DS_Store") { continue; } else if (fileDirectoryInformation.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory)) { Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName), recursive, credential); } _fileSystem.File.Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName)); } } fileStore.CloseFile(handle); Delete(path, credential); } } else { Delete(path); } }
private static QueryDirectoryFileInformation FromFileSystemEntry(FileSystemEntry entry, FileInformationClass informationClass) { switch (informationClass) { case FileInformationClass.FileBothDirectoryInformation: { FileBothDirectoryInformation result = new FileBothDirectoryInformation(); result.CreationTime = entry.CreationTime; result.LastAccessTime = entry.LastAccessTime; result.LastWriteTime = entry.LastWriteTime; result.ChangeTime = entry.LastWriteTime; result.EndOfFile = (long)entry.Size; result.AllocationSize = (long)GetAllocationSize(entry.Size); result.FileAttributes = GetFileAttributes(entry); result.EaSize = 0; result.FileName = entry.Name; return(result); } case FileInformationClass.FileDirectoryInformation: { FileDirectoryInformation result = new FileDirectoryInformation(); result.CreationTime = entry.CreationTime; result.LastAccessTime = entry.LastAccessTime; result.LastWriteTime = entry.LastWriteTime; result.ChangeTime = entry.LastWriteTime; result.EndOfFile = (long)entry.Size; result.AllocationSize = (long)GetAllocationSize(entry.Size); result.FileAttributes = GetFileAttributes(entry); result.FileName = entry.Name; return(result); } case FileInformationClass.FileFullDirectoryInformation: { FileFullDirectoryInformation result = new FileFullDirectoryInformation(); result.CreationTime = entry.CreationTime; result.LastAccessTime = entry.LastAccessTime; result.LastWriteTime = entry.LastWriteTime; result.ChangeTime = entry.LastWriteTime; result.EndOfFile = (long)entry.Size; result.AllocationSize = (long)GetAllocationSize(entry.Size); result.FileAttributes = GetFileAttributes(entry); result.EaSize = 0; result.FileName = entry.Name; return(result); } case FileInformationClass.FileIdBothDirectoryInformation: { FileIdBothDirectoryInformation result = new FileIdBothDirectoryInformation(); result.CreationTime = entry.CreationTime; result.LastAccessTime = entry.LastAccessTime; result.LastWriteTime = entry.LastWriteTime; result.ChangeTime = entry.LastWriteTime; result.EndOfFile = (long)entry.Size; result.AllocationSize = (long)GetAllocationSize(entry.Size); result.FileAttributes = GetFileAttributes(entry); result.EaSize = 0; result.FileId = 0; result.FileName = entry.Name; return(result); } case FileInformationClass.FileIdFullDirectoryInformation: { FileIdFullDirectoryInformation result = new FileIdFullDirectoryInformation(); result.CreationTime = entry.CreationTime; result.LastAccessTime = entry.LastAccessTime; result.LastWriteTime = entry.LastWriteTime; result.ChangeTime = entry.LastWriteTime; result.EndOfFile = (long)entry.Size; result.AllocationSize = (long)GetAllocationSize(entry.Size); result.FileAttributes = GetFileAttributes(entry); result.EaSize = 0; result.FileId = 0; result.FileName = entry.Name; return(result); } case FileInformationClass.FileNamesInformation: { FileNamesInformation result = new FileNamesInformation(); result.FileName = entry.Name; return(result); } default: { throw new UnsupportedInformationLevelException(); } } }
/// <exception cref="SMBLibrary.UnsupportedInformationLevelException"></exception> public static FindInformation GetFindInformation(QueryDirectoryFileInformation entry, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) { switch (informationLevel) { case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO: { FileDirectoryInformation fileDirectoryInfo = (FileDirectoryInformation)entry; FindFileDirectoryInfo result = new FindFileDirectoryInfo(); result.FileIndex = fileDirectoryInfo.FileIndex; result.CreationTime = fileDirectoryInfo.CreationTime; result.LastAccessTime = fileDirectoryInfo.LastAccessTime; result.LastWriteTime = fileDirectoryInfo.LastWriteTime; result.LastAttrChangeTime = fileDirectoryInfo.LastWriteTime; result.EndOfFile = fileDirectoryInfo.EndOfFile; result.AllocationSize = fileDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileDirectoryInfo.FileAttributes; result.FileName = fileDirectoryInfo.FileName; return(result); } case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO: { FileFullDirectoryInformation fileFullDirectoryInfo = (FileFullDirectoryInformation)entry; FindFileFullDirectoryInfo result = new FindFileFullDirectoryInfo(); result.FileIndex = fileFullDirectoryInfo.FileIndex; result.CreationTime = fileFullDirectoryInfo.CreationTime; result.LastAccessTime = fileFullDirectoryInfo.LastAccessTime; result.LastWriteTime = fileFullDirectoryInfo.LastWriteTime; result.LastAttrChangeTime = fileFullDirectoryInfo.LastWriteTime; result.EndOfFile = fileFullDirectoryInfo.EndOfFile; result.AllocationSize = fileFullDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileFullDirectoryInfo.FileAttributes; result.EASize = fileFullDirectoryInfo.EaSize; result.FileName = fileFullDirectoryInfo.FileName; return(result); } case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO: { FileNamesInformation fileNamesInfo = (FileNamesInformation)entry; FindFileNamesInfo result = new FindFileNamesInfo(); result.FileIndex = fileNamesInfo.FileIndex; result.FileName = fileNamesInfo.FileName; return(result); } case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO: { FileBothDirectoryInformation fileBothDirectoryInfo = (FileBothDirectoryInformation)entry; FindFileBothDirectoryInfo result = new FindFileBothDirectoryInfo(); result.FileIndex = fileBothDirectoryInfo.FileIndex; result.CreationTime = fileBothDirectoryInfo.CreationTime; result.LastAccessTime = fileBothDirectoryInfo.LastAccessTime; result.LastWriteTime = fileBothDirectoryInfo.LastWriteTime; result.LastChangeTime = fileBothDirectoryInfo.LastWriteTime; result.EndOfFile = fileBothDirectoryInfo.EndOfFile; result.AllocationSize = fileBothDirectoryInfo.AllocationSize; result.ExtFileAttributes = (ExtendedFileAttributes)fileBothDirectoryInfo.FileAttributes; result.EASize = fileBothDirectoryInfo.EaSize; result.Reserved = fileBothDirectoryInfo.Reserved; result.ShortName = fileBothDirectoryInfo.ShortName; result.FileName = fileBothDirectoryInfo.FileName; return(result); } default: { throw new UnsupportedInformationLevelException(); } } }
public override bool Exists(string path) { if (!path.IsSharePath()) { return(base.Exists(path)); } // For some reason Directory.Exists is returning true if a file exists at that path. // File.Exists works properly so as long as we check it here we are fine. if (_fileSystem.File.Exists(path)) { return(false); } ISMBFileStore fileStore = null; object handle = null; try { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to determine if {path} exists", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } NTStatus status = NTStatus.STATUS_SUCCESS; var credential = _credentialProvider.GetSMBCredential(path); using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); _logger?.LogTrace( $"Trying to determine if {{RelativePath: {relativePath}}} Exists for {{ShareName: {shareName}}}"); if (string.IsNullOrEmpty(relativePath)) { return(true); } var parentFullPath = path.GetParentPath(); var parentPath = parentFullPath.RelativeSharePath(); var directoryName = path.GetLastPathSegment().RemoveLeadingAndTrailingSeperators(); fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); status = fileStore.CreateFile(out handle, out FileStatus fileStatus, parentPath, AccessMask.GENERIC_READ, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, string.IsNullOrEmpty(directoryName) ? "*" : directoryName, FileInformationClass.FileDirectoryInformation); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == directoryName) { return(true); } } } } return(false); } catch (Exception ex) { _logger?.LogTrace(ex, $"Failed to determine if {path} exists."); return(false); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } }
private IEnumerable <string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption, ISMBCredential credential) { if (!path.IsSharePath()) { return(base.EnumerateFiles(path, searchPattern, searchOption)); } if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to EnumerateFiles for {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } NTStatus status = NTStatus.STATUS_SUCCESS; if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } if (credential == null) { throw new SMBException($"Failed to EnumerateFiles for {path}", new InvalidCredentialException($"Unable to find credential in SMBCredentialProvider for path: {path}")); } ISMBFileStore fileStore = null; object handle = null; try { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); _logger?.LogTrace($"Trying to EnumerateFiles for {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}"); using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, AccessMask.GENERIC_READ, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, searchPattern, FileInformationClass.FileDirectoryInformation); _logger?.LogTrace($"Found {queryDirectoryFileInformation.Count} FileDirectoryInformation for {path}"); List <string> files = new List <string>(); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == "." || fileDirectoryInformation.FileName == ".." || fileDirectoryInformation.FileName == ".DS_Store") { continue; } if (fileDirectoryInformation.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory)) { if (searchOption == SearchOption.AllDirectories) { files.AddRange(EnumerateFiles(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName), searchPattern, searchOption, credential)); } } else { files.Add(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName.RemoveLeadingAndTrailingSeperators())); } } } FileStoreUtilities.CloseFile(fileStore, ref handle); return(files); } } catch (Exception ex) { throw new SMBException($"Failed to EnumerateFiles {path}", ex); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } }
public void Delete(string path, bool recursive, ISMBCredential credential) { if (!path.IsSharePath()) { base.Delete(path, recursive); return; } if (recursive) { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to Delete {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } if (credential == null) { throw new SMBException($"Failed to Delete {path}", new InvalidCredentialException("Unable to find credential in SMBCredentialProvider for path: {path}")); } ISMBFileStore fileStore = null; object handle = null; try { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); _logger?.LogTrace($"Trying to Delete {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}"); using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize)) { fileStore = connection.SMBClient.TreeConnect(shareName, out var status); status.HandleStatus(); AccessMask accessMask = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ; ShareAccess shareAccess = ShareAccess.Delete; CreateDisposition disposition = CreateDisposition.FILE_OPEN; CreateOptions createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE; var stopwatch = new Stopwatch(); stopwatch.Start(); do { if (status == NTStatus.STATUS_PENDING) { _logger.LogTrace($"STATUS_PENDING while trying to delete directory {path}. {stopwatch.Elapsed.TotalSeconds}/{_smbFileSystemSettings.ClientSessionTimeout} seconds elapsed."); } status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess, disposition, createOptions, null); } while (status == NTStatus.STATUS_PENDING && stopwatch.Elapsed.TotalSeconds <= _smbFileSystemSettings.ClientSessionTimeout); stopwatch.Stop(); status.HandleStatus(); fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, "*", FileInformationClass.FileDirectoryInformation); foreach (var file in queryDirectoryFileInformation) { if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation) { FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file; if (fileDirectoryInformation.FileName == "." || fileDirectoryInformation.FileName == ".." || fileDirectoryInformation.FileName == ".DS_Store") { continue; } else if (fileDirectoryInformation.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory)) { Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName), recursive, credential); } _fileSystem.File.Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName)); } } FileStoreUtilities.CloseFile(fileStore, ref handle); Delete(path, credential); } } catch (Exception ex) { throw new SMBException($"Failed to Delete {path}", ex); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } } else { Delete(path); } }