|
|
#include "precomp.h"
typedef struct _VLOG_GLOBAL_DATA { BOOL bLoggingDisabled; WCHAR szSessionLog[MAX_PATH]; WCHAR szProcessLog[MAX_PATH]; } VLOG_GLOBAL_DATA, *PVLOG_GLOBAL_DATA;
PVLOG_GLOBAL_DATA g_pData = NULL;
HANDLE g_hMap = NULL; // mapping handle for global data
BOOL g_bVerifierLogInited = FALSE; // have we been through the init sequence?
BOOL g_bLoggingDisabled = TRUE; // have we been through the init sequence?
WCHAR g_szSessionLog[MAX_PATH]; WCHAR g_szProcessLog[MAX_PATH];
#define DEBUGGER_LOG L"DEBUGGER"
#define DEBUGGER_ENTRY_CRASH L"Crash"
#define DEBUGGER_ENTRY_CRASH_DESCRIPTION L"An AV occured. The application exited."
void WriteToProcessLog( LPCSTR szLine );
void WriteToSessionLog( LPCSTR szLine );
void GetExeName( LPWSTR szProcessPath, LPWSTR szProcessName ) { LPWSTR pszLast = NULL; LPWSTR psz; LPWSTR pszFound = NULL; psz = szProcessPath; while (psz) { pszFound = wcschr(psz, L'\\');
if (pszFound != NULL) { pszLast = pszFound; psz = pszFound + 1; } else { psz = pszFound; } }
if (pszLast != NULL) { psz = pszLast + 1; } else { psz = szProcessPath; }
pszFound = wcschr(psz, L'.');
if (pszFound != NULL) { wcsncpy(szProcessName, psz, pszFound - psz); } else { wcscpy(szProcessName, psz); } }
/*++
Function Description: Initializes the support for file logging.
Return Value: TRUE if successful, FALSE if failed
History:
04/26/2001 dmunsil Created
--*/ BOOL InitVerifierLogSupport( LPWSTR szProcessPath, DWORD dwID ) { WCHAR szShared[128]; WCHAR szVLogPath[MAX_PATH]; WCHAR szProcessName[MAX_PATH]; WCHAR szTime[128]; char szTemp[400]; HANDLE hFile; SYSTEMTIME LocalTime; int nTemp; BOOL bAlreadyInited; DWORD dwErr;
//
// if we've already been inited, get out
//
if (g_bVerifierLogInited) { return FALSE; } g_bVerifierLogInited = TRUE;
swprintf(szShared, L"VeriferLog_%08X", dwID); g_hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szShared); if (g_hMap) { bAlreadyInited = TRUE; } else { bAlreadyInited = FALSE; g_hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(VLOG_GLOBAL_DATA), szShared); }
if (!g_hMap) { DPF("Cannot get shared global data."); g_bLoggingDisabled = TRUE; return FALSE; }
g_pData = (PVLOG_GLOBAL_DATA)MapViewOfFile(g_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!g_pData) { DPF("Cannot map shared global data."); g_bLoggingDisabled = TRUE; return FALSE; }
if (bAlreadyInited) { if (g_pData->szProcessLog[0] == 0 || g_pData->szSessionLog[0] == 0) { g_bLoggingDisabled = TRUE; g_pData->bLoggingDisabled = TRUE; return FALSE; } g_bLoggingDisabled = g_pData->bLoggingDisabled; wcscpy(g_szSessionLog, g_pData->szSessionLog); wcscpy(g_szProcessLog, g_pData->szProcessLog); return TRUE; } else { //
// just in case -- make sure these are NULL
//
ZeroMemory(g_pData, sizeof(VLOG_GLOBAL_DATA)); }
//
// we need to init the file mapping, so temporarily disable logging, just in case.
//
g_pData->bLoggingDisabled = TRUE;
//
// init the CString objects
//
//
// the verifier log will be located in %windir%\AppPatch\VLog
//
//
// First, check that VLog exists; if not, we're not logging
//
GetSystemWindowsDirectoryW(szVLogPath, MAX_PATH);
wcscat(szVLogPath, L"\\AppPatch\\VLog");
if (GetFileAttributesW(szVLogPath) == -1) { if (!CreateDirectory(szVLogPath, NULL)) { DPF("No log directory %ls. Logging disabled.", szVLogPath); g_bLoggingDisabled = TRUE; return FALSE; } }
//
// Next, check for the existence of session.log. If it's not there,
// we're not logging
//
wcscpy(g_szSessionLog, szVLogPath); wcscat(g_szSessionLog, L"\\session.log"); if (GetFileAttributesW(g_szSessionLog) == -1) { hFile = CreateFile(g_szSessionLog, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } else { DPF("No session log file '%ls'. Logging disabled.", g_szSessionLog); g_bLoggingDisabled = TRUE; return FALSE; } }
//
// get the process log file name
//
GetExeName(szProcessPath, szProcessName); //
// combine into log name, find first available
//
nTemp = 0; do { swprintf(g_szProcessLog, L"%ls\\%ls%d.%ls", szVLogPath, szProcessName, nTemp, L"log");
nTemp++; } while (GetFileAttributesW(g_szProcessLog) != -1); //
// open the file. create it if it doesn't exist, and truncate
//
hFile = CreateFileW(g_szProcessLog, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError();
DPF("Cannot create verifier process log file '%ls'. Error 0x%08X.", g_szProcessLog, dwErr);
g_bLoggingDisabled = TRUE; return FALSE; } CloseHandle(hFile);
//
// put the info in the session log and the process log
//
g_pData->bLoggingDisabled = FALSE; g_bLoggingDisabled = FALSE;
//
// I realize these pointers point to process-specific memory, but since
// this mapping is only shared by this process, it seems safe.
//
wcscpy(g_pData->szProcessLog, g_szProcessLog); wcscpy(g_pData->szSessionLog, g_szSessionLog); GetLocalTime(&LocalTime); swprintf(szTime, L"%d/%d/%d %d:%02d:%02d", LocalTime.wMonth, LocalTime.wDay, LocalTime.wYear, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond); sprintf(szTemp, "# LOG_BEGIN %ls '%ls' '%ls'", szTime, szProcessPath, g_szProcessLog); WriteToProcessLog(szTemp); WriteToSessionLog(szTemp); //
// Dump the log provider info
//
sprintf(szTemp, "# SHIM_BEGIN %ls 1", DEBUGGER_LOG); WriteToProcessLog(szTemp); sprintf(szTemp, "# LOGENTRY %ls 0 '%ls", DEBUGGER_LOG, DEBUGGER_ENTRY_CRASH); WriteToProcessLog(szTemp); WriteToProcessLog("# DESCRIPTION BEGIN"); sprintf(szTemp, "%ls", DEBUGGER_ENTRY_CRASH_DESCRIPTION); WriteToProcessLog(szTemp); WriteToProcessLog("# DESCRIPTION END"); return TRUE; }
/*++
Function Description: clean up all our shared file resources
History:
04/26/2001 dmunsil Created
--*/ void ReleaseLogSupport( void ) { g_bLoggingDisabled = TRUE; if (g_pData) { UnmapViewOfFile(g_pData); g_pData = NULL; if (g_hMap) { CloseHandle(g_hMap); g_hMap = NULL; } } }
/*++
Function Description: Logs a problem that the verifier has found
History:
04/26/2001 dmunsil Created
--*/ void VLog( LPCSTR pszFmt, ... ) { char szT[1024]; char* szTemp; int nLen; int nRemain; va_list arglist;
if (g_bLoggingDisabled) { return; }
_snprintf(szT, 1023, "| %ls 0 '", DEBUGGER_LOG);
nLen = lstrlenA(szT); szTemp = szT + nLen; nRemain = 1023 - nLen;
if (nRemain > 0) { va_start(arglist, pszFmt); _vsnprintf(szTemp, nRemain, pszFmt, arglist); va_end(arglist); }
szT[1023] = 0; WriteToProcessLog(szT); }
/*++
Function Description: Writes a line of text to the process log file
Return Value: History:
04/26/2001 dmunsil Created
--*/ void WriteToProcessLog( LPCSTR szLine ) { HANDLE hFile; DWORD bytesWritten;
if (g_bLoggingDisabled) { return; }
// open the log file
hFile = CreateFileW(g_szProcessLog, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { DPF("Cannot open verifier log file '%s'", g_szProcessLog); return; }
// go to the end of the file
SetFilePointer(hFile, 0, NULL, FILE_END);
// make sure we have no '\n' or '\r' at the end of the string.
int len = lstrlenA(szLine);
while (len && (szLine[len - 1] == '\n' || szLine[len - 1] == '\r')) { len--; }
// write the actual log
WriteFile(hFile, szLine, len, &bytesWritten, NULL);
// new line
WriteFile(hFile, "\r\n", 2, &bytesWritten, NULL);
CloseHandle(hFile);
// dump it in the debugger as well on checked builds
#if DBG
DPF((LPSTR)szLine); #endif // DBG
}
/*++
Function Description: Writes a line of text to the session log file
Return Value: History:
04/26/2001 dmunsil Created
--*/ void WriteToSessionLog( LPCSTR szLine ) { HANDLE hFile; DWORD bytesWritten;
if (g_bLoggingDisabled) { return; }
// open the log file
hFile = CreateFileW(g_szSessionLog, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { DPF("Cannot open verifier log file '%s'", g_szSessionLog); return; }
// go to the end of the file
SetFilePointer(hFile, 0, NULL, FILE_END);
// make sure we have no '\n' or '\r' at the end of the string.
int len = lstrlenA(szLine);
while (len && (szLine[len - 1] == '\n' || szLine[len - 1] == '\r')) { len--; }
// write the actual log
WriteFile(hFile, szLine, len, &bytesWritten, NULL);
// new line
WriteFile(hFile, "\r\n", 2, &bytesWritten, NULL);
CloseHandle(hFile);
// dump it in the debugger as well on checked builds
#if DBG
DPF((LPSTR)szLine); #endif // DBG
}
|