public void Dispose() { for (int i = 0; i < volumeHandles.Length; i++) { if (volumeHandles[i] != IntPtr.Zero) { try { NativeDiskWrapper.RemoveLockOnVolume(volumeHandles[i]); } catch { } NativeDisk.CloseHandle(volumeHandles[i]); volumeHandles[i] = IntPtr.Zero; } } if (fileHandle != IntPtr.Zero) { NativeDisk.CloseHandle(fileHandle); fileHandle = IntPtr.Zero; } for (int i = 0; i < deviceHandles.Length; i++) { if (deviceHandles[i] != IntPtr.Zero) { NativeDisk.CloseHandle(deviceHandles[i]); deviceHandles[i] = IntPtr.Zero; } } Utils.AllowComputerSleep(); }
public static ulong GetDeviceLength(int deviceID) { ulong length = 0; IntPtr deviceHandle = NativeDiskWrapper.GetHandleOnDevice(deviceID, NativeDisk.GENERIC_READ); unsafe { int returnLength = 0; IntPtr lengthPtr = new IntPtr(&length); NativeDisk.DeviceIoControl(deviceHandle, NativeDisk.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0, lengthPtr, sizeof(ulong), ref returnLength, IntPtr.Zero); } NativeDisk.CloseHandle(deviceHandle); return(length); }
public static DiskPartitionInfo GetDiskPartitionInfo(char driveLetter) { int deviceID = NativeDiskWrapper.CheckDriveType(string.Format(@"\\.\{0}:\", driveLetter)); IntPtr deviceHandle = NativeDiskWrapper.GetHandleOnDevice(deviceID, NativeDisk.GENERIC_READ); uint partitionTableSize = 0; DiskPartitionInfo partitionsInfo = new DiskPartitionInfo(); var partitionInfo = NativeDiskWrapper.GetDiskPartitionInfo(deviceHandle); partitionsInfo.DiskTotalSize = GetDeviceLength(deviceID); if (partitionInfo.PartitionStyle == PARTITION_STYLE.MasterBootRecord) { partitionsInfo.PartitionType = PartitionType.MBR; partitionTableSize = 512; unsafe { byte *data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, 0, 1, 512); for (int i = 0; i < 4; i++) { ulong partitionStartSector = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1BE + 8 + 16 * i); ulong partitionNumSectors = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1BE + 12 + 16 * i); if (partitionStartSector + partitionNumSectors > 0) { partitionsInfo.PartitionSizes.Add(partitionNumSectors * 512); } } } } else if (partitionInfo.PartitionStyle == PARTITION_STYLE.GuidPartitionTable) { partitionsInfo.PartitionType = PartitionType.GPT; partitionTableSize = 17408; unsafe { byte *data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, 0, 1, 512); uint gptHeaderOffset = (uint)Marshal.ReadInt32(new IntPtr(data), 0x1C6); data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, gptHeaderOffset, 1, 512); ulong partitionTableSector = (ulong)Marshal.ReadInt64(new IntPtr(data), 0x48); uint noOfPartitionEntries = (uint)Marshal.ReadInt32(new IntPtr(data), 0x50); uint sizeOfPartitionEntry = (uint)Marshal.ReadInt32(new IntPtr(data), 0x54); data = NativeDiskWrapper.ReadSectorDataPointerFromHandle(deviceHandle, partitionTableSector, (512 / sizeOfPartitionEntry) * noOfPartitionEntries, 512); for (int i = 0; i < noOfPartitionEntries; i++) { ulong partitionStartSector = (ulong)Marshal.ReadInt64(new IntPtr(data), (int)(0x20 + sizeOfPartitionEntry * i)); ulong partitionNumSectors = (ulong)Marshal.ReadInt64(new IntPtr(data), (int)(0x28 + sizeOfPartitionEntry * i)); if (partitionStartSector + partitionNumSectors > 0) { partitionsInfo.PartitionSizes.Add(partitionNumSectors * 512); } } } } else { partitionsInfo.PartitionType = PartitionType.RAW; } NativeDisk.CloseHandle(deviceHandle); partitionsInfo.UnallocatedSize = partitionsInfo.DiskTotalSize - (partitionsInfo.PartitionSizes.Sum() + partitionTableSize); return(partitionsInfo); }
internal static int CheckDriveType(string name) { int retVal = 0; int bytesReaded = 0; IntPtr handle; string nameNoSlash = name.Substring(0, name.Length - 1); var driveType = NativeDisk.GetDriveType(name); switch (driveType) { case DriveType.Fixed: case DriveType.Removable: handle = NativeDisk.CreateFile(nameNoSlash, NativeDisk.FILE_READ_ATTRIBUTES, NativeDisk.FILE_SHARE_READ | NativeDisk.FILE_SHARE_WRITE, IntPtr.Zero, NativeDisk.OPEN_EXISTING, 0, IntPtr.Zero); if (handle == NativeDisk.INVALID_HANDLE_VALUE) { var exception = new Win32Exception(Marshal.GetLastWin32Error()); throw new Exception(string.Format("Error occured when trying to check drive type 1.\nError code: {0}\nMessage: {1}", exception.NativeErrorCode, exception.Message)); } else { STORAGE_DEVICE_DESCRIPTOR devDescriptor = new STORAGE_DEVICE_DESCRIPTOR(); STORAGE_DEVICE_NUMBER devNumber = GetDiskProperty(handle, ref devDescriptor); if ((driveType == DriveType.Removable && devDescriptor.BusType != STORAGE_BUS_TYPE.BusTypeSata) || (driveType == DriveType.Fixed && devDescriptor.BusType == STORAGE_BUS_TYPE.BusTypeUsb) || (devDescriptor.BusType == STORAGE_BUS_TYPE.BusTypeSd) || (devDescriptor.BusType == STORAGE_BUS_TYPE.BusTypeMmc)) { if (NativeDisk.DeviceIoControl(handle, NativeDisk.IOCTL_STORAGE_CHECK_VERIFY2, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReaded, IntPtr.Zero)) { retVal = devNumber.DeviceNumber; } else { NativeDisk.CloseHandle(handle); Utils.SetErrorMode(Utils.ErrorModes.SEM_FAILCRITICALERRORS); try { handle = NativeDisk.CreateFile(name, NativeDisk.FILE_READ_DATA, NativeDisk.FILE_SHARE_READ | NativeDisk.FILE_SHARE_WRITE, IntPtr.Zero, NativeDisk.OPEN_EXISTING, 0, IntPtr.Zero); } finally { Utils.SetErrorMode(Utils.ErrorModes.SYSTEM_DEFAULT); } if (handle == NativeDisk.INVALID_HANDLE_VALUE) { var exception = new Win32Exception(Marshal.GetLastWin32Error()); throw new Exception(string.Format("Error occured when trying to check drive type 2.\nError code: {0}\nMessage: {1}", exception.NativeErrorCode, exception.Message)); } if (NativeDisk.DeviceIoControl(handle, NativeDisk.IOCTL_STORAGE_CHECK_VERIFY, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReaded, IntPtr.Zero)) { retVal = devNumber.DeviceNumber; } } } NativeDisk.CloseHandle(handle); } break; default: throw new Win32Exception("Invalid device type"); } return(retVal); }