windows-nt/Source/XPSP1/NT/windows/appcompat/shims/general/ignoremessagebox.cpp
2020-09-26 16:20:57 +08:00

345 lines
9.2 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
IgnoreMessageBox.cpp
Abstract:
This APIHooks MessageBox and based on the passed in command line prevents the
message box from being displayed. Many applications display a message box with
some debugging or other extraneous comment. This is normally the result of
differences between Windows 98 and Whistler.
command line syntax:
text,caption;text1,caption1
The passed in command line is composed of a pair of one or more strings separated
by semicolons. These string pairs form the text and caption that must match in order
to block the display of the message box. If either the caption or text are not needed
then they can be left blank. For example, "block this text,;" would prevent the message
box from being displayed if the text passed to the message box was: block this text" the
caption parameter would not be used. The following are some examples:
"error message 1000,Error" - would not display the message box if the
lpCaption parameter contained Error and
the lpText parameter contained error
message 1000
"error message 1000," - would not display the message box if the
lpText parameter contained error message 1000
",Error" - would not display any message boxes if the
lpCaption parameter contained Error
"message1,Error;message2,Error2 - would not display the message box if the
lpText parameter contained message1 and
the lpCaption parameter contained Error or
the lpText parameter contained message2 and
the lpCaption paramter contained Error2.
The match is performed on the command line string to the current message box
parameter string. The command line string can contain wildcard specification
characters. This allows complex out of order matching to take place see below:
? match one character in this position
* match zero or more characters in this position
If the source string contains any ? * , ; \ characters, precede them with a backslash.
For example, the following command line would match the indicated text and caption:
Text: "Compatibility; A *very* important thing."
Caption: "D:\WORD\COMPAT.DOC"
Command line: "Compatibility\; A \*very\* important thing.,D:\\WORD\\COMPAT.DOC"
Notes:
History:
04/06/2000 philipdu Created
04/06/2000 markder Added wide-character conversion, plus Ex versions.
05/23/2001 mnikkel Added W routines so we can pick up system messagebox calls
--*/
#include "precomp.h"
#include "CharVector.h"
IMPLEMENT_SHIM_BEGIN(IgnoreMessageBox)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(MessageBoxA)
APIHOOK_ENUM_ENTRY(MessageBoxExA)
APIHOOK_ENUM_ENTRY(MessageBoxW)
APIHOOK_ENUM_ENTRY(MessageBoxExW)
APIHOOK_ENUM_END
class MBPair
{
public:
CString csText;
CString csCaption;
};
VectorT<MBPair> * g_IgnoreList = NULL;
BOOL IsBlockMessage(LPCSTR szOrigText, LPCSTR szOrigCaption)
{
CSTRING_TRY
{
CString csText(szOrigText);
CString csCaption(szOrigCaption);
for (int i = 0; i < g_IgnoreList->Size(); ++i)
{
const MBPair & mbPair = g_IgnoreList->Get(i);
BOOL bTextMatch = mbPair.csText.IsEmpty() || csText.PatternMatch(mbPair.csText);
BOOL bTitleMatch = mbPair.csCaption.IsEmpty() || csCaption.PatternMatch(mbPair.csCaption);
if (bTextMatch && bTitleMatch)
{
return TRUE;
}
}
}
CSTRING_CATCH
{
// Do Nothing
}
return FALSE;
}
BOOL IsBlockMessageW(LPWSTR szOrigText, LPWSTR szOrigCaption)
{
CSTRING_TRY
{
CString csText(szOrigText);
CString csCaption(szOrigCaption);
for (int i = 0; i < g_IgnoreList->Size(); ++i)
{
const MBPair & mbPair = g_IgnoreList->Get(i);
BOOL bTextMatch = mbPair.csText.IsEmpty() || csText.PatternMatch(mbPair.csText);
BOOL bTitleMatch = mbPair.csCaption.IsEmpty() || csCaption.PatternMatch(mbPair.csCaption);
if (bTextMatch && bTitleMatch)
{
return TRUE;
}
}
}
CSTRING_CATCH
{
// Do Nothing
}
return FALSE;
}
int
APIHOOK(MessageBoxA)(
HWND hWnd, // handle to owner window
LPCSTR lpText, // text in message box
LPCSTR lpCaption, // message box title
UINT uType // message box style
)
{
int iReturnValue;
//if this is the passed in string that we want do not
//want to display then simply return to caller.
if (IsBlockMessage(lpText, lpCaption))
{
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] MessageBoxA swallowed:\n");
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Caption = \"%s\"\n", lpCaption);
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Text = \"%s\"\n", lpText);
return MB_OK;
}
iReturnValue = ORIGINAL_API(MessageBoxA)(
hWnd,
lpText,
lpCaption,
uType);
return iReturnValue;
}
int
APIHOOK(MessageBoxExA)(
HWND hWnd, // handle to owner window
LPCSTR lpText, // text in message box
LPCSTR lpCaption, // message box title
UINT uType, // message box style
WORD wLanguageId // language identifier
)
{
int iReturnValue;
//if this is the passed in string that we want do not
//want to display then simply return to caller.
if (IsBlockMessage(lpText, lpCaption))
{
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] MessageBoxExA swallowed:\n");
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Caption = \"%s\"\n", lpCaption);
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Text = \"%s\"\n", lpText);
return MB_OK;
}
iReturnValue = ORIGINAL_API(MessageBoxExA)(
hWnd,
lpText,
lpCaption,
uType,
wLanguageId);
return iReturnValue;
}
int
APIHOOK(MessageBoxW)(
HWND hWnd, // handle to owner window
LPWSTR lpText, // text in message box
LPWSTR lpCaption, // message box title
UINT uType // message box style
)
{
int iReturnValue;
//if this is the passed in string that we want do not
//want to display then simply return to caller.
if (IsBlockMessageW(lpText, lpCaption))
{
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] MessageBoxW swallowed:\n");
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Caption = \"%S\"\n", lpCaption);
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Text = \"%S\"\n", lpText);
return MB_OK;
}
iReturnValue = ORIGINAL_API(MessageBoxW)(
hWnd,
lpText,
lpCaption,
uType);
return iReturnValue;
}
int
APIHOOK(MessageBoxExW)(
HWND hWnd, // handle to owner window
LPWSTR lpText, // text in message box
LPWSTR lpCaption, // message box title
UINT uType, // message box style
WORD wLanguageId // language identifier
)
{
int iReturnValue;
//if this is the passed in string that we want do not
//want to display then simply return to caller.
if (IsBlockMessageW(lpText, lpCaption))
{
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] MessageBoxExW swallowed:\n");
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Caption = \"%S\"\n", lpCaption);
DPFN( eDbgLevelInfo, "[IgnoreMessageBox] Text = \"%S\"\n", lpText);
return MB_OK;
}
iReturnValue = ORIGINAL_API(MessageBoxExW)(
hWnd,
lpText,
lpCaption,
uType,
wLanguageId);
return iReturnValue;
}
BOOL
ParseCommandLine(const char * cl)
{
CSTRING_TRY
{
CStringToken csCommandLine(COMMAND_LINE, ";");
CString csTok;
g_IgnoreList = new VectorT<MBPair>;
if (!g_IgnoreList)
{
return FALSE;
}
while (csCommandLine.GetToken(csTok))
{
MBPair mbPair;
CStringToken csMB(csTok, ",");
csMB.GetToken(mbPair.csText);
csMB.GetToken(mbPair.csCaption);
if (!g_IgnoreList->AppendConstruct(mbPair))
{
return FALSE;
}
}
}
CSTRING_CATCH
{
// Fall through
LOGN(eDbgLevelError, "[ParseCommandLine] Illegal command line");
}
return g_IgnoreList && g_IgnoreList->Size() > 0;
}
BOOL
NOTIFY_FUNCTION(
DWORD fdwReason
)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
return ParseCommandLine(COMMAND_LINE);
}
return TRUE;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
CALL_NOTIFY_FUNCTION
APIHOOK_ENTRY(USER32.DLL, MessageBoxA)
APIHOOK_ENTRY(USER32.DLL, MessageBoxExA)
APIHOOK_ENTRY(USER32.DLL, MessageBoxW)
APIHOOK_ENTRY(USER32.DLL, MessageBoxExW)
HOOK_END
IMPLEMENT_SHIM_END