CreateMutex never returns ERROR_ALREADY_EXISTS - c++

I am using CreateMutex to stop multiple application to run certain functions at the same time. These functions are in dll so can be called over by same application or separate applictions. This dll talks to hardware so I want to return 'busy' if another function is already running rather than have to wait on it. I thought best approach is to use CreateMutex instead combination of OpenMutex.
int FunctionExposedByDll()
{
hMutexAPI = CreateMutex(0, 0, API_RUNNING_MUTEXT );
if (!hMutexAPI )
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_ALREADY_EXISTS )
return MY_ERROR_BUSY;
}
// actual function here
CloseHandle( hMutexAPI );
}
So if the mutex is already created, I should get ERROR_ALREADY_EXISTS which tells me system is executing an api and I should return. However the above code always return a valid mutex even if the prior function has not returned and mutex handle is not closed.
I also tried CreateMutexEx function and in that case when I try it the 2nd time it returns ERROR_ACCESS_DENIED when I am expecting ERROR_ALREADY_EXISTS. So my question is what do I need to do to get correct status that mutex already exist when it exist?
I am using windows 7
**Update**
Based on Rob K answer, I have changed the code to following:
int FunctionExposedByDll()
{
hMutexAPI = CreateMutex(0, 0, API_RUNNING_MUTEXT );
DWORD dwErr = GetLastError();
if (dwErr == ERROR_ALREADY_EXISTS )
{
CloseHandle( hMutexAPI); // i have to call this but it contributes to first chance exception too!
return MY_ERROR_BUSY;
}
// actual function here
CloseHandle( hMutexAPI );
}
Now I am getting/reading the correct status of semaphore but releasing is an issue. If I don't release it when its in 'busy state', than I always get the ERROR_ALREADY_EXISTS even when the other API has finished. So CloseHandle() fixes that but creates another issue. When I return and close CloseHandle()from busy state and the first API completes later and want to close the handle, I get first chance exception. I don't see how can I avoid that!?

That's not the correct way to use CreateMutex(). CreateMutex() (almost) always succeeds in returning a valid handle to a mutex. From the MSDN doc which you linked: "If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS..."
Quoting again: "Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes with sufficient access rights simply open a handle to the existing mutex. This enables multiple processes to get handles of the same mutex, while relieving the user of the responsibility of ensuring that the creating process is started first."
What you want to do is use CreateMutex() to open a handle to the mutex, and then use WaitForSingleObject() with a timeout value of 0 to try to take it. If the WaitForSingleObject() fails to take the mutex, then you return MY_ERROR_BUSY. If it does succeed to take the mutex, call ReleaseMutex() when you are done using it to unlock it.
ETA:
If WaitForSingleObject returns WAIT_OBJECT_0 or WAIT_ABANDONED, then you own the mutex (e.g. it becomes signalled) and you must call ReleaseMutex to give-up ownership (e.g. unsignal it) before calling CloseHandle.
If it returns WAIT_TIMEOUT, you do not own the mutex, and you can just call CloseHandle.
int FunctionExposedByDll()
{
HANDLE hMutexAPI = CreateMutex(0, 0, API_RUNNING_MUTEXT );
int rval = MY_ERROR_BUSY;
if ( hMutexAPI )
{
DWORD wait_success = WaitForSingleObject( hMutexAPI, 0 );
if ( wait_success == WAIT_OBJECT_0 || wait_success == WAIT_ABANDONED )
{
// actual function here
ReleaseMutex( hMutexAPI );
rval = SUCCESS_VALUE;
}
CloseHandle( hMutexAPI );
}
return rval;
}
You should take some time to get more familiar with the basic interprocess communication primitives, starting here: http://en.wikipedia.org/wiki/Mutex
ETA once more
I figured C++ 11 may have added the IPC primitives to the standard library, and it appears they have:
http://en.cppreference.com/w/cpp/thread/mutex,
http://en.cppreference.com/w/cpp/thread/lock_guard
If you're using a C++11 capable compiler (e.g. Visual Studio 2013), please use these instead of the system primitives.
And one more edit...
As pointed out in a comment, the C++ standard library primitives are not usable for interprocess communication, only for synchronizing threads in the same process. (This is a great disappointment.)
Instead, use Boost.Interprocess if you can.

CreateMutex returns a valid handle anyway. That is, a test for !hMutexAPI fails and you never enter the clause.

Related

Use Win API to determine if an instance of an executable is already running

