c ++ - Hvordan bruger man GetFinalPathNameByHandle til at løse et symbolsk link til en lokal mappe?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har følgende kode:


std::wstring GetSymbolicLinkTarget(std::wstring const& linkPath)
{
    TCHAR path[MAX\_PATH];
    CAutoFile hFile = CreateFile( linkPath.c\_str(),
        FILE\_READ\_EA,
        FILE\_SHARE\_READ | FILE\_SHARE\_WRITE | FILE\_SHARE\_DELETE,
        0,
        OPEN\_EXISTING,
        FILE\_FLAG\_BACKUP\_SEMANTICS | FILE\_ATTRIBUTE\_REPARSE\_POINT | FILE\_FLAG\_OPEN\_REPARSE\_POINT,
        0);
    if (INVALID\_HANDLE\_VALUE != hFile)
    {
        auto rcode = GetFinalPathNameByHandle(hFile, path, MAX\_PATH, FILE\_NAME\_NORMALIZED);
        switch (rcode)
        {
        case ERROR\_PATH\_NOT\_FOUND:
            return std::wstring();
        case ERROR\_NOT\_ENOUGH\_MEMORY:
            return std::wstring();
        case ERROR\_INVALID\_PARAMETER:
            return std::wstring();
        case ERROR\_ACCESS\_DENIED:
            return std::wstring();
        default:
            break;
        };

        if (path[0] == '\' && path[1] == '\' && path[2] == '?' && path[3] == '\')
            return std::wstring(path + 4, path + MAX\_PATH);
        else
            return std::wstring(path, path + MAX\_PATH);
    }

    return std::wstring();
}


Jeg opretter et symbolsk link som sådan:


e:
cd ProjectsProjectAIDE\_Files
mklink /D src ..


Så i nogle kode kalder jeg ovenstående funktion, som ifølge dokumenterne siger, at:


e:ProjectsProjectAIDE\_Filessrc


bør løse til:


e:ProjectsProjectA


I stedet returnerer den bare indtastningsvejen:


e:ProjectsProjectAIDE\_Filessrc


Resultatet rcode indeholder antallet af tegn i stien. Ikke en fejlkode.


Hvorfor undlader jeg at returnere de resultater, jeg forventer?

Bedste reference


Dette svar kom fra Hans Passant:


Problemet skyldtes primært brugen af ​​flaget FILE\_FLAG\_OPEN\_REPARSE\_POINT, hvilket gør følgende:



  OpenFileById-funktionen åbner enten filen eller den reparse
  punkt, afhængigt af brugen af ​​FILE\_FLAG\_OPEN\_REPARSE\_POINT flag. [[Kilde]]. [10]



Her er den endelige kode (med flere rettelser fra kommentarerne ovenfor.):


std::wstring GetSymbolicLinkTarget(std::wstring const& linkPath)
{
    TCHAR path[MAX\_PATH];
    CAutoFile hFile = CreateFile( linkPath.c\_str(),
        0,
        0,  
        0,
        OPEN\_EXISTING,
        FILE\_FLAG\_BACKUP\_SEMANTICS,
        0);
    if (INVALID\_HANDLE\_VALUE != hFile)
    {
        auto rcode = GetFinalPathNameByHandle(hFile, path, MAX\_PATH, FILE\_NAME\_NORMALIZED);
        if (rcode)
        {
            if (path[0] == '\' && path[1] == '\' && path[2] == '?' && path[3] == '\')
                return std::wstring(path + 4, path + rcode);
            else
                return std::wstring(path, path + rcode);
        }
    }

    return std::wstring();
}