I was wondering whether you can convert a handle to a window "HWND". I need to call the "PostMessage" function using the "FindWindow" method.
I currently have to source
HANDLE mainProcess;
BOOL APIENTRY ATTACH_PROCESS(int ProcessID)
{
mainProcess = OpenProcess(PROCESS_ALL_ACCESS, true, ProcessID);
return TRUE;
}
BOOL APIENTRY SEND_INPUT(/*NOT USED FOR THIS SAMPLE*/ const char* String, bool Keydown)
{
int ToDo = WM_KEYUP;
if (Keydown)
ToDo = WM_KEYDOWN;
return PostMessage((HWND)mainProcess, ToDo, VK_TAB, NULL);
}
No. A process can create multiple windows. Since there does not exist a 1-to-1 mapping, such a function would not make sense.
On the other hand, it is certainly possible to have a function which returns a list of windows created by a process.
call GetProcessId() using the mainProcess handle to get the ProcessID.
call EnumWindows()
For Each Window, call GetWindowThreadProcessId() to get the ProcessId of the process associated with the window.
Compare the ProcessID's, if they match -- you've found the HWND you want.
This is a somewhat expensive task, so best to find the hwnd you want upfront and just store it.
Related
I try to write a Multithreading WIN32 Application in C++, but due to i get difficulties.
One of the Window Procedure creates a Thread, which manages the output of this window. If this Window Procedure receives a message (from the other Window Procedures), it should transmit it to their Thread. At the beginning i worked with the _beginthread(...) function, what doesn't work.
Then i tried it with the CreateThread(...) function, and it worked? What did i do wrong?
(My English isn't so good, i hope you understand my problem)
Code with CreateThread(...):
DWORD thHalloHandle; // global
HWND hwndHallo; // Hwnd of WndProc4
...
LRESULT APIENTRY WndProc4 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static PARAMS params ;
switch (message)
{
case WM_CREATE: {
params.hwnd = hwnd ;
params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
CreateThread(NULL, 0, thHallo, ¶ms, 0, &thHalloHandle);
return 0 ;
}
...
case WM_SPACE: {
PostThreadMessage(thHalloHandle, WM_SPACE, 0, 0);
return 0;
}
...
}
Code with _beginthread(...):
...
case WM_CREATE: {
params.hwnd = hwnd ;
params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
thHalloHandle = (DWORD)_beginthread (thHallo, 0, ¶ms) ;
return 0;
}
...
case WM_SPACE: {
PostThreadMessage(thHalloHandle, WM_SPACE, 0, 0);
return 0;
}
...
thHallo for CreateThread:
DWORD WINAPI thHallo(void *pvoid)
{
static TCHAR *szMessage[] = { TEXT(...), ...};
// Some Declaration
pparams = (PPARAMS) pvoid;
while(!pparams->bKill)
{
MsgReturn = GetMessage(&msg, NULL, 0, 0);
hdc = GetDC(pparams->hwnd);
if(MsgReturn)
{
switch(msg.message)
{
// case....
}
}
}
return 0;
}
thHallo for _beginthread(...):
void thHallo(void *pvoid)
{
...
// The Same like for CreateThread
...
_endthread();
}
The _beginthread/ex() function is proving to be radically difficult to eliminate. It was necessary back in the previous century, VS6 was the last Visual Studio version that required it. It was a band-aid to allow the CRT to allocate thread-local state for internal CRT variables. Like the ones used for strtok() and gmtime(), CRT functions that maintain internal state. That state must be stored separately for each thread so that the use of, say, strtok() in one thread doesn't screw up the use of strtok() in another thread. It must be stored in thread-local state. _beginthread/ex() ensures that this state is allocated and cleaned-up again.
That has been worked on, necessarily so when Windows 2000 introduced the thread-pool. There is no possible way to get that internal CRT state initialized when your code gets called by a thread-pool thread. Quite an effort btw, the hardest problem they had to solve was to ensure that the thread-local state is automatically getting cleaned-up again when the thread stops running. Many a program has died on that going wrong, Apple's QuickTime is a particularly nasty source of these crashes.
So forget that _beginthread() ever existed, using CreateThread() is fine.
There's a serious problem with your use of PostThreadMessage(). You are used the wrong argument in your _beginthread() code which is why it didn't work. But there are bigger problems with it. The message that is posted can only ever be retrieved in your message loop. Which works fine, until it is no longer your message loop that is dispatching messages. That happens in many cases in a GUI app. Simple examples are using MessageBox(), DialogBox() or the user resizing the window. Modal code that works by Windows itself pumping the message loop.
A big problem is the message loop in that code knows beans about the messages you posted. They just fall in the bit-bucket and disappear without trace. The DispatchMessage() call inside that modal loop fails, the message you posted has a NULL window handle.
You must fix this by using PostMessage() instead. Which requires a window handle. You can use any window handle, the handle of your main window is a decent choice. Better yet, you can create a dedicated window, one that just isn't visible, with its own WndProc() that just handles these inter-thread messages. A very common choice. DispatchMessage() can now no longer fail, solves your bug as well.
Your call to CreateThread puts the thread ID into thHalloHandle. The call to _beginthread puts the thread handle into thHalloHandle.
Now, the thread ID is not the same as the thread handle. When you call PostThreadMessage you do need to supply a thread ID. You only do that for the CreateThread variant which I believe explains the problem.
Your code lacks error checking. Had you checked for errors on the call to PostThreadMessage you would have found that PostThreadMessage returned FALSE. Had you then gone on to call GetLastError that would have returned ERROR_INVALID_THREAD_ID. I do urge you to include proper error checking.
In order to address this you must first be more clear on the difference between thread ID and thread handle. You should give thHalloHandle a different name: thHalloThreadId perhaps. If you wish to use _beginthread you will have to call GetThreadId, passing the thread handle, to obtain the thread ID. Alternatively, use _beginthreadex which yields the thread ID, or indeed CreateThread.
Your problem is that you need a TID (Thread Identifier) to use PostThreadMessage.
_beginthread doesn't return a TID, it return a Thread Handle.
Solution is to use the GetThreadId function.
HANDLE hThread = (HANDLE)_beginthread (thHallo, 0, ¶ms) ;
thHalloHandle = GetThreadId( hThread );
Better Code (see the documentation here)
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, thHallo, ¶ms, 0, &thHalloHandle ) ;
Good day.
I'm scratching my head over a problem I'm having in visual studio express 2012
I have the following code:
HANDLE hProc = INVALID_HANDLE_VALUE ; <= declared globally in cpp file
//my routine
//get myprocessid
//...
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocessid);
And the value of hProc is non zero.
Then in a different routine:
FARPROC varprocaddress = GetRemoteProcAddress (hProc, hModule, MethodName, 0, FALSE);
Problem is, when I debug the GetRemoteProcAddress routine,
the hProc value (in the hProcess variable) is FALSE, despite the fact I can clearly see it is passed as non false thanks to a variable watch, and so the routine obviously fails.
The getremoteprocaddress method is declared as this:
FARPROC WINAPI GetRemoteProcAddress (HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName, UINT Ordinal, BOOL UseOrdinal)
Can anybody help?
It's obvious that the hProc parameter is not zero, then why it is converted to zero upon function call?
The issue seems related to the handle value outside of the function call... but how can I tell?
Thanks in advance.
Turns out the reason for the handle mangling was that the getremoteprocaddress call was inside a
LRESULT CALLBACK WndProc
in an user driven event (click on a menu).
Could not really figure out -why- this happened, but after I moved the FARPROC varprocaddress = GetRemoteProcAddress ...
call inside a new function, and placed the new function call in the menu click event, the global handle valued passed fine into the getremoteprocaddress!
I have some event handles and I add them to a list. I want to know if I can store these handles, close the local ones and still use the stored ones later.
Example:
std::map<std::string, HANDLE> Events;
DWORD OpenSingleEvent(std::string EventName, bool InheritHandle, DWORD dwDesiredAccess, DWORD dwMilliseconds)
{
Handle hEvent = OpenEvent(dwDesiredAccess, InheritHandle, EventName.c_str()); //Local Handle.
if (hEvent)
{
DeleteSingleEvent(EventName); //Delete the correct/old handle in the map.
Events.insert(EventName, hEvent); //Add this new handle to the map.
DWORD Result = WaitForSingleObject(hEvent, dwMilliseconds);
CloseHandle(hEvent); //Close THIS handle. Not the one in my Map.
return Result;
}
CloseHandle(hEvent); //Close this handle.
return WAIT_FAILED;
}
Will the above work? If not, is there another way to do this? It's for shared memory communication so I cannot duplicate handles since I only have the client PID not the Server's.
Also can someone explain what InheritHandle does? The function I use is OpenEvent and it has that parameter but I'm not sure what it does.
A HANDLE is simply a void *, it's a token which actually represents an object in kernel space. Calling CloseHandle actually deallocates the kernel object so the short answer to your question is no, you can't keep a list of them and then close all the local ones. All you'll have is a list of void* which don't represent anything.
What you can do is use DuplicateHandle which actually creates another kernel object on your behalf. However... why not just close the handles when you've finished with the entry in the list?
best way to ask a question is to first show an example:
this is how i create a timer in c++:
if (FALSE == CreateTimerQueueTimer(&m_hSampleStarvationTimer,
m_hSampleStarvationTimerQueue,
(WAITORTIMERCALLBACK)TsSampleStarvationTimeBomb_Static,
(LPVOID)this,
dwDueTime,
0,
WT_EXECUTEONLYONCE))
once the following callback is triggered(TsSampleStarvationTimeBomb_Static), i try to kill both the queue handle and timer's handle inside that particular thread.
void CALLBACK CCaptureChannel::TsSampleStarvationTimeBomb_Static(LPVOID lpArg, BOOLEAN TimerOrWaitFired)
{
HRESULT hr;
BOOL bHandleDeletion = FALSE;
CCaptureChannel* pCaptureChannel = (CCaptureChannel*)lpArg;
ATLASSERT(pCaptureChannel);
bHandleDeletion = DeleteTimerQueueTimer(pCaptureChannel->m_hSampleStarvationTimerQueue, pCaptureChannel->m_hSampleStarvationTimer, NULL);
bHandleDeletion = DeleteTimerQueue(pCaptureChannel->m_hSampleStarvationTimerQueue);
my question is: is it valid? i read over MSDN that the following deletion functions may return i/o errors which shouldn't concern me too much. their termination will be executed once the callback thread turns signled, automatically.
am i right?
Thanks!
DeleteTimerQueueEx will cancel and delete all timers associated with the queue as soon as all timer callbacks complete, so a single call to DeleteTimerQueueEx will suffice. You don't need the call to DeleteTimerQueueTimer. If you call it from within the callback as you currently have in your code, you must pass NULL as the CompletionEvent parameter to avoid deadlocking.
I have an application consists of a single EXE and multiple DLLs. After reading Windows via C/C++, I try to perform hook on Sleep function in one of the DLL, and expecting the hook will work across both EXE and all DLLs. Note that, CAPIHook code is getting from Windows via C/C++'s sample code
In DLL Project
void WINAPI MySleep( DWORD dwMilliseconds );
CAPIHook g_Sleep("Kernel32.dll", "Sleep", (PROC)MySleep);
typedef void (WINAPI *Sleep_Type)( DWORD dwMilliseconds );
// Hook function.
void WINAPI MySleep( DWORD dwMilliseconds )
{
printf ("-------> In MySleep\n");
((Sleep_Type)(PROC)g_Sleep)(dwMilliseconds);
}
// This is an example of an exported function.
DLL_API int dll_function_which_is_going_to_call_sleep(void)
{
printf ("DLL function being called\n");
printf ("Call Sleep in DLL function\n");
Sleep(100);
return 42;
}
In EXE Project
void CexeDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
printf ("Button being clicked\n");
printf ("Call Sleep in EXE function\n");
Sleep(100);
dll_function_which_is_going_to_call_sleep();
printf ("Call Sleep in EXE function\n");
Sleep(100);
dll_function_which_is_going_to_call_sleep();
}
This is the output I am getting
Button being clicked
Call Sleep in EXE function
-------> In MySleep
DLL function being called
Call Sleep in DLL function
Call Sleep in EXE function
-------> In MySleep
DLL function being called
Call Sleep in DLL function
What make me feel strange is that, I am expecting CAPIHook will take effect across entire single process. Since EXE and DLLs belong to a same process, both should be able to reach MySleep. However, my observation is that, only call from EXE will reach MySleep, but not DLL.
I locate sample code right here CAPIHook-doesnt-have-effect-in-entire-process.zip, it contains dll and exe projects.
I also once drop in replace CHookAPI with code in apihijack. Same problem still happen. The hooking effect will not spread across entire process.
Is there anything I had missed out? Please do not suggest me to use EasyHook, Detours, ..., as I just want to know why the above code won't work, and how I can fix it.
This is because the original CAPIHook does not replace local IAT (in your case, the DLL project which contains binaries for CAPIHook).
The reason behind this was to protect itself from infinite recursion which lead to stackoverflow (which the users will also post question in SO :D).
To ensure that any subsequent modules loaded will be importing the "correct" function,CAPIHook search and re-direct LoadLibrary and GetProcAddress upon construction.
However, these function are used by CAPIHook itself too, so changing local IAT to proxy function (CAPIHook::LoadLibrary or CAPIHook::GetProcAddress) will cause infinite recursion as the proxies unintentionally called itself while trying to call underlying OS API !
One way to solve this is by modifying CAPIHook to check whether it is alright to replace local IAT.
1.) New attribute m_bIncludeLocalIAT added to CAPIHook and ctor/dtor modified accordingly.
class CAPIHook
{
...
CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName,
PROC pfnHook, BOOL bIncludeLocalIAT = TRUE);
...
BOOL m_bIncludeLocalIAT;
...
};
CAPIHook::CAPIHook( PSTR pszCalleeModName, PSTR pszFuncName,
PROC pfnHook, BOOL bIncludeLocalIAT) {
...
m_bIncludeLocalIAT = bIncludeLocalIAT;
...
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook, m_bIncludeLocalIAT);
}
CAPIHook::~CAPIHook() {
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnHook, m_pfnOrig, m_bIncludeLocalIAT);
...
}
2.) New parameter added to the static function CAPIHook::ReplaceIATEntryInAllMods.
static void WINAPI ReplaceIATEntryInAllMods(PCSTR pszCalleeModName,
PROC pfnOrig, PROC pfnHook, BOOL bReplaceLocalIAT){
HMODULE hmodThisMod = ExcludeAPIHookMod
? ModuleFromAddress(ReplaceIATEntryInAllMods) : NULL;
// Get the list of modules in this process
CToolhelp th(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32 me = { sizeof(me) };
for (BOOL bOk = th.ModuleFirst(&me); bOk; bOk = th.ModuleNext(&me)) {
if (bReplaceLocalIAT || (me.hModule != hmodThisMod)) {
// Hook this function in this module
ReplaceIATEntryInOneMod(
pszCalleeModName, pfnCurrent, pfnNew, me.hModule);
}
}
}
3.) Update the static CAPIHook instances
CAPIHook CAPIHook::sm_LoadLibraryA ("Kernel32.dll", "LoadLibraryA",
(PROC) CAPIHook::LoadLibraryA, FALSE);
CAPIHook CAPIHook::sm_LoadLibraryW ("Kernel32.dll", "LoadLibraryW",
(PROC) CAPIHook::LoadLibraryW, FALSE);
CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",
(PROC) CAPIHook::LoadLibraryExA, FALSE);
CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",
(PROC) CAPIHook::LoadLibraryExW, FALSE);
CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",
(PROC) CAPIHook::GetProcAddress, FALSE);