Hello All,

For those of you who have been helping me with this, thanks for your continued
help. However, I still cannot seem to get my application to work, and I
really do not know why. I am either missing something really simple, or
something really complex, because I have tried everything in between :-).

The problem (for those who have not been following this) is that an invalid
page fault occurs in ComCtl32.dll whenever I do a GetItem to a TabCtrl in
another process. As suggested, I have created a hooked DLL to intercept the
SendMessage, and that _seems_ to work fine. I have also created shared data
segments, and initialized them. However, the problem still happens.

Attached is a copy of the EXACT code that causes this problem. The three
files (the DLL, the .def, and the calling app) are all it takes to cause
the problem. The code interacts with the Wordpad->Options TabCtrl, so that
has to be open for this to work.

So, what I humbly ask is this:

1. Can ANYONE get this to work so the page fault does not happen, and the
name of one of the Wordpad->Options TabCtrl pages is returned by the HookDLL?
I set up my project (TempProj) as one empty Console app (CallDLL) using
MFC as shared DLL, with another project (TempDLL) inserted (the HookDLL)
as an empty MFC DLL. I then insert the files. I am using VC++ 6.0, on a
Windows 98 system.
2. Shared variables have to be initialized. How do you deal with structures
in this fashion?? I share the TCITEM* and initialize it using new TCITEM,
but the members do not get initialized this way.
3. I tried setting a WH_GETMESSAGE hook in Wordpad to intercept a PostMessage
(and SendMessage) from Wordpad's point of view, but the hook proc is never
called. Am I correct in believing all Windows and dialog boxes call GetMessage??

I thank all of you who have been helping me, as well as those who can help
now. If you have any questions, please let me know.

-Johnny

The files are:

// HookDLL.cpp
// Used to intercept SendMessage messages via CallWndProc
// SetMemHandle is called from the calling app to set the window handle to
send the message

#include <afxcmn.h>

#define TEXT_MAX 255

#pragma data_seg(".shared")
static char str2[255] = "";
static TCITEM* tcItem = new TCITEM;
static BOOL bBranch = FALSE;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")

HWND gApp = NULL;

LRESULT CALLBACK CallWndProc(int Code, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* Msg = (CWPSTRUCT*)lParam;
LRESULT Ret = 0;
if(gApp == NULL)
{
return CallNextHookEx(NULL, Code, wParam, lParam);
}
if(!IsWindow(gApp))
{
return CallNextHookEx(NULL, Code, wParam, lParam);
}
if(Msg->message == TCM_GETITEM && bBranch == FALSE)
{
tcItem->mask = TCIF_TEXT;
tcItem->pszText = str2;
tcItem->cchTextMax = 254;
bBranch = TRUE; // This is necessary so following SendMessage will not
be processed

if(SendMessage(gApp , TCM_GETITEM, Msg->wParam, (LPARAM)&tcItem))
{
printf("%s\n", tcItem->pszText);
}
else
{
printf("GetItem Failed\n%s", tcItem->pszText);
}
bBranch = FALSE;
return CallNextHookEx(NULL, Code, wParam, lParam);
}
if(Code < 0 || bBranch)
{
return CallNextHookEx(NULL, Code, wParam, lParam);
}
return CallNextHookEx(NULL, Code, wParam, lParam);
}

void WINAPI SetMemHandle(HWND InHand)
{
gApp = InHand;
}
///// END HOOKDLL.CPP **************

The .def file (HookDLL.def) looks like:

LIBRARY HookDLL
DESCRIPTION "DLL Memory Share Module"
EXPORTS
CallWndProc @2
SetMemHandle @3
SECTIONS .shared READ WRITE SHARED

and the calling App (CallDLL.cpp) looks like:

// CallDLL.cpp calls the HookDLL as a CallWndProc Hook

#include <afx.h>
#include <stdio.h>
#include <string.h>

#ifndef __FUNCTION_PTRS__
#define __FUNCTION_PTRS__
typedef void (CALLBACK* SETHANDLE)(HWND);
#endif

#ifndef __G_HOOK__
#define __G_HOOK__

#pragma data_seg (".InjectDll")
static HINSTANCE hMemShare = NULL;
static HWND g_App = NULL;
static HOOKPROC lpHook = NULL;
static SETHANDLE SetMemHandle = NULL;
static FARPROC Proc = NULL;
static HHOOK g_Hook = NULL;
#pragma data_seg ()
#pragma comment(linker, "/section:.InjectDll,rws")
#endif

void main(int NumArgs, char* Args[])
{
CString Command = "GetTabText";
CString InParams = "3";
CString Name = "Options";
CString Class = "#32770";
CString PgClass = "SysTabControl32";

HWND Win;

Win = FindWindowEx(NULL, NULL, Class, Name);
g_App = FindWindowEx(Win, NULL, PgClass, "");
if(g_App == NULL)
{
printf("Error*** No Window ******");
return;
}

hMemShare = LoadLibrary("c:\\TempProj\\TempDLL\\debug\\HookDLL.dll");
if(hMemShare == NULL)
{
printf("Error********* 1");
return;
}
lpHook = (HOOKPROC)GetProcAddress(hMemShare, "CallWndProc");
if(lpHook == NULL)
{
printf("Error********* 2");
return;
}
Proc = (FARPROC)GetProcAddress(hMemShare, "SetMemHandle");
if(Proc == NULL)
{
printf("Error********* 3");
return;
}
SetMemHandle = (SETHANDLE)Proc;
SetMemHandle(g_App);
g_Hook = SetWindowsHookEx(WH_CALLWNDPROC, lpHook, hMemShare, 0);
if(g_Hook == NULL)
{
FreeLibrary(hMemShare);
hMemShare = NULL;
printf("Error********* 4");
return;
}
SendMessage(g_App, TCM_GETITEM, 255, NULL);

// UNHOOK
if(g_Hook != NULL)
{
UnhookWindowsHookEx(g_Hook);
g_Hook = NULL;
}
if(hMemShare != NULL)
{
FreeLibrary(hMemShare);
hMemShare = NULL;
}
return;
}
////// END CALLDLL.CPP

The Error is:

WORDPAD caused an invalid page fault in
module COMCTL32.DLL at 0167:bfe9236f.
Registers:
EAX=004068b8 CS=0167 EIP=bfe9236f EFLGS=00010206
EBX=10135000 SS=016f ESP=0056f248 EBP=0056f270
ECX=815c22b8 DS=016f ESI=00406ac8 FS=111f
EDX=00400000 ES=016f EDI=004068b8 GS=10d6
Bytes at CS:EIP:
f6 03 01 0f 85 b6 af 02 00 8b 03 57 ff 75 10 89
Stack dump:
Etc...