Programmatically monitor files on Windows - c++

I'm looking for a way to monitor which processes are using (or attempting to access) a file over a duration of time. What are some good Windows APIs or tools to achieve this?

You could replace the file by a reparse point. The reparse point invokes a custom file system filter, which can redirect the access to anothe file. This is for instance how NTFS junctions work. If you let your file system filter handle reparse points in the same way, you can intercept all attempts by all processes to open the underlying file. It's a rather heavy-handed approach though, as it involves modifying the file system itself.

You can use the FileSystemWatcher.
Here's a nice tut.
http://www.geekpedia.com/tutorial173_File-monitoring-using-FileSystemWatcher.html

FileSystemWatcher is not suitable for determining the process.
There already was a different question. look here, this solution fits your needs.

Related

How to track the number of times my console application in C++14 has been launched?

I'm building a barebones Notepad-styled project (console-based, does not have a GUI as of now) and I'd like to track, display (and later use it in some ways) the number of times the console application has been launched. I don't know if this helps, but I'm building my console application on Windows 10, but I'd like it to run on Windows 7+ as well as on Linux distros such as Ubuntu and the like.
I prefer not storing the details in a file and then subsequently reading from it to maintain count. Please suggest a way or any other resource that details how to do this.
I'd put a strikethrough on my quote above, but SO doesn't have it apparently.
Note that this is my first time building such a project so I may not be familiar with advanced stuff... So, when you're answering please try to explain as is required for a not-so-experienced software developer.
Thanks & Have a great one!
Edit: It seems that the general advice is to use text files to protect portability and to account for the fact that if down-the-line, I need to store some extra info, the text file will come in super handy. In light of this, I'll focus my efforts on the text file.
Thanks to all for keeping my efforts from de-railing!
I prefer not storing the details in a file
In the comments, you wrote that the reason is security and you consider using a file as "over-kill" in this case.
Security can be solved easily - just encrypt the file. You can use a library like this to get it done.
In addition, since you are writing and reading to/from the file only once each time the application is opened/closed, and the file should take only small number of bytes to store such data, I think it's the right, portable solution.
If you still don't want to use a file, you can use windows registry to store the data, but this solution is not portable

Is there a faster alternative to enumerating folders than FindFirstFile/FindNextFile with C++?

I need to get all paths to subfolders within a folder (with WinAPIs and C++.) So far the only solution that I found is recursively calling FindFirstFile / FindNextFile but it takes a significant amount of time to do this on a folder with a deeper hierarchy.
So I was wondering, just to get folder names, is there a faster approach?
If you really just need subfolders you should be able to use FindFirstFileEx with
search options to filter out non-directories.
The docs suggest this is an advisory flag only, but your filesystem may support this optimization - give it a try.
FindExSearchLimitToDirectories
This is an advisory flag. If the file
system supports directory filtering, the function searches for a file
that matches the specified name and is also a directory. If the file
system does not support directory filtering, this flag is silently
ignored.
A faster approach would be to bypass the FindFirstFile...() API and go straight to the file system directly. You can use DeviceIoControl() with the FSCTL_ENUM_USN_DATA control to access the master file table, at least on NTFS formatted volumes. With that information, you can directly access the records for files/folders, which includes their attributes, parent info, etc. Yes, it would be more work, but it should also be faster since you can optimize the code to access just the pieces you need.
That is the fastest approach you can come across. Also you may consider using another thread to manage directory enumerations as it takes a lot of time. even Microsoft file explorer spend some time if the directory has a lot of sub folders/files.
One more thing here is that you can enumerate directories once and then register for any updates. so the cost of enumerating the folder should be made only once during start up.

Extended file attributes on windows (ntfs)

I'm currently working on a cross platform application that uses extended file attributes for storing it's own file ownership information (uid, gid) outside of the normal filesystem ownership. This information is application specific and has nothing to do with the normal filesystem ownership.
I just changed from using a small database stored in each folder for storing this information for performance reasons, but this leaves my solution lacking on the Windows platform.
According to wikipedia, NTFS may have some limited functionality as far as being able to store extended file attributes, but I certainly can't find any further information on how to get and set these attributes.
Has anyone done this before and can tell me how to do it? Or is it just plain not possible?
I'd ideally like to not have to revert to the database solution on Windows.
Maybe NTFS streams are what you are searching for?
Read more here: http://support.microsoft.com/kb/105763 , http://msdn.microsoft.com/en-us/library/ff469210.aspx

