1181 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			1181 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
	
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| //  Detours Test Program (trcser.cpp of trcser.dll)
 | |
| //
 | |
| //  Microsoft Research Detours Package
 | |
| //
 | |
| //  Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //
 | |
| #define _WIN32_WINNT        0x0400
 | |
| #define WIN32
 | |
| #define NT
 | |
| 
 | |
| #define DBG_TRACE   0
 | |
| 
 | |
| #include <windows.h>
 | |
| #include <stdio.h>
 | |
| #include "detours.h"
 | |
| #include "syelog.h"
 | |
| 
 | |
| #define PULONG_PTR          PVOID
 | |
| #define PLONG_PTR           PVOID
 | |
| #define ULONG_PTR           PVOID
 | |
| #define ENUMRESNAMEPROCA    PVOID
 | |
| #define ENUMRESNAMEPROCW    PVOID
 | |
| #define ENUMRESLANGPROCA    PVOID
 | |
| #define ENUMRESLANGPROCW    PVOID
 | |
| #define ENUMRESTYPEPROCA    PVOID
 | |
| #define ENUMRESTYPEPROCW    PVOID
 | |
| #define STGOPTIONS          PVOID
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////
 | |
| #pragma warning(disable:4127)   // Many of our asserts are constants.
 | |
| 
 | |
| #define ASSERT_ALWAYS(x)   \
 | |
|     do {                                                        \
 | |
|     if (!(x)) {                                                 \
 | |
|             AssertMessage(#x, __FILE__, __LINE__);              \
 | |
|             DebugBreak();                                       \
 | |
|     }                                                           \
 | |
|     } while (0)
 | |
| 
 | |
| #ifndef NDEBUG
 | |
| #define ASSERT(x)           ASSERT_ALWAYS(x)
 | |
| #else
 | |
| #define ASSERT(x)
 | |
| #endif
 | |
| 
 | |
| #define UNUSED(c)       (c) = (c)
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////
 | |
| static HMODULE s_hInst = NULL;
 | |
| static CHAR s_szDllPath[MAX_PATH];
 | |
| 
 | |
| VOID _PrintDump(HANDLE h, PCHAR pszData, INT cbData);
 | |
| VOID _PrintEnter(PCSTR psz, ...);
 | |
| VOID _PrintExit(PCSTR psz, ...);
 | |
| VOID _Print(PCSTR psz, ...);
 | |
| 
 | |
| VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine);
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| extern "C" {
 | |
|     HANDLE (WINAPI * Real_CreateFileW)(LPCWSTR a0,
 | |
|                                        DWORD a1,
 | |
|                                        DWORD a2,
 | |
|                                        LPSECURITY_ATTRIBUTES a3,
 | |
|                                        DWORD a4,
 | |
|                                        DWORD a5,
 | |
|                                        HANDLE a6)
 | |
|         = CreateFileW;
 | |
| 
 | |
|     BOOL (WINAPI * Real_WriteFile)(HANDLE hFile,
 | |
|                                      LPCVOID lpBuffer,
 | |
|                                      DWORD nNumberOfBytesToWrite,
 | |
|                                      LPDWORD lpNumberOfBytesWritten,
 | |
|                                      LPOVERLAPPED lpOverlapped)
 | |
|         = WriteFile;
 | |
|     BOOL (WINAPI * Real_FlushFileBuffers)(HANDLE hFile)
 | |
|         = FlushFileBuffers;
 | |
|     BOOL (WINAPI * Real_CloseHandle)(HANDLE hObject)
 | |
|         = CloseHandle;
 | |
| 
 | |
|     BOOL (WINAPI * Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
 | |
|         = WaitNamedPipeW;
 | |
|     BOOL (WINAPI * Real_SetNamedPipeHandleState)(HANDLE hNamedPipe,
 | |
|                                                    LPDWORD lpMode,
 | |
|                                                    LPDWORD lpMaxCollectionCount,
 | |
|                                                    LPDWORD lpCollectDataTimeout)
 | |
|         = SetNamedPipeHandleState;
 | |
| 
 | |
|     DWORD (WINAPI * Real_GetCurrentProcessId)(VOID)
 | |
|         = GetCurrentProcessId;
 | |
|     VOID (WINAPI * Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime)
 | |
|         = GetSystemTimeAsFileTime;
 | |
| 
 | |
|     VOID (WINAPI * Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection)
 | |
|         = InitializeCriticalSection;
 | |
|     VOID (WINAPI * Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection)
 | |
|         = EnterCriticalSection;
 | |
|     VOID (WINAPI * Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection)
 | |
|         = LeaveCriticalSection;
 | |
| }
 | |
| 
 | |
| DWORD (WINAPI * Real_GetModuleFileNameW)(HMODULE a0,
 | |
|                                          LPWSTR a1,
 | |
|                                          DWORD a2)
 | |
|     = GetModuleFileNameW;
 | |
| 
 | |
| DWORD (WINAPI * Real_GetModuleFileNameA)(HMODULE a0,
 | |
|                                          LPSTR a1,
 | |
|                                          DWORD a2)
 | |
|     = GetModuleFileNameA;
 | |
| 
 | |
| BOOL (WINAPI * Real_CreateProcessW)(LPCWSTR a0,
 | |
|                                     LPWSTR a1,
 | |
|                                     LPSECURITY_ATTRIBUTES a2,
 | |
|                                     LPSECURITY_ATTRIBUTES a3,
 | |
|                                     BOOL a4,
 | |
|                                     DWORD a5,
 | |
|                                     LPVOID a6,
 | |
|                                     LPCWSTR a7,
 | |
|                                     struct _STARTUPINFOW* a8,
 | |
|                                     LPPROCESS_INFORMATION a9)
 | |
|     = CreateProcessW;
 | |
| 
 | |
| BOOL (WINAPI * Real_BuildCommDCBA)(LPCSTR a0,
 | |
|                                    struct _DCB* a1)
 | |
|     = BuildCommDCBA;
 | |
| 
 | |
| BOOL (WINAPI * Real_BuildCommDCBAndTimeoutsA)(LPCSTR a0,
 | |
|                                               struct _DCB* a1,
 | |
|                                               struct _COMMTIMEOUTS* a2)
 | |
|     = BuildCommDCBAndTimeoutsA;
 | |
| 
 | |
| BOOL (WINAPI * Real_BuildCommDCBAndTimeoutsW)(LPCWSTR a0,
 | |
|                                               struct _DCB* a1,
 | |
|                                               struct _COMMTIMEOUTS* a2)
 | |
|     = BuildCommDCBAndTimeoutsW;
 | |
| 
 | |
| BOOL (WINAPI * Real_BuildCommDCBW)(LPCWSTR a0,
 | |
|                                    struct _DCB* a1)
 | |
|     = BuildCommDCBW;
 | |
| 
 | |
| BOOL (WINAPI * Real_ClearCommBreak)(HANDLE a0)
 | |
|     = ClearCommBreak;
 | |
| 
 | |
| BOOL (WINAPI * Real_ClearCommError)(HANDLE a0,
 | |
|                                     LPDWORD a1,
 | |
|                                     struct _COMSTAT* a2)
 | |
|     = ClearCommError;
 | |
| 
 | |
| HANDLE (WINAPI * Real_CreateFileA)(LPCSTR a0,
 | |
|                                    DWORD a1,
 | |
|                                    DWORD a2,
 | |
|                                    LPSECURITY_ATTRIBUTES a3,
 | |
|                                    DWORD a4,
 | |
|                                    DWORD a5,
 | |
|                                    HANDLE a6)
 | |
|     = CreateFileA;
 | |
| 
 | |
| BOOL (WINAPI * Real_EscapeCommFunction)(HANDLE a0,
 | |
|                                         DWORD a1)
 | |
|     = EscapeCommFunction;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommConfig)(HANDLE a0,
 | |
|                                    LPCOMMCONFIG a1,
 | |
|                                    LPDWORD a2)
 | |
