[EVENTLOG]
[reactos.git] / reactos / base / services / eventlog / rpc.c
index 915e35d..99f8d72 100644 (file)
@@ -11,6 +11,9 @@
 
 #include "eventlog.h"
 
+#define NDEBUG
+#include <debug.h>
+
 LIST_ENTRY LogHandleListHead;
 
 /* FUNCTIONS ****************************************************************/
@@ -44,12 +47,17 @@ DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
     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);
 
@@ -58,7 +66,7 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
     if (!lpLogHandle)
     {
         DPRINT1("Failed to allocate Heap!\n");
-        return NULL;
+        return STATUS_NO_MEMORY;
     }
 
     wcscpy(lpLogHandle->szName, Name);
@@ -68,7 +76,8 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
     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 */
@@ -114,45 +123,115 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
     }
 
     if (!lpLogHandle->LogFile)
-        goto Cleanup;
+        Status = STATUS_UNSUCCESSFUL;
 
-    /* Append log handle */
-    InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
+Done:
+    if (NT_SUCCESS(Status))
+    {
+        /* Append log handle */
+        InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
+        *LogHandle = lpLogHandle;
+    }
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, lpLogHandle);
+    }
 
-    return lpLogHandle;
+    return Status;
+}
 
-Cleanup:
-    HeapFree(GetProcessHeap(), 0, lpLogHandle);
 
-    return NULL;
+static NTSTATUS
+ElfCreateBackupLogHandle(PLOGHANDLE *LogHandle,
+                         PUNICODE_STRING FileName)
+{
+    PLOGHANDLE lpLogHandle;
+
+    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 */
@@ -170,6 +249,10 @@ NTSTATUS ElfrClearELFW(
         return STATUS_INVALID_HANDLE;
     }
 
+    /* Fail, if the log file is a backup file */
+    if (lpLogHandle->Flags & LOG_HANDLE_BACKUP_FILE)
+        return STATUS_INVALID_HANDLE;
+
     return LogfClearFile(lpLogHandle->LogFile,
                          (PUNICODE_STRING)BackupFileName);
 }
@@ -199,12 +282,7 @@ NTSTATUS ElfrBackupELFW(
 NTSTATUS ElfrCloseEL(
     IELF_HANDLE *LogHandle)
 {
-    if (!ElfDeleteEventLogHandle(*LogHandle))
-    {
-        return STATUS_INVALID_HANDLE;
-    }
-
-    return STATUS_SUCCESS;
+    return ElfDeleteEventLogHandle(*LogHandle);
 }
 
 
@@ -212,12 +290,7 @@ NTSTATUS ElfrCloseEL(
 NTSTATUS ElfrDeregisterEventSource(
     IELF_HANDLE *LogHandle)
 {
-    if (!ElfDeleteEventLogHandle(*LogHandle))
-    {
-        return STATUS_INVALID_HANDLE;
-    }
-
-    return STATUS_SUCCESS;
+    return ElfDeleteEventLogHandle(*LogHandle);
 }
 
 
@@ -229,7 +302,7 @@ NTSTATUS ElfrNumberOfRecords(
     PLOGHANDLE lpLogHandle;
     PLOGFILE lpLogFile;
 
-    DPRINT("ElfrNumberOfRecords()");
+    DPRINT("ElfrNumberOfRecords()\n");
 
     lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
     if (!lpLogHandle)
@@ -307,14 +380,9 @@ NTSTATUS ElfrOpenELW(
 
     /*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);
 }
 
 
@@ -342,9 +410,9 @@ NTSTATUS ElfrRegisterEventSourceW(
 
     /*FIXME: Must verify that caller has write access */
 
-    *LogHandle = ElfCreateEventLogHandle(ModuleName->Buffer, TRUE);
-
-    return STATUS_SUCCESS;
+    return ElfCreateEventLogHandle((PLOGHANDLE *)LogHandle,
+                                   ModuleName->Buffer,
+                                   TRUE);
 }
 
 
@@ -356,8 +424,17 @@ NTSTATUS ElfrOpenBELW(
     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);
 }
 
 
@@ -474,6 +551,14 @@ NTSTATUS ElfrReportEventW(
                 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;
@@ -597,16 +682,13 @@ NTSTATUS ElfrOpenELA(
 
     /* 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;
 }
 
 
@@ -646,12 +728,13 @@ NTSTATUS ElfrRegisterEventSourceA(
 
     /* 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;
 }
 
 
@@ -663,8 +746,36 @@ NTSTATUS ElfrOpenBELA(
     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;
 }
 
 
@@ -821,20 +932,22 @@ NTSTATUS ElfrReportEventA(
     }
 
 Done:
-    for (i = 0; i < NumStrings; i++)
+    if (StringsArrayW != NULL)
     {
-        if (StringsArrayW[i] != NULL)
+        for (i = 0; i < NumStrings; i++)
         {
-            if (StringsArrayW[i]->Buffer)
+            if (StringsArrayW[i] != NULL)
             {
-                RtlFreeUnicodeString(StringsArrayW[i]);
-                HeapFree(MyHeap, 0, StringsArrayW[i]);
+                if (StringsArrayW[i]->Buffer)
+                {
+                    RtlFreeUnicodeString(StringsArrayW[i]);
+                    HeapFree(MyHeap, 0, StringsArrayW[i]);
+                }
             }
         }
-    }
 
-    if (StringsArrayW != NULL)
         HeapFree(MyHeap, 0, StringsArrayW);
+    }
 
     RtlFreeUnicodeString(&ComputerNameW);