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.
4 // The source is free, but if you want to use it, mention my name and e-mail
7 ///////////////////////////////////////////////////////////////////////////////
13 // Date Version Description
14 // ----------------------------------------------------------------------------
15 // 10/16/00 1.0 Initial version
16 // 11/09/00 1.1 NT4 doesn't like if we bother the System process fix :)
17 // SystemInfoUtils::GetDeviceFileName() fix (subst drives
19 // NT Major version added to INtDLL class
21 ///////////////////////////////////////////////////////////////////////////////
27 #include "SystemInfo.h"
31 using std::stringstream
;
34 #error You need Windows NT to use this source code. Define WINNT!
37 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
43 // From wide char string to string
44 void SystemInfoUtils::LPCWSTR2string( LPCWSTR strW
, string
& str
)
47 // if it is already UNICODE, no problem
52 TCHAR
* actChar
= (TCHAR
*)strW
;
54 if ( actChar
== _T('\0') )
57 ULONG len
= wcslen(strW
) + 1;
58 TCHAR
* pBuffer
= new TCHAR
[ len
];
59 TCHAR
* pNewStr
= pBuffer
;
63 *(pNewStr
++) = *actChar
;
73 // From wide char string to unicode
74 void SystemInfoUtils::Unicode2string( UNICODE_STRING
* strU
, string
& str
)
76 if ( *(DWORD
*)strU
!= 0 )
77 LPCWSTR2string( (LPCWSTR
)strU
->Buffer
, str
);
82 // From device file name to DOS filename
83 BOOL
SystemInfoUtils::GetFsFileName( LPCTSTR lpDeviceFileName
,
88 TCHAR lpDeviceName
[0x1000];
89 TCHAR lpDrive
[3] = _T("A:");
91 // Iterating through the drive letters
92 for ( TCHAR actDrive
= _T('A'); actDrive
<= _T('Z'); actDrive
++ ) {
93 lpDrive
[0] = actDrive
;
95 // Query the device for the drive letter
96 if ( QueryDosDevice( lpDrive
, lpDeviceName
, 0x1000 ) != 0 ) {
98 if ( _tcsnicmp( _T("\\Device\\LanmanRedirector\\"),
99 lpDeviceName
, 25 ) == 0 ) {
100 //Mapped network drive
105 TCHAR lpSharedName
[0x1000];
107 if ( _stscanf( lpDeviceName
,
108 _T("\\Device\\LanmanRedirector\\;%c:%d\\%s"),
111 lpSharedName
) != 3 )
114 _tcscpy( lpDeviceName
,
115 _T("\\Device\\LanmanRedirector\\") );
116 _tcscat( lpDeviceName
, lpSharedName
);
119 // Is this the drive letter we are looking for?
120 if ( _tcsnicmp( lpDeviceName
, lpDeviceFileName
,
121 _tcslen( lpDeviceName
) ) == 0 )
123 fsFileName
= lpDrive
;
124 fsFileName
+= (LPCTSTR
)( lpDeviceFileName
125 + _tcslen( lpDeviceName
) );
137 // From DOS file name to device file name
138 BOOL
SystemInfoUtils::GetDeviceFileName( LPCTSTR lpFsFileName
,
139 string
& deviceFileName
)
144 // Get the drive letter
145 // unfortunetaly it works only with DOS file names
146 _tcsncpy( lpDrive
, lpFsFileName
, 2 );
147 lpDrive
[2] = _T('\0');
149 TCHAR lpDeviceName
[0x1000];
151 // Query the device for the drive letter
152 if ( QueryDosDevice( lpDrive
, lpDeviceName
, 0x1000 ) != 0 )
155 if ( _tcsnicmp( _T("\\??\\"), lpDeviceName
, 4 ) == 0 )
157 deviceFileName
= lpDeviceName
+ 4;
158 deviceFileName
+= lpFsFileName
+ 2;
164 if ( _tcsnicmp( _T("\\Device\\LanmanRedirector\\"),
165 lpDeviceName
, 25 ) == 0 ) {
166 //Mapped network drive
171 TCHAR lpSharedName
[0x1000];
173 if ( _stscanf( lpDeviceName
,
174 _T("\\Device\\LanmanRedirector\\;%c:%d\\%s"),
177 lpSharedName
) != 3 )
180 _tcscpy( lpDeviceName
,
181 _T("\\Device\\LanmanRedirector\\") );
182 _tcscat( lpDeviceName
, lpSharedName
);
185 _tcscat( lpDeviceName
, lpFsFileName
+ 2 );
187 deviceFileName
= lpDeviceName
;
196 DWORD
SystemInfoUtils::GetNTMajorVersion()
198 OSVERSIONINFOEX osvi
;
199 BOOL bOsVersionInfoEx
;
201 // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
202 // which is supported on Windows 2000.
204 // If that fails, try using the OSVERSIONINFO structure.
206 ZeroMemory(&osvi
, sizeof(OSVERSIONINFOEX
));
207 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEX
);
209 bOsVersionInfoEx
= GetVersionEx ((OSVERSIONINFO
*) &osvi
);
211 if( bOsVersionInfoEx
== 0 )
213 // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
215 osvi
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
216 if (! GetVersionEx ( (OSVERSIONINFO
*) &osvi
) )
220 return osvi
.dwMajorVersion
;
223 ///////////////////////////////////////////////////////////////////////////////
227 ///////////////////////////////////////////////////////////////////////////////
228 INtDll::PNtQuerySystemInformation
INtDll::NtQuerySystemInformation
= NULL
;
229 INtDll::PNtQueryObject
INtDll::NtQueryObject
= NULL
;
230 INtDll::PNtQueryInformationThread
INtDll::NtQueryInformationThread
= NULL
;
231 INtDll::PNtQueryInformationFile
INtDll::NtQueryInformationFile
= NULL
;
232 INtDll::PNtQueryInformationProcess
INtDll::NtQueryInformationProcess
= NULL
;
233 DWORD
INtDll::dwNTMajorVersion
= SystemInfoUtils::GetNTMajorVersion();
235 BOOL
INtDll::NtDllStatus
= INtDll::Init();
239 // Get the NtDll function pointers
240 NtQuerySystemInformation
= (PNtQuerySystemInformation
)
241 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
242 _T("NtQuerySystemInformation") );
244 NtQueryObject
= (PNtQueryObject
)
245 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
246 _T("NtQueryObject") );
248 NtQueryInformationThread
= (PNtQueryInformationThread
)
249 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
250 _T("NtQueryInformationThread") );
252 NtQueryInformationFile
= (PNtQueryInformationFile
)
253 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
254 _T("NtQueryInformationFile") );
256 NtQueryInformationProcess
= (PNtQueryInformationProcess
)
257 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
258 _T("NtQueryInformationProcess") );
260 return NtQuerySystemInformation
!= NULL
&&
261 NtQueryObject
!= NULL
&&
262 NtQueryInformationThread
!= NULL
&&
263 NtQueryInformationFile
!= NULL
&&
264 NtQueryInformationProcess
!= NULL
;
267 ///////////////////////////////////////////////////////////////////////////////
269 // SystemProcessInformation
271 ///////////////////////////////////////////////////////////////////////////////
273 SystemProcessInformation::SystemProcessInformation( BOOL bRefresh
)
275 m_pBuffer
= (UCHAR
*)VirtualAlloc ((void*)0x100000,
284 SystemProcessInformation::~SystemProcessInformation()
286 VirtualFree( m_pBuffer
, 0, MEM_RELEASE
);
289 BOOL
SystemProcessInformation::Refresh()
291 m_ProcessInfos
.clear();
292 m_pCurrentProcessInfo
= NULL
;
294 if ( !NtDllStatus
|| m_pBuffer
== NULL
)
297 // query the process information
298 if ( INtDll::NtQuerySystemInformation( 5, m_pBuffer
, BufferSize
, NULL
)
302 DWORD currentProcessID
= GetCurrentProcessId(); //Current Process ID
304 SYSTEM_PROCESS_INFORMATION
* pSysProcess
=
305 (SYSTEM_PROCESS_INFORMATION
*)m_pBuffer
;
308 // fill the process information map
309 m_ProcessInfos
[pSysProcess
->dUniqueProcessId
] = pSysProcess
;
311 // we found this process
312 if ( pSysProcess
->dUniqueProcessId
== currentProcessID
)
313 m_pCurrentProcessInfo
= pSysProcess
;
315 // get the next process information block
316 if ( pSysProcess
->dNext
!= 0 )
317 pSysProcess
= (SYSTEM_PROCESS_INFORMATION
*)
318 ((UCHAR
*)pSysProcess
+ pSysProcess
->dNext
);
322 } while ( pSysProcess
!= NULL
);
327 ///////////////////////////////////////////////////////////////////////////////
329 // SystemThreadInformation
331 ///////////////////////////////////////////////////////////////////////////////
333 SystemThreadInformation::SystemThreadInformation( DWORD pID
, BOOL bRefresh
)
341 BOOL
SystemThreadInformation::Refresh()
343 // Get the Thread objects ( set the filter to "Thread" )
344 SystemHandleInformation
hi( m_processId
);
345 BOOL rc
= hi
.SetFilter( _T("Thread"), TRUE
);
347 m_ThreadInfos
.clear();
352 THREAD_INFORMATION ti
;
354 // Iterating through the found Thread objects
355 for (list
<SystemHandleInformation::SYSTEM_HANDLE
>::iterator iter
= hi
.m_HandleInfos
.begin(); iter
!= hi
.m_HandleInfos
.end(); iter
++) {
356 SystemHandleInformation::SYSTEM_HANDLE
& h
= *iter
;
358 ti
.ProcessId
= h
.ProcessID
;
359 ti
.ThreadHandle
= (HANDLE
)h
.HandleNumber
;
361 // This is one of the threads we are lokking for
362 if ( SystemHandleInformation::GetThreadId( ti
.ThreadHandle
,
363 ti
.ThreadId
, ti
.ProcessId
) )
364 m_ThreadInfos
.push_back( ti
);
370 ///////////////////////////////////////////////////////////////////////////////
372 // SystemHandleInformation
374 ///////////////////////////////////////////////////////////////////////////////
376 SystemHandleInformation::SystemHandleInformation( DWORD pID
, BOOL bRefresh
,
377 LPCTSTR lpTypeFilter
)
382 SetFilter( lpTypeFilter
, bRefresh
);
385 SystemHandleInformation::~SystemHandleInformation()
389 BOOL
SystemHandleInformation::SetFilter( LPCTSTR lpTypeFilter
, BOOL bRefresh
)
391 // Set the filter ( default = all objects )
392 m_strTypeFilter
= lpTypeFilter
== NULL
? _T("") : lpTypeFilter
;
394 return bRefresh
? Refresh() : TRUE
;
397 const string
& SystemHandleInformation::GetFilter()
399 return m_strTypeFilter
;
402 BOOL
SystemHandleInformation::IsSupportedHandle( SYSTEM_HANDLE
& handle
)
404 //Here you can filter the handles you don't want in the Handle list
406 // Windows 2000 supports everything :)
407 if ( dwNTMajorVersion
>= 5 )
410 //NT4 System process doesn't like if we bother his internal security :)
411 if ( handle
.ProcessID
== 2 && handle
.HandleType
== 16 )
417 BOOL
SystemHandleInformation::Refresh()
425 m_HandleInfos
.clear();
427 if ( !INtDll::NtDllStatus
)
430 // Allocate the memory for the buffer
431 SYSTEM_HANDLE_INFORMATION
* pSysHandleInformation
=
432 (SYSTEM_HANDLE_INFORMATION
*)
433 VirtualAlloc( NULL
, size
, MEM_COMMIT
, PAGE_READWRITE
);
435 if ( pSysHandleInformation
== NULL
)
438 // Query the needed buffer size for the objects ( system wide )
439 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation
,
440 size
, &needed
) != 0 )
448 // The size was not enough
449 VirtualFree( pSysHandleInformation
, 0, MEM_RELEASE
);
451 pSysHandleInformation
= (SYSTEM_HANDLE_INFORMATION
*)
452 VirtualAlloc( NULL
, size
= needed
+ 256,
453 MEM_COMMIT
, PAGE_READWRITE
);
456 if ( pSysHandleInformation
== NULL
)
459 // Query the objects ( system wide )
460 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation
,
467 // Iterating through the objects
468 for ( i
= 0; i
< pSysHandleInformation
->Count
; i
++ )
470 if ( !IsSupportedHandle( pSysHandleInformation
->Handles
[i
] ) )
473 // ProcessId filtering check
474 if ( pSysHandleInformation
->Handles
[i
].ProcessID
==
475 m_processId
|| m_processId
== (DWORD
)-1 ) {
478 if ( m_strTypeFilter
== _T("") )
483 GetTypeToken( (HANDLE
)pSysHandleInformation
484 ->Handles
[i
].HandleNumber
,
486 pSysHandleInformation
487 ->Handles
[i
].ProcessID
);
489 bAdd
= strType
== m_strTypeFilter
;
492 // That's it. We found one.
495 pSysHandleInformation
->Handles
[i
].HandleType
=
496 (WORD
)(pSysHandleInformation
497 ->Handles
[i
].HandleType
% 256);
499 m_HandleInfos
.push_back( pSysHandleInformation
508 if ( pSysHandleInformation
!= NULL
)
509 VirtualFree( pSysHandleInformation
, 0, MEM_RELEASE
);
514 HANDLE
SystemHandleInformation::OpenProcess( DWORD processId
)
516 // Open the process for handle duplication
517 return ::OpenProcess( PROCESS_DUP_HANDLE
, TRUE
, processId
);
520 HANDLE
SystemHandleInformation::DuplicateHandle( HANDLE hProcess
,
525 // Duplicate the remote handle for our process
526 ::DuplicateHandle( hProcess
, hRemote
, GetCurrentProcess(), &hDup
,
527 0, FALSE
, DUPLICATE_SAME_ACCESS
);
532 //Information functions
533 BOOL
SystemHandleInformation::GetTypeToken( HANDLE h
, string
& str
,
537 UCHAR
* lpBuffer
= NULL
;
541 HANDLE hRemoteProcess
= NULL
;
542 BOOL remote
= processId
!= GetCurrentProcessId();
549 // Open the remote process
550 hRemoteProcess
= OpenProcess( processId
);
552 if ( hRemoteProcess
== NULL
)
555 // Duplicate the handle
556 handle
= DuplicateHandle( hRemoteProcess
, h
);
561 // Query the info size
562 INtDll::NtQueryObject( handle
, 2, NULL
, 0, &size
);
564 lpBuffer
= new UCHAR
[size
];
566 // Query the info size ( type )
567 if ( INtDll::NtQueryObject( handle
, 2, lpBuffer
, size
, NULL
) == 0 )
570 SystemInfoUtils::LPCWSTR2string( (LPCWSTR
)(lpBuffer
+0x60),
578 if ( hRemoteProcess
!= NULL
)
579 CloseHandle( hRemoteProcess
);
581 if ( handle
!= NULL
)
582 CloseHandle( handle
);
585 if ( lpBuffer
!= NULL
)
591 BOOL
SystemHandleInformation::GetType( HANDLE h
, WORD
& type
, DWORD processId
)
595 type
= OB_TYPE_UNKNOWN
;
597 if ( !GetTypeToken( h
, strType
, processId
) )
600 return GetTypeFromTypeToken( strType
.c_str(), type
);
603 BOOL
SystemHandleInformation::GetTypeFromTypeToken( LPCTSTR typeToken
,
606 const WORD count
= 27;
607 string constStrTypes
[count
] = {
608 _T(""), _T(""), _T("Directory"), _T("SymbolicLink"),
609 _T("Token"), _T("Process"), _T("Thread"), _T("Unknown7"),
610 _T("Event"), _T("EventPair"), _T("Mutant"), _T("Unknown11"),
611 _T("Semaphore"), _T("Timer"), _T("Profile"),
612 _T("WindowStation"), _T("Desktop"), _T("Section"), _T("Key"),
613 _T("Port"), _T("WaitablePort"), _T("Unknown21"),
614 _T("Unknown22"), _T("Unknown23"), _T("Unknown24"),
615 _T("IoCompletion"), _T("File") };
617 type
= OB_TYPE_UNKNOWN
;
619 for ( WORD i
= 1; i
< count
; i
++ )
620 if ( constStrTypes
[i
] == typeToken
)
629 BOOL
SystemHandleInformation::GetName( HANDLE handle
, string
& str
, DWORD processId
)
633 if ( !GetType( handle
, type
, processId
) )
636 return GetNameByType( handle
, type
, str
, processId
);
639 BOOL
SystemHandleInformation::GetNameByType( HANDLE h
, WORD type
, string
& str
, DWORD processId
)
642 UCHAR
* lpBuffer
= NULL
;
646 HANDLE hRemoteProcess
= NULL
;
647 BOOL remote
= processId
!= GetCurrentProcessId();
655 hRemoteProcess
= OpenProcess( processId
);
657 if ( hRemoteProcess
== NULL
)
660 handle
= DuplicateHandle( hRemoteProcess
, h
);
666 // let's be happy, handle is in our process space, so query the infos :)
669 case OB_TYPE_PROCESS
:
670 GetProcessId( handle
, dwId
);
672 hex
<< "PID: 0x" << std::hex
<< dwId
;
680 GetThreadId( handle
, dwId
);
682 hex
<< "TID: 0x" << std::hex
<< dwId
;
689 ret
= GetFileName( handle
, str
);
692 if ( ret
&& str
== _T("") )
698 INtDll::NtQueryObject ( handle
, 1, NULL
, 0, &size
);
700 // let's try to use the default
704 lpBuffer
= new UCHAR
[size
];
706 if ( INtDll::NtQueryObject( handle
, 1, lpBuffer
, size
, NULL
) == 0 )
708 SystemInfoUtils::Unicode2string( (UNICODE_STRING
*)lpBuffer
, str
);
716 if ( hRemoteProcess
!= NULL
)
717 CloseHandle( hRemoteProcess
);
719 if ( handle
!= NULL
)
720 CloseHandle( handle
);
723 if ( lpBuffer
!= NULL
)
729 //Thread related functions
730 BOOL
SystemHandleInformation::GetThreadId( HANDLE h
, DWORD
& threadID
, DWORD processId
)
732 SystemThreadInformation::BASIC_THREAD_INFORMATION ti
;
734 HANDLE hRemoteProcess
= NULL
;
735 BOOL remote
= processId
!= GetCurrentProcessId();
743 hRemoteProcess
= OpenProcess( processId
);
745 if ( hRemoteProcess
== NULL
)
749 handle
= DuplicateHandle( hRemoteProcess
, h
);
754 // Get the thread information
755 if ( INtDll::NtQueryInformationThread( handle
, 0, &ti
, sizeof(ti
), NULL
) == 0 )
756 threadID
= ti
.ThreadId
;
760 if ( hRemoteProcess
!= NULL
)
761 CloseHandle( hRemoteProcess
);
763 if ( handle
!= NULL
)
764 CloseHandle( handle
);
770 //Process related functions
771 BOOL
SystemHandleInformation::GetProcessPath( HANDLE h
, string
& strPath
, DWORD remoteProcessId
)
773 h
; strPath
; remoteProcessId
;
776 number
<< remoteProcessId
;
777 strPath
= number
.str();
782 BOOL
SystemHandleInformation::GetProcessId( HANDLE h
, DWORD
& processId
, DWORD remoteProcessId
)
786 HANDLE hRemoteProcess
= NULL
;
787 BOOL remote
= remoteProcessId
!= GetCurrentProcessId();
788 SystemProcessInformation::PROCESS_BASIC_INFORMATION pi
;
790 ZeroMemory( &pi
, sizeof(pi
) );
799 hRemoteProcess
= OpenProcess( remoteProcessId
);
801 if ( hRemoteProcess
== NULL
)
805 handle
= DuplicateHandle( hRemoteProcess
, h
);
810 // Get the process information
811 if ( INtDll::NtQueryInformationProcess( handle
, 0, &pi
, sizeof(pi
), NULL
) == 0 )
813 processId
= pi
.UniqueProcessId
;
819 if ( hRemoteProcess
!= NULL
)
820 CloseHandle( hRemoteProcess
);
822 if ( handle
!= NULL
)
823 CloseHandle( handle
);
829 //File related functions
830 void SystemHandleInformation::GetFileNameThread( PVOID pParam
)
832 // This thread function for getting the filename
833 // if access denied, we hang up in this function,
834 // so if it times out we just kill this thread
835 GetFileNameThreadParam
* p
= (GetFileNameThreadParam
*)pParam
;
837 UCHAR lpBuffer
[0x1000];
840 p
->rc
= INtDll::NtQueryInformationFile( p
->hFile
, iob
, lpBuffer
, sizeof(lpBuffer
), 9 );
843 *p
->pName
= (const char *)lpBuffer
;
846 BOOL
SystemHandleInformation::GetFileName( HANDLE h
, string
& str
, DWORD processId
)
849 HANDLE hThread
= NULL
;
850 GetFileNameThreadParam tp
;
852 HANDLE hRemoteProcess
= NULL
;
853 BOOL remote
= processId
!= GetCurrentProcessId();
861 hRemoteProcess
= OpenProcess( processId
);
863 if ( hRemoteProcess
== NULL
)
867 handle
= DuplicateHandle( hRemoteProcess
, h
);
876 // Let's start the thread to get the file name
877 hThread
= (HANDLE
)_beginthread( GetFileNameThread
, 0, &tp
);
879 if ( hThread
== NULL
)
885 // Wait for finishing the thread
886 if ( WaitForSingleObject( hThread
, 100 ) == WAIT_TIMEOUT
)
889 // Terminate the thread
890 TerminateThread( hThread
, 0 );
897 ret
= ( tp
.rc
== 0 );
903 if ( hRemoteProcess
!= NULL
)
904 CloseHandle( hRemoteProcess
);
906 if ( handle
!= NULL
)
907 CloseHandle( handle
);
913 //////////////////////////////////////////////////////////////////////////////////////
915 // SystemModuleInformation
917 //////////////////////////////////////////////////////////////////////////////////////
919 SystemModuleInformation::SystemModuleInformation( DWORD pID
, BOOL bRefresh
)
927 void SystemModuleInformation::GetModuleListForProcess( DWORD processID
)
931 HMODULE
* hModules
= NULL
;
932 MODULE_INFO moduleInfo
;
934 // Open process to read to query the module list
935 HANDLE hProcess
= OpenProcess( PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, processID
);
937 if ( hProcess
== NULL
)
940 //Get the number of modules
941 if ( !(*m_EnumProcessModules
)( hProcess
, NULL
, 0, &cbNeeded
) )
944 hModules
= new HMODULE
[ cbNeeded
/ sizeof( HMODULE
) ];
947 if ( !(*m_EnumProcessModules
)( hProcess
, hModules
, cbNeeded
, &cbNeeded
) )
950 for ( i
= 0; i
< cbNeeded
/ sizeof( HMODULE
); i
++ )
952 moduleInfo
.ProcessId
= processID
;
953 moduleInfo
.Handle
= hModules
[i
];
955 //Get module full paths
956 if ( (*m_GetModuleFileNameEx
)( hProcess
, hModules
[i
], moduleInfo
.FullPath
, _MAX_PATH
) )
957 m_ModuleInfos
.push_back( moduleInfo
);
961 if ( hModules
!= NULL
)
964 if ( hProcess
!= NULL
)
965 CloseHandle( hProcess
);
968 BOOL
SystemModuleInformation::Refresh()
971 m_EnumProcessModules
= NULL
;
972 m_GetModuleFileNameEx
= NULL
;
974 m_ModuleInfos
.clear();
977 HINSTANCE hDll
= LoadLibrary( "PSAPI.DLL" );
985 //Get Psapi.dll functions
986 m_EnumProcessModules
= (PEnumProcessModules
)GetProcAddress( hDll
, "EnumProcessModules" );
988 m_GetModuleFileNameEx
= (PGetModuleFileNameEx
)GetProcAddress( hDll
,
990 "GetModuleFileNameExW" );
992 "GetModuleFileNameExA" );
995 if ( m_GetModuleFileNameEx
== NULL
|| m_EnumProcessModules
== NULL
)
1001 // Everey process or just a particular one
1002 if ( m_processId
!= -1 )
1003 // For a particular one
1004 GetModuleListForProcess( m_processId
);
1007 // Get teh process list
1009 SystemProcessInformation::SYSTEM_PROCESS_INFORMATION
* p
= NULL
;
1010 SystemProcessInformation
pi( TRUE
);
1012 if ( pi
.m_ProcessInfos
.empty() )
1018 // Iterating through the processes and get the module list
1019 for (map
<DWORD
, SystemProcessInformation::SYSTEM_PROCESS_INFORMATION
*>::iterator iter
= pi
.m_ProcessInfos
.begin(); iter
!= pi
.m_ProcessInfos
.end(); iter
++) {
1022 GetModuleListForProcess( pID
);
1032 FreeLibrary( hDll
);
1037 //////////////////////////////////////////////////////////////////////////////////////
1039 // SystemWindowInformation
1041 //////////////////////////////////////////////////////////////////////////////////////
1043 SystemWindowInformation::SystemWindowInformation( DWORD pID
, BOOL bRefresh
)
1051 BOOL
SystemWindowInformation::Refresh()
1053 m_WindowInfos
.clear();
1055 // Enumerating the windows
1056 EnumWindows( EnumerateWindows
, (LPARAM
)this );
1061 BOOL CALLBACK
SystemWindowInformation::EnumerateWindows( HWND hwnd
, LPARAM lParam
)
1063 SystemWindowInformation
* _this
= (SystemWindowInformation
*)lParam
;
1067 GetWindowThreadProcessId(hwnd
, &wi
.ProcessId
) ;
1069 // Filtering by process ID
1070 if ( _this
->m_processId
== -1 || _this
->m_processId
== wi
.ProcessId
)
1072 GetWindowText( hwnd
, wi
.Caption
, MaxCaptionSize
);
1074 // That is we are looking for
1075 if ( GetLastError() == 0 )
1076 _this
->m_WindowInfos
.push_back( wi
);