Passing a file location to an external process using Win32/MFC - c++

I'm trying to fulfill a client request here, and I'm not entirely sure I can actually do it. I have an MFC application that relies upon ShellExecute to open files in their appropriate viewer, which spawns multiple viewers if you try to open multiple files one after the other. If you open one .txt document, and then open another, two copies of notepad appear as expected.
The client wants us to change this functionality - Windows' functionality - to just pass file locations to any viewers that might already be opening. The first image clicked should open Image Viewer, but any other should just be opened in that existing process.
Is that kind of inter-application control/communication possible? Can I generically "pass" files to existing processes? I don't think I can. Executing a program with a file as a parameter is one thing, but passing a file to a running process is something else altogether. I'm not sure you can do that generically, I don't think that kind of functionality is anywhere in the Windows APIs.
I could be wrong, though.

This isn't possible if the viewer don't support multiple open files in same instance.
in your example: notepad will launch a new version with each file, while Notepad++ (a free editor) will open in same instance in a new tab.

The first thing you should try is calling the program again with the new parameters. If the program is written in such a way it will delegate the new parameter to the existing instance. Notepad doesn't do this, image viewer may though.
The next thing you can try is managing the life of the application by keeping track of the handle yourself. You call CreateProcess, so you create and own the handle to this process. On the next call to CreateProcess, enumerate the open windows and try to find your last handle. If the handle is found, close it and continue with your open process. You should only get one open application. For the most reliable solution, put this in a separate thread and wait for the handle (as well as a new request event) to avoid any race conditions.

Related

Using temporary files safely

