Как можно использовать GetFinalPathNameByHandle для разрешения символической ссылки на локальный каталог? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть следующий код:

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();
}

Я создаю символическую ссылку примерно так:

e:
cd Projects\ProjectA\IDE_Files
mklink /D src ..

Затем в некотором коде я вызываю вышеуказанную функцию, которая согласно документам гласит:

e:\Projects\ProjectA\IDE_Files\src

должно разрешить до:

e:\Projects\ProjectA

Вместо этого он просто возвращает путь ввода:

e:\Projects\ProjectA\IDE_Files\src

Результат rcode содержит количество символов в пути. Не код ошибки.

Почему это не дает ожидаемых результатов?

1 Ответ

0 голосов
/ 04 мая 2018

Ответ пришел от Ганс Пассант :

Проблема была связана главным образом с использованием флага FILE_FLAG_OPEN_REPARSE_POINT, который выполняет следующие действия:

Функция OpenFileById откроет файл или ответ точка, в зависимости от использования флага FILE_FLAG_OPEN_REPARSE_POINT. [источник] .

Вот окончательный код (с несколькими исправлениями из комментариев выше):

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...