для этого вам нужно
(1) открыть файл на устройстве
(2) запросить имя устройства через IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
этот ioctl не имеет входного буфера и возвращает
Клиент менеджера монтирования возвращает структуру переменной длины типа MOUNTDEV_NAME
, определенный в Mountmgr.h
и
Если выходной буфер слишком мал для хранения имени устройства, клиент менеджера монтирования должен установить для поля Information значение sizeof(MOUNTDEV_NAME)
и для поля Status значение STATUS_BUFFER_OVERFLOW
. Кроме того, клиент менеджера монтирования заполняет элемент NameLength структуры MOUNTDEV_NAME
.
STATUS_BUFFER_OVERFLOW
, преобразованный в ERROR_MORE_DATA
win32 error , если DeviceIoControl
вернет эту ошибку, мы можем получить требуемый размер буфера как
FIELD_OFFSET(MOUNTDEV_NAME, Name) + pmdn->NameLength;
(3) устройство диспетчера монтирования запросов с IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
с этим ioct take в качестве ввода MOUNTDEV_NAME
, которое мы получили на шаге 2, и возвращаем MOUNTMGR_VOLUME_PATHS
(об этом читайте внутри mountmgr.h )
итоговый код
#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);
}