예제 #1
0
        /// <summary>
        /// Returns the volume serial of the drive where this path resides or empty if no serial is found.
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static string GetDriveVolumeSerial(this FileSystemInfo self)
        {
            DriveInfo driveInfo = self.GetDriveInfo();
            string    serial    = (driveInfo != null) ? driveInfo.GetVolumeSerial() : string.Empty;

            return(serial);
        }
예제 #2
0
        /// <summary>
        /// Gets a value indicating if the FileSystemInfo object is currently available
        /// </summary>
        /// <param name="fsInfo"></param>
        /// <param name="serial">if a serial is specified the return value is more reliable.</param>
        /// <returns></returns>
        public static bool IsAvailable(FileSystemInfo fsInfo, string recordedSerial)
        {
            // Get Drive Information
            DriveInfo driveInfo = GetDriveInfo(fsInfo);

            // Refresh the object information (important)
            fsInfo.Refresh();

            // Check if the file exists
            bool fileExists = fsInfo.Exists;

            // Do we have a logical volume?
            if (driveInfo != null && fileExists)
            {
                string currentSerial = driveInfo.GetVolumeSerial();
                // if we have both the recorded and the current serial we can do this very exact
                // by checking if the serials match
                if (!String.IsNullOrEmpty(recordedSerial) && !String.IsNullOrEmpty(currentSerial))
                {
                    // return the exact check result
                    return(currentSerial == recordedSerial);
                }
            }

            // return the simple check result
            return(fileExists);
        }
