Source code of Windows XP (NT5)
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.

159 lines
2.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. NBALive.cpp
  5. Abstract:
  6. On Win9x, SetWindowText used to pass the pointer directly to the window
  7. proc in a WM_SETTEXT message. However, on NT, the string goes through the
  8. standard message workers and get's converted to unicode etc. When it does
  9. get to the window proc, it's not the original pointer.
  10. NBA Live 99 depends on the pointer being the same, since it sends more than
  11. just the string.
  12. The fix is to subclass the WindowProc on SetWindowText and change the
  13. pointer (in lParam) to the one that was originally passed.
  14. Notes:
  15. This is an app specific shim.
  16. History:
  17. 06/19/2000 linstev Created
  18. --*/
  19. #include "precomp.h"
  20. // This module has been given an official blessing to use the str routines.
  21. #include "LegalStr.h"
  22. IMPLEMENT_SHIM_BEGIN(NBALive)
  23. #include "ShimHookMacro.h"
  24. APIHOOK_ENUM_BEGIN
  25. APIHOOK_ENUM_ENTRY(SetWindowTextA)
  26. APIHOOK_ENUM_END
  27. //
  28. // Critical section for global variable access
  29. //
  30. CRITICAL_SECTION g_csGlobals;
  31. //
  32. // Text for window and previous windowproc
  33. //
  34. CHAR *g_szText;
  35. WNDPROC g_lpWndProc;
  36. /*++
  37. The subclassed windowproc that we use to change the text pointer to the
  38. original one passed to SetWindowTextA.
  39. --*/
  40. LRESULT
  41. CALLBACK
  42. WindowProcA(
  43. HWND hWnd,
  44. UINT uMsg,
  45. WPARAM wParam,
  46. LPARAM lParam
  47. )
  48. {
  49. if (uMsg == WM_SETTEXT) {
  50. if (lParam) {
  51. if (strcmp(g_szText, (CHAR *) lParam) == 0) {
  52. lParam = (LPARAM) g_szText;
  53. }
  54. }
  55. }
  56. return CallWindowProcA(g_lpWndProc, hWnd, uMsg, wParam, lParam);
  57. }
  58. /*++
  59. Subclass the windowproc for this call and fix the pointer that comes out in
  60. the WM_SETTEXT message that is generated by SetWindowTextA.
  61. --*/
  62. BOOL
  63. APIHOOK(SetWindowTextA)(
  64. HWND hWnd,
  65. LPCSTR lpString
  66. )
  67. {
  68. BOOL bRet = FALSE;
  69. //
  70. // Set the text for this window
  71. //
  72. EnterCriticalSection(&g_csGlobals);
  73. //
  74. // Subclass the window
  75. //
  76. g_lpWndProc = (WNDPROC) GetWindowLongA(hWnd, GWL_WNDPROC);
  77. if (g_lpWndProc) {
  78. SetWindowLongA(hWnd, GWL_WNDPROC, (LONG_PTR) WindowProcA);
  79. }
  80. //
  81. // Call the original function which generates a WM_SETTEXT message
  82. //
  83. g_szText = (CHAR *) lpString;
  84. bRet = ORIGINAL_API(SetWindowTextA)(hWnd, lpString);
  85. //
  86. // Restore the wndproc
  87. //
  88. SetWindowLongA(hWnd, GWL_WNDPROC, (LONG_PTR) g_lpWndProc);
  89. LeaveCriticalSection(&g_csGlobals);
  90. return bRet;
  91. }
  92. /*++
  93. Register hooked functions
  94. --*/
  95. BOOL
  96. NOTIFY_FUNCTION(
  97. DWORD fdwReason)
  98. {
  99. if (fdwReason == DLL_PROCESS_ATTACH) {
  100. InitializeCriticalSection(&g_csGlobals);
  101. }
  102. return TRUE;
  103. }
  104. HOOK_BEGIN
  105. CALL_NOTIFY_FUNCTION
  106. APIHOOK_ENTRY(USER32.DLL, SetWindowTextA )
  107. HOOK_END
  108. IMPLEMENT_SHIM_END