[EVENTLOG]
[reactos.git] / reactos / base / services / eventlog / rpc.c
index d0efdad..0526e5d 100644 (file)
@@ -49,6 +49,9 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
     PLOGHANDLE lpLogHandle;
     PLOGFILE currentLogFile = NULL;
     INT i, LogsActive;
+    PEVENTSOURCE pEventSource;
+
+    DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
 
     lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
                                   + ((wcslen(Name) + 1) * sizeof(WCHAR)));
@@ -70,19 +73,43 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
 
     /* If Creating, default to the Application Log in case we fail, as documented on MSDN */
     if (Create == TRUE)
-        lpLogHandle->LogFile = LogfListItemByName(L"Application");
+    {
+        pEventSource = GetEventSourceByName(Name);
+        DPRINT("EventSource: %p\n", pEventSource);
+        if (pEventSource)
+        {
+            DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile);
+            lpLogHandle->LogFile = pEventSource->LogFile;
+        }
+        else
+        {
+            DPRINT("EventSource LogFile: Application log file\n");
+            lpLogHandle->LogFile = LogfListItemByName(L"Application");
+        }
+
+        DPRINT("LogHandle LogFile: %p\n", lpLogHandle->LogFile);
+    }
     else
+    {
         lpLogHandle->LogFile = NULL;
 
-    for (i = 1; i <= LogsActive; i++)
-    {
-        currentLogFile = LogfListItemByIndex(i);
+        for (i = 1; i <= LogsActive; i++)
+        {
+            currentLogFile = LogfListItemByIndex(i);
 
-        if (_wcsicmp(Name, currentLogFile->LogName) == 0)
+            if (_wcsicmp(Name, currentLogFile->LogName) == 0)
+            {
+                lpLogHandle->LogFile = LogfListItemByIndex(i);
+                lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
+                break;
+            }
+        }
+
+        /* Use the application log if the desired log does not exist */
+        if (lpLogHandle->LogFile == NULL)
         {
-            lpLogHandle->LogFile = LogfListItemByIndex(i);
+            lpLogHandle->LogFile = LogfListItemByName(L"Application");
             lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
-            break;
         }
     }
 
@@ -133,8 +160,25 @@ NTSTATUS ElfrClearELFW(
     IELF_HANDLE LogHandle,
     PRPC_UNICODE_STRING BackupFileName)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLOGHANDLE lpLogHandle;
+    PLOGFILE lpLogFile;
+
+    lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+    if (!lpLogHandle)
+    {
+        return STATUS_INVALID_HANDLE;
+    }
+
+    lpLogFile = lpLogHandle->LogFile;
+
+    if (BackupFileName->Length > 0)
+    {
+        /* FIXME: Write a backup file */
+    }
+
+    LogfInitializeNew(lpLogFile);
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -179,6 +223,7 @@ NTSTATUS ElfrNumberOfRecords(
     DWORD *NumberOfRecords)
 {
     PLOGHANDLE lpLogHandle;
+    PLOGFILE lpLogFile;
 
     lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
     if (!lpLogHandle)
@@ -186,7 +231,13 @@ NTSTATUS ElfrNumberOfRecords(
         return STATUS_INVALID_HANDLE;
     }
 
-    *NumberOfRecords = lpLogHandle->LogFile->Header.CurrentRecordNumber;
+    lpLogFile = lpLogHandle->LogFile;
+
+    if (lpLogFile->Header.OldestRecordNumber == 0)
+        *NumberOfRecords = 0;
+    else
+        *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber -
+                           lpLogFile->Header.OldestRecordNumber;
 
     return STATUS_SUCCESS;
 }
@@ -267,6 +318,8 @@ NTSTATUS ElfrRegisterEventSourceW(
     DWORD MinorVersion,
     IELF_HANDLE *LogHandle)
 {
+    DPRINT("ElfrRegisterEventSourceW()\n");
+
     if ((MajorVersion != 1) || (MinorVersion != 1))
         return STATUS_INVALID_PARAMETER;
 
@@ -274,6 +327,8 @@ NTSTATUS ElfrRegisterEventSourceW(
     if (RegModuleName->Length > 0)
         return STATUS_INVALID_PARAMETER;
 
+    DPRINT("ModuleName: %S\n", ModuleName->Buffer);
+
     /*FIXME: UNCServerName must specify the server or empty for local */
 
     /*FIXME: Must verify that caller has write access */
@@ -366,6 +421,7 @@ NTSTATUS ElfrReportEventW(
     DWORD lastRec;
     DWORD recSize;
     DWORD dwStringsSize = 0;
+    DWORD dwUserSidLength = 0;
     DWORD dwError = ERROR_SUCCESS;
     WCHAR *lpStrings;
     int pos = 0;
@@ -408,10 +464,10 @@ NTSTATUS ElfrReportEventW(
                 DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]);
                 break;
         }
-        dwStringsSize += (wcslen(Strings[i]->Buffer) + 1) * sizeof(WCHAR);
+        dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
     }
 
-    lpStrings = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, dwStringsSize * 2);
+    lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
     if (!lpStrings)
     {
         DPRINT1("Failed to allocate heap\n");
@@ -420,10 +476,14 @@ NTSTATUS ElfrReportEventW(
 
     for (i = 0; i < NumStrings; i++)
     {
-        wcscpy((WCHAR*)(lpStrings + pos), Strings[i]->Buffer);
-        pos += (wcslen(Strings[i]->Buffer) + 1) * sizeof(WCHAR);
+        CopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
+        pos += Strings[i]->Length / sizeof(WCHAR);
+        lpStrings[pos] = UNICODE_NULL;
+        pos += sizeof UNICODE_NULL / sizeof(WCHAR);
     }
 
+    if (UserSID)
+        dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
     LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
                                            lastRec,
                                            EventType,
@@ -431,10 +491,10 @@ NTSTATUS ElfrReportEventW(
                                            EventID,
                                            lpLogHandle->szName,
                                            ComputerName->Buffer,
-                                           sizeof(UserSID),
-                                           &UserSID,
+                                           dwUserSidLength,
+                                           UserSID,
                                            NumStrings,
-                                           (WCHAR*)lpStrings,
+                                           lpStrings,
                                            DataSize,
                                            Data);
 
@@ -457,8 +517,21 @@ NTSTATUS ElfrClearELFA(
     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 = ElfrClearELFW(LogHandle,
+                           (PRPC_UNICODE_STRING)&BackupFileNameW);
+
+    RtlFreeUnicodeString(&BackupFileNameW);
+
+    return Status;
 }
 
 
@@ -467,8 +540,21 @@ NTSTATUS ElfrBackupELFA(
     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;
 }
 
 
@@ -482,6 +568,7 @@ NTSTATUS ElfrOpenELA(
     IELF_HANDLE *LogHandle)
 {
     UNICODE_STRING ModuleNameW;
+    NTSTATUS Status;
 
     if ((MajorVersion != 1) || (MinorVersion != 1))
         return STATUS_INVALID_PARAMETER;
@@ -490,7 +577,9 @@ NTSTATUS ElfrOpenELA(
     if (RegModuleName->Length > 0)
         return STATUS_INVALID_PARAMETER;
 
-    RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
+    Status = RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
+    if (!NT_SUCCESS(Status))
+        return Status;
 
     /* FIXME: Must verify that caller has read access */
 
@@ -516,12 +605,16 @@ NTSTATUS ElfrRegisterEventSourceA(
     DWORD MinorVersion,
     IELF_HANDLE *LogHandle)
 {
-    UNICODE_STRING ModuleNameW    = { 0, 0, NULL };
+    UNICODE_STRING ModuleNameW;
+    NTSTATUS Status;
 
-    if (ModuleName &&
-        !RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
+    Status = RtlAnsiStringToUnicodeString(&ModuleNameW,
+                                          (PANSI_STRING)ModuleName,
+                                          TRUE);
+    if (!NT_SUCCESS(Status))
     {
-        return STATUS_NO_MEMORY;
+        DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status);
+        return Status;
     }
 
     /* RegModuleName must be an empty string */
@@ -593,8 +686,104 @@ NTSTATUS ElfrReportEventA(
     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:
+    for (i = 0; i < NumStrings; i++)
+    {
+        if (StringsArrayW[i] != NULL)
+        {
+            if (StringsArrayW[i]->Buffer)
+            {
+                RtlFreeUnicodeString(StringsArrayW[i]);
+                HeapFree(MyHeap, 0, StringsArrayW[i]);
+            }
+        }
+    }
+
+    if (StringsArrayW != NULL)
+        HeapFree(MyHeap, 0, StringsArrayW);
+
+    RtlFreeUnicodeString(&ComputerNameW);
+
+    return Status;
 }