PathAvailableSpace() static private method

Return the number of available bytes in the specified file path.
DriveInfo.AvailableFreeSpace gives this information, but only for drives. This makes it less useful as paths may contain NTFS junction points, symbolic links, or be UNC paths.
static private PathAvailableSpace ( string path ) : ulong
path string The standard or UNC path to retrieve available bytes for.
return ulong
        private void DownloadProgThread()
        {
            // Raise a progress event to give the user some feedback
            this.Progress?.Invoke(this.episodeInfo.Epid, 0, Provider.ProgressType.Downloading);

            if (!Provider.Handler.Exists(this.pluginId))
            {
                this.DownloadError(Provider.ErrorType.LocalProblem, "The plugin provider required to download this episode is not currently available.  Please try updating the Radio Downloader providers or cancelling the download.");
                return;
            }

            lock (this.pluginInstanceLock)
            {
                this.pluginInstance           = Provider.Handler.GetFromId(this.pluginId).CreateInstance();
                this.pluginInstance.Progress += this.DownloadPluginInst_Progress;
            }

            string saveLocation;

            try
            {
                saveLocation = FileUtils.GetSaveFolder();
            }
            catch (DirectoryNotFoundException)
            {
                this.DownloadError(Provider.ErrorType.LocalProblem, "Your chosen location for saving downloaded programmes no longer exists.  Select a new one under Options -> Main Options.");
                return;
            }

            const int FreeMb         = 250;
            ulong     availableSpace = OsUtils.PathAvailableSpace(saveLocation);

            if (availableSpace <= FreeMb * 1024 * 1024)
            {
                this.DownloadError(Provider.ErrorType.LocalProblem, "Your chosen location for saving downloaded programmes does not have enough free space.  Make sure that you have at least " + FreeMb.ToString(CultureInfo.CurrentCulture) + " MB free, or select a new location under Options -> Main Options.");
                return;
            }

            Provider.DownloadInfo info = null;

            try
            {
                try
                {
                    info = this.pluginInstance.DownloadProgramme(this.progExtId, this.episodeExtId, this.providerProgInfo, this.providerEpisodeInfo);
                }
                catch (Provider.DownloadException downloadExp)
                {
                    if (downloadExp.ErrorType == Provider.ErrorType.UnknownError)
                    {
                        this.DownloadError(downloadExp);
                    }
                    else
                    {
                        this.DownloadError(downloadExp.ErrorType, downloadExp.Message);
                    }

                    return;
                }
                catch (Exception unknownExp)
                {
                    this.DownloadError(unknownExp);
                    return;
                }

                if (this.cancelled)
                {
                    this.cancelResponse = true;
                    return;
                }

                string finalName;

                try
                {
                    finalName = Model.Download.MoveToSaveFolder(Settings.FileNameFormat, this.progInfo, this.episodeInfo, saveLocation, info.Extension, info.Downloaded.FilePath);
                }
                catch (IOException ioExp)
                {
                    this.DownloadError(Provider.ErrorType.LocalProblem, "Encountered an error saving the downloaded file.  " + ioExp.Message + "  You may need to select a new location for saving downloaded programmes under Options -> Main Options.");
                    return;
                }
                catch (UnauthorizedAccessException unAuthExp)
                {
                    this.DownloadError(Provider.ErrorType.LocalProblem, "Encountered a permissions problem saving the downloaded file.  " + unAuthExp.Message + "  You may need to select a new location for saving downloaded programmes under Options -> Main Options.");
                    return;
                }

                lock (DbUpdateLock)
                {
                    Model.Download.SetComplete(this.episodeInfo.Epid, finalName, info);
                    Model.Programme.SetLatestDownload(this.progInfo.Progid, this.episodeInfo.Date);
                }

                // Remove single episode subscriptions
                if (Model.Subscription.IsSubscribed(this.progInfo.Progid))
                {
                    if (this.progInfo.SingleEpisode)
                    {
                        Model.Subscription.Remove(this.progInfo.Progid);
                    }
                }

                if (!string.IsNullOrEmpty(Settings.RunAfterCommand))
                {
                    try
                    {
                        // Use VB Interaction.Shell as Process.Start doesn't give the option of a non-focused window
                        // The "comspec" environment variable gives the path to cmd.exe
                        Microsoft.VisualBasic.Interaction.Shell("\"" + Environment.GetEnvironmentVariable("comspec") + "\" /c " + Settings.RunAfterCommand.Replace("%file%", finalName), Microsoft.VisualBasic.AppWinStyle.NormalNoFocus);
                    }
                    catch
                    {
                        // Just ignore the error, as it just means that something has gone wrong with the run after command.
                    }
                }
            }
            finally
            {
                info?.Dispose();
            }

            this.DownloadFinished();
        }