The title was what this class was mainly created for. It's a small wrapper that extends the System.IO.DriveInfo, mainly with the purpose of setting the drive mappings.
namespace Subro.IO
{
using System;
using System.Collections.Generic;
using System.Text;
using io = System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Drawing;
/// <summary>
/// Information on a drive. The 'default' information of <see cref="System.IO.DriveInfo"/>
/// can be obtained with the <see cref="Info"/> property.
/// Further added functionality includes: mappings to network locations, obtaining drive images
///
public class DriveInfo
{
public
readonly string Name;
io.
DriveInfo info;
string apidrive;
public DriveInfo(
string Drive)
{
this.Name = Drive;
apidrive = Drive.Trim();
if (!apidrive.EndsWith(":")) apidrive += ":";
Refresh();
}
#region Get info
public
void Refresh()
{
unc = GetUNC();
try{
info = new io.DriveInfo(Name);
}
catch { info =
null; }
if (info !=
null) type = info.DriveType;
}
string GetUNC()
{
StringBuilder remotename = new StringBuilder();
int bufferlen = 255;
int res = WNetGetConnection(apidrive, remotename, ref bufferlen);
if (CheckAPIRes(res) ==
API_Result.NO_ERROR)
{
return remotename.ToString();
}return null;
}
API_Result CheckAPIRes(
int res)
{
API_Result ares = (
API_Result)res;
if (res > 0)
Debug.WriteLine("Error: " + ares.ToString());
return ares;
}#endregion
#region static
#region API definitions
enum
API_Result{
ERROR_BAD_DEVICE = 1200,
ERROR_CONNECTION_UNAVAIL = 1201,
ERROR_EXTENDED_ERROR = 1208,
ERROR_MORE_DATA = 234,
ERROR_NOT_SUPPORTED = 50,
ERROR_NO_NET_OR_BAD_PATH = 1203,
ERROR_NO_NETWORK = 1222,
ERROR_NOT_CONNECTED = 2250,
NO_ERROR = 0
}
[DllImport("mpr.dll")]
static extern int WNetGetConnection(string LocalName, StringBuilder RemoteName, ref int BufferSize);
[DllImport("shell32.dll")]
static extern IntPtr ExtractIcon(int hInst, string lpszExeFileName, int nIconIndex);
//http://www.allapi.net/apilist/WNetAddConnection2.shtml
[DllImport("mpr.dll")]
static extern int WNetAddConnection2A(ref NetResource ConnectionInfo, string pw, string user, ConnectionType Flags);
[
StructLayout(
LayoutKind.Sequential)]
struct NetResource{
/// <summary>ignored
public int Scope;
public ResourceType Type;
/// <summary>ignored
public int DisplayType;
/// <summary>ignored
public int Usage;
/// <summary>
/// Drive Name
///
public string LocalName;
/// <summary>
/// The unc
///
public string RemoteName;
/// <summary>ignored
public string Comment;
/// <summary>
/// Provider
///
public string Provider;
}public
enum ConnectionType{
CurrentSessionOnly = 0,
/// <summary>
/// the change also counts when rebooted
///
Update_Profile = 1
}
public
enum ResourceType{
Disk = 1,
Printer = 2
}
//http://www.allapi.net/apilist/WNetCancelConnection2.shtml
[DllImport("mpr.dll")]
static extern int WNetCancelConnection2A(string Drive, ConnectionType Flags, int Force);
#endregion
public
static IEnumerable<
DriveInfo> GetDrives()
{
return GetDrives(false);
}
public static IEnumerable<DriveInfo> GetMappings()
{foreach (
DriveInfo inf
in GetDrives(
true))
{
if (inf.HasMapping) yield return inf;
} }static
IEnumerable<
DriveInfo> GetDrives(
bool IncludeMappings)
{
foreach (
string s
in GetDriveNames(IncludeMappings))
{
DriveInfo inf = new DriveInfo(s);
if (inf.Exists || (IncludeMappings && inf.HasMapping)) yield return inf;
} }///
<summary>
/// Returns an enumeration of all POSSIBLE drive/mapping names
///
/// <param name="IncludeMappings">
/// <returns>
public static IEnumerable<
string> GetDriveNames(
bool IncludeMappings)
{
for (
char c =
'A'; c <=
'Z'; c++)
{
yield return c.ToString();
}
if (IncludeMappings)for (
int i = 1; i < 4; i++)
{
yield return "LPT" + i;
} }#endregion
#region props
#region mapping
public
bool HasMapping
{
get { return unc != null; }
}string unc;
public string Mapping
{
get
{
return unc;
}
set
{if (unc ==
value)
return;
if (
value ==
null)
{
RemoveMapping();
}
else{
SetMapping(value, ConnectionType.Update_Profile);
}
Refresh();
} }public
void RemoveMapping()
{
RemoveMapping(ConnectionType.Update_Profile);
}
public void RemoveMapping(
ConnectionType Persistance)
{
int res = WNetCancelConnection2A(apidrive, Persistance, 1);
CheckAPIRes(res);
Refresh();
}public
void SetMapping(
string UNC,
ConnectionType ConnectionType)
{
SetMapping(UNC, ConnectionType, ResourceType.Disk);
}
public void SetMapping(
string UNC,
ConnectionType ConnectionType,
ResourceType ResourceType)
{
if (UNC ==
null)
throw new ArgumentNullException("UNC");
if (unc !=
null && unc.ToLower() == UNC.Trim().ToLower())
return;
RemoveMapping(ConnectionType);
NetResource nr =
new NetResource();
nr.LocalName = apidrive;
nr.RemoteName = UNC;
nr.Type = ResourceType;
int res = WNetAddConnection2A(
ref nr,
null,
null, ConnectionType);
CheckAPIRes(res);
Refresh();
}#endregion
///
<summary>
/// Indicates if the drive is known on the current system
///
public bool Exists
{
get { return info != null && info.DriveType != System.IO.DriveType.NoRootDirectory; }
}private io.DriveType type;
public io.
DriveType DriveType
{
get { return type; }
}public
override string ToString()
{
string res = apidrive;
if (!Exists && !HasMapping)
{
res += " [Does not exist]";
}
else{
if(Exists)
res += " [" + type + " drive]";
if (HasMapping)
res += " --> " + unc;
}
return res;
}
#endregion
#region Graphical
static
Icon GetIcon(
int index)
{
IntPtr handle = ExtractIcon(0, "shell32.dll", index);
return Icon.FromHandle(handle);
}
static int GetIndex(io.DriveType type)
{switch (type)
{
case System.IO.
DriveType.CDRom:
return 11;
case System.IO.
DriveType.Fixed:
return 8;
case System.IO.
DriveType.Network:
return 9;
case System.IO.
DriveType.Ram:
return 12;
case System.IO.
DriveType.Removable:
return 6;
case System.IO.
DriveType.Unknown:
return 7;
}
return -1; }///
<summary>
/// Gets the icon normally associated with the drive
///
/// <returns>
public Icon GetIcon()
{
int index = GetIndex(type);
if (index == -1) return null;
return GetIcon(index);
}public
Image GetImage()
{
Icon ic = GetIcon();
if (ic == null) return null;
Bitmap res = Bitmap.FromHicon(ic.Handle);
return res;
}#endregion
}
}
. . .