How Could I Get the Window Title from Its Process Name? - c++

This is my code to check if the process name existed or not:
bool isRunning (LPCSTR processname)
{
HANDLE Snapshot;
Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(Snapshot != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 ProcessEntry;
BOOL Succeed;
ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
Succeed = Process32First(Snapshot, &ProcessEntry);
while(Succeed)
{
if(lstrcmp(ProcessEntry.szExeFile,processname) == 0)
{
return true;
}
Succeed = Process32Next(Snapshot, &ProcessEntry);
}
CloseHandle(Snapshot);
}
}
How could I use it or edit it to get the window title from its process name (for example "notepad.exe")?
If it existed the program would return text like "New text document - Notepad"

This is actually addressed in Microsoft's description of CreateToolhelp32Snapshot.
It says "You can use the QueryFullProcessImageName function to retrieve the full name of an executable image for both 32- and 64-bit processes from a 32-bit process."
You'll basically need to iterate through checking your HANDLEs with QueryFullProcessImageName.

Related

How to check whether Microsoft outlook is opened or not in c++?

I want to perform a specific action in my application based on whether outlook is opened or not.
I tried this piece of code, but it is always returning false.
CLSID clsid;
HRESULT hr = CLSIDFromProgID(_T("Outlook.Application"), &clsid);
if (hr != S_OK)
return false;
IUnknown *pUnknown = NULL;
hr = GetActiveObject(clsid, 0, &pUnknown);
return (hr == S_OK);
Could anyone please let me know how do we check whether "Outlook" is opened or not in c++.
As far as I know, C++ standard will not help in this case, as your question is operating system specific.
You can use "WinAPI" if you are on windows OS.
Below are some steps. The code for below steps is available in below MSDN link. You can modify the code as required for your usage.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx
Call "EnumProcesses". Will return the list of process IDs.
Iterate through each process using process ID return by "EnumProcesses".
Then find the name of process using "OpenProcess" and "GetModuleBaseName" as shown in above MSDN link.
Search for the string "Outlook" in the process name returned by above step (step 3).
This is a rough way I know.
Get the snapshot of all process running in the system, iterate to find
whether "outlook" is present in any of the exe name.
void isOutlookRunning()
{
bool retval = false;
PROCESSENTRY32 t_entry;
t_entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE t_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(t_snapshot, &t_entry))
{
while (Process32Next(t_snapshot, &t_entry))
{
if(StrStrI(t_entry.szExeFile,"outlook")
retval = true;
}
}
CloseHandle(t_snapshot);
return retval;
}

C++ | Windows - Is there a way to find out which process has ownership of the locked file?

