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?
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