#include <windows.h>
static LPSTR DupeString(LPSTR pszIn)
{
LPSTR pszOut = (LPSTR)LocalAlloc(LMEM_FIXED,strlen(pszIn)+1);
strcpy(pszOut,pszIn); return pszOut;
}
static BOOL GetSystemString(DWORD dwError,LPSTR *ppszOut)
{
DWORD rc =
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)ppszOut,0,NULL);
if (rc == 0)
{
*ppszOut = DupeString("");
if (*ppszOut == NULL) return FALSE;
}
return TRUE;
}
DWORD
LogEvent(LPCSTR pszEvSrc, DWORD dwEventID, LPCSTR pszFormat,...)
{
DWORD dwReturn = NOERROR;
LPSTR *ppszSubst = NULL;
ULONG nSubst = 0;
DWORD dwLastErrorOnInput = GetLastError();
/*--- (1) CREATE nSubst AND pszSubst FOR ReportEvent CALL ---*/
if (pszFormat != NULL && *pszFormat != '\0')
{
/*-- ALLOCATE AN ARRAY OF POINTERS FOR ReportEvent ---*/
nSubst = strlen(pszFormat);
ppszSubst=
(LPSTR*)LocalAlloc(LMEM_FIXED, sizeof(LPSTR)*nSubst);
if (ppszSubst == NULL) goto return_last_error;
for (ULONG k=0; k < nSubst; k++) ppszSubst[k] = NULL;
/*--- FILL IN THE ARRAY OF POINTERS FROM va_list --*/
va_list vl;
va_start(vl,pszFormat);
for (ULONG i=0; i < nSubst && dwReturn == NOERROR ;i++)
{
LPVOID pArg = va_arg(vl, LPVOID);
switch (tolower(pszFormat[i]))
{
case 's':
ppszSubst[i]=DupeString((LPSTR)pArg);
if (ppszSubst[i]==NULL) dwReturn = GetLastError();
break;
case 'd':
{ /*--- FORMAT A DECIMAL DIGIT ---*/
char szDigits[20];
ppszSubst[i] =
DupeString(itoa((INT)pArg,szDigits,10));
if (ppszSubst[i]==NULL)
dwReturn = GetLastError();
break;
}
case 'x':
{ /*-- FORMAT A HEXIDECIMAL DIGIT,
C STYLE ---*/
char szDigits[22] = "0x";
ppszSubst[i]=
DupeString(itoa((INT)pArg,
szDigits+2, 16)-2);
if (ppszSubst[i]==NULL)
dwReturn = GetLastError();
break;
}
case 'm':
{
if (!GetSystemString(((DWORD)pArg & 0xFFFF),
&ppszSubst[i]))
dwReturn = GetLastError();
break;
}
default:
dwReturn = ERROR_INVALID_PARAMETER;
}
}
va_end(vl);
if (dwReturn != NOERROR) goto done;
}
/*--- (2) GET THE EVENT TYPE FROM THE EVENT ID PARAMETER ---*/
WORD wType;
wType = EVENTLOG_INFORMATION_TYPE;
if ((dwEventID & ERROR_SEVERITY_WARNING) ==
ERROR_SEVERITY_WARNING)
wType = EVENTLOG_WARNING_TYPE;
if ((dwEventID & ERROR_SEVERITY_ERROR) ==
ERROR_SEVERITY_ERROR)
{ wType = EVENTLOG_ERROR_TYPE; }
/*-- (3) WRITE THE EVENT TO THE EVENT LOG ---*/
HANDLE hEventSource;
hEventSource = RegisterEventSource(NULL,pszEvSrc);
if (hEventSource == NULL) goto return_last_error;
BOOL fSuccess;
fSuccess =
ReportEvent(hEventSource, wType,
0, /*-- USE THE DEFAULT CATEGORY ---*/
dwEventID,
NULL, /*--- USE THE DEFAULT SID ---*/
nSubst,
0, /*---- NO DATA ---*/
(LPCSTR*)ppszSubst,
NULL); /*---- NO DATA ----*/
if (!fSuccess)
{
dwReturn = GetLastError();
DeregisterEventSource(hEventSource);
goto done;
}
DeregisterEventSource(hEventSource);
/*--- END OF STEP (3) ----*/
goto done; /*-- ALL EXIT POINTS ARE BELOW ---*/
return_last_error:
dwReturn = GetLastError();
done:
if (ppszSubst != NULL)
{ /*-- FREE ALL THE MEMORY ---*/
for (ULONG i=0; i < nSubst && ppszSubst[i] != NULL; i++)
LocalFree(ppszSubst[i]);
LocalFree(ppszSubst);
}
/*-- RESTORE THE GetLastError ON INPUT --*/
SetLastError(dwLastErrorOnInput);
return dwReturn;
}