Handle to window handle - c

I've tried using the "grab all of the process IDs enumerated by the desktop" method, however that doesn't work.
Is there a way to convert a handle to a window handle? -or-
Is there a way to take a process ID and find out all of the child windows spawned by the process?
I don't want to use FindWindow due to multiple process issues.

You could call EnumWindows() to iterate over all the top-level windows on the screen, then use GetWindowThreadProcessId() to find out which ones belong to your process.
For example, something like:
BOOL CALLBACK ForEachTopLevelWindow(HWND hwnd, LPARAM lp)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (DWORD) lp) {
// `hwnd` belongs to the target process.
}
return TRUE;
}
VOID LookupProcessWindows(DWORD processId)
{
EnumWindows(ForEachTopLevelWindow, (LPARAM) processId);
}

Related

How to use close handler in winapi if you need to clean up everything in another thread?

I'm creating a thread for my game. But I found, that if close button is pressed, or the task is killed I cannot properly finish the work, deallocating all the resources I needed inside the program.
I found that Close handler exists, but the example given is an unknown magic to me, because I need to create something similar in ANSI-C.
static BOOL CloseHandler(DWORD evt)
{
if (evt == CTRL_CLOSE_EVENT)
{
m_bAtomActive = false;
// Wait for thread to be exited
std::unique_lock<std::mutex> ul(m_muxGame);
m_cvGameFinished.wait(ul);
}
return true;
}
I know that Winapi has Mutex and conditional variables, but I do not know anything about std::atomic equivalent.
I have this thread start function and inside thread function GameThread I have a regular bool variable m_bAtomActive checked now.
void Start(void* _self)
{
DWORD dwThreadID;
HANDLE hThread;
struct c_class* this = _self;
this->m_bAtomActive = true;
hThread = CreateThread(
NULL,
0,
&GameThread,
_self,
0,
&dwThreadID);
WaitForSingleObject(hThread, INFINITE);
}
I'm bad at threading, what should I do to properly finish the work of my game?
All the additional details will be provided in the comments or on the chat.
UPD: The first thing seems to be easy, it is solvable with this line inside close handler
if(Active)
InterlockedDecrement(&Active);
But the second and third is still under question. They might be created for the reason of CloseHandler killing the app before destruction, but I don't know for sure.

SetWindowsHookEx injection failed on release mode but worked on debug mode

I'm writing a program which monitors Keystrokes of a target process using SetWindowsHookEx. (IDE: Visual Studio 2013)Here's an overview of my program:
Obtain a HWND of the target process using FindWindow().
If HWND is valid, obtain the process id using GetWindowThreadProcessId()
Obtain a thread id by traversing the thread list with CreateToolhelp32Snapshot(TH32CS_THREAD)
Call SetWindowsHookEx().
Actual code:
//obtain the window handle
HWND hwnd = FindWindowA(NULL, "A valid title");
DWORD pid = 0;
//obtain the process id.
GetWindowThreadProcessId(hwnd, &pid);
//obtain the thread id.
DWORD threadId = GetThreadId(pid);
printf("Injecting to Process: %d Thread: %d\n", pid, threadId);
HMODULE hDll = LoadLibraryA("TestDLL.dll");
if (hDll == INVALID_HANDLE_VALUE)
{
printf("LoadLibrary() failed! %d!\n", GetLastError());
return 0;
}
HOOKPROC hookproc = (HOOKPROC)GetProcAddress(hDll, "KeyboardProc");
if (!hookproc)
{
printf("GetProcAddress() failed\n");
return 0;
}
HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC, hookproc, hDll, threadId);
if (!hook)
{
printf("SetWindowsHookEx() failed! %d\n", GetLastError());
return 0;
}
//post a message. This will trigger the hook and cause the target process
//to load my dll. Actual key monitoring code is inside the dll.
printf("SendMessage() returns:%d", SendMessage(hwnd, WM_NULL, 0, 0));
printf("Success!\n");
UnhookWindowsHookEx(hook);
getchar();
Under Debug mode, the output shows:
Injecting to process 4052 Thread:460
SendMessage() returns:0
Success!
A simple analysis shows that the target process did load my dll. Which means the program works. However, under release mode, the output is the same but dll is not loaded into the target process. I tried this multiple times with restarting target process each time. But still doesn't work.
How do I resolve this problem?
When you say "under Debug mode" - does it mean that you are debugging inside VS?
If so, my guess that the problem might be in permission set - you can run VS with elevated permissions or under another user/group. Try to run your release version of the app in Admin mode. Otherwise it would be a security flaw if any process can inject code into any another process.

