Add WhoUses, a program to determine which processes access a given file
[msysgit.git] / src / WhoUses / WhoUses.cpp
blob0deb5a2a7954c33e66807deb2c5cef08925efebe
1 // Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
2 // For companies(Austin,TX): If you would like to get my resume, send an email.
3 //
4 // The source is free, but if you want to use it, mention my name and e-mail
5 // address
6 //
7 ///////////////////////////////////////////////////////////////////////////////
8 //
9 // WhoUses.cpp : Defines the entry point for the console application.
12 #include <windows.h>
13 #include <tchar.h>
14 #include "SystemInfo.h"
16 LPCTSTR GetFileNamePosition( LPCTSTR lpPath )
18 LPCTSTR lpAct = lpPath + _tcslen( lpPath );
20 while ( lpAct > lpPath && *lpAct != _T('\\') && *lpAct != _T('/') )
21 lpAct--;
23 if ( lpAct > lpPath )
24 lpAct++;
26 return lpAct;
29 void WhoUsesModule( LPCTSTR lpFileName, BOOL bFullPathCheck )
31 string processName;
32 BOOL bShow = FALSE;
33 SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* p;
35 SystemProcessInformation pi;
36 SystemModuleInformation mi;
38 if ( !mi.Refresh() )
40 _tprintf( _T("SystemModulesInformation::Refresh() failed.\n") );
41 return;
44 if ( mi.m_ModuleInfos.empty() )
46 _tprintf( _T("No module information\n") );
47 return;
50 pi.Refresh();
52 _tprintf( _T("%-6s %-20s %s\n"), _T("PID"), _T("Name"), _T("Path") );
53 _tprintf( _T("------------------------------------------------------------------\n") );
55 for (list<SystemModuleInformation::MODULE_INFO>::iterator iter2 = mi.m_ModuleInfos.begin(); iter2 != mi.m_ModuleInfos.end(); iter2++) {
56 SystemModuleInformation::MODULE_INFO& m = *iter2;
58 if ( bFullPathCheck )
59 bShow = _tcsicmp( m.FullPath, lpFileName ) == 0;
60 else
61 bShow = _tcsicmp( GetFileNamePosition(m.FullPath), lpFileName ) == 0;
63 if ( bShow )
65 p = pi.m_ProcessInfos[m.ProcessId];
66 if (p) {
67 SystemInfoUtils::Unicode2string( &p->usName, processName );
69 else
70 processName = "";
72 _tprintf( _T("0x%04X %-20s %s\n"),
73 m.ProcessId,
74 processName.c_str(),
75 m.FullPath );
80 void WhoUsesFile( LPCTSTR lpFileName, BOOL bFullPathCheck )
82 BOOL bShow = FALSE;
83 string name;
84 string processName;
85 string deviceFileName;
86 string fsFilePath;
87 SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* p;
88 SystemProcessInformation pi;
89 SystemHandleInformation hi;
91 if ( bFullPathCheck )
93 if ( !SystemInfoUtils::GetDeviceFileName( lpFileName, deviceFileName ) )
95 _tprintf( _T("GetDeviceFileName() failed.\n") );
96 return;
100 hi.SetFilter( _T("File"), TRUE );
102 if ( hi.m_HandleInfos.empty() )
104 _tprintf( _T("No handle information\n") );
105 return;
108 pi.Refresh();
110 _tprintf( _T("%-6s %-20s %s\n"), _T("PID"), _T("Name"), _T("Path") );
111 _tprintf( _T("------------------------------------------------------\n") );
113 for (list<SystemHandleInformation::SYSTEM_HANDLE>::iterator iter = hi.m_HandleInfos.begin(); iter != hi.m_HandleInfos.end(); iter++) {
114 SystemHandleInformation::SYSTEM_HANDLE& h = *iter;
116 p = pi.m_ProcessInfos[h.ProcessID];
117 if (p) {
118 SystemInfoUtils::Unicode2string( &p->usName, processName );
120 else
121 processName = "";
123 //NT4 Stupid thing if it is the services.exe and I call GetName :((
124 if ( INtDll::dwNTMajorVersion == 4 && _tcsicmp( processName.c_str(), _T("services.exe" ) ) == 0 )
125 continue;
127 hi.GetName( (HANDLE)h.HandleNumber, name, (DWORD)h.ProcessID );
129 if ( bFullPathCheck )
130 bShow = _tcsicmp( name.c_str(), deviceFileName.c_str() ) == 0;
131 else
132 bShow = _tcsicmp( GetFileNamePosition(name.c_str()), lpFileName ) == 0;
134 if ( bShow )
136 if ( !bFullPathCheck )
138 fsFilePath = "";
139 SystemInfoUtils::GetFsFileName( name.c_str(), fsFilePath );
142 _tprintf( _T("0x%04X %-20s %s\n"),
143 h.ProcessID,
144 processName.c_str(),
145 !bFullPathCheck ? fsFilePath.c_str() : lpFileName );
150 void EnableDebugPriv( void )
152 HANDLE hToken;
153 LUID sedebugnameValue;
154 TOKEN_PRIVILEGES tkp;
156 // enable the SeDebugPrivilege
157 if ( ! OpenProcessToken( GetCurrentProcess(),
158 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
160 _tprintf( _T("OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available.\n") , GetLastError() );
161 return;
164 if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
166 _tprintf( _T("LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
167 CloseHandle( hToken );
168 return;
171 tkp.PrivilegeCount = 1;
172 tkp.Privileges[0].Luid = sedebugnameValue;
173 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
175 if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
176 _tprintf( _T("AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
178 CloseHandle( hToken );
181 void ShowUsage()
183 _tprintf( _T("WhoUses 1.0 for www.codeguru.com\n") );
184 _tprintf( _T("Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com \n") );
185 _tprintf( _T("\n") );
186 _tprintf( _T("Usage: WhoUses.exe [-M] fileName\n") );
187 _tprintf( _T("\n") );
188 _tprintf( _T(" -M fileName is a module name ( EXE, DLL, ... )\n") );
189 _tprintf( _T(" fileName File name\n") );
190 _tprintf( _T("\n") );
191 _tprintf( _T("Examples:\n") );
192 _tprintf( _T("\n") );
193 _tprintf( _T(" WhoUses.exe -M kernel32.dll\n") );
194 _tprintf( _T(" WhoUses.exe -M c:\\test\\test.dll\n") );
195 _tprintf( _T(" WhoUses.exe yourTextFile.txt\n") );
196 _tprintf( _T(" WhoUses.exe c:\\pagefile.sys\n") );
197 _tprintf( _T(" WhoUses.exe Serial0\n") );
200 int _tmain(int argc, TCHAR* argv[])
202 ULONG nonSwitchCount = 0;
203 BOOL bModule = FALSE;
204 LPCTSTR lpPath = NULL;
205 BOOL bFullPathCheck = FALSE;
206 BOOL bUsage = TRUE;
207 TCHAR lpFilePath[_MAX_PATH];
209 for ( int i = 1; i < argc; i++ )
211 if ( _tcsicmp( argv[i], _T("-h" ) ) == 0 || _tcsicmp( argv[i], _T("-?" ) ) == 0 )
213 bUsage = TRUE;
214 break;
216 else
217 if ( _tcsicmp( argv[i], _T("-m" ) ) == 0 || _tcsicmp( argv[i], _T("-m" ) ) == 0 )
219 bModule = TRUE;
221 else
223 if ( nonSwitchCount != 0 )
225 bUsage = TRUE;
226 break;
229 lpPath = argv[i];
231 bUsage = FALSE;
233 nonSwitchCount++;
237 if ( bUsage )
239 ShowUsage();
240 return -1;
243 EnableDebugPriv();
245 bFullPathCheck = GetFileNamePosition( lpPath ) != lpPath ;
247 if ( bFullPathCheck )
249 if ( GetFullPathName( lpPath, _MAX_PATH, lpFilePath, NULL ) == 0 )
251 _tprintf( _T("GetFullPathName() failed. Error = %d\n"), GetLastError() );
252 return -2;
255 else
256 _tcscpy( lpFilePath, GetFileNamePosition( lpPath ) );
258 if ( bModule )
259 WhoUsesModule( lpFilePath, bFullPathCheck );
260 else
261 WhoUsesFile( lpFilePath, bFullPathCheck );
263 return 0;