|
|
/********************************************************************/ /** 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 ); } }
|