Run process and wait for it AND its child processes to end [duplicate]

Is it possible to wait for all processes launched by a child process in Windows? I can't modify the child or grandchild processes.
Specifically, here's what I want to do. My process launches uninstallA.exe. The process uninistallA.exe launches uninstallB.exe and immediately exits, and uninstallB.exe runs for a while. I'd like to wait for uninstallB.exe to exit so that I can know when the uninstall is finished.
Create a Job Object with CreateJobObject. Use CreateProcess to start UninstallA.exe in a suspended state. Assign that new process to your job object with AssignProcessToJobObject. Start UninstallA.exe running by calling ResumeThread on the handle of the thread you got back from CreateProcess.
Then the hard part: wait for the job object to complete its execution. Unfortunately, this is quite a bit more complex than anybody would reasonably hope for. The basic idea is that you create an I/O completion port, then you create the object object, associate it with the I/O completion port, and finally wait on the I/O completion port (getting its status with GetQueuedCompletionStatus). Raymond Chen has a demonstration (and explanation of how this came about) on his blog.
Here's a technique that, while not infallible, can be useful if for some reason you can't use a job object. The idea is to create an anonymous pipe and let the child process inherit the handle to the write end of the pipe.
Typically, grandchild processes will also inherit the write end of the pipe. In particular, processes launched by cmd.exe (e.g., from a batch file) will inherit handles.
Once the child process has exited, the parent process closes its handle to the write end of the pipe, and then attempts to read from the pipe. Since nobody is writing to the pipe, the read operation will block indefinitely. (Of course you can use threads or asynchronous I/O if you want to keep doing stuff while waiting for the grandchildren.)
When (and only when) the last handle to the write end of the pipe is closed, the write end of the pipe is automatically destroyed. This breaks the pipe and the read operation completes and reports an ERROR_BROKEN_PIPE failure.
I've been using this code (and earlier versions of the same code) in production for a number of years.
// pwatch.c
//
// Written in 2011 by Harry Johnston, University of Waikato, New Zealand.
// This code has been placed in the public domain. It may be freely
// used, modified, and distributed. However it is provided with no
// warranty, either express or implied.
//
// Launches a process with an inherited pipe handle,
// and doesn't exit until (a) the process has exited
// and (b) all instances of the pipe handle have been closed.
//
// This effectively waits for any child processes to exit,
// PROVIDED the child processes were created with handle
// inheritance enabled. This is usually but not always
// true.
//
// In particular if you launch a command shell (cmd.exe)
// any commands launched from that command shell will be
// waited on.
#include <windows.h>
#include <stdio.h>
void error(const wchar_t * message, DWORD err) {
wchar_t msg[512];
swprintf_s(msg, sizeof(msg)/sizeof(*msg), message, err);
printf("pwatch: %ws\n", msg);
MessageBox(NULL, msg, L"Error in pwatch utility", MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
ExitProcess(err);
}
int main(int argc, char ** argv) {
LPWSTR lpCmdLine = GetCommandLine();
wchar_t ch;
DWORD dw, returncode;
HANDLE piperead, pipewrite;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
char buffer[1];
while (ch = *(lpCmdLine++)) {
if (ch == '"') while (ch = *(lpCmdLine++)) if (ch == '"') break;
if (ch == ' ') break;
}
while (*lpCmdLine == ' ') lpCmdLine++;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&piperead, &pipewrite, &sa, 1)) error(L"Unable to create pipes: %u", GetLastError());
GetStartupInfo(&si);
if (!CreateProcess(NULL, lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
error(L"Error %u creating process.", GetLastError());
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) error(L"Error %u waiting for process.", GetLastError());
if (!GetExitCodeProcess(pi.hProcess, &returncode)) error(L"Error %u getting exit code.", GetLastError());
CloseHandle(pipewrite);
if (ReadFile(piperead, buffer, 1, &dw, NULL)) {
error(L"Unexpected data received from pipe; bug in application being watched?", ERROR_INVALID_HANDLE);
}
dw = GetLastError();
if (dw != ERROR_BROKEN_PIPE) error(L"Unexpected error %u reading from pipe.", dw);
return returncode;
}
There is not a generic way to wait for all grandchildren but for your specific case you may be able to hack something together. You know you are looking for a specific process instance. I would first wait for uninstallA.exe to exit (using WaitForSingleObject) because at that point you know that uninstallB.exe has been started. Then use EnumProcesses and GetProcessImageFileName from PSAPI to find the running uninstallB.exe instance. If you don't find it you know it has already finished, otherwise you can wait for it.
An additional complication is that if you need to support versions of Windows older than XP you can't use GetProcessImageFileName, and for Windows NT you can't use PSAPI at all. For Windows 2000 you can use GetModuleFileNameEx but it has some caveats that mean it might fail sometimes (check docs). If you have to support NT then look up Toolhelp32.
Yes this is super ugly.
Use a named mutex.
One possibility is to install Cygwin and then use the ps command to watch for the grandchild to exit

