/// <summary> /// Конструктор, связывающий раздел с устройством. /// </summary> /// <param name="device">Устройство, на котором расположен раздел.</param> public Partition(Device device, Interop.PARTITION_INFORMATION partInfo) : base() { if (device == null) throw new ArgumentNullException(); _device = device; _partInfo = partInfo; _mounts.AddRange(QueryMountPoints()); _updateInterval = TimeSpan.FromSeconds(20); }
/// <summary> /// Обновляет внутренний список устройств, добавляя /// появившиеся и уничтожая отключенные. /// </summary> private void UpdateDevices() { lock (_syncObject) { Guid GUID_DEVINTERFACE_DISK = new Guid(0x53f56307, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); IntPtr devInfoSet = Interop.SetupDiGetClassDevs( ref GUID_DEVINTERFACE_DISK, IntPtr.Zero, IntPtr.Zero, Interop.DIGCF_PROFILE | Interop.DIGCF_DEVICEINTERFACE | Interop.DIGCF_PRESENT ); if ((int)devInfoSet == Interop.INVALID_HANDLE_VALUE) { //throw new Win32Exception(error); return; } Interop.SP_DEVINFO_DATA devInfoData = new Interop.SP_DEVINFO_DATA(); List<Device> ndevices = new List<Device>(); uint i; for (i = 0; ; ++i) { Interop.SP_DEVICE_INTERFACE_DATA interfaceData = new Interop.SP_DEVICE_INTERFACE_DATA(); if (!Interop.SetupDiEnumDeviceInterfaces(devInfoSet, null, ref GUID_DEVINTERFACE_DISK, i, interfaceData)) { int error = Marshal.GetLastWin32Error(); if (error != Interop.ERROR_NO_MORE_ITEMS) { //throw new Win32Exception(error); continue; } break; } Interop.SP_DEVINFO_DATA devData = new Interop.SP_DEVINFO_DATA(); int size = 0; if (!Interop.SetupDiGetDeviceInterfaceDetail(devInfoSet, interfaceData, IntPtr.Zero, 0, ref size, devData)) { int error = Marshal.GetLastWin32Error(); if (error != Interop.ERROR_INSUFFICIENT_BUFFER) throw new Win32Exception(error); } IntPtr buffer = Marshal.AllocHGlobal(size); Interop.SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new Interop.SP_DEVICE_INTERFACE_DETAIL_DATA(); detailData.cbSize = Marshal.SizeOf(typeof(Interop.SP_DEVICE_INTERFACE_DETAIL_DATA)); Marshal.StructureToPtr(detailData, buffer, false); if (!Interop.SetupDiGetDeviceInterfaceDetail(devInfoSet, interfaceData, buffer, size, ref size, devData)) { Marshal.FreeHGlobal(buffer); //throw new Win32Exception(Marshal.GetLastWin32Error()); continue; } // Немного магии с плана Лимбо. IntPtr pDevicePath = (IntPtr)((int)buffer + Marshal.SizeOf(typeof(int))); string devicePath = Marshal.PtrToStringAuto(pDevicePath); Marshal.FreeHGlobal(buffer); if (devicePath.Length != 0) { try { Device dev = new Device(this, devicePath); ndevices.Add(dev); } catch (DriverException e) { } } } Interop.SetupDiDestroyDeviceInfoList(devInfoSet); // Список старых устройств. IList<Device> oldDevices = new List<Device>(_devices); //Убираем из существующих устройств те, //которых нет в полученном списке. foreach (Device dev in oldDevices) { if (!ndevices.Exists( delegate(Device d) { return d.Equals(dev); } )) { _devices.Remove(dev); //TODO: Вызывать здесь dev.Dispose(). } } //Добавляем к устройствам те, //которых нет в полученном списке. foreach (Device dev in ndevices) { if (!_devices.Exists( delegate(Device d) { return d.Equals(dev); } )) { _devices.Add(dev); } } } // lock }