157 lines
2.9 KiB
C++
157 lines
2.9 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
NBALive.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
On Win9x, SetWindowText used to pass the pointer directly to the window
|
||
|
proc in a WM_SETTEXT message. However, on NT, the string goes through the
|
||
|
standard message workers and get's converted to unicode etc. When it does
|
||
|
get to the window proc, it's not the original pointer.
|
||
|
|
||
|
NBA Live 99 depends on the pointer being the same, since it sends more than
|
||
|
just the string.
|
||
|
|
||
|
The fix is to subclass the WindowProc on SetWindowText and change the
|
||
|
pointer (in lParam) to the one that was originally passed.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is an app specific shim.
|
||
|
|
||
|
History:
|
||
|
|
||
|
06/19/2000 linstev Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(NBALive)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(SetWindowTextA)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
|
||
|
//
|
||
|
// Critical section for global variable access
|
||
|
//
|
||
|
|
||
|
CRITICAL_SECTION g_csGlobals;
|
||
|
|
||
|
//
|
||
|
// Text for window and previous windowproc
|
||
|
//
|
||
|
|
||
|
CHAR *g_szText;
|
||
|
WNDPROC g_lpWndProc;
|
||
|
|
||
|
/*++
|
||
|
|
||
|
The subclassed windowproc that we use to change the text pointer to the
|
||
|
original one passed to SetWindowTextA.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LRESULT
|
||
|
CALLBACK
|
||
|
WindowProcA(
|
||
|
HWND hWnd,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
if (uMsg == WM_SETTEXT) {
|
||
|
if (lParam) {
|
||
|
if (strcmp(g_szText, (CHAR *) lParam) == 0) {
|
||
|
lParam = (LPARAM) g_szText;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return CallWindowProcA(g_lpWndProc, hWnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Subclass the windowproc for this call and fix the pointer that comes out in
|
||
|
the WM_SETTEXT message that is generated by SetWindowTextA.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(SetWindowTextA)(
|
||
|
HWND hWnd,
|
||
|
LPCSTR lpString
|
||
|
)
|
||
|
{
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
//
|
||
|
// Set the text for this window
|
||
|
//
|
||
|
|
||
|
EnterCriticalSection(&g_csGlobals);
|
||
|
|
||
|
//
|
||
|
// Subclass the window
|
||
|
//
|
||
|
|
||
|
g_lpWndProc = (WNDPROC) GetWindowLongA(hWnd, GWL_WNDPROC);
|
||
|
|
||
|
if (g_lpWndProc) {
|
||
|
SetWindowLongA(hWnd, GWL_WNDPROC, (LONG_PTR) WindowProcA);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Call the original function which generates a WM_SETTEXT message
|
||
|
//
|
||
|
|
||
|
g_szText = (CHAR *) lpString;
|
||
|
bRet = ORIGINAL_API(SetWindowTextA)(hWnd, lpString);
|
||
|
|
||
|
//
|
||
|
// Restore the wndproc
|
||
|
//
|
||
|
|
||
|
SetWindowLongA(hWnd, GWL_WNDPROC, (LONG_PTR) g_lpWndProc);
|
||
|
|
||
|
LeaveCriticalSection(&g_csGlobals);
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(
|
||
|
DWORD fdwReason)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH) {
|
||
|
InitializeCriticalSection(&g_csGlobals);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
APIHOOK_ENTRY(USER32.DLL, SetWindowTextA )
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|