[EVENTLOG]

- Use NT functions to retrieve timestamps for events.
- Log kernel events with the current computer name.
- Don't hardcode variables types for sizeofs.
- Add type-checks for the data to be retrieved from the registry, and use default values in case the values do not exist or are invalid.
- Use ULONG_PTR to perform pointer arithmetics.
- Use string-safe functions for copy/concatenation.
- Cache EventLog source for eventlog service self-logging.
- Unlock the LogFile in LogfClearFile.
- Fix rounding in LogfAllocAndBuildNewRecord.
- Verify ELF handle validity in ElfrGetLogInformation.
- Implement IELF_HANDLE_rundown to correctly cleanup ELF handles when client apps shut down. Adapt also the parameter of ElfDeleteEventLogHandle for reusing it there.
- Update some code formatting.
CORE-11842 #resolve

I don't completely touch file.c as it contains most of my upcoming eventlog fixes...

svn path=/trunk/; revision=72213
This commit is contained in:
Hermès Bélusca-Maïto 2016-08-12 19:14:55 +00:00
parent 275590c74e
commit f7cb5ca5c0
6 changed files with 758 additions and 650 deletions

View file

@ -33,6 +33,8 @@ SERVICE_STATUS_HANDLE ServiceStatusHandle;
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
HANDLE MyHeap = NULL;
PEVENTSOURCE EventLogSource = NULL;
/* FUNCTIONS ****************************************************************/
static VOID
@ -74,7 +76,6 @@ ServiceControlHandler(DWORD dwControl,
0,
EVENT_EventlogStopped, 0, NULL, 0, NULL);
/* Stop listening to incoming RPC messages */
RpcMgmtStopServerListening(NULL);
UpdateServiceStatus(SERVICE_STOPPED);
@ -120,15 +121,13 @@ ServiceInit(VOID)
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)
PortThreadRoutine,
(LPTHREAD_START_ROUTINE)PortThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Can't create PortThread\n");
DPRINT("Cannot create PortThread\n");
return GetLastError();
}
else
@ -136,15 +135,14 @@ ServiceInit(VOID)
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)
RpcThreadRoutine,
RpcThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Can't create RpcThread\n");
DPRINT("Cannot create RpcThread\n");
return GetLastError();
}
else
@ -165,14 +163,14 @@ ReportProductInfoEvent(VOID)
DWORD dwType;
LONG lResult = ERROR_SUCCESS;
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO));
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
ZeroMemory(&versionInfo, sizeof(versionInfo));
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
/* Get version information */
if (!GetVersionExW(&versionInfo))
return;
ZeroMemory(szBuffer, 512 * sizeof(WCHAR));
ZeroMemory(szBuffer, sizeof(szBuffer));
/* Write version into the buffer */
dwLength = swprintf(szBuffer,
@ -197,7 +195,7 @@ ReportProductInfoEvent(VOID)
&hKey);
if (lResult == ERROR_SUCCESS)
{
dwValueLength = 512 - dwLength;
dwValueLength = ARRAYSIZE(szBuffer) - dwLength;
lResult = RegQueryValueEx(hKey,
L"CurrentType",
NULL,
@ -268,7 +266,8 @@ ServiceMain(DWORD argc,
}
PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
static PLOGFILE
LoadLogFile(HKEY hKey, WCHAR* LogName)
{
DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
WCHAR *Buf = NULL, *Expanded = NULL;
@ -280,58 +279,81 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
DPRINT("LoadLogFile: %S\n", LogName);
Result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &MaxValueLen, NULL, NULL);
Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &MaxValueLen, NULL, NULL);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
return NULL;
}
MaxValueLen = ROUND_DOWN(MaxValueLen, sizeof(WCHAR));
Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
if (!Buf)
{
DPRINT1("Can't allocate heap!\n");
DPRINT1("Cannot allocate heap!\n");
return NULL;
}
ValueLen = MaxValueLen;
Result = RegQueryValueEx(hKey,
L"File",
NULL,
&Type,
(LPBYTE) Buf,
&ValueLen);
if (Result != ERROR_SUCCESS)
Result = RegQueryValueExW(hKey,
L"File",
NULL,
&Type,
(LPBYTE)Buf,
&ValueLen);
/*
* If we failed, because the registry value was inexistent
* or the value type was incorrect, create a new "File" value
* that holds the default event log path.
*/
if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
{
DPRINT1("RegQueryValueEx failed: %lu\n", Result);
HeapFree(MyHeap, 0, Buf);
return NULL;
MaxValueLen = (wcslen(L"%SystemRoot%\\System32\\Config\\") +
wcslen(LogName) + wcslen(L".evt") + 1) * sizeof(WCHAR);
Expanded = HeapReAlloc(MyHeap, 0, Buf, MaxValueLen);
if (!Expanded)
{
DPRINT1("Cannot reallocate heap!\n");
HeapFree(MyHeap, 0, Buf);
return NULL;
}
Buf = Expanded;
StringCbCopyW(Buf, MaxValueLen, L"%SystemRoot%\\System32\\Config\\");
StringCbCatW(Buf, MaxValueLen, LogName);
StringCbCatW(Buf, MaxValueLen, L".evt");
ValueLen = MaxValueLen;
Result = RegSetValueExW(hKey,
L"File",
0,
REG_EXPAND_SZ,
(LPBYTE)Buf,
ValueLen);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegSetValueEx failed: %lu\n", Result);
HeapFree(MyHeap, 0, Buf);
return NULL;
}
}
if (Type != REG_EXPAND_SZ && Type != REG_SZ)
{
DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type);
HeapFree(MyHeap, 0, Buf);
return NULL;
}
ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0);
ExpandedLen = ExpandEnvironmentStringsW(Buf, NULL, 0);
Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR));
if (!Expanded)
{
DPRINT1("Can't allocate heap!\n");
DPRINT1("Cannot allocate heap!\n");
HeapFree(MyHeap, 0, Buf);
return NULL;
}
ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
ExpandEnvironmentStringsW(Buf, Expanded, ExpandedLen);
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName,
NULL, NULL))
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName, NULL, NULL))
{
DPRINT1("Can't convert path!\n");
DPRINT1("Cannot convert path!\n");
HeapFree(MyHeap, 0, Expanded);
HeapFree(MyHeap, 0, Buf);
return NULL;
@ -339,73 +361,92 @@ PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
DPRINT("%S -> %S\n", Buf, Expanded);
ValueLen = sizeof(ULONG);
Result = RegQueryValueEx(hKey,
L"MaxSize",
NULL,
&Type,
(LPBYTE)&ulMaxSize,
&ValueLen);
if (Result != ERROR_SUCCESS)
ValueLen = sizeof(ulMaxSize);
Result = RegQueryValueExW(hKey,
L"MaxSize",
NULL,
&Type,
(LPBYTE)&ulMaxSize,
&ValueLen);
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
{
ulMaxSize = 512 * 1024; /* 512 kBytes */
ValueLen = sizeof(ULONG);
Result = RegQueryValueEx(hKey,
L"Retention",
NULL,
&Type,
(LPBYTE)&ulRetention,
&ValueLen);
if (Result != ERROR_SUCCESS)
Result = RegSetValueExW(hKey,
L"MaxSize",
0,
REG_DWORD,
(LPBYTE)&ulMaxSize,
sizeof(ulMaxSize));
}
ValueLen = sizeof(ulRetention);
Result = RegQueryValueExW(hKey,
L"Retention",
NULL,
&Type,
(LPBYTE)&ulRetention,
&ValueLen);
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
{
/* On Windows 2003 it is 604800 (secs) == 7 days */
ulRetention = 0;
Result = RegSetValueExW(hKey,
L"Retention",
0,
REG_DWORD,
(LPBYTE)&ulRetention,
sizeof(ulRetention));
}
// TODO: Add, or use, default values for "AutoBackupLogFiles" (REG_DWORD)
// and "CustomSD" (REG_SZ).
Status = LogfCreate(&pLogf, LogName, &FileName, ulMaxSize, ulRetention, TRUE, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status);
}
HeapFree(MyHeap, 0, Buf);
HeapFree(MyHeap, 0, Expanded);
HeapFree(MyHeap, 0, Buf);
return pLogf;
}
BOOL LoadLogFiles(HKEY eventlogKey)
static BOOL
LoadLogFiles(HKEY eventlogKey)
{
LONG Result;
DWORD MaxLognameLen, LognameLen;
WCHAR *Buf = NULL;
INT i;
DWORD dwIndex;
PLOGFILE pLogFile;
Result = RegQueryInfoKey(eventlogKey,
NULL, NULL, NULL, NULL,
&MaxLognameLen,
NULL, NULL, NULL, NULL, NULL, NULL);
Result = RegQueryInfoKeyW(eventlogKey, NULL, NULL, NULL, NULL, &MaxLognameLen,
NULL, NULL, NULL, NULL, NULL, NULL);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
return FALSE;
}
MaxLognameLen++;
Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR));
if (!Buf)
{
DPRINT1("Error: can't allocate heap!\n");
DPRINT1("Error: cannot allocate heap!\n");
return FALSE;
}
i = 0;
LognameLen = MaxLognameLen;
while (RegEnumKeyEx(eventlogKey,
i,
Buf,
&LognameLen,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
dwIndex = 0;
while (RegEnumKeyExW(eventlogKey,
dwIndex,
Buf,
&LognameLen,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY SubKey;
@ -431,15 +472,17 @@ BOOL LoadLogFiles(HKEY eventlogKey)
}
RegCloseKey(SubKey);
LognameLen = MaxLognameLen;
i++;
dwIndex++;
}
HeapFree(MyHeap, 0, Buf);
return TRUE;
}
INT wmain()
int wmain(int argc, WCHAR* argv[])
{
WCHAR LogPath[MAX_PATH];
INT RetCode = 0;
@ -458,9 +501,9 @@ INT wmain()
goto bye_bye;
}
GetWindowsDirectory(LogPath, MAX_PATH);
GetWindowsDirectoryW(LogPath, MAX_PATH);
if (GetDriveType(LogPath) == DRIVE_CDROM)
if (GetDriveTypeW(LogPath) == DRIVE_CDROM)
{
DPRINT("LiveCD detected\n");
onLiveCD = TRUE;
@ -475,7 +518,7 @@ INT wmain()
if (Result != ERROR_SUCCESS)
{
DPRINT1("Fatal error: can't open eventlog registry key.\n");
DPRINT1("Fatal error: cannot open eventlog registry key.\n");
RetCode = 1;
goto bye_bye;
}
@ -483,9 +526,15 @@ INT wmain()
LoadLogFiles(elogKey);
}
EventLogSource = GetEventSourceByName(L"EventLog");
if (!EventLogSource)
{
DPRINT1("No EventLog source available, the EventLog service will not be able to log its own events.\n");
}
StartServiceCtrlDispatcher(ServiceTable);
bye_bye:
bye_bye:
LogfCloseAll();
if (MyHeap)
@ -494,40 +543,10 @@ INT wmain()
return RetCode;
}
VOID EventTimeToSystemTime(DWORD EventTime, SYSTEMTIME * pSystemTime)
{
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
FILETIME ftLocal;
union
{
FILETIME ft;
ULONGLONG ll;
} u1970, uUCT;
uUCT.ft.dwHighDateTime = 0;
uUCT.ft.dwLowDateTime = EventTime;
SystemTimeToFileTime(&st1970, &u1970.ft);
uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
FileTimeToSystemTime(&ftLocal, pSystemTime);
}
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime)
{
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
union
{
FILETIME ft;
ULONGLONG ll;
} Time, u1970;
SystemTimeToFileTime(pSystemTime, &Time.ft);
SystemTimeToFileTime(&st1970, &u1970.ft);
*pEventTime = (DWORD)((Time.ll - u1970.ll) / 10000000ull);
}
VOID PRINT_HEADER(PEVENTLOGHEADER header)
{
ULONG Flags = header->Flags;
DPRINT("HeaderSize = %lu\n", header->HeaderSize);
DPRINT("Signature = 0x%x\n", header->Signature);
DPRINT("MajorVersion = %lu\n", header->MajorVersion);
@ -540,10 +559,30 @@ VOID PRINT_HEADER(PEVENTLOGHEADER header)
DPRINT("Retention = 0x%x\n", header->Retention);
DPRINT("EndHeaderSize = %lu\n", header->EndHeaderSize);
DPRINT("Flags: ");
if (header->Flags & ELF_LOGFILE_HEADER_DIRTY) DPRINT("ELF_LOGFILE_HEADER_DIRTY");
if (header->Flags & ELF_LOGFILE_HEADER_WRAP) DPRINT("| ELF_LOGFILE_HEADER_WRAP ");
if (header->Flags & ELF_LOGFILE_LOGFULL_WRITTEN) DPRINT("| ELF_LOGFILE_LOGFULL_WRITTEN ");
if (header->Flags & ELF_LOGFILE_ARCHIVE_SET) DPRINT("| ELF_LOGFILE_ARCHIVE_SET ");
if (Flags & ELF_LOGFILE_HEADER_DIRTY)
{
DPRINT("ELF_LOGFILE_HEADER_DIRTY");
Flags &= ~ELF_LOGFILE_HEADER_DIRTY;
}
if (Flags) DPRINT(" | ");
if (Flags & ELF_LOGFILE_HEADER_WRAP)
{
DPRINT("ELF_LOGFILE_HEADER_WRAP");
Flags &= ~ELF_LOGFILE_HEADER_WRAP;
}
if (Flags) DPRINT(" | ");
if (Flags & ELF_LOGFILE_LOGFULL_WRITTEN)
{
DPRINT("ELF_LOGFILE_LOGFULL_WRITTEN");
Flags &= ~ELF_LOGFILE_LOGFULL_WRITTEN;
}
if (Flags) DPRINT(" | ");
if (Flags & ELF_LOGFILE_ARCHIVE_SET)
{
DPRINT("ELF_LOGFILE_ARCHIVE_SET");
Flags &= ~ELF_LOGFILE_ARCHIVE_SET;
}
if (Flags) DPRINT(" | 0x%x", Flags);
DPRINT("\n");
}
@ -551,21 +590,24 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
{
UINT i;
WCHAR *str;
SYSTEMTIME time;
LARGE_INTEGER SystemTime;
TIME_FIELDS Time;
DPRINT("Length = %lu\n", pRec->Length);
DPRINT("Reserved = 0x%x\n", pRec->Reserved);
DPRINT("RecordNumber = %lu\n", pRec->RecordNumber);
EventTimeToSystemTime(pRec->TimeGenerated, &time);
RtlSecondsSince1970ToTime(pRec->TimeGenerated, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
DPRINT("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
time.wDay, time.wMonth, time.wYear,
time.wHour, time.wMinute, time.wSecond);
Time.Day, Time.Month, Time.Year,
Time.Hour, Time.Minute, Time.Second);
EventTimeToSystemTime(pRec->TimeWritten, &time);
RtlSecondsSince1970ToTime(pRec->TimeWritten, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
DPRINT("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
time.wDay, time.wMonth, time.wYear,
time.wHour, time.wMinute, time.wSecond);
Time.Day, Time.Month, Time.Year,
Time.Hour, Time.Minute, Time.Second);
DPRINT("EventID = %lu\n", pRec->EventID);
@ -600,17 +642,17 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
DPRINT("DataLength = %lu\n", pRec->DataLength);
DPRINT("DataOffset = %lu\n", pRec->DataOffset);
DPRINT("SourceName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD)));
DPRINT("SourceName: %S\n", (WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD)));
i = (lstrlenW((WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD))) + 1) *
i = (lstrlenW((WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD))) + 1) *
sizeof(WCHAR);
DPRINT("ComputerName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD) + i));
DPRINT("ComputerName: %S\n", (WCHAR *) ((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD) + i));
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
{
DPRINT("Strings:\n");
str = (WCHAR *) (((PBYTE) pRec) + pRec->StringOffset);
str = (WCHAR *) ((ULONG_PTR)pRec + pRec->StringOffset);
for (i = 0; i < pRec->NumStrings; i++)
{
DPRINT("[%u] %S\n", i, str);
@ -618,5 +660,5 @@ VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
}
}
DPRINT("Length2 = %lu\n", *(PDWORD) (((PBYTE) pRec) + pRec->Length - 4));
DPRINT("Length2 = %lu\n", *(PDWORD) ((ULONG_PTR)pRec + pRec->Length - 4));
}

