summaryrefslogtreecommitdiffstats
path: root/private/eventlog/test
diff options
context:
space:
mode:
Diffstat (limited to 'private/eventlog/test')
-rw-r--r--private/eventlog/test/buildreg.dat3
-rw-r--r--private/eventlog/test/makefile6
-rw-r--r--private/eventlog/test/sources89
-rw-r--r--private/eventlog/test/test.c1400
-rw-r--r--private/eventlog/test/testwin.c770
-rw-r--r--private/eventlog/test/testwina.c693
6 files changed, 2961 insertions, 0 deletions
diff --git a/private/eventlog/test/buildreg.dat b/private/eventlog/test/buildreg.dat
new file mode 100644
index 000000000..9a74e65e5
--- /dev/null
+++ b/private/eventlog/test/buildreg.dat
@@ -0,0 +1,3 @@
+System,\systemroot\sysevent.log,4096,10
+Application,\systemroot\appevent.log,4096,10
+Security,\systemroot\audit.log,4096,10
diff --git a/private/eventlog/test/makefile b/private/eventlog/test/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/eventlog/test/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/eventlog/test/sources b/private/eventlog/test/sources
new file mode 100644
index 000000000..226e46d04
--- /dev/null
+++ b/private/eventlog/test/sources
@@ -0,0 +1,89 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Rajen Shah (rajens) 2-Jul-1991
+
+
+Revision History:
+
+!ENDIF
+
+#
+# The TARGETNAME variable is defined by the developer. It is the name of
+# the target (component) that is being built by this makefile. It
+# should NOT include any path or file extension information.
+#
+
+MAJORCOMP = eventlog
+MINORCOMP = test
+TARGETNAME= elftest
+
+#
+# The TARGETPATH and TARGETTYPE varialbes are defined by the developer.
+# The first specifies where the target is to be build. The second specifies
+# the type of target (either PROGRAM, DYNLINK or LIBRARY)
+#
+
+TARGETPATH=obj
+
+TARGETTYPE=PROGRAM
+
+TARGETLIBS= \
+ $(BASEDIR)\public\sdk\lib\*\advapi32.lib
+
+
+#
+# The INCLUDES variable specifies any include paths that are specific to
+# this source directory. Separate multiple directory paths with single
+# semicolons. Relative path specifications are okay.
+#
+
+INCLUDES=.;..;$(BASEDIR)\public\sdk\inc;$(BASEDIR)\private\net\inc
+
+#
+# The SOURCES variable is defined by the developer. It is a list of all the
+# source files for this component. Each source file should be on a separate
+# line using the line continuation character. This will minimize merge
+# conflicts if two developers adding source files to the same component.
+#
+
+SOURCES= \
+ test.c
+
+
+C_DEFINES=-DNTOS2=1
+
+UMTYPE=console
+
+# The following builds the server executable file. The client is built
+# in the client directory.
+
+UMTYPE=console
+UMTEST=testwin*testwina
+UMLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib
+OPTIONAL_UMTEST=wintest
+
+#
+# Defining the NTTARGETFILES variable causes MAKEFILE.DEF to attempt to
+# include .\makefile.inc immediately after it specifies the top
+# level targets (all, clean and loc) and their dependencies. MAKEFILE.DEF
+# also expands the value of the NTTARGETFILES variable at the end of the
+# list of dependencies for the all target. Useful for specifying additional
+# targets and dependencies that don't fit the general case covered by
+# MAKEFILE.DEF
+#
diff --git a/private/eventlog/test/test.c b/private/eventlog/test/test.c
new file mode 100644
index 000000000..bb996bf8d
--- /dev/null
+++ b/private/eventlog/test/test.c
@@ -0,0 +1,1400 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ TEST.C
+
+Abstract:
+
+ Test program for the eventlog service. This program calls the Elf
+ APIs to test out the operation of the service.
+
+Author:
+
+ Rajen Shah (rajens) 05-Aug-1991
+
+Revision History:
+
+
+--*/
+/*----------------------*/
+/* INCLUDES */
+/*----------------------*/
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#include <stdio.h> // printf
+#include <string.h> // stricmp
+#include <stdlib.h>
+#include <process.h> // exit
+#include <elfcommn.h>
+#include <windows.h>
+#include <ntiolog.h>
+#include <malloc.h>
+
+#define READ_BUFFER_SIZE 1024*2 // Use 2K buffer
+
+#define SIZE_DATA_ARRAY 22
+
+#define SET_OPERATION(x) \
+ if (Operation != Invalid) { \
+ printf("Only one operation at a time\n"); \
+ Usage(); \
+ } \
+ Operation = x;
+
+//
+// Global buffer used to emulate "binary data" when writing an event
+// record.
+//
+ULONG Data[SIZE_DATA_ARRAY];
+enum _OPERATION_TYPE {
+ Invalid,
+ Clear,
+ Backup,
+ Read,
+ Write,
+ Notify,
+ LPC
+} Operation = Invalid;
+ULONG ReadFlags;
+BOOL Verbose = FALSE;
+ULONG NumberofRecords = 1;
+ULONG DelayInMilliseconds = 0;
+CHAR DefaultModuleName[] = "TESTAPP";
+PCHAR pModuleName = DefaultModuleName;
+PCHAR pBackupFileName;
+ANSI_STRING AnsiString;
+UNICODE_STRING ServerName;
+BOOL ReadingBackupFile = FALSE;
+BOOL ReadingModule = FALSE;
+BOOL WriteInvalidRecords = FALSE;
+BOOL InvalidUser = FALSE;
+
+// Function prototypes
+
+VOID ParseParms(ULONG argc, PCHAR *argv);
+
+VOID
+Initialize (
+ VOID
+ )
+{
+ ULONG i;
+
+ // Initialize the values in the data buffer.
+ //
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] = i;
+
+}
+
+
+VOID
+Usage (
+ VOID
+ )
+{
+ printf( "usage: \n" );
+ printf( "-c Clears the specified log\n");
+ printf( "-b <filename> Backs up the log to file <filename>\n");
+ printf( "-f <filename> Filename of backup log to use for read\n");
+ printf( "-i Generate invalid SID\n");
+ printf( "-l[i] nn Writes nn records thru LPC port [i ==> bad records]\n");
+ printf( "-m <modulename> Module name to use for read/clear\n");
+ printf( "-n Test out change notify\n");
+ printf( "-rsb Reads nn event log records sequentially backwards\n");
+ printf( "-rsf nn Reads nn event log records sequentially forwards\n");
+ printf( "-rrb <record> Reads event log from <record> backwards\n");
+ printf( "-rrf <record> Reads event log from <record> forwards\n");
+ printf( "-s <servername> Name of server to remote calls to\n");
+ printf( "-t nn Number of milliseconds to delay between read/write"
+ " (default 0)\n\tOnly used with -l switch\n");
+ printf( "-w <count> Writes <count> records\n");
+ exit(0);
+
+} // Usage
+
+
+NTSTATUS
+WriteLogEntry (
+ HANDLE LogHandle,
+ ULONG EventID
+ )
+{
+#define NUM_STRINGS 2
+#define SIZE_TOKEN_BUFFER 512
+
+ NTSTATUS Status;
+ USHORT EventType, i;
+ ULONG DataSize;
+ PSID pUserSid;
+ PWSTR Strings[NUM_STRINGS] = {L"StringOne", L"StringTwo"};
+ PUNICODE_STRING UStrings[NUM_STRINGS];
+ HANDLE hProcess;
+ HANDLE hToken;
+ PTOKEN_USER pTokenUser;
+ DWORD SizeRequired;
+
+ EventType = EVENTLOG_INFORMATION_TYPE;
+ DataSize = sizeof(ULONG) * SIZE_DATA_ARRAY;
+
+ //
+ // Get the SID of the current user (process)
+ //
+
+ pTokenUser = malloc(SIZE_TOKEN_BUFFER);
+
+ if (!InvalidUser) {
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
+ GetCurrentProcessId());
+ if (!hProcess) {
+ printf("Couldn't open the process, rc = %d\n", GetLastError());
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
+ printf("Couldn't open the token, rc = %d\n", GetLastError());
+ CloseHandle(hProcess);
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (!pTokenUser) {
+ printf("Couldn't allocate buffer for TokenUser\n");
+ CloseHandle(hToken);
+ CloseHandle(hProcess);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (!GetTokenInformation(hToken, TokenUser, pTokenUser, SIZE_TOKEN_BUFFER,
+ &SizeRequired)) {
+ printf("Couldn't get TokenUser information, rc = %d\n",
+ GetLastError());
+ CloseHandle(hToken);
+ CloseHandle(hProcess);
+ free(pTokenUser);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ CloseHandle(hToken);
+ CloseHandle(hProcess);
+ }
+ else {
+ memset(pTokenUser, 0xFADE, SIZE_TOKEN_BUFFER);
+ pTokenUser->User.Sid = (PSID)pUserSid;
+ }
+
+ pUserSid = pTokenUser->User.Sid;
+
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] += i;
+
+ // Allocate space for the unicode strings in the array, and
+ // copy over the strings from Strings[] to that array.
+ //
+ for (i=0; i<NUM_STRINGS; i++) {
+
+ UStrings[i] = malloc(sizeof(UNICODE_STRING));
+ RtlInitUnicodeString (UStrings[i], Strings[i]);
+ // force this to be non-null terminated
+ UStrings[i]->MaximumLength = UStrings[i]->Length;
+ }
+ Status = ElfReportEventW (
+ LogHandle,
+ EventType,
+ 0, // category
+ EventID,
+ pUserSid,
+ NUM_STRINGS,
+ DataSize,
+ UStrings,
+ (PVOID)Data,
+ 0, // Flags - paired event support
+ NULL, // RecordNumber | not in product 1
+ NULL // TimeWritten -
+ );
+
+ for (i=0; i<NUM_STRINGS; i++)
+ free(UStrings[i]);
+
+ free(pTokenUser);
+ return (Status);
+}
+
+
+VOID
+DisplayEventRecords( PVOID Buffer,
+ ULONG BufSize,
+ PULONG NumRecords)
+
+{
+ PEVENTLOGRECORD pLogRecord;
+ LPWSTR pwString;
+ ULONG Count = 0;
+ ULONG Offset = 0;
+ ULONG i;
+
+ pLogRecord = (PEVENTLOGRECORD) Buffer;
+
+ while (Offset < BufSize && Count < *NumRecords) {
+
+ printf("\nRecord # %lu\n", pLogRecord->RecordNumber);
+
+ printf("Length: 0x%lx TimeGenerated: 0x%lx EventID: 0x%lx EventType: 0x%x\n",
+ pLogRecord->Length, pLogRecord->TimeGenerated, pLogRecord->EventID,
+ pLogRecord->EventType);
+
+ printf("NumStrings: 0x%x StringOffset: 0x%lx UserSidLength: 0x%lx TimeWritten: 0x%lx\n",
+ pLogRecord->NumStrings, pLogRecord->StringOffset,
+ pLogRecord->UserSidLength, pLogRecord->TimeWritten);
+
+ printf("UserSidOffset: 0x%lx DataLength: 0x%lx DataOffset: 0x%lx Category: 0x%lx\n",
+ pLogRecord->UserSidOffset, pLogRecord->DataLength,
+ pLogRecord->DataOffset, pLogRecord->EventCategory);
+
+ //
+ // Print out module name
+ //
+
+ pwString = (PWSTR)((LPBYTE) pLogRecord + sizeof(EVENTLOGRECORD));
+ printf("ModuleName: %ws\n", pwString);
+
+ //
+ // Display ComputerName
+ //
+ pwString += wcslen(pwString) + 1;
+ printf("ComputerName: %ws\n", pwString);
+
+ //
+ // Display strings
+ //
+
+ pwString = (PWSTR)((LPBYTE)pLogRecord + pLogRecord->StringOffset);
+
+ printf("Strings: ");
+ for (i=0; i<pLogRecord->NumStrings; i++) {
+
+ printf(" %ws ", pwString);
+ pwString += wcslen(pwString) + 1;
+ }
+
+ printf("\n");
+
+ //
+ // If verbose mode, display binary data (up to 256 bytes)
+ // BUGBUG - this code will hit an alignment fault on mips.
+ //
+
+ if (Verbose) {
+ PULONG pData;
+ PULONG pEnd;
+
+ if (pLogRecord->DataLength < 80) {
+ pEnd = (PULONG)((PBYTE) pLogRecord + pLogRecord->DataOffset +
+ pLogRecord->DataLength);
+ }
+ else {
+ pEnd = (PULONG)((PBYTE) pLogRecord + pLogRecord->DataOffset +
+ 256);
+ }
+
+ printf("Data: \n\n");
+ for (pData = (PULONG)((PBYTE) pLogRecord + pLogRecord->DataOffset);
+ pData < pEnd; (PBYTE) pData += 32) {
+
+ printf("\t%08x %08x %08x %08x\n", pData[0], pData[1], pData[2],
+ pData[3]);
+ }
+ }
+
+ // Get next record
+ //
+ Offset += pLogRecord->Length;
+
+ pLogRecord = (PEVENTLOGRECORD)((ULONG)Buffer + Offset);
+
+ Count++;
+
+ }
+
+ *NumRecords = Count;
+
+}
+
+
+NTSTATUS
+ReadFromLog ( HANDLE LogHandle,
+ PVOID Buffer,
+ PULONG pBytesRead,
+ ULONG ReadFlag,
+ ULONG Record
+ )
+{
+ NTSTATUS Status;
+ ULONG MinBytesNeeded;
+
+ Status = ElfReadEventLogW (
+ LogHandle,
+ ReadFlag,
+ Record,
+ Buffer,
+ READ_BUFFER_SIZE,
+ pBytesRead,
+ &MinBytesNeeded
+ );
+
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ printf("Buffer too small. Need %lu bytes min\n", MinBytesNeeded);
+
+ return (Status);
+}
+
+
+NTSTATUS
+TestReadEventLog (
+ ULONG Count,
+ ULONG ReadFlag,
+ ULONG Record
+ )
+
+{
+ NTSTATUS Status, IStatus;
+
+ HANDLE LogHandle;
+ UNICODE_STRING ModuleNameU;
+ ANSI_STRING ModuleNameA;
+ ULONG NumRecords, BytesReturned;
+ PVOID Buffer;
+ ULONG RecordOffset;
+ ULONG NumberOfRecords;
+ ULONG OldestRecord;
+
+ printf("Testing ElfReadEventLog API to read %lu entries\n",Count);
+
+ Buffer = malloc (READ_BUFFER_SIZE);
+
+ //
+ // Initialize the strings
+ //
+ NumRecords = Count;
+ RtlInitAnsiString(&ModuleNameA, pModuleName);
+ RtlAnsiStringToUnicodeString(&ModuleNameU, &ModuleNameA, TRUE);
+ ModuleNameU.MaximumLength = ModuleNameU.Length;
+
+ //
+ // Open the log handle
+ //
+
+ if (ReadingBackupFile) {
+ printf("ElfOpenBackupEventLog - ");
+ Status = ElfOpenBackupEventLogW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+ }
+ else {
+ printf("ElfOpenEventLog - ");
+ Status = ElfOpenEventLogW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Error - 0x%lx\n", Status);
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Get and print record information
+ //
+
+ Status = ElfNumberOfRecords(LogHandle, & NumberOfRecords);
+ if (NT_SUCCESS(Status)) {
+ Status = ElfOldestRecord(LogHandle, & OldestRecord);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Query of record information failed with %X", Status);
+ return(Status);
+ }
+
+ printf("\nThere are %d records in the file, %d is the oldest"
+ " record number\n", NumberOfRecords, OldestRecord);
+
+ RecordOffset = Record;
+
+ while (Count && NT_SUCCESS(Status)) {
+
+ printf("Read %u records\n", NumRecords);
+ //
+ // Read from the log
+ //
+ Status = ReadFromLog ( LogHandle,
+ Buffer,
+ &BytesReturned,
+ ReadFlag,
+ RecordOffset
+ );
+ if (NT_SUCCESS(Status)) {
+
+ printf("Bytes read = 0x%lx\n", BytesReturned);
+ NumRecords = Count;
+ DisplayEventRecords(Buffer, BytesReturned, &NumRecords);
+ Count -= NumRecords;
+ }
+
+ }
+ printf("\n");
+
+ if (!NT_SUCCESS(Status)) {
+ if (Status == STATUS_END_OF_FILE) {
+ printf("Tried to read more records than in log file\n");
+ }
+ else {
+ printf ("Error - 0x%lx. Remaining count %lu\n", Status, Count);
+ }
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling ElfCloseEventLog\n");
+ IStatus = ElfCloseEventLog (LogHandle);
+ }
+
+ return (Status);
+}
+
+
+NTSTATUS
+TestReportEvent (
+ ULONG Count
+ )
+
+{
+ NTSTATUS Status, IStatus;
+ HANDLE LogHandle;
+ UNICODE_STRING ModuleNameU;
+ ANSI_STRING ModuleNameA;
+ ULONG EventID = 99;
+
+ printf("Testing ElfReportEvent API\n");
+
+ //
+ // Initialize the strings
+ //
+
+ RtlInitAnsiString(&ModuleNameA, pModuleName);
+ RtlAnsiStringToUnicodeString(&ModuleNameU, &ModuleNameA, TRUE);
+ ModuleNameU.MaximumLength = ModuleNameU.Length;
+
+ //
+ // Open the log handle
+ //
+ printf("Calling ElfRegisterEventSource for WRITE %lu times - ", Count);
+ Status = ElfRegisterEventSourceW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Error - 0x%lx\n", Status);
+
+ } else {
+ printf("SUCCESS\n");
+
+ while (Count && NT_SUCCESS(Status)) {
+
+ printf("Record # %u \n", Count);
+
+ //
+ // Write an entry into the log
+ //
+ Data[0] = Count; // Make data "unique"
+ EventID = (EventID + Count) % 100; // Vary the eventids
+ Status = WriteLogEntry ( LogHandle, EventID );
+ Count--;
+ }
+ printf("\n");
+
+ if (!NT_SUCCESS(Status)) {
+ if (Status == STATUS_LOG_FILE_FULL) {
+ printf("Log Full\n");
+ }
+ else {
+ printf ("Error - 0x%lx. Remaining count %lu\n", Status, Count);
+ }
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling ElfDeregisterEventSource\n");
+ IStatus = ElfDeregisterEventSource (LogHandle);
+ }
+
+ return (Status);
+}
+
+
+NTSTATUS
+TestElfClearLogFile(
+ VOID
+ )
+
+{
+ NTSTATUS Status, IStatus;
+ HANDLE LogHandle;
+ UNICODE_STRING BackupU, ModuleNameU;
+ ANSI_STRING ModuleNameA;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE ClearHandle;
+ FILE_DISPOSITION_INFORMATION DeleteInfo = {TRUE};
+ IO_STATUS_BLOCK IoStatusBlock;
+ BOOLEAN DontRetry = FALSE;
+
+ printf("Testing ElfClearLogFile API\n");
+ //
+ // Initialize the strings
+ //
+ RtlInitAnsiString( &ModuleNameA, pModuleName);
+ RtlAnsiStringToUnicodeString(&ModuleNameU, &ModuleNameA, TRUE);
+ ModuleNameU.MaximumLength = ModuleNameU.Length ;
+
+ //
+ // Open the log handle
+ //
+ printf("Calling ElfOpenEventLog for CLEAR - ");
+ Status = ElfOpenEventLogW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Error - 0x%lx\n", Status);
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Clear the log file and back it up to "view.evt"
+ //
+
+ RtlInitUnicodeString( &BackupU,
+ L"\\SystemRoot\\System32\\Config\\view.evt" );
+ BackupU.MaximumLength = BackupU.Length;
+retry:
+ printf("Calling ElfClearEventLogFile backing up to view.evt ");
+ Status = ElfClearEventLogFileW (
+ LogHandle,
+ &BackupU
+ );
+
+ if (Status == STATUS_OBJECT_NAME_COLLISION) {
+ if (DontRetry) {
+ printf("Still can't backup to View.Evt\n");
+ }
+ else {
+ printf("Failed.\nView.Evt already exists, deleting ...\n");
+
+ //
+ // Open the file with delete access
+ //
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &BackupU,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+
+ Status = NtOpenFile(&ClearHandle,
+ GENERIC_READ | DELETE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ );
+
+ Status = NtSetInformationFile(
+ ClearHandle,
+ &IoStatusBlock,
+ &DeleteInfo,
+ sizeof(DeleteInfo),
+ FileDispositionInformation
+ );
+
+ if (NT_SUCCESS (Status) ) {
+ Status = NtClose (ClearHandle); // Discard status
+ goto retry;
+ }
+
+ printf("Delete failed 0x%lx\n",Status);
+ Status = NtClose (ClearHandle); // Discard status
+ goto JustClear;
+ }
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ printf ("Error - 0x%lx\n", Status);
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+JustClear:
+
+ //
+ // Now just clear the file without backing it up
+ //
+ printf("Calling ElfClearEventLogFile with no backup ");
+ Status = ElfClearEventLogFileW (
+ LogHandle,
+ NULL
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf ("Error - 0x%lx\n", Status);
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling ElfCloseEventLog\n");
+ IStatus = ElfCloseEventLog (LogHandle);
+ }
+
+ return(Status);
+}
+
+
+NTSTATUS
+TestElfBackupLogFile(
+ VOID
+ )
+
+{
+ NTSTATUS Status, IStatus;
+ HANDLE LogHandle;
+ UNICODE_STRING BackupU, ModuleNameU;
+ ANSI_STRING AnsiString;
+
+ printf("Testing ElfBackupLogFile API\n");
+
+ //
+ // Initialize the strings
+ //
+
+ RtlInitAnsiString( &AnsiString, pModuleName);
+ RtlAnsiStringToUnicodeString(&ModuleNameU, &AnsiString, TRUE);
+ ModuleNameU.MaximumLength = ModuleNameU.Length ;
+
+ //
+ // Open the log handle
+ //
+
+ printf("Calling ElfOpenEventLog for BACKUP - ");
+ Status = ElfOpenEventLogW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Error - 0x%lx\n", Status);
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Backup the log file
+ //
+
+ printf("Calling ElfBackupEventLogFile backing up to %s ",
+ pBackupFileName);
+
+ RtlInitAnsiString( &AnsiString, pBackupFileName);
+ RtlAnsiStringToUnicodeString(&BackupU, &AnsiString, TRUE);
+ BackupU.MaximumLength = BackupU.Length;
+
+ Status = ElfBackupEventLogFileW (
+ LogHandle,
+ &BackupU
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf ("Error - 0x%lx\n", Status);
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+
+ printf("Calling ElfCloseEventLog - ");
+ IStatus = ElfCloseEventLog (LogHandle);
+ if (NT_SUCCESS(IStatus)) {
+ printf("Success\n");
+ }
+ else {
+ printf("Failed with code %X\n", IStatus);
+ }
+ }
+
+ return(Status);
+}
+
+#define DRIVER_NAME L"FLOPPY"
+#define DEVICE_NAME L"A:"
+#define STRING L"Test String"
+
+// These include the NULL terminator, but is length in chars, not bytes
+#define DRIVER_NAME_LENGTH 7
+#define DEVICE_NAME_LENGTH 3
+#define STRING_LENGTH 12
+
+#define NUMBER_OF_DATA_BYTES 8
+
+VOID
+TestLPCWrite(
+ DWORD NumberOfRecords,
+ DWORD MillisecondsToDelay
+ )
+{
+
+ HANDLE PortHandle;
+ UNICODE_STRING PortName;
+ NTSTATUS Status;
+ SECURITY_QUALITY_OF_SERVICE Qos;
+ PIO_ERROR_LOG_MESSAGE pIoErrorLogMessage;
+ DWORD i;
+ LPWSTR pDestinationString;
+ PPORT_MESSAGE RequestMessage;
+ PORT_MESSAGE ReplyMessage;
+ WORD DataLength;
+ WORD TotalLength;
+ INT YorN;
+ CHAR NumberString[8];
+ ULONG MessageId = 1;
+ DWORD BadType = 0;
+
+ //
+ // Warn the user about how this test works
+ //
+
+ printf("\nThis test doesn't end! It will write a number of\n"
+ "records, then prompt you to write more. This is \n"
+ "required since it is simulating the system thread\n"
+ "which never shuts down it's connection\n\n"
+ "Do you wish to continue with this test (y or n)? ");
+
+ YorN = getc(stdin);
+
+ if (YorN == 'n' || YorN == 'N') {
+ return;
+ }
+
+ //
+ // Initialize the SecurityQualityofService structure
+ //
+
+ Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
+ Qos.ImpersonationLevel = SecurityImpersonation;
+ Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+ Qos.EffectiveOnly = TRUE;
+
+ //
+ // Connect to the LPC Port
+ //
+
+ RtlInitUnicodeString( &PortName, L"\\ErrorLogPort" );
+
+ Status = NtConnectPort(& PortHandle,
+ & PortName,
+ & Qos,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Connect to the LPC port failed with RC %X\n", Status);
+ return;
+ }
+
+ //
+ // Allocate the memory for the Message to send to the LPC port. It
+ // will contain a PORT_MESSAGE followed by an IO_ERROR_LOG_MESSAGE
+ // followed by Drivername and Devicename UNICODE strings
+ //
+
+ DataLength = PORT_MAXIMUM_MESSAGE_LENGTH -
+ (sizeof(IO_ERROR_LOG_MESSAGE)
+ + DRIVER_NAME_LENGTH * sizeof(WCHAR)
+ + DEVICE_NAME_LENGTH * sizeof(WCHAR)
+ + STRING_LENGTH * sizeof(WCHAR));
+ TotalLength = PORT_MAXIMUM_MESSAGE_LENGTH + (WORD) sizeof(PORT_MESSAGE);
+
+ RequestMessage = (PPORT_MESSAGE) malloc(TotalLength);
+ if (RequestMessage == NULL) {
+ printf("Couldn't alloc %d bytes of memory for message\n", TotalLength);
+ NtClose(PortHandle);
+ return;
+ }
+
+ pIoErrorLogMessage = (PIO_ERROR_LOG_MESSAGE) ((LPBYTE) RequestMessage +
+ sizeof(PORT_MESSAGE));
+
+ //
+ // Initialize the PORT_MESSAGE
+ //
+
+ RequestMessage->u1.s1.DataLength = PORT_MAXIMUM_MESSAGE_LENGTH;
+ RequestMessage->u1.s1.TotalLength = TotalLength;
+ RequestMessage->u2.s2.Type = 0;
+ RequestMessage->u2.ZeroInit = 0;
+ RequestMessage->ClientId.UniqueProcess = GetCurrentProcess();
+ RequestMessage->ClientId.UniqueThread = GetCurrentThread();
+ RequestMessage->MessageId = 0x1234;
+
+ //
+ // Initialize the IO_ERROR_LOG_MESSAGE
+ //
+
+ pIoErrorLogMessage->Type = IO_TYPE_ERROR_MESSAGE;
+ pIoErrorLogMessage->Size = PORT_MAXIMUM_MESSAGE_LENGTH;
+ pIoErrorLogMessage->DriverNameLength = DRIVER_NAME_LENGTH * sizeof(WCHAR);
+ NtQuerySystemTime((PTIME) &pIoErrorLogMessage->TimeStamp);
+ pIoErrorLogMessage->DriverNameOffset = sizeof(IO_ERROR_LOG_MESSAGE) +
+ DataLength - sizeof(DWORD);
+
+ pIoErrorLogMessage->EntryData.MajorFunctionCode = 1;
+ pIoErrorLogMessage->EntryData.RetryCount = 5;
+ pIoErrorLogMessage->EntryData.DumpDataSize = DataLength;
+ pIoErrorLogMessage->EntryData.NumberOfStrings = 2;
+ pIoErrorLogMessage->EntryData.StringOffset = sizeof(IO_ERROR_LOG_MESSAGE)
+ - sizeof(DWORD) + DataLength +
+ DRIVER_NAME_LENGTH * sizeof(WCHAR);
+ pIoErrorLogMessage->EntryData.EventCategory = 0;
+ pIoErrorLogMessage->EntryData.ErrorCode = 0xC0020008;
+ pIoErrorLogMessage->EntryData.UniqueErrorValue = 0x20008;
+ pIoErrorLogMessage->EntryData.FinalStatus = 0x1111;
+ pIoErrorLogMessage->EntryData.SequenceNumber = 1;
+ pIoErrorLogMessage->EntryData.IoControlCode = 0xFF;
+ pIoErrorLogMessage->EntryData.DeviceOffset =
+ RtlConvertUlongToLargeInteger(1);
+
+ for (i = 0; i < DataLength ; i++ ) {
+ pIoErrorLogMessage->EntryData.DumpData[i] = i;
+ }
+
+ //
+ // Copy the strings
+ //
+
+ pDestinationString = (LPWSTR) ((LPBYTE) pIoErrorLogMessage
+ + sizeof(IO_ERROR_LOG_MESSAGE)
+ - sizeof(DWORD) + pIoErrorLogMessage->EntryData.DumpDataSize);
+ wcscpy(pDestinationString, DRIVER_NAME);
+
+ pDestinationString += DRIVER_NAME_LENGTH;
+ wcscpy(pDestinationString, DEVICE_NAME);
+
+ pDestinationString += DEVICE_NAME_LENGTH;
+ wcscpy(pDestinationString, STRING);
+
+ //
+ // Write the packet as many times as requested, with delay, then ask
+ // if they want to write more
+ //
+ while (NumberOfRecords) {
+
+ printf("\n\nWriting %d records\n", NumberOfRecords);
+
+ while(NumberOfRecords--) {
+ printf(".");
+
+ //
+ // Put in a unique message number
+ //
+
+ RequestMessage->MessageId = MessageId++;
+
+ //
+ // If they want invalid records, give them invalid records
+ //
+
+ if (WriteInvalidRecords) {
+ switch (BadType++) {
+ case 0:
+ pIoErrorLogMessage->EntryData.DumpDataSize++;
+ break;
+
+ case 1:
+ pIoErrorLogMessage->EntryData.NumberOfStrings++;
+ break;
+
+ case 2:
+ pIoErrorLogMessage->EntryData.StringOffset++;
+ break;
+
+ default:
+ BadType = 0;
+ }
+ }
+
+ Status = NtRequestWaitReplyPort(PortHandle,
+ RequestMessage,
+ & ReplyMessage);
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Request to LPC port failed with RC %X\n", Status);
+ break;
+ }
+
+ //
+ // Delay a little bit, if requested
+ //
+
+ if (MillisecondsToDelay) {
+ Sleep(MillisecondsToDelay);
+ }
+ }
+ printf("\nEnter the number of records to write ");
+
+ while (!gets(NumberString) || !(NumberOfRecords = atoi(NumberString))) {
+ printf("Enter the number of records to write ");
+ }
+ }
+
+ //
+ // Clean up and exit
+ //
+
+ Status = NtClose(PortHandle);
+ if (!NT_SUCCESS(Status)) {
+ printf("Close of Port failed with RC %X\n", Status);
+ }
+
+ free(RequestMessage);
+
+ return;
+
+}
+
+
+VOID
+TestChangeNotify(
+ VOID
+ )
+{
+
+ HANDLE Event;
+ UNICODE_STRING ModuleNameU;
+ ANSI_STRING ModuleNameA;
+ NTSTATUS Status;
+ HANDLE LogHandle;
+ OBJECT_ATTRIBUTES obja;
+ ULONG NumRecords;
+ ULONG BytesRead;
+ ULONG MinBytesNeeded;
+ PVOID Buffer;
+ ULONG OldestRecord;
+ ULONG NumberOfRecords;
+
+ RtlInitAnsiString(&ModuleNameA, pModuleName);
+ RtlAnsiStringToUnicodeString(&ModuleNameU, &ModuleNameA, TRUE);
+ ModuleNameU.MaximumLength = ModuleNameU.Length ;
+
+ Buffer = malloc (READ_BUFFER_SIZE);
+ ASSERT(Buffer);
+
+ //
+ // Open the log handle
+ //
+
+ printf("ElfOpenEventLog - ");
+ Status = ElfOpenEventLogW (
+ &ServerName,
+ &ModuleNameU,
+ &LogHandle
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Error - 0x%lx\n", Status);
+ return;
+ }
+
+ printf("SUCCESS\n");
+
+ //
+ // Create the Event
+ //
+
+ InitializeObjectAttributes( &obja, NULL, 0, NULL, NULL);
+
+ Status = NtCreateEvent(
+ &Event,
+ SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE,
+ &obja,
+ SynchronizationEvent,
+ FALSE
+ );
+
+ ASSERT(NT_SUCCESS(Status));
+
+ //
+ // Get the read pointer to the end of the log
+ //
+
+ Status = ElfOldestRecord(LogHandle, & OldestRecord);
+ ASSERT(NT_SUCCESS(Status));
+ Status = ElfNumberOfRecords(LogHandle, & NumberOfRecords);
+ ASSERT(NT_SUCCESS(Status));
+ OldestRecord += NumberOfRecords - 1;
+
+ Status = ElfReadEventLogW (
+ LogHandle,
+ EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ,
+ OldestRecord,
+ Buffer,
+ READ_BUFFER_SIZE,
+ &BytesRead,
+ &MinBytesNeeded
+ );
+
+
+ //
+ // This one should hit end of file
+ //
+
+ Status = ElfReadEventLogW (
+ LogHandle,
+ EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0,
+ Buffer,
+ READ_BUFFER_SIZE,
+ &BytesRead,
+ &MinBytesNeeded
+ );
+
+ if (Status != STATUS_END_OF_FILE) {
+ printf("Hmmm, should have hit EOF (unless there are writes going"
+ " on elsewhere- %X\n", Status);
+ }
+
+ //
+ // Call ElfChangeNotify
+ //
+
+ Status = ElfChangeNotify(LogHandle, Event);
+ ASSERT(NT_SUCCESS(Status));
+
+ //
+ // Now loop waiting for the event to get toggled
+ //
+
+ while (1) {
+
+ Status = NtWaitForSingleObject(Event, FALSE, 0);
+ printf("The change notify event just got kicked\n");
+
+ //
+ // Now read the new records
+ //
+
+ while(1) {
+
+ Status = ElfReadEventLogW (
+ LogHandle,
+ EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0,
+ Buffer,
+ READ_BUFFER_SIZE,
+ &BytesRead,
+ &MinBytesNeeded
+ );
+
+ if (Status == STATUS_END_OF_FILE) {
+ break;
+ }
+
+ NumRecords = 0xffff; // should be plenty
+ DisplayEventRecords (Buffer, BytesRead, &NumRecords);
+ }
+ }
+}
+
+VOID
+_CRTAPI1
+main (
+ IN SHORT argc,
+ IN PSZ argv[]
+ )
+{
+
+ Initialize(); // Init any data
+
+ //
+ // Parse the command line
+ //
+
+ ParseParms(argc, argv);
+
+ switch (Operation) {
+ case Clear:
+
+ TestElfClearLogFile();
+ break;
+
+ case Backup:
+
+ TestElfBackupLogFile();
+ break;
+
+ case Read:
+
+ if (ReadFlags & EVENTLOG_SEEK_READ) {
+ TestReadEventLog(1, ReadFlags, NumberofRecords) ;
+ }
+ else {
+ TestReadEventLog(NumberofRecords, ReadFlags, 0) ;
+ }
+ break;
+
+ case Write:
+
+ TestReportEvent (NumberofRecords);
+ break;
+
+ case LPC:
+ TestLPCWrite(NumberofRecords, DelayInMilliseconds);
+ break;
+
+ case Notify:
+ TestChangeNotify();
+ break;
+
+ default:
+ printf("Invalid switch from ParseParms %d\n", Operation);
+ }
+}
+
+
+VOID
+ParseParms(
+ ULONG argc,
+ PCHAR *argv
+ )
+{
+
+ ULONG i;
+ PCHAR pch;
+
+ for (i = 1; i < argc; i++) { /* for each argument */
+ if (*(pch = argv[i]) == '-') {
+ while (*++pch) {
+ switch (*pch) {
+ case 'b':
+
+ SET_OPERATION(Backup)
+
+ //
+ // Get the file name for backup
+ //
+
+ if (i+1 < argc) {
+ pBackupFileName = argv[++i];
+ }
+ else {
+ Usage();
+ }
+ break;
+
+ case 'c':
+
+ SET_OPERATION(Clear)
+
+ break;
+
+ case 'f':
+ if (i+1 < argc) {
+ pModuleName = argv[++i];
+ ReadingBackupFile = TRUE;
+ }
+ else {
+ Usage();
+ }
+ break;
+
+ case '?':
+ case 'h':
+ case 'H':
+ Usage();
+ break;
+
+ case 'i':
+ InvalidUser = TRUE;
+ break;
+
+ case 'l':
+
+ SET_OPERATION(LPC);
+
+ //
+ // See if they want invalid records
+ //
+
+ if (*++pch == 'i') {
+ WriteInvalidRecords = TRUE;
+ }
+
+ //
+ // See if they specified a number of records
+ //
+
+ if (i + 1 < argc && argv[i+1][0] != '-') {
+ NumberofRecords = atoi(argv[++i]);
+ if (NumberofRecords == 0) {
+ Usage();
+ }
+ }
+
+ break;
+
+ case 'm':
+ if (i+1 < argc) {
+ pModuleName = argv[++i];
+ ReadingModule = TRUE;
+ }
+ else {
+ Usage();
+ }
+ break;
+
+ case 'n':
+ SET_OPERATION(Notify)
+ break;
+
+ case 'r':
+
+ SET_OPERATION(Read)
+
+ //
+ // Different Read options
+ //
+
+ if (*++pch == 's') {
+ ReadFlags |= EVENTLOG_SEQUENTIAL_READ;
+ }
+ else if (*pch == 'r') {
+ ReadFlags |= EVENTLOG_SEEK_READ;
+ }
+ else {
+ Usage();
+ }
+
+ if (*++pch == 'f') {
+ ReadFlags |= EVENTLOG_FORWARDS_READ;
+ }
+ else if (*pch == 'b') {
+ ReadFlags |= EVENTLOG_BACKWARDS_READ;
+ }
+ else {
+ Usage();
+ }
+
+ //
+ // See if they specified a number of records
+ //
+
+ if (i + 1 < argc && argv[i+1][0] != '-') {
+ NumberofRecords = atoi(argv[++i]);
+ if (NumberofRecords == 0) {
+ Usage();
+ }
+ }
+
+ break;
+
+ case 's':
+ if (i+1 >= argc) {
+ printf("Must supply a server name with -s\n");
+ Usage();
+ }
+ RtlInitAnsiString(&AnsiString, argv[++i]);
+ RtlAnsiStringToUnicodeString(&ServerName, &AnsiString,
+ TRUE);
+ break;
+
+ case 't':
+ DelayInMilliseconds = atoi(argv[++i]);
+ break;
+
+ case 'v':
+ Verbose = TRUE;
+ break;
+
+ case 'w':
+
+ SET_OPERATION(Write)
+
+ //
+ // See if they specified a number of records
+ //
+
+ if (i + 1 < argc && argv[i+1][0] != '-') {
+ NumberofRecords = atoi(argv[++i]);
+ if (NumberofRecords == 0) {
+ Usage();
+ }
+ }
+
+ break;
+
+ default: /* Invalid options */
+ printf("Invalid option %c\n\n", *pch);
+ Usage();
+ break;
+ }
+ }
+ }
+
+ //
+ // There aren't any non switch parms
+ //
+
+ else {
+ Usage();
+ }
+ }
+
+ //
+ // Verify parms are correct
+ //
+
+
+ if ( Operation == Invalid) {
+ printf( "Must specify an operation\n");
+ Usage( );
+ }
+
+ if (ReadingBackupFile && ReadingModule) {
+ printf("-m and -f are mutually exclusive\n");
+ Usage();
+ }
+
+ if (ReadingBackupFile && Operation == Write) {
+ printf("You cannot write to a backup log file\n");
+ Usage();
+ }
+ if (DelayInMilliseconds && Operation != LPC) {
+ printf("\n\n-t switch is only used with -l\n\n");
+ }
+}
+
diff --git a/private/eventlog/test/testwin.c b/private/eventlog/test/testwin.c
new file mode 100644
index 000000000..bea524159
--- /dev/null
+++ b/private/eventlog/test/testwin.c
@@ -0,0 +1,770 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ TESTWIN.C
+
+Abstract:
+
+ Test program for the eventlog service. This program calls the Win
+ APIs to test out the operation of the service.
+
+Author:
+
+ Rajen Shah (rajens) 05-Aug-1991
+
+Revision History:
+
+
+--*/
+/*----------------------*/
+/* INCLUDES */
+/*----------------------*/
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#include <stdio.h> // printf
+#include <string.h> // stricmp
+#include <stdlib.h>
+#include <windows.h>
+#include <netevent.h>
+
+//
+// Turn on NotifyChangeEventLog
+//
+#define TEST_NOTIFY 1
+//#define TEST_REMOTE 1
+
+#define READ_BUFFER_SIZE 1024*2 // Use 2K buffer
+
+#define SIZE_DATA_ARRAY 65
+
+//
+// Global buffer used to emulate "binary data" when writing an event
+// record.
+//
+ DWORD Data[SIZE_DATA_ARRAY];
+// LPWSTR ServerName=L"\\\\danl2";
+ LPWSTR ServerName=NULL;
+
+
+VOID
+Initialize (
+ VOID
+ )
+{
+ DWORD i;
+
+ // Initialize the values in the data buffer.
+ //
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] = i;
+
+}
+
+
+BOOL
+Usage (
+ VOID
+ )
+{
+ printf( "usage: \n" );
+ printf( "-b <filename> Tests BackupEventLog API\n");
+ printf( "-c Tests ClearEventLog API\n");
+ printf( "-n Tests NotifyChangeEventlog\n");
+ printf( "-rsb Reads event log sequentially backwards\n");
+ printf( "-rsf Reads event log sequentially forwards\n");
+ printf( "-rrb <record> Reads event log from <record> backwards\n");
+ printf( "-rrf <record> Reads event log from <record> forwards\n");
+ printf( "-w <count> Tests ReportEvent API <count> times\n");
+ return ERROR_INVALID_PARAMETER;
+
+} // Usage
+
+
+
+BOOL
+WriteLogEntry ( HANDLE LogHandle, DWORD EventID )
+
+{
+#define NUM_STRINGS 2
+
+ BOOL Status;
+ WORD EventType, i;
+ DWORD DataSize;
+ PSID pUserSid;
+
+ PWSTR Strings[NUM_STRINGS] = {L"StringAOne",
+ L"StringATwo"
+ };
+
+ EventType = EVENTLOG_INFORMATION_TYPE;
+ pUserSid = NULL;
+ DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
+
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] += i;
+
+ Status = ReportEventW (
+ LogHandle,
+ EventType,
+ 0, // event category
+ EventID,
+ pUserSid,
+ NUM_STRINGS,
+ DataSize,
+ Strings,
+ (PVOID)Data
+ );
+
+ return (Status);
+}
+
+DWORD
+WriteLogEntryMsg ( HANDLE LogHandle, DWORD EventID )
+/*
+ This function requires a registry entry in the Applications section
+ of the Eventlog for TESTWINAPP, it will use the netevent.dll message file.
+*/
+
+{
+#define NUM_STRINGS 2
+
+ WORD EventType;
+ DWORD DataSize;
+ PSID pUserSid;
+
+ PWSTR Strings[NUM_STRINGS];
+
+ Strings[0] = L"This is a BOGUS message for TEST purposes Ignore this substitution text";
+ Strings[1] = L"GHOST SERVICE in the long string format - I wanted a long string to pass into this function";
+
+ EventType = EVENTLOG_INFORMATION_TYPE;
+ pUserSid = NULL;
+ DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
+
+
+ if (!ReportEventW (
+ LogHandle,
+ EventType,
+ 0, // event category
+ EVENT_SERVICE_START_FAILED_NONE,
+ pUserSid,
+ NUM_STRINGS,
+ 0, // DataSize
+ Strings,
+ (PVOID)NULL // Data
+ )) {
+
+ printf("ReportEventW failed %d\n",GetLastError());
+ return(GetLastError());
+ }
+ return (NO_ERROR);
+}
+
+
+VOID
+DisplayEventRecords( PVOID Buffer,
+ DWORD BufSize,
+ ULONG *NumRecords)
+
+{
+ PEVENTLOGRECORD pLogRecord;
+ ANSI_STRING StringA;
+ UNICODE_STRING StringU;
+ PWSTR pwString;
+ DWORD Count = 0;
+ DWORD Offset = 0;
+ DWORD i;
+
+ pLogRecord = (PEVENTLOGRECORD) Buffer;
+
+ while ((DWORD)Offset < BufSize) {
+
+ printf("\nRecord # %lu\n", ++Count);
+
+ printf("Length: 0x%lx TimeGenerated: 0x%lx EventID: 0x%lx EventType: 0x%x\n",
+ pLogRecord->Length, pLogRecord->TimeGenerated, pLogRecord->EventID,
+ pLogRecord->EventType);
+
+ printf("NumStrings: 0x%x StringOffset: 0x%lx UserSidLength: 0x%lx TimeWritten: 0x%lx\n",
+ pLogRecord->NumStrings, pLogRecord->StringOffset,
+ pLogRecord->UserSidLength, pLogRecord->TimeWritten);
+
+ printf("UserSidOffset: 0x%lx DataLength: 0x%lx DataOffset: 0x%lx \n",
+ pLogRecord->UserSidOffset, pLogRecord->DataLength,
+ pLogRecord->DataOffset);
+
+ //
+ // Print out module name
+ //
+ pwString = (PWSTR)((DWORD)pLogRecord + sizeof(EVENTLOGRECORD));
+ RtlInitUnicodeString (&StringU, pwString);
+ RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
+
+ printf("ModuleName: %s ", StringA.Buffer);
+ RtlFreeAnsiString (&StringA);
+
+ //
+ // Display ComputerName
+ //
+ pwString = pwString + (wcslen(pwString) + 1);
+
+ RtlInitUnicodeString (&StringU, pwString);
+ RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
+
+ printf("ComputerName: %s\n",StringA.Buffer);
+ RtlFreeAnsiString (&StringA);
+
+ //
+ // Display strings
+ //
+ pwString = (PWSTR)((DWORD)Buffer + pLogRecord->StringOffset);
+
+ printf("\nStrings: \n");
+ for (i=0; i<pLogRecord->NumStrings; i++) {
+
+ RtlInitUnicodeString (&StringU, pwString);
+ RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
+
+ printf(" %s \n",StringA.Buffer);
+
+ RtlFreeAnsiString (&StringA);
+
+ pwString = (PWSTR)((DWORD)pwString + StringU.MaximumLength);
+ }
+
+ // Get next record
+ //
+ Offset += pLogRecord->Length;
+
+ pLogRecord = (PEVENTLOGRECORD)((DWORD)Buffer + Offset);
+
+ }
+ *NumRecords = Count;
+
+}
+
+
+BOOL
+ReadFromLog ( HANDLE LogHandle,
+ PVOID Buffer,
+ ULONG *pBytesRead,
+ DWORD ReadFlag,
+ DWORD Record
+ )
+{
+ BOOL Status;
+ DWORD MinBytesNeeded;
+ DWORD ErrorCode;
+
+ Status = ReadEventLogW (
+ LogHandle,
+ ReadFlag,
+ Record,
+ Buffer,
+ READ_BUFFER_SIZE,
+ pBytesRead,
+ &MinBytesNeeded
+ );
+
+
+ if (!Status) {
+ ErrorCode = GetLastError();
+ if (ErrorCode == ERROR_HANDLE_EOF) {
+ Status = TRUE;
+ }
+ else if (ErrorCode == ERROR_NO_MORE_FILES) {
+ printf("Buffer too small. Need %lu bytes min\n", MinBytesNeeded);
+ }
+ else {
+ printf("Error from ReadEventLog %d \n", ErrorCode);
+ }
+
+ }
+
+ return (Status);
+}
+
+
+
+
+BOOL
+TestReadEventLog (DWORD Count, DWORD ReadFlag, DWORD Record)
+
+{
+ BOOL bStatus,IStatus;
+ DWORD status;
+ HANDLE LogHandle;
+ LPWSTR ModuleName;
+ DWORD NumRecords, BytesReturned;
+ PVOID Buffer;
+ DWORD RecordOffset;
+ DWORD NumberOfRecords;
+ DWORD OldestRecord;
+
+ printf("Testing ReadEventLog API to read %lu entries\n",Count);
+
+ Buffer = malloc (READ_BUFFER_SIZE);
+
+ //
+ // Initialize the strings
+ //
+ NumRecords = Count;
+ ModuleName = L"TESTWINAPP";
+
+ //
+ // Open the log handle
+ //
+ printf("OpenEventLog - ");
+ LogHandle = OpenEventLogW (
+ ServerName,
+ ModuleName
+ );
+
+ if (LogHandle == NULL) {
+ printf("Error - %d\n", GetLastError());
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Get and print record information
+ //
+
+ bStatus = GetNumberOfEventLogRecords(LogHandle, & NumberOfRecords);
+ if (bStatus) {
+ bStatus = GetOldestEventLogRecord(LogHandle, & OldestRecord);
+ }
+
+ if (!bStatus) {
+ printf("Query of record information failed with %X", GetLastError());
+ return(bStatus);
+ }
+
+ printf("\nThere are %d records in the file, %d is the oldest"
+ " record number\n", NumberOfRecords, OldestRecord);
+
+ RecordOffset = Record;
+
+ printf("Reading %u records\r", Count);
+
+ while (Count) {
+
+ //
+ // Read from the log
+ //
+ bStatus = ReadFromLog ( LogHandle,
+ Buffer,
+ &BytesReturned,
+ ReadFlag,
+ RecordOffset
+ );
+ if (bStatus) {
+ printf("Bytes read = 0x%lx\n", BytesReturned);
+ printf("Read %u records\n", NumRecords);
+ DisplayEventRecords(Buffer, BytesReturned, &NumRecords);
+ Count -= NumRecords;
+ RecordOffset += NumRecords;
+ } else {
+ break;
+ }
+
+ if (BytesReturned == 0)
+ break;
+ }
+ printf("\n");
+
+ if (!bStatus) {
+ printf ("ReadFromLog Error - %d. Remaining count %lu\n", GetLastError(),
+ Count);
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling CloseEventLog\n");
+ IStatus = CloseEventLog (LogHandle);
+ }
+
+ return (bStatus);
+}
+
+
+
+BOOL
+TestWriteEventLog (DWORD Count)
+
+{
+ DWORD Status=NO_ERROR;
+ BOOL IStatus;
+ HANDLE LogHandle;
+ LPWSTR ModuleName;
+ DWORD EventID = 99;
+ DWORD WriteCount;
+ DWORD DataNum=0;
+
+ printf("Testing ReportEvent API\n");
+
+ //
+ // Initialize the strings
+ //
+ ModuleName = L"TESTWINAPP";
+
+ printf("Calling RegisterEventSource for WRITE %lu times\n", Count);
+ while ((Count > 0) && (Status== NO_ERROR)) {
+ //
+ // Open the log handle
+ //
+ LogHandle = RegisterEventSourceW (
+ ServerName,
+ ModuleName
+ );
+
+ if (LogHandle == NULL) {
+ Status = GetLastError();
+ printf("RegisterEventSource Failure - %d\n", Status);
+ return(Status);
+
+ } else {
+ printf("Registered - ");
+ WriteCount = 5;
+ printf("Record # %u: ", Count);
+
+ while ((WriteCount>0) && (Status==NO_ERROR)) {
+
+ //
+ // Write an entry into the log
+ //
+ Data[0] = DataNum; // Make data "unique"
+ EventID = (EventID + DataNum) % 100; // Vary the eventids
+ Status = WriteLogEntryMsg( LogHandle, EventID );
+ DataNum++;
+ WriteCount--;
+
+ if (Status != NO_ERROR) {
+ printf ("WriteLogEntry Error - %d. Remaining count %lu\n",Status,Count);
+ } else {
+ printf ("%d,",WriteCount);
+ }
+ }
+
+ IStatus = DeregisterEventSource (LogHandle);
+ printf(" - Deregistered\n");
+ }
+ Count--;
+ }
+
+ printf("\n");
+ return (Status);
+}
+
+
+
+BOOL
+TestClearLogFile ()
+
+{
+ BOOL Status, IStatus;
+ HANDLE LogHandle;
+ LPWSTR ModuleName, BackupName;
+
+ printf("Testing ClearLogFile API\n");
+ //
+ // Initialize the strings
+ //
+ ModuleName = L"TESTWINAPP";
+
+ //
+ // Open the log handle
+ //
+ printf("Calling OpenEventLog for CLEAR - ");
+ LogHandle = OpenEventLogW (
+ NULL,
+ ModuleName
+ );
+
+ if (LogHandle == NULL) {
+ printf("OpenEventLog Error - %d\n", GetLastError());
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Clear the log file and back it up to "view.log"
+ //
+
+ printf("Calling ClearEventLog backing up to view.log ");
+ BackupName = L"\\\\danhi386\\roote\\view.log";
+
+ Status = ClearEventLogW (
+ LogHandle,
+ BackupName
+ );
+
+ if (!Status) {
+ printf ("ClearEventLog Error - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ //
+ // Now just clear the file without backing it up
+ //
+ printf("Calling ClearEventLog with no backup ");
+ Status = ClearEventLogW (
+ LogHandle,
+ NULL
+ );
+
+ if (!Status) {
+ printf ("ClearEventLogError - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling CloseEventLog\n");
+ IStatus = CloseEventLog (LogHandle);
+ }
+
+ return(Status);
+}
+
+BOOL
+TestBackupLogFile (LPSTR BackupFileName)
+
+{
+ BOOL Status, IStatus;
+ HANDLE LogHandle;
+ LPWSTR ModuleName;
+ ANSI_STRING AnsiString;
+ UNICODE_STRING UnicodeString;
+
+ printf("Testing BackupLogFile API\n");
+ //
+ // Initialize the strings
+ //
+ ModuleName = L"TESTWINAPP";
+
+ //
+ // Open the log handle
+ //
+ printf("Calling OpenEventLog for BACKUP - ");
+ LogHandle = OpenEventLogW (
+ NULL,
+ ModuleName
+ );
+
+ if (LogHandle == NULL) {
+ printf("OpenEventLog Failure %d\n", GetLastError());
+
+ } else {
+ printf("OpenEventLog SUCCESS\n");
+
+ //
+ // Backup the log file to BackupFileName
+ //
+
+ printf("Calling BackupEventLog backing up to %s ", BackupFileName);
+
+ RtlInitAnsiString(&AnsiString, BackupFileName);
+ RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
+
+ Status = BackupEventLogW (LogHandle, UnicodeString.Buffer);
+
+ if (!Status) {
+ printf ("BackupEventLog failure - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling CloseEventLog\n");
+ IStatus = CloseEventLog (LogHandle);
+ }
+
+ return(Status);
+}
+
+VOID
+NotifyThread(
+ HANDLE hEventLog)
+{
+ Sleep(30000);
+ printf("NotifyThread: Writing an event...\n");
+ if (!WriteLogEntryMsg(hEventLog,1)) {
+ printf("NotifyThread: WriteLogEntryMsg failed\n");
+ }
+ else {
+ printf("Event was written\n");
+ }
+ ExitThread(NO_ERROR);
+}
+
+VOID
+TestChangeNotify(
+ )
+
+/*++
+
+Routine Description:
+
+
+Arguments:
+
+
+Return Value:
+
+
+--*/
+{
+ HANDLE hEvent;
+ HANDLE hThread;
+ HANDLE hEventLog;
+ DWORD threadId;
+ DWORD status;
+
+ hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
+ if (hEvent == NULL) {
+ printf("CreateEvent Failed %d\n",GetLastError());
+ return;
+ }
+#ifdef TEST_REMOTE
+ hEventLog = RegisterEventSourceW(L"\\\\DANL2",L"TESTWINAPP");
+#else
+ hEventLog = RegisterEventSourceW(NULL,L"TESTWINAPP");
+#endif
+ if (hEventLog == NULL) {
+ printf("OpenEventLog failed %d\n",GetLastError());
+ }
+
+#ifdef TEST_NOTIFY
+
+ if (!NotifyChangeEventLog(hEventLog,hEvent)) {
+ printf("NotifyChangeEventLog failed %d\n",GetLastError());
+ }
+#endif // TEST_NOTIFY
+
+ hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)NotifyThread,hEventLog,0,&threadId);
+ if (hThread == NULL) {
+ printf("CreateThread Failed %d\n",GetLastError());
+ CloseHandle(hEvent);
+ return;
+ }
+
+ CloseHandle(hThread);
+
+ printf("Wait for event to become signaled\n");
+ status = WaitForSingleObject(hEvent,INFINITE);
+ if (status == WAIT_OBJECT_0) {
+ printf("The Event was signaled\n");
+ }
+ else {
+ printf("The Event was NOT signaled\n");
+ }
+ return;
+}
+/****************************************************************************/
+DWORD _CRTAPI1
+main (
+ IN SHORT argc,
+ IN PSZ argv[],
+ IN PSZ envp[]
+ )
+/*++
+*
+* Routine Description:
+*
+*
+*
+* Arguments:
+*
+*
+*
+*
+* Return Value:
+*
+*
+*
+--*/
+/****************************************************************************/
+{
+
+ DWORD ReadFlags;
+
+ Initialize(); // Init any data
+
+ if ( argc < 2 ) {
+ printf( "Not enough parameters\n" );
+ return Usage( );
+ }
+
+ if ( stricmp( argv[1], "-c" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ return TestClearLogFile();
+ }
+ }
+ else if ( stricmp( argv[1], "-b" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ printf("You must supply a filename to backup to\n");
+ return(FALSE);
+ }
+
+ return TestBackupLogFile(argv[2]);
+
+ } else if (stricmp ( argv[1], "-rsf" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags,0 );
+ } else {
+ return Usage();
+ }
+ } else if (stricmp ( argv[1], "-rsb" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags,0 );
+ } else {
+ return Usage();
+ }
+ } else if (stricmp ( argv[1], "-n" ) == 0 ) {
+ TestChangeNotify();
+
+ } else if (stricmp ( argv[1], "-rrf" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags ,1);
+ } else if (argc == 3) {
+ return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
+ }
+ } else if (stricmp ( argv[1], "-rrb" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags, 1);
+ } else if (argc == 3) {
+ return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
+ }
+ } else if (stricmp ( argv[1], "-w" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ return TestWriteEventLog(1);
+ } else if (argc == 3) {
+ return (TestWriteEventLog (atoi(argv[2])));
+ }
+
+ } else {
+
+ return Usage();
+ }
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+ UNREFERENCED_PARAMETER(envp);
+
+
+}
diff --git a/private/eventlog/test/testwina.c b/private/eventlog/test/testwina.c
new file mode 100644
index 000000000..efd558f57
--- /dev/null
+++ b/private/eventlog/test/testwina.c
@@ -0,0 +1,693 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ TESTWINA.C
+
+Abstract:
+
+ Test program for the eventlog service. This program calls the Win
+ APIs to test out the operation of the service.
+
+Author:
+
+ Rajen Shah (rajens) 05-Aug-1991
+
+Revision History:
+
+
+--*/
+/*----------------------*/
+/* INCLUDES */
+/*----------------------*/
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#include <stdio.h> // printf
+#include <string.h> // stricmp
+#include <stdlib.h>
+#include <windows.h>
+#include <netevent.h>
+//#include <elfcommn.h>
+
+
+#define READ_BUFFER_SIZE 1024*2 // Use 2K buffer
+
+#define SIZE_DATA_ARRAY 65
+
+//
+// Global buffer used to emulate "binary data" when writing an event
+// record.
+//
+DWORD Data[SIZE_DATA_ARRAY];
+BOOL bHackTestBackup = FALSE;
+PCHAR pServerName = NULL;
+
+
+VOID
+Initialize (
+ VOID
+ )
+{
+ DWORD i;
+
+ // Initialize the values in the data buffer.
+ //
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] = i;
+
+}
+
+
+BOOL
+Usage (
+ VOID
+ )
+{
+ printf( "usage: \n" );
+ printf( "-c Tests ClearEventLog API\n");
+ printf( "-b filename Tests BackupEventLog API\n");
+ printf( "-rsb Reads event log sequentially backwards\n");
+ printf( "-rsf Reads event log sequentially forwards\n");
+ printf( "-rrb <record> Reads event log from <record> backwards\n");
+ printf( "-rrf <record> Reads event log from <record> forwards\n");
+ printf( "-w <count> Tests ReportEvent API <count> times\n");
+ return ERROR_INVALID_PARAMETER;
+
+} // Usage
+
+
+
+BOOL
+WriteLogEntry ( HANDLE LogHandle, DWORD EventID )
+
+{
+#define NUM_STRINGS 2
+#define MAX_STRING_SIZE 32767 // Max size is FFFF/2 for ANSI strings
+
+ BOOL Status;
+ WORD EventType;
+ DWORD i;
+ DWORD DataSize;
+ PSID pUserSid;
+ PCHAR BigString;
+
+ // PSTR Strings[NUM_STRINGS] = {"StringAOne","StringATwo" };
+ PSTR Strings[NUM_STRINGS];
+
+ Strings[0] = "StringAOne";
+
+ BigString = malloc(MAX_STRING_SIZE);
+
+ for (i = 0; i < MAX_STRING_SIZE; i++) {
+ BigString[i] = 'A';
+ }
+
+ BigString[MAX_STRING_SIZE-1] = '\0';
+ Strings[1] = BigString;
+
+ EventType = EVENTLOG_INFORMATION_TYPE;
+ pUserSid = NULL;
+ DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
+
+ for (i=0; i< SIZE_DATA_ARRAY; i++)
+ Data[i] += i;
+
+ Status = ReportEventA (
+ LogHandle,
+ EventType,
+ 0, // event category
+ EventID,
+ pUserSid,
+ (WORD) NUM_STRINGS,
+ DataSize,
+ Strings,
+ (PVOID)Data
+ );
+
+ free(BigString);
+ return (Status);
+}
+
+BOOL
+WriteLogEntryMsg ( HANDLE LogHandle, DWORD EventID )
+/*
+ This function requires a registry entry in the Applications section
+ of the Eventlog for TESTWINAAPP, it will use the netevent.dll message file.
+*/
+{
+#define NUM_STRINGS 2
+
+ BOOL Status;
+ WORD EventType;
+ DWORD DataSize;
+ PSID pUserSid;
+ PCHAR BigString;
+
+ PSTR Strings[NUM_STRINGS];
+
+ Strings[0] = "This is a BOGUS message for TEST purposes Ignore this substitution text";
+ Strings[1] = "GHOST SERVICE in the long string format - I wanted a long string to pass into this function";
+
+ EventType = EVENTLOG_INFORMATION_TYPE;
+ pUserSid = NULL;
+ DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
+
+ Status = ReportEventA (
+ LogHandle,
+ EventType,
+ 0, // event category
+ EVENT_SERVICE_START_FAILED_NONE,
+ pUserSid,
+ (WORD) NUM_STRINGS,
+ 0, // DataSize
+ Strings,
+ (PVOID)NULL // Data
+ );
+
+ free(BigString);
+ return (Status);
+}
+
+
+VOID
+DisplayEventRecords( PVOID Buffer,
+ DWORD BufSize,
+ ULONG *NumRecords)
+
+{
+ PEVENTLOGRECORD pLogRecord;
+ PSTR pString;
+ DWORD Count = 0;
+ DWORD Offset = 0;
+ DWORD i;
+
+ pLogRecord = (PEVENTLOGRECORD) Buffer;
+
+ while ((DWORD)Offset < BufSize) {
+
+ Count++;
+
+ printf("\n\nRecord # %lu\n", pLogRecord->RecordNumber);
+
+ printf("Length: 0x%lx TimeGenerated: 0x%lx EventID: 0x%lx EventType: 0x%x\n",
+ pLogRecord->Length, pLogRecord->TimeGenerated, pLogRecord->EventID,
+ pLogRecord->EventType);
+
+ printf("NumStrings: 0x%x StringOffset: 0x%lx UserSidLength: 0x%lx TimeWritten: 0x%lx\n",
+ pLogRecord->NumStrings, pLogRecord->StringOffset,
+ pLogRecord->UserSidLength, pLogRecord->TimeWritten);
+
+ printf("UserSidOffset: 0x%lx DataLength: 0x%lx DataOffset: 0x%lx \n",
+ pLogRecord->UserSidOffset, pLogRecord->DataLength,
+ pLogRecord->DataOffset);
+
+ //
+ // Print out module name
+ //
+ pString = (PSTR)((DWORD)pLogRecord + sizeof(EVENTLOGRECORD));
+ printf("ModuleName: %s ", pString);
+
+ //
+ // Display ComputerName
+ //
+ pString = (PSTR)((DWORD)pString + strlen(pString) + 1);
+ printf("ComputerName: %s\n",pString);
+
+ //
+ // Display strings
+ //
+ pString = (PSTR)((DWORD)Buffer + pLogRecord->StringOffset);
+
+ printf("Strings: ");
+ for (i=0; i<pLogRecord->NumStrings; i++) {
+
+ printf(" %s ", pString);
+ pString = (PSTR)((DWORD)pString + strlen(pString) + 1);
+ }
+
+ // Get next record
+
+ Offset += pLogRecord->Length;
+
+ pLogRecord = (PEVENTLOGRECORD)((DWORD)Buffer + Offset);
+
+ }
+ *NumRecords = Count;
+
+}
+
+
+BOOL
+ReadFromLog ( HANDLE LogHandle,
+ PVOID Buffer,
+ ULONG *pBytesRead,
+ DWORD ReadFlag,
+ DWORD Record
+ )
+{
+ BOOL Status;
+ DWORD MinBytesNeeded;
+ DWORD ErrorCode;
+
+ Status = ReadEventLogA (
+ LogHandle,
+ ReadFlag,
+ Record,
+ Buffer,
+ READ_BUFFER_SIZE,
+ pBytesRead,
+ &MinBytesNeeded
+ );
+
+
+ if (!Status) {
+ ErrorCode = GetLastError();
+ printf("Error from ReadEventLog %d \n", ErrorCode);
+ if (ErrorCode == ERROR_NO_MORE_FILES)
+ printf("Buffer too small. Need %lu bytes min\n", MinBytesNeeded);
+
+ }
+
+ return (Status);
+}
+
+
+
+
+BOOL
+TestReadEventLog (DWORD Count, DWORD ReadFlag, DWORD Record)
+
+{
+ BOOL Status, IStatus;
+
+ HANDLE LogHandle;
+ LPSTR ModuleName;
+ DWORD NumRecords, BytesReturned;
+ PVOID Buffer;
+ DWORD RecordOffset;
+ DWORD NumberOfRecords;
+ DWORD OldestRecord;
+
+ printf("Testing ReadEventLog API to read %lu entries\n",Count);
+
+ Buffer = malloc (READ_BUFFER_SIZE);
+
+ //
+ // Initialize the strings
+ //
+ NumRecords = Count;
+ ModuleName = "TESTWINAAPP";
+
+ //
+ // Open the log handle
+ //
+
+ //
+ // This is just a quick and dirty way to test the api to read a backup
+ // log, until I can fix test.c to be more general purpose.
+ //
+
+ if (bHackTestBackup) {
+ printf("OpenBackupEventLog = ");
+ LogHandle = OpenBackupEventLog(
+ NULL,
+ "\\\\danhi386\\roote\\view.log"
+ );
+ }
+ else {
+ printf("OpenEventLog - ");
+ LogHandle = OpenEventLog (
+ pServerName,
+ ModuleName
+ );
+ }
+
+ if (LogHandle == NULL) {
+ printf("Error - %d\n", GetLastError());
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Get and print record information
+ //
+
+ Status = GetNumberOfEventLogRecords(LogHandle, & NumberOfRecords);
+ if (NT_SUCCESS(Status)) {
+ Status = GetOldestEventLogRecord(LogHandle, & OldestRecord);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ printf("Get of record information failed with %X", Status);
+ return(Status);
+ }
+
+ printf("\nThere are %d records in the file, %d is the oldest"
+ " record number\n", NumberOfRecords, OldestRecord);
+
+ RecordOffset = Record;
+
+ while (Count && (BytesReturned != 0)) {
+
+ printf("Read %u records\n", NumRecords);
+ //
+ // Read from the log
+ //
+ Status = ReadFromLog ( LogHandle,
+ Buffer,
+ &BytesReturned,
+ ReadFlag,
+ RecordOffset
+ );
+ if (Status) {
+ printf("Bytes read = 0x%lx\n", BytesReturned);
+ DisplayEventRecords(Buffer, BytesReturned, &NumRecords);
+ Count -= NumRecords;
+ RecordOffset += NumRecords;
+ } else {
+ break;
+ }
+
+ }
+ printf("\n");
+
+ if (!Status) {
+ printf ("Error - %d. Remaining count %lu\n", GetLastError(), Count);
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling CloseEventLog\n");
+ IStatus = CloseEventLog (LogHandle);
+ }
+ free(Buffer);
+ return (Status);
+}
+
+
+
+BOOL
+TestWriteEventLog (DWORD Count)
+
+{
+ BOOL Status, IStatus;
+ HANDLE LogHandle=NULL;
+ LPSTR ModuleName;
+ DWORD EventID = 99;
+ DWORD WriteCount;
+
+ printf("Testing ReportEvent API\n");
+
+ //
+ // Initialize the strings
+ //
+ ModuleName = "TESTWINAAPP";
+
+ //
+ // Open the log handle
+ //
+ while (Count && NT_SUCCESS(Status)) {
+ //printf("Calling RegisterEventSource for WRITE %lu times - ", Count);
+ LogHandle = RegisterEventSourceA (
+ pServerName,
+ ModuleName
+ );
+
+ if (LogHandle == NULL) {
+ printf("Error - %d\n", GetLastError());
+
+ } else {
+ printf("Registered - ");
+ WriteCount = 5;
+ printf("Record # %u ", Count);
+
+ while (WriteCount && NT_SUCCESS(Status)) {
+
+ //
+ // Write an entry into the log
+ //
+ Data[0] = Count; // Make data "unique"
+ EventID = (EventID + Count) % 100; // Vary the eventids
+ Status = WriteLogEntryMsg ( LogHandle, EventID );
+ Count--;
+ WriteCount--;
+
+ if (!Status) {
+ printf ("Error - %d. Remaining count %lu\n", GetLastError(), Count);
+ } else {
+ printf ("%d,",WriteCount);
+ }
+ }
+ IStatus = DeregisterEventSource (LogHandle);
+ printf(" - Deregistered\n");
+ }
+ }
+
+ return (Status);
+}
+
+
+
+BOOL
+TestClearLogFile ()
+
+{
+ BOOL Status, IStatus;
+ HANDLE LogHandle;
+ LPSTR ModuleName, BackupName;
+
+ printf("Testing ClearLogFile API\n");
+ //
+ // Initialize the strings
+ //
+ ModuleName = "TESTWINAAPP";
+
+ //
+ // Open the log handle
+ //
+ printf("Calling OpenEventLog for CLEAR - ");
+ LogHandle = OpenEventLogA (
+ pServerName,
+ ModuleName
+ );
+
+ if (!Status) {
+ printf("Error - %d\n", GetLastError());
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Clear the log file and back it up to "view.log"
+ //
+
+ printf("Calling ClearEventLog backing up to view.log ");
+ BackupName = "view.log";
+
+ Status = ClearEventLogA (
+ LogHandle,
+ BackupName
+ );
+
+ if (!Status) {
+ printf ("Error - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ //
+ // Now just clear the file without backing it up
+ //
+ printf("Calling ClearEventLog with no backup ");
+ Status = ClearEventLogA (
+ LogHandle,
+ NULL
+ );
+
+ if (!Status) {
+ printf ("Error - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+ printf("Calling CloseEventLog\n");
+ IStatus = CloseEventLog (LogHandle);
+ }
+
+ return(Status);
+}
+
+
+BOOL
+TestBackupLogFile(
+ LPSTR FileName
+ )
+
+{
+ HANDLE LogHandle;
+
+ printf("Testing BackupEventLog API\n");
+
+ //
+ // Open the log handle
+ //
+
+ printf("Calling ElfOpenEventLog for BACKUP - ");
+ LogHandle = OpenEventLogA (
+ NULL,
+ "Application"
+ );
+
+ if (!LogHandle) {
+ printf("Error - %d\n", GetLastError());
+
+ } else {
+ printf("SUCCESS\n");
+
+ //
+ // Backup the log file
+ //
+
+ printf("Calling BackupEventLogFile backing up to %s\n", FileName);
+
+ if (!BackupEventLogA (
+ LogHandle,
+ FileName
+ )) {
+ printf ("Error - %d\n", GetLastError());
+ } else {
+ printf ("SUCCESS\n");
+ }
+
+
+ printf("Calling CloseEventLog - ");
+ if (CloseEventLog (LogHandle)) {
+ printf("Success\n");
+ }
+ else {
+ printf("Failed with code %d\n", GetLastError());
+ }
+ }
+
+ return(TRUE);
+}
+
+
+/****************************************************************************/
+BOOL
+main (
+ IN SHORT argc,
+ IN PSZ argv[],
+ )
+/*++
+*
+* Routine Description:
+*
+*
+*
+* Arguments:
+*
+*
+*
+*
+* Return Value:
+*
+*
+*
+--*/
+/****************************************************************************/
+{
+
+ DWORD ReadFlags;
+
+ Initialize(); // Init any data
+
+ //
+ // Just till I can replace this horrid parm parsing with my own
+ //
+
+ if (getenv("REMOTE")) {
+ pServerName = "\\\\danhi20";
+ }
+
+ if ( argc < 2 ) {
+ printf( "Not enough parameters\n" );
+ return Usage( );
+ }
+
+ if ( stricmp( argv[1], "-c" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ return TestClearLogFile();
+ }
+
+ } else if (stricmp ( argv[1], "-b" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ return Usage();
+ } else {
+ return TestBackupLogFile(argv[2]);
+ }
+
+ } else if (stricmp ( argv[1], "-rsf" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags,0 );
+ } else {
+ return Usage();
+ }
+ } else if (stricmp ( argv[1], "-xsf" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ;
+ bHackTestBackup = TRUE;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags,0 );
+ } else {
+ return Usage();
+ }
+ } else if (stricmp ( argv[1], "-rsb" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags,0 );
+ } else {
+ return Usage();
+ }
+ } else if (stricmp ( argv[1], "-rrf" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags ,1);
+ } else if (argc == 3) {
+ return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
+ }
+ } else if (stricmp ( argv[1], "-rrb" ) == 0 ) {
+
+ ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ;
+ if ( argc < 3 ) {
+ return TestReadEventLog(1,ReadFlags, 1);
+ } else if (argc == 3) {
+ return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
+ }
+ } else if (stricmp ( argv[1], "-w" ) == 0 ) {
+
+ if ( argc < 3 ) {
+ return TestWriteEventLog(1);
+ } else if (argc == 3) {
+ return (TestWriteEventLog (atoi(argv[2])));
+ }
+
+ } else {
+
+ return Usage();
+ }
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
+
+}