mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
7.1 KiB
324 lines
7.1 KiB
/*****************************************************************************\
|
|
*
|
|
* Module: hook.c
|
|
*
|
|
* Contains the message hooking functions for the Windows debugging Spy
|
|
* SDK applet.
|
|
*
|
|
* History:
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
#include "spy.h"
|
|
|
|
|
|
PRIVATE BOOL gfProcessHooks = TRUE;
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* CreateHookThread
|
|
*
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
*
|
|
* Returns:
|
|
*
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
BOOL
|
|
CreateHookThread(
|
|
VOID
|
|
)
|
|
{
|
|
WNDCLASS wc;
|
|
DWORD Id;
|
|
|
|
//
|
|
// Register a class for the hook stuff to forward its messages to.
|
|
//
|
|
wc.hCursor = NULL; // this window never shown, so no
|
|
wc.hIcon = NULL; // cursor or icon are necessary
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = HOOKWINDOWCLASS;
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
wc.hInstance = ghInst;
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = HookWndProc;
|
|
wc.cbWndExtra = sizeof(HWND) + sizeof(HWND);
|
|
wc.cbClsExtra = 0;
|
|
|
|
if (!RegisterClass(&wc))
|
|
return FALSE;
|
|
|
|
//
|
|
// Now create another thread to handle the new queue
|
|
//
|
|
if (!(ghHookThread = CreateThread(NULL, 0, HookMain,
|
|
0L, STANDARD_RIGHTS_REQUIRED, &Id)))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* HookMain
|
|
*
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
*
|
|
* Returns:
|
|
*
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
DWORD
|
|
HookMain(
|
|
LPVOID lpv
|
|
)
|
|
{
|
|
MSG msg;
|
|
|
|
//
|
|
// Create a hidden window for all to find, but not to see
|
|
//
|
|
ghwndSpyHook = CreateWindow(HOOKWINDOWCLASS, HOOKWINDOWNAME,
|
|
WS_OVERLAPPEDWINDOW,
|
|
0, 0, 0, 0,
|
|
(HWND) NULL, /* no parent */
|
|
(HMENU) NULL, /* use class menu */
|
|
(HANDLE) ghInst, /* handle to window instance */
|
|
(LPSTR) NULL /* no params to pass on */
|
|
);
|
|
|
|
if (!ghwndSpyHook)
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
|
|
SetWindowToSpyOn(HWND_ALL);
|
|
|
|
//
|
|
// Polling forwarded messages from hook's event queue
|
|
//
|
|
while (IsWindow(ghwndSpyHook) && GetMessage(&msg, ghwndSpyHook, 0, 0))
|
|
{
|
|
if (gfProcessHooks)
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
ghwndSpyHook = NULL;
|
|
|
|
return 0; // not reached
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* HookWndProc
|
|
*
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
*
|
|
* Returns:
|
|
*
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
LRESULT CALLBACK
|
|
HookWndProc(
|
|
HWND hwnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_COPYDATA:
|
|
{
|
|
MSG msgT;
|
|
|
|
msgT.hwnd = (HWND)wParam;
|
|
msgT.message = ((PCOPYDATASTRUCT)lParam)->dwData;
|
|
msgT.wParam = ((PSPYMSGDATA)((PCOPYDATASTRUCT)lParam)->lpData)->wParam;
|
|
msgT.lParam = ((PSPYMSGDATA)((PCOPYDATASTRUCT)lParam)->lpData)->lParam;
|
|
//DbgPrintf("S Received Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
|
|
PrintMsg(&msgT);
|
|
//DbgPrintf("S Printed Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
case WM_CREATE:
|
|
//
|
|
// Initialize the second HWND in the window words to be the
|
|
// window handle of the spy app. This will be queried by
|
|
// the hook DLL.
|
|
//
|
|
SetWindowLong(hwnd, sizeof(HWND), (LONG)ghwndSpyApp);
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
|
|
case WM_NCDESTROY:
|
|
gfProcessHooks = FALSE;
|
|
break;
|
|
}
|
|
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* SetSpyHook
|
|
*
|
|
* Sets the windows hooks used to trap the messages. After this
|
|
* is called with a TRUE for fSet, the messages will start flowing
|
|
* through the hook DLL.
|
|
*
|
|
* Arguments:
|
|
* BOOL fSet - TRUE to hook, FALSE to unhook.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
BOOL
|
|
SetSpyHook(
|
|
BOOL fSet
|
|
)
|
|
{
|
|
static HHOOK hhkGetMessage = NULL;
|
|
static HHOOK hhkCallWndProc = NULL;
|
|
static HANDLE hmodHook;
|
|
|
|
if (fSet)
|
|
{
|
|
if (!hmodHook)
|
|
{
|
|
if (!(hmodHook = LoadLibrary("hook")))
|
|
{
|
|
Message(MB_OK | MB_ICONEXCLAMATION,
|
|
LoadResourceString(IDS_ERROR_CANT_LOAD_DLL));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!hhkGetMessage)
|
|
{
|
|
if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,
|
|
(HOOKPROC)GetProcAddress(hmodHook, "SpyGetMsgProc"), hmodHook, 0)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!hhkCallWndProc)
|
|
{
|
|
if (!(hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC,
|
|
(HOOKPROC)GetProcAddress(hmodHook, "SpyCallWndProc"), hmodHook, 0)))
|
|
{
|
|
UnhookWindowsHookEx(hhkGetMessage);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (hhkGetMessage)
|
|
{
|
|
UnhookWindowsHookEx(hhkGetMessage);
|
|
hhkGetMessage = NULL;
|
|
}
|
|
|
|
if (hhkCallWndProc)
|
|
{
|
|
UnhookWindowsHookEx(hhkCallWndProc);
|
|
hhkCallWndProc = NULL;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* SetWindowToSpyOn
|
|
*
|
|
* Sets the current window to spy on to the specified hwnd. This hwnd can
|
|
* also be the special value HWND_ALL to specify that all windows should
|
|
* be spy'd upon.
|
|
*
|
|
* Arguments:
|
|
* HWND hwndSpyingOn - Window handle to spy on, or HWND_ALL for all windows.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
VOID
|
|
SetWindowToSpyOn(
|
|
HWND hwndSpyingOn
|
|
)
|
|
{
|
|
ghwndSpyingOn = hwndSpyingOn;
|
|
gfSpyAll = (ghwndSpyingOn == HWND_ALL) ? TRUE : FALSE;
|
|
SetWindowLong(ghwndSpyHook, 0, (LONG)ghwndSpyingOn);
|
|
SetSpyCaption();
|
|
}
|
|
|
|
|
|
|
|
#ifdef DBG
|
|
/****************************************************************************
|
|
* DBGprintf
|
|
*
|
|
* This debugging function prints out a string to the debug output.
|
|
* An optional set of substitutional parameters can be specified,
|
|
* and the final output will be the processed result of these combined
|
|
* with the format string, just like printf. A newline is always
|
|
* output after every call to this function.
|
|
*
|
|
* Arguments:
|
|
* LPTSTR fmt - Format string (printf style).
|
|
* ... - Variable number of arguments.
|
|
*
|
|
* History:
|
|
* 28-Aug-1990 Byron Dazey - Created
|
|
****************************************************************************/
|
|
|
|
VOID DbgPrintf(
|
|
LPTSTR fmt,
|
|
...
|
|
)
|
|
{
|
|
va_list marker;
|
|
TCHAR szBuf[256];
|
|
|
|
va_start(marker, fmt);
|
|
wvsprintf(szBuf, fmt, marker);
|
|
va_end(marker);
|
|
|
|
OutputDebugString(szBuf);
|
|
OutputDebugString(TEXT("\r\n"));
|
|
}
|
|
#endif
|