Where in the process is a file open? - c++

I have an application suite that I maintain for Windows platforms. I recently added some code to a shared library to remove a directory after the app is done with it. In one app, the deletion is successful; in the other, I receive a message telling me the file is in use by another process.
After downloading Process Explorer, I learned what I had already expected, that the process holding the folder is the one trying to delete it.
When I google for an answer, all I see is, "You need to download XYZ to find out what process is holding the file, then close that process," where "XYZ" is Unlocker, Process Explorer, etc. I know the process that is holding the file, but if I terminate it, how can it delete the folder?
Does anyone have any idea about how to locate the code that is holding the folder open? Of the tools that are available for finding which processes are using which files, can any be used to find where in the process the folder is open?

There is no concept of a "location in the process" where a file is open. E.g. a very common cause of unintentional open files are leaked handles. That means the file is open precisely because there is no location for the file handle in the process anymore.

Related

Problems with directory deletion MFC

I am doing a mfc program in which i have created a directory to store dicom images using
CreateDirectory(Directory_name,NULL);
and succesfully created the folder,
After that i have used this folder of dicom images to perform volume rendering and it goes well too.
After that when i try to delete the directory including the dicom files ,everything is deleted except the last dicom file of the folder which i have given to the volume rendering process.
What is the concept going on here?
How do i delete it?
Under Windows, you can't delete a file while it's open.
If you're using Windows functions directly, and specifically, opening the files with CreateFile, you can pass FILE_FLAG_DELETE_ON_CLOSE to (obviously enough) have each file deleted as soon as it's closed.
If (far more likely) you're using almost any other way to open the files (iostreams, FILE *s, CFile, etc.) you're pretty much stuck with the fact that you'll need to close the files before you can delete them. In the case of the file being open in a child process, you'll typically need to wait for that process to finish and close the file before you try to delete the files.
Again, your options there depend somewhat on how you create the child process. If you call CreateProcess directly, you'll get a handle to the child process. That handle will be signaled when the child process exits, so you can do something like WaitForSingleObject on the handle, and when it returns success, you know the child process has exited. Most other methods of spawning the child require at least slightly more roundabout methods though (and, like with opening files, it's far more common to use other methods than to call CreateProcess directly--understandably, since using CreateProcess directly can be a bit of a pain).

Stop two instances of my application writing to the same folder simultaneously

I have an application that writes files to a folder, I want to prevent (or at least show a warning) if another instance of my application attempts to write to the same directory.
Is there a way I can temporarily block access to a folder to prevent this from happening?
EDIT:
I had an idea about creating a temp file to use as a flag, however is there a way to ensure that a temp file is deleted if my application were to crash?
Why not use a lock file?
You have to ensure, that the "check-and-create" operation is atomic. If it tells You that the lockfile already exists, then there is another process accessing the directory.
Blocking the whole directory for other processes is not what You want. You would also block shells and files browsers from accessing it.
I saw Your edit: You could write the process ID of the file into the lockfile.
If Your application detects an existing lock file, it can check if a process with that ID exists. If it doesn't, remove the lockfile and start over.

MFC C++: how can I lock a file to be used only in my process?

I'd like to lock a couple of files to be only used by my process, denying any other application access to these files while my program is running. Of course I know that I can get exclusive access to a file using Createfile, but my application works differently, I read a bunch of filenames froma config, and process these files with a Lib linked to my application, i.e. one of the functions in my lib accesses the files, but I don't get a filoehandle or something similar in return.
So what I want to acchieve is that while my app is processing these files, no other application can modify them. Is this somehow possible? I am developing using MFC in Visual Studio 8.
I've never used them, but LockFile/LockFileEx docs say: Locks the specified file for exclusive access by the calling process.
You need cooperation from the OS, because that's the only way to influence other processes.
The OS requires that you use handles to refer to files. It's really the only practical way for the OS; using pathnames would be far too complex. So, you will need to call CreateFile. At that point, just request exclusive access.
Why doens't the CreateFile()'s exclusive flag achieve this? It looks like you don't need anything fancy. If your library opens the file with CFile::shareDenyRead and CFile::shareDenyWrite, no other process can read your files as long as they are open by your library.
What you're asking can't be done.
Because exclusive access is granted per handle, not per process, if you open a file with exclusive access once, every subsequent attempt to open it will fail, even if it is from the same process. Exclusive access here means your handle is the only valid one, not that only your process can access it.
So even if you lock a file, your lib won't be able to open it, so it's useless to you. The only way is to lock a file and pass the handle to your lib, which you can't do because your lib wants a filename. Likewise you can't lock the file once it's open by the lib because it won't give you the handle. If you don't have access to the source code of the lib, you're stuck.
You possibly could try something with user permissions, having you're process run from it's own user account and changing the ownership of the files you're about to modify and then changing it back when you're done.

