/// <summary> /// <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365194(v=vs.85).aspx" /> /// </summary> public VOLUME_DISK_EXTENTS VolumeGetVolumeDiskExtents() { // Fetch in increments of 32 bytes, as one extent (the most common case) is one extent pr. volume. byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.VolumeGetVolumeDiskExtents, 32); // Build the VOLUME_DISK_EXTENTS structure VOLUME_DISK_EXTENTS res = new VOLUME_DISK_EXTENTS(); res.NumberOfDiskExtents = BitConverter.ToUInt32(data, 0); res.Extents = new DISK_EXTENT[res.NumberOfDiskExtents]; using (UnmanagedMemory dataPtr = new UnmanagedMemory(data)) { // TODO: This code needs to be tested for volumes with more than one extent. for (int i = 0; i < res.NumberOfDiskExtents; i++) { IntPtr currentDataPtr = new IntPtr(dataPtr.Handle.ToInt64() + 8 + i * MarshalHelper.SizeOf <DISK_EXTENT>()); DISK_EXTENT extent = currentDataPtr.ToStructure <DISK_EXTENT>(); res.Extents[i] = extent; } } return(res); }
//method for disk extents private static uint?GetPhysicalDriveNumber(string driveLetter) { var sDrive = "\\\\.\\" + driveLetter + ":"; var hDrive = CreateFileW(sDrive, 0, // No access to drive FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hDrive == null || hDrive.IsInvalid) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); log.Warn("CreateFile failed. " + message); return(uint.MinValue); } uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS); // From winioctl.h VOLUME_DISK_EXTENTS query_disk_extents = new VOLUME_DISK_EXTENTS(); uint returned_query_disk_extents_size; bool query_disk_extents_result = DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, ref query_disk_extents, (uint)Marshal.SizeOf(query_disk_extents), out returned_query_disk_extents_size, IntPtr.Zero); hDrive.Close(); if (query_disk_extents_result == false || query_disk_extents.Extents.Length != 1) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); log.Warn("DeviceIoControl failed. " + message); return(null); } return(query_disk_extents.Extents[0].DiskNumber); }
public static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped );
/// <summary> /// Get volume disk extents for volumes that may or may not span more than one physical drive. /// </summary> /// <param name="devicePath">The device path of the volume.</param> /// <returns>An array of DiskExtent structures.</returns> /// <remarks></remarks> public static DiskExtent[] GetDiskExtentsFor(string devicePath) { DiskExtent[] deOut = null; MemPtr inBuff = new MemPtr(); int inSize; IntPtr file; int h = 0; var de = new DISK_EXTENT(); var ve = new VOLUME_DISK_EXTENTS(); bool r; file = IO.CreateFile(devicePath, IO.GENERIC_READ, IO.FILE_SHARE_READ | IO.FILE_SHARE_WRITE, IntPtr.Zero, IO.OPEN_EXISTING, IO.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (file == DevProp.INVALID_HANDLE_VALUE) { return(null); } uint arb = 0; inSize = Marshal.SizeOf(de) + Marshal.SizeOf(ve); inBuff.Length = inSize; r = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero); if (!r && User32.GetLastError() == ERROR_MORE_DATA) { inBuff.Length = inSize * inBuff.IntAt(0L); r = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero); } if (!r) { inBuff.Free(); User32.CloseHandle(file); return(null); } User32.CloseHandle(file); ve = VOLUME_DISK_EXTENTS.FromPtr(inBuff); inBuff.Free(); h = 0; deOut = new DiskExtent[ve.Extents.Length]; foreach (var currentDe in ve.Extents) { de = currentDe; deOut[h].PhysicalDevice = de.DiskNumber; deOut[h].Space = de.Space; deOut[h].Size = de.ExtentLength; deOut[h].Offset = de.StartingOffset; h += 1; } return(deOut); }
//method for disk extents public static uint?GetPhysicalDriveNumber(string driveLetter) { var sDrive = "\\\\.\\" + driveLetter + ":"; var hDrive = CreateFileW(sDrive, 0, // No access to drive FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); VOLUME_DISK_EXTENTS query_disk_extents; bool query_disk_extents_result; try { if (hDrive == INVALID_HANDLE_VALUE) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); if (Log.IsInfoEnabled) { Log.Info("CreateFile failed. " + message); } return(uint.MinValue); } uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS); // From winioctl.h query_disk_extents = new VOLUME_DISK_EXTENTS(); uint returned_query_disk_extents_size; query_disk_extents_result = DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, ref query_disk_extents, (uint)Marshal.SizeOf(query_disk_extents), out returned_query_disk_extents_size, IntPtr.Zero); } finally { Win32ThreadsMethods.CloseHandle(hDrive); } if (query_disk_extents_result == false || query_disk_extents.Extents.Length != 1) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); if (Log.IsInfoEnabled) { Log.Info("DeviceIoControl failed. " + message); } return(null); } return(query_disk_extents.Extents[0].DiskNumber); }
private int GetDiskForVolume(string volume) { int disk = -1; // CreateFile method accepts "\\\\.\\Volume{4b3d5e28-4b1a-11e9-b640-54bf64435496}" SafeFileHandle hndl = CreateFile(string.Format("\\\\.\\{0}", volume), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, IntPtr.Zero); if (hndl.IsInvalid) { LogHelper.Log("EFIFirmwareService:GetDiskForVolume: Invalid handle:"); } else { VOLUME_DISK_EXTENTS vde = new VOLUME_DISK_EXTENTS(); UInt32 outBufferSize = (UInt32)Marshal.SizeOf(vde); IntPtr outBuffer = Marshal.AllocHGlobal((int)outBufferSize); UInt32 bytesReturned = 0; if (DeviceIoControl(hndl, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero)) { Marshal.PtrToStructure(outBuffer, vde); disk = Convert.ToInt32(vde.Extents.DiskNumber); } Marshal.FreeHGlobal(outBuffer); } hndl.Close(); return(disk); }
public static VOLUME_DISK_EXTENTS FromPtr(IntPtr ptr) { VOLUME_DISK_EXTENTS FromPtrRet = default; var ve = new VOLUME_DISK_EXTENTS(); int cb = Marshal.SizeOf <DISK_EXTENT>(); MemPtr m = ptr; int i; ve.NumberOfExtents = m.IntAt(0L); ve.Space = m.IntAt(1L); ve.Extents = new DISK_EXTENT[ve.NumberOfExtents]; m = m + 8; var c = ve.NumberOfExtents; for (i = 0; i < c; i++) { ve.Extents[i] = m.ToStruct <DISK_EXTENT>(); m = m + cb; } FromPtrRet = ve; return(FromPtrRet); }
public static extern bool DeviceIoControl([InAttribute()] VolumeSafeHandle hDevice, UInt32 dwIoControlCode, [InAttribute()] IntPtr lpInBuffer, Int32 nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
public Extents(string name) { // Remove trailing '/' character from path string newname = name.Substring(0, name.Length - 1); IntPtr volhandle = CreateFile(newname, EFileAccess.Any, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Normal, 0); if (volhandle.ToInt32() == INVALID_HANDLE_VALUE) { return; } try { VOLUME_DISK_EXTENTS vextents = new VOLUME_DISK_EXTENTS(); DISK_EXTENT dextent = new DISK_EXTENT(); uint numextents = 1; int allocsize = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent); IntPtr memblock = IntPtr.Zero; IntPtr alloced; memblock = Marshal.AllocHGlobal((int)allocsize); alloced = memblock; try { int returned = 0; VOLUME_DISK_EXTENTS diskExtents = new VOLUME_DISK_EXTENTS(); while (true) { if (!DeviceIoControl(volhandle, IoctlControlCodes.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, memblock, allocsize, out returned, 0)) { int err = Marshal.GetLastWin32Error(); if ((err == ERROR_INSUFFICIENT_BUFFER) || (err == ERROR_MORE_DATA)) { Marshal.PtrToStructure(memblock, diskExtents); numextents = diskExtents.NumberOfDiskExtents; allocsize = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent); memblock = Marshal.ReAllocHGlobal(memblock, new IntPtr(allocsize)); alloced = memblock; continue; } else { return; } } break; } Marshal.PtrToStructure(memblock, diskExtents); memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(diskExtents)); for (int i = 0; i < diskExtents.NumberOfDiskExtents; i++) { Marshal.PtrToStructure(memblock, dextent); Extent extent = new Extent { DiskNumber = dextent.DiskNumber, ExtentLength = dextent.ExtentLength, StartingOffset = dextent.StartingOffset }; this.Add(extent); memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(dextent)); } } finally { Marshal.FreeHGlobal(alloced); } } catch (Exception e) { WmiBase.Singleton.DebugMsg("Extent listing exception : " + e.ToString()); throw; } finally { CloseHandle(volhandle); } }
public static extern bool DeviceIoControl([InAttribute()] VolumeSafeHandle hDevice, UInt32 dwIoControlCode, [InAttribute()] IntPtr lpInBuffer, Int32 nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
private void dumpDiskInfo() { if (cbDriveInfos.SelectedIndex <=0 ) return; MyDrive myDrive = (MyDrive)this.cbDriveInfos.SelectedItem; rtxtExtends.Clear(); SafeFileHandle volume = CreateFile( "\\\\.\\" + myDrive.DriveLetter, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero); if (volume.IsInvalid) { string message = GetSystemMessage(Marshal.GetHRForLastWin32Error()); MessageBox.Show(message); } else { uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS); VOLUME_DISK_EXTENTS query_disk_extents = new VOLUME_DISK_EXTENTS(); uint returned_query_disk_extents_size; try { bool query_disk_extents_result = DeviceIoControl( volume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, ref query_disk_extents, (uint)Marshal.SizeOf(query_disk_extents), out returned_query_disk_extents_size, IntPtr.Zero); if (query_disk_extents_result == false || query_disk_extents.Extents.Length != 1) { string message = GetSystemMessage(Marshal.GetLastWin32Error()); MessageBox.Show(message); } else { this.lblNumbersOfDiskExtends.Text = String.Format("{0}", query_disk_extents.NumberOfDiskExtents); foreach (DISK_EXTENT ext in query_disk_extents.Extents) { rtxtExtends.AppendText(String.Format("Disk number:{0}\n", ext.DiskNumber)); rtxtExtends.AppendText(String.Format("Extend length:{0}\n", ext.ExtentLength)); rtxtExtends.AppendText(String.Format("Starting offset:{0}\n", ext.StartingOffset)); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (!volume.IsInvalid && !volume.IsClosed) { volume.Close(); } } } }
private static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);