What I want to know is it possible to try an open a file (and when it fails because it's opened with another process with sharing off) to figure out which process is using said file?
The reason I am wanting to know this information is because I am making a little application that will "fix" malicious files.
For example, some malicious/adware etc set the file security descriptor so the user can't delete the file, etc. My application just resets the security descriptor allowing the user to regain control.
I have also seen a file open up its child process with for example (CreateFile) and have Shared Mode turned off so the file can't be touched, then the application would execute the childprocess from memory.
Yes, you can in general just use the openfiles command, after having enabled collection of this information via, it appears, openfiles /local on.
In Windows NT up to and including (it seems) Windows XP there was a similar Resource Kit command named oh, short for open handles.
An alternative to both is to use SysInternal's Process Explorer.
Note: In some cases openfiles will fail to list some handle. This happens for me when Windows refuses to unmount an USB disk, claiming that some process is using a file on that disk. No such process ever shows up.
I have developed a function to locate such process, kill it and delete the locked file.
bool ForceDeleteFile(LPWSTR FileName);
Here is the full source code:
bool KillFileProcess(LPWSTR FileName)
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
bool result = false;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
//printError(TEXT("CreateToolhelp32Snapshot (of processes)"));
return(FALSE);
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32))
{
//printError(TEXT("Process32First")); // show cause of failure
CloseHandle(hProcessSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
// Retrieve the priority class.
dwPriorityClass = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if (hProcess == NULL)
{
//printError(TEXT("OpenProcess"));
}
else
{
dwPriorityClass = GetPriorityClass(hProcess);
if (!dwPriorityClass)
{
//printError(TEXT("GetPriorityClass"));
}
CloseHandle(hProcess);
if (HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID))
{
WCHAR filename[MAX_PATH] = {};
if (GetModuleFileNameEx(hProcess, NULL, filename, MAX_PATH))
{
if (_wcsicmp((const wchar_t *)FileName, (const wchar_t *)filename) == NULL)
{
if (TerminateProcess(pe32.th32ProcessID, 0))
{
_tprintf(L"Found: Process full killed\nKILLED!\n");
result = true;
}
else
{
_tprintf(L"Found: Process full \nFailed to terminate\n");
DoRun(((CString)L"taskkill /F /IM " + (CString)pe32.szExeFile).GetBuffer());
result = false;
}
}
}
else
{
// handle error
}
CloseHandle(hProcess);
}
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return(result);
}
bool ForceDeleteFile(LPWSTR FileName)
{
bool result = DeleteFile(FileName);
if (!result)
{
_tprintf(L"Can't delete file. using DeleteFile(). Trying to locate process and kill it\n");
result = KillFileProcess(FileName);
if (!result)
_tprintf(L"Couldn't find the process\n");
else
{
Sleep(1000);
result = DeleteFile(FileName);
if (result)
_tprintf(L"DeleteFile success");
else
_tprintf(L"DeleteFile ============== failed ===============");
}
}
return result;
}
BOOL TerminateProcess(DWORD dwProcessId, UINT uExitCode)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, uExitCode);
CloseHandle(hProcess);
return result;
}

CreateToolhelp32Snapshot: INVALID_HANDLE_VALUE (ERROR_PARTIAL_COPY)