How to create extended (custom) file property in Windows?

We have a proprietary file format which has embedded in it a product-code.
I am just starting down the path of "enabling the end-user to sort / filter by product-code when opening a file".
The simplest approach for us might be to simply have another drop-down in our customized Open File Dialog in which to choose a product-code to filter by.
However, I think it might be more useful to the end-user if we could present this information as a column in the details view for this file type - just as name, date-modified, type, size, etc., are also detail properties of a file-type (or perhaps generic to all files).
My vague understanding is that XP and prior Windows OSes embedded some sort of meta data like this in an alternate data stream in NTFS. However, Starting in Vista Microsoft stopped using alternate data streams due to their dependence upon NTFS, and hence fragility (i.e. can't send via file attachment, can't move to a FAT formatted thumb drive, etc.)
Things I need to know but haven't figured out yet:
Is it possible / Is it practicable / how to create a custom extended file property for our file type that expresses the product-code to the Windows shell so that it can be seen in Windows Explorer (and hence File dialogs)?
If that is doable, then how to configure things so that the product-code column is displayed by default for folders containing our file type.
Can anyone point me to a good starting point on the above? We certainly don't have to accomplish this by publishing a custom extended file property - but that seems like a sensible approach, in absence of any way to measure the costs of going this route.
If you have sensible alternative approaches to the problem, I'd be interested in those as well!
Just found: http://www.codeproject.com/Articles/830/The-Complete-Idiot-s-Guide-to-Writing-Shell-Extens
CRAP! It seems I'm very late to the banquet, and MS has already removed this functionality from their shell: http://xpwasmyidea.blogspot.com/2009/10/evil-conspiracy-behind-customizable.html
By far the easiest approach to developing a shell extension is to use a library made for the purpose.
I can recommend EZShellExtension because I have used it in the past to add columns and thumbnails/preview for a custom file format for our company.

Opening a File with different text editors

Apparently this supposed to be possible. For example opening and operating on a file with NOTEPAD, or HxD. But aren't they all text files...how would one specify which text editor to open the file and operate on the file with using the WINDOWS API. It is certainly not in "CreateFile".
Hopefully I'm understanding your question... The easiest way to do this is to launch the desired editor and pass the filename as an argument, rather than "invoking" the file (which will launch the default program associated with the file type).
For example, notepad.exe mytextfile.txt or gvim.exe mytextfile.txt.
If the editor is not on your %PATH%, you'll need to use a full path file name.
What are you trying to do, exactly? You could:
Maintain a list of editors that you expect to be installed and have entries for in the system's PATH (bad idea)
Have an editor/editors that you want to use, query the Windows registry to find the installation path of the editors (using RegGetValue), and launch the editor with CreateProcess) (a little better idea)
Query the registry to get the default editor for a given file type and then launch that editor using CreateProcess. (best idea)
But it all depends on what your goal is really.
Edit based on requirements
So, just so we're on the same page, from C++, you want to:
Take a command line parameter to your C++ application (filename)
Open that file in an arbitrary editor
Detect when the user has made changes to that file
Operate on the file contents
Is that correct?
If so, you could:
Use Boost libs to compute a CRC for the current data in the file
Launch an editor using one of the methods I initially described
Stick in a tight loop and sleep so you don't chew up resources while the initially computed CRC matches one calculated every iteration of the loop
Of course, there are all kinds of issues that you'd have to deal with (that's just a super simple way of describing the algorithm I might use), such as:
What happens if the user doesn't change the file?
What happens if the file isn't found?
I'm sure that there are a number of different methods of doing this, but this is the easiest method that I can think of at the moment (while still being able to be fairly certain of the changes).
Disclaimer: I haven't implemented something like this, so I might be completely off base ;)
Are you looking for the ShellExecute() or ShellExecuteEx() APIs on Windows? They'll launch whatever program is registered for a file (generally based on the filename extention).