Check for CWinApp existence - c++

I have a process that was programed and used
CWinApp(
LPCTSTR lpszAppName = NULL
);
I know the lpszAppName.
By using the lpszAppName, I want to check whether this WinApp process exists or not.
How can I do it?
Thanks

Use named mutex:
At the beginning of program:
HANDLE hMutex = CreateMutex(NULL, TRUE, "Your program name");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// Process already running.
CloseHandle(hMutex);
}
else
{
// No process running.
}
At the end of program:
if (hMutex)
{
CloseHandle(hMutex);
hMutex = NULL;
}

Related

Destructor not being called upon program exit

I'm writing a very simple debugger and I defined a class called BREAKPOINT_INFO that contains information about breakpoints set.
class BREAKPOINT_INFO
{
public:
HANDLE hProcess;
PCHAR lpBreakPoint;
CHAR instr;
BOOL justCalled;
//Set default values
BREAKPOINT_INFO()
{
hProcess = NULL;
lpBreakPoint = NULL;
instr = 0x00;
justCalled = FALSE;
}
//Destructor
~BREAKPOINT_INFO()
{
//Let me know the destructor is being called
MessageBox(NULL, "Destructor called", NULL, MB_OK);
DWORD dwError = 0;
LPCSTR szErrorRest = (LPCSTR)"Error restoring original instruction: ";
LPCSTR szErrorHanlde = (LPCSTR)"Error closing process handle: ";
std::ostringstream oss;
if(hProcess != NULL && lpBreakPoint != NULL)
{
//write back the original instruction stored in instr
if(!WriteProcessMemory(hProcess, lpBreakPoint, &instr, sizeof(CHAR), NULL))
{
dwError = GetLastError();
oss << szErrorRest << dwError;
MessageBox(NULL, oss.str().c_str(), "ERROR", MB_OK|MB_ICONERROR);
}
}
}
};
I need the destructor to clean up any breakpoints set however the deconstructor is never called and I'm not quite sure why that is in my particular case.
Here's main.cpp:
BREAKPOINT_INFO instrMov;
//GetProcModuleHandle is a function I made to get the handle of a
//of a module in a remote process
LPVOID lpServerDll = (LPVOID)GetProcModuleHandle(dwPid, szServerDll);
//the instructions address is relative to the starting address of the server dll. Hence the offset.
PCHAR lpInstr = (PCHAR)((DWORD)lpServerDll+instr_offset);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwPid);
//sets the breakpoint
instrMov.InitializeBreakPoint(hProcess, lpInstr);
while(1)
{
if(!instrMov.justCalled)
{
instrMov.SetBreakPoint();
}
if(instrMov.justCalled)
{
instrMov.justCalled = FALSE;
}
if(WaitForDebugEvent(&dbgEvent, 0))
{
ProcessDebugEvent(&dbgEvent, lpBreakPoints, 3);
ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE);
}
}
return 0; //<---never reaches return
It's a never ending loop so the program, at the moment, never actually reaches the return. It has to be terminated with either Ctrl+C or by closing the terminal. Not sure if this could be causing the destructor to not be called or not.
Any information, solutions, etc would be greatly appreciated. Thank you for your time.
you have to handle SIGINT signal, otherwise program is terminated abnormally and dtors are not called.

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;
}

Windows prevent multiple instances code not working

I am using CreateEvent to prevent multiple instances of my application:
CreateEvent(NULL, TRUE, FALSE, "MyEvent");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// Do Stuff
return FALSE;
}
However, at startup I have noticed that this doesn't work:
After the desktop is shown I automatically run a batch script that attempts to launch multiple instances of my program. The batch script succeeds and I can indeed see multiple instances.
Investigation so far:
OutputDebug shows that each instance does not get ERROR_ALREADY_EXISTS
ProcessExplorer.exe shows that each instance was able to get a handle to the event "MyEvent".
Can anybody think why this might be happening, and how I could solve it?
We use the function below, which is in our common utility DLL. The method is derived from a Microsoft article explaining how to prevent multiple instances in WIN32.
#define STRICT
#include <stdheaders.h>
HANDLE ghSem;
BOOL IExist( LPSTR lpszWindowClass )
{
HWND hWndMe;
int attempt;
for( attempt=0; attempt<2; attempt++ )
{
// Create or open a named semaphore.
ghSem = CreateSemaphore( NULL, 0, 1, lpszWindowClass );
// Close handle and return NULL if existing semaphore was opened.
if( (ghSem != NULL) &&
(GetLastError() == ERROR_ALREADY_EXISTS) )
{ // Someone has this semaphore open...
CloseHandle( ghSem );
ghSem = NULL;
hWndMe = FindWindow( lpszWindowClass, NULL );
if( hWndMe && IsWindow(hWndMe) )
{ // I found the guy, try to wake him up
if( SetForegroundWindow( hWndMe ) )
{ // Windows says we woke the other guy up
return TRUE;
}
}
Sleep(100); // Maybe the semaphore will go away like the window did...
}
else
{ // If new semaphore was created, return FALSE.
return FALSE;
}
}
// We never got the semaphore, so we must
// behave as if a previous instance exists
return TRUE;
}
Just do something like this in your WinMain:
if( IExist("MyWindowClass") )
{
return 1;
}
Of course, you could replace the return with whatever you need to do when you are not the first instance (such as activating the existing instance).

