Определить букву диска (имя душ) съемного диска - PullRequest
1 голос
/ 20 апреля 2020

У меня есть путь к тому \\?\USBSTOR#Disk&Ven_SanDisk&Prod_Ultra_Fit&Rev_1.00#4C530000260829120162&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}, и я хочу определить местоположение dos (c: / d: / ...) пути. Я получаю путь от:

PDEV_BROADCAST_DEVICEINTERFACE lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE)lpdb;
lpdbv->dbcc_name <---path

Как я могу получить букву диска из этого? Поможет ли в любом случае функция

FilterGetDosName(LPCWSTR lpVolumeName,
  LPWSTR  lpDosName,
  DWORD   dwDosNameBufferSize)

?

1 Ответ

1 голос
/ 20 апреля 2020

для этого вам нужно

(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);
    }
...