Get UNC path from a local path or mapped path

Chris J picture Chris J · Sep 11, 2009 · Viewed 12.8k times · Source

In Delphi there is a function ExpandUNCFileName that takes in a filename and converts it into the UNC equivalent. It expands mapped drives and skips local and already expanded locations.

Samples

C:\Folder\Text.txt -> C:\Folder\Text.txt
L:\Folder\Sample.txt -> \\server\Folder1\Folder\Sample.txt Where L: is mapped to \\server\Folder1\
\\server\Folder\Sample.odf -> \server\Folder\Sample.odf

Is there a simple way to do this in C# or will I have to use windows api call WNetGetConnection and then manually check the ones that wouldn't get mapped?

Answer

Jack Culhane picture Jack Culhane · Oct 1, 2013

Here's some C# code with a wrapper function LocalToUNC, which seems to work OK, though I haven't tested it extensively.

    [DllImport("mpr.dll")]
    static extern int WNetGetUniversalNameA(
        string lpLocalPath, int dwInfoLevel, IntPtr lpBuffer, ref int lpBufferSize
    );

    // I think max length for UNC is actually 32,767
    static string LocalToUNC(string localPath, int maxLen = 2000)
    {
        IntPtr lpBuff;

        // Allocate the memory
        try
        {
            lpBuff = Marshal.AllocHGlobal(maxLen); 
        }
        catch (OutOfMemoryException)
        {
            return null;
        }

        try
        {
            int res = WNetGetUniversalNameA(localPath, 1, lpBuff, ref maxLen);

            if (res != 0)
                return null;

            // lpbuff is a structure, whose first element is a pointer to the UNC name (just going to be lpBuff + sizeof(int))
            return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(lpBuff));
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            Marshal.FreeHGlobal(lpBuff);
        }
    }