bool wxProcessKiller::PSExtract(wxProcessKiller::wxPInfoArray &arPinfo) { bool rc=false; arPinfo.clear(); // If Windows NT: switch(GetPlatform()) { case VER_PLATFORM_WIN32_NT: if(hInstLib1) { // Get procedure addresses. static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( (HINSTANCE) hInstLib1, "EnumProcesses" ) ; if( lpfEnumProcesses) { if(hInstLib2) { static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) = (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( (HINSTANCE) hInstLib2,"NtQueryInformationProcess" ) ; if(lpfNtQueryInformationProcess){ DWORD dwMaxPids=256; DWORD dwPidSize; DWORD *arPids = NULL ; do { delete [] arPids; arPids=new DWORD[dwMaxPids]; } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ; if(dwPidSize/sizeof(DWORD)<dwMaxPids){ rc=true; for( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) { // Regardless of OpenProcess success or failure, we // still call the enum func with the ProcID. DWORD pid=arPids[dwIndex]; HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid ); if (hProcess ) { struct { DWORD ExitStatus; // receives process termination status DWORD PebBaseAddress; // receives process environment block address DWORD AffinityMask; // receives process affinity mask DWORD BasePriority; // receives process priority class ULONG UniqueProcessId; // receives process identifier ULONG InheritedFromUniqueProcessId; // receives parent process identifier } pbi; memset( &pbi, 0, sizeof(pbi)); DWORD retLen; __int64 ftCreation,ftExit,ftKernel,ftUser; if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 && TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ // The second test is important. It excludes orphaned processes who appear to have been adopted by virtue of a new // process having been created with the same ID as their original parent. wxPInfo p; p.PID=pid; p.PPID=pbi.InheritedFromUniqueProcessId; p.tCreation=ftCreation; p.tCpu=Time((ftKernel+ftUser)/10000); arPinfo.push_back(p); } CloseHandle(hProcess); } } } delete [] arPids; } } } } break; case VER_PLATFORM_WIN32_WINDOWS: if( hInstLib1) { static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)= (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( (HINSTANCE) hInstLib1,"CreateToolhelp32Snapshot" ) ; static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32First" ) ; static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32Next" ) ; if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) { // Get a handle to a Toolhelp snapshot of the systems // processes. HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; if(INVALID_HANDLE_VALUE != hSnapShot) { // Get the first process' information. PROCESSENTRY32 procentry; procentry.dwSize = sizeof(PROCESSENTRY32) ; if(lpfProcess32First( hSnapShot, &procentry )){ rc=true; do { wxPInfo p; p.PID=procentry.th32ProcessID; p.PPID=procentry.th32ParentProcessID; arPinfo.push_back(p); } while(lpfProcess32Next( hSnapShot, &procentry )); } CloseHandle(hSnapShot); } } } break; default: break; } SetParents(arPinfo); if(!rc){ wxLogError(_T("Couldn't get process information!\n")); } return rc; }
// // The EnumProcs function takes a pointer to a callback function // that will be called once per process with the process filename // and process ID. // // lpProc -- Address of callback routine. // // lParam -- A user-defined LPARAM value to be passed to // the callback routine. // // Callback function definition: // BOOL CALLBACK Proc(DWORD dw, WORD w, LPCSTR lpstr, LPARAM lParam); // BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam) { OSVERSIONINFO osver; HINSTANCE hInstLib = NULL; HINSTANCE hInstLib2 = NULL; HANDLE hSnapShot = NULL; LPDWORD lpdwPIDs = NULL; PROCESSENTRY32 procentry; BOOL bFlag; DWORD dwSize; DWORD dwSize2; DWORD dwIndex; HMODULE hMod; HANDLE hProcess; char szFileName[MAX_PATH]; EnumInfoStruct sInfo; // ToolHelp Function Pointers. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD); BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32); BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32); // PSAPI Function Pointers. BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *); BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD); DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD); // VDMDBG Function Pointers. INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM); // Retrieve the OS version osver.dwOSVersionInfoSize = sizeof(osver); if (!GetVersionEx(&osver)) return FALSE; // If Windows NT 4.0 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion == 4) { __try { // Get the procedure addresses explicitly. We do // this so we don't have to worry about modules // failing to load under OSes other than Windows NT 4.0 // because references to PSAPI.DLL can't be resolved. hInstLib = LoadLibraryA("PSAPI.DLL"); if (hInstLib == NULL) __leave; hInstLib2 = LoadLibraryA("VDMDBG.DLL"); if (hInstLib2 == NULL) __leave; // Get procedure addresses. lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*)) GetProcAddress(hInstLib, "EnumProcesses"); lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules"); lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD)) GetProcAddress(hInstLib, "GetModuleBaseNameA"); lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); if (lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || lpfGetModuleBaseName == NULL || lpfVDMEnumTaskWOWEx == NULL) __leave; // // Call the PSAPI function EnumProcesses to get all of the // ProcID's currently in the system. // // NOTE: In the documentation, the third parameter of // EnumProcesses is named cbNeeded, which implies that you // can call the function once to find out how much space to // allocate for a buffer and again to fill the buffer. // This is not the case. The cbNeeded parameter returns // the number of PIDs returned, so if your buffer size is // zero cbNeeded returns zero. // // NOTE: The "HeapAlloc" loop here ensures that we // actually allocate a buffer large enough for all the // PIDs in the system. // dwSize2 = 256 * sizeof(DWORD); do { if (lpdwPIDs) { HeapFree(GetProcessHeap(), 0, lpdwPIDs); dwSize2 *= 2; } lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0, dwSize2); if (lpdwPIDs == NULL) __leave; if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) __leave; } while (dwSize == dwSize2); // How many ProcID's did we get? dwSize /= sizeof(DWORD); // Loop through each ProcID. for (dwIndex = 0; dwIndex < dwSize; dwIndex++) { szFileName[0] = 0; // Open the process (if we can... security does not // permit every process in the system to be opened). hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]); if (hProcess != NULL) { // Here we call EnumProcessModules to get only the // first module in the process. This will be the // EXE module for which we will retrieve the name. if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize2)) { // Get the module name if (!lpfGetModuleBaseName(hProcess, hMod, szFileName, sizeof(szFileName))) szFileName[0] = 0; } CloseHandle(hProcess); } // Regardless of OpenProcess success or failure, we // still call the enum func with the ProcID. if (!lpProc(lpdwPIDs[dwIndex], 0, szFileName, lParam)) break; // Did we just bump into an NTVDM? if (_stricmp(szFileName, "NTVDM.EXE") == 0) { // Fill in some info for the 16-bit enum proc. sInfo.dwPID = lpdwPIDs[dwIndex]; sInfo.lpProc = lpProc; sInfo.lParam = (DWORD) lParam; sInfo.bEnd = FALSE; // Enum the 16-bit stuff. lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo); // Did our main enum func say quit? if (sInfo.bEnd) break; } } } __finally { if (hInstLib) FreeLibrary(hInstLib); if (hInstLib2) FreeLibrary(hInstLib2); if (lpdwPIDs) HeapFree(GetProcessHeap(), 0, lpdwPIDs); } // If any OS other than Windows NT 4.0. } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
int KILL_PROC_BY_NAME(const TCHAR *szToTerminate) // Created: 6/23/2000 (RK) // Last modified: 3/10/2002 (RK) // Please report any problems or bugs to [email protected] // The latest version of this routine can be found at: // http://www.neurophys.wisc.edu/ravi/software/killproc/ // Terminate the process "szToTerminate" if it is currently running // This works for Win/95/98/ME and also Win/NT/2000/XP // The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE" // will both work (for szToTerminate) // Return codes are as follows: // 0 = Process was successfully terminated // 603 = Process was not currently running // 604 = No permission to terminate process // 605 = Unable to load PSAPI.DLL // 602 = Unable to terminate process for some other reason // 606 = Unable to identify system type // 607 = Unsupported OS // 632 = Invalid process name // 700 = Unable to get procedure address from PSAPI.DLL // 701 = Unable to get process list, EnumProcesses failed // 702 = Unable to load KERNEL32.DLL // 703 = Unable to get procedure address from KERNEL32.DLL // 704 = CreateToolhelp32Snapshot failed // Change history: // modified 3/8/2002 - Borland-C compatible if BORLANDC is defined as // suggested by Bob Christensen // modified 3/10/2002 - Removed memory leaks as suggested by // Jonathan Richard-Brochu (handles to Proc and Snapshot // were not getting closed properly in some cases) { BOOL bResult,bResultm; DWORD aiPID[1000],iCb=1000,iNumProc,iV2000=0; DWORD iCbneeded,i,iFound=0; TCHAR szName[MAX_PATH],szToTermUpper[MAX_PATH]; HANDLE hProc,hSnapShot,hSnapShotm; OSVERSIONINFO osvi; HINSTANCE hInstLib; int iLen,iLenP,indx; HMODULE hMod; PROCESSENTRY32 procentry; MODULEENTRY32 modentry; // Transfer Process name into "szToTermUpper" and // convert it to upper case iLenP=(int)wcslen(szToTerminate); if(iLenP<1 || iLenP>MAX_PATH) return 632; for(indx=0;indx<iLenP;indx++) szToTermUpper[indx]=toupper(szToTerminate[indx]); szToTermUpper[iLenP]=0; // PSAPI Function Pointers. BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ); BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ); DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE, LPTSTR, DWORD ); // ToolHelp Function Pointers. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ; BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ; BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ; // First check what version of Windows we're in osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); bResult=GetVersionEx(&osvi); if(!bResult) // Unable to identify system version return 606; // At Present we only support Win/NT/2000/XP or Win/9x/ME if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607; if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) { // Win/NT or 2000 or XP // Load library and get the procedures explicitly. We do // this so that we don't have to worry about modules using // this code failing to load under Windows 9x, because // it can't resolve references to the PSAPI.DLL. hInstLib = LoadLibraryA("PSAPI.DLL"); if(hInstLib == NULL) return 605; // Get procedure addresses. lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*)) GetProcAddress( hInstLib, "EnumProcesses" ) ; lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ) ; lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameW" ) ; if(lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || lpfGetModuleBaseName == NULL) { FreeLibrary(hInstLib); return 700; } bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded); if(!bResult) { // Unable to get process list, EnumProcesses failed FreeLibrary(hInstLib); return 701; } // How many processes are there? iNumProc=iCbneeded/sizeof(DWORD); // Get and match the name of each process for(i=0;i<iNumProc;i++) { // Get the (module) name for this process wcscpy_s(szName,L"Unknown"); // First, get a handle to the process hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE, aiPID[i]); // Now, get the process name if(hProc) { if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) { iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH); } } CloseHandle(hProc); // We will match regardless of lower or upper case #ifdef BORLANDC if(strcmp(strupr(szName),szToTermUpper)==0) #else if(wcscmp(_wcsupr(szName),szToTermUpper)==0) #endif { // Process found, now terminate it iFound=1; // First open for termination hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]); if(hProc) { if(TerminateProcess(hProc,0)) { // process terminated CloseHandle(hProc); FreeLibrary(hInstLib); return 0; } else { // Unable to terminate process CloseHandle(hProc); FreeLibrary(hInstLib); return 602; } } else { // Unable to open process for termination FreeLibrary(hInstLib); return 604; } } } } if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) { // Win/95 or 98 or ME hInstLib = LoadLibraryA("Kernel32.DLL"); if( hInstLib == NULL ) return 702; // Get procedure addresses. // We are linking to these functions of Kernel32 // explicitly, because otherwise a module using // this code would fail to load under Windows NT, // which does not have the Toolhelp32 // functions in the Kernel 32. lpfCreateToolhelp32Snapshot= (HANDLE(WINAPI *)(DWORD,DWORD)) GetProcAddress( hInstLib, "CreateToolhelp32Snapshot" ) ; lpfProcess32First= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32First" ) ; lpfProcess32Next= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32Next" ) ; lpfModule32First= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32First" ) ; lpfModule32Next= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32Next" ) ; if( lpfProcess32Next == NULL || lpfProcess32First == NULL || lpfModule32Next == NULL || lpfModule32First == NULL || lpfCreateToolhelp32Snapshot == NULL ) { FreeLibrary(hInstLib); return 703; } // The Process32.. and Module32.. routines return names in all uppercase // Get a handle to a Toolhelp snapshot of all the systems processes. hSnapShot = lpfCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ; if( hSnapShot == INVALID_HANDLE_VALUE ) { FreeLibrary(hInstLib); return 704; } // Get the first process' information. procentry.dwSize = sizeof(PROCESSENTRY32); bResult=lpfProcess32First(hSnapShot,&procentry); // While there are processes, keep looping and checking. while(bResult) { // Get a handle to a Toolhelp snapshot of this process. hSnapShotm = lpfCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, procentry.th32ProcessID) ; if( hSnapShotm == INVALID_HANDLE_VALUE ) { CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 704; } // Get the module list for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32First(hSnapShotm,&modentry); // While there are modules, keep looping and checking while(bResultm) { if(wcscmp(modentry.szModule,szToTermUpper)==0) { // Process found, now terminate it iFound=1; // First open for termination hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID); if(hProc) { if(TerminateProcess(hProc,0)) { // process terminated CloseHandle(hSnapShotm); CloseHandle(hSnapShot); CloseHandle(hProc); FreeLibrary(hInstLib); return 0; } else { // Unable to terminate process CloseHandle(hSnapShotm); CloseHandle(hSnapShot); CloseHandle(hProc); FreeLibrary(hInstLib); return 602; } } else { // Unable to open process for termination CloseHandle(hSnapShotm); CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 604; } } else { // Look for next modules for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32Next(hSnapShotm,&modentry); } } //Keep looking CloseHandle(hSnapShotm); procentry.dwSize = sizeof(PROCESSENTRY32); bResult = lpfProcess32Next(hSnapShot,&procentry); } CloseHandle(hSnapShot); } if(iFound==0) { FreeLibrary(hInstLib); return 603; } FreeLibrary(hInstLib); return 0; }
int FIND_PROC_BY_NAME(const char *szToFind) // Created: 12/29/2000 (RK) // Last modified: 6/16/2003 (RK) // Please report any problems or bugs to [email protected] // The latest version of this routine can be found at: // http://www.neurophys.wisc.edu/ravi/software/killproc/ // Check whether the process "szToFind" is currently running in memory // This works for Win/95/98/ME and also Win/NT/2000/XP // The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE" // will both work (for szToFind) // Return codes are as follows: // 0 = Process was not found // 1 = Process was found // 605 = Unable to search for process // 606 = Unable to identify system type // 607 = Unsupported OS // 632 = Process name is invalid // Change history: // 3/10/2002 - Fixed memory leak in some cases (hSnapShot and // and hSnapShotm were not being closed sometimes) // 6/13/2003 - Removed iFound (was not being used, as pointed out // by John Emmas) { BOOL bResult,bResultm; DWORD aiPID[1000],iCb=1000,iNumProc,iV2000=0; DWORD iCbneeded,i; char szName[MAX_PATH],szToFindUpper[MAX_PATH]; HANDLE hProc,hSnapShot,hSnapShotm; OSVERSIONINFO osvi; HINSTANCE hInstLib; int iLen,iLenP,indx; HMODULE hMod; PROCESSENTRY32 procentry; MODULEENTRY32 modentry; // PSAPI Function Pointers. BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ); BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ); DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE, LPTSTR, DWORD ); // ToolHelp Function Pointers. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ; BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ; BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ; // Transfer Process name into "szToFindUpper" and // convert it to upper case iLenP=strlen(szToFind); if(iLenP<1 || iLenP>MAX_PATH) return 632; for(indx=0;indx<iLenP;indx++) szToFindUpper[indx]=toupper(szToFind[indx]); szToFindUpper[iLenP]=0; // First check what version of Windows we're in osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); bResult=GetVersionEx(&osvi); if(!bResult) // Unable to identify system version return 606; // At Present we only support Win/NT/2000 or Win/9x/ME if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607; if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) { // Win/NT or 2000 or XP // Load library and get the procedures explicitly. We do // this so that we don't have to worry about modules using // this code failing to load under Windows 95, because // it can't resolve references to the PSAPI.DLL. hInstLib = LoadLibraryA("PSAPI.DLL"); if(hInstLib == NULL) return 605; // Get procedure addresses. lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*)) GetProcAddress( hInstLib, "EnumProcesses" ) ; lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ) ; lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameA" ) ; if( lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || lpfGetModuleBaseName == NULL) { FreeLibrary(hInstLib); return 605; } bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded); if(!bResult) { // Unable to get process list, EnumProcesses failed FreeLibrary(hInstLib); return 605; } // How many processes are there? iNumProc=iCbneeded/sizeof(DWORD); // Get and match the name of each process for(i=0;i<iNumProc;i++) { // Get the (module) name for this process strcpy(szName,"Unknown"); // First, get a handle to the process hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE, aiPID[i]); // Now, get the process name if(hProc) { if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) { iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH); } } CloseHandle(hProc); // Match regardless of lower or upper case if(strcmp(_strupr(szName),szToFindUpper)==0) { // Process found FreeLibrary(hInstLib); return 1; } } } if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) { // Win/95 or 98 or ME hInstLib = LoadLibraryA("Kernel32.DLL"); if( hInstLib == NULL ) return FALSE ; // Get procedure addresses. // We are linking to these functions of Kernel32 // explicitly, because otherwise a module using // this code would fail to load under Windows NT, // which does not have the Toolhelp32 // functions in the Kernel 32. lpfCreateToolhelp32Snapshot= (HANDLE(WINAPI *)(DWORD,DWORD)) GetProcAddress( hInstLib, "CreateToolhelp32Snapshot" ) ; lpfProcess32First= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32First" ) ; lpfProcess32Next= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32Next" ) ; lpfModule32First= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32First" ) ; lpfModule32Next= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32Next" ) ; if( lpfProcess32Next == NULL || lpfProcess32First == NULL || lpfModule32Next == NULL || lpfModule32First == NULL || lpfCreateToolhelp32Snapshot == NULL ) { FreeLibrary(hInstLib); return 605; } // The Process32.. and Module32.. routines return names in all uppercase // Get a handle to a Toolhelp snapshot of all the systems processes. hSnapShot = lpfCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ; if( hSnapShot == INVALID_HANDLE_VALUE ) { FreeLibrary(hInstLib); return 605; } // Get the first process' information. procentry.dwSize = sizeof(PROCESSENTRY32); bResult=lpfProcess32First(hSnapShot,&procentry); // While there are processes, keep looping and checking. while(bResult) { // Get a handle to a Toolhelp snapshot of this process. hSnapShotm = lpfCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, procentry.th32ProcessID) ; if( hSnapShotm == INVALID_HANDLE_VALUE ) { CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 605; } // Get the module list for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32First(hSnapShotm,&modentry); // While there are modules, keep looping and checking while(bResultm) { if(strcmp(modentry.szModule,szToFindUpper)==0) { // Process found CloseHandle(hSnapShotm); CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 1; } else { // Look for next modules for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32Next(hSnapShotm,&modentry); } } //Keep looking CloseHandle(hSnapShotm); procentry.dwSize = sizeof(PROCESSENTRY32); bResult = lpfProcess32Next(hSnapShot,&procentry); } CloseHandle(hSnapShot); } FreeLibrary(hInstLib); return 0; }
int os_msw::terminate_process_by_name( const wxString& named_process_to_terminate ) { // A more wxWindows type interface const char *szToTerminate = named_process_to_terminate.c_str(); // See notes to is_named_process_running for credits and info. BOOL bResult,bResultm; DWORD aiPID[1000],iCb=1000,iNumProc,iV2000=0; DWORD iCbneeded,i,iFound=0; char szName[MAX_PATH],szToTermUpper[MAX_PATH]; HANDLE hProc,hSnapShot,hSnapShotm; OSVERSIONINFO osvi; HINSTANCE hInstLib; int iLen,iLenP,indx; HMODULE hMod; PROCESSENTRY32 procentry; MODULEENTRY32 modentry; // Transfer Process name into "szToTermUpper" and // convert it to upper case iLenP=strlen(szToTerminate); if(iLenP<1 || iLenP>MAX_PATH) return 632; for(indx=0;indx<iLenP;indx++) szToTermUpper[indx]=toupper(szToTerminate[indx]); szToTermUpper[iLenP]=0; // PSAPI Function Pointers. BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ); BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ); DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE, LPTSTR, DWORD ); // ToolHelp Function Pointers. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ; BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ; BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ; // First check what version of Windows we're in osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); bResult=GetVersionEx(&osvi); if(!bResult) // Unable to identify system version return 606; // At Present we only support Win/NT/2000/XP or Win/9x/ME if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607; if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) { // Win/NT or 2000 or XP // Load library and get the procedures explicitly. We do // this so that we don't have to worry about modules using // this code failing to load under Windows 9x, because // it can't resolve references to the PSAPI.DLL. hInstLib = LoadLibraryA("PSAPI.DLL"); if(hInstLib == NULL) return 605; // Get procedure addresses. lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*)) GetProcAddress( hInstLib, "EnumProcesses" ) ; lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ) ; lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameA" ) ; if(lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || lpfGetModuleBaseName == NULL) { FreeLibrary(hInstLib); return 700; } bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded); if(!bResult) { // Unable to get process list, EnumProcesses failed FreeLibrary(hInstLib); return 701; } // How many processes are there? iNumProc=iCbneeded/sizeof(DWORD); // Get and match the name of each process for(i=0;i<iNumProc;i++) { // Get the (module) name for this process strcpy(szName,"Unknown"); // First, get a handle to the process hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE, aiPID[i]); // Now, get the process name if(hProc) { if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) { iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH); } } CloseHandle(hProc); // We will match regardless of lower or upper case #ifdef __BORLANDC__ if(strcmp(strupr(szName),szToTermUpper)==0) #else if(strcmp(_strupr(szName),szToTermUpper)==0) #endif { // Process found, now terminate it iFound=1; // First open for termination hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]); if(hProc) { if(TerminateProcess(hProc,0)) { // process terminated CloseHandle(hProc); FreeLibrary(hInstLib); return 0; } else { // Unable to terminate process CloseHandle(hProc); FreeLibrary(hInstLib); return 602; } } else { // Unable to open process for termination FreeLibrary(hInstLib); return 604; } } } } if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) { // Win/95 or 98 or ME hInstLib = LoadLibraryA("Kernel32.DLL"); if( hInstLib == NULL ) return 702; // Get procedure addresses. // We are linking to these functions of Kernel32 // explicitly, because otherwise a module using // this code would fail to load under Windows NT, // which does not have the Toolhelp32 // functions in the Kernel 32. lpfCreateToolhelp32Snapshot= (HANDLE(WINAPI *)(DWORD,DWORD)) GetProcAddress( hInstLib, "CreateToolhelp32Snapshot" ) ; lpfProcess32First= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32First" ) ; lpfProcess32Next= (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress( hInstLib, "Process32Next" ) ; lpfModule32First= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32First" ) ; lpfModule32Next= (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) GetProcAddress( hInstLib, "Module32Next" ) ; if( lpfProcess32Next == NULL || lpfProcess32First == NULL || lpfModule32Next == NULL || lpfModule32First == NULL || lpfCreateToolhelp32Snapshot == NULL ) { FreeLibrary(hInstLib); return 703; } // The Process32.. and Module32.. routines return names in all uppercase // Get a handle to a Toolhelp snapshot of all the systems processes. hSnapShot = lpfCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ; if( hSnapShot == INVALID_HANDLE_VALUE ) { FreeLibrary(hInstLib); return 704; } // Get the first process' information. procentry.dwSize = sizeof(PROCESSENTRY32); bResult=lpfProcess32First(hSnapShot,&procentry); // While there are processes, keep looping and checking. while(bResult) { // Get a handle to a Toolhelp snapshot of this process. hSnapShotm = lpfCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, procentry.th32ProcessID) ; if( hSnapShotm == INVALID_HANDLE_VALUE ) { CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 704; } // Get the module list for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32First(hSnapShotm,&modentry); // While there are modules, keep looping and checking while(bResultm) { if(strcmp(modentry.szModule,szToTermUpper)==0) { // Process found, now terminate it iFound=1; // First open for termination hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID); if(hProc) { //ROB: Replaced with best_terminate_process //if(TerminateProcess(hProc,0)) if ( best_terminate_process( hProc, 0 ) ) { // process terminated CloseHandle(hSnapShotm); CloseHandle(hSnapShot); CloseHandle(hProc); FreeLibrary(hInstLib); return 0; } else { // Unable to terminate process CloseHandle(hSnapShotm); CloseHandle(hSnapShot); CloseHandle(hProc); FreeLibrary(hInstLib); return 602; } } else { // Unable to open process for termination CloseHandle(hSnapShotm); CloseHandle(hSnapShot); FreeLibrary(hInstLib); return 604; } } else { // Look for next modules for this process modentry.dwSize=sizeof(MODULEENTRY32); bResultm=lpfModule32Next(hSnapShotm,&modentry); } } //Keep looking CloseHandle(hSnapShotm); procentry.dwSize = sizeof(PROCESSENTRY32); bResult = lpfProcess32Next(hSnapShot,&procentry); } CloseHandle(hSnapShot); } if(iFound==0) { FreeLibrary(hInstLib); return 603; } FreeLibrary(hInstLib); return 0; }
// Get PID and name of each process that has our DLL loaded. static bool GetProcesses(std::vector<ProcessInfo>& processes) { // PSAPI function pointers. BOOL (WINAPI* lpfEnumProcesses)(DWORD*, DWORD, DWORD*); BOOL (WINAPI* lpfEnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD ); DWORD (WINAPI* lpfGetModuleBaseName)(HANDLE, HMODULE, LPCTSTR, DWORD); bool found = false; // Load library and get function pointers. HINSTANCE hInstLib = LoadLibraryA("PSAPI.DLL"); if (!hInstLib) { DBG("Failed to load PSAPI.DLL"); return false; } // Get procedure addresses. lpfEnumProcesses = (BOOL (WINAPI*)(DWORD*,DWORD,DWORD*)) GetProcAddress(hInstLib, "EnumProcesses"); lpfEnumProcessModules = (BOOL (WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ); lpfGetModuleBaseName =(DWORD (WINAPI*)(HANDLE, HMODULE, LPCTSTR, DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameW" ); if (!lpfEnumProcesses || !lpfEnumProcessModules || !lpfGetModuleBaseName) { DBG("GetProcAddress failed"); FreeLibrary(hInstLib); return false; } DWORD pidList[1000]; DWORD iCbneeded; if (!lpfEnumProcesses(pidList, sizeof(pidList), &iCbneeded)) { DBG("EnumProcesses failed"); FreeLibrary(hInstLib); return false; } // How many processes are there? int iNumProc = iCbneeded/sizeof(DWORD); // Get and match the name of each process for (int i = 0; i < iNumProc; ++i) { // First, get a handle to the process HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pidList[i]); if (processHandle) { // Get modules loaded by process int maxModules = 1000; HMODULE* hMod = 0; while (1) { hMod = new HMODULE[maxModules]; // Determine number of modules if (!lpfEnumProcessModules(processHandle, hMod, maxModules*sizeof(HMODULE), &iCbneeded)) { DWORD err = GetLastError(); if (err = ERROR_PARTIAL_COPY) { // This means that we are looking at the SYSTEM process. Skip it. delete[] hMod; hMod = 0; break; } } else if (iCbneeded <= maxModules*sizeof(HMODULE)) break; delete[] hMod; if (maxModules > 50000) { DBG("maxModules: " << maxModules); return false; // This is getting ridiculous... } } if (!hMod) continue; // Explorer? TCHAR executableName[MAX_PATH]; if (!lpfGetModuleBaseName(processHandle, hMod[0], executableName, MAX_PATH)) { DBG("GetModuleBaseName failed for process " << pidList[i]); return false; } //DBG("PROCESS " << wxAscii(executableName)); if (!_tcsicmp(executableName, wxT("explorer.exe"))) { // Explorer must always be killed processes.push_back(ProcessInfo(pidList[i], executableName, wxT(""))); continue; } // Check if any of the modules are our DLL int numModules = iCbneeded/sizeof(HMODULE); for (int j = 1; j < numModules; ++j) { TCHAR name[MAX_PATH]; if (!lpfGetModuleBaseName(processHandle, hMod[j], name, MAX_PATH)) { DBG("GetModuleBaseName failed for module " << j); return false; } if (!_tcsicmp(name, wxT("tortoiseshell.dll")) || !_tcsicmp(name, wxT("tortoiseshell64.dll"))) { DBG("Process " << pidList[i] << " has " << wxAscii(name) << " loaded"); // Yes, this process must be terminated windowTitle.clear(); EnumWindows(EnumWindowsCallback, pidList[i]); processes.push_back(ProcessInfo(pidList[i], executableName, windowTitle)); } } delete[] hMod; CloseHandle(processHandle); } } FreeLibrary(hInstLib); DBG("GetProcesses SUCCESS"); return true; }