Delete file on process termination - winapi

Is there a way to create/access a temporary file (e.g. GetTempFileName) and delete it right after the process has been killed/terminated? I know it is possible with the JobAPI to terminate all child processes but I was wondering if you could use such a method with a file.

Pass the FILE_FLAG_DELETE_ON_CLOSE flag to CreateFile and the file will be deleted when all of its handles are closed. The documentation says:
The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles.

Related

Non-blocking read on Windows named pipes

I need to implement non-blocking reading and writing from windows named pipes using Python (ctypes).
I am able to achieve this if the pipe is opened in server mode.
But I fail to do it when opening the pipe with client, using CreateFile.
ReadFile blocks, no matter that the pipe was created with PIPE_NOWAIT by the server process.
I'm trying to use windll.kernel32.SetNamedPipeHandleState on the handle returned by windll.kernel32.CreateFileW, but get an error ERROR_ACCESS_DENIED
The description for SetNamedPipeHandleState says that it must have GENERIC_READ and FILE_WRITE_ATTRIBUTES access for a read-only pipe.
How do I set these flags when opening a file? And will it actually help to resolve my problem?

How to rename a file without closing all of it's open file handles?

I create GENERIC_READ file handle with createFile.
This is my instruction :
hfile := CreateFileA(aFileName,
GENERIC_READ,
FILE_SHARE_READ or
FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or
FILE_FLAG_SEQUENTIAL_SCAN or
FILE_FLAG_OVERLAPPED,
0);
Now the problem is that when to process will read the file via hfile sometime another process will need to "swap" the file, and to do this will need to rename it
this is how I do it :
MoveFileA(aFileName, aNewFileName);
But I have an error when I do this when their is still some file handle open. Is their any way to rename a file without first closing all it's GENERIC_READ file handle?
Obviously the preferred choice is to ensure that every time the file is opened, the FILE_SHARE_DELETE flag is passed.
If you can't do that (e.g., some other process over which you have no control may open it) the remaining alternative is to use MoveFileEx with the MOVEFILE_DELAY_UNTIL_REBOOT flag. As you'd guess from the name, this waits until the next time the computer is restarted, and renames it then. This is particularly useful for files that are used by something like a service that opens them as soon as the service starts, and keeps them open until the system is shut down.
This does have some limitations of its own though. For one example, you can't use it to rename a file via a network share. The renaming is done fairly early in the boot process, before persistent network shares are re-connected.
Open another HANDLE to the file and then use SetFileInformationByHandle(), setting the FileInformationClass parameter to FileRenameInfo, and the lpFileInformation parameter to a pointer to a FILE_RENAME_INFO struct.
just add FILE_SHARE_DELETE to do the job

Locking of file by specific set of processes

I am facing a scenario where I have to allow access to a file for multiple instances of the same executable, but deny access to the file to all other executables.
For example, if I have a file foo.txt and an executable proc.exe then any number of prox.exe instances should be able to access and modify foo.txt but no other process should be able to access or modify this file.
You can't do this based directly on which executable a process is running. However, you can make your processes co-operate with one another, so that the only processes that can access the file are those that know how to do it.
One particularly simple approach would be to create a named file mapping object for the file using CreateFileMapping(). Only processes that know the name of the file mapping would be able to access it. However, you would then only be able to access the file via memory mapping, not via normal I/O functions.
DuplicateHandle() provides another option, but because the duplicated handle shares a single file object you need to be very careful how you use it. Overlapped I/O is probably the safest approach, as it explicitly supports multiple simultaneous operations on the same object.

Share file handle only to certain process and its childs

I am creating file and usually setting share to 0 will not allow other processes to open handle to it but how can i make so that certain process (and its child proccesses) can open it too ?
Using CreateFile() in each process, you cannot selectively choose which processes can access the file. It is an all or none type of access. What you would have to do instead is create the file and leave the handle open while you need the file, then have that source process use DuplicateHandle() to make a copy of that file handle for any specific process that needs access to the file, using any IPC mechanism you want to get the duplicate handle over to that process so it can use the file.

What to do when a file remains left open when a remote application crashes or forgets to close the file

I have not worked so much with files: I am wondering about possible issues with accessing remote files on another computer. What if the distant application crashes and doesn't close the file ?
My aim is to use this win32 function:
HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle);
Using the flag OF_SHARE_EXCLUSIVE assures me that any concurrent access will be denied
(because several machines are writing to this file from time to time).
But what if the file is left open ? (application crash for example ?)
How to put the file back to normal ?
What if the distant application crashes and doesn't close the file ?
Then the O/S should close the file when it cleans up after the "crashed" application.
This won't help with a "hung" application (an application which stays open but does nothing forever).
I don't know what the issues are with network access: for example if the network connection disappears when a client has the file open (or if the client machine switches off or reboots). I'd guess there are timeouts which might eventually close the file on the server machine, but I don't know.
It might be better to use a database engine instead of a file: because database engines are explicitly built to handle concurrent access, locking, timeouts, etc.
I came across the same problem using VMware, which sometimes doe not release file handles on the host, when files are closed on the guest.
You can close such handles using the handle utility from www.sysinternals.com
First determine the file handle id my passing a part of the filename. handle will show all open files where the given string matches a part of the file name:
D:\sysinternals\>handle myfile
deadhist.exe pid: 744 3C8: D:\myfile.txt
Then close the hanlde using the parameters -c and -p
D:\sysinternals\>handle -c 3c8 -p 744
3C8: File (---) D:\myfile.txt
Close handle 3C8 in LOCKFILE.exe (PID 744)? (y/n) y
Handle closed.
handle does not care about the application holding the file handle. You are now able to reopen, remove, rename etc. the file

Resources