About Terminal Server, Citrix, Delphi and other stuff
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; |
.NET .NET FrameWork Active Directory Altiris Automation Manager bug Citrix datastore Dell Delphi Excel Exchange Exchange2003 Exchange2010 Hack HP iOS Java LinkedIn Linux Lync Office Office 2010 Outlook Passat Password PowerPoint PowerShell RES RNS510 SasLibEx Security Terminal Server ThinApp TSAdminEx Unattended VBS VCDS Vista Visual Basic VMWare Volkswagen Windows PE Wordpress XenApp
WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.
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 = 0×400;//some big size
IntPtr buffer = Marshal.AllocHGlobal(size);
uint bytesReturned = 0;
DeviceIoControl(device, 0×00560000, 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