Re[5]: CreateFile - AccessDenied когда существует папка
От: Alexander G Украина  
Дата: 12.05.20 16:13
Оценка: 5 (2) +1
Здравствуйте, MuPoB, Вы писали:

MPB>Проблема в том, что между вызовом функции CreateFile и вызовом любой функции, анализирующей ошибку (GetFilAttrbutes, FindFirstFile и т.п.) может произойти всё что угодно, и то, что вернёт функция анализа, будет уже неадекватно. Или если сначала проверить, существует такая папка или нет, а потом создать файл — опять перед созданием состояние ФС может поменяться


MPB>Нужно чтобы сразу ошибка была говорящей, а не просто AccessDenied. Создание рандомного файла и его переименование сразу позволяет понять, что директория с таким именем уже существует


Есть решение. После неуспешного CreateFile получить последний NTSTATUS из TEB.

HANDLE h = ::CreateFile(path, 0, 7, 0, OPEN_ALWAYS, 0, 0);
if (h == INVALID_HANDLE_VALUE)
{
   NTSTATUS status = GetLastNtStatus();
   if (status == STATUS_FILE_IS_A_DIRECTORY) { ... }
}


Разве что заминка будет с GetLastNtStatus. Документриованный путь мне неизвестен.
Недокументировано как-то так:
inline NTSTATUS GetLastNtStatus()
{
#if defined(_M_X64)
    return __readgsdword(0x1250);
#elif defined (_M_IX86)
    return __readfsdword(0xBF4);
#else
#error Implement this for ARM or whatever architecture you have
#endif 
}

Магические константы подсмотрел в Википедии.

Более чистым, возможно, будет прямой вызов NtCreateFile / NtOpenFile.
Это более легально с точки зрения документрованности, но потребует большего изменения вызывающего кода.
Русский военный корабль идёт ко дну!
Отредактировано 12.05.2020 16:18 Alexander G . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.