internal IDriveInfo FromDriveName(string shareName, ISMBCredential credential) { if (credential == null) { credential = _smbCredentialProvider.GetSMBCredentials().Where(c => c.Path.ShareName().Equals(shareName)).FirstOrDefault(); if (credential == null) { return(null); } } var path = credential.Path; if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\""); } NTStatus status = NTStatus.STATUS_SUCCESS; using var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize); var relativePath = path.RelativeSharePath(); ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); var smbFileSystemInformation = new SMBFileSystemInformation(fileStore, path, status); var smbDriveInfo = new SMBDriveInfo(path, _fileSystem, smbFileSystemInformation, credential); return(smbDriveInfo); }
protected override void Dispose(bool disposing) { if (!this.disposedValue) { if (disposing) { if (this.Handle != null) { try { this._store?.CloseFile(this.Handle); } catch (Exception) { } } this._store = null; this.Handle = null; } this.disposedValue = true; } base.Dispose(disposing); }
public static async Task <SMBFileShare> ConnectAsync(IPAddress address, string share, string username = "", string password = "") { return(await Task.Run(() => { SMB2Client client = new SMB2Client(); bool isConnected = client.Connect(address, SMBTransportType.DirectTCPTransport); if (!isConnected) { throw new Exception($"Could not connect to {address}"); } NTStatus status = client.Login(string.Empty, username, password); if (status != NTStatus.STATUS_SUCCESS) { throw new Exception($"Could not login: {status}"); } ISMBFileStore fileStore = client.TreeConnect(share, out status); if (status != NTStatus.STATUS_SUCCESS) { throw new Exception($"Could not access share: {status}"); } return new SMBFileShare(client, fileStore); }).ConfigureAwait(false)); }
public Smb2Handler( ISMBFileStore store, string path, HandleType handleType, NodeType nodeType ) : base(SmbType.Smb2, store, path, handleType, nodeType) { }
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); } }
public SMBStream(ISMBFileStore fileStore, object fileHandle, SMBConnection connection, long fileLength) { _fileStore = fileStore; _fileHandle = fileHandle; _connection = connection; _maxReadSize = Convert.ToInt32(_connection.SMBClient.MaxReadSize); _maxWriteSize = Convert.ToInt32(_connection.SMBClient.MaxWriteSize); _length = fileLength; }
internal void SaveDirectoryInfo(SMBDirectoryInfo dirInfo, ISMBCredential credential = null) { var path = dirInfo.FullName; if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to SaveDirectoryInfo 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 SaveDirectoryInfo for {path}", new InvalidCredentialException($"Unable to find credential for path: {path}")); } ISMBFileStore fileStore = null; object handle = null; try { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); _logger?.LogTrace($"Trying to SaveDirectoryInfo {{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_WRITE, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); var fileInfo = dirInfo.ToSMBFileInformation(credential); status = fileStore.SetFileInformation(handle, fileInfo); status.HandleStatus(); } catch (Exception ex) { throw new SMBException($"Failed to SaveDirectoryInfo for {path}", ex); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } }
public static void CloseFile(ISMBFileStore fileStore, ref object fileHandle) { if (fileStore == null || fileHandle == null) { return; } fileStore.CloseFile(fileHandle); fileHandle = null; }
public void readSmbFile() { SMB1Client client = new SMB1Client(); // SMB2Client can be used as well bool isConnected = client.Connect(IPAddress.Parse("192.168.10.200"), SMBTransportType.DirectTCPTransport); if (isConnected) { NTStatus status = client.Login(String.Empty, "jing.luo", "ximai_2016"); ISMBFileStore fileStore = client.TreeConnect("software", out status); object fileHandle; FileStatus fileStatus; string filePath = "EXCEL在财务管理中的高级应用.pdf"; if (fileStore is SMB1FileStore) { filePath = @"\\" + filePath; } status = fileStore.CreateFile(out fileHandle, out fileStatus, filePath, AccessMask.GENERIC_READ | AccessMask.SYNCHRONIZE, (SMBLibrary.FileAttributes)System.IO.FileAttributes.Normal, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null); if (status == NTStatus.STATUS_SUCCESS) { System.IO.MemoryStream stream = new System.IO.MemoryStream(); byte[] data; long bytesRead = 0; while (true) { status = fileStore.ReadFile(out data, fileHandle, bytesRead, (int)client.MaxReadSize); if (status != NTStatus.STATUS_SUCCESS && status != NTStatus.STATUS_END_OF_FILE) { throw new Exception("Failed to read from file"); } if (status == NTStatus.STATUS_END_OF_FILE || data.Length == 0) { break; } bytesRead += data.Length; stream.Write(data, 0, data.Length); } } status = fileStore.CloseFile(fileHandle); status = fileStore.Disconnect(); } //if (status == NTStatus.STATUS_SUCCESS) //{ // List<string> shares = client.ListShares(out status); // client.Logoff(); //} //client.Disconnect(); }
internal void Delete(string path, ISMBCredential credential) { if (!path.IsSharePath()) { base.Delete(path); return; } 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); } if (EnumerateFileSystemEntries(path).Count() > 0) { throw new IOException("Cannot delete directory. Directory is not empty."); } 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.DELETE, 0, ShareAccess.Delete, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DELETE_ON_CLOSE, null); }while (status == NTStatus.STATUS_PENDING && attempts < allowedRetrys); status.HandleStatus(); // This is the correct delete command, but it doesn't work for some reason. You have to use FILE_DELETE_ON_CLOSE // fileStore.SetFileInformation(handle, new FileDispositionInformation()); fileStore.CloseFile(handle); } }
public SMBStream(ISMBFileStore fileStore, object fileHandle, SMBConnection connection, long fileLength, ISmbFileSystemSettings smbFileSystemSettings = null) { _smbFileSystemSettings = smbFileSystemSettings ?? new SmbFileSystemSettings(); _fileStore = fileStore; _fileHandle = fileHandle; _connection = connection; _maxReadSize = Convert.ToInt32(_connection.SMBClient.MaxReadSize); _maxWriteSize = Convert.ToInt32(_connection.SMBClient.MaxWriteSize); _length = fileLength; }
public SMBReadStream(ISMBFileStore fileStore, int maxReadSize, string path) { this.fileStore = fileStore; this.maxReadSize = maxReadSize; NTStatus status = fileStore.CreateFile(out fileHandle, out FileStatus _, path, AccessMask.GENERIC_READ | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null); if (status != NTStatus.STATUS_SUCCESS) { throw new IOException($"Failed to read from file: {status}"); } }
public NTStatus BindPipe() { NTStatus status; NamedPipeShare = Client.TreeConnect("IPC$", out status); if (NamedPipeShare == null) { return(status); } status = NamedPipeHelper.BindPipe(NamedPipeShare, ServicePipeName, ServiceInterfaceGuid, ServiceVersion, out pipeHandle, out maxTransmitFragmentSize); return(status); }
internal IDirectoryInfo FromDirectoryName(string path, ISMBCredential credential) { if (!path.IsSharePath() || !path.IsValidSharePath()) { return(null); } 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); } if (credential == null) { throw new Exception($"Unable to find credential for path: {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(); status = fileStore.GetFileInformation(out FileInformation fileInfo, handle, FileInformationClass.FileBasicInformation); // If you call this with any other FileInformationClass value // it doesn't work for some reason if (status != NTStatus.STATUS_SUCCESS) { return(null); } return(new SMBDirectoryInfo(path, fileInfo, _fileSystem, _credentialProvider, credential)); }
public override void Delete(string path) { if (!path.IsSharePath()) { base.Delete(path); return; } 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 relativePath = path.RelativeSharePath(); var directoryPath = _fileSystem.Path.GetDirectoryName(relativePath); 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.DELETE, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DELETE_ON_CLOSE, null); }while (status == NTStatus.STATUS_PENDING && attempts < allowedRetrys); status.HandleStatus(); // There should be a seperate option to delete, but it doesn't seem to exsist in the library we are using, so this should work for now. Really hacky though. fileStore.CloseFile(handle); } }
private void tsbExplore_Click(object sender, EventArgs e) { SMB1Client client = new SMB1Client(); // SMB2Client can be used as well bool isConnected = client.Connect(IPAddress.Parse("192.168.10.200"), SMBTransportType.DirectTCPTransport); NTStatus status = client.Login(String.Empty, "jing.luo", "ximai_2016"); if (isConnected) { if (status == NTStatus.STATUS_SUCCESS) { List <string> shares = client.ListShares(out status); foreach (var item in shares) { richTextBox1.Text += item.ToString() + " "; } } } ISMBFileStore fileStore = client.TreeConnect("5S", out status); //if (status == NTStatus.STATUS_SUCCESS) //{ // object directoryHandle; // FileStatus fileStatus; // status = fileStore.CreateFile(out directoryHandle, out fileStatus, // "\\", AccessMask.GENERIC_READ, FileAttributes.Directory, // ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, // CreateOptions.FILE_DIRECTORY_FILE, null); // if (status == NTStatus.STATUS_SUCCESS) // { // List<FindInformation> fileList2; // status = ((SMB1FileStore)fileStore).QueryDirectory(out fileList2, "\\*", // FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO); // //status = fileStore.CloseFile(directoryHandle); // foreach (var item in fileList2) // { // //richTextBox1.Text += item.; // } // } //} status = fileStore.Disconnect(); }
public List <string> ListShares(out NTStatus status) { if (!m_isConnected || !m_isLoggedIn) { throw new InvalidOperationException("A login session must be successfully established before retrieving share list"); } ISMBFileStore namedPipeShare = TreeConnect("IPC$", out status); if (namedPipeShare == null) { return(null); } List <string> shares = ServerServiceHelper.ListShares(namedPipeShare, SMBLibrary.Services.ShareType.DiskDrive, out status); namedPipeShare.Disconnect(); return(shares); }
internal void SaveDirectoryInfo(SMBDirectoryInfo dirInfo, ISMBCredential credential = null) { var path = dirInfo.FullName; 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); } if (credential == null) { throw new Exception($"Unable to find credential for path: {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_WRITE, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null); status.HandleStatus(); var fileInfo = dirInfo.ToSMBFileInformation(credential); status = fileStore.SetFileInformation(handle, fileInfo); status.HandleStatus(); }
public SMBFileSystemInformation(ISMBFileStore fileStore, string path, NTStatus status) { var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); if (status == NTStatus.STATUS_SUCCESS) { fileStore.GetFileSystemInformation(out var fileFsVolumeInformation, FileSystemInformationClass.FileFsVolumeInformation); fileStore.GetFileSystemInformation(out var fileFsDeviceInformation, FileSystemInformationClass.FileFsDeviceInformation); fileStore.GetFileSystemInformation(out var fileFsFullSizeInformation, FileSystemInformationClass.FileFsFullSizeInformation); fileStore.GetFileSystemInformation(out var fileFsAttributeInformation, FileSystemInformationClass.FileFsAttributeInformation); fileStore.GetFileSystemInformation(out var fileFsControlInformation, FileSystemInformationClass.FileFsControlInformation); fileStore.GetFileSystemInformation(out var fileFsSectorSizeInformation, FileSystemInformationClass.FileFsSectorSizeInformation); VolumeInformation = (FileFsVolumeInformation)fileFsVolumeInformation; DeviceInformation = (FileFsDeviceInformation)fileFsDeviceInformation; SizeInformation = (FileFsFullSizeInformation)fileFsFullSizeInformation; AttributeInformation = (FileFsAttributeInformation)fileFsAttributeInformation; ControlInformation = (FileFsControlInformation)fileFsControlInformation; SectorSizeInformation = (FileFsSectorSizeInformation)fileFsSectorSizeInformation; } }
public ShareBase(ISMBClient client, string name) { this.IsConnected = false; this._name = name; if (client == null) { this.AddError("Constructor", "Required client."); return; } if (string.IsNullOrEmpty(name)) { this.AddError("Constructor", "Required name."); return; } this._store = client.TreeConnect(name, out var status); this.IsConnected = (status == NTStatus.STATUS_SUCCESS); }
protected override void Dispose(bool disposing) { if (!this.disposedValue) { if (disposing) { try { this._store?.Disconnect(); } catch (Exception) { } this._store = null; this._name = null; } this.disposedValue = true; } base.Dispose(disposing); }
public HandlerBase( SmbType smbType, ISMBFileStore store, string path, HandleType handleType, NodeType nodeType ) { this.Handle = null; this.Succeeded = false; if (store == null || nodeType == NodeType.Server) { return; } this._store = store; var args = handleType.ToArgs(smbType, nodeType); var status = this._store.CreateFile( out var handle, out var handleStatus, path, args.AccessMask, args.FileAttributes, args.ShareAccess, args.CreateDisposition, args.CreateOptions, null ); if (status == NTStatus.STATUS_SUCCESS) { this.Handle = handle; this.FileStatus = handleStatus; this.Succeeded = true; } }
internal Stream Open(string path, FileMode mode, FileAccess access, FileShare share, FileOptions fileOptions, ISMBCredential credential) { if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to Open {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } NTStatus status = NTStatus.STATUS_SUCCESS; AccessMask accessMask = AccessMask.MAXIMUM_ALLOWED; ShareAccess shareAccess = ShareAccess.None; CreateDisposition disposition = CreateDisposition.FILE_OPEN; CreateOptions createOptions; switch (fileOptions) { case FileOptions.DeleteOnClose: createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DELETE_ON_CLOSE; break; case FileOptions.RandomAccess: createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_RANDOM_ACCESS; break; case FileOptions.SequentialScan: createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_SEQUENTIAL_ONLY; break; case FileOptions.WriteThrough: createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_WRITE_THROUGH; break; case FileOptions.None: case FileOptions.Encrypted: // These two are not suported unless I am missing something case FileOptions.Asynchronous: // default: createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_NON_DIRECTORY_FILE; break; } switch (access) { case FileAccess.Read: accessMask = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ; shareAccess = ShareAccess.Read; break; case FileAccess.Write: accessMask = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_WRITE; shareAccess = ShareAccess.Write; break; case FileAccess.ReadWrite: accessMask = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE; shareAccess = ShareAccess.Read | ShareAccess.Write; break; } if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } if (credential == null) { throw new SMBException($"Failed to Open {path}", new InvalidCredentialException($"Unable to find credential in SMBCredentialProvider for path: {path}")); } SMBConnection connection = null; try { connection = SMBConnection.CreateSMBConnectionForStream(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize); var shareName = path.ShareName(); var relativePath = path.RelativeSharePath(); ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); switch (mode) { case FileMode.Create: disposition = CreateDisposition.FILE_OVERWRITE_IF; break; case FileMode.CreateNew: disposition = CreateDisposition.FILE_CREATE; break; case FileMode.Open: disposition = CreateDisposition.FILE_OPEN; break; case FileMode.OpenOrCreate: disposition = CreateDisposition.FILE_OPEN_IF; break; } object handle; var stopwatch = new Stopwatch(); stopwatch.Start(); do { if (status == NTStatus.STATUS_PENDING) { _logger.LogTrace($"STATUS_PENDING while trying to open file {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(); FileInformation fileInfo; stopwatch.Reset(); stopwatch.Start(); do { status = fileStore.GetFileInformation(out fileInfo, handle, FileInformationClass.FileStandardInformation); }while (status == NTStatus.STATUS_NETWORK_NAME_DELETED && stopwatch.Elapsed.TotalSeconds <= _smbFileSystemSettings.ClientSessionTimeout); stopwatch.Stop(); status.HandleStatus(); var fileStandardInfo = (FileStandardInformation)fileInfo; Stream s = new SMBStream(fileStore, handle, connection, fileStandardInfo.EndOfFile, _smbFileSystemSettings); if (mode == FileMode.Append) { s.Seek(0, SeekOrigin.End); } return(s); } catch (Exception ex) { // Dispose connection if fail to open stream connection?.Dispose(); throw new SMBException($"Failed to Open {path}", ex); } }
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); } }
public override void Delete(string path) { if (!path.IsSharePath()) { base.Delete(path); return; } if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to Delete {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } var 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.DELETE; ShareAccess shareAccess = ShareAccess.Read | ShareAccess.Delete; CreateDisposition disposition = CreateDisposition.FILE_OPEN; CreateOptions createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DELETE_ON_CLOSE; var stopwatch = new Stopwatch(); stopwatch.Start(); do { if (status == NTStatus.STATUS_PENDING) { _logger.LogTrace($"STATUS_PENDING while trying to delete file {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(); // There should be a seperate option to delete, but it doesn't seem to exsist in the library we are using, so this should work for now. Really hacky though. FileStoreUtilities.CloseFile(fileStore, ref handle); } } catch (Exception ex) { throw new SMBException($"Failed to Delete {path}", ex); } finally { FileStoreUtilities.CloseFile(fileStore, ref handle); } }
internal IDriveInfo[] GetDrives(ISMBCredential smbCredential) { var credentialsToCheck = new List <ISMBCredential>(); credentialsToCheck = _smbCredentialProvider.GetSMBCredentials().ToList(); List <IDriveInfo> driveInfos = new List <IDriveInfo>(); if (smbCredential == null && credentialsToCheck.Count == 0) { _logger?.LogTrace($"No provided credentials and no credentials stored credentials in SMBCredentialProvider."); return(driveInfos.ToArray()); } NTStatus status = NTStatus.STATUS_SUCCESS; var shareHostNames = new List <string>(); if (smbCredential != null) { credentialsToCheck.Add(smbCredential); } else { credentialsToCheck = _smbCredentialProvider.GetSMBCredentials().ToList(); } shareHostNames = credentialsToCheck.Select(smbCredential => smbCredential.Path.Hostname()).Distinct().ToList(); var shareHostShareNames = new Dictionary <string, IEnumerable <string> >(); foreach (var shareHost in shareHostNames) { var credential = credentialsToCheck.Where(smbCredential => smbCredential.Path.Hostname().Equals(shareHost)).First(); try { var path = credential.Path; if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new SMBException($"Failed to connect to {path.Hostname()}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\"")); } using var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize); var shareNames = connection.SMBClient.ListShares(out status); var shareDirectoryInfoFactory = new SMBDirectoryInfoFactory(_fileSystem, _smbCredentialProvider, _smbClientFactory, _maxBufferSize); foreach (var shareName in shareNames) { var sharePath = path.BuildSharePath(shareName); var relativeSharePath = sharePath.RelativeSharePath(); _logger?.LogTrace($"Trying to get drive info for {shareName}"); try { ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status); status.HandleStatus(); var smbFileSystemInformation = new SMBFileSystemInformation(fileStore, sharePath, status); var smbDriveInfo = new SMBDriveInfo(sharePath, _fileSystem, smbFileSystemInformation, credential); driveInfos.Add(smbDriveInfo); } catch (IOException ioEx) { _logger?.LogTrace(ioEx, $"Failed to get drive info for {shareName}"); throw new SMBException($"Failed to get drive info for {shareName}", new AggregateException($"Unable to connect to {shareName}", ioEx)); } catch (Exception ex) { _logger?.LogTrace(ex, $"Failed to get drive info for {shareName}"); continue; } } } catch (Exception ex) { _logger?.LogTrace(ex, $"Failed to GetDrives for {shareHost}."); continue; } } return(driveInfos.ToArray()); }
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); } }
private IDirectoryInfo CreateDirectory(string path, ISMBCredential credential) { if (!path.IsSharePath()) { return(base.CreateDirectory(path)); } if (!path.TryResolveHostnameFromPath(out var ipAddress)) { throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\""); } NTStatus status = NTStatus.STATUS_SUCCESS; AccessMask accessMask = AccessMask.MAXIMUM_ALLOWED; ShareAccess shareAccess = ShareAccess.Read; CreateDisposition disposition = CreateDisposition.FILE_OPEN_IF; CreateOptions createOptions = CreateOptions.FILE_DIRECTORY_FILE; if (credential == null) { credential = _credentialProvider.GetSMBCredential(path); } if (credential == null) { throw new Exception($"Unable to find credential for path: {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, 0, shareAccess, disposition, createOptions, null); if (status == NTStatus.STATUS_OBJECT_PATH_NOT_FOUND) { CreateDirectory(path.GetParentPath(), credential); status = fileStore.CreateFile(out handle, out fileStatus, relativePath, accessMask, 0, shareAccess, disposition, createOptions, null); } }while (status == NTStatus.STATUS_PENDING && attempts < allowedRetrys); status.HandleStatus(); fileStore.CloseFile(handle); return(_directoryInfoFactory.FromDirectoryName(path, credential)); }
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); } }
public async Task <IActionResult> td([FromBody] DocumentModel[] docs) { if (docs.Length == 0) { return(new NoContentResult()); } SMB2Client client = new SMB2Client(); string site = docs[0].site; string url = _baseurl + "sites/" + site; string listname = docs[0].list; Guid listGuid = new Guid(listname); using (ClientContext cc = AuthHelper.GetClientContextForUsernameAndPassword(url, _username, _password)) try { SMBCredential SMBCredential = new SMBCredential() { username = Environment.GetEnvironmentVariable("smb_username"), password = Environment.GetEnvironmentVariable("smb_password"), domain = Environment.GetEnvironmentVariable("domain"), ipaddr = Environment.GetEnvironmentVariable("ipaddr"), share = Environment.GetEnvironmentVariable("share"), }; var serverAddress = System.Net.IPAddress.Parse(SMBCredential.ipaddr); bool success = client.Connect(serverAddress, SMBTransportType.DirectTCPTransport); NTStatus nts = client.Login(SMBCredential.domain, SMBCredential.username, SMBCredential.password); ISMBFileStore fileStore = client.TreeConnect(SMBCredential.share, out nts); List list = cc.Web.Lists.GetById(listGuid); List <Metadata> fields = SharePointHelper.GetFields(cc, list); //List list = cc.Web.Lists.GetByTitle(listname); for (int i = 0; i < docs.Length; i++) { string filename = docs[i].filename; string file_url = docs[i].file_url; var inputFields = docs[i].fields; var taxFields = docs[i].taxFields; FileCreationInformation newFile = SharePointHelper.GetFileCreationInformation(file_url, filename, SMBCredential, client, nts, fileStore); ///FileCreationInformation newFile = SharePointHelper.GetFileCreationInformation(file_url, filename); if (newFile == null) { _logger.LogError("Failed to upload. Skip: " + filename); continue; } File uploadFile; if (docs[i].foldername == null) { uploadFile = list.RootFolder.Files.Add(newFile); } else { string foldername = docs[i].foldername; string sitecontent = docs[i].sitecontent; //Folder folder = list.RootFolder.Folders.GetByUrl(foldername); Folder folder = SharePointHelper.GetFolder(cc, list, foldername); if (folder == null && taxFields != null) { folder = SharePointHelper.CreateDocumentSetWithTaxonomy(cc, list, sitecontent, foldername, inputFields, fields, taxFields); } else if (folder == null) { folder = SharePointHelper.CreateFolder(cc, list, sitecontent, foldername, inputFields, fields); } //cc.ExecuteQuery(); uploadFile = folder.Files.Add(newFile); } _logger.LogInformation("Upload file: " + newFile.Url); ListItem item = uploadFile.ListItemAllFields; if (taxFields != null) { var clientRuntimeContext = item.Context; for (int t = 0; t < taxFields.Count; t++) { var inputField = taxFields.ElementAt(t); var fieldValue = inputField.Value; var field = list.Fields.GetByInternalNameOrTitle(inputField.Key); cc.Load(field); cc.ExecuteQuery(); var taxKeywordField = clientRuntimeContext.CastTo <TaxonomyField>(field); Guid _id = taxKeywordField.TermSetId; string _termID = TermHelper.GetTermIdByName(cc, fieldValue, _id); TaxonomyFieldValue termValue = new TaxonomyFieldValue() { Label = fieldValue.ToString(), TermGuid = _termID, }; taxKeywordField.SetFieldValueByValue(item, termValue); taxKeywordField.Update(); } } DateTime dtMin = new DateTime(1900, 1, 1); Regex regex = new Regex(@"~t.*"); if (inputFields != null) { foreach (KeyValuePair <string, string> inputField in inputFields) { if (inputField.Value == null || inputField.Value == "") { continue; } string fieldValue = inputField.Value; Match match = regex.Match(fieldValue); Metadata field = fields.Find(x => x.InternalName.Equals(inputField.Key)); if (field.TypeAsString.Equals("User")) { int uid = SharePointHelper.GetUserId(cc, fieldValue); item[inputField.Key] = new FieldUserValue { LookupId = uid }; } //endre hard koding else if (inputField.Key.Equals("Modified_x0020_By") || inputField.Key.Equals("Created_x0020_By") || inputField.Key.Equals("Dokumentansvarlig")) { StringBuilder sb = new StringBuilder("i:0#.f|membership|"); sb.Append(fieldValue); item[inputField.Key] = sb; } else if (match.Success) { fieldValue = fieldValue.Replace("~t", ""); if (DateTime.TryParse(fieldValue, out DateTime dt)) { if (dtMin <= dt) { item[inputField.Key] = dt; _logger.LogInformation("Set field " + inputField.Key + "to " + dt); } else { continue; } } } else { item[inputField.Key] = fieldValue; _logger.LogInformation("Set " + inputField.Key + " to " + fieldValue); } } item.Update(); } try { await cc.ExecuteQueryAsync(); Console.WriteLine("Successfully uploaded " + newFile.Url + " and updated metadata"); } catch (System.Exception e) { _logger.LogError("Failed to update metadata."); Console.WriteLine(e); continue; } } } catch (System.Exception) { throw; } finally { client.Logoff(); client.Disconnect(); } return(new NoContentResult()); }