1

I have a volume path \\?\USBSTOR#Disk&Ven_SanDisk&Prod_Ultra_Fit&Rev_1.00#4C530000260829120162&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} and I want to determine the dos location(c:/d:/...) of the path. I get the path from :

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

How can I get the drive letter from this? Will the function

FilterGetDosName(LPCWSTR lpVolumeName,
  LPWSTR  lpDosName,
  DWORD   dwDosNameBufferSize)

help in anyway?

MyCopy
  • 155
  • 1
  • 8

1 Answers1

1

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);
    }
RbMm
  • 31,280
  • 3
  • 35
  • 56