View file

@ -11,12 +11,18 @@
#include <stdarg.h>
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#define NTOS_MODE_USER
#include <ndk/rtlfuncs.h>
#include <ndk/obfuncs.h>
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
#include <eventlogrpc_s.h>
#include <strsafe.h>
@ -26,21 +32,21 @@ typedef struct _IO_ERROR_LPC
IO_ERROR_LOG_MESSAGE Message;
} IO_ERROR_LPC, *PIO_ERROR_LPC;
#define MAJORVER 1
#define MINORVER 1
/*
* Our file format will be compatible with NT's
*/
#define MAJORVER 1
#define MINORVER 1
#define LOGFILE_SIGNATURE 0x654c664c
/*
* Flags used in logfile header
*/
#define ELF_LOGFILE_HEADER_DIRTY 1
#define ELF_LOGFILE_HEADER_WRAP 2
#define ELF_LOGFILE_HEADER_DIRTY 1
#define ELF_LOGFILE_HEADER_WRAP 2
#define ELF_LOGFILE_LOGFULL_WRITTEN 4
#define ELF_LOGFILE_ARCHIVE_SET 8
#define ELF_LOGFILE_ARCHIVE_SET 8
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
typedef struct _EVENTLOGHEADER
@ -114,22 +120,38 @@ typedef struct _LOGHANDLE
WCHAR szName[1];
} LOGHANDLE, *PLOGHANDLE;
/* eventlog.c */
extern HANDLE MyHeap;
extern PEVENTSOURCE EventLogSource;
VOID PRINT_HEADER(PEVENTLOGHEADER header);
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
/* eventsource.c */
VOID InitEventSourceList(VOID);
BOOL
LoadEventSources(HKEY hKey,
PLOGFILE pLogFile);
PEVENTSOURCE
GetEventSourceByName(LPCWSTR Name);
/* file.c */
VOID LogfListInitialize(VOID);
PLOGFILE LogfListHead(VOID);
DWORD LogfListItemCount(VOID);
INT LogfListItemCount(VOID);
PLOGFILE LogfListItemByIndex(DWORD Index);
PLOGFILE LogfListItemByIndex(INT Index);
PLOGFILE LogfListItemByName(LPCWSTR Name);
PLOGFILE LogfListItemByName(WCHAR * Name);
// DWORD LogfListItemIndexByName(WCHAR * Name);
INT LogfListItemIndexByName(WCHAR * Name);
VOID LogfListAddItem(PLOGFILE Item);
VOID LogfListRemoveItem(PLOGFILE Item);
DWORD LogfReadEvent(PLOGFILE LogFile,
DWORD Flags,
@ -171,61 +193,34 @@ DWORD LogfGetOldestRecord(PLOGFILE LogFile);
DWORD LogfGetCurrentRecord(PLOGFILE LogFile);
ULONG LogfOffsetByNumber(PLOGFILE LogFile,
DWORD RecordNumber);
PBYTE
LogfAllocAndBuildNewRecord(PULONG lpRecSize,
ULONG dwRecordNumber, // FIXME!
USHORT wType,
USHORT wCategory,
ULONG dwEventId,
PCWSTR SourceName,
PCWSTR ComputerName,
ULONG dwSidLength,
PSID lpUserSid,
USHORT wNumStrings,
WCHAR* lpStrings,
ULONG dwDataSize,
PVOID lpRawData);
BOOL LogfAddOffsetInformation(PLOGFILE LogFile,
ULONG ulNumber,
ULONG ulOffset);
BOOL LogfDeleteOffsetInformation(PLOGFILE LogFile,
ULONG ulNumber);
PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
DWORD dwRecordNumber,
WORD wType,
WORD wCategory,
DWORD dwEventId,
LPCWSTR SourceName,
LPCWSTR ComputerName,
DWORD dwSidLength,
PSID lpUserSid,
WORD wNumStrings,
WCHAR * lpStrings,
DWORD dwDataSize,
LPVOID lpRawData);
static __inline void LogfFreeRecord(LPVOID Rec)
{
HeapFree(MyHeap, 0, Rec);
}
VOID
LogfReportEvent(WORD wType,
WORD wCategory,
DWORD dwEventId,
WORD wNumStrings,
WCHAR *lpStrings,
DWORD dwDataSize,
LPVOID lpRawData);
/* eventlog.c */
extern HANDLE MyHeap;
VOID PRINT_HEADER(PEVENTLOGHEADER header);
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
VOID EventTimeToSystemTime(DWORD EventTime,
SYSTEMTIME * SystemTime);
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime,
DWORD * pEventTime);
/* eventsource.c */
VOID InitEventSourceList(VOID);
BOOL
LoadEventSources(HKEY hKey,
PLOGFILE pLogFile);
PEVENTSOURCE
GetEventSourceByName(LPCWSTR Name);
LogfReportEvent(USHORT wType,
USHORT wCategory,
ULONG dwEventId,
USHORT wNumStrings,
WCHAR* lpStrings,
ULONG dwDataSize,
PVOID lpRawData);
/* logport.c */
@ -238,9 +233,4 @@ NTSTATUS ProcessPortMessage(VOID);
/* rpc.c */
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter);
static __inline void LogfFreeRecord(LPVOID Rec)
{
HeapFree(MyHeap, 0, Rec);
}
#endif /* __EVENTLOG_H__ */

