#include "eventlog.h"
+#define NDEBUG
+#include <debug.h>
+
LIST_ENTRY LogHandleListHead;
/* FUNCTIONS ****************************************************************/
return 0;
}
-PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
+
+static NTSTATUS
+ElfCreateEventLogHandle(PLOGHANDLE *LogHandle,
+ LPCWSTR Name,
+ BOOL Create)
{
PLOGHANDLE lpLogHandle;
PLOGFILE currentLogFile = NULL;
INT i, LogsActive;
PEVENTSOURCE pEventSource;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
if (!lpLogHandle)
{
DPRINT1("Failed to allocate Heap!\n");
- return NULL;
+ return STATUS_NO_MEMORY;
}
wcscpy(lpLogHandle->szName, Name);
if (LogsActive == 0)
{
DPRINT1("EventLog service reports no log files!\n");
- goto Cleanup;
+ Status = STATUS_UNSUCCESSFUL;
+ goto Done;
}
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */
}
if (!lpLogHandle->LogFile)
- goto Cleanup;
+ Status = STATUS_UNSUCCESSFUL;
+
+Done:
+ if (NT_SUCCESS(Status))
+ {
+ /* Append log handle */
+ InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
+ *LogHandle = lpLogHandle;
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, lpLogHandle);
+ }
- /* Append log handle */
- InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
+ return Status;
+}
- return lpLogHandle;
-Cleanup:
- HeapFree(GetProcessHeap(), 0, lpLogHandle);
+static NTSTATUS
+ElfCreateBackupLogHandle(PLOGHANDLE *LogHandle,
+ PUNICODE_STRING FileName)
+{
+ PLOGHANDLE lpLogHandle;
- return NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("ElfCreateBackupLogHandle(FileName: %wZ)\n", FileName);
+
+ lpLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE));
+ if (lpLogHandle == NULL)
+ {
+ DPRINT1("Failed to allocate Heap!\n");
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Create the log file */
+ Status = LogfCreate(&lpLogHandle->LogFile,
+ NULL,
+ FileName,
+ 0,
+ 0,
+ FALSE,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create the log file! (Status 0x%08lx)\n", Status);
+ goto Done;
+ }
+
+ /* Set the backup flag */
+ lpLogHandle->Flags |= LOG_HANDLE_BACKUP_FILE;
+
+ /* Get the current record */
+ lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
+
+Done:
+ if (NT_SUCCESS(Status))
+ {
+ /* Append log handle */
+ InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
+ *LogHandle = lpLogHandle;
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, lpLogHandle);
+ }
+
+ return Status;
}
+
PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
{
+ PLIST_ENTRY CurrentEntry;
PLOGHANDLE lpLogHandle;
- if (IsListEmpty(&LogHandleListHead))
+ CurrentEntry = LogHandleListHead.Flink;
+ while (CurrentEntry != &LogHandleListHead)
{
- return NULL;
- }
+ lpLogHandle = CONTAINING_RECORD(CurrentEntry,
+ LOGHANDLE,
+ LogHandleListEntry);
+ CurrentEntry = CurrentEntry->Flink;
- lpLogHandle = CONTAINING_RECORD((PLOGHANDLE)EventLogHandle, LOGHANDLE, LogHandleListEntry);
+ if (lpLogHandle == EventLogHandle)
+ return lpLogHandle;
+ }
- return lpLogHandle;
+ return NULL;
}
-BOOL ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle)
+
+static NTSTATUS
+ElfDeleteEventLogHandle(IELF_HANDLE LogHandle)
{
- PLOGHANDLE lpLogHandle = (PLOGHANDLE)EventLogHandle;
- if (!ElfGetLogHandleEntryByHandle(lpLogHandle))
+ PLOGHANDLE lpLogHandle;
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
{
- return FALSE;
+ return STATUS_INVALID_HANDLE;
}
RemoveEntryList(&lpLogHandle->LogHandleListEntry);
- HeapFree(GetProcessHeap(),0,lpLogHandle);
+ LogfClose(lpLogHandle->LogFile, FALSE);
+
+ HeapFree(GetProcessHeap(), 0, lpLogHandle);
- return TRUE;
+ return STATUS_SUCCESS;
}
/* Function 0 */
PRPC_UNICODE_STRING BackupFileName)
{
PLOGHANDLE lpLogHandle;
- PLOGFILE lpLogFile;
+
+ DPRINT("ElfrClearELFW()\n");
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
return STATUS_INVALID_HANDLE;
}
- lpLogFile = lpLogHandle->LogFile;
-
- if (BackupFileName->Length > 0)
- {
- /* FIXME: Write a backup file */
- }
-
- LogfInitializeNew(lpLogFile);
+ /* Fail, if the log file is a backup file */
+ if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
+ return STATUS_INVALID_HANDLE;
- return STATUS_SUCCESS;
+ return LogfClearFile(lpLogHandle->LogFile,
+ (PUNICODE_STRING)BackupFileName);
}
IELF_HANDLE LogHandle,
PRPC_UNICODE_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLOGHANDLE lpLogHandle;
+
+ DPRINT("ElfrBackupELFW()\n");
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
+ {
+ return STATUS_INVALID_HANDLE;
+ }
+
+ return LogfBackupFile(lpLogHandle->LogFile,
+ (PUNICODE_STRING)BackupFileName);
}
+
/* Function 2 */
NTSTATUS ElfrCloseEL(
IELF_HANDLE *LogHandle)
{
- if (!ElfDeleteEventLogHandle(*LogHandle))
- {
- return STATUS_INVALID_HANDLE;
- }
-
- return STATUS_SUCCESS;
+ return ElfDeleteEventLogHandle(*LogHandle);
}
NTSTATUS ElfrDeregisterEventSource(
IELF_HANDLE *LogHandle)
{
- if (!ElfDeleteEventLogHandle(*LogHandle))
- {
- return STATUS_INVALID_HANDLE;
- }
-
- return STATUS_SUCCESS;
+ return ElfDeleteEventLogHandle(*LogHandle);
}
PLOGHANDLE lpLogHandle;
PLOGFILE lpLogFile;
+ DPRINT("ElfrNumberOfRecords()\n");
+
lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!lpLogHandle)
{
lpLogFile = lpLogHandle->LogFile;
- if (lpLogFile->Header.OldestRecordNumber == 0)
- *NumberOfRecords = 0;
- else
- *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber -
- lpLogFile->Header.OldestRecordNumber;
+ DPRINT("Oldest: %lu Current: %lu\n",
+ lpLogFile->Header.OldestRecordNumber,
+ lpLogFile->Header.CurrentRecordNumber);
+
+ *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber -
+ lpLogFile->Header.OldestRecordNumber;
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
- *OldestRecordNumber = 0;
*OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
+
return STATUS_SUCCESS;
}
RPC_CLIENT_ID ClientId,
DWORD Event)
{
+ DPRINT("ElfrChangeNotify()");
+
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*FIXME: Must verify that caller has read access */
- *LogHandle = ElfCreateEventLogHandle(ModuleName->Buffer, FALSE);
-
- if (*LogHandle == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- return STATUS_SUCCESS;
+ return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
+ ModuleName->Buffer,
+ FALSE);
}
/*FIXME: Must verify that caller has write access */
- *LogHandle = ElfCreateEventLogHandle(ModuleName->Buffer, TRUE);
-
- return STATUS_SUCCESS;
+ return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
+ ModuleName->Buffer,
+ TRUE);
}
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
+
+ if ((MajorVersion != 1) || (MinorVersion != 1))
+ return STATUS_INVALID_PARAMETER;
+
+ /*FIXME: UNCServerName must specify the server */
+
+ /*FIXME: Must verify that caller has read access */
+
+ return ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
+ (PUNICODE_STRING)BackupFileName);
}
return STATUS_INVALID_HANDLE;
}
- if (!Buffer)
- return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER);
+ if (!Buffer)
+ return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */
if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
}
dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
- NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded);
+ NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
+ FALSE);
/* Update the handles CurrentRecord if success*/
if (dwError == ERROR_SUCCESS)
lpLogHandle->CurrentRecord = RecordNumber;
}
+ /* HACK!!! */
+ if (dwError == ERROR_HANDLE_EOF)
+ return STATUS_END_OF_FILE;
+
return I_RpcMapWin32Status(dwError);
}
DPRINT("Info: %wZ\n", Strings[i]);
break;
+ case EVENTLOG_AUDIT_SUCCESS:
+ DPRINT("Audit Success: %wZ\n", Strings[i]);
+ break;
+
+ case EVENTLOG_AUDIT_FAILURE:
+ DPRINT("Audit Failure: %wZ\n", Strings[i]);
+ break;
+
default:
DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
break;
IELF_HANDLE LogHandle,
PRPC_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING BackupFileNameW;
+ NTSTATUS Status;
+
+ Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
+ (PANSI_STRING)BackupFileName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = ElfrBackupELFW(LogHandle,
+ (PRPC_UNICODE_STRING)&BackupFileNameW);
+
+ RtlFreeUnicodeString(&BackupFileNameW);
+
+ return Status;
}
/* FIXME: Must verify that caller has read access */
- *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
+ Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
+ ModuleNameW.Buffer,
+ FALSE);
RtlFreeUnicodeString(&ModuleNameW);
- if (*LogHandle == NULL)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- return STATUS_SUCCESS;
+ return Status;
}
/* FIXME: Must verify that caller has write access */
- *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer,
- TRUE);
+ Status = ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
+ ModuleNameW.Buffer,
+ TRUE);
RtlFreeUnicodeString(&ModuleNameW);
- return STATUS_SUCCESS;
+ return Status;
}
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING BackupFileNameW;
+ NTSTATUS Status;
+
+ DPRINT("ElfrOpenBELA(%Z)\n", BackupFileName);
+
+ Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
+ (PANSI_STRING)BackupFileName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ if ((MajorVersion != 1) || (MinorVersion != 1))
+ {
+ RtlFreeUnicodeString(&BackupFileNameW);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /*FIXME: UNCServerName must specify the server */
+
+ /*FIXME: Must verify that caller has read access */
+
+ Status = ElfCreateBackupLogHandle((PLOGHANDLE *)LogHandle,
+ &BackupFileNameW);
+
+ RtlFreeUnicodeString(&BackupFileNameW);
+
+ return Status;
}
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLOGHANDLE lpLogHandle;
+ DWORD dwError;
+ DWORD RecordNumber;
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
+ {
+ return STATUS_INVALID_HANDLE;
+ }
+
+ if (!Buffer)
+ return STATUS_INVALID_PARAMETER;
+
+ /* If sequential read, retrieve the CurrentRecord from this log handle */
+ if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
+ {
+ RecordNumber = lpLogHandle->CurrentRecord;
+ }
+ else
+ {
+ RecordNumber = RecordOffset;
+ }
+
+ dwError = LogfReadEvent(lpLogHandle->LogFile,
+ ReadFlags,
+ &RecordNumber,
+ NumberOfBytesToRead,
+ Buffer,
+ NumberOfBytesRead,
+ MinNumberOfBytesNeeded,
+ TRUE);
+
+ /* Update the handles CurrentRecord if success*/
+ if (dwError == ERROR_SUCCESS)
+ {
+ lpLogHandle->CurrentRecord = RecordNumber;
+ }
+
+ /* HACK!!! */
+ if (dwError == ERROR_HANDLE_EOF)
+ return STATUS_END_OF_FILE;
+
+ return I_RpcMapWin32Status(dwError);
}
DWORD *RecordNumber,
DWORD *TimeWritten)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING ComputerNameW;
+ PUNICODE_STRING *StringsArrayW = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ USHORT i;
+
+ DPRINT("ElfrReportEventA(%hu)\n", NumStrings);
+
+#if 0
+ for (i = 0; i < NumStrings; i++)
+ {
+ if (Strings[i] == NULL)
+ {
+ DPRINT1("String %hu is null\n", i);
+ }
+ else
+ {
+ DPRINT1("String %hu: %Z\n", i, Strings[i]);
+ }
+ }
+#endif
+
+ Status = RtlAnsiStringToUnicodeString((PUNICODE_STRING)&ComputerNameW,
+ (PANSI_STRING)ComputerName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (NumStrings != 0)
+ {
+ StringsArrayW = HeapAlloc(MyHeap,
+ HEAP_ZERO_MEMORY,
+ NumStrings * sizeof (PUNICODE_STRING));
+ if (StringsArrayW == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Done;
+ }
+
+ for (i = 0; i < NumStrings; i++)
+ {
+ if (Strings[i] != NULL)
+ {
+ StringsArrayW[i] = HeapAlloc(MyHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(UNICODE_STRING));
+ if (StringsArrayW[i] == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ Status = RtlAnsiStringToUnicodeString(StringsArrayW[i],
+ (PANSI_STRING)Strings[i],
+ TRUE);
+ }
+
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ Status = ElfrReportEventW(LogHandle,
+ Time,
+ EventType,
+ EventCategory,
+ EventID,
+ NumStrings,
+ DataSize,
+ (PRPC_UNICODE_STRING)&ComputerNameW,
+ UserSID,
+ (PRPC_UNICODE_STRING*)StringsArrayW,
+ Data,
+ Flags,
+ RecordNumber,
+ TimeWritten);
+ }
+
+Done:
+ if (StringsArrayW != NULL)
+ {
+ for (i = 0; i < NumStrings; i++)
+ {
+ if (StringsArrayW[i] != NULL)
+ {
+ if (StringsArrayW[i]->Buffer)
+ {
+ RtlFreeUnicodeString(StringsArrayW[i]);
+ HeapFree(MyHeap, 0, StringsArrayW[i]);
+ }
+ }
+ }
+
+ HeapFree(MyHeap, 0, StringsArrayW);
+ }
+
+ RtlFreeUnicodeString(&ComputerNameW);
+
+ return Status;
}