// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Kevin Dente (kevindente@yahoo.com)
// This class is an extremely stripped down version of Jared Bienz's code from CodeProject.com,
// Even stripped down, it still includes more than NAnt needs right now, but
// the extra functionality was left in there in case it's needed in the future.
using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
namespace NAnt.Core {
[Serializable]
public class InvalidVolumeException : ApplicationException {
#region Public Instance Constructors
///
/// Initializes a new instance of the class.
///
public InvalidVolumeException() : base() {
}
///
/// Initializes a new instance of the class
/// with a descriptive message.
///
/// A descriptive message to include with the exception.
public InvalidVolumeException(string message) : base(message) {
}
///
/// Initializes a new instance of the class
/// with the specified descriptive message and inner exception.
///
/// A descriptive message to include with the exception.
/// A nested exception that is the cause of the current exception.
public InvalidVolumeException(string message, Exception innerException) : base(message, innerException) {
}
///
/// Initializes a new instance of the class
/// with the specified .
///
/// of the invalid volume.
public InvalidVolumeException(Uri volUri) : base("Volume information could not be retrieved for the path '" + volUri.LocalPath + "'. Verify that the path is valid and ends in a trailing backslash, and try again."){}
#endregion Public Instance Constructors
#region Protected Instance Constructors
///
/// Initializes a new instance of the class
/// with serialized data.
///
/// The that holds the serialized object data about the exception being thrown.
/// The that contains contextual information about the source or destination.
protected InvalidVolumeException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
#endregion Protected Instance Constructors
}
///
/// Represents the different types of drives that may exist in a system.
///
public enum VolumeType {
Unknown, // The drive type cannot be determined.
Invalid, // The root path is invalid. For example, no volume is mounted at the path.
Removable, // The disk can be removed from the drive.
Fixed, // The disk cannot be removed from the drive.
Remote, // The drive is a remote (network) drive.
CDRom, // The drive is a CD-ROM drive.
RamDisk // The drive is a RAM disk.
};
///
/// Represents the different supporting flags that may be set on a file system.
///
[Flags]
public enum VolumeFlags {
Unknown = 0x0,
CaseSensitive = 0x00000001,
Compressed = 0x00008000,
PersistentAcls = 0x00000008,
PreservesCase = 0x00000002,
ReadOnly = 0x00080000,
SupportsEncryption = 0x00020000,
SupportsFileCompression = 0x00000010,
SupportsNamedStreams = 0x00040000,
SupportsObjectIds = 0x00010000,
SupportsQuotas = 0x00000020,
SupportsReparsePoints = 0x00000080,
SupportsSparseFiles = 0x00000040,
SupportsUnicodeOnVolume = 0x00000004
};
///
/// Presents information about a volume.
///
public sealed class VolumeInfo {
#region Private Static Fields
private const int NAMESIZE = 80;
private const int MAX_PATH = 256;
#endregion Private Static Fields
#region Private classes, structs and enums
[StructLayout(LayoutKind.Sequential)]
private class UniversalNameInfo {
public string NetworkPath = null;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
private struct SHFILEINFOA {
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=NAMESIZE)]
public string szTypeName;
};
private enum UniInfoLevel {
Universal=1,
Remote=2
};
#endregion Private classes, structs and enums
#region Private Instance Constructors
///
/// Initializes a new instance of the class.
///
///
/// Uses a private access modifier to prevent instantiation of this class.
///
private VolumeInfo() {
}
#endregion Private Instance Constructors
#region Public Static Methods
///
/// Determines whether the file system is case sensitive. Performs a
/// P/Invoke to the Win32 API GetVolumeInformation.
///
///
///
/// if the specified volume is case-sensitive;
/// otherwise, .
///
public static bool IsVolumeCaseSensitive(Uri uri) {
ValidateURI(uri);
return PlatformHelper.IsVolumeCaseSensitive(uri.LocalPath);
}
#endregion Public Static Methods
#region Private Static Methods
private static void ValidateURI(Uri uri) {
// Make sure we were passed something
if (uri == null) throw new ArgumentNullException();
// Make sure we can handle this type of uri
if (!uri.IsFile) throw new InvalidVolumeException(uri);
// Make sure Uri is trailed properly
string dirsep = String.Format(CultureInfo.InvariantCulture, "{0}", Path.DirectorySeparatorChar);
if (!uri.LocalPath.EndsWith(dirsep) ) throw new InvalidVolumeException(uri);
}
#endregion Private Static Methods
}
}