This code is running in a 64-bit application. The target application is 32-bit.
Every time I run this code, CreateToolhelp32Snapshot() returns INVALID_HANDLE_VALUE and then GetLastError() returns ERROR_PARTIAL_COPY. So it skips the loop and returns false.
BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
//Get Handle to Remote Process
HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
....
//Check to see if 64-bit or 32-bit application
IsWow64Process(Proc, &isWow64);
size_t szCurProc = sizeof(void*); //returns 8
if (isWow64)
{
__debugbreak();
//Get list of all Modules associated with the Process
HANDLE hProc32Module;
do {
hProc32Module = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32, pID);
}
while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));
if (hProc32Module == INVALID_HANDLE_VALUE) {
__debugbreak();
DWORD err = GetLastError(); //just to see the error code which is 0x12b
return false;
}
//Find the module for Kernel.dll and get the base address of it
MODULEENTRY32 entryModule;
entryModule.dwSize = sizeof(MODULEENTRY32);
BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
DWORD errEndofList = GetLastError();
BOOL isSuccessful = false;
while (errEndofList != ERROR_NO_MORE_FILES && isGetModuleSuccess)
{
if (_tcscmp(entryModule.szModule, KERNEL32_DLL)){
isSuccessful = true;
break;
}
isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
errEndofList = GetLastError();
}
if (!isSuccessful)
{
__debugbreak();
CloseHandle(hProc32Module);
return false;
}
//Get handle for Kernel.dll module
hKernel32 = entryModule.hModule;
CloseHandle(hProc32Module);
}
else
{
....
According to the documentation, CreateToolhelp32Snapshot() only fails with ERROR_PARTIAL_COPY when CreateToolhelp32Snapshot() is called by a 32bit process trying to access a 64bit process:
If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
Make sure your app really is compiled for 64bit to begin with. TH32CS_SNAPMODULE32 only makes sense to use when CreateToolhelp32Snapshot() is being called in a 64bit process:
TH32CS_SNAPMODULE32
0x00000010
Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process.
You are also not taking into account that GetLastError() is only updated when API functions fail, unless documented otherwise. Your loops are assuming that GetLastError() is updated after every API call, that is simply not true.
Try something more like this instead:
BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
//Get Handle to Remote Process
HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
....
DWORD dwFlag;
#ifdef _WIN64
//Check if Remote Process is a 32-bit application
BOOL isWow64 = FALSE;
IsWow64Process(Proc, &isWow64);
if (!isWow64) return false;
// TH32CS_SNAPMODULE32 includes 32bit modules when used by a 64bit process...
dwFlag = TH32CS_SNAPMODULE32;
#else
// TH32CS_SNAPMODULE includes 32bit modules when used by a 32bit process...
dwFlag = TH32CS_SNAPMODULE;
#endif
__debugbreak();
//Get list of all Modules associated with the Process
HANDLE hProc32Module;
do {
hProc32Module = CreateToolhelp32Snapshot(dwFlag, pID);
}
while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));
if (hProc32Module == INVALID_HANDLE_VALUE) {
__debugbreak();
return false;
}
//Find the module for Kernel.dll and get the base address of it
hKernel32 = NULL;
MODULEENTRY32 entryModule = {0};
entryModule.dwSize = sizeof(MODULEENTRY32);
BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
while (isGetModuleSuccess) {
if (_tcscmp(entryModule.szModule, KERNEL32_DLL)) {
hKernel32 = entryModule.hModule;
break;
}
isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
}
if (!hKernel32) {
__debugbreak();
CloseHandle(hProc32Module);
return false;
}
CloseHandle(hProc32Module);
....
}
According to the documentation, CreateToolhelp32Snapshot() only fails with ERROR_PARTIAL_COPY when CreateToolhelp32Snapshot() is called by a 32bit process trying to access a 64bit process:
If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
This is plain wrong as you could have deduced from the excerpt you posted. Where does it say it ONLY fails with ERROR_PARTIAL_COPY (299) when the caller is 32bit trying to access 64bit? It doesn't.
If the documentation would be complete, which it is not, then you would be right to assume that the stated behaviour is the only way to generate an ERROR_PARTIAL_COPY error code. Sadly the documentation is not complete.
For example if you start a process with the CREATE_SUSPENDED flag the CreateToolhelp32Snapshot API will set the error code to ERROR_PARTIAL_COPY when queried for modules regardless of the bitness of the host or target application. The reason it fails is because the DLLs aren't loaded until after the main thread is resumed and therefore the PebLdr pointer in the PEB structure is NULL.
Basically anything which prevents read of process memory (missing address in PEB, unmapped segment, etc.) can cause ERROR_PARTIAL_COPY as its description states:
ERROR_PARTIAL_COPY 299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

C++ Check if specific process is running

I have a C++ DLL that i am writing that needs to check if a particular process is running.
the dll will be launched application will be running in:
c:\Directory\application.exe
there is a subdirectory within that that has another executable in it:
c:\Directory\SubDirectory\application2.exe
What the DLL needs to do when it runs if check that application2.exe is running, most importantly that it is running within that folder -- there will be multiple copies running, so we need to ensure that the correct one is running.
I have the following code that is working well at detecting that the application2.exe is running, but it does not take the file path into consideration:
HANDLE pss = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(pe);
if (Process32First(pss, &pe))
{
do
{
if(wcscmp(pe.szExeFile, L"application2.exe") == 0)
{
CloseHandle(pss);
return (1);
}
}
while(Process32Next(pss, &pe));
}
CloseHandle(pss);
How can I check that the path of the process matches the path of the application which called the DLL?
Use WMI for this.
From the command line you can do:
wmic process where "executablepath = 'c:\path\to\executable.exe'" get ProcessId
You can use the WMI apis from C++ to do something similar.
http://www.codeproject.com/Articles/10539/Making-WMI-Queries-In-C
I have been given a solution that works for this, in case anyone else searching here it is:
HANDLE ProcessSnap;
PROCESSENTRY32 Pe32;
unsigned int LoopCounter = 0;
Pe32.dwSize = sizeof(PROCESSENTRY32);
ProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Process32First(ProcessSnap, &Pe32);
wchar_t TermPath[MAX_PATH];
GetModuleFileName(NULL, TermPath, MAX_PATH);
wstring WTermPath(TermPath);
int index = WTermPath.find(L"\\application.exe");
wstring Path = WTermPath.substr(0, (index));
Path = Path + L"\\SubDirectory\\Application2.exe";
do
{
HANDLE Process;
wchar_t FilePath[MAX_PATH];
Process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, Pe32.th32ProcessID);
if (Process)
{
GetModuleFileNameEx(Process, 0, FilePath, MAX_PATH);
wstring WFilePath(FilePath);
if(WFilePath == Path)
{
CloseHandle(ProcessSnap);
return (1);
}
CloseHandle(Process);
}
LoopCounter++;
} while (Process32Next(ProcessSnap, &Pe32));
CloseHandle(ProcessSnap);

