Add an interactive test that tests some parts of the event log service.
Get rid of MyHeap.
Continue using safe string functions.
Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value (see Eventlog Key (MSDN article)).
Correctly compute the number of records (if OldestRecordNumber == 0 then the log is empty and the number of records is 0, otherwise do the original computation).
Correctly return the event number (RecordNumber) and the write timestamp (TimeWritten) of reported events.
Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented.
Rewrite the file.c functions using NT-APIs almost exclusively for file operations.
Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage.
Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp.
Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. Indeed, the problem with the old technique was that it was possible to allocate different records with the same number. Suppose that two concurrent events writes happen for the same log, and the execution goes inside this function. The callers of this function have normally retrieved the 'CurrentRecordNumber' of this log, where the access to the log was non locked and no write operation happened in between. Then we have two different records for the same log with the very same record number, that will be written later. It is only in 'LogfWriteRecord' that the 'CurrentRecordNumber' is incremented!! Therefore this function must not take any "precomputed" record number, but should attribute a new record number under lock, and then increment it atomically, so that all event records have unique record numbers.
Correctly initialize the OldestRecordNumber to zero for new (empty) logs.
Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks.
Rewrite almost all of the functions to support event log wrapping as described in Event Log File Format (MSDN article) and splitted records (NOTE: an EOF record can be splitted anywhere (on DWORD boundary) while the fixed portion of an EVENTLOGRECORD cannot be). Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+.
As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values).
The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now.