Check for Named Event

I have a process that creates a named event, using ::CreateEvent.
In my process, I want to check whether the event exists or not, but I don't want to create the event in case it doesn't exist.
How can I do it?
I can do it like this, but then the event will be created in case it doesn't exist:
HANDLE hEvent;
hEvent= ::CreateEvent(NULL, FALSE, FALSE, _T("MyEvent"));
if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
.......
}
OpenEvent does not create the event if it doesn't already exist, so your code already almost does what you want. You need to check the event handle for NULL before checking the error code:
HANDLE hEvent;
hEvent= ::OpenEvent(FALSE, FALSE, _T("MyEvent"));
if (!hEvent) // event does not already exist, or other problem
{
.......
}
CString csHandleName = "hEvent";
int nHandleinc(0);
HANDLE hHandleEvent = NULL;
while(!hHandleEvent)
{
csHandleName.Format("hEvent%d",nHandleinc);
hHandleEvent = CreateEvent(NULL,TRUE,false,csHandleName);
if (GetLastError() == ERROR_ALREADY_EXISTS )
{
CloseHandle( hHandleEvent );
hHandleEvent = NULL;
}
nHandleinc++;
}

How to catch quit message from another process?

I want to "listen" some other application and decide what to do when it has been terminated.
How?
Edit: The two programs are run on same computer, and i want to know when i close the other program. And then do action in the other program. I cant modify the other program code. I may or may not start the app B from app A. I could identify the app B by its full path to the exe.
As Abyx wrote, WaitForSingleObject (or possibly WaitForMulipleObjects) is the API function you need.
Create an event
Start a (worker) thread
Pass the event handle to the thread -> HANDLE1
Get handle for the process to be watched. See How can I get a process handle by its name in C++? -> HANDLE2
In your thread function call WaitForMulipleObjects and wait for the two handles.
If HANDLE2 fires, do whatever action you want... and possibly terminate the thread.
If HANDLE1 fires, leave the thread. This is for a graceful termination of your application: Before exiting the main (GUI) thread you set the event.
WaitForSingleObject(hProcess, INFINITE);
If you start yourself, the process which termination you want wait for, for example with respect of the CreateProcess, the waiting for the process end is very simple
WaitForSingleObject(pi.hProcess, INFINITE);
If the process, which termination you want wait for, is started before you should find the process id dwProcessId of the process and then do following
HANDLE hProcess = OpenProcess (SYNCHRONIZE, FALSE, dwProcessId);
WaitForSingleObject(hProcess, INFINITE);
The searching of the process id can be implemented in different ways depend on which information you know about the process and the knowledge how many instances of the process can be running simultaneously.
For example if you know the filename of the process which is currently running you can use EnumProcesses, OpenProcess and GetProcessImageFileName. Here is the corresponding code in a simplified form:
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <Psapi.h>
#include <shlwapi.h>
#pragma comment (lib, "Psapi.lib")
#pragma comment (lib, "shlwapi.lib")
int _tmain (int argc, LPCTSTR argv[])
{
DWORD arProcessIds[1024], cbNeeded, i, dwStatus;
HANDLE hProcess = NULL;
LPCTSTR pszProcessName = NULL;
if (argc != 2) {
_tprintf (TEXT("USAGE:\n")
TEXT(" \"%s\" ExeName\n\n")
TEXT("Examples:\n")
TEXT(" \"%s\" TaskMgr.exe\n"),
argv[0], argv[0]);
return 1; // error
}
pszProcessName = argv[1];
if (!EnumProcesses (arProcessIds, sizeof(arProcessIds), &cbNeeded)) {
// here shold be allocated array dynamically
return 1; // error
}
for (i = 0; i < cbNeeded/sizeof(DWORD); i++ ) {
if (arProcessIds[i] != 0) {
TCHAR szFileName[MAX_PATH];
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, arProcessIds[i]);
if (hProcess != NULL) {
dwStatus = GetProcessImageFileName (hProcess, szFileName, sizeof(szFileName)/sizeof(TCHAR));
if (dwStatus > 0 ) {
LPCTSTR pszFileName = PathFindFileName (szFileName);
//_tprintf(TEXT("Process: %s\n"),szFileName);
if (StrCmpI(pszFileName, pszProcessName) == 0) {
break;
}
}
CloseHandle (hProcess);
hProcess = NULL;
}
}
}
//hProcess = OpenProcess (SYNCHRONIZE, FALSE, dwProcessId);
if (hProcess == NULL) {
_tprintf(TEXT("The process \"%s\" is not found.\n"), pszProcessName);
return 1;
}
_tprintf(TEXT("Start waiting for the end of the process %s\n"), pszProcessName);
WaitForSingleObject(hProcess, INFINITE);
_tprintf(TEXT("The process is terminated"));
CloseHandle (hProcess);
return 0;
}
you can just get the process list from OS in intervals you want and take appropriate action