From d768c1f8545840f5d0809ef20ea60c972cdef6e9 Mon Sep 17 00:00:00 2001
From: sebastiii <sebastiii@team-mediaportal.com>
Date: Tue, 20 Nov 2012 20:07:11 +0100
Subject: [PATCH] WMI DetectDriver (Deda Patch)

---
 .../TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj    |    1 +
 mediaportal/Core/Core.csproj                       |    1 +
 mediaportal/Core/Util/Util.cs                      |   44 +++++++
 mediaportal/Core/Util/VirtualDirectory.cs          |   36 ++++++
 mediaportal/MediaPortal.Application/MediaPortal.cs |   18 +++
 .../WindowPlugins/GUIMusic/GUIMusicFiles.cs        |   52 +++-----
 .../WindowPlugins/GUIPictures/GUIPictures.cs       |  130 +++++++-------------
 7 files changed, 164 insertions(+), 118 deletions(-)

diff --git a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj
index 3300394..79344f9 100644
--- a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj
+++ b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj
@@ -110,6 +110,7 @@
     </Reference>
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Management" />
     <Reference Include="System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Program Files\Reference Assemblies\Microsoft\WinFX\v3.0\System.Runtime.Remoting.dll</HintPath>
diff --git a/mediaportal/Core/Core.csproj b/mediaportal/Core/Core.csproj
index e7a3c11..1dd5f87 100644
--- a/mediaportal/Core/Core.csproj
+++ b/mediaportal/Core/Core.csproj
@@ -1867,6 +1867,7 @@
     <Compile Include="Util\WindowsController.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Util\WmiExtensions.cs" />
     <Compile Include="Vista Toolbelt\NativeInterop.cs" />
     <Compile Include="Vista Toolbelt\ThumbnailGenerator.cs" />
     <Compile Include="wmfsdk\BufferTypes.cs">
diff --git a/mediaportal/Core/Util/Util.cs b/mediaportal/Core/Util/Util.cs
index 8726864..a38edce 100644
--- a/mediaportal/Core/Util/Util.cs
+++ b/mediaportal/Core/Util/Util.cs
@@ -4597,6 +4597,50 @@ namespace MediaPortal.Util
       }
       return false;
     }
+
+    /// <summary>
+    /// Returns connected USB hard disk drives letters
+    /// Works only from Vista and above
+    /// </summary>
+    /// <returns></returns>
+    public static List<string> GetAvailableUsbHardDisks()
+    {
+      List<string> disks = new List<string>();
+      
+      try
+      {
+        // browse all USB WMI physical disks
+        foreach (ManagementObject drive in
+          new ManagementObjectSearcher(
+            "select DeviceID, Model from Win32_DiskDrive where InterfaceType='USB' AND MediaType LIKE '%hard disk%'").
+            Get())
+        {
+          // associate physical disks with partitions
+          ManagementObject partition = new ManagementObjectSearcher(String.Format(
+            "associators of {{Win32_DiskDrive.DeviceID='{0}'}} where AssocClass = Win32_DiskDriveToDiskPartition",
+            drive["DeviceID"])).First();
+
+          if (partition != null)
+          {
+            // associate partitions with logical disks (drive letter volumes)
+            ManagementObject logical = new ManagementObjectSearcher(String.Format(
+              "associators of {{Win32_DiskPartition.DeviceID='{0}'}} where AssocClass = Win32_LogicalDiskToPartition",
+              partition["DeviceID"])).First();
+
+            if (logical != null)
+            {
+              disks.Add(logical["Name"].ToString());
+            }
+          }
+        }
+      }
+      catch (Exception ex)
+      {
+        Log.Error("Utils: GetUsbHardDisks Error: {0}", ex.Message);
+      }
+      
+      return disks;
+    }
   }
 
   public static class GenericExtensions
diff --git a/mediaportal/Core/Util/VirtualDirectory.cs b/mediaportal/Core/Util/VirtualDirectory.cs
index 0593084..67aebd8 100644
--- a/mediaportal/Core/Util/VirtualDirectory.cs
+++ b/mediaportal/Core/Util/VirtualDirectory.cs
@@ -109,6 +109,42 @@ namespace MediaPortal.Util
           }
           else break;
         }
