Search code examples
c#kernel32

GetShortPathName() return garbled when feeding particular path


Our team have used the following code for years

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern Int32 GetShortPathName(string path, StringBuilder shortPath, int shortPathLength);

public static string GetShortPathName(string longPath)
{
    StringBuilder shortPath = new StringBuilder(longPath.Length + 1);

    if (0 == GetShortPathName(longPath, shortPath, shortPath.Capacity))
    {
        return longPath;
    }

    return shortPath.ToString();
}

Somewhen last week we had a report that our application stops working. After troubleshooting we found when feeding the following path to the GetShortPathName() and it returns path with garbled inside.

\\?\C:\Disks\WDT\58.6.5\winpex32.wim

So I was trying to find the pattern but couldn't find any...

var r1 = GetShortPathName(@"\\?\C:\Disks\WDT\58.6.5\winpex32.wim"); // r1 = \\?\C:\Disks\WDT\586~1.5䳸ĴDšóó%
var r2 = GetShortPathName(@"\\?\C:\Disks\WDT\test\winpex32.wim");   // r2 = \\?\C:\Disks\WDT\test\winpex32.wim
var r3 = GetShortPathName(@"\\?\C:\Disks\WDT\1.2.3\winpex32.wim");  // r3 = \\?\C:\Disks\WDT\1.2.3\winpex32.wim
var r4 = GetShortPathName(@"\\?\C:\Disks\WDT\11.6.5\winpex32.wim"); // r4 = \\?\C:\Disks\WDT\11.6.5\winpex32.wim
var r5 = GetShortPathName(@"\\?\C:\Disks\WDT\58.6.6\winpex32.wim"); // r5 = \\?\C:\Disks\WDT\58.6.6\winpex32.wim
var r6 = GetShortPathName(@"\\?\C:\Disks\WDT\58.6.4\winpex32.wim"); // r6 = \\?\C:\Disks\WDT\58.6.4\winpex32.wim
var r7 = GetShortPathName(@"\\?\C:\Disks\WDT\0.6.5\winpex32.wim");  // r7 = \\?\C:\Disks\WDT\0.6.5\winpex32.wim
var r8 = GetShortPathName(@"\\?\C:\X\WDT\58.6.5\winpex32.wim");     // r8 = \\?\C:\X\WDT\58.6.5\winpex32.wim
var r9 = GetShortPathName(@"\\?\C:\Disks\T\58.6.5\winpex32.wim");   // r9 = \\?\C:\Disks\T\58.6.5\winpex32.wim
var r10 = GetShortPathName(@"\\?\C:\Disks\WDT\58.6.5\wx.wim");      // r10 = \\?\C:\Disks\WDT\58.6.5\wx.wim

All the others work fine except r1 and I'm running out of ideas.

What causes the garbled in this particular case and what can I do to prevent it?

enter image description here


Solution

  • So I found that every time the garbled is slightly different.
    Which makes me wonder if somehow GetShortPathName() can't properly store the result to StringBuilder, and Yes it was, I didn't provide enough space to StringBuilder which result in all these messes.

    Once I add sufficient volume of capacity

    StringBuilder shortPath = new StringBuilder(260);
    

    I can retrieve the path without garbling:

    \\?\C:\Disks\WDT\586~1.5\winpex32.wim