diff options
Diffstat (limited to 'private/eventlog/test')
-rw-r--r-- | private/eventlog/test/buildreg.dat | 3 | ||||
-rw-r--r-- | private/eventlog/test/makefile | 6 | ||||
-rw-r--r-- | private/eventlog/test/sources | 89 | ||||
-rw-r--r-- | private/eventlog/test/test.c | 1400 | ||||
-rw-r--r-- | private/eventlog/test/testwin.c | 770 | ||||
-rw-r--r-- | private/eventlog/test/testwina.c | 693 |
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); + + +} |