How to assign a letter to a vhdx disk without getting it listed?

Laila 20 Reputation points
2024-12-21T01:06:36.7066667+00:00

One way I know to assign a letter to a vhdx disk is using the winapi AddAcessPath but to it work, first i need to attach the disk.

Even attaching the disk with the flag ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, when it receives a letter it shows a shell notification and the disk get listed under Devices and drives of the This PC window.

I dont need it to be listed there neither that notification, i'm working on a software to create virtual disks and spamming that nofication for each disk is not nice, I have been able to get everything done on background, i mean, installing the windows image/updates, using just the disk volume path \\?\Volume{1a855945-6630-4f69-848d-cfbf1674b1ce}\.

The letter is also necessary at the boot configuration as bcdboot seens to not work with the guid path for the Windows partition, only the system partition seens to accept a guid:

1. bcdboot G:\ /s Volume{d2a1742f-a81e-4740-ba78-c0ff34898478}
2. bcdboot \PhysicalDrive3\Windows /s Volume{d2a1742f-a81e-4740-ba78-c0ff34898478}
3. bcdboot \\?\Volume{ec668c78-a652-4056-862e-6e1a29dafe27}\  /s Volume{d2a1742f-a81e-4740-ba78-c0ff34898478}
4. bcdboot Volume{ec668c78-a652-4056-862e-6e1a29dafe27}  /s Volume{d2a1742f-a81e-4740-ba78-c0ff34898478}

Where d2a1742f... is the system partition and ec668... the Windows folder gpt partition. Only 1. works all other attempts fail with:

Failure when attempting to copy boot files.

The machine fails to boot when the disk doesn't contains a letter (i tried copying the boot files and after removing the letter) i wonder if there's any way to "force" it to auto pick a letter on this case.

I also tried setting the disk offline using DISK_ATTRIBUTE_OFFLINE before calling AddAcessPath but the api fail.

Looks like another way is using IOCTL_MOUNTMGR_CREATE_POINT, i tried to follow the example on the documentation but i have been unable to get it working, i get an error at DeviceIoControl:

Error: 123 The filename, directory name, or volume label syntax is incorrect.

    HANDLE m_hMountMgr = CreateFileW(
        MOUNTMGR_DOS_DEVICE_NAME,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL
    );

    if (m_hMountMgr == INVALID_HANDLE_VALUE)
    {
        log(L"Failed to open mount manager", GetLastError());
        return;
    }

	const wchar_t* mountPoint = L"H:\\";
	const wchar_t* volumePath = L"\\\\?\\Volume{81a19d6b-9c49-4d43-8caf-c69680bfad2a}\\";

    size_t volPathLen = wcslen(volumePath) * sizeof(WCHAR);
    size_t mountPointLen = wcslen(mountPoint) * sizeof(WCHAR);

    size_t totalSize = sizeof(MOUNTMGR_CREATE_POINT_INPUT) + volPathLen + mountPointLen;
    PMOUNTMGR_CREATE_POINT_INPUT pInput = (PMOUNTMGR_CREATE_POINT_INPUT)calloc(1, totalSize);
    if (!pInput)
    {
        log(L"Memory allocation failed");
        return;
    }

    pInput->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
    pInput->SymbolicLinkNameLength = (USHORT)mountPointLen;
    pInput->DeviceNameOffset = (USHORT)(pInput->SymbolicLinkNameOffset + mountPointLen);
    pInput->DeviceNameLength = (USHORT)volPathLen;

    RtlCopyMemory((BYTE*)pInput + pInput->SymbolicLinkNameOffset, mountPoint, mountPointLen);
    RtlCopyMemory((BYTE*)pInput + pInput->DeviceNameOffset, volumePath, volPathLen);

    DWORD bytesReturned = 0;
    BOOL success = DeviceIoControl(
        m_hMountMgr,
        IOCTL_MOUNTMGR_CREATE_POINT,
        pInput,
        (DWORD)totalSize,
        NULL,
        0,
        &bytesReturned,
        NULL
    );

    if (!success)
        log(L"DeviceIoControl failed", GetLastError());

    free(pInput);

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,804 questions
{count} votes

Accepted answer
  1. RLWA32 46,191 Reputation points
    2024-12-22T14:12:50.0433333+00:00

    The DefineDosDevice function can assign a disk letter to a partition. However, its behavior varies depending on the account and elevation status under which the function is called. If running as LocalSystem the assignment is made in the global namespace. Otherwise, it is made in the session's namespace. If running as Administrator with elevated privileges the assignment is visible to the elevated process but not visible to unelevated processes (e.g., explorer). If running without elevation the assignment is visible to unelevated processes like explorer, but not to an elevated process.

    Following minimal example with virtually no error checking can assign a drive letter without causing any notifications and so will not automatically appear in explorer.

    The sample code -

    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    
    #include <stdio.h>
    
    int wmain(int argc, WCHAR *argv[])
    {
        if (argc != 4)
        {
            wprintf(L"AddDev deviceletter disknumber partitionnumber\n"
                    L"For example AddDev S: 2 1\n");
    
            return 1;
        }
    
    
        WCHAR szDevice[MAX_PATH]{}, szTargetPath[MAX_PATH]{};
        swprintf_s(szDevice, L"Harddisk%sPartition%s", argv[2], argv[3]);
        if (QueryDosDeviceW(szDevice, szTargetPath, MAX_PATH))
        {
            if (DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, argv[1], szTargetPath))
                wprintf_s(L"Drive letter %s assigned\n", argv[1]);
            else
                wprintf_s(L"DefineDosDeviceW for %s failed with %d\n", argv[1], GetLastError());
        }
        else
            wprintf_s(L"QueryDosDeviceW for %s failed with %d\n", szDevice, GetLastError());
    
        return 0;
    }
    

    Following shows results of creating, attaching and partitioning a vhdx. No drive letters were assigned to any of the partitions.

    enter image description hereYou can see that it was added as Disk 2.

    From an unelevated command prompt assign drive letter S: to the first partition (PARTITION_SYSTEM_GUID). Note that the letter did not automatically appear in explorer and there were no notifications.

    Driveletter

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.