|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
eventlog.c
Abstract:
This file contains all functions that access the application event log.
Author:
Wesley Witt (wesw) 19-Mar-1996
Environment:
User Mode
--*/
#include <windows.h>
#include <tapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include "fxsapip.h"
#include "faxutil.h"
#include "faxreg.h"
#include "faxext.h"
#include "..\service\registry\faxsvcrg.h"
#include "faxdev.h"
#include "faxevent.h"
#include "faxevent_messages.h"
#include "CritSec.h"
static DWORD gs_dwWarningEvents; static DWORD gs_dwErrorEvents; static DWORD gs_dwInformationEvents;
#define MAX_STRINGS 64
static HANDLE gs_hEventSrc; static DWORD gs_FaxCategoryCount; static CFaxCriticalSection gs_CsEvent;
PFAX_LOG_CATEGORY gs_pFaxCategory;
#ifdef __cplusplus
extern "C" { #endif
BOOL FXSEVENTInitialize( VOID ) { //
// Becuase the process is not always terminated when the service is stopped,
// We must not have any staticly initialized global variables.
// Initialize FXSEVENT global variables before starting the service
//
gs_hEventSrc = NULL; gs_pFaxCategory = NULL; gs_FaxCategoryCount = 0; gs_dwWarningEvents = 0; gs_dwErrorEvents = 0; gs_dwInformationEvents = 0;
return TRUE; }
VOID FXSEVENTFree( VOID ) { DEBUG_FUNCTION_NAME(TEXT("FXSEVENTFree"));
if (NULL != gs_hEventSrc) { if (!DeregisterEventSource(gs_hEventSrc)) { DebugPrintEx( DEBUG_ERR, TEXT("DeregisterEventSource() failed (ec: %ld)"), GetLastError()); } gs_hEventSrc = NULL; }
gs_CsEvent.SafeDelete();
for (DWORD i = 0; i < gs_FaxCategoryCount; i++) { MemFree( (LPVOID)gs_pFaxCategory[i].Name ); } MemFree (gs_pFaxCategory); gs_pFaxCategory = NULL; gs_FaxCategoryCount = 0;
HeapCleanup(); return; }
BOOL InitializeEventLog(OUT PREG_FAX_SERVICE* ppFaxReg)
/*++
Routine Description:
Initializes the event log for the FAX service to record event entries.
Arguments: ppFaxReg -
Return Value:
TRUE for success, FALSE for failure
--*/
{ DWORD i; DWORD ec;
FAX_LOG_CATEGORY DefaultCategories[] = { { L"Initialization/Termination", FAXLOG_CATEGORY_INIT, FAXLOG_LEVEL_MED }, { L"Outbound", FAXLOG_CATEGORY_OUTBOUND, FAXLOG_LEVEL_MED }, { L"Inbound", FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MED }, { L"Unknown", FAXLOG_CATEGORY_UNKNOWN, FAXLOG_LEVEL_MED } };
DEBUG_FUNCTION_NAME(TEXT("InitializeEventLog")); if (!gs_CsEvent.InitializeAndSpinCount()) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("CFaxCriticalSection::InitializeAndSpinCount (&gs_CsEvent) failed: err = %d"), ec); return FALSE; }
*ppFaxReg = NULL; ec = GetFaxRegistry(ppFaxReg); if (ERROR_SUCCESS != ec) { DebugPrintEx( DEBUG_ERR, TEXT("GetFaxRegistry() failed (ec: %ld)"), ec); return FALSE; }
//
// create the event source, if it does not already exist
//
if (!CreateFaxEventSource( *ppFaxReg, DefaultCategories, ARR_SIZE(DefaultCategories))) { DebugPrintEx( DEBUG_ERR, TEXT("CreateFaxEventSource() failed")); return FALSE; }
Assert( (*ppFaxReg)->Logging ); //
// allocate memory for the logging category info
//
EnterCriticalSection( &gs_CsEvent ); gs_pFaxCategory = (PFAX_LOG_CATEGORY) MemAlloc( sizeof(FAX_LOG_CATEGORY) * (*ppFaxReg)->LoggingCount ); if (!gs_pFaxCategory) { DebugPrintEx( DEBUG_ERR, TEXT("MemAlloc() failed")); LeaveCriticalSection( &gs_CsEvent ); return FALSE; } ZeroMemory (gs_pFaxCategory, sizeof(FAX_LOG_CATEGORY) * (*ppFaxReg)->LoggingCount); gs_FaxCategoryCount = (*ppFaxReg)->LoggingCount;
//
// capture the event categories from the registry
//
for (i = 0; i < (*ppFaxReg)->LoggingCount; i++) { Assert (NULL != (*ppFaxReg)->Logging[i].CategoryName);
gs_pFaxCategory[i].Name = StringDup( (*ppFaxReg)->Logging[i].CategoryName ); if (NULL == gs_pFaxCategory[i].Name) { //
// FXSEVENTFree() will free all resources
//
LeaveCriticalSection( &gs_CsEvent ); return FALSE; } gs_pFaxCategory[i].Category = (*ppFaxReg)->Logging[i].Number; gs_pFaxCategory[i].Level = (*ppFaxReg)->Logging[i].Level; }
LeaveCriticalSection( &gs_CsEvent );
//
// get a handle to the event log
//
gs_hEventSrc = RegisterEventSource( NULL, FAX_SVC_EVENT );
if (!gs_hEventSrc) { return FALSE; }
return TRUE; }
DWORD RefreshEventLog( PREG_FAX_LOGGING FaxReg )
/*++
Routine Description:
Refreshes the event log for the FAX service to record event entries.
Arguments:
None.
Return Value:
Win32 error code.
--*/
{ DWORD i; PFAX_LOG_CATEGORY pLoggingCategories = NULL; DWORD dwRes = ERROR_SUCCESS; DEBUG_FUNCTION_NAME(TEXT("RefreshEventLog"));
EnterCriticalSection( &gs_CsEvent );
pLoggingCategories = (PFAX_LOG_CATEGORY) MemAlloc( sizeof(FAX_LOG_CATEGORY) * FaxReg->LoggingCount); if (NULL == pLoggingCategories) { DebugPrintEx( DEBUG_ERR, TEXT("MemAlloc() failed")); dwRes = ERROR_OUTOFMEMORY; goto exit; } ZeroMemory (pLoggingCategories, sizeof(FAX_LOG_CATEGORY) * FaxReg->LoggingCount);
//
// Set the new values
//
for (i = 0; i < FaxReg->LoggingCount; i++) { pLoggingCategories[i].Name = StringDup( FaxReg->Logging[i].CategoryName ); if (NULL == pLoggingCategories[i].Name) { dwRes = ERROR_OUTOFMEMORY; goto exit; } pLoggingCategories[i].Category = FaxReg->Logging[i].Number; pLoggingCategories[i].Level = FaxReg->Logging[i].Level; }
//
// Free old settings
//
for (i = 0; i < gs_FaxCategoryCount; i++) { MemFree( (LPVOID)gs_pFaxCategory[i].Name ); } MemFree (gs_pFaxCategory);
//
// Set the gs_pFaxCategory to point to the new values
//
gs_pFaxCategory = pLoggingCategories; gs_FaxCategoryCount = FaxReg->LoggingCount; pLoggingCategories = NULL; // Do not free at exit
Assert (ERROR_SUCCESS == dwRes); exit: LeaveCriticalSection( &gs_CsEvent );
if (NULL != pLoggingCategories) { for (i = 0; i < FaxReg->LoggingCount; i++) { MemFree( (LPVOID)pLoggingCategories[i].Name ); } MemFree(pLoggingCategories); } return dwRes; }
BOOL FaxLog( DWORD Category, DWORD Level, DWORD StringCount, DWORD FormatId, ... )
/*++
Routine Description:
Writes a log file entry to the event log.
Arguments:
Level - Severity of the log record StringCount - Number of strings included in the varargs FormatId - Message file id
Return Value:
TRUE for success, FALSE for failure
--*/
{ LPCTSTR Strings[MAX_STRINGS]; DWORD i; va_list args; WORD Type; WORD wEventCategory; // The event categoey as it appears in the MC file. The WINFAX.H cateogry values
// are mapped to the .MC values before ReportEvent() is called.
DEBUG_FUNCTION_NAME(TEXT("FaxLog"));
if(StringCount > MAX_STRINGS) { DebugPrintEx(DEBUG_ERR, TEXT("Too many parameters.")); return FALSE; }
if (!gs_hEventSrc) { //
// Not yet initialized
//
DebugPrintEx( DEBUG_WRN, TEXT("Event log is not initialized yet."), Category); return FALSE; } //
// look for the category
//
EnterCriticalSection( &gs_CsEvent );
for (i = 0; i < gs_FaxCategoryCount; i++) { if (gs_pFaxCategory[i].Category == Category) { if (Level > gs_pFaxCategory[i].Level) { LeaveCriticalSection( &gs_CsEvent ); return FALSE; } } }
va_start( args, FormatId );
//
// capture the strings
//
for (i=0; i<StringCount; i++) { Strings[i] = va_arg( args, LPTSTR ); if(Strings[i] == NULL) { Strings[i] = TEXT(""); } }
va_end (args);
switch (FormatId >> 30) { case STATUS_SEVERITY_WARNING:
Type = EVENTLOG_WARNING_TYPE; gs_dwWarningEvents++; break;
case STATUS_SEVERITY_ERROR: Type = EVENTLOG_ERROR_TYPE; gs_dwErrorEvents++; break;
case STATUS_SEVERITY_INFORMATIONAL: case STATUS_SEVERITY_SUCCESS: Type = EVENTLOG_INFORMATION_TYPE; gs_dwInformationEvents++; break;
default: DebugPrintEx( DEBUG_ERR, TEXT("Invalid Type id [%ld]"), (FormatId >> 30)); ASSERT_FALSE; break; }
LeaveCriticalSection( &gs_CsEvent );
//
// Map the public category index to the .MC category index
//
//
switch (Category) { case FAXLOG_CATEGORY_INIT: wEventCategory = FAX_LOG_CATEGORY_INIT; break; case FAXLOG_CATEGORY_OUTBOUND: wEventCategory = FAX_LOG_CATEGORY_OUTBOUND; break; case FAXLOG_CATEGORY_INBOUND: wEventCategory = FAX_LOG_CATEGORY_INBOUND; break; case FAXLOG_CATEGORY_UNKNOWN: wEventCategory = FAX_LOG_CATEGORY_UNKNOWN; break; default: DebugPrintEx( DEBUG_ERR, TEXT("Invalid category id [%ld]"), Category); ASSERT_FALSE;
}
//
// record the event
//
if (!ReportEvent( gs_hEventSrc, // event log handle
Type, // type
wEventCategory, // category
FormatId, // event id
NULL, // security id
(WORD) StringCount, // string count
0, // data buffer size
Strings, // strings
NULL // data buffer
)) { DebugPrintEx( DEBUG_ERR, TEXT("ReportEvent() failed, ec: %ld"), GetLastError()); }
return TRUE; }
void GetEventsCounters( OUT LPDWORD lpdwWarningEvents, OUT LPDWORD lpdwErrorEvents, OUT LPDWORD lpdwInformationEvents ) { Assert (lpdwWarningEvents && lpdwErrorEvents && lpdwInformationEvents);
EnterCriticalSection( &gs_CsEvent );
*lpdwWarningEvents = gs_dwWarningEvents; *lpdwErrorEvents = gs_dwErrorEvents; *lpdwInformationEvents = gs_dwInformationEvents;
LeaveCriticalSection( &gs_CsEvent ); return; }
DWORD GetLoggingCategories( OUT PFAX_LOG_CATEGORY* lppFaxCategory, OUT LPDWORD lpdwFaxCategorySize, OUT LPDWORD lpdwNumberCategories ) /*++
Routine Description:
returns the logging categories. The caller should call MemFree to deallocate (lppFaxCategory). The returned data is serialized. The caller should call FixupString() on CategoryName to convert offset to address.
Arguments:
OUT LPBYTE *lppFaxCategory - Address of a buffer to recieve the fax category. The buffer is allocated by the function. OUT LPDWORD lpdwFaxCategorySize - Allocated buffer size. OUT LPDWORD lpdwNumberCategories - Number of fax logging categories.
Return Value:
None.
--*/
{ DWORD i; DWORD dwBufferSize; ULONG_PTR ulpOffset; DEBUG_FUNCTION_NAME(TEXT("GetLoggingCategories"));
Assert (lppFaxCategory && lpdwFaxCategorySize && lpdwNumberCategories); *lpdwFaxCategorySize = 0; *lppFaxCategory = NULL; *lpdwNumberCategories = 0;
EnterCriticalSection( &gs_CsEvent ); //
// Calculate buffer size
//
dwBufferSize = gs_FaxCategoryCount * sizeof(FAX_LOG_CATEGORY); for (i = 0; i < gs_FaxCategoryCount; i++) { dwBufferSize += StringSize(gs_pFaxCategory[i].Name); }
//
// Allocate memory
//
*lppFaxCategory = (PFAX_LOG_CATEGORY)MemAlloc(dwBufferSize); if (NULL == *lppFaxCategory) { DebugPrintEx( DEBUG_ERR, TEXT("MemAlloc failed")); LeaveCriticalSection( &gs_CsEvent ); return ERROR_NOT_ENOUGH_MEMORY; } *lpdwFaxCategorySize = dwBufferSize; *lpdwNumberCategories = gs_FaxCategoryCount;
//
// Get the fax logging logging
//
ulpOffset = gs_FaxCategoryCount * sizeof(FAX_LOG_CATEGORY); for (i = 0; i < gs_FaxCategoryCount; i++) { StoreString( gs_pFaxCategory[i].Name, (PULONG_PTR)&((*lppFaxCategory)[i].Name), (LPBYTE)*lppFaxCategory, &ulpOffset, dwBufferSize );
(*lppFaxCategory)[i].Category = gs_pFaxCategory[i].Category; (*lppFaxCategory)[i].Level = gs_pFaxCategory[i].Level; }
LeaveCriticalSection( &gs_CsEvent );
return ERROR_SUCCESS; } // GetLoggingCategories
#ifdef __cplusplus
} #endif
|