How to check if a file is still being written?

How can I check if a file is still being written? I need to wait for a file to be created, written and closed again by another process, so I can go on and open it again in my process.
In general, this is a difficult problem to solve. You can ask whether a file is open, under certain circumstances; however, if the other process is a script, it might well open and close the file multiple times. I would strongly recommend you use an advisory lock, or some other explicit method for the other process to communicate when it's done with the file.
That said, if that's not an option, there is another way. If you look in the /proc/<pid>/fd directories, where <pid> is the numeric process ID of some running process, you'll see a bunch of symlinks to the files that process has open. The permissions on the symlink reflect the mode the file was opened for - write permission means it was opened for write mode.
So, if you want to know if a file is open, just scan over every process's /proc entry, and every file descriptor in it, looking for a writable symlink to your file. If you know the PID of the other process, you can directly look at its proc entry, as well.
This has some major downsides, of course. First, you can only see open files for your own processes, unless you're root. It's also relatively slow, and only works on Linux. And again, if the other process opens and closes the file several times, you're stuck - you might end up seeing it during the closed period, and there's no easy way of knowing if it'll open it again.
You could let the writing process write a sentinel file (say "sentinel.ok") after it is finished writing the data file your reading process is interested in. In the reading process you can check for the existence of the sentinel before reading the data file, to ensure that the data file is completely written.
#blu3bird's idea of using a sentinel file isn't bad, but it requires modifying the program that's writing the file.
Here's another possibility that also requires modifying the writer, but it may be more robust:
Write to a temporary file, say "foo.dat.part". When writing is complete, rename "foo.dat.part" to "foo.dat". That way a reader either won't see "foo.dat" at all, or will see a complete version of it.
You can try using inotify
http://en.wikipedia.org/wiki/Inotify
If you know that the file will be opened once, written and then closed, it would be possible for your app to wait for the IN_CLOSE_WRITE event.
However if the behaviour of the other application doing the writing of the file is more like open,write,close,open,write,close....then you'll need some other mechanism of determining when the other app has truly finished with the file.

Intercept windows open file

I'm trying to make a small program that could intercept the open process of a file.
The purpose is when an user double-click on a file in a given folder, windows would inform to the software, then it process that petition and return windows the data of the file.
Maybe there would be another solution like monitoring Open messages and force Windows to wait while the program prepare the contents of the file.
One application of this concept, could be to manage desencryption of a file in a transparent way to the user.
In this context, the encrypted file would be on the disk and when the user open it ( with double-click on it or with some application such as notepad ), the background process would intercept that open event, desencrypt the file and give the contents of that file to the asking application.
It's a little bit strange concept, it could be like "Man In The Middle" network concept, but with files instead of network packets.
Thanks for reading.
The best way to do it to cover all cases of opening from any program would be via a file system filter driver. This may be too complex for your needs though.
You can use the trick that Process Explorer uses to replace itself with task manager. Basically create a key like this:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe
Where you replace 'taskmgr.exe' with the name of the process to intercept. Then add a string value called 'Debugger' that has the path to your executable. E.g:
Debugger -> "C:\windows\system32\notepad.exe"
Every a process is run that matches the image name your process will actually be called as a debugger for that process with the path to the actual process as an argument.
You could use code injection and API redirection. You'd start your target process and then inject a DLL which hooks the windows API functions that you want to intercept. You then get called when the target process thinks it's calling OpenFile() or whatever and you can do what you like before passing the call on to the real API.
Google for "IAT hooking".
Windows has an option to encrypt files on the disk (file->properties->advanced->encrypt) and this option is completely transparent to the applications.
Maybe to encrypt decrypt file portions of a disk you should consider softwares like criptainer?
There is this software as well http://www.truecrypt.org/downloads (free and open source) but I haven't tried it.
Developing a custom solution sounds very difficult.