QueryDosDevice (kernel32)
Last changed: -66.61.25.155

.
Summary

C# Signature:

[DllImport("kernel32.dll")]
static extern uint QueryDosDevice(string lpDeviceName, IntPtr lpTargetPath,
   uint ucchMax);

Alternate signature:

[DllImport("kernel32.dll")]

static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);

User-Defined Types:

None.

Notes:

Use the second signature if you want only the current mapping for the DOS device. The first null-terminated string returned by the function contains the current mapping, and will be automatically read into the StringBuilder.

Tips & Tricks:

If you are trying to get a string array of all the Devices on your system, this is the code that I used for this.

Not sure if it's the cleanest... but it works

Sample Code:

private static string[] QueryDosDevice()

{

    // Allocate some memory to get a list of all system devices.
    // Start with a small size and dynamically give more space until we have enough room.
    int returnSize = 0;
    int maxSize = 100;
    string allDevices = null;
    IntPtr mem;
    string [] retval = null;

    while(returnSize == 0)
    {
        mem = Marshal.AllocHGlobal(maxSize);
        if(mem != IntPtr.Zero)
        {
            // mem points to memory that needs freeing
            try
            {
                returnSize = QueryDosDevice(null, mem, maxSize);
                if(returnSize != 0)
                {
                    allDevices = Marshal.PtrToStringAnsi(mem, returnSize);
                    retval = allDevices.Split('\0');
                    break;    // not really needed, but makes it more clear...
                }
                else if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                {
                    maxSize *= 10;
                }
                else
                {
                    Marshal.ThrowExceptionForHR(GetLastError());
                }
            }
            finally
            {
                Marshal.FreeHGlobal(mem);
            }
        }
        else
        {
            throw new OutOfMemoryException();
        }
    }
    return retval;

}

Sample Code for second signature:

private static string GetRealPath(string path)

{

    string realPath;
    StringBuilder pathInformation = new StringBuilder(250);

    // Get the drive letter of the
     string driveLetter = Path.GetPathRoot(path).Replace("\\", "");
     QueryDosDevice(driveLetter, pathInformation, 250);

    // If drive is substed, the result will be in the format of "\??\C:\RealPath\".
    if (pathInformation.ToString().Contains(\\??\\))
    {
       // Strip the \??\ prefix.
       string realRoot = pathInformation.ToString().Remove(0, 4);

       //Combine the paths.
       realPath = Path.Combine(realRoot, path.Replace(Path.GetPathRoot(path), ""));
    }
    else
    {
       realPath = path;
    }

    return realPath;

}

Alternative Managed API:

Do you know one? Please contribute it!

Documentation