DELETE_ON_CLOSE is too early

I am trying to create a process on another machine that removes itself when this is done. I use the DELETE_ON_CLOSE flag with CreateFile. This method is a little popular, but I am having problems because I cannot execute it while it is open (it is expected, but some solutions do). To get around this, I tried to open the file with read permissions. The DELETE_ON_CLOSE flag says that it should only delete a file when all pointers to it have disappeared. I have a pointer to this with reading, I close the write descriptor, and the file deletes, leaving my open descriptor unreadable. Any other approach to this would be appreciated.

I also considered the possibility that, since this is a remote file system, something funky happens to the handles.

I cannot change the execuatble code I submit, so the self-cleaning executable is the last thing I want to do.

Running my program to clean up the service will cause it to work for an unacceptably long time due to how long it takes to destroy the service in the remote box.

//Open remote file for reading and set the delete flag HANDLE remote_fh = CreateFile(&remote_file_location[0], GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); if(!remote_fh) { debug.DebugMessage(Error::GetErrorMessageW(GetLastError())); RevertToSelf(); return dead_return; } //File to read from HANDLE local_fh = CreateFile(&local_file_location[0], GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(!local_fh) { debug.DebugMessage(Error::GetErrorMessageW(GetLastError())); RevertToSelf(); return dead_return; } byte buf[256]; DWORD bytesRead; DWORD bytesWritten; //Copy the file while(ReadFile(local_fh, buf, 256, &bytesRead, NULL) && bytesRead > 0) { WriteFile(remote_fh, buf, bytesRead, &bytesWritten, NULL); } CloseHandle(local_fh); //Create a file retainer to hold the pointer so the file doesn't get deleted before the service starts HANDLE remote_retain_fh = CreateFile(&remote_file_location[0], GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (!remote_retain_fh) { debug.DebugMessage(Error::GetErrorMessageW(GetLastError())); RevertToSelf(); return dead_return; } CloseHandle(remote_fh); //if(!CopyFile(&local_file_location[0], &remote_file_location[0], false)) //{ // debug.DebugMessage(Error::GetErrorMessageW(GetLastError())); // RevertToSelf(); // return dead_return; //} remote_service.Create(Service::GetServiceName().c_str()); //In the words of my daughter: "OH, OH, FILE ALL GONE!" Pipe pipe(L"\\\\" + *hostname + L"\\pipe\\dbg"); CloseHandle(remote_fh); 
+4
source share
1 answer

FILE_FLAG_DELETE_ON_CLOSE requires FILE_SHARE_DELETE permission. The problem is that when the process starts, the operating system opens the file descriptor to the executable file and does not require the exchange of permissions FILE_SHARE_DELETE so that you cannot delete the executable file while the process is open.

Consider: you open an executable file descriptor without the exclusive FILE_SHARE_DELETE, but say only FILE_GENERIC_READ. Someone else (you, later, or even another thread or process) runs this executable. No problem, because no one is trying to delete the executable file. But if you tried to get FILE_SHARE_DELETE permission, you would fail because the executable is already running with exclusive permission to delete files.

0
source

Source: https://habr.com/ru/post/1496907/


All Articles