Windows-Server-2003/net/rras/common/rtutils/event.c

776 lines
20 KiB
C

/********************************************************************/
/** Copyright(c) 1992 Microsoft Corporation. **/
/********************************************************************/
//
//
// Filename: event.c
//
// Description:
//
// History:
// August 26,1992. Stefan Solomon Created original version.
// August 27,1995. Abolade Gbadegesin Modified to support Unicode.
// See trace.h for notes on how
// this file is used to support
// both ANSI and Unicode.
//
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <winsvc.h>
#include <tchar.h>
#include <stdio.h>
#include <nb30.h>
#include <lmcons.h>
#include <rtutils.h>
#include <mprapi.h>
#include <raserror.h>
#include <mprerror.h>
#include <mprlog.h>
//#define STRSAFE_LIB
#include <strsafe.h>
#define ROUTER_SERVICE RRAS_SERVICE_NAME
HINSTANCE g_hDll;
#if defined(UNICODE) || defined(_UNICODE)
#define STRING_NULL UNICODE_NULL
#define UNICODE_STRING_TAG L'S'
#define ANSI_STRING_TAG L's'
#define TCHAR_STRING_TAG L't'
#define DECIMAL_TAG L'd'
#define IPADDRESS_TAG L'I'
#else
#define STRING_NULL '\0'
#define UNICODE_STRING_TAG 'S'
#define ANSI_STRING_TAG 's'
#define TCHAR_STRING_TAG 't'
#define DECIMAL_TAG 'd'
#define IPADDRESS_TAG 'I'
#endif
#define PRINT_IPADDR(x) \
((x)&0x000000ff),(((x)&0x0000ff00)>>8),(((x)&0x00ff0000)>>16),(((x)&0xff000000)>>24)
//
//
// Function: LogError
//
// Descr:
//
//
VOID
APIENTRY
LogError(
IN DWORD dwMessageId,
IN DWORD cNumberOfSubStrings,
IN LPTSTR *plpszSubStrings,
IN DWORD dwErrorCode
) {
HANDLE hLog;
PSID pSidUser = NULL;
hLog = RegisterEventSource(NULL, ROUTER_SERVICE );
if (hLog == NULL)
return;
if ( dwErrorCode == NO_ERROR )
{
//
// No error codes were specified
//
ReportEvent( hLog,
EVENTLOG_ERROR_TYPE,
0, // event category
dwMessageId,
pSidUser,
(WORD)cNumberOfSubStrings,
0,
plpszSubStrings,
(PVOID)NULL
);
}
else
{
//
// Log the error code specified
//
ReportEvent( hLog,
EVENTLOG_ERROR_TYPE,
0, // event category
dwMessageId,
pSidUser,
(WORD)cNumberOfSubStrings,
sizeof(DWORD),
plpszSubStrings,
(PVOID)&dwErrorCode
);
}
DeregisterEventSource( hLog );
}
//
//
// Function: LogEvent
//
// Descr:
//
//
VOID
APIENTRY
LogEvent(
IN DWORD wEventType,
IN DWORD dwMessageId,
IN DWORD cNumberOfSubStrings,
IN LPTSTR *plpszSubStrings
) {
HANDLE hLog;
PSID pSidUser = NULL;
// Audit enabled
hLog = RegisterEventSource( NULL, ROUTER_SERVICE );
if (hLog == NULL)
return;
ReportEvent( hLog,
(WORD)wEventType, // success/failure audit
0, // event category
dwMessageId,
pSidUser,
(WORD)cNumberOfSubStrings,
0,
plpszSubStrings,
(PVOID)NULL);
DeregisterEventSource( hLog );
}
//----------------------------------------------------------------------------
// Function: RouterLogRegister
//
// Returns a HANDLE which can be passed to RouterLogEvent
// to log events from the specified source.
//----------------------------------------------------------------------------
HANDLE
RouterLogRegister(
LPCTSTR lpszSource
) {
return RegisterEventSource(NULL, lpszSource);
}
//----------------------------------------------------------------------------
// Function: RouterLogDeregister
//
// Closes a HANDLE created by RouterLogRegister
//----------------------------------------------------------------------------
VOID
RouterLogDeregister(
HANDLE hLogHandle
) {
if(NULL != hLogHandle)
{
DeregisterEventSource(hLogHandle);
}
}
//----------------------------------------------------------------------------
// Function: RouterLogEvent
//
// Logs an event using a HANDLE created by RouterLogRegister.
//----------------------------------------------------------------------------
VOID
RouterLogEvent(
IN HANDLE hLogHandle,
IN DWORD dwEventType,
IN DWORD dwMessageId,
IN DWORD dwSubStringCount,
IN LPTSTR *plpszSubStringArray,
IN DWORD dwErrorCode
) {
if(NULL == hLogHandle)
{
return;
}
if (dwErrorCode == NO_ERROR) {
ReportEvent(
hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
(WORD)dwSubStringCount,
0,
plpszSubStringArray,
(PVOID)NULL
);
}
else {
ReportEvent(
hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
(WORD)dwSubStringCount,
sizeof(DWORD),
plpszSubStringArray,
(PVOID)&dwErrorCode
);
}
}
VOID
RouterLogEventEx(
IN HANDLE hLogHandle,
IN DWORD dwEventType,
IN DWORD dwErrorCode,
IN DWORD dwMessageId,
IN LPCTSTR ptszFormat,
...
)
{
va_list vlArgList;
if(NULL == hLogHandle)
{
return;
}
va_start(vlArgList, ptszFormat);
RouterLogEventValistEx(
hLogHandle,
dwEventType,
dwErrorCode,
dwMessageId,
ptszFormat,
vlArgList
);
va_end(vlArgList);
}
VOID
RouterLogEventValistEx(
IN HANDLE hLogHandle,
IN DWORD dwEventType,
IN DWORD dwErrorCode,
IN DWORD dwMessageId,
IN LPCTSTR ptszFormat,
IN va_list vlArgList
)
/*++
Routine Description
This function logs an event, but also parses out the insert strings
Locks
None
Arguments
hLogHandle Handle from RegisterLogRegister()
dwEventType EVENTLOG_{ERROR|WARNING|INFORMATION}_TYPE
dwErrorCode The error code to report
dwMessageId The ID of the message string
ptszFormat A string specifying the format of the following insert
values. The type of the value is dictated by the format
string. The format string consists of a series of %<X>
There MUST BE NOTHING ELSE - no escape characters, no
nothing.
Valid <X> are:
S: Unicode string
s: ANSII string
t: TCHAR string
d: integer
I: IP Address in network order
Return Value
None
--*/
{
PWCHAR rgpwszInsertArray[20];
LPCTSTR ptszTemp;
WORD wNumInsert;
ULONG i, ulDecIndex, ulFormatLen;
DWORD dwErr=NO_ERROR, dwNumAllocStrings=0;
PWCHAR pszAllocArray[20];
HRESULT hrResult;
//
// 22 is enough to hold 2^64
// There can be max 20 insert strings
//
WCHAR rgpwszDecString[20][22];
if (ptszFormat==NULL)
ptszFormat = TEXT("");
if(NULL == hLogHandle)
{
return;
}
//
// First make sure that the format list doesnt specify more than
// 20 characters
//
ptszTemp = ptszFormat;
ulFormatLen = _tcslen(ptszFormat);
wNumInsert = 0;
ulDecIndex = 0;
i = 0;
//
// We will only walk the first 20 format specifiers
//
while((i < ulFormatLen) && (wNumInsert < 20))
{
if(*ptszTemp == __TEXT('%'))
{
//
// Ok so this could be a good specifier - check the next character
//
i++;
ptszTemp++;
switch(*ptszTemp)
{
case UNICODE_STRING_TAG:
{
rgpwszInsertArray[wNumInsert] = va_arg(vlArgList, PWCHAR);
wNumInsert++;
break;
}
case ANSI_STRING_TAG:
{
PCHAR pszString;
PWCHAR pwszWideString;
ULONG ulLenNumChars;//nu
pszString = va_arg(vlArgList,
PCHAR);
ulLenNumChars = strlen(pszString);
if(ulLenNumChars)
{
pwszWideString = HeapAlloc(GetProcessHeap(), 0,
(ulLenNumChars+1) * sizeof(WCHAR));
if (!pwszWideString)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
pszAllocArray[dwNumAllocStrings++] = pwszWideString;
MultiByteToWideChar(CP_ACP,
0,
pszString,
-1,
pwszWideString,
ulLenNumChars+1);
rgpwszInsertArray[wNumInsert] = pwszWideString;
}
else
{
//
// L"" will be on our stack, but it cant go away
//
rgpwszInsertArray[wNumInsert] = L"";
}
wNumInsert++;
break;
}
case TCHAR_STRING_TAG:
{
#if defined(UNICODE) || defined(_UNICODE)
rgpwszInsertArray[wNumInsert] = va_arg(vlArgList, PWCHAR);
#else
PCHAR pszString;
PWCHAR pwszWideString;
ULONG ulLenNumChars;
pszString = va_arg(vlArgList, PCHAR);
ulLenNumChars = strlen(pszString);
if(ulLenNumChars)
{
pwszWideString = HeapAlloc(GetProcessHeap(), 0,
(ulLenNumChars+1) * sizeof(WCHAR));
if (!pwszWideString)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
pszAllocArray[dwNumAllocStrings++] = pwszWideString;
if (MultiByteToWideChar(CP_ACP,
0,
pszString,
-1,
pwszWideString,
ulLenNumChars+1) == 0)
{
dwErr = GetLastError();
break;
}
rgpwszInsertArray[wNumInsert] = pwszWideString;
}
else
{
//
// L"" will be on our stack, but it cant go away
//
rgpwszInsertArray[wNumInsert] = L"";
}
#endif
wNumInsert++;
break;
}
case DECIMAL_TAG:
{
hrResult = StringCchPrintfW(&(rgpwszDecString[ulDecIndex][0]),
21,
L"%d",
va_arg(vlArgList, int));
if (FAILED(hrResult)){
dwErr = HRESULT_CODE(hrResult);
break;
}
rgpwszInsertArray[wNumInsert] =
&(rgpwszDecString[ulDecIndex][0]);
ulDecIndex++;
wNumInsert++;
break;
}
case IPADDRESS_TAG:
{
DWORD dwAddr;
dwAddr = va_arg(vlArgList, int);
hrResult = StringCchPrintfW(&(rgpwszDecString[ulDecIndex][0]),
21,
L"%d.%d.%d.%d",
PRINT_IPADDR(dwAddr));
if (FAILED(hrResult)){
dwErr = HRESULT_CODE(hrResult);
break;
}
rgpwszInsertArray[wNumInsert] =
&(rgpwszDecString[ulDecIndex][0]);
ulDecIndex++;
wNumInsert++;
break;
}
}
}
//
// Scan next character
//
ptszTemp++;
i++;
}
if (dwErr == NO_ERROR)
{
if (dwErrorCode == NO_ERROR)
{
ReportEventW(hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
wNumInsert,
0,
rgpwszInsertArray,
(PVOID)NULL);
}
else
{
ReportEventW(hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
wNumInsert,
sizeof(DWORD),
rgpwszInsertArray,
(PVOID)&dwErrorCode);
}
}
// free the strings
while (dwNumAllocStrings--)
{
HeapFree(GetProcessHeap(), 0, pszAllocArray[dwNumAllocStrings]);
}
}
//----------------------------------------------------------------------------
// Function: RouterLogEventData
//
// Logs an event using a HANDLE created by RouterLogRegister.
// Allows caller to include data in the eventlog message.
//----------------------------------------------------------------------------
VOID
RouterLogEventData(
IN HANDLE hLogHandle,
IN DWORD dwEventType,
IN DWORD dwMessageId,
IN DWORD dwSubStringCount,
IN LPTSTR *plpszSubStringArray,
IN DWORD dwDataBytes,
IN LPBYTE lpDataBytes
) {
// plpszSubStringArray can be null.
if(NULL == hLogHandle)
{
return;
}
ReportEvent(
hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
(WORD)dwSubStringCount,
dwDataBytes,
plpszSubStringArray,
(PVOID)lpDataBytes
);
}
//----------------------------------------------------------------------------
// Function: RouterLogEventString
//
// Logs an event using a HANDLE created by RouterLogRegister.
// Allows caller to include an error code string into the log
//----------------------------------------------------------------------------
VOID
RouterLogEventString(
IN HANDLE hLogHandle,
IN DWORD dwEventType,
IN DWORD dwMessageId,
IN DWORD dwSubStringCount,
IN LPTSTR *plpszSubStringArray,
IN DWORD dwErrorCode,
IN DWORD dwErrorIndex
){
DWORD dwRetCode;
DWORD dwIndex;
DWORD dwSubStringIndex = 0;
LPTSTR plpszStringArray[20];
if(NULL == hLogHandle)
{
return;
}
if (dwSubStringCount >= 21 || dwErrorIndex>dwSubStringCount)
return;
dwSubStringCount++;
for ( dwIndex = 0; dwIndex < dwSubStringCount; dwIndex++ )
{
if ( dwIndex == dwErrorIndex )
{
dwRetCode = RouterGetErrorString(
dwErrorCode,
&plpszStringArray[dwIndex] );
if ( dwRetCode != NO_ERROR )
{
//RTASSERT( dwRetCode == NO_ERROR );
return;
}
}
else
{
plpszStringArray[dwIndex] = plpszSubStringArray[dwSubStringIndex++];
}
}
ReportEvent(
hLogHandle,
(WORD)dwEventType,
0,
dwMessageId,
NULL,
(WORD)dwSubStringCount,
sizeof(DWORD),
plpszStringArray,
(PVOID)&dwErrorCode
);
LocalFree( plpszStringArray[dwErrorIndex] );
}
//----------------------------------------------------------------------------
// Function: RouterGetErrorString
//
// Given an error code from raserror.h mprerror.h or winerror.h will return
// a string associated with it. The caller is required to free the string
// by calling LocalFree.
//----------------------------------------------------------------------------
DWORD
RouterGetErrorString(
IN DWORD dwError,
OUT LPTSTR * lplpszErrorString
)
{
DWORD dwRetCode = NO_ERROR;
DWORD dwBufferSize;
if ( ( ( dwError >= RASBASE ) && ( dwError <= RASBASEEND ) ) ||
( ( dwError >= ROUTEBASE ) && ( dwError <= ROUTEBASEEND ) ) ||
( ( dwError >= ROUTER_LOG_BASE) && (dwError <= ROUTER_LOG_BASEEND)))
{
// make sure that load library is called only once
if (InterlockedCompareExchangePointer(
&g_hDll,
INVALID_HANDLE_VALUE,
NULL) == NULL)
{
g_hDll = LoadLibrary( TEXT("mprmsg.dll") );
if(g_hDll == NULL)
{
return( GetLastError() );
}
}
while (*((HINSTANCE volatile *)&g_hDll)==INVALID_HANDLE_VALUE)
Sleep(500);
if (g_hDll==NULL)
return ERROR_CAN_NOT_COMPLETE;
dwRetCode = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
g_hDll,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)lplpszErrorString,
0,
NULL );
}
else
{
dwRetCode = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)lplpszErrorString,
0,
NULL );
}
if ( dwRetCode == 0 )
{
return( GetLastError() );
}
else
{
return( NO_ERROR );
}
}