2

Many of our exe's dynamically load B.dll. B.dll makes a copy of itself in a temp file and reloads %TMP%\B-.dll. I'm trying to use this code to mark B-.dll for delete, but it fails with "access is denied", no doubt because of the LoadLibrary call:

        char ourDllPath[MAX_PATH];
        // ... set ourDllPath to absolute path...

        char tempPath[MAX_PATH];  
        DWORD dwRetVal = GetTempPath(MAX_PATH, tempPath); 
        char shadowPath[MAX_PATH];
        UINT uRetVal = GetTempFileNameA(tempPath, "FOO_", 0, shadowPath);
        BOOL ok = CopyFileA(ourDllPath, shadowPath, false);
        HMODULE hShadowDll = LoadLibraryA(shadowPath);
        typedef int (WINAPI *PRESUMEFOO)();
        PRESUMEFOO onload2 = (PRESUMEFOO)GetProcAddress(hShadowDll,"_Resume_Foo@0");

        BOOL ok2 = DeleteFileA(shadowPath); // Fails with "Access is denied"

However, according to here (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v=vs.85).aspx) this should be possible:

"The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed."

Any ideas on how I can mark a currently open file to be deleted-on-close on a Windows server OS?

Dave C
  • 1,572
  • 4
  • 23
  • 34
  • In order to set the disposition flag you have to be able to open the handle with DELETE access, and the sharing rules still apply. I'm not sure, however, whether the problem is that LoadLibrary doesn't specify FILE_SHARE_DELETE or that DeleteFile doesn't specify FILE_SHARE_READ (or both). If LoadLibrary does specify FILE_SHARE_DELETE, then you could open the file yourself with FILE_SHARE_READ and use SetFileInformationByHandle with FileDispositionInfo to set the deletion flag. Worth a try. – Harry Johnston Jul 22 '14 at 04:05
  • Interesting. But I think LoadLibrary prevents all this. I tried to call SetFileInformationByHandle on the handle returned by LoadLibrary, but that got Access Denied. Then I tried to get my own handle to the file with CreateFile (setting FILE_SHARE_DELETE and FILE_FLAG_DELETE_ON_CLOSE). If I did that first, then LoadLibrary failed. If I did that after calling LoadLibrary, it got Access Denied. – Dave C Jul 22 '14 at 18:07
  • I tried several other permutations - including one that successfully deleted the file after the LoadLibrary call -- but then the process fell over dead, presumably because the file got deleted before it could all get read/paged in. – Dave C Jul 22 '14 at 18:08
  • Yes, I've done a bit of testing too and it doesn't seem to be possible to do it this way. I'm afraid you're going to have to track the files and delete each one after unloading the associated library. Alternatively, MoveFileEx can be used to schedule the files for deletion on the next reboot. (Or you could hook NtCreateFile and add FILE_FLAG_DELETE_ON_CLOSE when LoadLibrary opens the DLL, but API hooking is both tricky and unsupported.) – Harry Johnston Jul 22 '14 at 21:14
  • MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT) would be a cool choice, except it requires privs, and our process doesn't have privs. Oh well. Unfortunately, the dll is used until the process exits, so I have no place to unload it. Thanks for your suggestions. I'll have to think of another approach. – Dave C Jul 23 '14 at 13:28
  • In that case you could create a guard DLL and use its DllMain function to delete the files on process exit. Just make sure the guard DLL is loaded first (preferably using load-time linking) so that it gets unloaded last. – Harry Johnston Jul 23 '14 at 22:02
  • That's a clever idea, but in my case, a guard DLL would have the same issue - namely I'd need it to be shadow-copied, too. The main issue I'm trying to solve is my DLL is a plugin to a third party app. After it's loaded, I want it to shadow copy itself and unload itself so that my original DLL is not locked in the file system during the run of the third party process, which can be quite long. We've solved all the issues except for the delete of the shadow copy on exit. – Dave C Jul 24 '14 at 13:00

0 Answers0