I want to monitor access to some files on Windows.
What I need:
procmon.exe
(which AFAIK does not support real-time logging to another process, only manually exporting the logs to a file), just a lot less infos neededresmon
's 'Disk' tabWhat I do NOT need:
java.nio.file.WatchService
because it cannot raise the read
event, nor give info about the amount of bytesorg.apache.commons.io
, because that's even less suitedSo as you might have noticed, the final thing shall run in Java, but I'm OK with wrapping an app and parsing its output from its stdio's InputStream (and ErrorInputStream). So, the central piece could also be a PowerShell script or .exe file or something alike.
I have scoured the internet and a few Microsoft articles, and there was a plethora of maybe possible solutions, but all quite complicated, like writing a driver in C and JNIing it, etc.
I do not mind using JNI or other means to access the Windows API though.
So I'm hoping there's an easier way to get this done than to write a driver...
ETW would be a good fit for this use case. The FileIo
class has subclasses including FileIo_Name
, which you can use to temporally associate file names with FileKey
s, and FileIo_ReadWrite
, which contain information on reads/writes associated with one of those FileKey
s.
If you're looking to do this in C and wrap it with JNI, Microsoft has published an example that is similar to what you'd need to do in order to consume these events. Note that instead of EVENT_TRACE_FLAG_NETWORK_TCPIP
you'd want to specify EVENT_TRACE_FLAG_DISK_FILE_IO
, as mentioned in the FileIo
docs. This example also logs to a file; to instead log into memory, see discussion on the docs for EVENT_TRACE_PROPERTIES
. An example of parsing the events using the MOF classes can be found here.
You might also take inspiration from ProcMonX, which consumes ETW events in C#. .NET's Microsoft.Diagnostics.Tracing.TraceEvent library (used by ProcMonX) and reflection certainly make this much more straightforward. If you're okay with hooking up .NET to Java (I don't know how feasible this is myself) or especially if you're okay with having a separate process, this is likely the far easier path forward when compared with using the lower-level C APIs.
ProcMonX v2 also exists, which does this in C++, largely using the Tdh
family of APIs.