I was under the assumption that if you use CreateFileW requesting exclusive access, that if it was already opened I should receive a sharing violation. However, I've come across an example where this is not the case. If LoadLibraryEx is called to load a DLL with the LOAD_LIBRARY_AS_DATAFILE flag set, then CreateFileW returns successfully. However there are operations that will be rejected (such as setting attributes like end of file). Is there a better way to detect if these files are open? Am I using CreateFileW incorrectly? Loading a DLL without the LOAD_LIBRARY_AS_DATAFILE flag does result in CreateFileW failing indicating it can not access the file because it is in use by another process.
HMODULE hModule = LoadLibraryEx(L"\\Pathto\\module.dll", NULL, NULL);
DWORD access = GENERIC_READ | GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY;
DWORD creation = OPEN_EXISTING;
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
HANDLE file = CreateFileW(L"\\Pathto\\module.dll", access, 0, NULL, creation, flags, 0);
The above will result in CreateFileW failing with error code 32 (can't access cause it is in use by another process) which is the expected result. If I add the flag to LoadLibraryEx:
HMODULE hModule = LoadLibraryEx(name, NULL, LOAD_LIBRARY_AS_DATAFILE);
And use the exact same call to CreateFileW then I'm told it's successful, although I will run into problems later when attempting to set end of file (as an example). Additionally, deleting the file will fail with an access denied error (without the application or any other having an open handle).
Other odd behavior involves hard links with loaded libraries. If I generate a new hard link to the loaded module, and try to delete the alternate newly created hard link, it also fails (NO open file handles, just loaded module). Why? Shouldn't it just remove the link and dereference the link count, or schedule deletion on module close since I could have obtained exclusive access previously?
Also of note, the process itself runs in a privileged user account with the following additional privileges enabled: SE_SECURITY_NAME, SE_BACKUP_NAME, SE_RESTORE_NAME, SE_TAKE_OWNERSHIP_NAME
How would one determine if you truly have exclusive access to a file when libraries are loaded?
Edit: Just to doubly check, I verified no other open handles besides loading the module via the SysInternals tool "handle".
MmFlushImageSection
with eitherMmFlushForWrite
orMmFlushForDelete
. A File object opened for a hard link uses the section object pointers from the underlying SCB/FCB. – Eryk Sun