There is a static library I use in my program which can only take filenames as its input, not actual file contents. There is nothing I can do about the library's source code. So I want to: create a brand-new file, store data to being processed into it, flush it onto the disk(?), pass its name to the library, then delete it.
But I also want this process to be rather secure:
1) the file must be created anew, without any bogus data (maybe it's not critical, but whatever);
2) anyone but my process must not be able read or write from/to this file (I want the library to process my actual data, not bogus data some wiseguy managed to plug in);
3) after I'm done with this file, it must be deleted (okay, if someone TerminateProcess() me, I guess there is nothing much can be done, but still).
The library seems to use non-Unicode fopen() to open the given file though, so I am not quite sure how to handle all this, since the program is intended to run on Windows. Any suggestions?
You have a lot of suggestions already, but another option that I don't think has been mentioned is using named pipes. It will depend on the library in question as to whether it works or not, but it might be worth a try. You can create a named pipe in your application using the CreateNamedPipe function, and pass the name of the pipe to the library to operate on (the filename you would pass would be \\.\pipe\PipeName). Whether the library accepts a filename like that or not is something you would have to try, but if it works the advantage is your file never has to actually be written to disk.
This can be achieved using the CreateFile and GetTempFileName functions (if you don't know if you can write to the current working directory, you may also want to use , GetTempPath).
Determine a directory to store your temporary file in; the current directory (".") or the result of GetTempPath would be good candidates.
Use GetTempFileName to create a temporary file name.
Finally, call CreateFile to create the temporary file.
For the last step, there are a few things to consider:
The dwFlagsAndAttributes parameter of CreateFile should probably include FILE_ATTRIBUTE_TEMPORARY.
The dwFlagsAndAttributes parameter should probably also include FILE_FLAG_DELETE_ON_CLOSE to make sure that the file gets deleted no matter what (this probably also works if your process crashes, in which case the system closes all handles for you).
The dwShareMode parameter of CreateFile should probably be FILE_SHARE_READ so that other attempts to open the file will succeed, but only for reading. This means that your library code will be able to read the file, but nobody will be able to write to it.
This article should give you some good guidelines on the issue.
The gist of the matter is this:
The POSIX mkstemp() function is the secure and preferred solution where available. Unfortunately, it is not available in Windows, so you would need to find a wrapper that properly implements this functionality using Windows API calls.
On Windows, the tmpfile_s() function is the only one that actually opens the temporary file atomically (instead of simply generating a filename), protecting you from a race condition. Unfortunately, this function does not allow you to specify which directory the file will be created in, which is a potential security issue.
Primarily, you can create file in user's temporary folder (eg. C:\Users\\AppData\Local\Temp) - it is a perfect place for such files. Secondly, when creating a file, you can specify, what kind of access sharing do you provide.
Fragment of CreateFile help page on MSDN:
dwShareMode
0 Prevents other processes from opening a file or device
if they request delete, read, or write access.
FILE_SHARE_DELETE Enables subsequent open operations on a file or device to
request delete access. Otherwise, other processes cannot open the file or device if they
request delete access. If this flag is not specified, but the file or device has been opened for delete access, the function fails. Note: Delete access allows both delete and rename operations.
FILE_SHARE_READ Enables subsequent open operations on a
file or device to request read access. Otherwise, other processes cannot open the file or device if they request read access. If this flag is not specified, but the file or device has been opened for read access, the function fails.
FILE_SHARE_WRITE Enables subsequent open operations on a file or device to request
write access.
Otherwise, other processes cannot open the file or device if they
request write access.
If this flag is not specified, but the file or device has been opened
for write access or has a file mapping with write access, the function
fails.
Whilst suggestions given are good, such as using FILE_SHARE_READ, FILE_DELETE_ON_CLOSE, etc, I don't think there is a completely safe way to do thist.
I have used Process Explorer to close files that are meant to prevent a second process starting - I did this because the first process got stuck and was "not killable and not dead, but not responding", so I had a valid reason to do this - and I didn't want to reboot the machine at that particular point due to other processes running on the system.
If someone uses a debugger of some sort [including something non-commercial, written specifically for this purpose], attaches to your running process, sets a breakpoint and stops the code, then closes the file you have open, it can write to the file you just created.
You can make it harder, but you can't stop someone with sufficient privileges/skills/capabilities from intercepting your program and manipulating the data.
Note that file/folder protection only works if you reliably know that users don't have privileged accounts on the machine - typical Windows users are either admins right away, or have another account for admin purposes - and I have access to sudo/root on nearly all of the Linux boxes I use at work - there are some fileservers that I don't [and shouldn't] have root access. But all the boxes I use myself or can borrow of testing purposes, I can get to a root environment. This is not very unusual.
A solution I can think of is to find a different library that uses a different interface [or get the sources of the library and modify it so that it]. Not that this prevents a "stop, modify and go" attack using the debugger approach described above.
Create your file in your executable's folder using CreateFile API, You can give the file name some UUID, each time its created, so that no other process can guess the file name to open it. and set its attribute to hidden. After using it, just delete the file .Is it enough?

How to make application not to run a new instance when openening a new file in Qt?

For example we have a TextEditor Application. Like notepad++. We have tabs at which file content was displaying.
The default text editor in OS is set to TextEditor Application. When we open a new file application added a tab and put content to it.
How to make an application not to run a new instance when opening a new file in Qt?
Which is the best way you think?
The problem is how can you make a single-instance application. When you open a file the operating system will open the associated application and give it the file as a command line argument. You cannot simply delegate an 'open file' command to a running application through OS mechanism, you have to implement it by yourself.
At the AppWhirr project we used QLocalServer/Client to communicate between instances: when the AppWhirr app is executed it checks whether a QLocalServer with a fix ID is already taken or not. If not this instance of the application is the first/only running instance. If the ID is already taken it means another instance of the application is already running so this second instance will only do 2 things: send the given input arguments to the other instance through Qt's local client/server communication, and when it's successfully finish the communication it will quit (the second instance).
That's one solution for the problem, requires quite a bit of coding and I would not recommend it if you don't want to use local client/server communication for anything else, but it's a viable solution.
Another solution would be that the first instance of the application creates a text file at a fixed location and writes our the instance's ID. After this the second instance can read the text file and send a message to the specified ID. And of course the first instance have to remove the text-file when it quits and probably you have to implement some fail-safe code to remove the text-file in case the first instance crashes. This solution will use less resource than the first one but requires a fail-safe cleanup code.
Or as a third option you can use third-party solutions like #Matteo Italia suggested.

Win32 C++ ReadDirectoryChangesW "creation" and "modification" of file difference detect?

Here is the problem: I monitor a directory using Win32 API ReadDirectoryChangesW function. And I need to distinguish between newly created files and modified files. But there are problems... as always :(
Cases:
I monitor directory for new/modify (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE). Problem: After file creation, new file event + modify file event is triggered. But i need only one. How can I avoid that? When file is modified I get what I want :).
I monitor directory only for new file (FILE_NOTIFY_CHANGE_FILE_NAME) - NO PROBLEM.
I monitor directory only for modify file (FILE_NOTIFY_CHANGE_SIZE). Problem: When a new file is, modify action is fired along with file creation event. How can I avoid that?
Of course, I implemented some workarounds. But, I want to know if there any elegant way of handling the problems I described.
You should be catching FILE_NOTIFY_CHANGE_LAST_WRITE, not FILE_NOTIFY_CHANGE_SIZE, for a modified file. Files may be modified without the size changing.
You should also keep a queue of changes and the time they happened and only process the queue after there have been no changes in the past 1-2 seconds. Some applications can do very strange things when creating or modifying files, and you'll most likely want to special case for popular applications if you plan on using this code in the wild.
ReadDirectoryChanges isn't one of the friendliest winapi functions. You probably can't get around receiving two events on file creation; I'm not completely sure whether you'll get an extra modify for FILE_NOTIFY_CHANGE_LAST_WRITE on creation, but I think you probably will. Using the queue approach will allow you to easily throw out the extra event if it has the same time stamp as the creation event.

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.

How do I open a new document in running application without opening a new instance of the application?

I have a situation that has been partially covered by other answers at SO, but I cannot find a complete answer. In short, we are trying to use URL's for our specific data types that when double clicked will open up our application and load those data sets into that app. We have this part working.
(for example, an URL might look like this: resource://shaders/basic_shader.hlsl)
What we would like to do is to prevent new instances of the application from opening when a new URL is double clicked. For example, let's say we have a URL that opens up a shader in our shader editor. When clicking this resource URL, it will open our shader editor. When a new shader URL is clicked, we'd like to be able to open up the shader in the currently running application and have it open up the new shader in a new tab in our editor.
We can easily detect if another instance of our application is running. The problem that we don't know how to easily solve is how to tell the currently running application to open up this new file for editing. This behavior is very much like the Apple Finder.
In unix, you could emulate this behavior by having your application open some named pipe and then new apps could check if this pipe is active and then send the document data down the pipe. Is there a more standard windows way of achieving this behavior?
We need a C/C++ solution. Thanks.
Named pipe is the best way.
First instance of your application opens the pipe and listens to it (use PIPE_ACCESS_INBOUND as dwOpenMode and the same code will also allow you to detect running instances).
All subsequent instances check that they are not alone, send command line argument to the pipe and shut down.
Create a named mutex when application launches as David Grant said, then before displaying the UI for the second URL, check for this mutex, if it is already created then just quit by passing the new URL to the first launched application (Have interface in the application to set the URL and tell to redirect programatically)
You can't avoid the program associated with the url to be executed.
The "windows" solutions would be to send a message (via DDE in the old days but maybe there is something more "modern" now) to the previously running application with the url then quit ...
You can acquire a named mutex upon startup and enforce it that way.
http://www.google.com/search?hl=en&q=named+mutex+single+instance
CreateMutex on MSDN
I got this working pretty well for my C++ MFC application by following Joseph Newcomer's tutorial here. He uses a named mutex that is checked on startup and a message sent to the already-running application with the new resource to be opened.