|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
eventlog.c
Abstract:
Implementation of event logging.
Author:
Wesley Witt (wesw) 18-Dec-1998
Revision History:
Andrew Ritz (andrewr) 7-Jul-1999 --*/
#include "sfcp.h"
#pragma hdrstop
typedef BOOL (WINAPI *PPSETUPLOGSFCERROR)(PCWSTR,DWORD);
//
// global handle to eventlog
//
HANDLE hEventSrc;
//
// pointer to gui-setup eventlog function
//
PPSETUPLOGSFCERROR pSetuplogSfcError;
BOOL pSfcGetSetuplogSfcError( VOID ) /*++
Routine Description:
Routine retreives a function pointer to the error logging entrypoint in syssetup.dll
Arguments:
None.
Return Value:
TRUE for success, FALSE for failure.
--*/ { HMODULE hMod;
if (NULL == pSetuplogSfcError) { hMod = GetModuleHandle( L"syssetup.dll" );
if (hMod) { pSetuplogSfcError = (PPSETUPLOGSFCERROR)SfcGetProcAddress( hMod, "pSetuplogSfcError" ); } else { DebugPrint1(LVL_MINIMAL, L"GetModuleHandle on syssetup.dll failed, ec=0x%08x",GetLastError()); } }
return pSetuplogSfcError != NULL; }
BOOL SfcReportEvent( IN ULONG EventId, IN PCWSTR FileName, IN PCOMPLETE_VALIDATION_DATA ImageValData, IN DWORD LastError OPTIONAL ) /*++
Routine Description:
Routine logs an event into the eventlog. Also contains a hack for logging data into the GUI-setup error log as well. we typically log unsigned files or the user tht cancelled the replacement of the signed files.
Arguments:
EventId - id of the eventlog error FileName - null terminated unicode string indicating the file that was unsigned, etc. ImageValData - pointer to file data for unsigned file LastError - contains an optional last error code for logging
Return Value:
TRUE for success, FALSE for failure.
--*/ { PFILE_VERSION_INFO FileVer; WCHAR SysVer[64]; WCHAR BadVer[64]; PCWSTR s[3]; WORD Count = 0; WCHAR LastErrorText[MAX_PATH]; PVOID ErrText = NULL; WORD wEventType;
//
// if we're in gui-mode setup, we take a special path to log into
// gui-setup's logfile instead of the eventlog
//
if (SFCDisable == SFC_DISABLE_SETUP) { if(!pSfcGetSetuplogSfcError()) { return FALSE; }
switch (EventId){ case MSG_DLL_CHANGE: //fall through
case MSG_SCAN_FOUND_BAD_FILE: pSetuplogSfcError( FileName,0 ); break;
case MSG_COPY_CANCEL_NOUI: case MSG_RESTORE_FAILURE: pSetuplogSfcError( FileName, 1 ); break;
case MSG_CACHE_COPY_ERROR: pSetuplogSfcError( FileName, 2 ); break;
default: DebugPrint1( LVL_MINIMAL, L"unexpected EventId 0x%08x in GUI Setup, ", EventId);
return FALSE; //ASSERT( FALSE && L"Unexpected EventId in SfcReportEvent");
}
return(TRUE); }
//
// we're outside of GUI-setup so we really want to log to the eventlog
//
if (EventId == 0) { ASSERT( FALSE && L"Unexpected EventId in SfcReportEvent"); return(FALSE); }
//
// if we don't have a handle to the eventlog, create one.
//
if (hEventSrc == NULL) { hEventSrc = RegisterEventSource( NULL, L"Windows File Protection" ); if (hEventSrc == NULL) { DebugPrint1(LVL_MINIMAL, L"RegisterEventSource failed, ec=0x%08x",GetLastError()); return(FALSE); } }
ASSERT(hEventSrc != NULL);
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, LastError, 0, (PWSTR) &ErrText, 0, NULL );
if (ErrText) { wsprintf(LastErrorText,L"0x%08x [%ws]",LastError,ErrText); LocalFree( ErrText ); } else { wsprintf(LastErrorText,L"0x%08x",LastError); }
//
// pick out the appropriate message to log
// the default event type is "information"
//
wEventType = EVENTLOG_INFORMATION_TYPE;
switch (EventId) { case MSG_DLL_CHANGE: ASSERT(FileName != NULL); s[0] = FileName;
//
// we prefer a message that is most informative message with
// version information for both dlls to the least informative
// message with no version information
//
//
if (ImageValData->New.DllVersion && ImageValData->Original.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion; swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion; swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); s[1] = BadVer; s[2] = SysVer; Count = 3; EventId = MSG_DLL_CHANGE2; } else if (ImageValData->New.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion; swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); s[1] = SysVer; Count = 2; EventId = MSG_DLL_CHANGE3; } else if (ImageValData->Original.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion; swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); s[1] = BadVer; Count = 2; EventId = MSG_DLL_CHANGE; } else { //
// we have to protect some things without version information,
// so we just log an error that doesn't mention version
// information. If we stop protecting files like this, this
// should be an assert in prerelease versions of the code
//
Count = 1; EventId = MSG_DLL_CHANGE_NOVERSION; DebugPrint1( LVL_MINIMAL, L"TskTsk...the protected OS file %ws does not have any version information", FileName); } break;
case MSG_SCAN_FOUND_BAD_FILE: ASSERT(FileName != NULL); s[0] = FileName;
//
// if we found a bad file, we only want the version of the restored file
//
if (ImageValData->New.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->New.DllVersion; swprintf( SysVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); s[1] = SysVer; Count = 2; } else { DebugPrint1( LVL_MINIMAL, L"TskTsk...the protected OS file %ws does not have any version information", FileName); EventId = MSG_SCAN_FOUND_BAD_FILE_NOVERSION; Count = 1; break; } break;
case MSG_RESTORE_FAILURE: Count = 3; s[0] = FileName; s[1] = BadVer; s[2] = (PCWSTR)LastErrorText;
if (ImageValData->Original.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion; swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); } else { LoadString( SfcInstanceHandle,IDS_UNKNOWN,BadVer,UnicodeChars(BadVer)); }
break; case MSG_CACHE_COPY_ERROR: Count = 2; s[0] = FileName; s[1] = (PCWSTR)LastErrorText; break;
case MSG_COPY_CANCEL_NOUI: //fall through
case MSG_COPY_CANCEL: Count = 3; s[0] = FileName; s[1] = LoggedOnUserName; s[2] = BadVer;
if (ImageValData->Original.DllVersion) { FileVer = (PFILE_VERSION_INFO)&ImageValData->Original.DllVersion; swprintf( BadVer, L"%d.%d.%d.%d", FileVer->VersionHigh, FileVer->VersionLow, FileVer->BuildNumber, FileVer->Revision ); } else { LoadString( SfcInstanceHandle,IDS_UNKNOWN,BadVer,UnicodeChars(BadVer)); }
break;
case MSG_DLL_NOVALIDATION_TERMINATION: wEventType = EVENTLOG_WARNING_TYPE; s[0] = FileName; Count = 1; break;
case MSG_RESTORE_FAILURE_MAX_RETRIES: s[0] = FileName; Count = 1; break;
case MSG_SCAN_STARTED: Count = 0; break;
case MSG_SCAN_COMPLETED: Count = 0; break;
case MSG_SCAN_CANCELLED: s[0] = LoggedOnUserName; Count = 1; break;
case MSG_DISABLE: Count = 0; break;
case MSG_DLLCACHE_INVALID: Count = 0; break;
case MSG_SXS_INITIALIZATION_FAILED: Count = 1; s[0] = LastErrorText; break;
case MSG_INITIALIZATION_FAILED: Count = 1; s[0] = LastErrorText; break;
case MSG_CATALOG_RESTORE_FAILURE: Count = 2; s[0] = FileName; s[1] = LastErrorText; break; default: ASSERT( FALSE && L"Unknown EventId in SfcReportEvent"); return FALSE; }
return ReportEvent( hEventSrc, wEventType, 0, EventId, NULL, Count, 0, s, NULL ); }
|