View file

@ -70,7 +70,7 @@ LoadEventSources(HKEY hKey,
NULL, NULL, NULL, NULL, NULL);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryInfoKey failed: %lu\n", Result);
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
return FALSE;
}
@ -81,12 +81,11 @@ LoadEventSources(HKEY hKey,
Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
if (!Buf)
{
DPRINT1("Error: can't allocate heap!\n");
DPRINT1("Error: cannot allocate heap!\n");
return FALSE;
}
dwEventSourceNameLength = dwMaxSubKeyLength;
dwIndex = 0;
while (RegEnumKeyExW(hKey,
dwIndex,
@ -127,7 +126,7 @@ PEVENTSOURCE
GetEventSourceByName(LPCWSTR Name)
{
PLIST_ENTRY CurrentEntry;
PEVENTSOURCE Result = NULL;
PEVENTSOURCE Item, Result = NULL;
DPRINT("GetEventSourceByName(%S)\n", Name);
EnterCriticalSection(&EventSourceListCs);
@ -135,9 +134,9 @@ GetEventSourceByName(LPCWSTR Name)
CurrentEntry = EventSourceListHead.Flink;
while (CurrentEntry != &EventSourceListHead)
{
PEVENTSOURCE Item = CONTAINING_RECORD(CurrentEntry,
EVENTSOURCE,
EventSourceListEntry);
Item = CONTAINING_RECORD(CurrentEntry,
EVENTSOURCE,
EventSourceListEntry);
DPRINT("Item->szName: %S\n", Item->szName);
// if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))

View file

@ -4,24 +4,253 @@
* FILE: base/services/eventlog/file.c
* PURPOSE: Event logging service
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
Michael Martin
* Michael Martin
*/
/* INCLUDES *****************************************************************/
/* INCLUDES ******************************************************************/
#include "eventlog.h"
#include <ndk/iofuncs.h>
#include <ndk/kefuncs.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ******************************************************************/
/* LOG FILE LIST - GLOBALS ***************************************************/
static LIST_ENTRY LogFileListHead;
static CRITICAL_SECTION LogFileListCs;
/* FUNCTIONS ****************************************************************/
/* LOG FILE LIST - FUNCTIONS *************************************************/
VOID LogfCloseAll(VOID)
{
EnterCriticalSection(&LogFileListCs);
while (!IsListEmpty(&LogFileListHead))
{
LogfClose(CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry), TRUE);
}
LeaveCriticalSection(&LogFileListCs);
DeleteCriticalSection(&LogFileListCs);
}
VOID LogfListInitialize(VOID)
{
InitializeCriticalSection(&LogFileListCs);
InitializeListHead(&LogFileListHead);
}
PLOGFILE LogfListItemByName(LPCWSTR Name)
{
PLIST_ENTRY CurrentEntry;
PLOGFILE Item, Result = NULL;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = Item;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
#if 0
/* Index starting from 1 */
DWORD LogfListItemIndexByName(WCHAR * Name)
{
PLIST_ENTRY CurrentEntry;
DWORD Result = 0;
DWORD i = 1;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = i;
break;
}
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
#endif
/* Index starting from 1 */
PLOGFILE LogfListItemByIndex(DWORD Index)
{
PLIST_ENTRY CurrentEntry;
PLOGFILE Result = NULL;
DWORD i = 1;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
if (i == Index)
{
Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
break;
}
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
DWORD LogfListItemCount(VOID)
{
PLIST_ENTRY CurrentEntry;
DWORD i = 0;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return i;
}
static VOID
LogfListAddItem(PLOGFILE Item)
{
EnterCriticalSection(&LogFileListCs);
InsertTailList(&LogFileListHead, &Item->ListEntry);
LeaveCriticalSection(&LogFileListCs);
}
static VOID
LogfListRemoveItem(PLOGFILE Item)
{
EnterCriticalSection(&LogFileListCs);
RemoveEntryList(&Item->ListEntry);
LeaveCriticalSection(&LogFileListCs);
}
/* FUNCTIONS *****************************************************************/
/* Returns 0 if nothing is found */
static ULONG
LogfOffsetByNumber(PLOGFILE LogFile,
DWORD RecordNumber)
{
DWORD i;
for (i = 0; i < LogFile->OffsetInfoNext; i++)
{
if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
return LogFile->OffsetInfo[i].EventOffset;
}
return 0;
}
DWORD LogfGetOldestRecord(PLOGFILE LogFile)
{
return LogFile->Header.OldestRecordNumber;
}
DWORD LogfGetCurrentRecord(PLOGFILE LogFile)
{
return LogFile->Header.CurrentRecordNumber;
}
static BOOL
LogfAddOffsetInformation(PLOGFILE LogFile,
ULONG ulNumber,
ULONG ulOffset)
{
LPVOID NewOffsetInfo;
if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
{
NewOffsetInfo = HeapReAlloc(MyHeap,
HEAP_ZERO_MEMORY,
LogFile->OffsetInfo,
(LogFile->OffsetInfoSize + 64) *
sizeof(EVENT_OFFSET_INFO));
if (!NewOffsetInfo)
{
DPRINT1("Cannot reallocate heap.\n");
return FALSE;
}
LogFile->OffsetInfo = (PEVENT_OFFSET_INFO)NewOffsetInfo;
LogFile->OffsetInfoSize += 64;
}
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
LogFile->OffsetInfoNext++;
return TRUE;
}
static BOOL
LogfDeleteOffsetInformation(PLOGFILE LogFile,
ULONG ulNumber)
{
DWORD i;
/*
* As the offset information is listed in increasing order, and we want
* to keep the list without holes, we demand that ulNumber is the first
* element in the list.
*/
if (ulNumber != LogFile->OffsetInfo[0].EventNumber)
return FALSE;
/*
* RtlMoveMemory(&LogFile->OffsetInfo[0],
* &LogFile->OffsetInfo[1],
* sizeof(EVENT_OFFSET_INFO) * (LogFile->OffsetInfoNext - 1));
*/
for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
{
LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
}
LogFile->OffsetInfoNext--;
return TRUE;
}
static NTSTATUS
LogfInitializeNew(PLOGFILE LogFile,
@ -466,141 +695,6 @@ LogfClose(PLOGFILE LogFile,
return;
}
VOID LogfCloseAll(VOID)
{
while (!IsListEmpty(&LogFileListHead))
{
LogfClose(LogfListHead(), TRUE);
}
DeleteCriticalSection(&LogFileListCs);
}
VOID LogfListInitialize(VOID)
{
InitializeCriticalSection(&LogFileListCs);
InitializeListHead(&LogFileListHead);
}
PLOGFILE LogfListHead(VOID)
{
return CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry);
}
PLOGFILE LogfListItemByName(WCHAR * Name)
{
PLIST_ENTRY CurrentEntry;
PLOGFILE Result = NULL;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = Item;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
/* Index starting from 1 */
INT LogfListItemIndexByName(WCHAR * Name)
{
PLIST_ENTRY CurrentEntry;
INT Result = 0;
INT i = 1;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = i;
break;
}
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
/* Index starting from 1 */
PLOGFILE LogfListItemByIndex(INT Index)
{
PLIST_ENTRY CurrentEntry;
PLOGFILE Result = NULL;
INT i = 1;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
if (i == Index)
{
Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
break;
}
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
INT LogfListItemCount(VOID)
{
PLIST_ENTRY CurrentEntry;
INT i = 0;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return i;
}
VOID LogfListAddItem(PLOGFILE Item)
{
EnterCriticalSection(&LogFileListCs);
InsertTailList(&LogFileListHead, &Item->ListEntry);
LeaveCriticalSection(&LogFileListCs);
}
VOID LogfListRemoveItem(PLOGFILE Item)
{
EnterCriticalSection(&LogFileListCs);
RemoveEntryList(&Item->ListEntry);
LeaveCriticalSection(&LogFileListCs);
}
static BOOL
ReadAnsiLogEntry(HANDLE hFile,
@ -930,7 +1024,7 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
{
DWORD dwWritten;
DWORD dwRead;
SYSTEMTIME st;
LARGE_INTEGER SystemTime;
EVENTLOGEOF EofRec;
PEVENTLOGRECORD RecBuf;
LARGE_INTEGER logFileSize;
@ -940,11 +1034,11 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
if (!Buffer)
return FALSE;
GetSystemTime(&st);
SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
NtQuerySystemTime(&SystemTime);
RtlTimeToSecondsSince1970(&SystemTime, &((PEVENTLOGRECORD)Buffer)->TimeWritten);
if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
{
RtlReleaseResource(&LogFile->Lock);
@ -1111,7 +1205,6 @@ BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
return TRUE;
}
NTSTATUS
LogfClearFile(PLOGFILE LogFile,
PUNICODE_STRING BackupFileName)
@ -1123,12 +1216,11 @@ LogfClearFile(PLOGFILE LogFile,
if (BackupFileName->Length > 0)
{
/* Write a backup file */
Status = LogfBackupFile(LogFile,
BackupFileName);
Status = LogfBackupFile(LogFile, BackupFileName);
if (!NT_SUCCESS(Status))
{
DPRINT1("LogfBackupFile failed (Status: 0x%08lx)\n", Status);
return Status;
goto Quit;
}
}
@ -1140,12 +1232,11 @@ LogfClearFile(PLOGFILE LogFile,
DPRINT1("LogfInitializeNew failed (Status: 0x%08lx)\n", Status);
}
Quit:
RtlReleaseResource(&LogFile->Lock);
return Status;
}
NTSTATUS
LogfBackupFile(PLOGFILE LogFile,
PUNICODE_STRING BackupFileName)
@ -1347,134 +1438,84 @@ Done:
}
/* Returns 0 if nothing found. */
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
{
DWORD i;
for (i = 0; i < LogFile->OffsetInfoNext; i++)
{
if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
return LogFile->OffsetInfo[i].EventOffset;
}
return 0;
}
DWORD LogfGetOldestRecord(PLOGFILE LogFile)
{
return LogFile->Header.OldestRecordNumber;
}
DWORD LogfGetCurrentRecord(PLOGFILE LogFile)
{
return LogFile->Header.CurrentRecordNumber;
}
BOOL LogfDeleteOffsetInformation(PLOGFILE LogFile, ULONG ulNumber)
{
DWORD i;
if (ulNumber != LogFile->OffsetInfo[0].EventNumber)
{
return FALSE;
}
for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
{
LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
}
LogFile->OffsetInfoNext--;
return TRUE;
}
BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
{
LPVOID NewOffsetInfo;
if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
{
NewOffsetInfo = HeapReAlloc(MyHeap,
HEAP_ZERO_MEMORY,
LogFile->OffsetInfo,
(LogFile->OffsetInfoSize + 64) *
sizeof(EVENT_OFFSET_INFO));
if (!NewOffsetInfo)
{
DPRINT1("Can't reallocate heap.\n");
return FALSE;
}
LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) NewOffsetInfo;
LogFile->OffsetInfoSize += 64;
}
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
LogFile->OffsetInfoNext++;
return TRUE;
}
PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
DWORD dwRecordNumber,
WORD wType,
WORD wCategory,
DWORD dwEventId,
LPCWSTR SourceName,
LPCWSTR ComputerName,
DWORD dwSidLength,
PSID lpUserSid,
WORD wNumStrings,
WCHAR * lpStrings,
DWORD dwDataSize,
LPVOID lpRawData)
PBYTE
LogfAllocAndBuildNewRecord(PULONG lpRecSize,
ULONG dwRecordNumber, // FIXME!
USHORT wType,
USHORT wCategory,
ULONG dwEventId,
PCWSTR SourceName,
PCWSTR ComputerName,
ULONG dwSidLength,
PSID lpUserSid,
USHORT wNumStrings,
WCHAR* lpStrings,
ULONG dwDataSize,
PVOID lpRawData)
{
DWORD dwRecSize;
PEVENTLOGRECORD pRec;
SYSTEMTIME SysTime;
LARGE_INTEGER SystemTime;
WCHAR *str;
UINT i, pos;
PBYTE Buffer;
dwRecSize =
sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
lstrlenW(SourceName) + 2) * sizeof(WCHAR);
sizeof(EVENTLOGRECORD) + (lstrlenW(SourceName) +
lstrlenW(ComputerName) + 2) * sizeof(WCHAR);
if (dwRecSize % 4 != 0)
dwRecSize += 4 - (dwRecSize % 4);
/* Align on DWORD boundary for the SID */
dwRecSize = ROUND_UP(dwRecSize, sizeof(ULONG));
dwRecSize += dwSidLength;
/* Add the sizes for the strings array */
for (i = 0, str = lpStrings; i < wNumStrings; i++)
{
dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
str += lstrlenW(str) + 1;
}
/* Add the data size */
dwRecSize += dwDataSize;
if (dwRecSize % 4 != 0)
dwRecSize += 4 - (dwRecSize % 4);
dwRecSize += 4;
/* Align on DWORD boundary for the full structure */
dwRecSize = ROUND_UP(dwRecSize, sizeof(ULONG));
/* Size of the trailing 'Length' member */
dwRecSize += sizeof(ULONG);
Buffer = HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);
if (!Buffer)
{
DPRINT1("Can't allocate heap!\n");
DPRINT1("Cannot allocate heap!\n");
return NULL;
}
pRec = (PEVENTLOGRECORD) Buffer;
pRec = (PEVENTLOGRECORD)Buffer;
pRec->Length = dwRecSize;
pRec->Reserved = LOGFILE_SIGNATURE;
// FIXME: The problem with this technique is that it is 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 we need to rewrite those functions. This function must
// not take any "precomputed" record number. It should attribute a new
// record number under lock, and then increment it atomically, so that
// all event records have unique record numbers.
pRec->RecordNumber = dwRecordNumber;
GetSystemTime(&SysTime);
SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
NtQuerySystemTime(&SystemTime);
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeGenerated);
// FIXME: Already done in LogfWriteRecord. Is it needed to do that here first??
RtlTimeToSecondsSince1970(&SystemTime, &pRec->TimeWritten);
pRec->EventID = dwEventId;
pRec->EventType = wType;
@ -1487,11 +1528,10 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
/* Align on DWORD boundary for the SID */
pos = ROUND_UP(pos, sizeof(ULONG));
pRec->UserSidOffset = pos;
if (pos % 4 != 0)
pos += 4 - (pos % 4);
if (dwSidLength)
{
CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
@ -1517,53 +1557,49 @@ PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
pos += dwDataSize;
}
if (pos % 4 != 0)
pos += 4 - (pos % 4);
/* Align on DWORD boundary for the full structure */
pos = ROUND_UP(pos, sizeof(ULONG));
/* Initialize the trailing 'Length' member */
*((PDWORD) (Buffer + pos)) = dwRecSize;
*lpRecSize = dwRecSize;
return Buffer;
}
VOID
LogfReportEvent(WORD wType,
WORD wCategory,
DWORD dwEventId,
WORD wNumStrings,
WCHAR *lpStrings,
DWORD dwDataSize,
LPVOID lpRawData)
LogfReportEvent(USHORT wType,
USHORT wCategory,
ULONG dwEventId,
USHORT wNumStrings,
WCHAR* lpStrings,
ULONG dwDataSize,
PVOID lpRawData)
{
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
PEVENTSOURCE pEventSource = NULL;
PBYTE logBuffer;
DWORD lastRec;
DWORD recSize;
DWORD dwError;
if (!EventLogSource)
return;
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
{
szComputerName[0] = 0;
szComputerName[0] = L'\0';
}
pEventSource = GetEventSourceByName(L"EventLog");
if (pEventSource == NULL)
{
return;
}
lastRec = LogfGetCurrentRecord(pEventSource->LogFile);
lastRec = LogfGetCurrentRecord(EventLogSource->LogFile);
logBuffer = LogfAllocAndBuildNewRecord(&recSize,
lastRec,
lastRec, // FIXME!
wType,
wCategory,
dwEventId,
pEventSource->szName,
(LPCWSTR)szComputerName,
EventLogSource->szName,
szComputerName,
0,
NULL,
wNumStrings,
@ -1571,10 +1607,10 @@ LogfReportEvent(WORD wType,
dwDataSize,
lpRawData);
dwError = LogfWriteData(pEventSource->LogFile, recSize, logBuffer);
dwError = LogfWriteData(EventLogSource->LogFile, recSize, logBuffer);
if (!dwError)
{
DPRINT1("ERROR WRITING TO EventLog %S\n", pEventSource->LogFile->FileName);
DPRINT1("ERROR WRITING TO EventLog %S\n", EventLogSource->LogFile->FileName);
}
LogfFreeRecord(logBuffer);

View file

@ -18,8 +18,8 @@
/* GLOBALS ******************************************************************/
HANDLE ConnectPortHandle = NULL;
HANDLE MessagePortHandle = NULL;
static HANDLE ConnectPortHandle = NULL;
static HANDLE MessagePortHandle = NULL;
extern BOOL onLiveCD;
/* FUNCTIONS ****************************************************************/
@ -70,7 +70,6 @@ NTSTATUS InitLogPort(VOID)
}
Status = NtListenPort(ConnectPortHandle, &Request);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
@ -79,7 +78,6 @@ NTSTATUS InitLogPort(VOID)
Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
NULL, TRUE, NULL, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
@ -93,7 +91,7 @@ NTSTATUS InitLogPort(VOID)
goto ByeBye;
}
ByeBye:
ByeBye:
if (!NT_SUCCESS(Status))
{
if (ConnectPortHandle != NULL)
@ -114,6 +112,8 @@ NTSTATUS ProcessPortMessage(VOID)
DWORD dwRecSize;
NTSTATUS Status;
PLOGFILE SystemLog = NULL;
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
DPRINT("ProcessPortMessage() called\n");
@ -150,18 +150,27 @@ NTSTATUS ProcessPortMessage(VOID)
Message = (PIO_ERROR_LOG_MESSAGE) & Request.Message;
ulRecNum = SystemLog ? SystemLog->Header.CurrentRecordNumber : 0;
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(&dwRecSize,
ulRecNum, Message->Type, Message->EntryData.EventCategory,
Message->EntryData.ErrorCode,
(WCHAR *) (((PBYTE) Message) + Message->DriverNameOffset),
L"MyComputer", /* FIXME */
0,
NULL,
Message->EntryData.NumberOfStrings,
(WCHAR *) (((PBYTE) Message) + Message->EntryData.StringOffset),
Message->EntryData.DumpDataSize,
(LPVOID) (((PBYTE) Message) + sizeof(IO_ERROR_LOG_PACKET) -
sizeof(ULONG)));
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
{
szComputerName[0] = L'\0';
}
// TODO: Log more information??
pRec = (PEVENTLOGRECORD) LogfAllocAndBuildNewRecord(
&dwRecSize,
ulRecNum, // FIXME!
Message->Type,
Message->EntryData.EventCategory,
Message->EntryData.ErrorCode,
(WCHAR *) ((ULONG_PTR)Message + Message->DriverNameOffset), // FIXME: Use DriverNameLength too!
szComputerName,
0,
NULL,
Message->EntryData.NumberOfStrings,
(WCHAR *) ((ULONG_PTR)Message + Message->EntryData.StringOffset),
Message->EntryData.DumpDataSize,
(LPVOID) ((ULONG_PTR)Message + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData)));
if (pRec == NULL)
{

View file

@ -5,6 +5,7 @@
* PURPOSE: Event logging service
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
* Copyright 2008 Michael Martin
* Copyright 2010-2011 Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -49,27 +50,31 @@ DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
static NTSTATUS
ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
LPCWSTR Name,
BOOL Create)
ElfCreateEventLogHandle(PLOGHANDLE* LogHandle,
PUNICODE_STRING LogName,
BOOLEAN Create)
{
NTSTATUS Status = STATUS_SUCCESS;
PLOGHANDLE lpLogHandle;
PLOGFILE currentLogFile = NULL;
INT i, LogsActive;
DWORD i, LogsActive;
PEVENTSOURCE pEventSource;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
DPRINT("ElfCreateEventLogHandle(Name: %wZ)\n", LogName);
lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
+ ((wcslen(Name) + 1) * sizeof(WCHAR)));
*LogHandle = NULL;
i = (LogName->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
lpLogHandle = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
FIELD_OFFSET(LOGHANDLE, szName[i]));
if (!lpLogHandle)
{
DPRINT1("Failed to allocate Heap!\n");
return STATUS_NO_MEMORY;
}
wcscpy(lpLogHandle->szName, Name);
StringCchCopy(lpLogHandle->szName, i, LogName->Buffer);
/* Get the number of Log Files the EventLog service found */
LogsActive = LogfListItemCount();
@ -81,9 +86,9 @@ ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
}
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */
if (Create == TRUE)
if (Create)
{
pEventSource = GetEventSourceByName(Name);
pEventSource = GetEventSourceByName(LogName->Buffer);
DPRINT("EventSource: %p\n", pEventSource);
if (pEventSource)
{
@ -106,9 +111,9 @@ ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
{
currentLogFile = LogfListItemByIndex(i);
if (_wcsicmp(Name, currentLogFile->LogName) == 0)
if (_wcsicmp(LogName->Buffer, currentLogFile->LogName) == 0)
{
lpLogHandle->LogFile = LogfListItemByIndex(i);
lpLogHandle->LogFile = currentLogFile;
lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
break;
}
@ -150,15 +155,16 @@ Done:
static NTSTATUS
ElfCreateBackupLogHandle(PLOGHANDLE *LogHandle,
ElfCreateBackupLogHandle(PLOGHANDLE* LogHandle,
PUNICODE_STRING FileName)
{
NTSTATUS Status = STATUS_SUCCESS;
PLOGHANDLE lpLogHandle;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ElfCreateBackupLogHandle(FileName: %wZ)\n", FileName);
*LogHandle = NULL;
lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE));
if (lpLogHandle == NULL)
{
@ -202,7 +208,8 @@ Done:
}
PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
static PLOGHANDLE
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
{
PLIST_ENTRY CurrentEntry;
PLOGHANDLE lpLogHandle;
@ -224,26 +231,28 @@ PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
static NTSTATUS
ElfDeleteEventLogHandle(IELF_HANDLE LogHandle)
ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle)
{
PLOGHANDLE lpLogHandle;
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
lpLogHandle = ElfGetLogHandleEntryByHandle(*LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
RemoveEntryList(&lpLogHandle->LogHandleListEntry);
LogfClose(lpLogHandle->LogFile, FALSE);
HeapFree(GetProcessHeap(), 0, lpLogHandle);
*LogHandle = NULL;
return STATUS_SUCCESS;
}
/* Function 0 */
NTSTATUS ElfrClearELFW(
NTSTATUS
ElfrClearELFW(
IELF_HANDLE LogHandle,
PRPC_UNICODE_STRING BackupFileName)
{
@ -253,9 +262,7 @@ NTSTATUS ElfrClearELFW(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
/* Fail, if the log file is a backup file */
if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
@ -267,7 +274,8 @@ NTSTATUS ElfrClearELFW(
/* Function 1 */
NTSTATUS ElfrBackupELFW(
NTSTATUS
ElfrBackupELFW(
IELF_HANDLE LogHandle,
PRPC_UNICODE_STRING BackupFileName)
{
@ -277,9 +285,7 @@ NTSTATUS ElfrBackupELFW(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
return LogfBackupFile(lpLogHandle->LogFile,
(PUNICODE_STRING)BackupFileName);
@ -287,25 +293,28 @@ NTSTATUS ElfrBackupELFW(
/* Function 2 */
NTSTATUS ElfrCloseEL(
IELF_HANDLE *LogHandle)
NTSTATUS
ElfrCloseEL(
PIELF_HANDLE LogHandle)
{
return ElfDeleteEventLogHandle(*LogHandle);
return ElfDeleteEventLogHandle(LogHandle);
}
/* Function 3 */
NTSTATUS ElfrDeregisterEventSource(
IELF_HANDLE *LogHandle)
NTSTATUS
ElfrDeregisterEventSource(
PIELF_HANDLE LogHandle)
{
return ElfDeleteEventLogHandle(*LogHandle);
return ElfDeleteEventLogHandle(LogHandle);
}
/* Function 4 */
NTSTATUS ElfrNumberOfRecords(
NTSTATUS
ElfrNumberOfRecords(
IELF_HANDLE LogHandle,
DWORD *NumberOfRecords)
PULONG NumberOfRecords)
{
PLOGHANDLE lpLogHandle;
PLOGFILE lpLogFile;
@ -314,9 +323,10 @@ NTSTATUS ElfrNumberOfRecords(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
if (!NumberOfRecords)
return STATUS_INVALID_PARAMETER;
lpLogFile = lpLogHandle->LogFile;
@ -332,22 +342,19 @@ NTSTATUS ElfrNumberOfRecords(
/* Function 5 */
NTSTATUS ElfrOldestRecord(
NTSTATUS
ElfrOldestRecord(
IELF_HANDLE LogHandle,
DWORD *OldestRecordNumber)
PULONG OldestRecordNumber)
{
PLOGHANDLE lpLogHandle;
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
if (!OldestRecordNumber)
{
return STATUS_INVALID_PARAMETER;
}
*OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
@ -356,26 +363,26 @@ NTSTATUS ElfrOldestRecord(
/* Function 6 */
NTSTATUS ElfrChangeNotify(
NTSTATUS
ElfrChangeNotify(
IELF_HANDLE LogHandle,
RPC_CLIENT_ID ClientId,
DWORD Event)
ULONG Event)
{
DPRINT("ElfrChangeNotify()");
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* Function 7 */
NTSTATUS ElfrOpenELW(
NTSTATUS
ElfrOpenELW(
EVENTLOG_HANDLE_W UNCServerName,
PRPC_UNICODE_STRING ModuleName,
PRPC_UNICODE_STRING RegModuleName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
@ -384,24 +391,25 @@ NTSTATUS ElfrOpenELW(
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
/*FIXME: UNCServerName must specify the server */
/* FIXME: UNCServerName must specify the server */
/*FIXME: Must verify that caller has read access */
/* FIXME: Must verify that caller has read access */
return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
ModuleName->Buffer,
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
(PUNICODE_STRING)ModuleName,
FALSE);
}
/* Function 8 */
NTSTATUS ElfrRegisterEventSourceW(
NTSTATUS
ElfrRegisterEventSourceW(
EVENTLOG_HANDLE_W UNCServerName,
PRPC_UNICODE_STRING ModuleName,
PRPC_UNICODE_STRING RegModuleName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
DPRINT("ElfrRegisterEventSourceW()\n");
@ -412,49 +420,51 @@ NTSTATUS ElfrRegisterEventSourceW(
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
DPRINT("ModuleName: %S\n", ModuleName->Buffer);
DPRINT("ModuleName: %wZ\n", ModuleName);
/*FIXME: UNCServerName must specify the server or empty for local */
/* FIXME: UNCServerName must specify the server or empty for local */
/*FIXME: Must verify that caller has write access */
/* FIXME: Must verify that caller has write access */
return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
ModuleName->Buffer,
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
(PUNICODE_STRING)ModuleName,
TRUE);
}
/* Function 9 */
NTSTATUS ElfrOpenBELW(
NTSTATUS
ElfrOpenBELW(
EVENTLOG_HANDLE_W UNCServerName,
PRPC_UNICODE_STRING BackupFileName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
/*FIXME: UNCServerName must specify the server */
/* FIXME: UNCServerName must specify the server */
/*FIXME: Must verify that caller has read access */
/* FIXME: Must verify that caller has read access */
return ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
return ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle,
(PUNICODE_STRING)BackupFileName);
}
/* Function 10 */
NTSTATUS ElfrReadELW(
NTSTATUS
ElfrReadELW(
IELF_HANDLE LogHandle,
DWORD ReadFlags,
DWORD RecordOffset,
ULONG ReadFlags,
ULONG RecordOffset,
RULONG NumberOfBytesToRead,
BYTE *Buffer,
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
PBYTE Buffer,
PULONG NumberOfBytesRead,
PULONG MinNumberOfBytesNeeded)
{
PLOGHANDLE lpLogHandle;
DWORD dwError;
@ -462,9 +472,7 @@ NTSTATUS ElfrReadELW(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
if (!Buffer)
return STATUS_INVALID_PARAMETER;
@ -479,11 +487,16 @@ NTSTATUS ElfrReadELW(
RecordNumber = RecordOffset;
}
dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
dwError = LogfReadEvent(lpLogHandle->LogFile,
ReadFlags,
&RecordNumber,
NumberOfBytesToRead,
Buffer,
NumberOfBytesRead,
MinNumberOfBytesNeeded,
FALSE);
/* Update the handles CurrentRecord if success*/
/* Update the handle's CurrentRecord if success */
if (dwError == ERROR_SUCCESS)
{
lpLogHandle->CurrentRecord = RecordNumber;
@ -498,21 +511,22 @@ NTSTATUS ElfrReadELW(
/* Function 11 */
NTSTATUS ElfrReportEventW(
NTSTATUS
ElfrReportEventW(
IELF_HANDLE LogHandle,
DWORD Time,
ULONG Time,
USHORT EventType,
USHORT EventCategory,
DWORD EventID,
ULONG EventID,
USHORT NumStrings,
DWORD DataSize,
ULONG DataSize,
PRPC_UNICODE_STRING ComputerName,
PRPC_SID UserSID,
PRPC_UNICODE_STRING Strings[],
BYTE *Data,
PBYTE Data,
USHORT Flags,
DWORD *RecordNumber,
DWORD *TimeWritten)
PULONG RecordNumber,
PULONG TimeWritten)
{
USHORT i;
PBYTE LogBuffer;
@ -527,15 +541,11 @@ NTSTATUS ElfrReportEventW(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
/* Flags must be 0 */
if (Flags)
{
return STATUS_INVALID_PARAMETER;
}
lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
@ -571,7 +581,7 @@ NTSTATUS ElfrReportEventW(
DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
break;
}
dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
dwStringsSize += Strings[i]->Length + sizeof(UNICODE_NULL);
}
lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
@ -583,16 +593,16 @@ NTSTATUS ElfrReportEventW(
for (i = 0; i < NumStrings; i++)
{
CopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
RtlCopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
pos += Strings[i]->Length / sizeof(WCHAR);
lpStrings[pos] = UNICODE_NULL;
pos += sizeof UNICODE_NULL / sizeof(WCHAR);
pos += sizeof(UNICODE_NULL) / sizeof(WCHAR);
}
if (UserSID)
dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
lastRec,
lastRec, // FIXME!
EventType,
EventCategory,
EventID,
@ -620,7 +630,8 @@ NTSTATUS ElfrReportEventW(
/* Function 12 */
NTSTATUS ElfrClearELFA(
NTSTATUS
ElfrClearELFA(
IELF_HANDLE LogHandle,
PRPC_STRING BackupFileName)
{
@ -643,7 +654,8 @@ NTSTATUS ElfrClearELFA(
/* Function 13 */
NTSTATUS ElfrBackupELFA(
NTSTATUS
ElfrBackupELFA(
IELF_HANDLE LogHandle,
PRPC_STRING BackupFileName)
{
@ -666,13 +678,14 @@ NTSTATUS ElfrBackupELFA(
/* Function 14 */
NTSTATUS ElfrOpenELA(
NTSTATUS
ElfrOpenELA(
EVENTLOG_HANDLE_A UNCServerName,
PRPC_STRING ModuleName,
PRPC_STRING RegModuleName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
UNICODE_STRING ModuleNameW;
NTSTATUS Status;
@ -690,8 +703,8 @@ NTSTATUS ElfrOpenELA(
/* FIXME: Must verify that caller has read access */
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
ModuleNameW.Buffer,
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
&ModuleNameW,
FALSE);
RtlFreeUnicodeString(&ModuleNameW);
@ -701,13 +714,14 @@ NTSTATUS ElfrOpenELA(
/* Function 15 */
NTSTATUS ElfrRegisterEventSourceA(
NTSTATUS
ElfrRegisterEventSourceA(
EVENTLOG_HANDLE_A UNCServerName,
PRPC_STRING ModuleName,
PRPC_STRING RegModuleName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
UNICODE_STRING ModuleNameW;
NTSTATUS Status;
@ -736,8 +750,8 @@ NTSTATUS ElfrRegisterEventSourceA(
/* FIXME: Must verify that caller has write access */
Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
ModuleNameW.Buffer,
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle,
&ModuleNameW,
TRUE);
RtlFreeUnicodeString(&ModuleNameW);
@ -747,12 +761,13 @@ NTSTATUS ElfrRegisterEventSourceA(
/* Function 16 */
NTSTATUS ElfrOpenBELA(
NTSTATUS
ElfrOpenBELA(
EVENTLOG_HANDLE_A UNCServerName,
PRPC_STRING BackupFileName,
DWORD MajorVersion,
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
ULONG MajorVersion,
ULONG MinorVersion,
PIELF_HANDLE LogHandle)
{
UNICODE_STRING BackupFileNameW;
NTSTATUS Status;
@ -774,11 +789,11 @@ NTSTATUS ElfrOpenBELA(
return STATUS_INVALID_PARAMETER;
}
/*FIXME: UNCServerName must specify the server */
/* FIXME: UNCServerName must specify the server */
/*FIXME: Must verify that caller has read access */
/* FIXME: Must verify that caller has read access */
Status = ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
Status = ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle,
&BackupFileNameW);
RtlFreeUnicodeString(&BackupFileNameW);
@ -788,14 +803,15 @@ NTSTATUS ElfrOpenBELA(
/* Function 17 */
NTSTATUS ElfrReadELA(
NTSTATUS
ElfrReadELA(
IELF_HANDLE LogHandle,
DWORD ReadFlags,
DWORD RecordOffset,
ULONG ReadFlags,
ULONG RecordOffset,
RULONG NumberOfBytesToRead,
BYTE *Buffer,
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
PBYTE Buffer,
PULONG NumberOfBytesRead,
PULONG MinNumberOfBytesNeeded)
{
PLOGHANDLE lpLogHandle;
DWORD dwError;
@ -803,9 +819,7 @@ NTSTATUS ElfrReadELA(
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
if (!Buffer)
return STATUS_INVALID_PARAMETER;
@ -829,7 +843,7 @@ NTSTATUS ElfrReadELA(
MinNumberOfBytesNeeded,
TRUE);
/* Update the handles CurrentRecord if success*/
/* Update the handle's CurrentRecord if success */
if (dwError == ERROR_SUCCESS)
{
lpLogHandle->CurrentRecord = RecordNumber;
@ -844,21 +858,22 @@ NTSTATUS ElfrReadELA(
/* Function 18 */
NTSTATUS ElfrReportEventA(
NTSTATUS
ElfrReportEventA(
IELF_HANDLE LogHandle,
DWORD Time,
ULONG Time,
USHORT EventType,
USHORT EventCategory,
DWORD EventID,
ULONG EventID,
USHORT NumStrings,
DWORD DataSize,
ULONG DataSize,
PRPC_STRING ComputerName,
PRPC_SID UserSID,
PRPC_STRING Strings[],
BYTE *Data,
PBYTE Data,
USHORT Flags,
DWORD *RecordNumber,
DWORD *TimeWritten)
PULONG RecordNumber,
PULONG TimeWritten)
{
UNICODE_STRING ComputerNameW;
PUNICODE_STRING *StringsArrayW = NULL;
@ -891,7 +906,7 @@ NTSTATUS ElfrReportEventA(
{
StringsArrayW = HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
NumStrings * sizeof (PUNICODE_STRING));
NumStrings * sizeof(PUNICODE_STRING));
if (StringsArrayW == NULL)
{
Status = STATUS_NO_MEMORY;
@ -964,7 +979,8 @@ Done:
/* Function 19 */
NTSTATUS ElfrRegisterClusterSvc(
NTSTATUS
ElfrRegisterClusterSvc(
handle_t BindingHandle)
{
UNIMPLEMENTED;
@ -973,7 +989,8 @@ NTSTATUS ElfrRegisterClusterSvc(
/* Function 20 */
NTSTATUS ElfrDeregisterClusterSvc(
NTSTATUS
ElfrDeregisterClusterSvc(
handle_t BindingHandle)
{
UNIMPLEMENTED;
@ -982,7 +999,8 @@ NTSTATUS ElfrDeregisterClusterSvc(
/* Function 21 */
NTSTATUS ElfrWriteClusterEvents(
NTSTATUS
ElfrWriteClusterEvents(
handle_t BindingHandle)
{
UNIMPLEMENTED;
@ -991,16 +1009,20 @@ NTSTATUS ElfrWriteClusterEvents(
/* Function 22 */
NTSTATUS ElfrGetLogInformation(
NTSTATUS
ElfrGetLogInformation(
IELF_HANDLE LogHandle,
DWORD InfoLevel,
BYTE *Buffer,
DWORD cbBufSize,
DWORD *pcbBytesNeeded)
ULONG InfoLevel,
PBYTE Buffer,
ULONG cbBufSize,
PULONG pcbBytesNeeded)
{
NTSTATUS Status = STATUS_SUCCESS;
PLOGHANDLE lpLogHandle;
/* FIXME: check handle first */
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
return STATUS_INVALID_HANDLE;
switch (InfoLevel)
{
@ -1011,10 +1033,16 @@ NTSTATUS ElfrGetLogInformation(
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
{
return STATUS_BUFFER_TOO_SMALL;
Status = STATUS_BUFFER_TOO_SMALL;
break;
}
efi->dwFull = 0; /* FIXME */
/*
* FIXME. To check whether an event log is "full" one needs
* to compare its current size with respect to the maximum
* size threshold "MaxSize" contained in its header.
*/
efi->dwFull = 0;
}
break;
@ -1028,7 +1056,8 @@ NTSTATUS ElfrGetLogInformation(
/* Function 23 */
NTSTATUS ElfrFlushEL(
NTSTATUS
ElfrFlushEL(
IELF_HANDLE LogHandle)
{
UNIMPLEMENTED;
@ -1037,22 +1066,23 @@ NTSTATUS ElfrFlushEL(
/* Function 24 */
NTSTATUS ElfrReportEventAndSourceW(
NTSTATUS
ElfrReportEventAndSourceW(
IELF_HANDLE LogHandle,
DWORD Time,
ULONG Time,
USHORT EventType,
USHORT EventCategory,
ULONG EventID,
PRPC_UNICODE_STRING SourceName,
USHORT NumStrings,
DWORD DataSize,
ULONG DataSize,
PRPC_UNICODE_STRING ComputerName,
PRPC_SID UserSID,
PRPC_UNICODE_STRING Strings[],
BYTE *Data,
PBYTE Data,
USHORT Flags,
DWORD *RecordNumber,
DWORD *TimeWritten)
PULONG RecordNumber,
PULONG TimeWritten)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
@ -1073,4 +1103,6 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
void __RPC_USER IELF_HANDLE_rundown(IELF_HANDLE LogHandle)
{
/* Close the handle */
ElfDeleteEventLogHandle(&LogHandle); // ElfrCloseEL(&LogHandle);
}