windowswinapifile-iofilesystemsdevice-driver

Why does Windows return ERROR_ACCESS_DENIED when I try to open a delete pended file


When we open a delete pended file, the Windows subsystem returns ERROR_ACCESS_DENIED even though they have the ERROR_DELETE_PENDING status.

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?    

For the last CreateFile function, file system driver returned STATUS_DELETE_PENDING.
But Win32 subsystem converted it to ERROR_ACCESS_DENIED. Why?

I think it should be a ERROR_DELETE_PENDING and am very curious why they designed like this.
Is there a good reason?


Solution

  • The Windows kernel and the "native" api use NTSTATUS codes. Win32 uses Win32 error codes which date back to DOS error codes. Windows has always mapped STATUS_DELETE_PENDING to ERROR_ACCESS_DENIED. I was able to verify this on NT4 which did not define ERROR_DELETE_PENDING in winerror.h.

    The definition of ERROR_DELETE_PENDING was added to winerror.h in Windows XP, but it looks like the mapping has always been this way.

    I guess that someone had the same idea as you - why not map STATUS_DELETE_PENDING to ERROR_DELETE_PENDING, tried to add this new error code and found out that it broke applications which were expecting ERROR_ACCESS_DENIED. So he changed the mapping back but forgot to remove the definition from winerror.h