How to handle all key presses in a parent window

Ive been struggling for a while with a basic UI thing. I have a parent window and several child windows. With child windows such as button (BS_CHECKBOX style) and edit Im not able to process any message for pressing the ESC key event. I could subclass child windows but it seems to be an overkill just to handle one event. I also have a listview child and for some reason I can handle the VK_ESCAPE correctly. I also checked spy++ and noticed there are NO messages sent to the parent window when ESC key is pressed (and the child is focused). If I set spy++ to log child messages only, the correct messages are generated for the key press - they are just not passed to the parent. Any ideas what (not) to do?
Main window loop:
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage (&Msg);
DispatchMessage (&Msg);
}
Working code in parent's WndProc for handling listview key press:
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case LVN_KEYDOWN:
if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_ESCAPE)
Exit();
break;
}
break;
Thanks,
Kra
One way to do this is to catch it in your message loop before it gets dispatched to the focus window, e.g.:
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
if (Msg.message == WM_KEYDOWN && Msg.wParam == VK_ESCAPE)
{
// process escape key
}
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
There are other ways to do it of course, but this is a very simple solution.

Problem in CreateProcess function!

I have my main application ,from my main application I will be calling another
module(third party) to perform a small operation in my main application,when I call that module..it processes for a particular time say 5 sec.while its proccessing it shows the process in the commmand window with some information..now my main application waits until the called module finishes its process.Now my Question is..how to do I hide this command window without disturbing its process..I tried to use the createprocess but it seems to not work...
for example: my main application is the Parent process and the called application is child process..Parent process should be independent of the child process..check my example below
int main()
{
execl("c:\\users\\rakesh\\Desktop\\calledapplication.exe","c:\\users\\rakesh\\Desktop \\calledapplication.exe",0);
}
code in calledapplication
int main
{
printf("Rakesh");
}
now considering the above if you run the first program...output would appear in the same
command window(It shouldnt be like that)...I want the main application to create the process but it should not be affected by child process.
Pass CREATE_NO_WINDOW in the dwCreationFlags parameter of CreateProcess.
You talked about a "command window", so I presume that the child is a console application.
In that case you can create the process in a separate conole and optionally force the new console to be iconified or hidden.
The following code launch a child process that interprets a batch file (mytest.bat).
I hope it can help. Regards.
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL rv = FALSE;
WCHAR cmdline[] = TEXT("cmd.exe /c mytest.bat");
memset(&si,0,sizeof(si));
si.cb = sizeof(si);
// Add this if you want to hide or minimize the console
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; //or SW_MINIMIZE
///////////////////////////////////////////////////////
memset(&pi,0,sizeof(pi));
rv = CreateProcess(NULL, cmdline, NULL, NULL,
FALSE, CREATE_NEW_CONSOLE,
NULL, NULL, &si, &pi);
if (rv) {
WaitForSingleObject(pi.hProcess, INFINITE);
printf("Done! :)\n");
}
else {
printf("Failed :(\n");
}
return rv ? 0 : 1;
}
It sounds like you want the child process's output to show up in a separate window. If so, you want to call CreateProcess and pass it the CREATE_NEW_CONSOLE flag, rather than using exec*.

Resources