Почему Windows возвращает ERROR_ACCESS_DENIED, когда я пытаюсь открыть файл, ожидающий удаления

Когда мы открываем файл, ожидающий удаления, подсистема Windows возвращает ERROR_ACCESS_DENIED, даже если они имеют статус ERROR_DELETE_PENDING.

HANDLE h = CreateFile(L"C:\\test.txt",
    GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, 0, CREATE_ALWAYS, 0, 0);
// Succeed

BOOL fOk = DeleteFile(L"C:\\test.txt");
// Succeed. The file has been delete pended now, 
// because the file is still opening.

HANDLE h2 = CreateFile(L"C:\\test.txt",
    GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0);
// Failed with ERROR_ACCESS_DENIED. But why not ERROR_DELETE_PENDING?    

Для последней функции CreateFile драйвер файловой системы вернул STATUS_DELETE_PENDING.
Но подсистема Win32 преобразовала его в ERROR_ACCESS_DENIED. Почему?

Я думаю, что это должно быть ERROR_DELETE_PENDING, и мне очень любопытно, почему они так спроектировали.
Есть веская причина?


person Benjamin    schedule 13.07.2011    source источник


Ответы (2)


Ядро Windows и «родной» API используют коды NTSTATUS. Win32 использует коды ошибок Win32, которые восходят к кодам ошибок DOS. Windows всегда сопоставляла STATUS_DELETE_PENDING с ERROR_ACCESS_DENIED. Я смог проверить это на NT4, которая не определяла ERROR_DELETE_PENDING в winerror.h.

Определение ERROR_DELETE_PENDING было добавлено в winerror.h в Windows XP, но похоже, что сопоставление всегда было таким.

Я предполагаю, что у кого-то была такая же идея, как и у вас - почему бы не сопоставить STATUS_DELETE_PENDING с ERROR_DELETE_PENDING, попытался добавить этот новый код ошибки и обнаружил, что он ломает приложения, которые ожидали ERROR_ACCESS_DENIED. Поэтому он изменил сопоставление обратно, но забыл удалить определение из winerror.h.

person John    schedule 03.08.2011

Пришлось исследовать и эту мелочь, как всегда, когда что-то в winapi можно объяснить только историческими причинами, Раймонд Чен здесь, чтобы рассказать нам об этом:

http://blogs.msdn.com/b/oldnewthing/archive/2007/11/09/6001644.aspx

Таким образом, STATUS_DELETE_PENDING на самом деле означает нечто иное, чем вы ожидаете!

person Bernd Elkemann    schedule 13.07.2011
comment
CreateFile не вернет ERROR_DELETE_PENDING, а вернет ERROR_ACCESS_DENIED. Этот факт не имеет значения для той точки, в которой Рэймонд делает запись в блоге. - person John; 04.08.2011
comment
Я только указываю, что STATUS_DELETE_PENDING отличается от того, что вы ожидаете. Вопрос был изменен после того, как я ответил на него, и это было несколько недель назад. - person Bernd Elkemann; 04.08.2011