$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
Windows has a couple of different formats for volume names but it is unclear how to convert a Volumename (example: \\?\Volume{GUID}\) to a DeviceName (example: \Device\HarddiskVolume1).
I found at that you can use the QueryDosDevice function but you need to remove the preceeding \\?\ and the trailing \ of the VolumeName:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function VolumeNameToDeviceName(const VolName: String): String; var s: String; TargetPath: Array[0..MAX_PATH] of WideChar; bSucceeded: Boolean; begin Result := ''; // VolumeName has a format like this: \\?\Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}\ // We need to strip this to Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963} s := Copy(VolName, 5, Length(VolName) - 5); bSucceeded := QueryDosDeviceW(PWideChar(WideString(s)), TargetPath, MAX_PATH) <> 0; if bSucceeded then begin Result := TargetPath; end else begin // raise exception end; end; |
2 Responses for "Converting a volume name to a device name"
“\Device\HarddiskVolume1”
That’s not a device name. It’s a DOS name for the volume.
\\.\PHYSICALDRIVE …
is the name for the device. And I’m not finding too many examples on how to get a list volumes on a physicaldriveX or check what PHYSICALDRIVE a volume is on.
Here’s the code to get physicaldrive from volumeguid:
[DllImport(“Kernel32.dll”, SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(string fileName, [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess, [MarshalAs(UnmanagedType.U4)] FileShare fileShare, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, int flags, IntPtr template);
[DllImport(“kernel32.dll”, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(Microsoft.Win32.SafeHandles.SafeFileHandle hDevice, uint dwIoControlCode,
IntPtr lpInBuffer, uint nInBufferSize,
IntPtr lpOutBuffer, uint nOutBufferSize,
out uint lpBytesReturned, IntPtr lpOverlapped);
[DllImport(“Kernel32.dll”, SetLastError = true)]
internal static extern bool CloseHandle(IntPtr hObject);
[StructLayout(LayoutKind.Sequential)]
internal struct DISK_EXTENT
{
internal int DiskNumber;
internal long StartingOffset;
internal long ExtentLength;
}
public static string GetPhysicalDrive(string volumeid)
{
String Result = String.Empty;
//\\?\Volume{e4d4a1ae-407c-11e1-9f1a-005056c00008}\
volumeid=volumeid.TrimEnd(‘\\’);
using (SafeFileHandle device = CreateFile(volumeid, FileAccess.Read, FileShare.Write | FileShare.Read | FileShare.Delete, IntPtr.Zero, FileMode.Open, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN, IntPtr.Zero))
{
if (device.IsInvalid) return “”;
int size = 0x400;//some big size
IntPtr buffer = Marshal.AllocHGlobal(size);
uint bytesReturned = 0;
DeviceIoControl(device, 0x00560000, IntPtr.Zero, 0, buffer, (uint)size, out bytesReturned, IntPtr.Zero);
// DOES NOT SUPPORT VOLUMES THAT SPAN DIFFERENT DRIVES
if (bytesReturned > 0)
{
int numberOfDiskExtents = (int)Marshal.PtrToStructure(buffer, typeof(int));
if (numberOfDiskExtents > 1)
return String.Empty;
IntPtr extentPtr = new IntPtr(buffer.ToInt32() + Marshal.SizeOf(typeof(long)));
DISK_EXTENT extent = (DISK_EXTENT)Marshal.PtrToStructure(extentPtr, typeof(DISK_EXTENT));
Result = String.Format(“\\\\.\\PHYSICALDRIVE{0}”, extent.DiskNumber);
}
Marshal.FreeHGlobal(buffer);
}
return Result;
}
Leave a reply