Leaked source code of windows server 2003
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.

143 lines
3.9 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. QuickBooks8.cpp
  5. Abstract:
  6. Looks like a bug in "C:\Program Files\Intuit\QuickBooks Pro\qbw32.exe". All
  7. cab file are coming from this program. It's sending a TB_ADDSTRING message
  8. to the toolbar control, but the lParam of the message is malformed. The
  9. lParam is documented to be an array of null-termnated string with the last
  10. string in the array being double nulled. In the case of this program, the
  11. last string is not double nulled, causing comctl32 to read of the end of
  12. the buffer while processing the message.
  13. Notes:
  14. This is an app specific shim.
  15. History:
  16. 04/16/2002 v-ramora Created
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(QuickBooks8)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(SendMessageA)
  23. APIHOOK_ENUM_END
  24. /*++
  25. If the strings are well formed or double null terminated return TRUE and
  26. strings length. If the strings are not well formed, return FALSE and length
  27. of strings
  28. --*/
  29. BOOL
  30. AreTheStringsGood(
  31. LPCSTR pszStrings,
  32. DWORD &dwStringsLen
  33. )
  34. {
  35. dwStringsLen = 0;
  36. __try
  37. {
  38. while (*pszStrings) {
  39. DWORD dwOneStringLen = 0;
  40. // I am assuming single tooltip or string length can be at most 256
  41. while (*pszStrings && (dwOneStringLen < 256)) {
  42. pszStrings++;
  43. dwOneStringLen++;
  44. }
  45. if (*pszStrings == NULL) {
  46. // String was terminated by '\0' means good.
  47. DPFN( eDbgLevelInfo, "Toolbar TB_ADDSTRING = %s", (pszStrings - dwOneStringLen));
  48. dwStringsLen += dwOneStringLen + 1; // 1 is for end of string
  49. pszStrings++; // goto next string
  50. } else {
  51. return FALSE;
  52. }
  53. }
  54. }
  55. __except (1) {
  56. return FALSE;
  57. }
  58. return TRUE;
  59. }
  60. /*++
  61. Make sure the last string is double null terminated.
  62. --*/
  63. BOOL
  64. APIHOOK(SendMessageA)(
  65. HWND hWnd,
  66. UINT uMsg, // TB_ADDSTRING
  67. WPARAM wParam,// hInst to Module which contains strings, In this case NULL since array of strings
  68. LPARAM lParam // points to a character array with one or more strings
  69. )
  70. {
  71. #define CLASSNAME_LENGTH 256
  72. WCHAR wszClassName[CLASSNAME_LENGTH] = L"";
  73. if (GetClassName(hWnd, wszClassName, CLASSNAME_LENGTH-1) && lParam) {
  74. // I care about only send message to toolbar
  75. if ((wcsncmp(wszClassName, L"ToolbarWindow32", CLASSNAME_LENGTH) == 0) &&
  76. (uMsg == TB_ADDSTRING) && (wParam == NULL)) {
  77. LPCSTR pszStrings = (LPCSTR) lParam;
  78. DWORD dwStringsLen = 0;
  79. //
  80. // If strings are not double null terminated, then only create new strings
  81. // with double null
  82. //
  83. if ((AreTheStringsGood(pszStrings, dwStringsLen) == FALSE) && dwStringsLen) {
  84. LOGN(eDbgLevelError, "[SendMessageA] Toolbar TB_ADDSTRING bad lParam");
  85. LPSTR pszNewStrings = (LPSTR) malloc(dwStringsLen + 1);
  86. if (pszNewStrings) {
  87. MoveMemory(pszNewStrings, pszStrings, dwStringsLen);
  88. *(pszNewStrings + dwStringsLen) = '\0'; //second '\0'
  89. LRESULT lResult = ORIGINAL_API(SendMessageA)(hWnd, uMsg,
  90. wParam, (LPARAM) pszNewStrings);
  91. free(pszNewStrings);
  92. return lResult;
  93. }
  94. }
  95. }
  96. }
  97. return ORIGINAL_API(SendMessageA)(hWnd, uMsg, wParam, lParam);
  98. }
  99. /*++
  100. Register hooked functions
  101. --*/
  102. HOOK_BEGIN
  103. APIHOOK_ENTRY(USER32.DLL, SendMessageA)
  104. HOOK_END
  105. IMPLEMENT_SHIM_END