For a file browser I'm working on, I need to generate a list of open files on a Windows system.
I've begun with code that successfully generates a list of process IDs. Is there a way to turn this into something that lists all the files that each process has open?
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
using namespace std;
void PrintProcessNameAndID(DWORD processID) {
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
// Get a handle to the process.
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
// Get the process name.
if (NULL != hProcess) {
HMODULE hMod;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hMod, sizeof (hMod),
&cbNeeded)) {
GetModuleBaseName(hProcess, hMod, szProcessName,
sizeof (szProcessName) / sizeof (TCHAR));
}
}
// Print the process name and identifier.
_tprintf(TEXT("%s (PID: %u)\n"), szProcessName, processID);
// Release the handle to the process.
CloseHandle(hProcess);
}
int startup(void) {
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof (aProcesses), &cbNeeded)) {
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof (DWORD);
// Print the name and process identifier for each process.
for (i = 0; i < cProcesses; i++) {
if (aProcesses[i] != 0) {
PrintProcessNameAndID(aProcesses[i]);
}
}
return 0;
}
int main(int argc, char** argv) {
startup();
return 0;
}
The typical way to do this is to use the "undocumented" features of NtQueryInformationProcess to enumerate over the handles. Note that this will give back file-paths relative to Devices - you'd need to use GetVolumePathName to then relate this back to drive letters.