C++ How to Check if an Outlook Process is already running

I am new to C++ programming but I would like to know if there is an easy way to check if an Outlook Process is already running, or in other words check if Outlook is already open.
Can anyone show me, please?
Thanks
You can check the running instance of the outlook OLE:
static const bool isOutlookRunning()
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID( _T("Outlook.Application"), &clsid );
if( hr != S_OK ) return false;
IUnknown *pUnknown = NULL;
hr = GetActiveObject( clsid, 0, &pUnknown );
return ( hr == S_OK );
}
This code will not work if the app from you invoke it is running in different user security context than Outlook.
Its better to check for the process name.
//////////////////////////////////////////////////////////////////////
// IsProcessRunning
//////////////////////////////////////////////////////////////////////
bool IsProcessRunning(string &strProcessFullPathName)
{
// Get the list of process identifiers.
DWORD dwProcesses[2048];
DWORD dwSizeNeeded = 0;
DWORD dwProcessesCount = 0;
if ( !EnumProcesses( dwProcesses, sizeof(dwProcesses), &dwSizeNeeded ) )
{
_dwLastErrorCode = GetLastError();
_strLastError = "EnumProcesses";
return false;
}
dwProcessesCount = dwSizeNeeded / sizeof(DWORD);
string strToCheck = strProcessFullPathName;
transform(strToCheck.begin(), strToCheck.end(), strToCheck.begin(), tolower);
for(int i=0; i<(int)dwProcessesCount; i++ )
{
if( dwProcesses[i] != 0 )
{
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcesses[i]);
if(hProcess)
{
HMODULE hModule = NULL;
dwSizeNeeded = 0;
char cName[MAX_PATH];
if(EnumProcessModules(hProcess, &hModule, sizeof(DWORD), &dwSizeNeeded) )
{
if(GetModuleFileNameEx(hProcess, hModule, cName, MAX_PATH ) != 0)
{
string strName(cName);
// Convert to LowerCase
transform(strName.begin(), strName.end(), strName.begin(), tolower);
if(strName == strToCheck)
{
CloseHandle(hProcess);
return true;
}
}
}
CloseHandle(hProcess);
}
}
}
return false;
}
I assume that you are using Windows as platform, since Outlook normally runs under a Windows OS.
For a simple check you can use the Windows API functions EnumProcesses() and GetModuleBaseName() to determine the executable filename of the running processes and check if the executable name is "outlook.exe". A reference for the functions can be found in the MSDN.
Be aware that the this check may fail if the user runs another program that is using the same executable filename as Outlook. Another trap with the provided solution might be the access rights a user needs for the specified API calls.
Improvements might be to check the version information in the executable file too by using GetFileVersionInfo().
You can use CreateToolhelp32Snapshot and iterate through the running processes. If you need to heck for Outlook again (say you need to poll for the process), then save the process ID and use OpenProcess (many times faster). More details are given in the answer to this question:
Check whether one specific process is running on windows with C++