8

This is an add-on to another question found here.

In short: I would like to list all of the open files on a system and retrieve their associated file names. If this is the wrong approach, or if there's another way, please give me a push in the right direction. Or, if I'm missing any details or something's unclear, please yell at me.

Like the other question (linked above), I don't care about language (a C or C++ solution wouldn't hurt though), but I'd like for this to work on Windows XP. Also, I require avoiding a kernel-mode driver.

The problem I have with the original solution to this question is that if a file handle was opened a certain way, the NtQueryObject call may hang. This is outlined on the SysInternals forums here.

According to the SysInternals forums, using CreateThread with a time-out has been the accepted solution, but doing that does not appear to allow the process to close properly every time. Even while debugging this in Visual Studio, I am sometimes forced to reboot the computer. Having to reboot my computer sometimes when I run this isn't the best option.

Another accepted solution is skipping handles with a particular GrantedAccess. The problem I have with that is that I miss too many of the handles to be useful given the GrantedAccess outlined on the above forum postings.

Is anyone able to point me towards a solution to my problem?

Thanks!

Edit: Sorry, I should have been more specific about my problem. The NtQuerySystemInformation call will get me handles, the NtQueryObject called with ObjectNameInformation will hang on handles that are synchronous pipes (at least that's what people seem to say). The example posted here uses a kernel-mode driver to read the filename from the FILE_OBJECT -- but I want to avoid using a driver. So yes, much like the SysInternals Handle utility, but I believe they use a driver as well, don't they?

Edit 2: This is sort of an academic interest, so use of the native API or other undocumented techniques that may be broken in future versions is not a concern. Also, a GrantedAccess that just avoids objects that hang would be perfect.

Edit 3: My end goal is to just be able to see what files are currently open on the system. If this is totally the wrong approach, another point in the right direction would be greatly appreciated.

Edit: This just needs to work on Windows XP as there are more elegant solutions for Vista+, so using undocumented functions really isn't a concern.

Thanks again!

Community
  • 1
  • 1
mrduclaw
  • 3,965
  • 4
  • 36
  • 37
  • Thank you very much for this. Actually even in system greater then WinXP this is a concern. *IF you have the full path to a file*, then you can use the Restart Manager. But my issue was I have the PID and now I need to know all the files that PID is locking, so I had to use this method to list the handles then get file paths. Thanks for asking this! http://stackoverflow.com/q/39910608/1828637 – Noitidart Oct 08 '16 at 00:10

1 Answers1

6

I think you can get somewhere with the forbidden NtQuerySystemInformation() API. A sample project that ab/uses this API is available here.

Lots of warning flags need to be raised with this, you're monkeying with intentionally undocumented internal kernel data structures. You most definitely do not want to do what that article proposes, closing file handles involuntarily is a great way to cause random file system corruption.

And you'll have a hard time keeping this kind of code compatible with future versions of Windows. A possibly better, but not more elegant solution is to rely on the SysInternals' Handle utility. It is likely to be maintained for a while to come. Run this program from yours, redirecting the output. Parsing the text is doable.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    I don't want to sound argumentative, since I am likely confused and appreciate the help, but I was under the impression that from the example you linked his `ListFileDrv.c` file that contains `DriverEntry` and handles IRP_MJ_DEVICE_CONTROL IRPs was his driver code for copying the filename from the `FILE_OBJECT`. Also, to quote the example you linked: "The driver accepts this address and copies the file name from FILE_OBJECT, setting it in the out parameter of the DeviceIoControl function." In the following paragraph he describes extracting the driver from an embedded resource and loading it. – mrduclaw Sep 02 '10 at 18:48
  • Oh, okay, I never actually studied this code. I'll never use it. I suspect it was reverse-engineered from Handle.exe – Hans Passant Sep 02 '10 at 18:59
  • That's fine, I just wanted to make sure we were talking about the same thing. Any other ideas would be greatly appreciated. Thanks again :D – mrduclaw Sep 02 '10 at 20:07
  • handle.exe is not an option for distributable software. See technet.microsoft.com/en-us/sysinternals/bb847944. – marknuzz Dec 09 '13 at 04:53