Volume.cs
上传用户:lyzyl198
上传日期:2008-05-19
资源大小:174k
文件大小:7k
源码类别:

C#编程

开发平台:

C#

  1. // UsbEject version 1.0 March 2006
  2. // written by Simon Mourier <email: simon [underscore] mourier [at] hotmail [dot] com>
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Diagnostics;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. namespace UsbEject.Library
  10. {
  11.     /// <summary>
  12.     /// A volume device.
  13.     /// </summary>
  14.     public class Volume : Device, IComparable
  15.     {
  16.         private string _volumeName;
  17.         private string _logicalDrive;
  18.         private int[] _diskNumbers;
  19.         private List<Device> _disks;
  20.         private List<Device> _removableDevices;
  21.         internal Volume(DeviceClass deviceClass, Native.SP_DEVINFO_DATA deviceInfoData, string path, int index)
  22.             :base(deviceClass, deviceInfoData, path, index)
  23.         {
  24.         }
  25.         /// <summary>
  26.         /// Gets the volume's name.
  27.         /// </summary>
  28.         public string VolumeName
  29.         {
  30.             get
  31.             {
  32.                 if (_volumeName == null)
  33.                 {
  34.                     StringBuilder sb = new StringBuilder(1024);
  35.                     if (!Native.GetVolumeNameForVolumeMountPoint(Path + "\", sb, sb.Capacity))
  36.                     {
  37.                         // throw new Win32Exception(Marshal.GetLastWin32Error());
  38.                         
  39.                     }
  40.                     if (sb.Length > 0)
  41.                     {
  42.                         _volumeName = sb.ToString();
  43.                     }
  44.                 }
  45.                 return _volumeName;
  46.             }
  47.         }
  48.         /// <summary>
  49.         /// Gets the volume's logical drive in the form [letter]:
  50.         /// </summary>
  51.         public string LogicalDrive
  52.         {
  53.             get
  54.             {
  55.                 if ((_logicalDrive == null) && (VolumeName != null))
  56.                 {
  57.                     ((VolumeDeviceClass)DeviceClass)._logicalDrives.TryGetValue(VolumeName, out _logicalDrive);
  58.                 }
  59.                 return _logicalDrive;
  60.             }
  61.         }
  62.         /// <summary>
  63.         /// Gets a value indicating whether this volume is a based on USB devices.
  64.         /// </summary>
  65.         public override bool IsUsb
  66.         {
  67.             get
  68.             {
  69.                 if (Disks != null)
  70.                 {
  71.                     foreach (Device disk in Disks)
  72.                     {
  73.                         if (disk.IsUsb)
  74.                             return true;
  75.                     }
  76.                 }
  77.                 return false;
  78.             }
  79.         }
  80.         /// <summary>
  81.         /// Gets a list of underlying disks for this volume.
  82.         /// </summary>
  83.         public List<Device> Disks
  84.         {
  85.             get
  86.             {
  87.                 if (_disks == null)
  88.                 {
  89.                     _disks = new List<Device>();
  90.                     if (DiskNumbers != null)
  91.                     {
  92.                         DiskDeviceClass disks = new DiskDeviceClass();
  93.                         foreach (int index in DiskNumbers)
  94.                         {
  95.                             if (index < disks.Devices.Count)
  96.                             {
  97.                                 _disks.Add(disks.Devices[index]);
  98.                             }
  99.                         }
  100.                     }
  101.                 }
  102.                 return _disks;
  103.             }
  104.         }
  105.         private int[] DiskNumbers
  106.         {
  107.             get
  108.             {
  109.                 if (_diskNumbers == null)
  110.                 {
  111.                     List<int> numbers = new List<int>();
  112.                     if (LogicalDrive != null)
  113.                     {
  114.                         IntPtr hFile = Native.CreateFile(@"\." + LogicalDrive, Native.GENERIC_READ, Native.FILE_SHARE_READ | Native.FILE_SHARE_WRITE, IntPtr.Zero, Native.OPEN_EXISTING, 0, IntPtr.Zero);
  115.                         if (hFile.ToInt32() == Native.INVALID_HANDLE_VALUE)
  116.                             throw new Win32Exception(Marshal.GetLastWin32Error());
  117.                         int size = 0x400; // some big size
  118.                         IntPtr buffer = Marshal.AllocHGlobal(size);
  119.                         int bytesReturned = 0;
  120.                         try
  121.                         {
  122.                             if (!Native.DeviceIoControl(hFile, Native.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, buffer, size, out bytesReturned, IntPtr.Zero))
  123.                             {
  124.                                 // do nothing here on purpose
  125.                             }
  126.                         }
  127.                         finally
  128.                         {
  129.                             Native.CloseHandle(hFile);
  130.                         }
  131.                         if (bytesReturned > 0)
  132.                         {
  133.                             int numberOfDiskExtents = (int)Marshal.PtrToStructure(buffer, typeof(int));
  134.                             for (int i = 0; i < numberOfDiskExtents; i++)
  135.                             {
  136.                                 IntPtr extentPtr = new IntPtr(buffer.ToInt32() + Marshal.SizeOf(typeof(long)) + i * Marshal.SizeOf(typeof(Native.DISK_EXTENT)));
  137.                                 Native.DISK_EXTENT extent = (Native.DISK_EXTENT)Marshal.PtrToStructure(extentPtr, typeof(Native.DISK_EXTENT));
  138.                                 numbers.Add(extent.DiskNumber);
  139.                             }
  140.                         }
  141.                         Marshal.FreeHGlobal(buffer);
  142.                     }
  143.                     _diskNumbers = new int[numbers.Count];
  144.                     numbers.CopyTo(_diskNumbers);
  145.                 }
  146.                 return _diskNumbers;
  147.             }
  148.         }
  149.         /// <summary>
  150.         /// Gets a list of removable devices for this volume.
  151.         /// </summary>
  152.         public override List<Device> RemovableDevices
  153.         {
  154.             get
  155.             {
  156.                 if (_removableDevices == null)
  157.                 {
  158.                     _removableDevices = new List<Device>();
  159.                     if (Disks == null)
  160.                     {
  161.                         _removableDevices = base.RemovableDevices;
  162.                     }
  163.                     else
  164.                     {
  165.                         foreach (Device disk in Disks)
  166.                         {
  167.                             foreach (Device device in disk.RemovableDevices)
  168.                             {
  169.                                 _removableDevices.Add(device);
  170.                             }
  171.                         }
  172.                     }
  173.                 }
  174.                 return _removableDevices;
  175.             }
  176.         }
  177.         /// <summary>
  178.         /// Compares the current instance with another object of the same type.
  179.         /// </summary>
  180.         /// <param name="obj">An object to compare with this instance.</param>
  181.         /// <returns>A 32-bit signed integer that indicates the relative order of the comparands.</returns>
  182.         public override int CompareTo(object obj)
  183.         {
  184.             Volume device = obj as Volume;
  185.             if (device == null)
  186.                 throw new ArgumentException();
  187.             if (LogicalDrive == null)
  188.                 return 1;
  189.             if (device.LogicalDrive == null)
  190.                 return -1;
  191.             return LogicalDrive.CompareTo(device.LogicalDrive);
  192.         }
  193.     }
  194. }