Why would WaitForSingleObject return WAIT_FAILED - windows

MSDN says
If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError.
The code is:
HANDLE m_mutex_handle; /**< m_mutex_handle. The handle to the created mutex. */
m_mutex_handle = ::CreateMutex( 0, false, NULL );
::WaitForSingleObject( m_mutex_handle, INFINITE );
But what are the reasons that could happen?

If you lack the SYNCHRONIZE privilege on the object, then you cannot wait. WAIT_FAILED will be returned.

Passing in a bogus object might cause that.

Closing a handle while the handle is being waited on can also cause undefined behaviour.

I got WAIT_FAILED from WaitForMultipleObjects when passing in an array of thread handles as one of them was a pseudo handle. As ever the immortal Raymond Chen explained, and provided the fix: https://devblogs.microsoft.com/oldnewthing/20141015-00/?p=43843

Related

How to use setevent to stop process handler

I'm trying to createProcess then inherit process handle to event handle
HANDLE app_event;
TCHAR* path = L"C:\\My.exe";
STARTUPINFO info;
PROCESS_INFORMATION processInfo;
ZeroMemory(&info, sizeof(info));
info.cb = sizeof(info);
ZeroMemory(&processInfo, sizeof(processInfo));
CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
ThreadId = processInfo.dwThreadId;
app_event = CreateEventW(nullptr, TRUE, FALSE, nullptr);
DuplicateHandle(GetCurrentProcess(), processInfo.hProcess,
GetCurrentProcess(),
&app_event,
0, FALSE,
DUPLICATE_SAME_ACCESS);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
and I'm creating thread for event
But when I call setEvent to stop process
The process don't stop and i got stuck at WaitForSingleObject
SetEvent(app_event);
WaitForSingleObject(app_thread, INFINITE);
Am I doing something wrong?
Sorry I'm new to C++.
DuplicateHandle doesn't do what you think it does. It makes a new handle to an existing object. You seem to think it can be used to turn an object of one type into an object of another type. It cannot. A process handle cannot become an event handle.
This mis-understanding is compounded by your code's lack of error checking. The Win32 API won't raise exceptions. Errors are signaled by way of the API function return values. Which you ignore, unfortunately.
What you seem to be doing is trying to terminate a process in a co-operative manner. Signal an event to indicate termination is required. Then wait for the process to stop. That only works if the other process co-operates. There's no indication that is the case for you. You certainly cannot inject a termination event into the other process.
If the other process doesn't have a documented way to be signaled for termination then the best you can do is call TerminateProcess. If you are in control of the other process then you can agree on a co-operative procedure for termination. Use a named event that both process can gain access to.
I would like to repeat my main advice one more time. Always check for errors when calling Win32 functions. There's no one single way to do that, you must read the documentation carefully for each and every function that you call.

Correct return value of "WindowProc" in a Win32 application

In MSDN's Win32-Api documentation (at http://msdn.microsoft.com/en-us/library/ms633573%28VS.85%29.aspx) on the WindowProc, it states: The return value is the result of the message processing and depends on the message sent.
Since I have to implement this (callback) procedure, I'd like to know what it depends on, and what I have to return. Can someone shed some light on this?
It is dependent on the exact message you are processing. You need to refer to the documentation for that message to see the expected values and meanings of the return value.
For instance, for WM_CREATE, you should return zero to continue window creation, and -1 to fail and destroy the window. For WM_GETICON, you should return a handle to the icon for your window.
For messages that you do not explictly handle, you should call DefWindowProc, passing to it all the parameters to your window proc, and return its return value to the caller.
Michael's answer answers the question perfectly, but just for reference, the usual return value will always be 0.
For most messages it means that your application has processed the message. But always consult the MSDN page for the actual message to know for sure.

Using event object in inter-process

