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.

176 lines
3.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. HandleWvsprintfExceptions.cpp
  5. Abstract:
  6. This fix provides a facility to fix argument list from LPSTR into va_list.
  7. Some native Win9x app use LPSTR (pointer of string) instead of
  8. va_list (pointer to pointer of string).
  9. Without properly checking the return value, these apps assume that it is safe
  10. to use wvsprintf like that because it doesn't cause AV.
  11. In NT, this will cause AV.
  12. This shim takes one command line: "arglistfix" (case insensitive).
  13. By default - if there is no command line - it will do exactly
  14. what Win9x's wvsprintfA has :
  15. Do nothing inside the exception handler if there is an exception occurs.
  16. If arglistfix specified in command line, it will try to fix the argument
  17. list (va_list).
  18. History:
  19. 09/29/2000 andyseti Created
  20. 11/28/2000 jdoherty Converted to framework version 2
  21. 03/15/2001 robkenny Converted to CString
  22. --*/
  23. #include "precomp.h"
  24. int g_iWorkMode = 0;
  25. enum
  26. {
  27. WIN9X_MODE = 0,
  28. ARGLISTFIX_MODE
  29. } TEST;
  30. IMPLEMENT_SHIM_BEGIN(HandleWvsprintfExceptions)
  31. #include "ShimHookMacro.h"
  32. //
  33. // Add APIs that you wish to hook to this macro construction.
  34. //
  35. APIHOOK_ENUM_BEGIN
  36. APIHOOK_ENUM_ENTRY(wvsprintfA)
  37. APIHOOK_ENUM_END
  38. int Fix_wvsprintf_ArgList(
  39. LPSTR lpOut,
  40. LPCSTR lpFmt,
  41. ...)
  42. {
  43. int iRet;
  44. va_list argptr;
  45. va_start( argptr, lpFmt );
  46. iRet = ORIGINAL_API(wvsprintfA)(
  47. lpOut,
  48. lpFmt,
  49. argptr);
  50. va_end( argptr );
  51. return iRet;
  52. }
  53. int
  54. APIHOOK(wvsprintfA)(
  55. LPSTR lpOut,
  56. LPCSTR lpFmt,
  57. va_list arglist)
  58. {
  59. int iRet = 0;
  60. __try {
  61. iRet = ORIGINAL_API(wvsprintfA)(
  62. lpOut,
  63. lpFmt,
  64. arglist);
  65. }
  66. __except (EXCEPTION_EXECUTE_HANDLER) {
  67. if (g_iWorkMode == ARGLISTFIX_MODE)
  68. {
  69. DPFN( eDbgLevelInfo,
  70. "Exception occurs in wvsprintfA. \narglist contains pointer to string: %s.\n" , arglist);
  71. iRet = Fix_wvsprintf_ArgList(lpOut,lpFmt,arglist);
  72. }
  73. else
  74. {
  75. // Copied from Win9x's wvsprintfA
  76. __try {
  77. // tie off the output
  78. *lpOut = 0;
  79. }
  80. __except( EXCEPTION_EXECUTE_HANDLER) {
  81. // Do nothing
  82. }
  83. iRet = 0;
  84. }
  85. }
  86. return iRet;
  87. }
  88. void ParseCommandLine()
  89. {
  90. CString csCmdLine(COMMAND_LINE);
  91. if (csCmdLine.CompareNoCase(L"arglistfix") == 0)
  92. {
  93. DPFN( eDbgLevelInfo,
  94. "HandleWvsprintfExceptions called with argument: %S.\n", csCmdLine.Get());
  95. DPFN( eDbgLevelInfo,
  96. "HandleWvsprintfExceptions mode: Argument List Fix.\n");
  97. g_iWorkMode = ARGLISTFIX_MODE;
  98. }
  99. else
  100. {
  101. DPFN( eDbgLevelInfo,
  102. "HandleWvsprintfExceptions called with no argument.\n");
  103. DPFN( eDbgLevelInfo,
  104. "HandleWvsprintfExceptions mode: Win9x.\n");
  105. g_iWorkMode = WIN9X_MODE;
  106. }
  107. }
  108. /*++
  109. Handle DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH in your notify function
  110. to do initialization and uninitialization.
  111. IMPORTANT: Make sure you ONLY call NTDLL, KERNEL32 and MSVCRT APIs during
  112. DLL_PROCESS_ATTACH notification. No other DLLs are initialized at that
  113. point.
  114. --*/
  115. BOOL
  116. NOTIFY_FUNCTION(
  117. DWORD fdwReason)
  118. {
  119. if (fdwReason == DLL_PROCESS_ATTACH) {
  120. DPFN( eDbgLevelInfo, "HandleWvsprintfExceptions initialized.");
  121. ParseCommandLine();
  122. }
  123. return TRUE;
  124. }
  125. /*++
  126. Register hooked functions
  127. --*/
  128. HOOK_BEGIN
  129. APIHOOK_ENTRY(USER32.DLL, wvsprintfA)
  130. CALL_NOTIFY_FUNCTION
  131. HOOK_END
  132. IMPLEMENT_SHIM_END