[EVENTLOG]
authorEric Kohl <eric.kohl@reactos.org>
Sun, 14 Mar 2010 12:26:49 +0000 (12:26 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 14 Mar 2010 12:26:49 +0000 (12:26 +0000)
- Set the current service status from the service control handler.
- Fix type declarations.
- ElfrOpenELA/ElfrRegisterEventSourceA: Do not call the Unicode functions because in this case it is easier to do things yourself.
- Implement ElfrGetLogInformation partially.
- Bind client to the EventLog Pipe.
- Use RtlInitAnsiString and RtlInitUnicodeString instead of building strings manually.
- GetEventLogInformation: Check for valid dwInfoLevel.

svn path=/trunk/; revision=46199

reactos/base/services/eventlog/eventlog.c
reactos/base/services/eventlog/eventlog.h
reactos/base/services/eventlog/rpc.c
reactos/dll/win32/advapi32/service/eventlog.c

index 4f0120a..7066335 100644 (file)
@@ -21,20 +21,76 @@ static SERVICE_TABLE_ENTRYW ServiceTable[2] =
     { NULL, NULL }
 };
 
+SERVICE_STATUS ServiceStatus;
+SERVICE_STATUS_HANDLE ServiceStatusHandle;
+
 BOOL onLiveCD = FALSE;  // On livecd events will go to debug output only
 HANDLE MyHeap = NULL;
 
 /* FUNCTIONS ****************************************************************/
 
+static VOID
+UpdateServiceStatus(DWORD dwState)
+{
+    ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+    ServiceStatus.dwCurrentState = dwState;
+    ServiceStatus.dwControlsAccepted = 0;
+    ServiceStatus.dwWin32ExitCode = 0;
+    ServiceStatus.dwServiceSpecificExitCode = 0;
+    ServiceStatus.dwCheckPoint = 0;
+
+    if (dwState == SERVICE_START_PENDING ||
+        dwState == SERVICE_STOP_PENDING ||
+        dwState == SERVICE_PAUSE_PENDING ||
+        dwState == SERVICE_CONTINUE_PENDING)
+        ServiceStatus.dwWaitHint = 10000;
+    else
+        ServiceStatus.dwWaitHint = 0;
+
+    SetServiceStatus(ServiceStatusHandle,
+                     &ServiceStatus);
+}
+
 static DWORD WINAPI
 ServiceControlHandler(DWORD dwControl,
                       DWORD dwEventType,
                       LPVOID lpEventData,
                       LPVOID lpContext)
 {
-    /* FIXME */
-    DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
-    return ERROR_SUCCESS;
+    DPRINT("ServiceControlHandler() called\n");
+
+    switch (dwControl)
+    {
+        case SERVICE_CONTROL_STOP:
+            DPRINT("  SERVICE_CONTROL_STOP received\n");
+            UpdateServiceStatus(SERVICE_STOPPED);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_PAUSE:
+            DPRINT("  SERVICE_CONTROL_PAUSE received\n");
+            UpdateServiceStatus(SERVICE_PAUSED);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_CONTINUE:
+            DPRINT("  SERVICE_CONTROL_CONTINUE received\n");
+            UpdateServiceStatus(SERVICE_RUNNING);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_INTERROGATE:
+            DPRINT("  SERVICE_CONTROL_INTERROGATE received\n");
+            SetServiceStatus(ServiceStatusHandle,
+                             &ServiceStatus);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_SHUTDOWN:
+            DPRINT("  SERVICE_CONTROL_SHUTDOWN received\n");
+            UpdateServiceStatus(SERVICE_STOPPED);
+            return ERROR_SUCCESS;
+
+        default :
+            DPRINT1("  Control %lu received\n");
+            return ERROR_CALL_NOT_IMPLEMENTED;
+    }
 }
 
 
