mirror of https://github.com/tongzx/nt5src
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.
1532 lines
38 KiB
1532 lines
38 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ELTEST.C
|
|
|
|
Abstract:
|
|
|
|
Test Routines for the EventLog.
|
|
|
|
THINGS I WANT THIS TO DO...
|
|
AddReg <ServerName> <logname> <EntryName> <EventMessageFile>
|
|
<CategoryMessageFile> <CategoryCount> <ParameterMessageFile>
|
|
<TypesSupported> - Creates A Registry Entry.
|
|
|
|
eltest addreg application mytest mf= eltest.dll cat=
|
|
|
|
CreateMessageFile <??? Is this possible ???>
|
|
|
|
WriteEvent <ServerName> <EventSource> <Type> <Category> <EventId> <UserSid?>
|
|
<NumStrings> <Strings> <RawData>
|
|
|
|
ReadLog <Server> <LogFile> <ReadFlags> <RecordOffset> <bufSize>
|
|
If LogFile isn't one of the popular ones, then it could be a backup
|
|
logfile.
|
|
|
|
GetNumEvents <Server> <LogFile>
|
|
|
|
GetOldest <Server> <LogFile>
|
|
|
|
Clear <Server> <LogFile>
|
|
|
|
Backup <Server> <LogFile> <BackupFile>
|
|
|
|
|
|
LOOPTESTS....
|
|
I should be able to run this test like mprtest such that it doesn't leave
|
|
the test process until told. This way we can register an event source,
|
|
then if we call WriteEvent without a specified EventSource, it will use
|
|
the stored source. Calling RegisterEventSource twice without calling
|
|
DeRegisterSource would be an error. (Or better yet, I could keep a table
|
|
of sources and handles).
|
|
|
|
RegisterEventSource <EventSource>
|
|
DeRegisterSource <EventSource>
|
|
|
|
|
|
|
|
|
|
PROTOTYPES FOR FUNCTION....
|
|
|
|
BOOL
|
|
CloseEventLog (
|
|
HANDLE hEventLog
|
|
)
|
|
BOOL
|
|
DeregisterEventSource (
|
|
HANDLE hEventLog
|
|
)
|
|
|
|
BOOL
|
|
NotifyChangeEventLog(
|
|
HANDLE hEventLog,
|
|
HANDLE hEvent
|
|
)
|
|
BOOL
|
|
GetNumberOfEventLogRecords (
|
|
HANDLE hEventLog,
|
|
PDWORD NumberOfRecords
|
|
)
|
|
BOOL
|
|
GetOldestEventLogRecord (
|
|
HANDLE hEventLog,
|
|
PDWORD OldestRecord
|
|
)
|
|
BOOL
|
|
ClearEventLogW (
|
|
HANDLE hEventLog,
|
|
LPCWSTR BackupFileName
|
|
)
|
|
BOOL
|
|
BackupEventLogW (
|
|
HANDLE hEventLog,
|
|
LPCWSTR BackupFileName
|
|
)
|
|
HANDLE
|
|
OpenEventLogW (
|
|
LPCWSTR UNCServerName,
|
|
LPCWSTR ModuleName
|
|
)
|
|
HANDLE
|
|
RegisterEventSourceW (
|
|
LPCWSTR UNCServerName,
|
|
LPCWSTR ModuleName
|
|
)
|
|
HANDLE
|
|
OpenBackupEventLogW (
|
|
LPCWSTR UNCServerName,
|
|
LPCWSTR FileName
|
|
)
|
|
BOOL
|
|
ReadEventLogW (
|
|
HANDLE hEventLog,
|
|
DWORD dwReadFlags,
|
|
DWORD dwRecordOffset,
|
|
LPVOID lpBuffer,
|
|
DWORD nNumberOfBytesToRead,
|
|
DWORD *pnBytesRead,
|
|
DWORD *pnMinNumberOfBytesNeeded
|
|
)
|
|
BOOL
|
|
ReportEventW (
|
|
HANDLE hEventLog,
|
|
WORD wType,
|
|
WORD wCategory OPTIONAL,
|
|
DWORD dwEventID,
|
|
PSID lpUserSid OPTIONAL,
|
|
WORD wNumStrings,
|
|
DWORD dwDataSize,
|
|
LPCWSTR *lpStrings OPTIONAL,
|
|
LPVOID lpRawData OPTIONAL
|
|
)
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
Dan Lafferty (danl) 09-March-1994
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
09-Mar-1994 danl
|
|
created
|
|
|
|
--*/
|
|
|
|
//
|
|
// INCLUDES
|
|
//
|
|
#define UNICODE 1
|
|
#include <nt.h> // DbgPrint prototype
|
|
#include <ntrtl.h> // DbgPrint prototype
|
|
#include <nturtl.h> // needed for winbase.h
|
|
|
|
|
|
#include <stdlib.h> // atoi
|
|
#include <stdio.h> // printf
|
|
#include <conio.h> // getch
|
|
#include <string.h> // strcmp
|
|
#include <windows.h> // win32 typedefs
|
|
#include <tstr.h> // Unicode
|
|
#include <debugfmt.h> // FORMAT_LPTSTR
|
|
|
|
//------------------
|
|
// DEFINES
|
|
//------------------
|
|
#define APPLICATION_LOG "Application"
|
|
#define SYSTEM_LOG "System"
|
|
#define SECURITY_LOG "Security"
|
|
|
|
#define REG_APPLICATION_KEY "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"
|
|
#define REG_SYSTEM_KEY "SYSTEM\\CurrentControlSet\\Services\\EventLog\\System\\"
|
|
#define REG_SECURITY_KEY "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Security\\"
|
|
|
|
#define EVENT_SOURCE_NAME "tevent"
|
|
#define MSG_DLL "%SystemRoot%\\System32\\tevent.dll"
|
|
|
|
#define VALUE_EVENT_MF TEXT("EventMessageFile")
|
|
#define VALUE_CATEGORY_MF TEXT("CategoryMessageFile")
|
|
#define VALUE_PARAMETER_MF TEXT("ParameterMessageFile")
|
|
#define VALUE_TYPES_SUPPORTED TEXT("TypesSupported")
|
|
#define VALUE_CATEGORY_COUNT TEXT("CategoryCount")
|
|
|
|
#define TYPES_SUPPORTED (EVENTLOG_ERROR_TYPE | \
|
|
EVENTLOG_WARNING_TYPE | \
|
|
EVENTLOG_INFORMATION_TYPE)
|
|
//----------------------
|
|
// GLOBALS
|
|
//----------------------
|
|
LPTSTR ApplLogRegName=TEXT(REG_APPLICATION_KEY);
|
|
LPTSTR SysLogRegName =TEXT(REG_SYSTEM_KEY);
|
|
LPTSTR SecLogRegName =TEXT(REG_SECURITY_KEY);
|
|
LPTSTR ApplLogName = TEXT(APPLICATION_LOG);
|
|
LPTSTR SysLogName = TEXT(SYSTEM_LOG);
|
|
LPTSTR SecLogName = TEXT(SECURITY_LOG);
|
|
|
|
//----------------------
|
|
// FUNCTION PROTOTYPES
|
|
//----------------------
|
|
|
|
VOID
|
|
AddRegUsage(VOID);
|
|
|
|
DWORD
|
|
AddSourceToRegistry(
|
|
IN LPTSTR ServerName,
|
|
IN LPTSTR LogName,
|
|
IN LPTSTR EventSourceName,
|
|
IN LPTSTR *argv,
|
|
IN DWORD argc
|
|
);
|
|
|
|
BOOL
|
|
ConvertToUnicode(
|
|
OUT LPWSTR *UnicodeOut,
|
|
IN LPSTR AnsiIn
|
|
);
|
|
|
|
DWORD
|
|
DelSourceInRegistry(
|
|
IN LPTSTR ServerName,
|
|
IN LPTSTR LogName,
|
|
IN LPTSTR EventSourceName
|
|
);
|
|
|
|
VOID
|
|
DisplayStatus (
|
|
IN LPTSTR ServiceName,
|
|
IN LPTSTR DisplayName,
|
|
IN LPSERVICE_STATUS ServiceStatus
|
|
);
|
|
|
|
BOOL
|
|
MakeArgsUnicode (
|
|
DWORD argc,
|
|
PCHAR argv[]
|
|
);
|
|
|
|
BOOL
|
|
ProcessArgs (
|
|
LPTSTR ServerName,
|
|
DWORD argc,
|
|
LPTSTR argv[]
|
|
);
|
|
|
|
VOID
|
|
Usage(
|
|
VOID);
|
|
|
|
VOID
|
|
ConfigUsage(VOID);
|
|
|
|
VOID
|
|
CreateUsage(VOID);
|
|
|
|
VOID
|
|
QueryUsage(VOID);
|
|
|
|
LONG
|
|
wtol(
|
|
IN LPWSTR string
|
|
);
|
|
|
|
VOID
|
|
UserInputLoop(
|
|
LPTSTR ServerName
|
|
);
|
|
DWORD
|
|
ReadLogFile(
|
|
LPTSTR ServerName,
|
|
LPTSTR LogName,
|
|
IN LPTSTR *argv,
|
|
IN DWORD argc
|
|
);
|
|
VOID
|
|
ReadLogUsage(VOID);
|
|
|
|
VOID
|
|
DisplayRecord(
|
|
PEVENTLOGRECORD pElRecord,
|
|
BOOL PrintTheHeader
|
|
);
|
|
|
|
/****************************************************************************/
|
|
VOID __cdecl
|
|
main (
|
|
DWORD argc,
|
|
PCHAR argvAnsi[]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allows manual testing of the EVENTLOG API.
|
|
|
|
eltest
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
UCHAR i;
|
|
DWORD j;
|
|
DWORD argIndex;
|
|
LPTSTR pServerName=NULL;
|
|
LPTSTR *argv;
|
|
|
|
if (argc <2) {
|
|
Usage();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Make the arguments unicode if necessary.
|
|
//
|
|
#ifdef UNICODE
|
|
if (!MakeArgsUnicode(argc, argvAnsi)) {
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
argv = (LPTSTR *)argvAnsi;
|
|
|
|
argIndex = 1;
|
|
if (STRNCMP (argv[1], TEXT("\\\\"), 2) == 0) {
|
|
pServerName = argv[1];
|
|
argIndex = 2; // skip over servername.
|
|
}
|
|
|
|
//
|
|
// Check to see if we are to run in Loop Mode, or in single function
|
|
// mode. In Loop Mode, we go into a loop, and ask the user for
|
|
// input until the user decides to quit.
|
|
//
|
|
// Process Arguments:
|
|
//
|
|
// INDEX 0 1 2 3
|
|
// EL <ServerName> <Function> <FunctionOptions...>
|
|
//
|
|
|
|
if (STRICMP (argv[argIndex], TEXT("Loop")) == 0) {
|
|
UserInputLoop(pServerName);
|
|
}
|
|
else {
|
|
ProcessArgs(pServerName, argc-argIndex, &(argv[argIndex]));
|
|
}
|
|
|
|
|
|
#ifdef UNICODE
|
|
//
|
|
// Free up the unicode strings if there are any
|
|
//
|
|
for(j=0; j<argc; j++) {
|
|
LocalFree(argv[j]);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
UserInputLoop(
|
|
LPTSTR ServerName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sits in a loop, gathering input from the user, and
|
|
processing that input until the user indicates that it should stop.
|
|
The following user commands indicate that we should stop:
|
|
done
|
|
exit
|
|
stop
|
|
quit
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
UCHAR i;
|
|
DWORD j;
|
|
LPTSTR *argv;
|
|
UCHAR buffer[255];
|
|
LPSTR argvA[20];
|
|
DWORD argc=0;
|
|
BOOL KeepGoing;
|
|
|
|
do {
|
|
//------------------------------
|
|
// Get input from the user
|
|
//------------------------------
|
|
buffer[0] = 90-2;
|
|
|
|
printf("\nwaiting for instructions... \n");
|
|
_cgets(buffer);
|
|
|
|
if (buffer[1] > 0) {
|
|
//--------------------------------------
|
|
// put the string in argv/argc format.
|
|
//--------------------------------------
|
|
buffer[1]+=2; // make this an end offset
|
|
argc=0;
|
|
for (i=2,j=0; i<buffer[1]; i++,j++) {
|
|
argc++;
|
|
argvA[j] = &(buffer[i]);
|
|
while ((buffer[i] != ' ') && (buffer[i] != '\0')) {
|
|
i++;
|
|
}
|
|
buffer[i] = '\0';
|
|
}
|
|
|
|
//------------------------------------------
|
|
// Make the arguments unicode if necessary.
|
|
//------------------------------------------
|
|
#ifdef UNICODE
|
|
|
|
if (!MakeArgsUnicode(argc, argvA)) {
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
//-----------------------------------------------
|
|
// If the first argument doesn't indicate that
|
|
// we should stop, then process the arguments.
|
|
//-----------------------------------------------
|
|
argv = (LPTSTR *)argvA;
|
|
|
|
if((STRICMP (argv[0], TEXT("done")) == 0) ||
|
|
(STRICMP (argv[0], TEXT("stop")) == 0) ||
|
|
(STRICMP (argv[0], TEXT("exit")) == 0) ||
|
|
(STRICMP (argv[0], TEXT("quit")) == 0)) {
|
|
KeepGoing = FALSE;
|
|
}
|
|
else {
|
|
KeepGoing = ProcessArgs(ServerName, argc, argv);
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
//-----------------------------------------------
|
|
// Free up the unicode strings if there are any
|
|
//-----------------------------------------------
|
|
for(j=0; j<argc; j++) {
|
|
LocalFree(argv[j]);
|
|
}
|
|
#endif
|
|
}
|
|
} while (KeepGoing);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/****************************************************************************/
|
|
BOOL
|
|
ProcessArgs (
|
|
LPTSTR ServerName,
|
|
DWORD argc,
|
|
LPTSTR argv[]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD status;
|
|
DWORD specialFlag = FALSE;
|
|
DWORD argIndex; // index to unchecked portion of arglist.
|
|
|
|
|
|
argIndex = 0;
|
|
|
|
//
|
|
// If we are adding a registry entry, the get a handle to it.
|
|
// Otherwise, get a handle to the LogFile.
|
|
//
|
|
//-----------------------
|
|
// AddSourceToRegistry
|
|
//-----------------------
|
|
if (STRICMP (argv[argIndex], TEXT("AddReg")) == 0 ) {
|
|
|
|
//
|
|
// Must have at least "AddReg logname EntryName"
|
|
//
|
|
if (argc < (argIndex + 3)) {
|
|
AddRegUsage();
|
|
goto CleanExit;
|
|
}
|
|
|
|
status = AddSourceToRegistry(
|
|
ServerName,
|
|
argv[argIndex+1], // LogName
|
|
argv[argIndex+2], // SourceName
|
|
&argv[argIndex+1],
|
|
argc-(argIndex+2)
|
|
);
|
|
}
|
|
//-----------------------
|
|
// DeleteFromRegistry
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("DelReg")) == 0) {
|
|
//
|
|
// Must have at least "DelReg logname EntryName"
|
|
//
|
|
if (argc < (argIndex + 3)) {
|
|
goto CleanExit;
|
|
}
|
|
|
|
status = DelSourceInRegistry(
|
|
ServerName,
|
|
argv[argIndex+1], // LogName
|
|
argv[argIndex+2] // SourceName
|
|
);
|
|
|
|
}
|
|
//-----------------------
|
|
// WriteEvent
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("WriteEvent")) == 0) {
|
|
printf("In WriteEvent\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// ReadLog
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("ReadLog")) == 0) {
|
|
printf("In ReadLog\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
//
|
|
// Must have at least "ReadLog logname"
|
|
//
|
|
if (argc < (argIndex + 2)) {
|
|
ReadLogUsage();
|
|
goto CleanExit;
|
|
}
|
|
|
|
status = ReadLogFile(
|
|
ServerName, // ServerName
|
|
argv[argIndex+1], // LogName
|
|
&argv[argIndex+1], // argv
|
|
argc-(argIndex+1)); // argc
|
|
}
|
|
//-----------------------
|
|
// GetNumEvents
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("GetNumEvents")) == 0) {
|
|
printf("in GetNumEvents\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// GetOldest
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("GetOldest")) == 0) {
|
|
printf("in GetOldest\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// ClearLog
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("ClearLog")) == 0) {
|
|
printf("in ClearLog\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// Backup
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("Backup")) == 0) {
|
|
printf("in Backup\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// RegisterSource
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("RegisterSource")) == 0) {
|
|
printf("in RegisterSource\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//-----------------------
|
|
// DeRegisterSource
|
|
//-----------------------
|
|
else if (STRICMP (argv[argIndex], TEXT("DeRegisterSource")) == 0) {
|
|
printf("in DeRegisterSource\n");
|
|
if (ServerName != NULL) {
|
|
printf("ServerName = "FORMAT_LPTSTR"\n",ServerName);
|
|
}
|
|
}
|
|
//****************
|
|
// Exit Program
|
|
//****************
|
|
else if (STRICMP (argv[0], TEXT("Exit")) == 0) {
|
|
//
|
|
// THIS SHOULD CLOSE HANDLES.
|
|
//
|
|
return(FALSE);
|
|
}
|
|
else {
|
|
printf("Bad argument\n");
|
|
Usage();
|
|
}
|
|
|
|
CleanExit:
|
|
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
MakeArgsUnicode (
|
|
DWORD argc,
|
|
PCHAR argv[]
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
DWORD i;
|
|
|
|
//
|
|
// ScConvertToUnicode allocates storage for each string.
|
|
// We will rely on process termination to free the memory.
|
|
//
|
|
for(i=0; i<argc; i++) {
|
|
|
|
if(!ConvertToUnicode( (LPWSTR *)&(argv[i]), argv[i])) {
|
|
printf("Couldn't convert argv[%d] to unicode\n",i);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL
|
|
ConvertToUnicode(
|
|
OUT LPWSTR *UnicodeOut,
|
|
IN LPSTR AnsiIn
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function translates an AnsiString into a Unicode string.
|
|
A new string buffer is created by this function. If the call to
|
|
this function is successful, the caller must take responsibility for
|
|
the unicode string buffer that was allocated by this function.
|
|
The allocated buffer should be free'd with a call to LocalFree.
|
|
|
|
NOTE: This function allocates memory for the Unicode String.
|
|
|
|
Arguments:
|
|
|
|
AnsiIn - This is a pointer to an ansi string that is to be converted.
|
|
|
|
UnicodeOut - This is a pointer to a location where the pointer to the
|
|
unicode string is to be placed.
|
|
|
|
Return Value:
|
|
|
|
TRUE - The conversion was successful.
|
|
|
|
FALSE - The conversion was unsuccessful. In this case a buffer for
|
|
the unicode string was not allocated.
|
|
|
|
--*/
|
|
{
|
|
|
|
NTSTATUS ntStatus;
|
|
DWORD bufSize;
|
|
UNICODE_STRING unicodeString;
|
|
ANSI_STRING ansiString;
|
|
|
|
//
|
|
// Allocate a buffer for the unicode string.
|
|
//
|
|
|
|
bufSize = (strlen(AnsiIn)+1) * sizeof(WCHAR);
|
|
|
|
*UnicodeOut = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, (UINT)bufSize);
|
|
|
|
if (*UnicodeOut == NULL) {
|
|
printf("ScConvertToUnicode:LocalAlloc Failure %ld\n",GetLastError());
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Initialize the string structures
|
|
//
|
|
RtlInitAnsiString( &ansiString, AnsiIn);
|
|
|
|
unicodeString.Buffer = *UnicodeOut;
|
|
unicodeString.MaximumLength = (USHORT)bufSize;
|
|
unicodeString.Length = 0;
|
|
|
|
//
|
|
// Call the conversion function.
|
|
//
|
|
ntStatus = RtlAnsiStringToUnicodeString (
|
|
&unicodeString, // Destination
|
|
&ansiString, // Source
|
|
(BOOLEAN)FALSE); // Allocate the destination
|
|
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
|
|
printf("ScConvertToUnicode:RtlAnsiStringToUnicodeString Failure %lx\n",
|
|
ntStatus);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Fill in the pointer location with the unicode string buffer pointer.
|
|
//
|
|
*UnicodeOut = unicodeString.Buffer;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
/****************************************************************************/
|
|
VOID
|
|
DisplayStatus (
|
|
IN LPTSTR ServiceName,
|
|
IN LPTSTR DisplayName,
|
|
IN LPSERVICE_STATUS ServiceStatus
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Displays the service name and the service status.
|
|
|
|
|
|
|
|SERVICE_NAME: messenger
|
|
|DISPLAY_NAME: messenger
|
|
| TYPE : WIN32
|
|
| STATE : ACTIVE,STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN
|
|
| EXIT_CODE : 0xC002001
|
|
| CHECKPOINT : 0x00000001
|
|
| WAIT_HINT : 0x00003f21
|
|
|
|
|
|
|
Arguments:
|
|
|
|
ServiceName - This is a pointer to a string containing the name of
|
|
the service.
|
|
|
|
DisplayName - This is a pointer to a string containing the display
|
|
name for the service.
|
|
|
|
ServiceStatus - This is a pointer to a SERVICE_STATUS structure from
|
|
which information is to be displayed.
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
{
|
|
|
|
printf("\nSERVICE_NAME: "FORMAT_LPTSTR"\n", ServiceName);
|
|
if (DisplayName != NULL) {
|
|
printf("DISPLAY_NAME: "FORMAT_LPTSTR"\n", DisplayName);
|
|
}
|
|
|
|
printf(" TYPE : %lx ", ServiceStatus->dwServiceType);
|
|
|
|
switch(ServiceStatus->dwServiceType){
|
|
case SERVICE_WIN32_OWN_PROCESS:
|
|
printf("WIN32_OWN_PROCESS \n");
|
|
break;
|
|
case SERVICE_WIN32_SHARE_PROCESS:
|
|
printf("WIN32_SHARE_PROCESS \n");
|
|
break;
|
|
case SERVICE_WIN32:
|
|
printf("WIN32 \n");
|
|
break;
|
|
case SERVICE_ADAPTER:
|
|
printf("ADAPTER \n");
|
|
break;
|
|
case SERVICE_KERNEL_DRIVER:
|
|
printf("KERNEL_DRIVER \n");
|
|
break;
|
|
case SERVICE_FILE_SYSTEM_DRIVER:
|
|
printf("FILE_SYSTEM_DRIVER \n");
|
|
break;
|
|
case SERVICE_DRIVER:
|
|
printf("DRIVER \n");
|
|
break;
|
|
default:
|
|
printf(" ERROR \n");
|
|
}
|
|
|
|
printf(" STATE : %lx ", ServiceStatus->dwCurrentState);
|
|
|
|
switch(ServiceStatus->dwCurrentState){
|
|
case SERVICE_STOPPED:
|
|
printf("STOPPED ");
|
|
break;
|
|
case SERVICE_START_PENDING:
|
|
printf("START_PENDING ");
|
|
break;
|
|
case SERVICE_STOP_PENDING:
|
|
printf("STOP_PENDING ");
|
|
break;
|
|
case SERVICE_RUNNING:
|
|
printf("RUNNING ");
|
|
break;
|
|
case SERVICE_CONTINUE_PENDING:
|
|
printf("CONTINUE_PENDING ");
|
|
break;
|
|
case SERVICE_PAUSE_PENDING:
|
|
printf("PAUSE_PENDING ");
|
|
break;
|
|
case SERVICE_PAUSED:
|
|
printf("PAUSED ");
|
|
break;
|
|
default:
|
|
printf(" ERROR ");
|
|
}
|
|
|
|
//
|
|
// Print Controls Accepted Information
|
|
//
|
|
|
|
if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP) {
|
|
printf("\n (STOPPABLE,");
|
|
}
|
|
else {
|
|
printf("\n (NOT_STOPPABLE,");
|
|
}
|
|
|
|
if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) {
|
|
printf("PAUSABLE,");
|
|
}
|
|
else {
|
|
printf("NOT_PAUSABLE,");
|
|
}
|
|
|
|
if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) {
|
|
printf("ACCEPTS_SHUTDOWN)\n");
|
|
}
|
|
else {
|
|
printf("IGNORES_SHUTDOWN)\n");
|
|
}
|
|
|
|
//
|
|
// Print Exit Code
|
|
//
|
|
printf(" WIN32_EXIT_CODE : %d\t(0x%lx)\n",
|
|
ServiceStatus->dwWin32ExitCode,
|
|
ServiceStatus->dwWin32ExitCode);
|
|
printf(" SERVICE_EXIT_CODE : %d\t(0x%lx)\n",
|
|
ServiceStatus->dwServiceSpecificExitCode,
|
|
ServiceStatus->dwServiceSpecificExitCode );
|
|
|
|
//
|
|
// Print CheckPoint & WaitHint Information
|
|
//
|
|
|
|
printf(" CHECKPOINT : 0x%lx\n", ServiceStatus->dwCheckPoint);
|
|
printf(" WAIT_HINT : 0x%lx\n", ServiceStatus->dwWaitHint );
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
Usage(
|
|
VOID)
|
|
{
|
|
printf("DESCRIPTION:\n");
|
|
printf("\tEL is a command line program used for testing the eventlog \n");
|
|
printf("USAGE:\n");
|
|
printf("\tEL <ServerName> [Function] <FunctionOptions...> \n\n");
|
|
printf("\tThe option <server> has the form \"\\\\ServerName\"\n");
|
|
printf("\tFurther help on Functions can be obtained by typing: \"el [Function]\"\n");
|
|
printf("\tFunctions:\n"
|
|
"\t AddReg-----------Creates a registry entry for an event source.\n"
|
|
"\t DelReg-----------Deletes a registry entry.\n"
|
|
"\t WriteEvent-------Writes an event.\n"
|
|
"\t ReadLog----------Reads from the logfile.\n"
|
|
"\t GetNumEvents-----Gets the number of events in the specified log.\n"
|
|
"\t GetOldest--------Gets the record number for the oldest record"
|
|
"\t in the log\n"
|
|
"\t ClearLog---------Clears the specified Log.\n"
|
|
"\t Backup-----------Copies the specified log to a new file.\n"
|
|
"\t RegisterSource---Registers a name for the event source.\n"
|
|
"\t The handle is stored internally.\n"
|
|
"\t DeRegisterSource-Closes handle opened with RegSource.\n"
|
|
"\t NotifyChange-----A thread is created which gets notified of EL changes.\n");
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
VOID
|
|
AddRegUsage(VOID)
|
|
{
|
|
|
|
printf("\nAdds a subkey under one of the logfiles listed in the registry.\n");
|
|
printf("SYNTAX: \n eltest addreg <ServerName> logfile <SubKeyName> <option1> <option2>...\n");
|
|
printf("ADDREG OPTIONS:\n");
|
|
printf("NOTE: The option name includes the equal sign.\n");
|
|
|
|
printf(" MsgFile= Name of Event Message File\n"
|
|
" CatFile= Name of Category Message File\n"
|
|
" ParamFile= Name of Parameter Message File\n"
|
|
" CatCount= Category Count\n"
|
|
" Type= <error|warning|information|AuditSuccess|AuditFailure|All>\n");
|
|
printf("EXAMPLE:\n eltest addreg application myapp MsgFile= MyMsgs.dll"
|
|
" Type= error Type= warning\n");
|
|
|
|
}
|
|
|
|
VOID
|
|
ConfigUsage(VOID)
|
|
{
|
|
printf("Modifies a service entry in the registry and Service Database.\n");
|
|
printf("SYNTAX: \nsc config <service> <option1> <option2>...\n");
|
|
printf("CONFIG OPTIONS:\n");
|
|
printf("NOTE: The option name includes the equal sign.\n"
|
|
" type= <own|share|kernel|filesys|rec|adapt|error>\n"
|
|
" start= <boot|system|auto|demand|disabled|error>\n"
|
|
" error= <normal|severe|critical|error|ignore>\n"
|
|
" binPath= <BinaryPathName>\n"
|
|
" group= <LoadOrderGroup>\n"
|
|
" tag= <yes|no>\n"
|
|
" depend= <Dependencies(space seperated)>\n"
|
|
" obj= <AccountName|ObjectName>\n"
|
|
" DisplayName= <display name>\n"
|
|
" password= <password> \n");
|
|
}
|
|
VOID
|
|
CreateUsage(VOID)
|
|
{
|
|
printf("Creates a service entry in the registry and Service Database.\n");
|
|
printf("SYNTAX: \nsc create <service> <option1> <option2>...\n");
|
|
printf("CREATE OPTIONS:\n");
|
|
printf("NOTE: The option name includes the equal sign.\n"
|
|
" type= <own|share|kernel|filesys|rec|error>\n"
|
|
" start= <boot|system|auto|demand|disabled|error>\n"
|
|
" error= <normal|severe|critical|error|ignore>\n"
|
|
" binPath= <BinaryPathName>\n"
|
|
" group= <LoadOrderGroup>\n"
|
|
" tag= <yes|no>\n"
|
|
" depend= <Dependencies(space seperated)>\n"
|
|
" obj= <AccountName|ObjectName>\n"
|
|
" DisplayName= <display name>\n"
|
|
" password= <password> \n");
|
|
}
|
|
|
|
VOID
|
|
ReadLogUsage(VOID)
|
|
{
|
|
|
|
printf("\nReads a logfile and dumps the contents.\n");
|
|
printf("SYNTAX: \n eltest readlog <ServerName> logfile <option1> <option2>...\n");
|
|
printf("READLOG OPTIONS:\n");
|
|
printf("NOTE: The option name includes the equal sign.\n");
|
|
|
|
printf(" ReadFlag= <fwd|back|seek|seq> (default = fwd) \n"
|
|
" RecordNum= record number where read should start (default=0)\n"
|
|
" BufSize= size of the buffer (default = 10000)\n");
|
|
printf("EXAMPLE:\n eltest addreg application myapp MsgFile= MyMsgs.dll"
|
|
" Type= error Type= warning\n");
|
|
}
|
|
|
|
DWORD
|
|
AddSourceToRegistry(
|
|
IN LPTSTR ServerName,
|
|
IN LPTSTR LogName,
|
|
IN LPTSTR EventSourceName,
|
|
IN LPTSTR *argv,
|
|
IN DWORD argc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes to the registry all the information to register
|
|
this application as an event source.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
TCHAR tempName[MAX_PATH];
|
|
HKEY hKey;
|
|
DWORD dwStatus=NO_ERROR;
|
|
HKEY hRegistry=HKEY_LOCAL_MACHINE;
|
|
|
|
LPTSTR EventMessageFile=NULL;
|
|
LPTSTR CategoryMessageFile=NULL;
|
|
LPTSTR ParameterMessageFile=NULL;
|
|
DWORD dwTypes=0;
|
|
DWORD dwCategoryCount=0;
|
|
DWORD i;
|
|
|
|
//
|
|
// Look at the LogName, and generate the appropriate registry key
|
|
// path for that log.
|
|
//
|
|
if (STRICMP(LogName, ApplLogName) == 0) {
|
|
STRCPY(tempName, ApplLogRegName);
|
|
}
|
|
else if (STRICMP(LogName, SysLogName) == 0) {
|
|
STRCPY(tempName, SysLogRegName);
|
|
}
|
|
else if (STRICMP(LogName, SecLogName) == 0) {
|
|
STRCPY(tempName, SecLogRegName);
|
|
}
|
|
else {
|
|
printf("AddSourceToRegistry: Invalid LogName\n");
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
STRCAT(tempName, EventSourceName);
|
|
|
|
|
|
//
|
|
// Get Variable Arguments
|
|
//
|
|
for (i=0; i<argc ;i++ ) {
|
|
if (STRICMP(argv[i], TEXT("EventMsgFile=")) == 0) {
|
|
EventMessageFile = argv[i+1];
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("CategoryMsgFile=")) == 0) {
|
|
CategoryMessageFile = argv[i+1];
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("ParameterMsgFile=")) == 0) {
|
|
ParameterMessageFile = argv[i+1];
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("Type=")) == 0) {
|
|
//--------------------------------------------------------
|
|
// We want to allow for several arguments of type= in the
|
|
// same line. These should cause the different arguments
|
|
// to be or'd together.
|
|
//--------------------------------------------------------
|
|
if (STRICMP(argv[i+1],TEXT("error")) == 0) {
|
|
dwTypes |= EVENTLOG_ERROR_TYPE;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("warning")) == 0) {
|
|
dwTypes |= EVENTLOG_WARNING_TYPE;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("information")) == 0) {
|
|
dwTypes |= EVENTLOG_INFORMATION_TYPE;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("AuditSuccess")) == 0) {
|
|
dwTypes |= EVENTLOG_AUDIT_SUCCESS;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("AuditFailure")) == 0) {
|
|
dwTypes |= EVENTLOG_AUDIT_FAILURE;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("All")) == 0) {
|
|
dwTypes |= (EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
|
|
EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS |
|
|
EVENTLOG_AUDIT_FAILURE);
|
|
}
|
|
else {
|
|
printf("Invalid Type\n");
|
|
AddRegUsage();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("CategoryCount=")) == 0) {
|
|
dwCategoryCount = ATOL(argv[i+1]);
|
|
i++;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Connect to the registry on the correct machine.
|
|
//
|
|
printf("Connect to Registry\n");
|
|
dwStatus = RegConnectRegistry(ServerName, HKEY_LOCAL_MACHINE, &hRegistry);
|
|
if (dwStatus != NO_ERROR) {
|
|
printf("RegConnectRegistry Failed %d\n",GetLastError());
|
|
return(dwStatus);
|
|
}
|
|
|
|
//
|
|
// Create the new key for this source
|
|
//
|
|
printf("Create Key\n");
|
|
dwStatus = RegCreateKey(hRegistry, tempName, &hKey);
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("Couldn't create Source Key in registry %d\n",dwStatus);
|
|
return(dwStatus);
|
|
}
|
|
if (EventMessageFile != NULL) {
|
|
printf("Set EventMessageFile\n");
|
|
dwStatus = RegSetValueEx(
|
|
hKey,
|
|
VALUE_EVENT_MF,
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(LPBYTE)EventMessageFile,
|
|
STRLEN(EventMessageFile) + sizeof(TCHAR));
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("RegSetValue (messageFile) failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
//
|
|
// Set the Category Message File
|
|
//
|
|
if (CategoryMessageFile != NULL) {
|
|
printf("Set Category Message File\n");
|
|
dwStatus = RegSetValueEx(
|
|
hKey,
|
|
VALUE_CATEGORY_MF,
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(LPBYTE)CategoryMessageFile,
|
|
STRLEN(CategoryMessageFile) + sizeof(TCHAR));
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("RegSetValue (category mf) failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the Parameter Message File
|
|
//
|
|
if (ParameterMessageFile != NULL) {
|
|
printf("Set Parameter Message File\n");
|
|
dwStatus = RegSetValueEx(
|
|
hKey,
|
|
VALUE_PARAMETER_MF,
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(LPBYTE)ParameterMessageFile,
|
|
STRLEN(ParameterMessageFile) + sizeof(TCHAR));
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("RegSetValue (Parameter mf) failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the Types Supported
|
|
//
|
|
if (dwTypes != 0) {
|
|
printf("Set Types Supported\n");
|
|
dwStatus = RegSetValueEx(
|
|
hKey,
|
|
VALUE_TYPES_SUPPORTED,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &dwTypes,
|
|
sizeof(DWORD));
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("RegSetValue (TypesSupported) failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Set the Category Count
|
|
//
|
|
if (dwCategoryCount != 0) {
|
|
printf("Set CategoryCount\n");
|
|
dwStatus = RegSetValueEx(
|
|
hKey,
|
|
VALUE_CATEGORY_COUNT,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &dwCategoryCount,
|
|
sizeof(DWORD));
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("RegSetValue (CategoryCount) failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
}
|
|
dwStatus = NO_ERROR;
|
|
CleanExit:
|
|
RegCloseKey(hKey);
|
|
RegCloseKey(hRegistry);
|
|
return(dwStatus);
|
|
}
|
|
|
|
DWORD
|
|
DelSourceInRegistry(
|
|
IN LPTSTR ServerName,
|
|
IN LPTSTR LogName,
|
|
IN LPTSTR EventSourceName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes to the registry all the information to register
|
|
this application as an event source.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
LPTSTR tempName;
|
|
HKEY hParentKey;
|
|
BOOL status=FALSE;
|
|
DWORD dwStatus;
|
|
HKEY hRegistry=HKEY_LOCAL_MACHINE;
|
|
|
|
|
|
//
|
|
// Look at the LogName, and generate the appropriate registry key
|
|
// path for that log.
|
|
//
|
|
if (STRICMP(LogName, ApplLogName) == 0) {
|
|
tempName = ApplLogRegName;
|
|
}
|
|
else if (STRICMP(LogName, SysLogName) == 0) {
|
|
tempName = SysLogRegName;
|
|
}
|
|
else if (STRICMP(LogName, SecLogName) == 0) {
|
|
tempName = SecLogRegName;
|
|
}
|
|
else {
|
|
printf("AddSourceToRegistry: Invalid LogName\n");
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Connect to the registry on the correct machine.
|
|
//
|
|
dwStatus = RegConnectRegistry(ServerName, HKEY_LOCAL_MACHINE, &hRegistry);
|
|
if (dwStatus != NO_ERROR) {
|
|
printf("RegConnectRegistry Failed %d\n",GetLastError());
|
|
return(status);
|
|
}
|
|
|
|
//
|
|
// Open the Parent Key of the key we want to delete.
|
|
//
|
|
dwStatus = RegOpenKeyEx(
|
|
hRegistry,
|
|
tempName,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hParentKey);
|
|
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("Couldn't open Parent of key to be deleted. %d\n",dwStatus);
|
|
goto CleanExit;
|
|
}
|
|
//
|
|
// Delete the subkey.
|
|
//
|
|
dwStatus = RegDeleteKey(hParentKey, EventSourceName);
|
|
if (dwStatus != ERROR_SUCCESS) {
|
|
printf("Couldn't delete "FORMAT_LPTSTR" key from registry %d\n",
|
|
EventSourceName, dwStatus);
|
|
}
|
|
|
|
RegCloseKey(hParentKey);
|
|
CleanExit:
|
|
RegCloseKey(hRegistry);
|
|
return(status);
|
|
}
|
|
|
|
DWORD
|
|
ReadLogFile(
|
|
LPTSTR ServerName,
|
|
LPTSTR LogName,
|
|
IN LPTSTR *argv,
|
|
IN DWORD argc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
DWORD dwReadFlag = EVENTLOG_FORWARDS_READ;
|
|
DWORD dwRecordNum = 0;
|
|
DWORD BufSize = 10000;
|
|
DWORD numBytesRead;
|
|
DWORD numBytesReqd;
|
|
LPVOID pElBuffer = NULL;
|
|
PEVENTLOGRECORD pElRecord;
|
|
BOOL PrintTheHeader;
|
|
DWORD i;
|
|
HANDLE hEventLog=NULL;
|
|
|
|
//
|
|
// Get Variable Arguments
|
|
//
|
|
for (i=0; i<argc ;i++ ) {
|
|
if (STRICMP(argv[i], TEXT("ReadFlag=")) == 0) {
|
|
if (STRICMP(argv[i+1],TEXT("fwd")) == 0) {
|
|
dwReadFlag |= EVENTLOG_FORWARDS_READ;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("back")) == 0) {
|
|
dwReadFlag |= EVENTLOG_BACKWARDS_READ;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("seek")) == 0) {
|
|
dwReadFlag |= EVENTLOG_SEEK_READ;
|
|
}
|
|
if (STRICMP(argv[i+1],TEXT("seq")) == 0) {
|
|
dwReadFlag |= EVENTLOG_SEQUENTIAL_READ;
|
|
}
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("RecordNum=")) == 0) {
|
|
dwRecordNum = ATOL(argv[i+1]);
|
|
i++;
|
|
}
|
|
if (STRICMP(argv[i], TEXT("BufSize=")) == 0) {
|
|
BufSize = ATOL(argv[i+1]);
|
|
i++;
|
|
}
|
|
hEventLog = OpenEventLog(ServerName,LogName);
|
|
if (hEventLog == NULL) {
|
|
printf("OpenEventLog failed %d\n",GetLastError());
|
|
return(0);
|
|
}
|
|
pElBuffer = LocalAlloc(LPTR, BufSize);
|
|
if (pElBuffer == NULL) {
|
|
printf("ReadLogFile: LocalAlloc Failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Read and Display the contents of the eventlog
|
|
//---------------------------------------------------------
|
|
PrintTheHeader = TRUE;
|
|
TryAgain:
|
|
while(ReadEventLog(
|
|
hEventLog,
|
|
dwReadFlag,
|
|
dwRecordNum,
|
|
pElBuffer,
|
|
BufSize,
|
|
&numBytesRead,
|
|
&numBytesReqd)) {
|
|
|
|
pElRecord = (PEVENTLOGRECORD) pElBuffer;
|
|
while ((PBYTE) pElRecord < (PBYTE) pElBuffer + numBytesRead) {
|
|
//
|
|
// Print the record to the display
|
|
//
|
|
DisplayRecord(pElRecord,PrintTheHeader);
|
|
PrintTheHeader = FALSE;
|
|
//
|
|
// Move to the next event in the buffer
|
|
//
|
|
pElRecord = (PEVENTLOGRECORD)((PBYTE) pElRecord +
|
|
pElRecord->Length);
|
|
}
|
|
}
|
|
switch(GetLastError()) {
|
|
case ERROR_INSUFFICIENT_BUFFER:
|
|
//
|
|
// Increase the size of the buffer and try again
|
|
//
|
|
if (numBytesReqd > BufSize) {
|
|
LocalFree(pElBuffer);
|
|
BufSize = numBytesReqd;
|
|
pElBuffer = LocalAlloc(LPTR, BufSize);
|
|
if (!pElBuffer) {
|
|
printf("ReadLogFile: LocalAlloc Failed %d\n",GetLastError());
|
|
}
|
|
goto TryAgain;
|
|
}
|
|
else {
|
|
printf("ReadLogFile #1: THIS SHOULD NEVER HAPPEN\n");
|
|
}
|
|
break;
|
|
case ERROR_EVENTLOG_FILE_CHANGED:
|
|
//
|
|
// The current read position for this handle has been overwritten.
|
|
// Reopen the file and print a message to the effect that some
|
|
// records may have been missed.
|
|
//
|
|
printf("ReadLogFile: Current Read position has been overwritten\n");
|
|
|
|
hEventLog = OpenEventLog(ServerName,LogName);
|
|
if (hEventLog == NULL) {
|
|
printf("OpenEventLog failed %d\n",GetLastError());
|
|
goto CleanExit;
|
|
}
|
|
goto TryAgain;
|
|
case ERROR_HANDLE_EOF:
|
|
printf("EOF\n");
|
|
break;
|
|
default:
|
|
printf("UnknownError: %d\n",GetLastError());
|
|
break;
|
|
}
|
|
}
|
|
CleanExit:
|
|
if (pElBuffer != NULL) {
|
|
LocalFree(pElBuffer);
|
|
}
|
|
if (hEventLog != NULL) {
|
|
CloseEventLog(hEventLog);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
VOID
|
|
DisplayRecord(
|
|
PEVENTLOGRECORD pElRecord,
|
|
BOOL PrintTheHeader
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
if (PrintTheHeader) {
|
|
printf("RecNum/tTimeGen/tWriteTime/tEventID/tType/tNumStr/tCat/n");
|
|
}
|
|
printf("%d/t%d/t%d/t%d/t%d/t%d/t%d\n",
|
|
pElRecord->RecordNumber,
|
|
pElRecord->TimeGenerated,
|
|
pElRecord->TimeWritten,
|
|
pElRecord->EventID,
|
|
pElRecord->EventType,
|
|
pElRecord->NumStrings,
|
|
pElRecord->EventCategory);
|
|
}
|
|
|
|
LONG
|
|
wtol(
|
|
IN LPWSTR string
|
|
)
|
|
{
|
|
LONG value = 0;
|
|
|
|
while((*string != L'\0') &&
|
|
(*string >= L'0') &&
|
|
( *string <= L'9')) {
|
|
value = value * 10 + (*string - L'0');
|
|
string++;
|
|
}
|
|
|
|
return(value);
|
|
}
|
|
|