GetFinalPathNameByHandle() result without prepended '\\?\'

╄→尐↘猪︶ㄣ 提交于 2019-12-10 19:27:42

问题


Here is my code snippet:

char existingTarget[MAX_PATH]; 
HANDLE hFile = CreateFile(linkPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
    GetFinalPathNameByHandle(hFile, existingTarget, MAX_PATH, FILE_NAME_OPENED);
    CloseHandle(hFile);
}

However, existingTarget is coming out to be \\?\C:\mydir\etc. How can I get it to return just C:\mydir\etc?

Note: I don't want to check for the string \\?\ and just memmove it, it's a bit too hackish of a solution for this program.


回答1:


how can I get it to return just C:\mydir\etc

You cannot. VOLUME_NAME_DOS and VOLUME_NAME_GUID always use that format, and is documented as such:

The string that is returned by this function uses the \\?\ syntax.

See the example results in the Community Additions section of the documentation.

Note: I don't want to check for the string \\?\ and just memmove it, its a bit too hackish of a solution for this program.

That is the easiest solution. Otherwise, you have to use other APIs to translate the returned path into a more human-readable path. Such as using the result of VOLUME_NAME_NT with QueryDosDevice(), or using the result of VOLUME_NAME_GUID with GetVolumePathNamesForVolumeName().




回答2:


I know, you don't want to check for \\?\ and remove it, but as Remy explains in his answer, that's the easiest solution. However, you should be careful, because local paths and network paths have different prefixes. As you know, a local path starts with \\?\, but a network path starts with \??\UNC\, for example:

\\?\UNC\My server\My share\Directory

As a result, based on your code, my solution to remove the prefixes is as follows:

char existingTarget[MAX_PATH];
HANDLE hFile = CreateFileA(linkPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
    DWORD ret = GetFinalPathNameByHandleA(hFile, existingTarget, MAX_PATH, FILE_NAME_OPENED);
    CloseHandle(hFile);

    // Check whether existingTarget is large enough to hold the final path.
    if (ret < MAX_PATH)
    {
        // The local path prefix is also a prefix of the network path prefix.
        // Therefore, look for the network path prefix first.
        // Please note that backslashes have to be escaped.
        std::string targetPath(existingTarget);
        if (targetPath.substr(0, 8).compare("\\\\?\\UNC\\") == 0)
        {
            // In case of a network path, replace `\\?\UNC\` with `\\`.
            targetPath = "\\" + targetPath.substr(7);
        }
        else if (targetPath.substr(0, 4).compare("\\\\?\\") == 0)
        {
            // In case of a local path, crop `\\?\`.
            targetPath = targetPath.substr(4);
        }
    }
}

If needed, you can still use memmove() to copy targetPath into another variable.



来源:https://stackoverflow.com/questions/31439011/getfinalpathnamebyhandle-result-without-prepended

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!