|     = GetCommConfig;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommMask)(HANDLE a0,
 | |
|                                  LPDWORD a1)
 | |
|     = GetCommMask;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommModemStatus)(HANDLE a0,
 | |
|                                         LPDWORD a1)
 | |
|     = GetCommModemStatus;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommProperties)(HANDLE a0,
 | |
|                                        LPCOMMPROP a1)
 | |
|     = GetCommProperties;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommState)(HANDLE a0,
 | |
|                                   struct _DCB* a1)
 | |
|     = GetCommState;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetCommTimeouts)(HANDLE a0,
 | |
|                                      struct _COMMTIMEOUTS* a1)
 | |
|     = GetCommTimeouts;
 | |
| 
 | |
| DWORD (WINAPI * Real_GetCurrentThreadId)(void)
 | |
|     = GetCurrentThreadId;
 | |
| 
 | |
| BOOL (WINAPI * Real_GetOverlappedResult)(HANDLE a0,
 | |
|                                          LPOVERLAPPED a1,
 | |
|                                          LPDWORD a2,
 | |
|                                          BOOL a3)
 | |
|     = GetOverlappedResult;
 | |
| 
 | |
| BOOL (WINAPI * Real_PurgeComm)(HANDLE a0,
 | |
|                                DWORD a1)
 | |
|     = PurgeComm;
 | |
| 
 | |
| BOOL (WINAPI * Real_ReadFile)(HANDLE a0,
 | |
|                               LPVOID a1,
 | |
|                               DWORD a2,
 | |
|                               LPDWORD a3,
 | |
|                               LPOVERLAPPED a4)
 | |
|     = ReadFile;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetCommBreak)(HANDLE a0)
 | |
|     = SetCommBreak;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetCommConfig)(HANDLE a0,
 | |
|                                    LPCOMMCONFIG a1,
 | |
|                                    DWORD a2)
 | |
|     = SetCommConfig;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetCommMask)(HANDLE a0,
 | |
|                                  DWORD a1)
 | |
