Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

597 lines
14 KiB

/*++
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