예제 #3
0
        /// <summary>
        /// Gets the disk serial of the drive were the path is located.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetVolumeSerial(string path)
        {
            DriveInfo driveInfo = GetDriveInfo(path);

            if (driveInfo != null && driveInfo.IsReady)
            {
                return(driveInfo.GetVolumeSerial());
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #4
0
        public List <DBLocalMedia> GetLocalMedia(bool returnOnlyNew)
        {
            logger.Debug("Scanning: {0}", Directory.FullName);

            // default values
            string volume = string.Empty;
            string label  = string.Empty;
            string serial = string.Empty;
            string format = string.Empty;

            // validate the import path
            if (!_replaced && this.IsAvailable)
            {
                if (!this.IsUnc)
                {
                    // Logical volume (can be a mapped network share)
                    int retry = 0;
                    while (serial == string.Empty)
                    {
                        // Grab information for this logical volume
                        DriveInfo driveInfo = Directory.GetDriveInfo();
                        if (driveInfo != null && driveInfo.IsReady)
                        {
                            // get the volume properties
                            volume = driveInfo.GetDriveLetter();
                            label  = driveInfo.VolumeLabel;
                            serial = driveInfo.GetVolumeSerial();
                            format = driveInfo.DriveFormat;
                            logger.Debug("Drive='{0}', Label='{1}', Serial='{2}', Format='{3}'", volume, label, serial, format);
                        }

                        // check if the serial is empty
                        // logical volumes SHOULD have a serial number or something went wrong
                        // Currently the only exception is when a NDFS filesystem is detected to cover the special case of network paths mounted by 3rd party programs
                        // todo: to prevent more exceptions in the future we should keep an eye out for these special cases and come up with a better solution
                        if (serial == string.Empty && format != "NDFS")
                        {
                            // If we tried 3 times already then we should report a failure
                            if (retry == 3)
                            {
                                logger.Error("Canceled scan for '{0}': Could not get required volume information.", Directory.FullName);
                                return(null);
                            }

                            // up the retry count and wait for 1 second
                            retry++;
                            Thread.Sleep(1000);
                            logger.Debug("Retrying: {1} ({0})", Directory.FullName, retry);
                        }
                    }
                } // todo: for UNC paths we could consider using the host part of the UNC path as the MediaLabel (ex. '//SomeHost/../..' => 'SomeHost')
            }
            else
            {
                if (this.IsRemovable)
                {
                    if (this.IsUnc)
                    {
                        // network share
                        logger.Info("Skipping scan for '{0}': the share is offline.", Directory.FullName);
                    }
                    else if (this.IsOpticalDrive)
                    {
                        // optical drive
                        logger.Info("Skipping scan for '{0}': the drive is empty.", Directory.FullName);
                    }
                    else
                    {
                        // all other removable paths
                        logger.Info("Skipping scan for '{0}': the volume is disconnected.", Directory.FullName);
                    }
                }
                else
                {
                    logger.Error("Scan for '{0}' was cancelled because the import path is not available.", Directory.FullName);
                }

                // returning nothing
                return(null);
            }

            // Grab the list of files and validate them
            List <DBLocalMedia> rtn = new List <DBLocalMedia>();

            try {
                List <FileInfo> fileList = null;

                // When the option to ignore interactive content is enabled (applies to optical drives that are internally managed)
                // we first check for known video formats (DVD, Bluray etc..) before we are going to scan for all files on the disc.
                if (MovingPicturesCore.Settings.IgnoreInteractiveContentOnVideoDisc && IsOpticalDrive && InternallyManaged)
                {
                    string videoPath = VideoUtility.GetVideoPath(Directory.FullName);
                    if (VideoUtility.IsVideoDisc(videoPath))
                    {
                        // if we found one we can safely asume by standards that this will be the
                        // only valid video file on the disc so we create the filelist and add only this file
                        fileList = new List <FileInfo>();
                        fileList.Add(new FileInfo(videoPath));
                    }
                }

                // if the fileList is null it means that we didn't find an 'exclusive' video file above
                // and we are going to scan the whole tree
                if (fileList == null)
                {
                    fileList = VideoUtility.GetVideoFilesRecursive(Directory);
                }

                // go through the video file list
                DriveType type = GetDriveType();
                foreach (FileInfo videoFile in fileList)
                {
                    // Create or get a localmedia object from the video file path
                    DBLocalMedia newFile = DBLocalMedia.Get(videoFile.FullName, serial);

                    // The file is in the database
                    if (newFile.ID != null)
                    {
                        // for optical paths + DVD we have to check the actual DiscId
                        // todo: add bluray disc id support
                        if (IsOpticalDrive)
                        {
                            if ((newFile.IsDVD) && !newFile.IsAvailable)
                            {
                                string discId = newFile.VideoFormat.GetIdentifier(newFile.FullPath);
                                // Create/get a DBLocalMedia object using the the DiscID
                                newFile = DBLocalMedia.GetDisc(videoFile.FullName, discId);
                            }
                        }

                        // If the file is still in the database continue if we only want new files
                        if (newFile.ID != null && returnOnlyNew)
                        {
                            continue;
                        }
                    }
                    else if (!IsOpticalDrive && !IsUnc)
                    {
                        // Verify the new file, if we find a similar file it could be that the serial has changed
                        List <DBLocalMedia> otherFiles = DBLocalMedia.GetAll(newFile.FullPath);
                        if (otherFiles.Count == 1)
                        {
                            DBLocalMedia otherFile = otherFiles[0];
                            if (type != DriveType.Unknown && type != DriveType.CDRom && type != DriveType.NoRootDirectory)
                            {
                                bool fileAvailable = otherFile.IsAvailable;
                                if ((String.IsNullOrEmpty(otherFile.VolumeSerial) && fileAvailable) || (!fileAvailable && File.Exists(otherFile.FullPath)))
                                {
                                    // the disk serial was updated for this file
                                    otherFile.VolumeSerial = serial;
                                    otherFile.MediaLabel   = label;
                                    otherFile.Commit();
                                    logger.Info("Disk information updated for '{0}'", otherFile.FullPath);
                                    continue;
                                }
                            }
                        }
                    }

                    // NEW FILE

                    // Add additional file information
                    newFile.ImportPath   = this;
                    newFile.VolumeSerial = serial;
                    newFile.MediaLabel   = label;

                    // add the localmedia object to our return list
                    logger.Debug("New File: {0}", videoFile.Name);
                    rtn.Add(newFile);
                }
            }
            catch (Exception e) {
                if (e.GetType() == typeof(ThreadAbortException))
                {
                    throw e;
                }


                if (logger.IsDebugEnabled)
                {
                    // In debug mode we log the geeky version
                    logger.DebugException("Error scanning '" + Directory.FullName + "'", e);
                }
                else
                {
                    // In all other modes we do it more friendlier
                    logger.Error("Error scanning '{0}': {1}", Directory.FullName, e.Message);
                }
            }

            return(rtn);
        }
예제 #5
0
        private static void WatchDisks()
        {
            while (true)
            {
                lock (syncRoot) {
                    if (driveStates == null)
                    {
                        driveStates = new Dictionary <string, bool>();
                    }

                    foreach (string currDrive in watchedDrives)
                    {
                        try {
                            // check if the drive is available
                            bool      isAvailable;
                            DriveInfo driveInfo = DriveInfoHelper.GetDriveInfo(currDrive);
                            if (driveInfo == null)
                            {
                                isAvailable = false;
                            }
                            else
                            {
                                isAvailable = driveInfo.IsReady;
                            }

                            // if the previous drive state is not stored, store it and continue
                            if (!driveStates.ContainsKey(currDrive))
                            {
                                driveStates[currDrive] = isAvailable;
                                continue;
                            }

                            // if a change has occured
                            if (driveStates[currDrive] != isAvailable)
                            {
                                // update our state
                                driveStates[currDrive] = isAvailable;

                                // notify any listeners
                                if (isAvailable)
                                {
                                    if (driveInfo.DriveType != DriveType.Network)
                                    {
                                        logger.Info("Volume Inserted: " + currDrive);
                                    }
                                    else
                                    {
                                        logger.Info("Volume Online: " + currDrive);
                                    }

                                    if (OnVolumeInserted != null)
                                    {
                                        OnVolumeInserted(currDrive, driveInfo.GetVolumeSerial());
                                    }
                                }
                                else
                                {
                                    // if a mapped network share gets disconnected it can either show Network or NoRootDirectory
                                    if (driveInfo.DriveType != DriveType.Network && driveInfo.DriveType != DriveType.NoRootDirectory)
                                    {
                                        logger.Info("Volume Removed: " + currDrive);
                                    }
                                    else
                                    {
                                        logger.Info("Volume Offline: " + currDrive);
                                    }

                                    if (OnVolumeRemoved != null)
                                    {
                                        OnVolumeRemoved(currDrive, null);
                                    }
                                }
                            }
                        }
                        catch (Exception e) {
                            if (e is ThreadAbortException)
                            {
                                throw e;
                            }

                            logger.ErrorException("Unexpected error in Disk Watcher thread!", e);
                        }
                    }
                }
                Thread.Sleep(5000);
            }
        }