Check for Named Event - c++

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

Related

When i use CloseHandle(); why is Event still visible/running

I believe that calling CloseHandle() only closes the reference made to the handle? But the Event is still visible in Process Explorer, and the desired functionality isn't met.
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (stricmp(entry.szExeFile, "program.exe") == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
HANDLE hEvent = OpenEventA(EVENT_ALL_ACCESS,FALSE,"openEvent");
// Do stuff..
int sucess = CloseHandle(hEvent);
}
}
count = 0;
}
CloseHandle(snapshot);
Is there something I'm doing wrong? Why would the Event still be visible in Process Explorer?
Kernel objects are reference counted. Calling CloseHandle decrements the reference count, but the referenced object doesn't get removed, until the final handle to it gets closed.
In the code for OpenEventA to return a non-NULL value, the event referenced by name must already exist (i.e. its reference count must be at least 1). OpenEventA increments the reference count, and CloseHandle decrements it, but it's still at least 1 (unless the other handles to that event object have been closed).
Consequently the event object doesn't get closed, and Process Explorer rightfully reports that the event object still exists.

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).

AssignProcessToJobObject Failing The Handle is Invalid

Im creating a job with CreateJobObjectA(), then creating a new process with CreateProcessA(), and when I try to assign the new process to the job I have created with AssignProcessToJobObject() it returns 0. So I GetLastError() and im getting a value of 6. Which according to Windows systems error code means The Handle is invalid. Heres my code.
HANDLE job = CreateJobObjectA( NULL, "jobName" );
if( job == NULL )
{
printf( "Job is NULL" );
}
else
{
JOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if( 0 == SetInformationJobObject( job, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
printf("Could not SetInformationJobObject\n");
}
}
if( CreateProcessA( "C:\\Windows\\SysWOW64\\cmd.exe", "/c server.bat", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
printf("CreateProcess succeeded.\n");
if( job != NULL )
{
HANDLE derp = processInfo.hProcess;
if( derp != NULL )
{
if( 0 == AssignProcessToJobObject( job, derp ))
{
printf("Could not AssignProcessToObject\n");
DWORD err = GetLastError();
printf("derp");
}
}
}
//Can we free handles now? Not sure about this.
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
The bat file is doing what it is supposed to be doing and launching a jar that runs a server. I just dont get how my Handle is invalid. Any help would be amazing. Or possibly a different way to do this?
I want to launch this new process and have it be a child process so when my main process crashes the server closes also.
Thank you.
You've got a race condition. If cmd.exe exits before you call AssignProcessToJobObject it won't work (I'm not sure what error code you get in that scenario).
Start the process suspended using the CREATE_SUSPENDED flag and don't resume it until you've already assigned it to the job.

ReadDirectoryChangesW issues

I'am using ReadDirectoryChangesW to watch a directory changes asynchronously, based on this question I implement a function that watch a given directory, but I still get the error message GetQueuedCompletionStatus(): Timeout
void Filewatcher::OpenWatchDir(QString PathToOpen)
{
QString path=QDir::fromNativeSeparators(PathToOpen);
LPCTSTR Dirname=(LPCTSTR)path.utf16();//.toStdWString().c_str();
dirinfo_t* d =(dirinfo_t*) malloc(1*sizeof(dirinfo_t));
d->CompletionKey = (ULONG_PTR)&somekey;
dirinfo_init(d);
/* set up */
runthread = TRUE;
d->hDirFH = CreateFile(Dirname,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
d->hDirOPPort = CreateIoCompletionPort(d->hDirFH, NULL,
(ULONG_PTR)d->CompletionKey, 1);
DWORD errorcode = 0; // an error code
BOOL bResultQ = FALSE; // obvios=us
BOOL bResultR = FALSE;
DWORD NumBytes = 0;
FILE_NOTIFY_INFORMATION* pInfo = NULL; // the data incoming is a pointer
// to this struct.
int i = 0;
while ( runthread )
{
bResultR = ReadDirectoryChangesW(d->hDirFH, (void*)d->buffer,
16777216, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION ,
NULL,
&d->o->overlapped,
NULL );
bResultQ = GetQueuedCompletionStatus(d->hDirOPPort,
&NumBytes, &(d->CompletionKey),
(LPOVERLAPPED*)(d->o), 1000);
if ( bResultQ && bResultR )
{
wprintf(L"\n");
pInfo = (FILE_NOTIFY_INFORMATION*) d->buffer;
wprintf(L"File %s", pInfo->FileName);
wprintf(L" changes %d\n", pInfo->Action);
qDebug()<<"file "<<pInfo->FileName<<" was"<<pInfo->Action;
memset(d->buffer, 0, 16777216);
}
else
{
errorcode = GetLastError();
if ( errorcode == WAIT_TIMEOUT )
{
qDebug()<<"GetQueuedCompletionStatus(): Timeout\n";
}
else
{
qDebug()<<"GetQueuedCompletionStatus(): Failed\n";
qDebug()<<"Error Code "<<errorcode;
}
Sleep(500);
}
}
}
I need to know how use ReadDirectoryChangesW asynchronously with IoCompletionPort.
Any help please.
There's no reason to use a completion port here, simple overlapped I/O with an event will work fabulously.
The key is to wait for this operation (whether event or completion port) at the same time as all other events (possibly including GUI messages), and only check the status when the event becomes signaled. For that, use (Msg)WaitForMultipleObjects(Ex).
In Qt, you can add Win32 events (used by OVERLAPPED structure for async I/O) using QWinEventNotifier as described here:
http://www.downtowndougbrown.com/2010/07/adding-windows-event-objects-to-a-qt-event-loop/
thank you guys for your answers, after a deep research and retesting code I solve my problem based on this , I really appreciate your help.

Check for CWinApp existence

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