|     = SetCommMask;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetCommState)(HANDLE a0,
 | |
|                                   struct _DCB* a1)
 | |
|     = SetCommState;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetCommTimeouts)(HANDLE a0,
 | |
|                                      struct _COMMTIMEOUTS* a1)
 | |
|     = SetCommTimeouts;
 | |
| 
 | |
| BOOL (WINAPI * Real_SetupComm)(HANDLE a0,
 | |
|                                DWORD a1,
 | |
|                                DWORD a2)
 | |
|     = SetupComm;
 | |
| 
 | |
| BOOL (WINAPI * Real_TransmitCommChar)(HANDLE a0,
 | |
|                                       char a1)
 | |
|     = TransmitCommChar;
 | |
| 
 | |
| BOOL (WINAPI * Real_WaitCommEvent)(HANDLE a0,
 | |
|                                    LPDWORD a1,
 | |
|                                    LPOVERLAPPED a2)
 | |
|     = WaitCommEvent;
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| // Detours
 | |
| //
 | |
| 
 | |
| BOOL WINAPI Mine_CreateProcessW(LPCWSTR lpApplicationName,
 | |
|                                 LPWSTR lpCommandLine,
 | |
|                                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 | |
|                                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 | |
|                                 BOOL bInheritHandles,
 | |
|                                 DWORD dwCreationFlags,
 | |
|                                 LPVOID lpEnvironment,
 | |
|                                 LPCWSTR lpCurrentDirectory,
 | |
|                                 LPSTARTUPINFOW lpStartupInfo,
 | |
|                                 LPPROCESS_INFORMATION lpProcessInformation)
 | |