@@ -83,8 +139,6 @@ static VOID CALLBACK
 ServiceMain(DWORD argc,
             LPWSTR *argv)
 {
-    SERVICE_STATUS ServiceStatus;
-    SERVICE_STATUS_HANDLE ServiceStatusHandle;
     DWORD dwError;
 
     UNREFERENCED_PARAMETER(argc);
@@ -102,31 +156,20 @@ ServiceMain(DWORD argc,
         return;
     }
 
-    ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
-    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
-    ServiceStatus.dwControlsAccepted = 0;
-    ServiceStatus.dwWin32ExitCode = NO_ERROR;
-    ServiceStatus.dwServiceSpecificExitCode = 0;
-    ServiceStatus.dwCheckPoint = 0;
-    ServiceStatus.dwWaitHint = 2000;
-
-    SetServiceStatus(ServiceStatusHandle,
-                     &ServiceStatus);
+    UpdateServiceStatus(SERVICE_START_PENDING);
 
     dwError = ServiceInit();
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("Service stopped\n");
-        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+        DPRINT("Service stopped (dwError: %lu\n", dwError);
+        UpdateServiceStatus(SERVICE_START_PENDING);
     }
     else
     {
-        ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+        DPRINT("Service started\n");
+        UpdateServiceStatus(SERVICE_RUNNING);
     }
 
-    SetServiceStatus(ServiceStatusHandle,
-                     &ServiceStatus);
-
     DPRINT("ServiceMain() done\n");
 }
 
index 4b9c6a8..df0ab15 100644 (file)
@@ -44,7 +44,8 @@ typedef struct _IO_ERROR_LPC
 #define ELF_LOGFILE_ARCHIVE_SET 8
 
 /* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
-typedef struct _EVENTLOGHEADER {
+typedef struct _EVENTLOGHEADER
+{
     ULONG HeaderSize;
     ULONG Signature;
     ULONG MajorVersion;
@@ -59,7 +60,8 @@ typedef struct _EVENTLOGHEADER {
     ULONG EndHeaderSize;
 } EVENTLOGHEADER, *PEVENTLOGHEADER;
 
-typedef struct _EVENTLOGEOF {
+typedef struct _EVENTLOGEOF
+{
     ULONG RecordSizeBeginning;
     ULONG Ones;
     ULONG Twos;
@@ -72,13 +74,13 @@ typedef struct _EVENTLOGEOF {
     ULONG RecordSizeEnd;
 } EVENTLOGEOF, *PEVENTLOGEOF;
 
-typedef struct
+typedef struct _EVENT_OFFSET_INFO
 {
     ULONG EventNumber;
     ULONG EventOffset;
 } EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
 
-typedef struct
+typedef struct _LOGFILE
 {
     HANDLE hFile;
     EVENTLOGHEADER Header;
index e3ef33d..d399d1e 100644 (file)
@@ -480,45 +480,29 @@ NTSTATUS ElfrOpenELA(
     DWORD MinorVersion,
     IELF_HANDLE *LogHandle)
 {
-    UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
-    UNICODE_STRING ModuleNameW    = { 0, 0, NULL };
-    UNICODE_STRING RegModuleNameW = { 0, 0, NULL };
-    NTSTATUS Status;
+    UNICODE_STRING ModuleNameW;
 
-    if (UNCServerName &&
-        !RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
-    {
-        return STATUS_NO_MEMORY;
-    }
+    if ((MajorVersion != 1) || (MinorVersion != 1))
+        return STATUS_INVALID_PARAMETER;
 
-    if (ModuleName &&
-        !RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
-    {
-        RtlFreeUnicodeString(&UNCServerNameW);
-        return STATUS_NO_MEMORY;
-    }
+    /* RegModuleName must be an empty string */
+    if (RegModuleName->Length > 0)
+        return STATUS_INVALID_PARAMETER;
 
-    if (RegModuleName &&
-        !RtlAnsiStringToUnicodeString(&RegModuleNameW, (PANSI_STRING)RegModuleName, TRUE))
-    {
-        RtlFreeUnicodeString(&UNCServerNameW);
-        RtlFreeUnicodeString(&ModuleNameW);
-        return STATUS_NO_MEMORY;
-    }
+    RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
+
+    /* FIXME: Must verify that caller has read access */
 
-    Status = ElfrOpenELW(
-        UNCServerName ? UNCServerNameW.Buffer : NULL,
-        ModuleName ? (PRPC_UNICODE_STRING)&ModuleNameW : NULL,
-        RegModuleName ? (PRPC_UNICODE_STRING)&RegModuleNameW : NULL,
-        MajorVersion,
-        MinorVersion,
-        LogHandle);
+    *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
 