+
+        List<string> usbHdd = Utils.GetAvailableUsbHardDisks();
+
+        if (usbHdd.Count > 0)
+        {
+          foreach (string drive in usbHdd)
+          {
+            bool driveFound = false;
+            string driveName = Utils.GetDriveName(drive);
+
+            if (driveName.Length == 0)
+            {
+              driveName = String.Format("({0}:) Removable", drive.Substring(0, 1).ToUpper());
+            }
+            else
+            {
+              driveName = String.Format("({0}:) {1}", drive.Substring(0, 1).ToUpper(), driveName);
+            }
+
+            foreach (var share in m_shares)
+            {
+              if (share.Path == drive)
+              {
+                driveFound = true;
+                break;
+              }
+            }
+
+            if (driveFound == false)
+            {
+              Share removableShare = new Share(driveName, drive);
+              removableShare.RuntimeAdded = true;
+              Add(removableShare);
+            }
+          }
+        }
       }
     }
 
diff --git a/mediaportal/MediaPortal.Application/MediaPortal.cs b/mediaportal/MediaPortal.Application/MediaPortal.cs
index 2368ca4..b26221b 100644
--- a/mediaportal/MediaPortal.Application/MediaPortal.cs
+++ b/mediaportal/MediaPortal.Application/MediaPortal.cs
@@ -3543,7 +3543,25 @@ public class MediaPortalApp : D3DApp, IRender
           dlgNotify.TimeOut = message.Param1;
           dlgNotify.DoModal(GUIWindowManager.ActiveWindow);
         }
+        
+        break;
 
+      case GUIMessage.MessageType.GUI_MSG_ADD_REMOVABLE_DRIVE:
+        if (!Utils.IsRemovable(message.Label))
+        {
+          VirtualDirectories.Instance.Movies.AddRemovableDrive(message.Label, message.Label2);
+          VirtualDirectories.Instance.Music.AddRemovableDrive(message.Label, message.Label2);
+          VirtualDirectories.Instance.Pictures.AddRemovableDrive(message.Label, message.Label2);
+        }
+        break;
+
+      case GUIMessage.MessageType.GUI_MSG_REMOVE_REMOVABLE_DRIVE:
+        if (!Utils.IsRemovable(message.Label))
+        {
+          VirtualDirectories.Instance.Movies.Remove(message.Label);
+          VirtualDirectories.Instance.Music.Remove(message.Label);
+          VirtualDirectories.Instance.Pictures.Remove(message.Label);
+        }
         break;
     }
   }
diff --git a/mediaportal/WindowPlugins/GUIMusic/GUIMusicFiles.cs b/mediaportal/WindowPlugins/GUIMusic/GUIMusicFiles.cs
index bcaf78b..2d119d7 100644
--- a/mediaportal/WindowPlugins/GUIMusic/GUIMusicFiles.cs
+++ b/mediaportal/WindowPlugins/GUIMusic/GUIMusicFiles.cs
@@ -131,7 +131,7 @@ namespace MediaPortal.GUI.Music
     private MapSettings _mapSettings = new MapSettings();
     private DirectoryHistory _dirHistory = new DirectoryHistory();
     private GUIListItem _selectedListItem = null;
-    private static VirtualDirectory _virtualDirectory = new VirtualDirectory();
+    private static VirtualDirectory _virtualDirectory;
 
     private int _selectedAlbum = -1;
     private int _selectedItem = -1;
@@ -237,36 +237,23 @@ namespace MediaPortal.GUI.Music
         _useFileMenu = xmlreader.GetValueAsBool("filemenu", "enabled", true);
         _fileMenuPinCode = Util.Utils.DecryptPin(xmlreader.GetValueAsString("filemenu", "pincode", string.Empty));
 
