Get available drive letter and mount

Agha Khan 161 Reputation points
2022-10-03T17:41:35.807+00:00

[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_EX
{
public PARTITION_STYLE PartitionStyle;
public int PartitionCount;
public DRIVE_LAYOUT_INFORMATION_UNION DriveLayoutInformaiton;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 0x16)]  
        public PARTITION_INFORMATION_EX[] PartitionEntry;  
    }  

var driveList = DriveInfo.GetDrives();

        bool foundSystemDrive = false;  
        int finalDiskIndex = -1;  
        for (int diskIndex = 0; diskIndex < driveList.Length; diskIndex++)  
        {  
            if (!foundSystemDrive)  
            {  
                IntPtr hDisk = CreateFile(@$"\\.\PhysicalDrive{diskIndex}", GENERIC_READ,  
                    FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero,  
                    OPEN_EXISTING, 0, IntPtr.Zero);  
                if (hDisk != INVALID_HANDLE_VALUE)  
                {  
                    try  
                    {  
                        DRIVE_LAYOUT_INFORMATION_EX dli = new DRIVE_LAYOUT_INFORMATION_EX();  
                        uint lpBytesReturned;  
                        var fSuccess = DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, IntPtr.Zero, 0,  
                            ref dli, (uint)Marshal.SizeOf(dli), out lpBytesReturned, IntPtr.Zero);  
                        if (fSuccess)  
                        {  
                            var partitionEntryList = dli.PartitionEntry;  
                            string driveInfo = $"Drive has {partitionEntryList} partitions";  
                            string driveStyle = $"Drive partition style is {partitionEntryList}";  
                            string singlePartiton = string.Empty;  
                            foreach (var obj in partitionEntryList)  
                            {  
                                efiSystemPartition = obj.DriveLayoutInformaiton.Gpt.Name == "EFI system partition";  
                                partitionIndex = obj.PartitionNumber;  
                                singlePartiton =  
                                    $"Partition number is {obj.PartitionNumber}, style is {obj.PartitionStyle}, size is {obj.PartitionLength} bytes";  
                                if (efiSystemPartition)  
                                {  
                                    foundSystemDrive = true;  
                                    finalDiskIndex = diskIndex;  
                                    break;  
                                }  
                            }  
                        }  
                        else  
                        {  
                            string message = $"DeviceIoControl error code as {Marshal.GetLastWin32Error()}";  
                        }  
                    }  
                    catch (Exception ex)  
                    {  
                        Console.WriteLine(ex.Message);  
                    }  

                    CloseHandle(hDisk);  
                }  
            }  
        }  

This code gives me information that I have EFI partition at Desk #0 and partition #0.
Now I want to write some data at EFI partition but need a drive letter to the mountain it.
I need a function that tells me which drive letters are available. I just can’t assume that Z letter is available. (Z may be a network drive)

How can I ask Mountvol.exe that I am interested in Desk #0 and partition #0?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,446 questions
{count} votes

5 answers

Sort by: Most helpful
  1. Castorix31 82,036 Reputation points
    2022-10-03T18:01:03.02+00:00

    I need a function that tells me which drive letters are available.

    GetLogicalDrives or GetLogicalDriveStrings ?

    0 comments No comments

  2. Agha Khan 161 Reputation points
    2022-10-03T21:19:26.197+00:00

    Hello @Castorix31 :
    They are Logical drives and do not give information about which letters are available. Suppose you have a Network drive and a letter is assigned to it. You can not use that letter. I could also check network drives,


  3. Xiaopo Yang - MSFT 11,506 Reputation points Microsoft Vendor
    2022-10-04T02:12:53.163+00:00

    For Network Drives, you can use WNetEnumResource to enumerate network resources or existing connections. For an example, see Enumerating Network Resources.

    0 comments No comments

  4. Agha Khan 161 Reputation points
    2022-10-04T02:56:45.603+00:00

    @ XiaopoYang-MSFT · Looks good, but I am working with C#. Do you any code in C#.


  5. Agha Khan 161 Reputation points
    2022-10-15T05:18:38.387+00:00

    Hi @Xiaopo Yang - MSFT :
    // C++ solution
    std::list<char> driveList;
    auto drives = GetLogicalDrives();
    DWORD mask = 0x00000001;

    for (int i = 0; i < 32; i++, mask <<= 1)
    {
    if ((drives & mask) != 0)
    {
    driveList.push_back(i + _TEXT('A'));
    }
    }
    It will give you net drives and all logical drives.