I need to ensure only 1 instance of my C++ application is running.
Using the Win API how do I;
retrieve the information about my current application?
GetCurrentProcess() will give me a HANDLE on my application, how do I retrieve information about it
retrieve a list of all running processes for the user?
EnumProcesses() gives a list, but appears to require a pre-allocated buffer, so how do I find out how many processes are currently running?
I need to compare the exe name of my server to the running processes, and raise an error if I find more than one
Note: I cannot use any boost libraries, and I am not interested in using a mutex, seen on similar posts.
You can use the CreateMutex function to create a system-wide named mutex to denote whether your process is running. It will return ERROR_ALREADY_EXISTS if the process is already running:
(void)::CreateMutex( NULL,
TRUE,
TEXT( "My_Special_Invokation_Test_Mutex" ) );
switch ( ::GetLastError() ) {
case ERROR_SUCCESS:
// Process was not running already
break;
case ERROR_ALREADY_EXISTS:
// Process is running already
break;
default:
// Error occured, not sure whether process is running already.
break;
}
Now, if you insist on not using a mutex, you can use the CreateFile function instead. Make sure to pass zero for the dwShareMode field to get exclusive access semantics, CREATE_NEW for the dwCreationDisposition field (so that you create the file only if it doesn't exist already) and FILE_FLAG_DELETE_ON_CLOSE for the dwFlagsAndAttributes argument so that the file gets deleted once your process is terminated. Something like this:
LPCTSTR lockFileName = ...;
(void)::CreateFile( lockFileName,
GENERIC_READ,
0,
NULL,
CREATE_NEW,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
switch ( ::GetLastError() ) {
case ERROR_SUCCESS:
// Process was not running already
break;
case ERROR_FILE_EXISTS:
// Process is running already
break;
default:
// Error occured, not sure whether process is running already.
break;
}
See this article about Temporary file generation and usage best practices about how to deal with temporary files safely.
To make a long story short, it's certainly possible to use lock files for your task, but I think it's harder to do it right.
Updated version of Nawaz's answer:-
Handle mutex = CreateMutex (0, 0, "SomeUniqueName");
switch (GetLastError ())
{
case ERROR_ALREADY_EXISTS:
// app already running
break;
case ERROR_SUCCESS:
// first instance
break;
default:
// who knows what happened!
break;
}
This does have a security issue, a malicious application could create a mutex called "SomeUniqueName" before your app starts, which would then prevent your app from being run. To counter this, you can name the mutex based on a hash of some constant system parameter (the MAC address for example). The MSDN documentation has this to say about single instance applications:
If you are using a named mutex to limit your application to a single instance, a malicious user can create this mutex before you do and prevent your application from starting. To prevent this situation, create a randomly named mutex and store the name so that it can only be obtained by an authorized user. Alternatively, you can use a file for this purpose. To limit your application to one instance per user, create a locked file in the user's profile directory.
Since mutex isn't desired, you can for example use a file mapping instead. The documentation to CreateFilemapping says:
If the object exists before the function call, the function returns a handle to the existing object (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
If the function fails, the return value is NULL.
This leads to the following no-mutex implementation:
Handle h = CreateFileMapping(0, 0, PAGE_READONLY, 0, 4096, name);
bool already_running = !!h && (GetLastError() == ERROR_ALREADY_EXISTS);
Either the call succeeds and the mapping already exists, then another process is already running.
Or, a new mapping is created, or the call fails. In either case, no other process is already running. If the call fails, it almost certainly failed for any other process that may have tried before as well. Since once a call was successful, the mapping already exists, the only possible reason why two identical calls could succeed once and then fail would be "no more handles left", and that just doesn't (well, shouldn't) happen. Anyway, if this does happen, you have a much more serious problem elsewhere.
That thing probably works with every type of named kernel object you pick (i.e. every type of kernel object that has both a Create and an Open version).
A file mapping object has the advantage that if you also want to do IPC (say, forward your commandline to the already running instance, and then exit), then you already have a mapping that you can use (though sure enough a pipe would do mighty fine as well).
But otherwise, I don't see how this (or any other solution) is superior to using the mutex approach in any way. Really, why not use a mutex? It's what they're for.

Is there any way GetExitCodeProcess could set the exit code to the wrong value?

I'm maintaining code written by someone just before they retired, which means I can't find them to ask questions. :-) This is basically a C++ wrapper to launch a program. The chunk of code in question is this:
BOOL bSuccess = CreateProcess(NULL, (char *)strBatFile.c_str(),
NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, strLocalWorkingDir.c_str(), &si, &pi );
if( bSuccess )
{
DWORD dwMillisec = INFINITE;
DWORD dwWaitStatus = WaitForSingleObject( pi.hProcess, dwMillisec );
if( dwWaitStatus == WAIT_OBJECT_0 )
{
DWORD dwExitCode = NULL;
GetExitCodeProcess( pi.hProcess, &dwExitCode );
nRet = (int)dwExitCode;
}
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
else
nRet = START_PROCESS_FAILED;
If just one instance is run at a time, it always works fine. If multiple are run within a very short time frame, though, about half of them are having dwExitCode set to 1 instead of 0, even though the process isn't crashing, and the log file that internal program writes is completing.
So to clarify, the process is always starting fine, and it's always getting into the if statements, but it's the value of dwExitCode set by GetExitCodeProcess that isn't containing what's expected. Since we error check on this, we're flagging a bunch of these runs as incomplete when they in fact are fine.
Is there any way this value could be set to something different than the process exit code? And/or is there a utility I could run at the same time to confirm the exit codes are what I think they are?
Thanks!
ETA: Just realised this is putting the internal program call in a .bat file - "C:\\ --flags etc..." and then calling that as a command line in the second argument, rather than just calling it directly using lpApplicationName. No idea if this makes a difference! But when I print the PID of the process, I can see it's the PID for a cmd.exe process, and then our program has a child PID. However, when I trace in Process Monitor, I can see that both parent and child are exiting with exit code 0.
Found it! The application itself was in fact returning a 0 error code...it was the shell around it that was returning 1. And that was due to that .bat file in the second argument. The name was being generated from time, so it ended up being exactly the same name if multiple instances were run too closely together. This is why the inner app would run fine...there was always a bat file there with that name. But there were access collisions when the different instances were trying to generate or clean up the bat, from what I can tell.
As a proof-of-concept hack I just added the current PID to the end of the file name, and everything worked perfectly. Now I just need to decide the real fix, which I think will likely be getting rid of the whole bat file mechanism entirely and calling the app directly.
Whew! Thanks for all the help, everyone! Sadly, the bit of code I included didn't have the offending line, but everyone's tips above helped me narrow in on the problem. :-)

GetThreadContext via DuplicateHandle?

I am trying to open process duplicate handles and query information from thread handles using GetThreadContext but i get error ERROR_INVALID_HANDLE or ERROR_GEN_FAILURE. Information about this seems very limited....
processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)
DuplicateHandle(processHandle,handle.Handle,GetCurrentProcess(),&dupHandle,0,FALSE,DUPLICATE_SAME_ACCESS);
memset(&ctx,0x00,sizeof(ctx));
GetThreadContext(dupHandle,&ctx);
printf("Error:%x", GetLastError());
Anyone ?
First of all, as suggested above you should be passing thread handle as the argument, and not process handle.
Then, what part of CONTEXT structure you request to be filled by GetThreadContext API? You leave zero there and there should be 1+ flags to indicate data of interest:
CONTEXT ThreadContext = { CONTEXT_CONTROL };
if(GetThreadContext(ThreadHandle, &ThreadContext)) {
// ...
See also code snippet at https://stackoverflow.com/a/199809/868014
GetThreadContext takes a thread handle not a process handle.

How to check if a HANDLE is valid or not?

In C++, I have opened a serial port that has a HANDLE. Since the port may close by an external application, how can I verify that the HANDLE is still valid before reading data?
I think it can be done by checking the HANDLE against a suitable API function, but which?
Thank you.
Checking to see whether a handle is "valid" is a mistake. You need to have a better way of dealing with this.
The problem is that once a handle has been closed, the same handle value can be generated by a new open of something different, and your test might say the handle is valid, but you are not operating on the file you think you are.
For example, consider this sequence:
Handle is opened, actual value is 0x1234
Handle is used and the value is passed around
Handle is closed.
Some other part of the program opens a file, gets handle value 0x1234
The original handle value is "checked for validity", and passes.
The handle is used, operating on the wrong file.
So, if it is your process, you need to keep track of which handles are valid and which ones are not. If you got the handle from some other process, it will have been put into your process using DuplicateHandle(). In that case, you should manage the lifetime of the handle and the source process shouldn't do that for you. If your handles are being closed from another process, I assume that you are the one doing that, and you need to deal with the book keeping.
Some WinAPI functions return meaningless ERROR_INVALID_PARAMETER even if valid handles are passed to them, so there is a real use case to check handles for validity.
GetHandleInformation function does the job:
http://msdn.microsoft.com/en-us/library/ms724329%28v=vs.85%29.aspx
as the port may close by a external application
This is not possible, an external application cannot obtain the proper handle value to pass to CloseHandle(). Once you have the port opened, any other process trying to get a handle to the port will get AccessDenied.
That said, there's crapware out there that hacks around this restriction by having secret knowledge of the undocumented kernel structures that stores handles for a process. You are powerless against them, don't make the mistake of taking on this battle by doing the same. You will lose. If a customer complains about this then give them my doctor's advice: "if it hurts then don't do it".
If you are given a HANDLE and simply want to find out whether it is indeed an open file handle, there is the Windows API function GetFileInformationByHandle for that.
Depending on the permissions your handle grants you for the file, you can also try to move the file pointer using SetFilePointer, read some data from it using ReadFile, or perform a null write operation using WriteFile with nNumberOfBytesToWrite set to 0.
Probably you are under windows and using ReadFile to read the data. The only way to check it is trying to read. If the HANDLE is invalid it'll return an error code (use GetLastEror() to see which one it is) which will probably be ERROR_HANDLE_INVALID.
I know that it's a little bit late but I had a similar question to you, how to check if a pipe (a pipe I created using CreateFile) is still open (maybe the other end shut down the connection) and can read, and if it is not, to open it again. I did what #Felix Dombek suggested, and I used the WriteFile to check the connection. If it returned 1 it means the pipe is open, else I opened it using the CreateFile again. This implies that your pipe is duplex. Here's the CreateFile:
hPipe2 = CreateFile(lpszPipename2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
and here is how I checked for the connection:
while(1)
{
bool MessageSent = WriteFile(hPipe2, "Test", 0, &cbWritten, NULL);
if (!(MessageSent))
{
LogsOut("Read pipe has been disconnected");
//Call method to start the pipe again
break;
}
Sleep(200); // I need this because it is a thread
}
This is working just fine for me :)
You can use DuplicateHandle to test handle validity.
First method: You can try to duplicate the handle you want to check on validity. Basically, invalid handles can not be duplicated.
Second method: The DuplicateHandle function does search the Win32 handle descriptor table from beginning for an empty record to reuse it and so assign into it a duplicated handle. You can just test the duplicated handle address value on value greater than yours handle address and if it is greater, then the handle is not treated as invalid and so is not reused. But this method is very specific and limited, and it does only work, when there is no more empty or invalid handle records above the handle value address you want to test.
But all this just said above is valid only if you track all handles creation and duplication on your side.
Examples for Windows 7:
Method #1
// check stdin on validity
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}
Method #2
// Assume `0x03` address has a valid stdin handle, then the `0x07` address can be tested on validity (in Windows 7 basically stdin=0x03, stdout=0x07, stderr=0x0b).
// So you can duplicate `0x03` to test `0x07`.
bool is_stdout_handle_default_address_valid = false;
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), (HANDLE)0x03, GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
if (stdin_handle_dup > (HANDLE)0x07) {
is_stdout_handle_default_address_valid = true; // duplicated into address higher than 0x07, so 0x07 contains a valid handle
}
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}
In order to check the handle , first we need to know what is our HANDLE for, (for a File/Port/Window, ...), Then find an appropriate function to check it (thanks #janm for help). Note that the function's duty may be specially for this destination or not. In my case that iv'e opened a Serial port by CreateFile() , i can check the COM status by GetCommState() API function that fills our COM info struct. If the port is not open anymore or inaccessible the function returns 0 and if you call GetLastError() immediately, you`ll get the ERROR_INVALID_HANDLE value. Thanks everyone for helps.

How to Compare Two variable of HANDLE type

I have a variable of HANDLE type.
First HANDLE variable is a process HANDLE (with name hProcess) that does not have PROCESS_QUERY_INFORMATION access right.
Second variable is a process HANDLE (with name hwndProcess) too that I have opened via OpenProcess function and have PROCESS_QUERY_INFORMATION access right. I am sure both processes should have same handle.
But when i compare them as below, it returns false;
if (hProcess==hwndProcess) {do something}
How shall I do it?
There is not an explicit way to check whether two handles refer to the same process. The only way would be to query the process information and check that, e.g. using GetProcessId on each handle to check the process IDs.
If you don't have the necessary access rights to call the desired query functions then you can try calling DuplicateHandle to get a new handle with more access rights. However, if this fails then you have no way of telling whether the handles are to the same process or not.
hProcess must not hold the ProcessHandle of the Process that will be closed. It can and will most times be NULL. I'm doing something similar to get the PIDs of terminated processes.
if((hProcess == NULL) || (hProcess == GetCurrentProcess())){
pid = GetCurrentProcessId();
} else {
pid = ProcessHandleToId(hProcess);
}
Are your sure, that it's an access rights problem and your function doesn't fail, because the handle is NULL?
The Windows 10 SDK has CompareObjectHandles(HANDLE, HANDLE) which returns TRUE if the handles refer to the same underlying kernel object.
And you don't have to worry about access rights.