| {
 | |
|     _PrintEnter("CreateProcessW(%ls,%ls,%p,%p,%x,%x,%p,%ls,%p,%p)\n",
 | |
|                 lpApplicationName,
 | |
|                 lpCommandLine,
 | |
|                 lpProcessAttributes,
 | |
|                 lpThreadAttributes,
 | |
|                 bInheritHandles,
 | |
|                 dwCreationFlags,
 | |
|                 lpEnvironment,
 | |
|                 lpCurrentDirectory,
 | |
|                 lpStartupInfo,
 | |
|                 lpProcessInformation);
 | |
| 
 | |
|     _Print("Calling DetourCreateProcessWithDllExW(,%hs)\n", s_szDllPath);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = DetourCreateProcessWithDllExW(lpApplicationName,
 | |
|                                            lpCommandLine,
 | |
|                                            lpProcessAttributes,
 | |
|                                            lpThreadAttributes,
 | |
|                                            bInheritHandles,
 | |
|                                            dwCreationFlags,
 | |
|                                            lpEnvironment,
 | |
|                                            lpCurrentDirectory,
 | |
|                                            lpStartupInfo,
 | |
|                                            lpProcessInformation,
 | |
|                                            s_szDllPath,
 | |
|                                            Real_CreateProcessW);
 | |
|     } __finally {
 | |
|         _PrintExit("CreateProcessW(,,,,,,,,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_BuildCommDCBA(LPCSTR a0,
 | |
|                                LPDCB a1)
 | |
| {
 | |
|     _PrintEnter("BuildCommDCBA(%hs,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_BuildCommDCBA(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("BuildCommDCBA(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_BuildCommDCBAndTimeoutsA(LPCSTR a0,
 | |
|                                           LPDCB a1,
 | |
|                                           LPCOMMTIMEOUTS a2)
 | |
| {
 | |
|     _PrintEnter("BuildCommDCBAndTimeoutsA(%hs,%p,%p)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_BuildCommDCBAndTimeoutsA(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("BuildCommDCBAndTimeoutsA(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_BuildCommDCBAndTimeoutsW(LPCWSTR a0,
 | |
|                                           LPDCB a1,
 | |
|                                           LPCOMMTIMEOUTS a2)
 | |
| {
 | |
|     _PrintEnter("BuildCommDCBAndTimeoutsW(%ls,%p,%p)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_BuildCommDCBAndTimeoutsW(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("BuildCommDCBAndTimeoutsW(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_BuildCommDCBW(LPCWSTR a0,
 | |
|                                LPDCB a1)
 | |
| {
 | |
|     _PrintEnter("BuildCommDCBW(%ls,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_BuildCommDCBW(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("BuildCommDCBW(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_ClearCommBreak(HANDLE a0)
 | |
| {
 | |
|     _PrintEnter("ClearCommBreak(%p)\n", a0);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_ClearCommBreak(a0);
 | |
|     } __finally {
 | |
|         _PrintExit("ClearCommBreak() -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_ClearCommError(HANDLE a0,
 | |
|                                 LPDWORD a1,
 | |
|                                 LPCOMSTAT a2)
 | |
| {
 | |
|     _PrintEnter("ClearCommError(%p,%p,%p)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_ClearCommError(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("ClearCommError(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_CloseHandle(HANDLE a0)
 | |
| {
 | |
|     _PrintEnter("CloseHandle(%p)\n", a0);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_CloseHandle(a0);
 | |
|     } __finally {
 | |
|         _PrintExit("CloseHandle() -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| HANDLE WINAPI Mine_CreateFileA(LPCSTR a0,
 | |
|                                DWORD a1,
 | |
|                                DWORD a2,
 | |
|                                LPSECURITY_ATTRIBUTES a3,
 | |
|                                DWORD a4,
 | |
|                                DWORD a5,
 | |
|                                HANDLE a6)
 | |
| {
 | |
|     _PrintEnter("CreateFileA(%hs,%x,%x,%p,%x,%x,%p)\n", a0, a1, a2, a3, a4, a5, a6);
 | |
| 
 | |
|     HANDLE rv = 0;
 | |
|     __try {
 | |
|         rv = Real_CreateFileA(a0, a1, a2, a3, a4, a5, a6);
 | |
|     } __finally {
 | |
|         _PrintExit("CreateFileA(,,,,,,) -> %p\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0,
 | |
|                                DWORD a1,
 | |
|                                DWORD a2,
 | |
|                                LPSECURITY_ATTRIBUTES a3,
 | |
|                                DWORD a4,
 | |
|                                DWORD a5,
 | |
|                                HANDLE a6)
 | |
| {
 | |
|     _PrintEnter("CreateFileW(%ls,%x,%x,%p,%x,%x,%p)\n", a0, a1, a2, a3, a4, a5, a6);
 | |
| 
 | |
|     HANDLE rv = 0;
 | |
|     __try {
 | |
|         rv = Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6);
 | |
|     } __finally {
 | |
|         _PrintExit("CreateFileW(,,,,,,) -> %p\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_EscapeCommFunction(HANDLE a0,
 | |
|                                     DWORD a1)
 | |
| {
 | |
|     _PrintEnter("EscapeCommFunction(%p,%x)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_EscapeCommFunction(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("EscapeCommFunction(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommConfig(HANDLE a0,
 | |
|                                LPCOMMCONFIG a1,
 | |
|                                LPDWORD a2)
 | |
| {
 | |
|     _PrintEnter("GetCommConfig(%p,%p,%p)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommConfig(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommConfig(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommMask(HANDLE a0,
 | |
|                                 LPDWORD a1)
 | |
| {
 | |
|     _PrintEnter("GetCommMask(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommMask(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommMask(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommModemStatus(HANDLE a0,
 | |
|                                     LPDWORD a1)
 | |
| {
 | |
|     _PrintEnter("GetCommModemStatus(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommModemStatus(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommModemStatus(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommProperties(HANDLE a0,
 | |
|                                    LPCOMMPROP a1)
 | |
| {
 | |
|     _PrintEnter("GetCommProperties(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommProperties(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommProperties(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommState(HANDLE a0,
 | |
|                               LPDCB a1)
 | |
| {
 | |
|     _PrintEnter("GetCommState(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommState(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommState(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetCommTimeouts(HANDLE a0,
 | |
|                                  LPCOMMTIMEOUTS a1)
 | |
| {
 | |
|     _PrintEnter("GetCommTimeouts(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCommTimeouts(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("GetCommTimeouts(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| DWORD WINAPI Mine_GetCurrentThreadId(void)
 | |
| {
 | |
|     _PrintEnter("GetCurrentThreadId()\n");
 | |
| 
 | |
|     DWORD rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetCurrentThreadId();
 | |
|     } __finally {
 | |
|         _PrintExit("GetCurrentThreadId() -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| DWORD WINAPI Mine_GetModuleFileNameW(HINSTANCE a0,
 | |
|                                      LPWSTR a1,
 | |
|                                      DWORD a2)
 | |
| {
 | |
|     _PrintEnter("GetModuleFileNameW(%p,%p,%x)\n", a0, a1, a2);
 | |
| 
 | |
|     DWORD rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetModuleFileNameW(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("GetModuleFileNameW(,%ls,) -> %x\n", a1, rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_GetOverlappedResult(HANDLE a0,
 | |
|                                      LPOVERLAPPED a1,
 | |
|                                      LPDWORD a2,
 | |
|                                      BOOL a3)
 | |
| {
 | |
|     _PrintEnter("GetOverlappedResult(%p,%p,%p,%x)\n", a0, a1, a2, a3);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_GetOverlappedResult(a0, a1, a2, a3);
 | |
|     } __finally {
 | |
|         _PrintExit("GetOverlappedResult(,,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_PurgeComm(HANDLE a0,
 | |
|                            DWORD a1)
 | |
| {
 | |
|     _PrintEnter("PurgeComm(%p,%x)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_PurgeComm(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("PurgeComm(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_ReadFile(HANDLE a0,
 | |
|                           LPVOID a1,
 | |
|                           DWORD a2,
 | |
|                           LPDWORD a3,
 | |
|                           LPOVERLAPPED a4)
 | |
| {
 | |
|     _PrintEnter("ReadFile(%p,%p,%x,%p,%p)\n", a0, a1, a2, a3, a4);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_ReadFile(a0, a1, a2, a3, a4);
 | |
|     } __finally {
 | |
|         _PrintExit("ReadFile(,,,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetCommBreak(HANDLE a0)
 | |
| {
 | |
|     _PrintEnter("SetCommBreak(%p)\n", a0);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetCommBreak(a0);
 | |
|     } __finally {
 | |
|         _PrintExit("SetCommBreak() -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetCommConfig(HANDLE a0,
 | |
|                                LPCOMMCONFIG a1,
 | |
|                                DWORD a2)
 | |
| {
 | |
|     _PrintEnter("SetCommConfig(%p,%p,%x)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetCommConfig(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("SetCommConfig(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetCommMask(HANDLE a0,
 | |
|                              DWORD a1)
 | |
| {
 | |
|     _PrintEnter("SetCommMask(%p,%x)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetCommMask(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("SetCommMask(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetCommState(HANDLE a0,
 | |
|                               LPDCB a1)
 | |
| {
 | |
|     _PrintEnter("SetCommState(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetCommState(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("SetCommState(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetCommTimeouts(HANDLE a0,
 | |
|                                  LPCOMMTIMEOUTS a1)
 | |
| {
 | |
|     _PrintEnter("SetCommTimeouts(%p,%p)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetCommTimeouts(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("SetCommTimeouts(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_SetupComm(HANDLE a0,
 | |
|                            DWORD a1,
 | |
|                            DWORD a2)
 | |
| {
 | |
|     _PrintEnter("SetupComm(%p,%x,%x)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_SetupComm(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("SetupComm(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_TransmitCommChar(HANDLE a0,
 | |
|                                   char a1)
 | |
| {
 | |
|     _PrintEnter("TransmitCommChar(%p,%x)\n", a0, a1);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_TransmitCommChar(a0, a1);
 | |
|     } __finally {
 | |
|         _PrintExit("TransmitCommChar(,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_WaitCommEvent(HANDLE a0,
 | |
|                                LPDWORD a1,
 | |
|                                LPOVERLAPPED a2)
 | |
| {
 | |
|     _PrintEnter("WaitCommEvent(%p,%p,%p)\n", a0, a1, a2);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = Real_WaitCommEvent(a0, a1, a2);
 | |
|     } __finally {
 | |
|         _PrintExit("WaitCommEvent(,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_WriteFile(HANDLE a0,
 | |
|                            LPCVOID a1,
 | |
|                            DWORD a2,
 | |
|                            LPDWORD a3,
 | |
|                            LPOVERLAPPED a4)
 | |
| {
 | |
|     _PrintEnter("WriteFile(%p,%p,%x,%p,%p)\n", a0, a1, a2, a3, a4);
 | |
| 
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         _PrintDump(a0, (PCHAR)a1, a2);
 | |
|         rv = Real_WriteFile(a0, a1, a2, a3, a4);
 | |
|     } __finally {
 | |
|         _PrintExit("WriteFile(,,,,) -> %x\n", rv);
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| // AttachDetours
 | |
| //
 | |
| PCHAR DetRealName(PCHAR psz)
 | |
| {
 | |
|     PCHAR pszBeg = psz;
 | |
|     // Move to end of name.
 | |
|     while (*psz) {
 | |
|         psz++;
 | |
|     }
 | |
|     // Move back through A-Za-z0-9 names.
 | |
|     while (psz > pszBeg &&
 | |
|            ((psz[-1] >= 'A' && psz[-1] <= 'Z') ||
 | |
|             (psz[-1] >= 'a' && psz[-1] <= 'z') ||
 | |
|             (psz[-1] >= '0' && psz[-1] <= '9'))) {
 | |
|         psz--;
 | |
|     }
 | |
|     return psz;
 | |
| }
 | |
| 
 | |
| VOID DetAttach(PVOID *ppbReal, PVOID pbMine, PCHAR psz)
 | |
| {
 | |
|     LONG l = DetourAttach(ppbReal, pbMine);
 | |
|     if (l != 0) {
 | |
|         Syelog(SYELOG_SEVERITY_NOTICE,
 | |
|                "Attach failed: `%s': error %d\n", DetRealName(psz), l);
 | |
|     }
 | |
| }
 | |
| 
 | |
| VOID DetDetach(PVOID *ppbReal, PVOID pbMine, PCHAR psz)
 | |
| {
 | |
|     LONG l = DetourDetach(ppbReal, pbMine);
 | |
|     if (l != 0) {
 | |
|         Syelog(SYELOG_SEVERITY_NOTICE,
 | |
|                "Detach failed: `%s': error %d\n", DetRealName(psz), l);
 | |
|     }
 | |
| }
 | |
| 
 | |
| #define ATTACH(x)       DetAttach(&(PVOID&)Real_##x,Mine_##x,#x)
 | |
| #define DETACH(x)       DetDetach(&(PVOID&)Real_##x,Mine_##x,#x)
 | |
| 
 | |
| LONG AttachDetours(VOID)
 | |
| {
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
| 
 | |
|     ATTACH(BuildCommDCBA);
 | |
|     ATTACH(BuildCommDCBAndTimeoutsA);
 | |
|     ATTACH(BuildCommDCBAndTimeoutsW);
 | |
|     ATTACH(BuildCommDCBW);
 | |
|     ATTACH(ClearCommBreak);
 | |
|     ATTACH(ClearCommError);
 | |
|     ATTACH(CloseHandle);
 | |
|     ATTACH(CreateFileA);
 | |
|     ATTACH(CreateFileW);
 | |
|     ATTACH(EscapeCommFunction);
 | |
|     ATTACH(GetCommConfig);
 | |
|     ATTACH(GetCommMask);
 | |
|     ATTACH(GetCommModemStatus);
 | |
|     ATTACH(GetCommProperties);
 | |
|     ATTACH(GetCommState);
 | |
|     ATTACH(GetCommTimeouts);
 | |
|     ATTACH(GetCurrentThreadId);
 | |
|     ATTACH(GetModuleFileNameW);
 | |
|     ATTACH(GetOverlappedResult);
 | |
|     ATTACH(PurgeComm);
 | |
|     ATTACH(ReadFile);
 | |
|     ATTACH(SetCommBreak);
 | |
|     ATTACH(SetCommConfig);
 | |
|     ATTACH(SetCommMask);
 | |
|     ATTACH(SetCommState);
 | |
|     ATTACH(SetCommTimeouts);
 | |
|     ATTACH(SetupComm);
 | |
|     ATTACH(TransmitCommChar);
 | |
|     ATTACH(WaitCommEvent);
 | |
|     ATTACH(WriteFile);
 | |
| 
 | |
|     return DetourTransactionCommit();
 | |
| }
 | |
| 
 | |
| LONG DetachDetours(VOID)
 | |
| {
 | |
|     DetourTransactionBegin();
 | |
|     DetourUpdateThread(GetCurrentThread());
 | |
| 
 | |
|     DETACH(BuildCommDCBA);
 | |
|     DETACH(BuildCommDCBAndTimeoutsA);
 | |
|     DETACH(BuildCommDCBAndTimeoutsW);
 | |
|     DETACH(BuildCommDCBW);
 | |
|     DETACH(ClearCommBreak);
 | |
|     DETACH(ClearCommError);
 | |
|     DETACH(CloseHandle);
 | |
|     DETACH(CreateFileA);
 | |
|     DETACH(CreateFileW);
 | |
|     DETACH(EscapeCommFunction);
 | |
|     DETACH(GetCommConfig);
 | |
|     DETACH(GetCommMask);
 | |
|     DETACH(GetCommModemStatus);
 | |
|     DETACH(GetCommProperties);
 | |
|     DETACH(GetCommState);
 | |
|     DETACH(GetCommTimeouts);
 | |
|     DETACH(GetCurrentThreadId);
 | |
|     DETACH(GetModuleFileNameW);
 | |
|     DETACH(GetOverlappedResult);
 | |
|     DETACH(PurgeComm);
 | |
|     DETACH(ReadFile);
 | |
|     DETACH(SetCommBreak);
 | |
|     DETACH(SetCommConfig);
 | |
|     DETACH(SetCommMask);
 | |
|     DETACH(SetCommState);
 | |
|     DETACH(SetCommTimeouts);
 | |
|     DETACH(SetupComm);
 | |
|     DETACH(TransmitCommChar);
 | |
|     DETACH(WaitCommEvent);
 | |
|     DETACH(WriteFile);
 | |
| 
 | |
|     return DetourTransactionCommit();
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| // Detours
 | |
| //
 | |
| 
 | |
| VOID _PrintDump(HANDLE h, PCHAR pszData, INT cbData)
 | |
| {
 | |
|     if (pszData && cbData > 0) {
 | |
|         CHAR szBuffer[256];
 | |
|         PCHAR pszBuffer = szBuffer;
 | |
|         INT cbBuffer = 0;
 | |
|         INT nLines = 0;
 | |
| 
 | |
|         while (cbData > 0) {
 | |
|             if (nLines > 20) {
 | |
|                 *pszBuffer++ = '.';
 | |
|                 *pszBuffer++ = '.';
 | |
|                 *pszBuffer++ = '.';
 | |
|                 cbBuffer += 3;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             if (*pszData == '\t') {
 | |
|                 *pszBuffer++ = '\\';
 | |
|                 *pszBuffer++ = 't';
 | |
|                 cbBuffer += 2;
 | |
|                 pszData++;
 | |
|                 cbData--;
 | |
|                 continue;
 | |
|             }
 | |
|             if (*pszData == '\r') {
 | |
|                 *pszBuffer++ = '\\';
 | |
|                 *pszBuffer++ = 'r';
 | |
|                 cbBuffer += 2;
 | |
|                 pszData++;
 | |
|                 cbData--;
 | |
|                 continue;
 | |
|             }
 | |
|             else if (*pszData == '\n') {
 | |
|                 *pszBuffer++ = '\\';
 | |
|                 *pszBuffer++ = 'n';
 | |
|                 cbBuffer += 2;
 | |
|                 *pszBuffer++ = '\0';
 | |
|                 _Print("%p:   %hs\n", h, szBuffer);
 | |
|                 nLines++;
 | |
|                 pszBuffer = szBuffer;
 | |
|                 cbBuffer = 0;
 | |
|                 pszData++;
 | |
|                 cbData--;
 | |
|                 continue;
 | |
|             }
 | |
|             else if (cbBuffer >= 80) {
 | |
|                 *pszBuffer++ = '\0';
 | |
|                 _Print("%p:   %hs\n", h, szBuffer);
 | |
|                 nLines++;
 | |
|                 pszBuffer = szBuffer;
 | |
|                 cbBuffer = 0;
 | |
|             }
 | |
| 
 | |
|             if (*pszData < ' ' || *pszData >= 127) {
 | |
|                 *pszBuffer++ = '\\';
 | |
|                 *pszBuffer++ = 'x';
 | |
|                 *pszBuffer++ = "0123456789ABCDEF"[(*pszData & 0xf0) >> 4];
 | |
|                 *pszBuffer++ = "0123456789ABCDEF"[(*pszData & 0x0f)];
 | |
|                 cbBuffer += 4;
 | |
|             }
 | |
|             else {
 | |
|                 *pszBuffer++ = *pszData;
 | |
|             }
 | |
|             cbBuffer++;
 | |
|             pszData++;
 | |
|             cbData--;
 | |
|         }
 | |
| 
 | |
|         if (cbBuffer > 0) {
 | |
|             *pszBuffer++ = '\0';
 | |
|             _Print("%p:   %hs\n", h, szBuffer);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| ////////////////////////////////////////////////////////////// Logging System.
 | |
| //
 | |
| static BOOL s_bLog = 1;
 | |
| static LONG s_nTlsIndent = -1;
 | |
| static LONG s_nTlsThread = -1;
 | |
| static LONG s_nThreadCnt = 0;
 | |
| 
 | |
| VOID _PrintEnter(const CHAR *psz, ...)
 | |
| {
 | |
|     DWORD dwErr = GetLastError();
 | |
| 
 | |
|     LONG nIndent = 0;
 | |
|     LONG nThread = 0;
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent);
 | |
|         TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)(nIndent + 1));
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread);
 | |
|     }
 | |
| 
 | |
|     if (s_bLog && psz) {
 | |
|         CHAR szBuf[1024];
 | |
|         PCHAR pszBuf = szBuf;
 | |
|         PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1;
 | |
|         LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0;
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10));
 | |
|         *pszBuf++ = ' ';
 | |
|         while (nLen-- > 0) {
 | |
|             *pszBuf++ = ' ';
 | |
|         }
 | |
| 
 | |
|         va_list  args;
 | |
|         va_start(args, psz);
 | |
| 
 | |
|         while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) {
 | |
|             // Copy characters.
 | |
|         }
 | |
|         *pszEnd = '\0';
 | |
|         SyelogV(SYELOG_SEVERITY_INFORMATION,
 | |
|                 szBuf, args);
 | |
| 
 | |
|         va_end(args);
 | |
|     }
 | |
|     SetLastError(dwErr);
 | |
| }
 | |
| 
 | |
| VOID _PrintExit(const CHAR *psz, ...)
 | |
| {
 | |
|     DWORD dwErr = GetLastError();
 | |
| 
 | |
|     LONG nIndent = 0;
 | |
|     LONG nThread = 0;
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent) - 1;
 | |
|         ASSERT(nIndent >= 0);
 | |
|         TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)nIndent);
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread);
 | |
|     }
 | |
| 
 | |
|     if (s_bLog && psz) {
 | |
|         CHAR szBuf[1024];
 | |
|         PCHAR pszBuf = szBuf;
 | |
|         PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1;
 | |
|         LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0;
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10));
 | |
|         *pszBuf++ = ' ';
 | |
|         while (nLen-- > 0) {
 | |
|             *pszBuf++ = ' ';
 | |
|         }
 | |
| 
 | |
|         va_list  args;
 | |
|         va_start(args, psz);
 | |
| 
 | |
|         while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) {
 | |
|             // Copy characters.
 | |
|         }
 | |
|         *pszEnd = '\0';
 | |
|         SyelogV(SYELOG_SEVERITY_INFORMATION,
 | |
|                 szBuf, args);
 | |
| 
 | |
|         va_end(args);
 | |
|     }
 | |
|     SetLastError(dwErr);
 | |
| }
 | |
| 
 | |
| VOID _Print(const CHAR *psz, ...)
 | |
| {
 | |
|     DWORD dwErr = GetLastError();
 | |
| 
 | |
|     LONG nIndent = 0;
 | |
|     LONG nThread = 0;
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent);
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread);
 | |
|     }
 | |
| 
 | |
|     if (s_bLog && psz) {
 | |
|         CHAR szBuf[1024];
 | |
|         PCHAR pszBuf = szBuf;
 | |
|         PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1;
 | |
|         LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0;
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10));
 | |
|         *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10));
 | |
|         *pszBuf++ = ' ';
 | |
|         while (nLen-- > 0) {
 | |
|             *pszBuf++ = ' ';
 | |
|         }
 | |
| 
 | |
|         va_list  args;
 | |
|         va_start(args, psz);
 | |
| 
 | |
|         while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) {
 | |
|             // Copy characters.
 | |
|         }
 | |
|         *pszEnd = '\0';
 | |
|         SyelogV(SYELOG_SEVERITY_INFORMATION,
 | |
|                 szBuf, args);
 | |
| 
 | |
|         va_end(args);
 | |
|     }
 | |
| 
 | |
|     SetLastError(dwErr);
 | |
| }
 | |
| 
 | |
| VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine)
 | |
| {
 | |
|     Syelog(SYELOG_SEVERITY_FATAL,
 | |
|            "ASSERT(%s) failed in %s, line %d.\n", pszMsg, pszFile, nLine);
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| // DLL module information
 | |
| //
 | |
| BOOL ThreadAttach(HMODULE hDll)
 | |
| {
 | |
|     (void)hDll;
 | |
| 
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         TlsSetValue(s_nTlsIndent, (PVOID)0);
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         LONG nThread = InterlockedIncrement(&s_nThreadCnt);
 | |
|         TlsSetValue(s_nTlsThread, (PVOID)(LONG_PTR)nThread);
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL ThreadDetach(HMODULE hDll)
 | |
| {
 | |
|     (void)hDll;
 | |
| 
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         TlsSetValue(s_nTlsIndent, (PVOID)0);
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         TlsSetValue(s_nTlsThread, (PVOID)0);
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL ProcessAttach(HMODULE hDll)
 | |
| {
 | |
|     s_bLog = FALSE;
 | |
|     s_nTlsIndent = TlsAlloc();
 | |
|     s_nTlsThread = TlsAlloc();
 | |
| 
 | |
|     WCHAR wzExePath[MAX_PATH];
 | |
| 
 | |
|     s_hInst = hDll;
 | |
|     Real_GetModuleFileNameA(s_hInst, s_szDllPath, ARRAYSIZE(s_szDllPath));
 | |
|     Real_GetModuleFileNameW(NULL, wzExePath, ARRAYSIZE(wzExePath));
 | |
| 
 | |
|     SyelogOpen("trcser" DETOURS_STRINGIFY(DETOURS_BITS), SYELOG_FACILITY_APPLICATION);
 | |
|     Syelog(SYELOG_SEVERITY_INFORMATION,
 | |
|            "##################################################################\n");
 | |
|     Syelog(SYELOG_SEVERITY_INFORMATION,
 | |
|            "### %ls\n", wzExePath);
 | |
|     LONG error = AttachDetours();
 | |
|     if (error != NO_ERROR) {
 | |
|         Syelog(SYELOG_SEVERITY_FATAL, "### Error attaching detours: %d\n", error);
 | |
|     }
 | |
| 
 | |
|     ThreadAttach(hDll);
 | |
| 
 | |
|     s_bLog = TRUE;
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL ProcessDetach(HMODULE hDll)
 | |
| {
 | |
|     ThreadDetach(hDll);
 | |
|     s_bLog = FALSE;
 | |
| 
 | |
|     LONG error = DetachDetours();
 | |
|     if (error != NO_ERROR) {
 | |
|         Syelog(SYELOG_SEVERITY_FATAL, "### Error detaching detours: %d\n", error);
 | |
|     }
 | |
| 
 | |
|     Syelog(SYELOG_SEVERITY_NOTICE, "### Closing.\n");
 | |
|     SyelogClose(FALSE);
 | |
| 
 | |
|     if (s_nTlsIndent >= 0) {
 | |
|         TlsFree(s_nTlsIndent);
 | |
|     }
 | |
|     if (s_nTlsThread >= 0) {
 | |
|         TlsFree(s_nTlsThread);
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, PVOID lpReserved)
 | |
| {
 | |
|     (void)hModule;
 | |
|     (void)lpReserved;
 | |
| 
 | |
|     if (DetourIsHelperProcess()) {
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     switch (dwReason) {
 | |
|       case DLL_PROCESS_ATTACH:
 | |
|         DetourRestoreAfterWith();
 | |
|         return ProcessAttach(hModule);
 | |
|       case DLL_PROCESS_DETACH:
 | |
|         return ProcessDetach(hModule);
 | |
|       case DLL_THREAD_ATTACH:
 | |
|         return ThreadAttach(hModule);
 | |
|       case DLL_THREAD_DETACH:
 | |
|         return ThreadDetach(hModule);
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////// End of File.
 |