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

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.ComponentModel;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. namespace UsbEject.Library
  10. {
  11.     /// <summary>
  12.     /// A generic base class for physical device classes.
  13.     /// </summary>
  14.     public abstract class DeviceClass : IDisposable
  15. {
  16. private IntPtr _deviceInfoSet;
  17. private Guid _classGuid;
  18.         private List<Device> _devices;
  19. protected DeviceClass(Guid classGuid)
  20. :this(classGuid, IntPtr.Zero)
  21. {
  22. }
  23.         internal virtual Device CreateDevice(DeviceClass deviceClass, Native.SP_DEVINFO_DATA deviceInfoData, string path, int index)
  24.         {
  25.             return new Device(deviceClass, deviceInfoData, path, index);
  26.         }
  27.         /// <summary>
  28.         /// Initializes a new instance of the DeviceClass class.
  29.         /// </summary>
  30.         /// <param name="classGuid">A device class Guid.</param>
  31.         /// <param name="hwndParent">The handle of the top-level window to be used for any user interface or IntPtr.Zero for no handle.</param>
  32. protected DeviceClass(Guid classGuid, IntPtr hwndParent)
  33. {
  34. _classGuid = classGuid;
  35. _deviceInfoSet = Native.SetupDiGetClassDevs(ref _classGuid, 0, hwndParent, Native.DIGCF_DEVICEINTERFACE | Native.DIGCF_PRESENT);
  36. if (_deviceInfoSet.ToInt32() == Native.INVALID_HANDLE_VALUE)
  37. throw new Win32Exception(Marshal.GetLastWin32Error());
  38. }
  39.         /// <summary>
  40.         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  41.         /// </summary>
  42. public void Dispose()
  43. {
  44. if (_deviceInfoSet != IntPtr.Zero)
  45. {
  46. Native.SetupDiDestroyDeviceInfoList(_deviceInfoSet);
  47. _deviceInfoSet = IntPtr.Zero;
  48. }
  49. }
  50.         /// <summary>
  51.         /// Gets the device class's guid.
  52.         /// </summary>
  53. public Guid ClassGuid
  54. {
  55. get
  56. {
  57. return _classGuid;
  58. }
  59. }
  60.         /// <summary>
  61.         /// Gets the list of devices of this device class.
  62.         /// </summary>
  63.         public List<Device> Devices
  64.         {
  65.             get
  66.             {
  67.                 if (_devices == null)
  68.                 {
  69.                     _devices = new List<Device>();
  70.         int index = 0;
  71.                     while (true)
  72.                     {
  73.                         Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA();
  74.                         if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, null, ref _classGuid, index, interfaceData))
  75.                         {
  76.                             int error = Marshal.GetLastWin32Error();
  77.                             if (error != Native.ERROR_NO_MORE_ITEMS)
  78.                                 throw new Win32Exception(error);
  79.                             break;
  80.                         }
  81.                         Native.SP_DEVINFO_DATA devData = new Native.SP_DEVINFO_DATA();
  82.                         int size = 0;
  83.                         if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, IntPtr.Zero, 0, ref size, devData))
  84.                         {
  85.                             int error = Marshal.GetLastWin32Error();
  86.                             if (error != Native.ERROR_INSUFFICIENT_BUFFER)
  87.                                 throw new Win32Exception(error);
  88.                         }
  89.                         IntPtr buffer = Marshal.AllocHGlobal(size);
  90.                         Native.SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new Native.SP_DEVICE_INTERFACE_DETAIL_DATA();
  91.                         detailData.cbSize = Marshal.SizeOf(typeof(Native.SP_DEVICE_INTERFACE_DETAIL_DATA));
  92.                         Marshal.StructureToPtr(detailData, buffer, false);
  93.                         if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, interfaceData, buffer, size, ref size, devData))
  94.                         {
  95.                             Marshal.FreeHGlobal(buffer);
  96.                             throw new Win32Exception(Marshal.GetLastWin32Error());
  97.                         }
  98.                         IntPtr pDevicePath = (IntPtr)((int)buffer + Marshal.SizeOf(typeof(int)));
  99.                         string devicePath = Marshal.PtrToStringAuto(pDevicePath);
  100.                         Marshal.FreeHGlobal(buffer);
  101.                         Device device = CreateDevice(this, devData, devicePath, index);
  102.                         _devices.Add(device);
  103.                         index++;
  104.                     }
  105.                     _devices.Sort();
  106.                 }
  107.                 return _devices;
  108.             }
  109.         }
  110.         internal Native.SP_DEVINFO_DATA GetInfo(int dnDevInst)
  111.         {
  112.             StringBuilder sb = new StringBuilder(1024);
  113.             int hr = Native.CM_Get_Device_ID(dnDevInst, sb, sb.Capacity, 0);
  114.             if (hr != 0)
  115.                 throw new Win32Exception(hr);
  116.             Native.SP_DEVINFO_DATA devData = new Native.SP_DEVINFO_DATA();
  117.             devData.cbSize = Marshal.SizeOf(typeof(Native.SP_DEVINFO_DATA));
  118.             if (!Native.SetupDiOpenDeviceInfo(_deviceInfoSet, sb.ToString(), IntPtr.Zero, 0, devData))
  119.                 throw new Win32Exception(Marshal.GetLastWin32Error());
  120.             return devData;
  121.         }
  122.         internal string GetProperty(Native.SP_DEVINFO_DATA devData, int property, string defaultValue)
  123.         {
  124.             if (devData == null)
  125.                 throw new ArgumentNullException("devData");
  126.             int propertyRegDataType = 0;
  127.             int requiredSize;
  128.             int propertyBufferSize = 1024;
  129.             IntPtr propertyBuffer = Marshal.AllocHGlobal(propertyBufferSize);
  130.             if (!Native.SetupDiGetDeviceRegistryProperty(_deviceInfoSet,
  131.                 devData,
  132.                 property,
  133.                 out propertyRegDataType,
  134.                 propertyBuffer,
  135.                 propertyBufferSize,
  136.                 out requiredSize))
  137.             {
  138.                 Marshal.FreeHGlobal(propertyBuffer);
  139.                 int error = Marshal.GetLastWin32Error();
  140.                 if (error != Native.ERROR_INVALID_DATA)
  141.                     throw new Win32Exception(error);
  142.                 return defaultValue;
  143.             }
  144.             string value = Marshal.PtrToStringAuto(propertyBuffer);
  145.             Marshal.FreeHGlobal(propertyBuffer);
  146.             return value;
  147.         }
  148.         internal int GetProperty(Native.SP_DEVINFO_DATA devData, int property, int defaultValue)
  149.         {
  150.             if (devData == null)
  151.                 throw new ArgumentNullException("devData");
  152.             int propertyRegDataType = 0;
  153.             int requiredSize;
  154.             int propertyBufferSize = Marshal.SizeOf(typeof(int));
  155.             IntPtr propertyBuffer = Marshal.AllocHGlobal(propertyBufferSize);
  156.             if (!Native.SetupDiGetDeviceRegistryProperty(_deviceInfoSet,
  157.                 devData,
  158.                 property,
  159.                 out propertyRegDataType,
  160.                 propertyBuffer,
  161.                 propertyBufferSize,
  162.                 out requiredSize))
  163.             {
  164.                 Marshal.FreeHGlobal(propertyBuffer);
  165.                 int error = Marshal.GetLastWin32Error();
  166.                 if (error != Native.ERROR_INVALID_DATA)
  167.                     throw new Win32Exception(error);
  168.                 return defaultValue;
  169.             }
  170.             int value = (int)Marshal.PtrToStructure(propertyBuffer, typeof(int));
  171.             Marshal.FreeHGlobal(propertyBuffer);
  172.             return value;
  173.         }
  174.         internal Guid GetProperty(Native.SP_DEVINFO_DATA devData, int property, Guid defaultValue)
  175.         {
  176.             if (devData == null)
  177.                 throw new ArgumentNullException("devData");
  178.             int propertyRegDataType = 0;
  179.             int requiredSize;
  180.             int propertyBufferSize = Marshal.SizeOf(typeof(Guid));
  181.             IntPtr propertyBuffer = Marshal.AllocHGlobal(propertyBufferSize);
  182.             if (!Native.SetupDiGetDeviceRegistryProperty(_deviceInfoSet,
  183.                 devData,
  184.                 property,
  185.                 out propertyRegDataType,
  186.                 propertyBuffer,
  187.                 propertyBufferSize,
  188.                 out requiredSize))
  189.             {
  190.                 Marshal.FreeHGlobal(propertyBuffer);
  191.                 int error = Marshal.GetLastWin32Error();
  192.                 if (error != Native.ERROR_INVALID_DATA)
  193.                     throw new Win32Exception(error);
  194.                 return defaultValue;
  195.             }
  196.             Guid value = (Guid)Marshal.PtrToStructure(propertyBuffer, typeof(Guid));
  197.             Marshal.FreeHGlobal(propertyBuffer);
  198.             return value;
  199.         }
  200. }
  201. }