-        string strDefault = xmlreader.GetValueAsString("music", "default", string.Empty);
-        _virtualDirectory.Clear();
-        foreach (Share share in _shareList)
+        //string strDefault = xmlreader.GetValueAsString("music", "default", string.Empty);
+        _virtualDirectory = VirtualDirectories.Instance.Music;
+        if (currentFolder == string.Empty)
         {
-          if (!string.IsNullOrEmpty(share.Name))
+          if (_virtualDirectory.DefaultShare != null)
           {
-            if (strDefault == share.Name)
+            if (_virtualDirectory.DefaultShare.IsFtpShare)
             {
-              share.Default = true;
-              if (string.IsNullOrEmpty(currentFolder))
-              {
-                if (share.IsFtpShare)
-                {
-                  //remote:hostname?port?login?password?folder
-                  currentFolder = _virtualDirectory.GetShareRemoteURL(share);
-                  _startDirectory = currentFolder;
-                }
-                else
-                {
-                  currentFolder = share.Path;
-                  _startDirectory = share.Path;
-                }
-              }
+              //remote:hostname?port?login?password?folder
+              currentFolder = _virtualDirectory.GetShareRemoteURL(_virtualDirectory.DefaultShare);
+              _startDirectory = currentFolder;
+            }
+            else
+            {
+              currentFolder = _virtualDirectory.DefaultShare.Path;
+              _startDirectory = _virtualDirectory.DefaultShare.Path;
             }
-
-            _virtualDirectory.Add(share);
-          }
-          else
-          {
-            break;
           }
         }
         if (xmlreader.GetValueAsBool("music", "rememberlastfolder", false))
