for this you need
(1) open file on device
(2) query it device name via IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
this ioctl have no input buffer and return
The mount manager client returns a variable-length structure of type
MOUNTDEV_NAME
, defined in Mountmgr.h
and
If the output buffer is too small to hold the device name, the mount
manager client must set the Information field to
sizeof(MOUNTDEV_NAME)
and the Status field to
STATUS_BUFFER_OVERFLOW
. In addition, the mount manager client fills in the NameLength member of the MOUNTDEV_NAME
structure.
STATUS_BUFFER_OVERFLOW
converted to ERROR_MORE_DATA
win32 error. if DeviceIoControl
return this error we can get required size of buffer as
FIELD_OFFSET(MOUNTDEV_NAME, Name) + pmdn->NameLength;
(3) query mount manager device with IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
this ioct take as input MOUNTDEV_NAME
which we got on step 2 and return MOUNTMGR_VOLUME_PATHS
(read about this inside mountmgr.h)
so final code
#include <mountmgr.h>
inline ULONG BOOL_TO_ERROR(BOOL f)
{
return f ? NOERROR : GetLastError();
}
ULONG GetDosVolumePath(PCWSTR InterfaceLink, PWSTR* ppszDosPath)
{
*ppszDosPath = 0;
HANDLE hFile = CreateFileW(InterfaceLink, 0, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) return GetLastError();
union {
PVOID buf;
PMOUNTDEV_NAME pmdn;
};
ULONG dwError;
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = sizeof(MOUNTDEV_NAME) + 0x10, InputBufferLength;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
dwError = BOOL_TO_ERROR(DeviceIoControl(hFile, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, 0, 0, pmdn, cb, &rcb, 0));
rcb = FIELD_OFFSET(MOUNTDEV_NAME, Name) + pmdn->NameLength;
} while ( dwError == ERROR_MORE_DATA);
CloseHandle(hFile);
if (dwError == NOERROR)
{
hFile = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0, 0, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
union {
PVOID pv;
PMOUNTMGR_VOLUME_PATHS pmvp;
};
InputBufferLength = rcb, cb = 0, rcb = sizeof(MOUNTMGR_VOLUME_PATHS) + 0x4;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(pv = alloca(rcb - cb), pmdn);
}
dwError = BOOL_TO_ERROR(DeviceIoControl(hFile,
IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
pmdn, InputBufferLength, pmvp, cb, &rcb, 0));
if (dwError == NOERROR)
{
*ppszDosPath = _wcsdup(pmvp->MultiSz);
}
rcb = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + pmvp->MultiSzLength;
} while (dwError == ERROR_MORE_DATA);
CloseHandle(hFile);
}
}
return dwError;
}
PWSTR pszDosPath;
if (GetDosVolumePath(L"\\\\?\\USBSTOR#Disk&Ven_SanDisk&Prod_Ultra_Fit&Rev_1.00#4C530000260829120162&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}", &pszDosPath) == NOERROR)
{
DbgPrint("%S\n", pszDosPath);
free(pszDosPath);
}