using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Dokan;
using MediaAssistant.DAL;
using MediaAssistant.DAL.Helper;
using MefBasic.Data;
using MefBasic.Threading;
namespace MediaFS
{
public class MediaFSManager:ANotifyPropertyChanged
{
private static readonly object LockObject=new object();
private static MediaFSManager _instance;
public static MediaFSManager Instance
{
get
{
if(_instance==null)
{
lock (LockObject)
{
if(_instance==null)
{
_instance=new MediaFSManager();
}
}
}
return _instance;
}
}
public Profile SelectedProfile { get; set; }
private MediaFSManager()
{
}
public void Mount()
{
IsMounted = true;
var mountPoint = string.Format("{0}:\\",DriveLatter);
var job = new Job(j => StartDokanMain(mountPoint, j));
job.JobCompleted += HandleJobCompleted;
job.Start();
Thread.Sleep(1000);
if(DriveInfo.GetDrives().Any(d=>d.Name.Equals(mountPoint,StringComparison.CurrentCultureIgnoreCase)))
SystemHelper.Start(mountPoint);
}
private void StartDokanMain(string mountPoint, Job j)
{
try
{
DriveLatter = GetDriveLetter();
var opt = new DokanOptions
{
DebugMode = true,
MountPoint = mountPoint,
ThreadCount = 5,
VolumeLabel = "Media"
};
int status = DokanNet.DokanMain(opt, new MediaFSOperations());
j.Store.Add(status,"Status");
}
catch (Exception ex)
{
IsMounted = false;
j.Store.Add(ex);
}
}
private void HandleJobCompleted(object sender, EventArgs e)
{
var job = (Job) sender;
var exception = job.Store.GetObject<Exception>();
if(exception!=null && exception.Message.StartsWith("Unable to load DLL 'dokan.dll': The specified module could not be found."))
{
if(MessageBox.Show(@"Media drive uses Dokan filesystem driver which is not installed. Do you want to install it?",@"Dokan Library Not Installed",MessageBoxButtons.YesNo)==DialogResult.Yes)
{
var tempPath = Path.GetTempPath();
var installerPath = Path.Combine(tempPath, "DokanInstall_0.6.0.exe");
if(File.Exists(installerPath)==false)
{
ResourceHelper.CopyEmbededResource("MediaFS.DokanInstall_0.6.0.exe",installerPath);
}
SystemHelper.StartAndWait(installerPath);
Mount();
}
}
var status = job.Store.GetObject<int>("Status");
switch (status)
{
case DokanNet.DOKAN_DRIVER_INSTALL_ERROR:
MessageBox.Show(@"Driver install error", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case DokanNet.DOKAN_START_ERROR:
MessageBox.Show(@"Start error", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case DokanNet.DOKAN_ERROR:
MessageBox.Show(@"Unknown error", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case DokanNet.DOKAN_SUCCESS:
break;
default:
Unmount();
Mount();
break;
}
}
private static char GetDriveLetter()
{
var driveChar = 'D';
for (var i = 0; i < 26;i++ )
{
var driveStr = string.Format("{0}:\\",driveChar);
if(DriveInfo.GetDrives().All(d=>d.Name.Equals(driveStr,StringComparison.InvariantCultureIgnoreCase)==false))
{
break;
}
driveChar++;
}
return driveChar;
}
protected char DriveLatter { get; set; }
public void Unmount()
{
if (IsMounted)
{
DokanNet.DokanUnmount(DriveLatter);
IsMounted = false;
}
}
private bool _isMounted;
public bool IsMounted
{
get { return _isMounted; }
set
{
_isMounted = value;
OnPropertyChanged("IsMounted");
}
}
public void ToggleMount()
{
if(IsMounted)
Unmount();
else
{
Mount();
}
}
}
}