@@ -326,9 +313,7 @@ namespace MediaPortal.GUI.Music
     {
       base.OnAdded();
       currentFolder = string.Empty;
-      _virtualDirectory.AddDrives();
-      _virtualDirectory.SetExtensions(Util.Utils.AudioExtensions);
-
+      
       using (Profile.Settings xmlreader = new Profile.MPSettings())
       {
         MusicState.StartWindow = xmlreader.GetValueAsInt("music", "startWindow", GetID);
@@ -337,6 +322,9 @@ namespace MediaPortal.GUI.Music
 
       GUIWindowManager.OnNewAction += new OnActionHandler(GUIWindowManager_OnNewAction);
       GUIWindowManager.Receivers += new SendMessageHandler(GUIWindowManager_OnNewMessage);
+      LoadSettings();
+      _virtualDirectory.AddDrives();
+      _virtualDirectory.SetExtensions(Util.Utils.AudioExtensions);
     }
 
     public override bool Init()
@@ -376,13 +364,13 @@ namespace MediaPortal.GUI.Music
 
     protected override void OnPageLoad()
     {
+      base.OnPageLoad();
+
       if (!KeepVirtualDirectory(PreviousWindowId))
       {
         _virtualDirectory.Reset();
       }
 
-      base.OnPageLoad();
-
       if (MusicState.StartWindow != GetID)
       {
         GUIWindowManager.ReplaceWindow((int)Window.WINDOW_MUSIC_GENRE);
diff --git a/mediaportal/WindowPlugins/GUIPictures/GUIPictures.cs b/mediaportal/WindowPlugins/GUIPictures/GUIPictures.cs
index f0022f4..9c6687e 100644
--- a/mediaportal/WindowPlugins/GUIPictures/GUIPictures.cs
+++ b/mediaportal/WindowPlugins/GUIPictures/GUIPictures.cs
@@ -303,7 +303,7 @@ namespace MediaPortal.GUI.Pictures
     private static string currentFolder = string.Empty;
     private string m_strDirectoryStart = string.Empty;
     private string destinationFolder = string.Empty;
-    private static VirtualDirectory virtualDirectory = new VirtualDirectory();
+    private static VirtualDirectory _virtualDirectory;
     private MapSettings mapSettings = new MapSettings();
     private bool isFileMenuEnabled = false;
     private string fileMenuPinCode = string.Empty;
@@ -339,70 +339,27 @@ namespace MediaPortal.GUI.Pictures
         _playVideosInSlideshows = xmlreader.GetValueAsBool("pictures", "playVideosInSlideshows", false);
         isFileMenuEnabled = xmlreader.GetValueAsBool("filemenu", "enabled", true);
         fileMenuPinCode = Util.Utils.DecryptPin(xmlreader.GetValueAsString("filemenu", "pincode", string.Empty));
-        string strDefault = xmlreader.GetValueAsString("pictures", "default", string.Empty);
-        virtualDirectory.Clear();
-        for (int i = 0; i < VirtualDirectory.MaxSharesCount; i++)
+        //string strDefault = xmlreader.GetValueAsString("pictures", "default", string.Empty);
+        _virtualDirectory = VirtualDirectories.Instance.Pictures;
+        
+        if (currentFolder == string.Empty)
         {
-          string shareName = String.Format("sharename{0}", i);
-          string sharePath = String.Format("sharepath{0}", i);
-          string strPincode = String.Format("pincode{0}", i);
-
-          string shareType = String.Format("sharetype{0}", i);
-          string shareServer = String.Format("shareserver{0}", i);
-          string shareLogin = String.Format("sharelogin{0}", i);
-          string sharePwd = String.Format("sharepassword{0}", i);
-          string sharePort = String.Format("shareport{0}", i);
-          string remoteFolder = String.Format("shareremotepath{0}", i);
-          string shareViewPath = String.Format("shareview{0}", i);
-
-          Share share = new Share();
-          share.Name = xmlreader.GetValueAsString("pictures", shareName, string.Empty);
-          share.Path = xmlreader.GetValueAsString("pictures", sharePath, string.Empty);
-          string pinCode = Util.Utils.DecryptPin(xmlreader.GetValueAsString("pictures", strPincode, string.Empty));
-          if (pinCode != string.Empty)
+          if (_virtualDirectory.DefaultShare != null)
           {
-            share.Pincode = Convert.ToInt32(pinCode);
-          }
-          else
-          {
-            share.Pincode = -1;
-          }
-
-          share.IsFtpShare = xmlreader.GetValueAsBool("pictures", shareType, false);
-          share.FtpServer = xmlreader.GetValueAsString("pictures", shareServer, string.Empty);
-          share.FtpLoginName = xmlreader.GetValueAsString("pictures", shareLogin, string.Empty);
-          share.FtpPassword = xmlreader.GetValueAsString("pictures", sharePwd, string.Empty);
-          share.FtpPort = xmlreader.GetValueAsInt("pictures", sharePort, 21);
-          share.FtpFolder = xmlreader.GetValueAsString("pictures", remoteFolder, "/");
-          share.DefaultLayout = (Layout)xmlreader.GetValueAsInt("pictures", shareViewPath, (int)Layout.List);
-
-          if (share.Name.Length > 0)
-          {
-            if (strDefault == share.Name)
+            if (_virtualDirectory.DefaultShare.IsFtpShare)
             {
-              share.Default = true;
-              if (currentFolder.Length == 0)
-              {
-                if (share.IsFtpShare)
-                {
-                  //remote:hostname?port?login?password?folder
-                  currentFolder = virtualDirectory.GetShareRemoteURL(share);
-                  m_strDirectoryStart = currentFolder;
-                }
-                else
-                {
-                  currentFolder = share.Path;
-                  m_strDirectoryStart = share.Path;
-                }
-              }
+              //remote:hostname?port?login?password?folder
+              currentFolder = _virtualDirectory.GetShareRemoteURL(_virtualDirectory.DefaultShare);
+              m_strDirectoryStart = currentFolder;
+            }
+            else
+            {
+              currentFolder = _virtualDirectory.DefaultShare.Path;
+              m_strDirectoryStart = _virtualDirectory.DefaultShare.Path;
             }
-            virtualDirectory.Add(share);
-          }
-          else
-          {
-            break;
           }
         }
+
         if (xmlreader.GetValueAsBool("pictures", "rememberlastfolder", false))
         {
           string lastFolder = xmlreader.GetValueAsString("pictures", "lastfolder", currentFolder);
@@ -462,16 +419,17 @@ namespace MediaPortal.GUI.Pictures
     public override void OnAdded()
     {
       base.OnAdded();
-      virtualDirectory.AddDrives();
-      virtualDirectory.SetExtensions(Util.Utils.PictureExtensions);
+      LoadSettings();
+      _virtualDirectory.AddDrives();
+      _virtualDirectory.SetExtensions(Util.Utils.PictureExtensions);
       currentFolder = string.Empty;
       destinationFolder = string.Empty;
       thumbCreationPaths.Clear();
-      LoadSettings();
+      
       if (_enableVideoPlayback)
       {
         foreach (string ext in Util.Utils.VideoExtensions)
-          virtualDirectory.AddExtension(ext);
+          _virtualDirectory.AddExtension(ext);
       }
       GUIWindowManager.Receivers += new SendMessageHandler(GUIWindowManager_OnNewMessage);
     }
@@ -526,11 +484,11 @@ namespace MediaPortal.GUI.Pictures
 
     protected override void OnPageLoad()
     {
+      base.OnPageLoad();
       if (!KeepVirtualDirectory(PreviousWindowId))
       {
-        virtualDirectory.Reset();
+        _virtualDirectory.Reset();
       }
-      base.OnPageLoad();
       InitViewSelections();
       UpdateButtonStates();
 
@@ -652,7 +610,7 @@ namespace MediaPortal.GUI.Pictures
             currentFolder = message.Label;
             if (!Util.Utils.IsRemovable(message.Label))
             {
-              virtualDirectory.AddRemovableDrive(message.Label, message.Label2);
+              _virtualDirectory.AddRemovableDrive(message.Label, message.Label2);
             }
           }
           LoadDirectory(currentFolder);
@@ -661,7 +619,7 @@ namespace MediaPortal.GUI.Pictures
         case GUIMessage.MessageType.GUI_MSG_REMOVE_REMOVABLE_DRIVE:
           if (!Util.Utils.IsRemovable(message.Label))
           {
-            virtualDirectory.Remove(message.Label);
+            _virtualDirectory.Remove(message.Label);
           }
           if (currentFolder.Contains(message.Label))
           {
@@ -771,7 +729,7 @@ namespace MediaPortal.GUI.Pictures
       }
       dlg.AddLocalizedString(457); //Switch View
       int iPincodeCorrect;
-      if (!virtualDirectory.IsProtectedShare(item.Path, out iPincodeCorrect) && !item.IsRemote && isFileMenuEnabled)
+      if (!_virtualDirectory.IsProtectedShare(item.Path, out iPincodeCorrect) && !item.IsRemote && isFileMenuEnabled)
       {
         dlg.AddLocalizedString(500); // FileMenu      
       }
@@ -1024,7 +982,7 @@ namespace MediaPortal.GUI.Pictures
       }
       else
       {
-        Share share = virtualDirectory.GetShare(folderName);
+        Share share = _virtualDirectory.GetShare(folderName);
         if (share != null)
         {
           if (mapSettings == null)
@@ -1224,7 +1182,7 @@ namespace MediaPortal.GUI.Pictures
         if (item.Label != "..")
         {
           int pin;
-          if (!virtualDirectory.IsProtectedShare(item.Path, out pin))
+          if (!_virtualDirectory.IsProtectedShare(item.Path, out pin))
           {
             Util.Utils.SetThumbnails(ref item);
           }
@@ -1283,7 +1241,7 @@ namespace MediaPortal.GUI.Pictures
         if (item.Label != "..")
         {
           List<GUIListItem> items = new List<GUIListItem>();
-          items = virtualDirectory.GetDirectoryUnProtectedExt(item.Path, false);
+          items = _virtualDirectory.GetDirectoryUnProtectedExt(item.Path, false);
           foreach (GUIListItem subItem in items)
           {
             DoDeleteItem(subItem);
@@ -1299,7 +1257,7 @@ namespace MediaPortal.GUI.Pictures
 
     protected override void OnInfo(int itemNumber)
     {
-      if (virtualDirectory.IsRemote(currentFolder))
+      if (_virtualDirectory.IsRemote(currentFolder))
       {
         return;
       }
@@ -1407,15 +1365,15 @@ namespace MediaPortal.GUI.Pictures
       }
       else
       {
-        if (virtualDirectory.IsRemote(item.Path))
+        if (_virtualDirectory.IsRemote(item.Path))
         {
-          if (!virtualDirectory.IsRemoteFileDownloaded(item.Path, item.FileInfo.Length))
+          if (!_virtualDirectory.IsRemoteFileDownloaded(item.Path, item.FileInfo.Length))
           {
-            if (!virtualDirectory.ShouldWeDownloadFile(item.Path))
+            if (!_virtualDirectory.ShouldWeDownloadFile(item.Path))
             {
               return;
             }
-            if (!virtualDirectory.DownloadRemoteFile(item.Path, item.FileInfo.Length))
+            if (!_virtualDirectory.DownloadRemoteFile(item.Path, item.FileInfo.Length))
             {
               //show message that we are unable to download the file
               GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SHOW_WARNING, 0, 0, 0, 0, 0, 0);
@@ -1474,7 +1432,7 @@ namespace MediaPortal.GUI.Pictures
 
     private void AddDir(GUISlideShow SlideShow, string strDir)
     {
-      List<GUIListItem> itemlist = virtualDirectory.GetDirectoryExt(strDir);
+      List<GUIListItem> itemlist = _virtualDirectory.GetDirectoryExt(strDir);
       Filter(ref itemlist);
       foreach (GUIListItem item in itemlist)
       {
@@ -1664,7 +1622,7 @@ namespace MediaPortal.GUI.Pictures
       dlgFile.SetSourceItem(item);
       dlgFile.SetSourceDir(currentFolder);
       dlgFile.SetDestinationDir(destinationFolder);
-      dlgFile.SetDirectoryStructure(virtualDirectory);
+      dlgFile.SetDirectoryStructure(_virtualDirectory);
       dlgFile.DoModal(GetID);
       destinationFolder = dlgFile.GetDestinationDir();
 
@@ -1761,7 +1719,7 @@ namespace MediaPortal.GUI.Pictures
 
       if (disp == Display.Files)
       {
-        itemlist = virtualDirectory.GetDirectoryExt(currentFolder);
+        itemlist = _virtualDirectory.GetDirectoryExt(currentFolder);
         Filter(ref itemlist);
         MissingThumbCacher ThumbWorker = new MissingThumbCacher(currentFolder, _autocreateLargeThumbs, false);
         // int itemIndex = 0;
@@ -2047,28 +2005,28 @@ namespace MediaPortal.GUI.Pictures
 
     public static void ResetShares()
     {
-      virtualDirectory.Reset();
-      virtualDirectory.DefaultShare = null;
-      virtualDirectory.LoadSettings("pictures");
+      _virtualDirectory.Reset();
+      _virtualDirectory.DefaultShare = null;
+      _virtualDirectory.LoadSettings("pictures");
 
-      if (virtualDirectory.DefaultShare != null)
+      if (_virtualDirectory.DefaultShare != null)
       {
         int pincode;
-        bool folderPinProtected = virtualDirectory.IsProtectedShare(virtualDirectory.DefaultShare.Path, out pincode);
+        bool folderPinProtected = _virtualDirectory.IsProtectedShare(_virtualDirectory.DefaultShare.Path, out pincode);
         if (folderPinProtected)
         {
           currentFolder = string.Empty;
         }
         else
         {
-          currentFolder = virtualDirectory.DefaultShare.Path;
+          currentFolder = _virtualDirectory.DefaultShare.Path;
         }
       }
     }
 
     public static void ResetExtensions(ArrayList extensions)
     {
-      virtualDirectory.SetExtensions(extensions);
+      _virtualDirectory.SetExtensions(extensions);
     }
 
     #endregion
-- 
1.7.10.msysgit.1