I'm trying to use event object in win32 environment to synchronize two processes. Below are the simplified code of two programs.
// process1
int main()
{
HANDLE h = CreateEvent(NULL, FALSE, FALSE, TEXT("Hello"));
WaitForSingleObject(h, INFINITE);
// RunProcess(L"process2.exe", L"");
}
// process2
int main()
{
HANDLE h = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Hello"));
SetEvent(h);
}
It's quite simple, and works well when two processes are launched independently. However it does not work when the process 1 launches process 2 as a child process (which is commented in the above code) - the SetEvent call fails. What is the reason and solution of this problem?
Your code needs to check and handle errors. Both CreateEvent and OpenEvent will return NULL if they fail, in that case you need to check the error using GetLastError.
Your calls to WaitForSingleObject and SetEvent should be checked per the MSDN docs as well.
The order in which you need to do things in the parent process is:
CreateEvent
Start child process
WaitForSingleObject.
Otherwise you will hit the problem called out by #Mark Tolonen.
It would also be best to have a timeout on your wait, to handle the case where the child process fails to start, exits unexpectedly, or hangs.
An alternative approach if you intend to use this parent/child relationship would be to allow inheritance of the event handle. Then the event does not need to be named, and nobody else can 'squat' on it in a DoS attack on your apps. You can pass the handle value to the child as a command-line parameter. You do this using the bInheritHandle field on the eventAttributes parameter to CreateEvent.
A Boolean value that specifies whether
the returned handle is inherited when
a new process is created. If this
member is TRUE, the new process
inherits the handle.
Are you sure? As written, if process1 creates process2 in the current location, it will never create process2 because it will wait forever for the event to be fired. Create process2 first, then wait for the event to be set.
You have a NULL security descriptor, which the documentation says cannot allow the handle to be inherited by children processes, specifically:
If this parameter is NULL, the handle cannot be inherited by child processes
Maybe you need to create a proper security descriptor?

Can somebody explain this remark in the MSDN CreateMutex() documentation about the bInitialOwner flag?

The MSDN CreatMutex() documentation (http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx) contains the following remark near the end:
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. When using this technique, you should set the bInitialOwner flag to FALSE; otherwise, it can be difficult to be certain which process has initial ownership.
Can somebody explain the problem with using bInitialOwner = TRUE?
Earlier in the same documentation it suggests a call to GetLastError() will allow you to determine whether a call to CreateMutex() created the mutex or just returned a new handle to an existing mutex:
Return Value
If the function succeeds, the return value is a handle to the newly created mutex object.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
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, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
Using bInitialOwner combines two steps into one: creating the mutex and acquiring the mutex. If multiple people can be creating the mutex at once, the first step can fail while the second step can succeed.
As the other answerers mentioned, this isn't strictly a problem, since you'll get ERROR_ALREADY_EXISTS if someone else creates it first. But then you have to differentiate between the cases of "failed to create or find the mutex" and "failed to acquire the mutex; try again later" just by using the error code. It'll make your code hard to read and easier to screw up.
In contrast, when bInitialOwner is FALSE, the flow is much simpler:
result = create mutex()
if result == error:
// die
result = try to acquire mutex()
if result == error:
// try again later
else:
// it worked!
Well, not sure if there's a real problem. But if you set the argument to TRUE in both processes then you have to check the value of GetLastError() to check if you actually ended up having ownership. It will be first-come-first serve. Useful perhaps only if you use a named mutex to implement a singleton process instance.
The flag is used to create the mutex in an owned state - the successful caller will atomically create the synchronisation object and also acquire the lock before returning in the case that the caller needs to be certain that no race condition can form between creating the object and acquiring it.
Your protocol will determine whether you ever need to do this in one atomic operation.

GetLastError returning ERROR_SUCCESS after calling ConnectNamedPipe

When I call ConnectNamedPipe with an OVERLAPPED structure and check GetLastError afterwards, I often see GetLastError return ERROR_SUCCESS. The way I'm reading the documentation, that should never happen. My understanding is that if a client has already connected, ERROR_PIPE_CONNECTED should be set, not ERROR_SUCCESS.
Has anyone else seen this? The OS is 32-bit Windows 7.
That's typical for OVERLAPPED. It tells whether the parameters are okay before connecting, assuming an asynchronous socket. Once a connection completes or fails, then GetOverlappedResult() returns the proper status. So I guess this is a minor documentation error.
Try calling GetLastError() immediately after ConnectNamedPipe.
Don't call any API in between.

Resources