177 lines
3.7 KiB
C++
177 lines
3.7 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
HandleWvsprintfExceptions.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This fix provides a facility to fix argument list from LPSTR into va_list.
|
||
|
|
||
|
Some native Win9x app use LPSTR (pointer of string) instead of
|
||
|
va_list (pointer to pointer of string).
|
||
|
Without properly checking the return value, these apps assume that it is safe
|
||
|
to use wvsprintf like that because it doesn't cause AV.
|
||
|
In NT, this will cause AV.
|
||
|
|
||
|
This shim takes one command line: "arglistfix" (case insensitive).
|
||
|
By default - if there is no command line - it will do exactly
|
||
|
what Win9x's wvsprintfA has :
|
||
|
Do nothing inside the exception handler if there is an exception occurs.
|
||
|
If arglistfix specified in command line, it will try to fix the argument
|
||
|
list (va_list).
|
||
|
|
||
|
History:
|
||
|
|
||
|
09/29/2000 andyseti Created
|
||
|
11/28/2000 jdoherty Converted to framework version 2
|
||
|
03/15/2001 robkenny Converted to CString
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
|
||
|
int g_iWorkMode = 0;
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
WIN9X_MODE = 0,
|
||
|
ARGLISTFIX_MODE
|
||
|
} TEST;
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(HandleWvsprintfExceptions)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
//
|
||
|
// Add APIs that you wish to hook to this macro construction.
|
||
|
//
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(wvsprintfA)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
int Fix_wvsprintf_ArgList(
|
||
|
LPSTR lpOut,
|
||
|
LPCSTR lpFmt,
|
||
|
...)
|
||
|
{
|
||
|
int iRet;
|
||
|
|
||
|
va_list argptr;
|
||
|
va_start( argptr, lpFmt );
|
||
|
|
||
|
iRet = ORIGINAL_API(wvsprintfA)(
|
||
|
lpOut,
|
||
|
lpFmt,
|
||
|
argptr);
|
||
|
|
||
|
va_end( argptr );
|
||
|
return iRet;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
APIHOOK(wvsprintfA)(
|
||
|
LPSTR lpOut,
|
||
|
LPCSTR lpFmt,
|
||
|
va_list arglist)
|
||
|
{
|
||
|
int iRet = 0;
|
||
|
|
||
|
__try {
|
||
|
iRet = ORIGINAL_API(wvsprintfA)(
|
||
|
lpOut,
|
||
|
lpFmt,
|
||
|
arglist);
|
||
|
}
|
||
|
|
||
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
|
||
|
if (g_iWorkMode == ARGLISTFIX_MODE)
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo,
|
||
|
"Exception occurs in wvsprintfA. \narglist contains pointer to string: %s.\n" , arglist);
|
||
|
iRet = Fix_wvsprintf_ArgList(lpOut,lpFmt,arglist);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Copied from Win9x's wvsprintfA
|
||
|
__try {
|
||
|
// tie off the output
|
||
|
*lpOut = 0;
|
||
|
}
|
||
|
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER) {
|
||
|
// Do nothing
|
||
|
}
|
||
|
|
||
|
iRet = 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return iRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
void ParseCommandLine()
|
||
|
{
|
||
|
CString csCmdLine(COMMAND_LINE);
|
||
|
|
||
|
if (csCmdLine.CompareNoCase(L"arglistfix") == 0)
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo,
|
||
|
"HandleWvsprintfExceptions called with argument: %S.\n", csCmdLine.Get());
|
||
|
DPFN( eDbgLevelInfo,
|
||
|
"HandleWvsprintfExceptions mode: Argument List Fix.\n");
|
||
|
g_iWorkMode = ARGLISTFIX_MODE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelInfo,
|
||
|
"HandleWvsprintfExceptions called with no argument.\n");
|
||
|
DPFN( eDbgLevelInfo,
|
||
|
"HandleWvsprintfExceptions mode: Win9x.\n");
|
||
|
g_iWorkMode = WIN9X_MODE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Handle DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH in your notify function
|
||
|
to do initialization and uninitialization.
|
||
|
|
||
|
IMPORTANT: Make sure you ONLY call NTDLL, KERNEL32 and MSVCRT APIs during
|
||
|
DLL_PROCESS_ATTACH notification. No other DLLs are initialized at that
|
||
|
point.
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(
|
||
|
DWORD fdwReason)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH) {
|
||
|
DPFN( eDbgLevelInfo, "HandleWvsprintfExceptions initialized.");
|
||
|
ParseCommandLine();
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
APIHOOK_ENTRY(USER32.DLL, wvsprintfA)
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|