Результат GetFinalPathNameByHandle () без префиксного «\\? \»

Вот мой фрагмент кода:

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

Тем не мение, existingTarget выходит, чтобы быть \\?\C:\mydir\etc, Как я могу заставить его вернуться просто C:\mydir\etc?

Заметка: Я не хочу проверять строку \\?\ и просто memmove Это слишком хакерское решение для этой программы.

3

Решение

как я могу заставить его вернуть только C: \ mydir \ etc

Ты не можешь. VOLUME_NAME_DOS а также VOLUME_NAME_GUID всегда использовать этот формат, и задокументировано как таковой:

Строка, возвращаемая этой функцией, использует \\?\ синтаксис.

Увидеть пример результатов в разделе дополнений сообщества документация.

Примечание: я не хочу проверять строку \\?\ и просто запомни это, слишком хакерское решение для этой программы.

Это самое простое решение. В противном случае вам придется использовать другие API для перевода возвращаемого пути в более понятный для человека путь. Например, используя результат VOLUME_NAME_NT с QueryDosDevice(), или используя результат VOLUME_NAME_GUID с GetVolumePathNamesForVolumeName().

3

Другие решения

Я знаю, вы не хотите проверять \\?\ и удалить его, но, как объясняет Реми в своем ответ, это самое простое решение. Однако вы должны быть осторожны, потому что локальные и сетевые пути имеют разные префиксы. Как вы знаете, локальный путь начинается с \\?\, но сетевой путь начинается с \??\UNC\, например:

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

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

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

При необходимости вы все еще можете использовать memmove() копировать targetPath в другую переменную.

0

По вопросам рекламы [email protected]