Is there any Win32 API to check if a given handle belongs to the current process?
From a window handle you can use GetWindowThreadProcessId Function to get process id.
From a process handle you get the id with GetProcessId Function.
I don't know how easy is to get a process handle from some other handle. But I believe it'll have to do with kernel objects enumeration.
A handle can "belong" to more than one process (Inherited handles in child process etc)
Related
I am developing a Windows console application in C++. I need my program to do some operations on another process which I don't have any control over.
But, I have some doubts about a case where the target process might get terminated for some reason (by Task Manager, etc). Is it safe to use a handle to a process which is already terminated?
Note : I stop my operations if one of the functions fails.
HANDLE hProcess = OpenProcess(pid);
if( hProcess != NULL )
{
// Lets suppose process is terminated here
/* Some operations on process using returned handle*/
}
Kernel objects in Windows are reference-counted, with references being represented as handles to objects. Client code can create kernel objects and receive an initial reference (e.g. CreateProcess), increment the reference count on an existing object (e.g. OpenProcess, or DuplicateHandle), and decrement the reference count (CloseHandle). As long as you hold on to a HANDLE, the object referenced by that HANDLE is kept alive.
In case of a process object, that object is valid at least as long as you hold a reference (HANDLE) to it. The fact that a process has been terminated is observable, but doesn't otherwise invalidate or destroy the process object if there are any outstanding references to it.
Specifically this means that you can perform any operations you'd do with a "live" process (one for which the OS is still scheduling threads to execute), such as WaitForSingleObject. In addition you can call GetExitCodeProcess and that call won't return STILL_ACTIVE.
Barring a call to CloseHandle, you are now a stakeholder that has a say in the demise of the process object. It won't go away unless you sign it off. A corollary of this is that you now also control the validity of the PID. It's tied to the process' lifetime, and as long as you hold a reference to it by way of a HANDLE, that PID won't get reused for another process.
In summary, as long as you hold on to a (process) HANDLE you can do whatever.
I have two applications. Both of them use the same resources. Lets call these resources "profile resources". Application B cannot be started up until Application A shutsdown. So I have app A running and was trying to shut it down, then launch up with app B path. I explored RegisterApplicationRestart but I could not accomplish it. Is this possible to be done? I'm getting stuck at the point where Application A is shutdown, then I cant run any code to launch back App B.
A can launch B using CreateProcess() before exiting, passing its own process handle to B. Before B accesses the resource, it can wait on A's handle using WaitForSingleObject() or related function. When the handle is signaled, A has fully terminated, so B can close the handle using CloseHandle() and move on as needed.
To pass A's process handle to B, A can either:
open its own process handle using OpenProcess() with GetCurrentProcessId() as the process ID, mark the handle as inheritable using SetHandleInformation(), and then pass the handle value to B as a command-line parameter, setting the bInheritHandles parameter of CreateProcess() to TRUE.
Run B first and have it create an IPC listener (named pipe, mailslot, socket, etc), then A can duplicate its own process handle for B's use via DuplicateHandle() with GetCurrentProcess() as the source handle and B's process handle (from CreateProcess()) as the target process, then send the duplicate handle value to B via IPC.
A simpler technique is to have A pass its own process ID, rather than its process handle, to B as a command-line parameter, then B can use OpenProcess() to open A's process handle. Although this will usually work, it does have a small race condition - before B has a chance to open the process handle, A might terminate and the OS could reuse its process ID for a new unrelated process, thus B would get a handle to, and wait on, the wrong process.
I remember there was a way to do this, something similar to unix signals, but not so widely used. But can't remember the term. No events/mutexes are used: the thread is just interrupted at random place, the function is called and when it returns, the thread continues.
Windows has Asynchronous Procedure Calls which can call a function in the context of a specific thread. APC's do not just interrupt a thread at a random place (that would be dangerous - the thread could be in the middle of writing to a file or obtaining a lock or in Kernel mode). Instead an APC will be dispatched when the calling thread enters an alterable wait by calling a specific function (See the APC documentation).
If the reason that you need to call code in a specific thread is because you are interacting with the user interface, it would be more direct to send or post a window message to the window handle that you want to update. Window messages are always processed in the thread that created the window.
you can search RtlRemoteCall, it's an undocumented routine though. there's APC in Windows semantically similar to Unix signal, however APC requires target thread is in an alertable state to get delivered, it's not guaranteed this condition is always met
I wish to launch a separate thread for handling window messages (via a blocking GetMessage loop), but still create the windows in the initial thread, afterward.
Within the separate thread, as soon as it launches, I am calling PeekMessage with PM_NOREMOVE to ensure a message queue exists (is this necessary?), followed by..
AttachThreadInput(initial thread id,GetCurrentThreadId(),true)
..before finally entering the message loop
I am not yet using a mutex or cs to ensure this is happening in time, but am merely using a Sleep statement in my initial thread for the sake of simplicity.
Regardless, window messages do not appear to be intercepted by the separate thread.
I am a little unsure as to whether I am doing this correctly, and would appreciate any possible guidance. Both threads are in the same process
Thank you all
That's not what AttachThreadInput does. Even after you attach your input queue to another thread, Windows still have thread affinity. Messages in the queue for a given window can only be removed from the queue by that window's thread.
What AttachTheadInput does is to make two threads share an input queue. This allows them to query information about the input state and know that the other thread will get the same answer for the same query. For instance, one thread could call GetAsyncKeyState and know that the answer reflected the key state for the other thread.
It allows two or more threads to have the same relationship to the input queue and each other as processes had in Windows 3x. This is the reason that this API exists; so that complex multiprocess applications could be ported from Win 3x to Win95/WinNT.
It seems the best way to instigate window creation from the main thread, while having messages for them handled in a separate, looping thread is to use a custom message, that can be sent to the separate thread - Thus allowing it to create the window, but still allowing that action to be invoked from the initial thread:
1) Allocate a custom message, and create a structure to hold the window initialisation parameters:
message_create_window = WM_USER + 0;
class Message_create_window{
Message_create_window(...);
};
2) Instead of calling CreateWindow(Ex), use something similiar to the following, passing in the relavant window creation parameters:
PostThreadMessage(
thread.id,
message_create_window,
new Message_create_window(...),
0
);
3) Handle the custom message in the message pump of your ui handling thread, extract the creation parameters, & free afterwards:
MSG msg;
GetMessage(&msg,0,0,0);
...
switch(msg->message){
...
case message_create_window:{
Message_create_window *data=msg->wParam;
CreateWindowEx(data->...);
delete data;
}break;
...
This does, however, have the following side-effects:
The window will be created asynchronously. If it is required that the initial thread block until the window is created (or, indeed, that the window's existence can ever be asserted) then a thread synchronisation tool must be used (such as an event)
Care should be taken when interacting with the window (it is a multithreaded application, after all)
If there are any major holes in this answer, or this seems like a terrible approach, please correct me.
(This is still my question, & I am trying to find the best way to accomplish this)
I note an applications handle when I use the shell function to open it.
I then use that handle to close the application later.
However the user can also close that other application himself.
Can that handle then be reused by windows so that when I use that handle I close a different process.
If it is possible is it likely?
No, you don't have to worry about it. The handle returned by, say, OpenProcess, ShellExecuteEx() or CreateProcess keeps the process object alive. That's how it is possible to call GetExitCodeProcess() to retrieve the exit code after the process is terminated.
The object doesn't get released until the last handle on it is closed. Opposite of earlier advice given in this thread, it is very important that you call CloseHandle() or you'll have a leak.
You can wait on a process handle to figure out when it is exited.
WaitForSingleObject(hProcess, INFINITE);
Once this returns, you know the process has exited and you don't need to close it.