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);
        }
        public SMBDriveInfo(string path, IFileSystem fileSystem, SMBFileSystemInformation smbFileSystemInformation, ISMBCredential credential)
        {
            FileSystem    = fileSystem;
            DriveFormat   = smbFileSystemInformation.AttributeInformation.FileSystemName;
            Name          = path.ShareName();
            RootDirectory = _dirInfoFactory.FromDirectoryName(path, credential);
            var actualAvailableAllocationUnits = smbFileSystemInformation.SizeInformation.ActualAvailableAllocationUnits;
            var sectorsPerUnit           = smbFileSystemInformation.SizeInformation.SectorsPerAllocationUnit;
            var bytesPerSector           = smbFileSystemInformation.SizeInformation.BytesPerSector;
            var totalAllocationUnits     = smbFileSystemInformation.SizeInformation.TotalAllocationUnits;
            var availableAllocationUnits = smbFileSystemInformation.SizeInformation.CallerAvailableAllocationUnits;

            AvailableFreeSpace = availableAllocationUnits * sectorsPerUnit * bytesPerSector;
            TotalFreeSpace     = actualAvailableAllocationUnits * sectorsPerUnit * bytesPerSector;
            TotalSize          = totalAllocationUnits * sectorsPerUnit * bytesPerSector;
            _volumeLabel       = smbFileSystemInformation.VolumeInformation.VolumeLabel;
        }
        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());
        }