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 ///////////////////////////////////////////////////////////////////////////////
26 #include "SystemInfo.h"
30 using std::stringstream
;
33 #error You need Windows NT to use this source code. Define WINNT!
36 ///////////////////////////////////////////////////////////////////////////////
40 ///////////////////////////////////////////////////////////////////////////////
42 // From wide char string to string
43 void SystemInfoUtils::LPCWSTR2string( LPCWSTR strW
, string
& str
)
46 // if it is already UNICODE, no problem
51 TCHAR
* actChar
= (TCHAR
*)strW
;
53 if ( actChar
== _T('\0') )
56 ULONG len
= wcslen(strW
) + 1;
57 TCHAR
* pBuffer
= new TCHAR
[ len
];
58 TCHAR
* pNewStr
= pBuffer
;
62 *(pNewStr
++) = *actChar
;
72 // From wide char string to unicode
73 void SystemInfoUtils::Unicode2string( UNICODE_STRING
* strU
, string
& str
)
75 if ( *(DWORD
*)strU
!= 0 )
76 LPCWSTR2string( (LPCWSTR
)strU
->Buffer
, str
);
81 // From device file name to DOS filename
82 BOOL
SystemInfoUtils::GetFsFileName( LPCTSTR lpDeviceFileName
,
87 TCHAR lpDeviceName
[0x1000];
88 TCHAR lpDrive
[3] = _T("A:");
90 // Iterating through the drive letters
91 for ( TCHAR actDrive
= _T('A'); actDrive
<= _T('Z'); actDrive
++ ) {
92 lpDrive
[0] = actDrive
;
94 // Query the device for the drive letter
95 if ( QueryDosDevice( lpDrive
, lpDeviceName
, 0x1000 ) != 0 ) {
97 if ( _tcsnicmp( _T("\\Device\\LanmanRedirector\\"),
98 lpDeviceName
, 25 ) == 0 ) {
99 //Mapped network drive
104 TCHAR lpSharedName
[0x1000];
106 if ( _stscanf( lpDeviceName
,
107 _T("\\Device\\LanmanRedirector\\;%c:%d\\%s"),
110 lpSharedName
) != 3 )
113 _tcscpy( lpDeviceName
,
114 _T("\\Device\\LanmanRedirector\\") );
115 _tcscat( lpDeviceName
, lpSharedName
);
118 // Is this the drive letter we are looking for?
119 if ( _tcsnicmp( lpDeviceName
, lpDeviceFileName
,
120 _tcslen( lpDeviceName
) ) == 0 )
122 fsFileName
= lpDrive
;
123 fsFileName
+= (LPCTSTR
)( lpDeviceFileName
124 + _tcslen( lpDeviceName
) );
136 // From DOS file name to device file name
137 BOOL
SystemInfoUtils::GetDeviceFileName( LPCTSTR lpFsFileName
,
138 string
& deviceFileName
)
143 // Get the drive letter
144 // unfortunetaly it works only with DOS file names
145 _tcsncpy( lpDrive
, lpFsFileName
, 2 );
146 lpDrive
[2] = _T('\0');
148 TCHAR lpDeviceName
[0x1000];
150 // Query the device for the drive letter
151 if ( QueryDosDevice( lpDrive
, lpDeviceName
, 0x1000 ) != 0 )
154 if ( _tcsnicmp( _T("\\??\\"), lpDeviceName
, 4 ) == 0 )
156 deviceFileName
= lpDeviceName
+ 4;
157 deviceFileName
+= lpFsFileName
+ 2;
163 if ( _tcsnicmp( _T("\\Device\\LanmanRedirector\\"),
164 lpDeviceName
, 25 ) == 0 ) {
165 //Mapped network drive
170 TCHAR lpSharedName
[0x1000];
172 if ( _stscanf( lpDeviceName
,
173 _T("\\Device\\LanmanRedirector\\;%c:%d\\%s"),
176 lpSharedName
) != 3 )
179 _tcscpy( lpDeviceName
,
180 _T("\\Device\\LanmanRedirector\\") );
181 _tcscat( lpDeviceName
, lpSharedName
);
184 _tcscat( lpDeviceName
, lpFsFileName
+ 2 );
186 deviceFileName
= lpDeviceName
;
195 DWORD
SystemInfoUtils::GetNTMajorVersion()
197 OSVERSIONINFOEX osvi
;
198 BOOL bOsVersionInfoEx
;
200 // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
201 // which is supported on Windows 2000.
203 // If that fails, try using the OSVERSIONINFO structure.
205 ZeroMemory(&osvi
, sizeof(OSVERSIONINFOEX
));
206 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEX
);
208 bOsVersionInfoEx
= GetVersionEx ((OSVERSIONINFO
*) &osvi
);
210 if( bOsVersionInfoEx
== 0 )
212 // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
214 osvi
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
215 if (! GetVersionEx ( (OSVERSIONINFO
*) &osvi
) )
219 return osvi
.dwMajorVersion
;
222 ///////////////////////////////////////////////////////////////////////////////
226 ///////////////////////////////////////////////////////////////////////////////
227 INtDll::PNtQuerySystemInformation
INtDll::NtQuerySystemInformation
= NULL
;
228 INtDll::PNtQueryObject
INtDll::NtQueryObject
= NULL
;
229 INtDll::PNtQueryInformationThread
INtDll::NtQueryInformationThread
= NULL
;
230 INtDll::PNtQueryInformationFile
INtDll::NtQueryInformationFile
= NULL
;
231 INtDll::PNtQueryInformationProcess
INtDll::NtQueryInformationProcess
= NULL
;
232 DWORD
INtDll::dwNTMajorVersion
= SystemInfoUtils::GetNTMajorVersion();
234 BOOL
INtDll::NtDllStatus
= INtDll::Init();
238 // Get the NtDll function pointers
239 NtQuerySystemInformation
= (PNtQuerySystemInformation
)
240 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
241 _T("NtQuerySystemInformation") );
243 NtQueryObject
= (PNtQueryObject
)
244 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
245 _T("NtQueryObject") );
247 NtQueryInformationThread
= (PNtQueryInformationThread
)
248 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
249 _T("NtQueryInformationThread") );
251 NtQueryInformationFile
= (PNtQueryInformationFile
)
252 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
253 _T("NtQueryInformationFile") );
255 NtQueryInformationProcess
= (PNtQueryInformationProcess
)
256 GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
257 _T("NtQueryInformationProcess") );
259 return NtQuerySystemInformation
!= NULL
&&
260 NtQueryObject
!= NULL
&&
261 NtQueryInformationThread
!= NULL
&&
262 NtQueryInformationFile
!= NULL
&&
263 NtQueryInformationProcess
!= NULL
;
266 ///////////////////////////////////////////////////////////////////////////////
268 // SystemProcessInformation
270 ///////////////////////////////////////////////////////////////////////////////
272 SystemProcessInformation::SystemProcessInformation( BOOL bRefresh
)
274 m_pBuffer
= (UCHAR
*)VirtualAlloc ((void*)0x100000,
283 SystemProcessInformation::~SystemProcessInformation()
285 VirtualFree( m_pBuffer
, 0, MEM_RELEASE
);
288 BOOL
SystemProcessInformation::Refresh()
290 m_ProcessInfos
.clear();
291 m_pCurrentProcessInfo
= NULL
;
293 if ( !NtDllStatus
|| m_pBuffer
== NULL
)
296 // query the process information
297 if ( INtDll::NtQuerySystemInformation( 5, m_pBuffer
, BufferSize
, NULL
)
301 DWORD currentProcessID
= GetCurrentProcessId(); //Current Process ID
303 SYSTEM_PROCESS_INFORMATION
* pSysProcess
=
304 (SYSTEM_PROCESS_INFORMATION
*)m_pBuffer
;
307 // fill the process information map
308 m_ProcessInfos
[pSysProcess
->dUniqueProcessId
] = pSysProcess
;
310 // we found this process
311 if ( pSysProcess
->dUniqueProcessId
== currentProcessID
)
312 m_pCurrentProcessInfo
= pSysProcess
;
314 // get the next process information block
315 if ( pSysProcess
->dNext
!= 0 )
316 pSysProcess
= (SYSTEM_PROCESS_INFORMATION
*)
317 ((UCHAR
*)pSysProcess
+ pSysProcess
->dNext
);
321 } while ( pSysProcess
!= NULL
);
326 ///////////////////////////////////////////////////////////////////////////////
328 // SystemThreadInformation
330 ///////////////////////////////////////////////////////////////////////////////
332 SystemThreadInformation::SystemThreadInformation( DWORD pID
, BOOL bRefresh
)
340 BOOL
SystemThreadInformation::Refresh()
342 // Get the Thread objects ( set the filter to "Thread" )
343 SystemHandleInformation
hi( m_processId
);
344 BOOL rc
= hi
.SetFilter( _T("Thread"), TRUE
);
346 m_ThreadInfos
.clear();
351 THREAD_INFORMATION ti
;
353 // Iterating through the found Thread objects
354 for (list
<SystemHandleInformation::SYSTEM_HANDLE
>::iterator iter
= hi
.m_HandleInfos
.begin(); iter
!= hi
.m_HandleInfos
.end(); iter
++) {
355 SystemHandleInformation::SYSTEM_HANDLE
& h
= *iter
;
357 ti
.ProcessId
= h
.ProcessID
;
358 ti
.ThreadHandle
= (HANDLE
)h
.HandleNumber
;
360 // This is one of the threads we are lokking for
361 if ( SystemHandleInformation::GetThreadId( ti
.ThreadHandle
,
362 ti
.ThreadId
, ti
.ProcessId
) )
363 m_ThreadInfos
.push_back( ti
);
369 ///////////////////////////////////////////////////////////////////////////////
371 // SystemHandleInformation
373 ///////////////////////////////////////////////////////////////////////////////
375 SystemHandleInformation::SystemHandleInformation( DWORD pID
, BOOL bRefresh
,
376 LPCTSTR lpTypeFilter
)
381 SetFilter( lpTypeFilter
, bRefresh
);
384 SystemHandleInformation::~SystemHandleInformation()
388 BOOL
SystemHandleInformation::SetFilter( LPCTSTR lpTypeFilter
, BOOL bRefresh
)
390 // Set the filter ( default = all objects )
391 m_strTypeFilter
= lpTypeFilter
== NULL
? _T("") : lpTypeFilter
;
393 return bRefresh
? Refresh() : TRUE
;
396 const string
& SystemHandleInformation::GetFilter()
398 return m_strTypeFilter
;
401 BOOL
SystemHandleInformation::IsSupportedHandle( SYSTEM_HANDLE
& handle
)
403 //Here you can filter the handles you don't want in the Handle list
405 // Windows 2000 supports everything :)
406 if ( dwNTMajorVersion
>= 5 )
409 //NT4 System process doesn't like if we bother his internal security :)
410 if ( handle
.ProcessID
== 2 && handle
.HandleType
== 16 )
416 BOOL
SystemHandleInformation::Refresh()
424 m_HandleInfos
.clear();
426 if ( !INtDll::NtDllStatus
)
429 // Allocate the memory for the buffer
430 SYSTEM_HANDLE_INFORMATION
* pSysHandleInformation
=
431 (SYSTEM_HANDLE_INFORMATION
*)
432 VirtualAlloc( NULL
, size
, MEM_COMMIT
, PAGE_READWRITE
);
434 if ( pSysHandleInformation
== NULL
)
437 // Query the needed buffer size for the objects ( system wide )
438 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation
,
439 size
, &needed
) != 0 )
447 // The size was not enough
448 VirtualFree( pSysHandleInformation
, 0, MEM_RELEASE
);
450 pSysHandleInformation
= (SYSTEM_HANDLE_INFORMATION
*)
451 VirtualAlloc( NULL
, size
= needed
+ 256,
452 MEM_COMMIT
, PAGE_READWRITE
);
455 if ( pSysHandleInformation
== NULL
)
458 // Query the objects ( system wide )
459 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation
,
466 // Iterating through the objects
467 for ( i
= 0; i
< pSysHandleInformation
->Count
; i
++ )
469 if ( !IsSupportedHandle( pSysHandleInformation
->Handles
[i
] ) )
472 // ProcessId filtering check
473 if ( pSysHandleInformation
->Handles
[i
].ProcessID
==
474 m_processId
|| m_processId
== (DWORD
)-1 ) {
477 if ( m_strTypeFilter
== _T("") )
482 GetTypeToken( (HANDLE
)pSysHandleInformation
483 ->Handles
[i
].HandleNumber
,
485 pSysHandleInformation
486 ->Handles
[i
].ProcessID
);
488 bAdd
= strType
== m_strTypeFilter
;
491 // That's it. We found one.
494 pSysHandleInformation
->Handles
[i
].HandleType
=
495 (WORD
)(pSysHandleInformation
496 ->Handles
[i
].HandleType
% 256);
498 m_HandleInfos
.push_back( pSysHandleInformation
507 if ( pSysHandleInformation
!= NULL
)
508 VirtualFree( pSysHandleInformation
, 0, MEM_RELEASE
);
513 HANDLE
SystemHandleInformation::OpenProcess( DWORD processId
)
515 // Open the process for handle duplication
516 return ::OpenProcess( PROCESS_DUP_HANDLE
, TRUE
, processId
);
519 HANDLE
SystemHandleInformation::DuplicateHandle( HANDLE hProcess
,
524 // Duplicate the remote handle for our process
525 ::DuplicateHandle( hProcess
, hRemote
, GetCurrentProcess(), &hDup
,
526 0, FALSE
, DUPLICATE_SAME_ACCESS
);
531 //Information functions
532 BOOL
SystemHandleInformation::GetTypeToken( HANDLE h
, string
& str
,
536 UCHAR
* lpBuffer
= NULL
;
540 HANDLE hRemoteProcess
= NULL
;
541 BOOL remote
= processId
!= GetCurrentProcessId();
548 // Open the remote process
549 hRemoteProcess
= OpenProcess( processId
);
551 if ( hRemoteProcess
== NULL
)
554 // Duplicate the handle
555 handle
= DuplicateHandle( hRemoteProcess
, h
);
560 // Query the info size
561 INtDll::NtQueryObject( handle
, 2, NULL
, 0, &size
);
563 lpBuffer
= new UCHAR
[size
];
565 // Query the info size ( type )
566 if ( INtDll::NtQueryObject( handle
, 2, lpBuffer
, size
, NULL
) == 0 )
569 SystemInfoUtils::LPCWSTR2string( (LPCWSTR
)(lpBuffer
+0x60),
577 if ( hRemoteProcess
!= NULL
)
578 CloseHandle( hRemoteProcess
);
580 if ( handle
!= NULL
)
581 CloseHandle( handle
);
584 if ( lpBuffer
!= NULL
)
590 BOOL
SystemHandleInformation::GetType( HANDLE h
, WORD
& type
, DWORD processId
)
594 type
= OB_TYPE_UNKNOWN
;
596 if ( !GetTypeToken( h
, strType
, processId
) )
599 return GetTypeFromTypeToken( strType
.c_str(), type
);
602 BOOL
SystemHandleInformation::GetTypeFromTypeToken( LPCTSTR typeToken
,
605 const WORD count
= 27;
606 string constStrTypes
[count
] = {
607 _T(""), _T(""), _T("Directory"), _T("SymbolicLink"),
608 _T("Token"), _T("Process"), _T("Thread"), _T("Unknown7"),
609 _T("Event"), _T("EventPair"), _T("Mutant"), _T("Unknown11"),
610 _T("Semaphore"), _T("Timer"), _T("Profile"),
611 _T("WindowStation"), _T("Desktop"), _T("Section"), _T("Key"),
612 _T("Port"), _T("WaitablePort"), _T("Unknown21"),
613 _T("Unknown22"), _T("Unknown23"), _T("Unknown24"),
614 _T("IoCompletion"), _T("File") };
616 type
= OB_TYPE_UNKNOWN
;
618 for ( WORD i
= 1; i
< count
; i
++ )
619 if ( constStrTypes
[i
] == typeToken
)
628 BOOL
SystemHandleInformation::GetName( HANDLE handle
, string
& str
, DWORD processId
)
632 if ( !GetType( handle
, type
, processId
) )
635 return GetNameByType( handle
, type
, str
, processId
);
638 BOOL
SystemHandleInformation::GetNameByType( HANDLE h
, WORD type
, string
& str
, DWORD processId
)
641 UCHAR
* lpBuffer
= NULL
;
645 HANDLE hRemoteProcess
= NULL
;
646 BOOL remote
= processId
!= GetCurrentProcessId();
654 hRemoteProcess
= OpenProcess( processId
);
656 if ( hRemoteProcess
== NULL
)
659 handle
= DuplicateHandle( hRemoteProcess
, h
);
665 // let's be happy, handle is in our process space, so query the infos :)
668 case OB_TYPE_PROCESS
:
669 GetProcessId( handle
, dwId
);
671 hex
<< "PID: 0x" << std::hex
<< dwId
;
679 GetThreadId( handle
, dwId
);
681 hex
<< "TID: 0x" << std::hex
<< dwId
;
688 ret
= GetFileName( handle
, str
);
691 if ( ret
&& str
== _T("") )
697 INtDll::NtQueryObject ( handle
, 1, NULL
, 0, &size
);
699 // let's try to use the default
703 lpBuffer
= new UCHAR
[size
];
705 if ( INtDll::NtQueryObject( handle
, 1, lpBuffer
, size
, NULL
) == 0 )
707 SystemInfoUtils::Unicode2string( (UNICODE_STRING
*)lpBuffer
, str
);
715 if ( hRemoteProcess
!= NULL
)
716 CloseHandle( hRemoteProcess
);
718 if ( handle
!= NULL
)
719 CloseHandle( handle
);
722 if ( lpBuffer
!= NULL
)
728 //Thread related functions
729 BOOL
SystemHandleInformation::GetThreadId( HANDLE h
, DWORD
& threadID
, DWORD processId
)
731 SystemThreadInformation::BASIC_THREAD_INFORMATION ti
;
733 HANDLE hRemoteProcess
= NULL
;
734 BOOL remote
= processId
!= GetCurrentProcessId();
742 hRemoteProcess
= OpenProcess( processId
);
744 if ( hRemoteProcess
== NULL
)
748 handle
= DuplicateHandle( hRemoteProcess
, h
);
753 // Get the thread information
754 if ( INtDll::NtQueryInformationThread( handle
, 0, &ti
, sizeof(ti
), NULL
) == 0 )
755 threadID
= ti
.ThreadId
;
759 if ( hRemoteProcess
!= NULL
)
760 CloseHandle( hRemoteProcess
);
762 if ( handle
!= NULL
)
763 CloseHandle( handle
);
769 //Process related functions
770 BOOL
SystemHandleInformation::GetProcessPath( HANDLE h
, string
& strPath
, DWORD remoteProcessId
)
772 h
; strPath
; remoteProcessId
;
775 number
<< remoteProcessId
;
776 strPath
= number
.str();
781 BOOL
SystemHandleInformation::GetProcessId( HANDLE h
, DWORD
& processId
, DWORD remoteProcessId
)
785 HANDLE hRemoteProcess
= NULL
;
786 BOOL remote
= remoteProcessId
!= GetCurrentProcessId();
787 SystemProcessInformation::PROCESS_BASIC_INFORMATION pi
;
789 ZeroMemory( &pi
, sizeof(pi
) );
798 hRemoteProcess
= OpenProcess( remoteProcessId
);
800 if ( hRemoteProcess
== NULL
)
804 handle
= DuplicateHandle( hRemoteProcess
, h
);
809 // Get the process information
810 if ( INtDll::NtQueryInformationProcess( handle
, 0, &pi
, sizeof(pi
), NULL
) == 0 )
812 processId
= pi
.UniqueProcessId
;
818 if ( hRemoteProcess
!= NULL
)
819 CloseHandle( hRemoteProcess
);
821 if ( handle
!= NULL
)
822 CloseHandle( handle
);
828 //File related functions
829 void SystemHandleInformation::GetFileNameThread( PVOID pParam
)
831 // This thread function for getting the filename
832 // if access denied, we hang up in this function,
833 // so if it times out we just kill this thread
834 GetFileNameThreadParam
* p
= (GetFileNameThreadParam
*)pParam
;
836 UCHAR lpBuffer
[0x1000];
839 p
->rc
= INtDll::NtQueryInformationFile( p
->hFile
, iob
, lpBuffer
, sizeof(lpBuffer
), 9 );
842 *p
->pName
= (const char *)lpBuffer
;
845 BOOL
SystemHandleInformation::GetFileName( HANDLE h
, string
& str
, DWORD processId
)
848 HANDLE hThread
= NULL
;
849 GetFileNameThreadParam tp
;
851 HANDLE hRemoteProcess
= NULL
;
852 BOOL remote
= processId
!= GetCurrentProcessId();
860 hRemoteProcess
= OpenProcess( processId
);
862 if ( hRemoteProcess
== NULL
)
866 handle
= DuplicateHandle( hRemoteProcess
, h
);
875 // Let's start the thread to get the file name
876 hThread
= (HANDLE
)_beginthread( GetFileNameThread
, 0, &tp
);
878 if ( hThread
== NULL
)
884 // Wait for finishing the thread
885 if ( WaitForSingleObject( hThread
, 100 ) == WAIT_TIMEOUT
)
888 // Terminate the thread
889 TerminateThread( hThread
, 0 );
896 ret
= ( tp
.rc
== 0 );
902 if ( hRemoteProcess
!= NULL
)
903 CloseHandle( hRemoteProcess
);
905 if ( handle
!= NULL
)
906 CloseHandle( handle
);
912 //////////////////////////////////////////////////////////////////////////////////////
914 // SystemModuleInformation
916 //////////////////////////////////////////////////////////////////////////////////////
918 SystemModuleInformation::SystemModuleInformation( DWORD pID
, BOOL bRefresh
)
926 void SystemModuleInformation::GetModuleListForProcess( DWORD processID
)
930 HMODULE
* hModules
= NULL
;
931 MODULE_INFO moduleInfo
;
933 // Open process to read to query the module list
934 HANDLE hProcess
= OpenProcess( PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, processID
);
936 if ( hProcess
== NULL
)
939 //Get the number of modules
940 if ( !(*m_EnumProcessModules
)( hProcess
, NULL
, 0, &cbNeeded
) )
943 hModules
= new HMODULE
[ cbNeeded
/ sizeof( HMODULE
) ];
946 if ( !(*m_EnumProcessModules
)( hProcess
, hModules
, cbNeeded
, &cbNeeded
) )
949 for ( i
= 0; i
< cbNeeded
/ sizeof( HMODULE
); i
++ )
951 moduleInfo
.ProcessId
= processID
;
952 moduleInfo
.Handle
= hModules
[i
];
954 //Get module full paths
955 if ( (*m_GetModuleFileNameEx
)( hProcess
, hModules
[i
], moduleInfo
.FullPath
, _MAX_PATH
) )
956 m_ModuleInfos
.push_back( moduleInfo
);
960 if ( hModules
!= NULL
)
963 if ( hProcess
!= NULL
)
964 CloseHandle( hProcess
);
967 BOOL
SystemModuleInformation::Refresh()
970 m_EnumProcessModules
= NULL
;
971 m_GetModuleFileNameEx
= NULL
;
973 m_ModuleInfos
.clear();
976 HINSTANCE hDll
= LoadLibrary( "PSAPI.DLL" );
984 //Get Psapi.dll functions
985 m_EnumProcessModules
= (PEnumProcessModules
)GetProcAddress( hDll
, "EnumProcessModules" );
987 m_GetModuleFileNameEx
= (PGetModuleFileNameEx
)GetProcAddress( hDll
,
989 "GetModuleFileNameExW" );
991 "GetModuleFileNameExA" );
994 if ( m_GetModuleFileNameEx
== NULL
|| m_EnumProcessModules
== NULL
)
1000 // Everey process or just a particular one
1001 if ( m_processId
!= -1 )
1002 // For a particular one
1003 GetModuleListForProcess( m_processId
);
1006 // Get teh process list
1008 SystemProcessInformation::SYSTEM_PROCESS_INFORMATION
* p
= NULL
;
1009 SystemProcessInformation
pi( TRUE
);
1011 if ( pi
.m_ProcessInfos
.empty() )
1017 // Iterating through the processes and get the module list
1018 for (map
<DWORD
, SystemProcessInformation::SYSTEM_PROCESS_INFORMATION
*>::iterator iter
= pi
.m_ProcessInfos
.begin(); iter
!= pi
.m_ProcessInfos
.end(); iter
++) {
1021 GetModuleListForProcess( pID
);
1031 FreeLibrary( hDll
);
1036 //////////////////////////////////////////////////////////////////////////////////////
1038 // SystemWindowInformation
1040 //////////////////////////////////////////////////////////////////////////////////////
1042 SystemWindowInformation::SystemWindowInformation( DWORD pID
, BOOL bRefresh
)
1050 BOOL
SystemWindowInformation::Refresh()
1052 m_WindowInfos
.clear();
1054 // Enumerating the windows
1055 EnumWindows( EnumerateWindows
, (LPARAM
)this );
1060 BOOL CALLBACK
SystemWindowInformation::EnumerateWindows( HWND hwnd
, LPARAM lParam
)
1062 SystemWindowInformation
* _this
= (SystemWindowInformation
*)lParam
;
1066 GetWindowThreadProcessId(hwnd
, &wi
.ProcessId
) ;
1068 // Filtering by process ID
1069 if ( _this
->m_processId
== -1 || _this
->m_processId
== wi
.ProcessId
)
1071 GetWindowText( hwnd
, wi
.Caption
, MaxCaptionSize
);
1073 // That is we are looking for
1074 if ( GetLastError() == 0 )
1075 _this
->m_WindowInfos
.push_back( wi
);