-    RtlFreeUnicodeString(&UNCServerNameW);
     RtlFreeUnicodeString(&ModuleNameW);
-    RtlFreeUnicodeString(&RegModuleNameW);
 
-    return Status;
+    if (*LogHandle == NULL)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -531,45 +515,32 @@ NTSTATUS ElfrRegisterEventSourceA(
     DWORD MinorVersion,
     IELF_HANDLE *LogHandle)
 {
-    UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
     UNICODE_STRING ModuleNameW    = { 0, 0, NULL };
 
-    if (UNCServerName &&
-        !RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
-    {
-        return STATUS_NO_MEMORY;
-    }
-
     if (ModuleName &&
         !RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
     {
-        RtlFreeUnicodeString(&UNCServerNameW);
         return STATUS_NO_MEMORY;
     }
 
     /* RegModuleName must be an empty string */
     if (RegModuleName->Length > 0)
     {
-        RtlFreeUnicodeString(&UNCServerNameW);
         RtlFreeUnicodeString(&ModuleNameW);
         return STATUS_INVALID_PARAMETER;
     }
 
     if ((MajorVersion != 1) || (MinorVersion != 1))
     {
-        RtlFreeUnicodeString(&UNCServerNameW);
         RtlFreeUnicodeString(&ModuleNameW);
         return STATUS_INVALID_PARAMETER;
     }
 
-    /*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 */
 
     *LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer,
                                          TRUE);
 
-    RtlFreeUnicodeString(&UNCServerNameW);
     RtlFreeUnicodeString(&ModuleNameW);
 
     return STATUS_SUCCESS;
@@ -661,8 +632,32 @@ NTSTATUS ElfrGetLogInformation(
     DWORD cbBufSize,
     DWORD *pcbBytesNeeded)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* FIXME: check handle first */
+
+    switch (InfoLevel)
+    {
+        case EVENTLOG_FULL_INFO:
+            {
+                LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer;
+
+                *pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
+                if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
+                {
+                    return STATUS_BUFFER_TOO_SMALL;
+                }
+
+                efi->dwFull = 0; /* FIXME */
+            }
+            break;
+
+        default:
+            Status = STATUS_INVALID_LEVEL;
+            break;
+    }
+
+    return Status;
 }
 
 
index 7327532..8cb4b22 100644 (file)
@@ -42,7 +42,7 @@ EVENTLOG_HANDLE_A_bind(EVENTLOG_HANDLE_A UNCServerName)
     status = RpcStringBindingComposeA(NULL,
                                       (UCHAR *)"ncacn_np",
                                       (UCHAR *)UNCServerName,
-                                      (UCHAR *)"\\pipe\\ntsvcs",
+                                      (UCHAR *)"\\pipe\\EventLog",
                                       NULL,
                                       (UCHAR **)&pszStringBinding);
     if (status)
@@ -147,20 +147,17 @@ BOOL WINAPI
 BackupEventLogA(IN HANDLE hEventLog,
                 IN LPCSTR lpBackupFileName)
 {
-    RPC_STRING BackupFileName;
+    ANSI_STRING BackupFileName;
     NTSTATUS Status;
 
     TRACE("%p, %s\n", hEventLog, lpBackupFileName);
 
-    BackupFileName.Buffer = (LPSTR)lpBackupFileName;
-    BackupFileName.Length = BackupFileName.MaximumLength =
-        lpBackupFileName ? strlen(lpBackupFileName) : 0;
-    BackupFileName.MaximumLength += sizeof(CHAR);
+    RtlInitAnsiString(&BackupFileName, lpBackupFileName);
 
     RpcTryExcept
     {
         Status = ElfrBackupELFA(hEventLog,
-                                &BackupFileName);
+                                (PRPC_STRING)&BackupFileName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -188,20 +185,17 @@ BOOL WINAPI
 BackupEventLogW(IN HANDLE hEventLog,
                 IN LPCWSTR lpBackupFileName)
 {
-    RPC_UNICODE_STRING BackupFileName;
+    UNICODE_STRING BackupFileName;
     NTSTATUS Status;
 
     TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
 
-    BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
-    BackupFileName.Length = BackupFileName.MaximumLength =
-        lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
-    BackupFileName.MaximumLength += sizeof(WCHAR);
+    RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
 
     RpcTryExcept
     {
         Status = ElfrBackupELFW(hEventLog,
-                                &BackupFileName);
+                                (PRPC_UNICODE_STRING)&BackupFileName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -226,20 +220,17 @@ BOOL WINAPI
 ClearEventLogA(IN HANDLE hEventLog,
                IN LPCSTR lpBackupFileName)
 {
-    RPC_STRING BackupFileName;
+    ANSI_STRING BackupFileName;
     NTSTATUS Status;
 
     TRACE("%p, %s\n", hEventLog, lpBackupFileName);
 
-    BackupFileName.Buffer = (LPSTR)lpBackupFileName;
-    BackupFileName.Length = BackupFileName.MaximumLength =
-        lpBackupFileName ? strlen(lpBackupFileName) : 0;
-    BackupFileName.MaximumLength += sizeof(CHAR);
+    RtlInitAnsiString(&BackupFileName, lpBackupFileName);
 
     RpcTryExcept
     {
         Status = ElfrClearELFA(hEventLog,
-                               &BackupFileName);
+                               (PRPC_STRING)&BackupFileName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -264,20 +255,17 @@ BOOL WINAPI
 ClearEventLogW(IN HANDLE hEventLog,
                IN LPCWSTR lpBackupFileName)
 {
-    RPC_UNICODE_STRING BackupFileName;
+    UNICODE_STRING BackupFileName;
     NTSTATUS Status;
 
     TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
 
-    BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
-    BackupFileName.Length = BackupFileName.MaximumLength =
-        lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
-    BackupFileName.MaximumLength += sizeof(WCHAR);
+    RtlInitUnicodeString(&BackupFileName,lpBackupFileName);
 
     RpcTryExcept
     {
         Status = ElfrClearELFW(hEventLog,
-                               &BackupFileName);
+                               (PRPC_UNICODE_STRING)&BackupFileName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -380,6 +368,12 @@ GetEventLogInformation(IN HANDLE hEventLog,
 {
     NTSTATUS Status;
 
+    if (dwInfoLevel != EVENTLOG_FULL_INFO)
+    {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
     RpcTryExcept
     {
         Status = ElfrGetLogInformation(hEventLog,
@@ -562,21 +556,18 @@ HANDLE WINAPI
 OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
                     IN LPCWSTR lpFileName)
 {
-    RPC_UNICODE_STRING FileName;
+    UNICODE_STRING FileName;
     IELF_HANDLE LogHandle;
     NTSTATUS Status;
 
     TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
 
-    FileName.Buffer = (LPWSTR)lpFileName;
-    FileName.Length = FileName.MaximumLength =
-        lpFileName ? wcslen(lpFileName) * sizeof(WCHAR) : 0;
-    FileName.MaximumLength += sizeof(WCHAR);
+    RtlInitUnicodeString(&FileName, lpFileName);
 
     RpcTryExcept
     {
         Status = ElfrOpenBELW((LPWSTR)lpUNCServerName,
-                              &FileName,
+                              (PRPC_UNICODE_STRING)&FileName,
                               1,
                               1,
                               &LogHandle);
@@ -903,21 +894,18 @@ HANDLE WINAPI
 RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
                      IN LPCWSTR lpSourceName)
 {
-    RPC_UNICODE_STRING SourceName;
+    UNICODE_STRING SourceName;
     IELF_HANDLE LogHandle;
     NTSTATUS Status;
 
     TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
 
-    SourceName.Buffer = (LPWSTR)lpSourceName;
-    SourceName.Length = SourceName.MaximumLength =
-        lpSourceName ? wcslen(lpSourceName) * sizeof(WCHAR) : 0;
-    SourceName.MaximumLength += sizeof(WCHAR);
+    RtlInitUnicodeString(&SourceName, lpSourceName);
 
     RpcTryExcept
     {
         Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName,
-                                          &SourceName,
+                                          (PRPC_UNICODE_STRING)&SourceName,
                                           &EmptyStringU,
                                           1,
                                           1,