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

327 lines
9.3 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
EncompassMonitor.cpp
Abstract:
Filters messages from the apps CBT WindowsHook.
Notes:
This is a general purpose shim.
History:
1/30/2001 a-larrsh Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(EncompassMonitor)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(SetWindowsHookExA)
APIHOOK_ENUM_END
// Local Hook Information
HHOOK g_hCBTHook = NULL;
HOOKPROC g_OriginalEncompassMonitorCBTProc = NULL;
// Shared Data Infomation
#define SHARED_SECTION_NAME "EncompassMonitor_SharedMemoryData"
typedef struct
{
char szModuleFileName[MAX_PATH];
HANDLE hModule;
HOOKPROC pfnHookProc;
} SHARED_HOOK_INFO, *PSHARED_HOOK_INFO;
HANDLE g_hSharedMapping = NULL;
PSHARED_HOOK_INFO g_pSharedHookInfo = NULL;
// Creates Shared memory. Only called by the originial SHIM
void CreateSharedMemory(HMODULE hModule, HOOKPROC pfnHookProc)
{
HANDLE hSharedFile;
char szTempPath[MAX_PATH];
char szTempFileName[MAX_PATH];
DWORD dwTemp;
// create the memory mapped file necessary to comunicate between the original Instanace of SHIM
// and the following instances of SHIMS
if (GetTempPathA(sizeof(szTempPath), szTempPath) == 0)
{
DPFN( eDbgLevelError, "GetTempPath failed\n");
goto errCreateSharedSection;
}
if (GetTempFileNameA(szTempPath, "mem", NULL, szTempFileName) == 0)
{
DPFN( eDbgLevelError, "GetTempFileName failed\n");
goto errCreateSharedSection;
}
hSharedFile = CreateFileA( szTempFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (hSharedFile == NULL)
{
DPFN( eDbgLevelError, "CreateFile failed to create '%s'\n", szTempFileName);
goto errCreateSharedSection;
}
// Increase size of file (create the mapping)
g_hSharedMapping = CreateFileMappingA( hSharedFile,
NULL,
PAGE_READWRITE,
NULL,
sizeof(SHARED_HOOK_INFO),
SHARED_SECTION_NAME);
if (g_hSharedMapping == NULL)
{
DPFN( eDbgLevelError, "CreateFileMapping failed\n");
goto errCreateSharedSection;
}
g_pSharedHookInfo = (PSHARED_HOOK_INFO)MapViewOfFile(g_hSharedMapping,
FILE_MAP_ALL_ACCESS,
0,
0,
sizeof(SHARED_HOOK_INFO));
if (g_pSharedHookInfo == NULL)
{
DWORD dwErr = GetLastError();
DPFN( eDbgLevelError, "MapViewOfFile failed [%d]", (int)dwErr);
goto errCreateSharedSection;
}
CloseHandle(hSharedFile);
g_pSharedHookInfo->hModule = hModule;
g_pSharedHookInfo->pfnHookProc = pfnHookProc;
GetModuleFileNameA(hModule, g_pSharedHookInfo->szModuleFileName, MAX_PATH);
if (!FlushViewOfFile(g_pSharedHookInfo, sizeof(SHARED_HOOK_INFO)))
{
DPFN( eDbgLevelError, "FlushViewOfFile failed\n");
goto errCreateSharedSection;
}
DPFN( eDbgLevelInfo, "WRITE::Shared Section Successful");
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->hModule=%x", g_pSharedHookInfo->hModule);
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->pfnHookProc=%x", g_pSharedHookInfo->pfnHookProc);
DPFN( eDbgLevelInfo, "WRITE::g_pSharedHookInfo->szModuleFileName=%s", g_pSharedHookInfo->szModuleFileName);
return;
errCreateSharedSection:
DPFN( eDbgLevelError, "WRITE::Shared Section FAILED");
return;
}
// Gets Shared Memory - Only called by injected versions of hook function
void GetSharedMemory()
{
HANDLE hSharedFileMapping = NULL;
void *pSharedMem = NULL;
hSharedFileMapping = OpenFileMappingA( FILE_MAP_ALL_ACCESS,
FALSE,
SHARED_SECTION_NAME);
if (hSharedFileMapping != NULL)
{
PSHARED_HOOK_INFO pSharedHookInfo = (PSHARED_HOOK_INFO)MapViewOfFile( hSharedFileMapping,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (pSharedHookInfo)
{
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->hModule=%x", pSharedHookInfo->hModule);
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->pfnHookProc=%x", pSharedHookInfo->pfnHookProc);
DPFN( eDbgLevelInfo, "READ::pSharedHookInfo->szModuleFileName=%s", pSharedHookInfo->szModuleFileName);
// Load DLL with origianl CBT Proc in it.
HANDLE hMod = LoadLibraryA(pSharedHookInfo->szModuleFileName);
if (!hMod)
{
DPFN( eDbgLevelError, "LoadLibrary(\"%s\") - FAILED", pSharedHookInfo->szModuleFileName);
}
g_OriginalEncompassMonitorCBTProc = (HOOKPROC)((DWORD)hMod + ((DWORD)pSharedHookInfo->pfnHookProc) - (DWORD)pSharedHookInfo->hModule);
DPFN( eDbgLevelInfo, "READ::Shared Section Successful - Original Hook at %x", g_OriginalEncompassMonitorCBTProc);
CloseHandle(hSharedFileMapping);
UnmapViewOfFile(pSharedHookInfo);
}
else
{
DPFN( eDbgLevelError, "MapViewOfFile() Failed");
}
}
else
{
DPFN( eDbgLevelError, "READ::Shared Section Failed");
}
}
// Replacement CBT Hook function
LRESULT CALLBACK Filtered_EncompassMonitorCBTProc(
int nCode, // hook code
WPARAM wParam, // depends on hook code
LPARAM lParam // depends on hook code
)
{
LRESULT lResult = 0; // Allow operation to continue
bool bFilterMessage = false;
if(g_OriginalEncompassMonitorCBTProc == NULL)
{
GetSharedMemory();
}
if (nCode == HCBT_CREATEWND)
{
CBT_CREATEWNDA *pccw = (CBT_CREATEWNDA*)lParam;
if ( (IS_INTRESOURCE(pccw->lpcs->lpszClass)) )
{
char szBuf[256];
GetClassNameA((HWND)wParam, szBuf, 255);
bFilterMessage=true;
DPFN( eDbgLevelInfo, "[%x] - Filtered_EncompassMonitorCBTProc::HCBT_CREATEWND %s [ATOM CLASS FILTERED]", g_OriginalEncompassMonitorCBTProc, szBuf);
}
else
{
DPFN( eDbgLevelInfo, "[%x] - Filtered_EncompassMonitorCBTProc::HCBT_CREATEWND %s ", g_OriginalEncompassMonitorCBTProc, pccw->lpcs->lpszClass);
}
}
if ( g_OriginalEncompassMonitorCBTProc )
{
if (bFilterMessage)
{
lResult = CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
}
else
{
lResult = g_OriginalEncompassMonitorCBTProc(nCode, wParam, lParam);
}
}
else
{
DPFN( eDbgLevelError, "Filtered_EncompassMonitorCBTProc:: ** BAD g_OriginalEncompassMonitorCBTProc2 **");
lResult = CallNextHookEx(g_hCBTHook, nCode, wParam, lParam);
}
return lResult;
}
// SHIMMED API
HHOOK APIHOOK(SetWindowsHookExA)(
int idHook, // hook type
HOOKPROC lpfn, // hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // thread identifier
)
{
static int nNumCBThooks = 0;
HHOOK hHook;
if (idHook == WH_CBT)
{
nNumCBThooks++;
switch(nNumCBThooks)
{
case 1:
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
DPFN( eDbgLevelInfo, "%x=SetWindowsHookEx(%d, %x, %x, %x) - Ignoring First Hook Call", hHook, idHook, lpfn, hMod, dwThreadId);
break;
case 2:
g_OriginalEncompassMonitorCBTProc = lpfn;
g_hCBTHook = hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, Filtered_EncompassMonitorCBTProc, g_hinstDll, dwThreadId);
DPFN( eDbgLevelInfo, "%x=SetWindowsHookEx(%d, %x, %x, %x) - Replacing Hook with Filtered_EncompassMonitorCBTProc", hHook, idHook, lpfn, hMod, dwThreadId);
CreateSharedMemory(hMod, lpfn);
break;
default:
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
DPFN( eDbgLevelError, "SetWindowsHookEx -- More then 2 WH_CBT hooks [%d]", nNumCBThooks);
break;
}
}
else
{
hHook = ORIGINAL_API(SetWindowsHookExA)(idHook, lpfn, hMod, dwThreadId);
}
return hHook;
}
BOOL
NOTIFY_FUNCTION(DWORD fdwReason)
{
if (fdwReason == DLL_PROCESS_DETACH)
{
if (g_hSharedMapping)
{
CloseHandle(g_hSharedMapping);
g_hSharedMapping = NULL;
}
if (g_pSharedHookInfo)
{
UnmapViewOfFile(g_pSharedHookInfo);
g_pSharedHookInfo = NULL;
}
}
return TRUE;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
CALL_NOTIFY_FUNCTION
APIHOOK_ENTRY(USER32.DLL, SetWindowsHookExA)
HOOK_END
IMPLEMENT_SHIM_END