Saveliy Tretiakov <saveliyt@mail.ru>:
authorGé van Geldorp <ge@gse.nl>
Tue, 20 Sep 2005 07:58:28 +0000 (07:58 +0000)
committerGé van Geldorp <ge@gse.nl>
Tue, 20 Sep 2005 07:58:28 +0000 (07:58 +0000)
EventLog changes
- Implement basic file operations (WindowsNT compatible file format)
- Write events from lpc port to System Log
  (to read these events, open \ReactOS\system32\config\SysEvent.evt in Windows
  EventViewer)
- RPC server (stubs)

svn path=/trunk/; revision=17940

reactos/include/idl/eventlogrpc.idl [new file with mode: 0644]
reactos/include/idl/idl.xml
reactos/services/eventlog/eventlog.c
reactos/services/eventlog/eventlog.h
reactos/services/eventlog/eventlog.xml
reactos/services/eventlog/file.c [new file with mode: 0644]
reactos/services/eventlog/logport.c
reactos/services/eventlog/rpc.c [new file with mode: 0644]

diff --git a/reactos/include/idl/eventlogrpc.idl b/reactos/include/idl/eventlogrpc.idl
new file mode 100644 (file)
index 0000000..fb667c0
--- /dev/null
@@ -0,0 +1,237 @@
+/* 
+ *  Copyright (c) 2005 Saveliy Tretiakov (saveliyt@mail.ru)  
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+[
+       uuid(82273FDC-E32A-18C3-3F78-827929DC23EA),
+       version(0.0),
+       pointer_default(unique),
+       explicit_handle
+]
+
+interface eventlog
+{
+       /*
+       cpp_quote("#if 0")
+       typedef [handle, unique] wchar_t *LPWSTR;
+       typedef [handle, unique] char *LPSTR;
+       cpp_quote("#endif")
+       typedef [context_handle] void *LOGHANDLE;
+       typedef LOGHANDLE *PLOGHANDLE;
+       typedef unsigned int NTSTATUS;
+
+       typedef struct _UNICODE_STRING {
+               unsigned short Length;
+               unsigned short MaximumLength;
+               [size_is(MaximumLength)] wchar_t *Buffer;
+       } UNICODE_STRING, *PUNICODE_STRING;
+
+       typedef struct _ANSI_STRING {
+               unsigned short Length;
+               unsigned short MaximumLength;
+               [size_is(MaximumLength)] char *Buffer;
+       } ANSI_STRING, *PANSI_STRING;
+       */
+       
+       #define LPWSTR wchar_t*
+       #define LPSTR char*
+       #define LOGHANDLE unsigned char*
+       #define PLOGHANDLE int* 
+       #define NTSTATUS long
+       
+       /* Function 0 */
+       NTSTATUS EventLogClearW(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] wchar_t *BackupName);
+
+       /* Function 1 */
+       NTSTATUS EventLogBackupW(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] wchar_t *FileName);
+       
+       /* Function 2 */
+       NTSTATUS EventLogClose(
+               handle_t BindingHandle,
+               [in,out] PLOGHANDLE Handle);   
+
+       /* Function 3 */
+       NTSTATUS EventLogUnregSrc(
+               handle_t BindingHandle,
+               [in,out] PLOGHANDLE Handle);
+
+       /* Function 4 */
+       NTSTATUS EventLogRecordsNumber(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [out] unsigned long *RecordsNumber);
+
+       /* Function 5 */
+       NTSTATUS EventLogGetOldestRec(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [out] unsigned long *OldestRecNumber);
+
+       /* FIXME */
+       NTSTATUS Unknown6(handle_t BindingHandle);
+
+       /* Function 7 */
+       NTSTATUS EventLogOpenW(
+               handle_t BindingHandle,
+               [in] LPWSTR ServerName,
+               [in] wchar_t *FileName, 
+               [in] wchar_t *NullStr, 
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle );
+               
+       /* Function 8 */
+       NTSTATUS EventLogRegSrcW(
+               handle_t BindingHandle,
+               [in] LPWSTR ServerName,
+               [in] wchar_t *LogName, 
+               [in] wchar_t *NullStr, 
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle);
+               
+       /* Function 9 */
+       NTSTATUS EventLogOpenBackupW(
+               handle_t BindingHandle,
+               [in] LPWSTR ServerName,
+               [in] wchar_t *BackupName, 
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle);
+
+       /* Function 10 */
+       NTSTATUS EventLogReadW(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] unsigned long Flags,
+               [in] unsigned long Offset,
+               [in] unsigned long BufSize,
+               [out,size_is(BufSize)] unsigned char *Buffer,
+               [out] unsigned long *BytesRead,
+               [out] unsigned long *BytesNeeded);
+
+       /* Function 11 */
+       NTSTATUS EventLogReportEventW(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] unsigned long Time,
+               [in] unsigned short Type,
+               [in] unsigned short Category,
+               [in] unsigned long ID,
+               [in] unsigned short NumStrings,
+               [in] unsigned long DataSize,
+               [in] wchar_t *ComputerName,
+               [in] unsigned char *SID,
+               [in] wchar_t *Strings,
+               [in,size_is(DataSize)] unsigned char *Data,
+               [in] unsigned short Flags);
+               
+       /* Function 12 */
+       NTSTATUS EventLogClearA(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] char *BackupName);
+
+       /* Function 13 */
+       NTSTATUS EventLogBackupA(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] char *BackupName);
+
+       /* Function 14 */
+       NTSTATUS EventLogOpenA(
+               handle_t BindingHandle,
+               [in] LPSTR ServerName,
+               [in] char *LogName, 
+               [in] char *NullStr, 
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle);
+
+       /* Function 15 */
+       NTSTATUS EventLogRegSrcA(
+               handle_t BindingHandle,
+               [in] LPSTR ServerName,
+               [in] char *LogName, 
+               [in] char *NullStr,
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle);
+
+
+       /* Function 16 */
+       NTSTATUS EventLogOpenBackupA(
+               handle_t BindingHandle,
+               [in] LPSTR ServerName,
+               [in] char *BackupName, 
+               [in] unsigned long MajorVer,
+               [in] unsigned long MinorVer,
+               [out] PLOGHANDLE Handle);
+
+       /* Function 17 */
+       NTSTATUS EventLogReadA(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] unsigned long Flags,
+               [in] unsigned long Offset,
+               [in] unsigned long BufSize,
+               [out,size_is(BufSize)] unsigned char *Buffer,
+               [out] unsigned long *BytesRead,
+               [out] unsigned long *BytesNeeded);
+
+       /* Function 18 */
+       NTSTATUS EventLogReportEventA(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] unsigned long Time,
+               [in] unsigned short Type,
+               [in] unsigned short Category,
+               [in] unsigned long ID,
+               [in] unsigned short NumStrings,
+               [in] unsigned long DataSize,
+               [in] char *ComputerName,
+               [in] unsigned char *SID,
+               [in] char* Strings,
+               [in,size_is(DataSize)] unsigned char *Data,
+               [in] unsigned short Flags);
+               
+       /* FIXME */
+       NTSTATUS Unknown19(handle_t BindingHandle);
+       
+       /* FIXME */
+       NTSTATUS Unknown20(handle_t BindingHandle);
+
+       /* FIXME */
+       NTSTATUS Unknown21(handle_t BindingHandle);
+
+       /* Function 22 */
+       NTSTATUS EventLogGetInfo(
+               handle_t BindingHandle,
+               [in] LOGHANDLE Handle,
+               [in] unsigned long InfoLevel,
+               [out,size_is(BufSize)] unsigned char *Buffer,
+               [in] unsigned long BufSize,
+               [out] unsigned long *BytesNeeded);
+
+}
+
index a15c7e9..5148dd5 100644 (file)
        <define name="_X86_" />
        <file switches="-o">svcctl.idl</file>
 </module>
        <define name="_X86_" />
        <file switches="-o">svcctl.idl</file>
 </module>
+<module name="eventlog_server" type="rpcserver">
+       <include base="ReactOS">.</include>
+       <include base="ReactOS">w32api/include</include>
+       <define name="_X86_" />
+       <file switches="-o">eventlogrpc.idl</file>
+</module>
+<module name="eventlog_client" type="rpcclient">
+       <include base="ReactOS">.</include>
+       <include base="ReactOS">w32api/include</include>
+       <define name="_X86_" />
+       <file switches="-o">eventlogrpc.idl</file>
+</module>
 </group>
 </group>
index 446ded3..ec16837 100644 (file)
@@ -1,46 +1,16 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 2002, 2005 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             services/eventlog/eventlog.c
  * PURPOSE:          Event logging service
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             services/eventlog/eventlog.c
  * PURPOSE:          Event logging service
- * PROGRAMMER:       Eric Kohl
+ * PROGRAMMERS:      Saveliy Tretiakov (saveliyt@mail.ru)
+ *                   Eric Kohl  
  */
 
  */
 
-/* INCLUDES *****************************************************************/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
 
 #include "eventlog.h"
 
 
 #include "eventlog.h"
 
-#define NDEBUG
-#include <debug.h>
-
-
-VOID CALLBACK
-ServiceMain(DWORD argc, LPTSTR *argv);
-
-
-/* GLOBALS ******************************************************************/
+VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv);
 
 SERVICE_TABLE_ENTRY ServiceTable[2] =
 {
 
 SERVICE_TABLE_ENTRY ServiceTable[2] =
 {
@@ -48,36 +18,194 @@ SERVICE_TABLE_ENTRY ServiceTable[2] =
   {NULL, NULL}
 };
 
   {NULL, NULL}
 };
 
+HANDLE MyHeap = NULL;
+PLOGFILE SystemLog = NULL;
 
 
-/* FUNCTIONS *****************************************************************/
-
-
-VOID CALLBACK
-ServiceMain(DWORD argc, LPTSTR *argv)
+VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv)
 {
 {
-  DPRINT("ServiceMain() called\n");
+    HANDLE hThread;
+
+    hThread = CreateThread(NULL,
+                           0,
+                           (LPTHREAD_START_ROUTINE)
+                            PortThreadRoutine,
+                           NULL,
+                           0,
+                           NULL);
+    
+    if(!hThread) DPRINT("Can't create PortThread\n");
+    else CloseHandle(hThread);
+    
+    hThread = CreateThread(NULL,
+                           0,
+                           (LPTHREAD_START_ROUTINE)
+                            RpcThreadRoutine,
+                           NULL,
+                           0,
+                           NULL);
+
+    if(!hThread) DPRINT("Can't create RpcThread\n");
+    else CloseHandle(hThread);
+}
 
 
-  if (StartPortThread() == FALSE)
-    {
-      DPRINT("StartPortThread() failed\n");
-    }
 
 
-  DPRINT("ServiceMain() done\n");
+int main(int argc, char *argv[])
+{
+       WCHAR SysLogPath[MAX_PATH];
+       MyHeap = HeapCreate(0, 1024*256, 0);
+
+       if(MyHeap==NULL)
+       {
+               DbgPrint("EventLog: FATAL ERROR, can't create heap.\n");
+               return 1;
+       }
+       
+       /*
+       This will be fixed in near future
+        */
+       
+       GetWindowsDirectory(SysLogPath, MAX_PATH);
+       lstrcat(SysLogPath, L"\\system32\\config\\SysEvent.evt");
+
+       SystemLog = LogfCreate(L"System", SysLogPath);
+
+       if(SystemLog == NULL)
+       {
+               DbgPrint("EventLog: FATAL ERROR, can't create %S\n", SysLogPath);
+               HeapDestroy(MyHeap);
+               return 1;
+       }
+
+    StartServiceCtrlDispatcher(ServiceTable);
+
+       LogfClose(SystemLog);
+       HeapDestroy(MyHeap);
+
+    return 0;
 }
 
 }
 
+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);
+}
 
 
-int
-main(int argc, char *argv[])
+VOID SystemTimeToEventTime(SYSTEMTIME *pSystemTime,
+                                                  DWORD *pEventTime)
 {
 {
-  DPRINT("main() called\n");
+       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 = (Time.ll - u1970.ll) / 10000000; 
+}
 
 
-  StartServiceCtrlDispatcher(ServiceTable);
+VOID PRINT_HEADER(PFILE_HEADER header)
+{
+       DPRINT("SizeOfHeader=%d\n",header->SizeOfHeader);
+       DPRINT("Signature=0x%x\n",header->Signature);
+       DPRINT("MajorVersion=%d\n",header->MajorVersion);
+       DPRINT("MinorVersion=%d\n",header->MinorVersion);
+       DPRINT("FirstRecordOffset=%d\n",header->FirstRecordOffset);
+       DPRINT("EofOffset=0x%x\n",header->EofOffset);
+       DPRINT("NextRecord=%d\n",header->NextRecord);
+       DPRINT("OldestRecord=%d\n",header->OldestRecord);
+       DPRINT("unknown1=0x%x\n",header->unknown1);
+       DPRINT("unknown2=0x%x\n",header->unknown2);
+       DPRINT("SizeOfHeader2=%d\n",header->SizeOfHeader2);
+       DPRINT("Flags: ");
+       if(header->Flags & LOGFILE_FLAG1)DPRINT("LOGFILE_FLAG1 ");
+       if(header->Flags & LOGFILE_FLAG2)DPRINT("| LOGFILE_FLAG2 ");
+       if(header->Flags & LOGFILE_FLAG3)DPRINT("| LOGFILE_FLAG3 ");
+       if(header->Flags & LOGFILE_FLAG4)DPRINT("| LOGFILE_FLAG4");
+       DPRINT("\n"); 
+}
 
 
-  DPRINT("main() done\n");
+VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
+{
+       UINT i;
+       WCHAR *str;
+       SYSTEMTIME time;
+       
+       DPRINT("Length=%d\n", pRec->Length );
+       DPRINT("Reserved=0x%x\n", pRec->Reserved );
+       DPRINT("RecordNumber=%d\n", pRec->RecordNumber );
+       
+       EventTimeToSystemTime(pRec->TimeGenerated, &time);
+       DPRINT("TimeGenerated=%d.%d.%d %d:%d:%d\n", 
+                       time.wDay, time.wMonth, time.wYear,
+                       time.wHour, time.wMinute, time.wSecond);
+
+       EventTimeToSystemTime(pRec->TimeWritten, &time);  
+       DPRINT("TimeWritten=%d.%d.%d %d:%d:%d\n", 
+                       time.wDay, time.wMonth, time.wYear,
+                       time.wHour, time.wMinute, time.wSecond);
+
+       DPRINT("EventID=%d\n", pRec->EventID ); 
+
+       switch(pRec->EventType)
+       {
+               case EVENTLOG_ERROR_TYPE:
+                       DPRINT("EventType = EVENTLOG_ERROR_TYPE\n");
+                       break;
+               case EVENTLOG_WARNING_TYPE:
+                       DPRINT("EventType = EVENTLOG_WARNING_TYPE\n");
+                       break;
+               case EVENTLOG_INFORMATION_TYPE:
+                       DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n");
+                       break;
+               case EVENTLOG_AUDIT_SUCCESS:
+                       DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n");
+                       break;
+               case EVENTLOG_AUDIT_FAILURE:
+                       DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n");
+                       break;
+               default:
+                       DPRINT("EventType = %x\n");
+       }       
+
+       DPRINT("NumStrings=%d\n",  pRec->NumStrings );
+       DPRINT("EventCategory=%d\n",  pRec->EventCategory); 
+       DPRINT("ReservedFlags=0x%x\n", pRec->ReservedFlags);
+       DPRINT("ClosingRecordNumber=%d\n", pRec->ClosingRecordNumber);
+       DPRINT("StringOffset=%d\n", pRec->StringOffset); 
+       DPRINT("UserSidLength=%d\n", pRec->UserSidLength);  
+       DPRINT("UserSidOffset=%d\n", pRec->UserSidOffset); 
+       DPRINT("DataLength=%d\n", pRec->DataLength); 
+       DPRINT("DataOffset=%d\n", pRec->DataOffset); 
+
+       DPRINT("SourceName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)));
+       i = (lstrlenW((WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)))+1)*sizeof(WCHAR);
+       DPRINT("ComputerName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)+i));
+       
+       if(pRec->StringOffset < pRec->Length && pRec->NumStrings){
+               DPRINT("Strings:\n");
+               str = (WCHAR*)(((PBYTE)pRec)+pRec->StringOffset);
+               for(i = 0; i < pRec->NumStrings; i++)
+               {
+                       DPRINT("[%d] %S\n", i, str);
+                       str = str+lstrlenW(str)+1;
+               }
+       }
+
+       DPRINT("Length2=%d\n", *(PDWORD)(((PBYTE)pRec)+pRec->Length-4));
+}
 
 
-  ExitThread(0);
 
 
-  return 0;
-}
 
 
-/* EOF */
index 965d90d..4ecb0f2 100644 (file)
-
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS
+ * FILE:        eventlog.h
+ * PURPOSE:     Event logging service
+ * PROGRAMMER:  Saveliy Tretiakov (saveliyt@mail.ru)
+ */
 #ifndef __EVENTLOG_H__
 #define __EVENTLOG_H__
 
 #ifndef __EVENTLOG_H__
 #define __EVENTLOG_H__
 
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+#include <debug.h>
+#include "eventlogrpc_s.h"
+
 typedef struct _IO_ERROR_LPC
 {
     PORT_MESSAGE Header;
     IO_ERROR_LOG_MESSAGE Message;
 } IO_ERROR_LPC, *PIO_ERROR_LPC;
 
 typedef struct _IO_ERROR_LPC
 {
     PORT_MESSAGE Header;
     IO_ERROR_LOG_MESSAGE Message;
 } IO_ERROR_LPC, *PIO_ERROR_LPC;
 
-BOOL
-StartPortThread(VOID);
+#define LOGHANDLE unsigned char*
+#define PLOGHANDLE int* 
+
+#define MAJORVER 1
+#define MINORVER 1
+
+/*
+ *  Our file format will be compatible with NT's
+ */
+
+#define LOGFILE_SIGNATURE 0x654c664c 
+
+/*  
+ *  FIXME
+ *  Flags used in logfile header
+ */
+#define LOGFILE_FLAG1 1
+#define LOGFILE_FLAG2 2
+#define LOGFILE_FLAG3 4
+#define LOGFILE_FLAG4 8
+
+typedef struct {
+       DWORD SizeOfHeader;
+       DWORD Signature;
+       DWORD MajorVersion;
+       DWORD MinorVersion;
+       DWORD FirstRecordOffset;
+       DWORD EofOffset;
+       DWORD NextRecord;
+       DWORD OldestRecord;
+       DWORD unknown1;
+       DWORD Flags;
+       DWORD unknown2; 
+       DWORD SizeOfHeader2; 
+} FILE_HEADER, *PFILE_HEADER;
+
+typedef struct {
+       DWORD Size1;
+       DWORD Ones; // Must be 0x11111111
+       DWORD Twos; // Must be 0x22222222
+       DWORD Threes; // Must be 0x33333333
+       DWORD Fours; // Must be 0x44444444
+       DWORD StartOffset;
+       DWORD EndOffset;
+       DWORD NextRecordNumber;
+       DWORD OldestRecordNumber;
+       DWORD Size2;
+} EOF_RECORD, *PEOF_RECORD;
+
+typedef struct {
+       ULONG EventNumber;
+       ULONG EventOffset;
+} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
+
+typedef struct {
+       HANDLE hFile;
+       FILE_HEADER Header;
+       WCHAR *LogName;
+       WCHAR *FileName;
+    CRITICAL_SECTION cs;
+       PEVENT_OFFSET_INFO OffsetInfo;
+       ULONG OffsetInfoSize;
+       ULONG OffsetInfoNext;
+       PVOID Next;
+       PVOID Prev;
+} LOGFILE, *PLOGFILE;
+
+
+/* file.c */
+PLOGFILE LogfListHead();
+
+INT LogfListItemCount();
+
+PLOGFILE LogfListItemByIndex(INT Index);
+
+PLOGFILE LogfListItemByName(WCHAR *Name);
+
+VOID LogfListAddItem(PLOGFILE Item);
+
+VOID LogfListRemoveItem(PLOGFILE Item);
+
+BOOL LogfReadEvent(PLOGFILE LogFile,
+                   DWORD Flags,
+                   DWORD RecordNumber,
+                   DWORD BufSize,
+                   PBYTE Buffer,
+                   DWORD *BytesRead,
+                   DWORD *BytesNeeded);
+
+BOOL LogfWriteData(PLOGFILE LogFile,
+                    DWORD BufSize,
+                    PBYTE Buffer);
+
+PLOGFILE LogfCreate(WCHAR *LogName, 
+                    WCHAR *FileName);
+
+VOID LogfClose(PLOGFILE LogFile);
+
+BOOL LogfInitializeNew(PLOGFILE LogFile);
+
+BOOL LogfInitializeExisting(PLOGFILE LogFile);
+
+DWORD LogfGetOldestRecord(PLOGFILE LogFile);
+
+ULONG LogfOffsetByNumber(PLOGFILE LogFile,
+                                                DWORD RecordNumber);
+
+BOOL LogfAddOffsetInformation(PLOGFILE LogFile, 
+                                                         ULONG ulNumber,
+                                                         ULONG ulOffset);
+
+DWORD LogfBuildNewRecord(PBYTE Buffer, 
+                                                DWORD dwRecordNumber,
+                                                WORD wType,
+                                                WORD wCategory,
+                                                DWORD dwEventId,
+                                                LPCWSTR SourceName,
+                                                LPCWSTR ComputerName,
+                                                DWORD dwSidLength,
+                                                PSID lpUserSid,
+                                                WORD wNumStrings,
+                                                WCHAR *lpStrings,
+                                                DWORD dwDataSize,
+                                                LPVOID lpRawData);
+
+/* eventlog.c */
+VOID PRINT_HEADER(PFILE_HEADER header);
+
+VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
+
+VOID EventTimeToSystemTime(DWORD EventTime, 
+                                                  SYSTEMTIME *SystemTime);
+
+VOID SystemTimeToEventTime(SYSTEMTIME *pSystemTime,
+                                                  DWORD *pEventTime);
+
+/* logport.c */
+NTSTATUS STDCALL PortThreadRoutine(PVOID Param);
+
+NTSTATUS InitLogPort(VOID);
+
+NTSTATUS ProcessPortMessage(VOID);
+
+/* rpc.c */
+DWORD STDCALL RpcThreadRoutine(LPVOID lpParameter);
+
+NTSTATUS EventLogClearW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       wchar_t *BackupName);
+
+NTSTATUS EventLogBackupW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       wchar_t *FileName);
+
+NTSTATUS EventLogClose(
+       handle_t BindingHandle,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogUnregSrc(
+       handle_t BindingHandle,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogRecordsNumber(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long *RecordsNumber);
+
+NTSTATUS EventLogGetOldestRec(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long *OldestRecNumber);
+
+NTSTATUS Unknown6(handle_t BindingHandle);
+
+NTSTATUS EventLogOpenW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *FileName, 
+       wchar_t *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogRegSrcW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *LogName, 
+       wchar_t *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogOpenBackupW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *BackupName, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogReadW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Flags,
+       unsigned long Offset,
+       unsigned long BufSize,
+       unsigned char *Buffer,
+       unsigned long *BytesRead,
+       unsigned long *BytesNeeded);
+
+NTSTATUS EventLogReportEventW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Time,
+       unsigned short Type,
+       unsigned short Category,
+       unsigned long ID,
+       unsigned short NumStrings,
+       unsigned long DataSize,
+       wchar_t *ComputerName,
+       unsigned char *SID,
+       wchar_t *Strings,
+       unsigned char *Data,
+       unsigned short Flags);
+
+NTSTATUS EventLogClearA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       char *BackupName);
+
+NTSTATUS EventLogBackupA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       char *BackupName);
+
+NTSTATUS EventLogOpenA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *LogName, 
+       char *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogRegSrcA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *LogName, 
+       char *NullStr,
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogOpenBackupA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *BackupName, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle);
+
+NTSTATUS EventLogReadA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Flags,
+       unsigned long Offset,
+       unsigned long BufSize,
+       unsigned char *Buffer,
+       unsigned long *BytesRead,
+       unsigned long *BytesNeeded);
+
+NTSTATUS EventLogReportEventA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Time,
+       unsigned short Type,
+       unsigned short Category,
+       unsigned long ID,
+       unsigned short NumStrings,
+       unsigned long DataSize,
+       char *ComputerName,
+       unsigned char *SID,
+       char* Strings,
+       unsigned char *Data,
+       unsigned short Flags);
+
+NTSTATUS Unknown19(handle_t BindingHandle);
+
+NTSTATUS Unknown20(handle_t BindingHandle);
+
+NTSTATUS Unknown21(handle_t BindingHandle);
+
+NTSTATUS EventLogGetInfo(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long InfoLevel,
+       unsigned char *Buffer,
+       unsigned long BufSize,
+       unsigned long *BytesNeeded);
+
 
 
 #endif /* __EVENTLOG_H__ */
 
 
 
 #endif /* __EVENTLOG_H__ */
 
-/* EOF */
index 5d5c9ec..4742091 100644 (file)
@@ -1,12 +1,17 @@
 <module name="eventlog" type="win32cui" installbase="system32" installname="eventlog.exe">
        <include base="eventlog">.</include>
 <module name="eventlog" type="win32cui" installbase="system32" installname="eventlog.exe">
        <include base="eventlog">.</include>
+       <include base="eventlog_server">.</include>
        <define name="UNICODE" />
        <define name="_UNICODE" />
        <define name="__USE_W32API" />
        <library>ntdll</library>
        <library>kernel32</library>
        <library>advapi32</library>
        <define name="UNICODE" />
        <define name="_UNICODE" />
        <define name="__USE_W32API" />
        <library>ntdll</library>
        <library>kernel32</library>
        <library>advapi32</library>
+       <library>eventlog_server</library>
+       <library>rpcrt4</library>
        <file>eventlog.c</file>
        <file>logport.c</file>
        <file>eventlog.rc</file>
        <file>eventlog.c</file>
        <file>logport.c</file>
        <file>eventlog.rc</file>
+       <file>rpc.c</file>
+       <file>file.c</file>
 </module>
 </module>
diff --git a/reactos/services/eventlog/file.c b/reactos/services/eventlog/file.c
new file mode 100644 (file)
index 0000000..351291c
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS
+ * FILE:             services/eventlog/file.c
+ * PURPOSE:          Event logging service
+ * PROGRAMMER:       Saveliy Tretiakov (saveliyt@mail.ru)
+ */
+#include "eventlog.h"
+
+PLOGFILE _LogListHead = NULL;
+extern HANDLE MyHeap;
+
+BOOL LogfInitializeNew(PLOGFILE LogFile)
+{
+    DWORD dwWritten;
+       EOF_RECORD EofRec;
+    
+    ZeroMemory(&LogFile->Header, sizeof(FILE_HEADER));
+       SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
+       SetEndOfFile(LogFile->hFile);
+       
+       LogFile->Header.SizeOfHeader = sizeof(FILE_HEADER);
+       LogFile->Header.SizeOfHeader2 = sizeof(FILE_HEADER);
+       LogFile->Header.FirstRecordOffset = sizeof(FILE_HEADER);
+       LogFile->Header.EofOffset = sizeof(FILE_HEADER);
+       LogFile->Header.MajorVersion = MAJORVER;
+       LogFile->Header.MinorVersion = MINORVER;
+       LogFile->Header.NextRecord = 1;
+
+       LogFile->Header.Signature = LOGFILE_SIGNATURE;
+       WriteFile(LogFile->hFile,
+                         &LogFile->Header,
+                         sizeof(FILE_HEADER),
+                         &dwWritten,
+                         NULL);
+
+       EofRec.Ones = 0x11111111;
+       EofRec.Twos = 0x22222222;
+       EofRec.Threes = 0x33333333;
+       EofRec.Fours = 0x44444444;
+       EofRec.Size1 = sizeof(EOF_RECORD);
+       EofRec.Size2 = sizeof(EOF_RECORD);
+       EofRec.NextRecordNumber = LogFile->Header.NextRecord;
+       EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
+       EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
+       EofRec.EndOffset = LogFile->Header.EofOffset;
+
+       WriteFile(LogFile->hFile, &EofRec, sizeof(EOF_RECORD), &dwWritten, NULL);
+
+       FlushFileBuffers(LogFile->hFile);
+      
+    return TRUE;
+}
+
+BOOL LogfInitializeExisting(PLOGFILE LogFile)
+{
+       DWORD dwRead;
+       DWORD dwRecordsNumber = 0;
+       DWORD dwRecSize, dwRecSign, dwFilePointer;
+       PDWORD pdwRecSize2;
+       PEVENTLOGRECORD RecBuf;
+
+       SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
+       ReadFile(LogFile->hFile, 
+             &LogFile->Header, 
+             sizeof(FILE_HEADER), 
+             &dwRead, NULL);
+             
+       if(dwRead != sizeof(FILE_HEADER))
+       {
+               DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
+               return LogfInitializeNew(LogFile);
+    }
+    
+       if(LogFile->Header.SizeOfHeader != sizeof(FILE_HEADER) ||
+               LogFile->Header.SizeOfHeader2 != sizeof(FILE_HEADER))
+       {
+               DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
+               return LogfInitializeNew(LogFile);
+    }
+    
+    if(LogFile->Header.Signature != LOGFILE_SIGNATURE)
+    {
+        DPRINT("EventLog: Invalid signature %x in %S.\n", 
+               LogFile->Header.Signature,
+               LogFile->FileName);
+        return LogfInitializeNew(LogFile);
+    }
+
+       if(LogFile->Header.EofOffset > GetFileSize(LogFile->hFile, NULL)+1)
+       {
+        DPRINT("EventLog: Invalid eof offset %x in %S.\n", 
+               LogFile->Header.EofOffset,
+               LogFile->FileName);
+        return LogfInitializeNew(LogFile);
+       }
+
+       for(;;)
+       {
+               dwFilePointer = SetFilePointer(LogFile->hFile, 
+                                                                          0, 
+                                                                          NULL, 
+                                                                          FILE_CURRENT);
+
+               ReadFile(LogFile->hFile, 
+                                &dwRecSize, 
+                                sizeof(dwRecSize), 
+                                &dwRead, 
+                                NULL);
+
+               if(dwRead != sizeof(dwRecSize))
+                       break;
+
+               ReadFile(LogFile->hFile,
+                                &dwRecSign,
+                                sizeof(dwRecSign),
+                                &dwRead,
+                                NULL);
+               
+               if(dwRead != sizeof(dwRecSize))
+                       break;
+               
+               if(dwRecSign != LOGFILE_SIGNATURE ||
+                  dwRecSize + dwFilePointer > GetFileSize(LogFile->hFile, NULL)+1 ||
+                  dwRecSize < sizeof(EVENTLOGRECORD))
+               {
+                       break;
+               }
+               
+               SetFilePointer(LogFile->hFile, -((LONG)sizeof(DWORD)*2), NULL, FILE_CURRENT);
+               RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
+               ReadFile(LogFile->hFile,
+                                RecBuf,
+                                dwRecSize,
+                                &dwRead,
+                                NULL);         
+               
+               if(dwRead !=  dwRecSize)
+               {
+                       HeapFree(MyHeap, 0, RecBuf);
+                       break;
+               }
+
+               pdwRecSize2 = (PDWORD)(((PBYTE)RecBuf)+dwRecSize-4);
+               if(*pdwRecSize2 != dwRecSize)
+               {
+                       DPRINT("EventLog: Invalid size2 of record %d (%x) in %s\n", 
+                               dwRecordsNumber,
+                               *pdwRecSize2,
+                               LogFile->LogName);
+                       HeapFree(MyHeap, 0, RecBuf);
+                       break;
+               }
+
+               dwRecordsNumber++;
+               
+               if(!LogfAddOffsetInformation(LogFile, RecBuf->RecordNumber, dwFilePointer))
+               {
+                       HeapFree(MyHeap, 0, RecBuf);
+                       return FALSE;
+               }
+
+               HeapFree(MyHeap, 0, RecBuf);
+       }//for(;;)
+
+       LogFile->Header.NextRecord = dwRecordsNumber+1;
+       LogFile->Header.OldestRecord = dwRecordsNumber ? 1 : 0; //FIXME
+
+       SetFilePointer(LogFile->hFile, 0, 0, FILE_CURRENT);
+       WriteFile(LogFile->hFile,
+                         &LogFile->Header,
+                         sizeof(FILE_HEADER),
+                         &dwRead, 
+                         NULL);
+       FlushFileBuffers(LogFile->hFile);
+       
+       return TRUE;
+}
+
+PLOGFILE LogfCreate(WCHAR *LogName, 
+                    WCHAR *FileName)
+{
+    PLOGFILE LogFile;
+       BOOL bResult, bCreateNew = FALSE;
+    
+    LogFile = HeapAlloc(MyHeap, 
+                        HEAP_ZERO_MEMORY, 
+                        sizeof(LOGFILE));
+    if(!LogFile)
+    {
+        DbgPrint("EventLog: Can't allocate heap\n");
+        return NULL;
+    }
+    
+    LogFile->hFile = CreateFile(FileName, 
+                                GENERIC_READ | GENERIC_WRITE, 
+                                FILE_SHARE_READ, 
+                                NULL, 
+                                OPEN_ALWAYS,
+                                FILE_ATTRIBUTE_NORMAL | 
+                                FILE_FLAG_RANDOM_ACCESS,
+                                NULL);
+       
+    if(LogFile->hFile == INVALID_HANDLE_VALUE)
+    {
+               DbgPrint("EventLog: Can't open file %S.\n", FileName);
+        HeapFree(MyHeap, 0, LogFile); 
+               return NULL;
+       }
+       
+       bCreateNew = GetLastError() == ERROR_ALREADY_EXISTS ? FALSE : TRUE;
+       
+       LogFile->LogName = HeapAlloc(MyHeap,
+                                    HEAP_ZERO_MEMORY,
+                                    (lstrlenW(LogName)+1)*sizeof(WCHAR));
+    if(LogFile->LogName)
+               lstrcpyW(LogFile->LogName, LogName);
+       else 
+       {
+               DPRINT("EventLog: Can't allocate heap\n");
+               HeapFree(MyHeap, 0, LogFile);
+               return NULL;
+       }
+    
+       LogFile->FileName = HeapAlloc(MyHeap,
+                                    HEAP_ZERO_MEMORY,
+                                    (lstrlenW(FileName)+1)*sizeof(WCHAR));
+    if(LogFile->FileName)
+               lstrcpyW(LogFile->FileName, FileName);
+       else
+       {
+               DPRINT("EventLog: Can't allocate heap\n");
+               HeapFree(MyHeap, 0, LogFile->LogName);
+               HeapFree(MyHeap, 0, LogFile);
+               return NULL;
+       }
+
+
+       LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) 
+               HeapAlloc(MyHeap, 
+                                 HEAP_ZERO_MEMORY,
+                                 sizeof(EVENT_OFFSET_INFO)*64);
+
+       if(!LogFile->OffsetInfo)
+       {
+               DPRINT("EventLog: Can't allocate heap\n");
+               HeapFree(MyHeap, 0, LogFile->FileName);
+               HeapFree(MyHeap, 0, LogFile->LogName);
+               HeapFree(MyHeap, 0, LogFile);
+               return NULL;
+       }
+
+       LogFile->OffsetInfoSize = 64;
+
+       if(bCreateNew)
+               bResult = LogfInitializeNew(LogFile);
+       else bResult = LogfInitializeExisting(LogFile);
+
+       if(!bResult)
+       {
+               HeapFree(MyHeap, 0, LogFile->OffsetInfo);
+               HeapFree(MyHeap, 0, LogFile->FileName);
+               HeapFree(MyHeap, 0, LogFile->LogName);
+               HeapFree(MyHeap, 0, LogFile);
+               return NULL;
+       }
+    
+    InitializeCriticalSection(&LogFile->cs);
+    LogfListAddItem(LogFile);
+    return LogFile;
+}
+
+VOID LogfClose(PLOGFILE LogFile)
+{
+       if(LogFile == NULL)
+               return;
+
+    EnterCriticalSection(&LogFile->cs);
+    
+    FlushFileBuffers(LogFile->hFile);
+    CloseHandle(LogFile->hFile);
+    
+    LogfListRemoveItem(LogFile);
+    DeleteCriticalSection(&LogFile->cs);
+    
+    HeapFree(MyHeap, 0, LogFile->LogName);
+    HeapFree(MyHeap, 0, LogFile->FileName);
+       HeapFree(MyHeap, 0, LogFile->OffsetInfo);
+    HeapFree(MyHeap, 0, LogFile);
+    
+    return;
+}
+
+PLOGFILE LogfListHead()
+{
+    return _LogListHead;
+}
+
+PLOGFILE LogfListItemByName(WCHAR *Name)
+{
+    PLOGFILE Item;
+    Item = LogfListHead();
+    while(Item)
+    {
+        if(Item->LogName && lstrcmpW(Item->LogName, Name)==0)
+            return Item;
+        Item = (PLOGFILE)Item->Next;
+    }
+    return NULL;
+}
+
+PLOGFILE LogfListItemByIndex(INT Index)
+{
+    INT i = 0;
+    PLOGFILE Item;
+    Item = LogfListHead();
+    while(Item)
+    {
+        if(i == Index) 
+            return Item;
+        i++;
+        Item = (PLOGFILE)Item->Next;
+    }
+    return NULL;
+}
+
+INT LogfListItemCount()
+{
+    PLOGFILE Item = NULL;
+    INT i = 1;
+    Item = LogfListHead();
+    if(Item)
+    { 
+        while(Item->Next)
+        {
+            i++;
+            Item = (PLOGFILE) Item->Next;
+        }
+        return i;
+    }
+    else return 0;
+}
+
+VOID LogfListAddItem(PLOGFILE Item)
+{
+    PLOGFILE List;
+       
+       List = LogfListHead();
+    
+       if(List)
+    {
+        while(List->Next) 
+            List = (PLOGFILE)List->Next;
+        Item->Prev = (PVOID)List;
+        Item->Next = NULL;
+        InterlockedExchange((PLONG)&List->Next, (LONG)Item);
+    }
+    else {
+        Item->Next = NULL;
+        Item->Prev = NULL;
+        InterlockedExchange((PLONG)&_LogListHead, (LONG)Item);
+    }
+}
+
+VOID LogfListRemoveItem(PLOGFILE Item)
+{
+    if(Item->Prev)
+    {
+        InterlockedExchange((PLONG)&((PLOGFILE)Item->Prev)->Next,
+                            (LONG)Item->Next);
+    }
+    else {
+        InterlockedExchange((PLONG)&_LogListHead, (LONG)Item->Next);
+    }
+}
+
+BOOL LogfReadEvent(PLOGFILE LogFile,
+                   DWORD Flags,
+                   DWORD RecordNumber,
+                   DWORD BufSize,
+                   PBYTE Buffer,
+                   DWORD *BytesRead,
+                   DWORD *BytesNeeded)
+{
+       DWORD dwOffset, dwRead, dwRecSize;
+       DWORD dwBufferUsage = 0, dwRecNum;
+
+       if(Flags & EVENTLOG_FORWARDS_READ &&
+          Flags & EVENTLOG_BACKWARDS_READ)
+       {
+               return FALSE;
+       }
+
+       if(!(Flags & EVENTLOG_FORWARDS_READ) &&
+               !(Flags & EVENTLOG_BACKWARDS_READ))
+       {
+               return FALSE;
+       }
+
+       if(!Buffer || !BytesRead || !BytesNeeded)
+       {
+               return FALSE;
+       }
+       
+       dwRecNum = RecordNumber;
+       EnterCriticalSection(&LogFile->cs);
+       dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
+       
+       if(!dwOffset)
+       {
+               LeaveCriticalSection(&LogFile->cs);
+               return FALSE;
+       }
+
+       SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN);
+       ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL);
+       if(dwRecSize > BufSize)
+       {
+               *BytesRead = 0;
+               *BytesNeeded = dwRecSize;
+               SetLastError(ERROR_INSUFFICIENT_BUFFER);
+               LeaveCriticalSection(&LogFile->cs);
+               return FALSE;
+       }
+
+       SetFilePointer(LogFile->hFile, 
+                                  -((LONG)sizeof(DWORD)), 
+                                  NULL, 
+                                  FILE_CURRENT);
+
+       ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL);
+       dwBufferUsage+=dwRead;
+
+       while(dwBufferUsage<BufSize)
+       {
+               if(Flags & EVENTLOG_FORWARDS_READ)
+                       dwRecNum++;
+               else dwRecNum--;
+
+               dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
+               if(!dwOffset) break;
+
+               SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN);
+               ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL);
+               if(dwBufferUsage+dwRecSize>BufSize)break;
+
+               SetFilePointer(LogFile->hFile, 
+                                          -((LONG)sizeof(DWORD)),
+                                          NULL,
+                                          FILE_CURRENT);
+               
+               ReadFile(LogFile->hFile, 
+                                Buffer+dwBufferUsage,
+                                dwRecSize,
+                                &dwRead,
+                                NULL);
+
+               dwBufferUsage+=dwRead;
+       }
+
+       *BytesRead = dwBufferUsage;
+       LeaveCriticalSection(&LogFile->cs);
+       return TRUE;
+}
+
+BOOL LogfWriteData(PLOGFILE LogFile,
+                    DWORD BufSize,
+                    PBYTE Buffer)
+{
+       DWORD dwWritten;
+       SYSTEMTIME st;
+       EOF_RECORD EofRec;
+       BOOL bResult;
+
+       if(!Buffer)
+       {
+               return FALSE;
+       }
+
+       GetSystemTime(&st);
+       SystemTimeToEventTime(&st, &((PEVENTLOGRECORD)Buffer)->TimeWritten);
+       
+       EnterCriticalSection(&LogFile->cs);
+
+       SetFilePointer(LogFile->hFile, LogFile->Header.EofOffset, NULL, FILE_BEGIN);
+       WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL);
+
+       if(BufSize != dwWritten)
+       {
+               LeaveCriticalSection(&LogFile->cs);
+               return FALSE;
+       }
+
+       if(!LogfAddOffsetInformation(LogFile, 
+                       LogFile->Header.NextRecord, 
+                       LogFile->Header.EofOffset))
+       {
+               LeaveCriticalSection(&LogFile->cs);
+               return FALSE;
+       }
+
+       LogFile->Header.NextRecord++;
+       LogFile->Header.EofOffset += dwWritten;
+       
+       if(LogFile->Header.OldestRecord == 0)
+               LogFile->Header.OldestRecord = 1;
+
+       EofRec.Ones = 0x11111111;
+       EofRec.Twos = 0x22222222;
+       EofRec.Threes = 0x33333333;
+       EofRec.Fours = 0x44444444;
+       EofRec.Size1 = sizeof(EOF_RECORD);
+       EofRec.Size2 = sizeof(EOF_RECORD);
+       EofRec.NextRecordNumber = LogFile->Header.NextRecord;
+       EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
+       EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
+       EofRec.EndOffset = LogFile->Header.EofOffset;
+
+       WriteFile(LogFile->hFile, &EofRec, sizeof(EOF_RECORD), &dwWritten, NULL);
+
+       SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
+       bResult = WriteFile(LogFile->hFile, 
+               &LogFile->Header, 
+               sizeof(FILE_HEADER), 
+               &dwWritten, 
+               NULL);
+
+       if(!bResult)
+       {
+               DPRINT("WriteFile failed! LastError = %d\n", GetLastError());
+               LeaveCriticalSection(&LogFile->cs);
+               return FALSE;
+       }
+       
+       if(!FlushFileBuffers(LogFile->hFile))
+               DPRINT("FlushFileBuffers() failed!\n");
+
+       LeaveCriticalSection(&LogFile->cs);
+       return TRUE;
+}    
+
+ULONG LogfOffsetByNumber(PLOGFILE LogFile,
+                                                DWORD RecordNumber)
+/* Returns NULL if nothing found. */
+{
+       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.OldestRecord;
+}
+
+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)
+               {
+                       DbgPrint("EventLog: 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;
+}
+
+DWORD LogfBuildNewRecord(PBYTE Buffer, 
+                                                DWORD dwRecordNumber,
+                                                WORD wType,
+                                                WORD wCategory,
+                                                DWORD dwEventId,
+                                                LPCWSTR SourceName,
+                                                LPCWSTR ComputerName,
+                                                DWORD dwSidLength,
+                                                PSID lpUserSid,
+                                                WORD wNumStrings,
+                                                WCHAR *lpStrings,
+                                                DWORD dwDataSize,
+                                                LPVOID lpRawData)
+{
+       DWORD dwRecSize;
+       PEVENTLOGRECORD pRec;
+       SYSTEMTIME SysTime;
+       WCHAR *str;
+       UINT i, pos, nStrings;
+
+       dwRecSize = sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) + 
+       lstrlenW(SourceName) + 2)*sizeof(WCHAR);
+
+       if(dwRecSize % 4 != 0) dwRecSize += 4 - (dwRecSize % 4);
+       dwRecSize += dwSidLength;
+
+       for(i = 0, str = lpStrings; i < wNumStrings; i++)
+       {
+               dwRecSize += (lstrlenW(str)+1)*sizeof(WCHAR);
+               str += lstrlenW(str)+1;
+       }
+
+       dwRecSize += dwDataSize;
+       if(dwRecSize % 4 != 0) dwRecSize += 4 - (dwRecSize % 4);
+       dwRecSize+=4;
+
+       if(!Buffer)
+       {
+               return dwRecSize;
+       }
+
+       ZeroMemory(Buffer, dwRecSize);
+       pRec = (PEVENTLOGRECORD)Buffer;
+       pRec->Length = dwRecSize;
+       pRec->Reserved = LOGFILE_SIGNATURE;
+       pRec->RecordNumber = dwRecordNumber;
+
+       GetSystemTime(&SysTime);
+       SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
+       SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
+
+       pRec->EventID = dwEventId;
+       pRec->EventType = wType;
+       pRec->NumStrings = wNumStrings;
+       pRec->EventCategory = wCategory;
+
+       pos = sizeof(EVENTLOGRECORD);
+
+       lstrcpyW((WCHAR*)(Buffer+pos), SourceName);
+       pos+=(lstrlenW(SourceName)+1)*sizeof(WCHAR);
+       lstrcpyW((WCHAR*)(Buffer+pos), ComputerName);
+       pos+=(lstrlenW(ComputerName)+1)*sizeof(WCHAR);
+
+       pRec->UserSidOffset = pos;
+       if(dwSidLength)
+       {
+               if(pos % 4 != 0) pos += 4 - (pos % 4);
+               CopyMemory(Buffer+pos, lpUserSid, dwSidLength);
+               pRec->UserSidLength = dwSidLength;
+               pRec->UserSidOffset = pos;
+               pos+=dwSidLength;
+       }
+
+       pRec->StringOffset = pos;
+       for(i = 0, str = lpStrings, nStrings = 0; i < wNumStrings; i++)
+       {
+               lstrcpyW((WCHAR*)(Buffer+pos), str);
+               pos += (lstrlenW(str)+1)*sizeof(WCHAR);
+               str += lstrlenW(str)+1;
+               nStrings++;
+       }
+       pRec->NumStrings = nStrings;
+
+       pRec->DataOffset = pos;
+       if(dwDataSize)
+       {
+               pRec->DataLength = dwDataSize;
+               CopyMemory(Buffer+pos, lpRawData, dwDataSize);
+               pos += dwDataSize;
+       }
+
+       if(pos % 4 != 0) pos += 4 - (pos % 4);
+       *((PDWORD)(Buffer+pos)) = dwRecSize;
+
+       return TRUE;
+}
index a136bc6..b80abb2 100644 (file)
-/*
- *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             services/eventlog/logport.c
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             services/eventlog/logport.c
- * PURPOSE:          Event logger service
+ * PURPOSE:          Event logging service
  * PROGRAMMER:       Eric Kohl
  * PROGRAMMER:       Eric Kohl
+ *                   Saveliy Tretiakov (saveliyt@mail.ru)
  */
 
 /* INCLUDES *****************************************************************/
 
  */
 
 /* INCLUDES *****************************************************************/
 
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
 #include "eventlog.h"
 
 #include "eventlog.h"
 
-#define NDEBUG
-#include <debug.h>
-
-
 /* GLOBALS ******************************************************************/
 
 /* GLOBALS ******************************************************************/
 
-HANDLE PortThreadHandle = NULL;
 HANDLE ConnectPortHandle = NULL;
 HANDLE MessagePortHandle = NULL;
 HANDLE ConnectPortHandle = NULL;
 HANDLE MessagePortHandle = NULL;
+extern PLOGFILE SystemLog;
+extern HANDLE MyHeap;
 
 
 /* FUNCTIONS ****************************************************************/
 
 
 
 /* FUNCTIONS ****************************************************************/
 
-static NTSTATUS
-InitLogPort(VOID)
+NTSTATUS STDCALL PortThreadRoutine(PVOID Param)
 {
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING PortName;
-  PORT_MESSAGE Request;
-  NTSTATUS Status;
-
-  ConnectPortHandle = NULL;
-  MessagePortHandle = NULL;
-
-  RtlInitUnicodeString(&PortName,
-                      L"\\ErrorLogPort");
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &PortName,
-                            0,
-                            NULL,
-                            NULL);
-
-  Status = NtCreatePort(&ConnectPortHandle,
-                       &ObjectAttributes,
-                       0,
-                       0x100,
-                       0x2000);
-  if (!NT_SUCCESS(Status))
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    Status = InitLogPort();
+    if(!NT_SUCCESS(Status))
+        return Status;
+
+    while(NT_SUCCESS(Status))
     {
     {
-      DPRINT1("NtCreatePort() failed (Status %lx)\n", Status);
-      goto ByeBye;
+        Status = ProcessPortMessage();
     }
 
     }
 
-  Status = NtListenPort(ConnectPortHandle,
-                       &Request);
-  if (!NT_SUCCESS(Status))
+    if(ConnectPortHandle != NULL)
+        NtClose(ConnectPortHandle);
+
+    if(MessagePortHandle != NULL)
+        NtClose(MessagePortHandle);
+
+    return Status;
+}
+
+NTSTATUS InitLogPort(VOID)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING PortName;
+    PORT_MESSAGE Request;
+    NTSTATUS Status;
+    
+    ConnectPortHandle = NULL;
+    MessagePortHandle = NULL;
+
+    RtlInitUnicodeString(&PortName, L"\\ErrorLogPort");
+    InitializeObjectAttributes(
+                &ObjectAttributes,
+                &PortName,
+                0,
+                NULL,
+                NULL);
+
+    Status = NtCreatePort(
+                &ConnectPortHandle,
+                &ObjectAttributes,
+                0,
+                0x100,
+                0x2000);
+                
+    if(!NT_SUCCESS(Status))
     {
     {
-      DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
-      goto ByeBye;
+        DPRINT1("NtCreatePort() failed (Status %lx)\n", Status);
+        goto ByeBye;
     }
 
     }
 
-  Status = NtAcceptConnectPort(&MessagePortHandle,
-                              ConnectPortHandle,
-                              NULL,
-                              TRUE,
-                              NULL,
-                              NULL);
-  if (!NT_SUCCESS(Status))
+    Status = NtListenPort(ConnectPortHandle, &Request);
+  
+    if(!NT_SUCCESS(Status))
     {
     {
-      DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
-      goto ByeBye;
+        DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
+        goto ByeBye;
     }
 
     }
 
-  Status = NtCompleteConnectPort(MessagePortHandle);
-  if (!NT_SUCCESS(Status))
+    Status = NtAcceptConnectPort(
+                    &MessagePortHandle,
+                    ConnectPortHandle,
+                    NULL,
+                    TRUE,
+                    NULL,
+                    NULL);
+                    
+    if (!NT_SUCCESS(Status))
     {
     {
-      DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status);
-      goto ByeBye;
+        DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
+        goto ByeBye;
     }
 
     }
 
-ByeBye:
-  if (!NT_SUCCESS(Status))
+    Status = NtCompleteConnectPort(MessagePortHandle);
+    if (!NT_SUCCESS(Status))
     {
     {
-      if (ConnectPortHandle != NULL)
-       NtClose(ConnectPortHandle);
-
-      if (MessagePortHandle != NULL)
-       NtClose(MessagePortHandle);
+        DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status);
+        goto ByeBye;
     }
 
     }
 
-  return Status;
-}
-
-static NTSTATUS
-ProcessPortMessage(VOID)
-{
-  IO_ERROR_LPC Request;
-  PIO_ERROR_LOG_MESSAGE Message;
-//#ifndef NDEBUG
-  ULONG i;
-  PWSTR p;
-//#endif
-  NTSTATUS Status;
-
-
-  DPRINT1("ProcessPortMessage() called\n");
-
-  Status = STATUS_SUCCESS;
-
-  while (TRUE)
+ByeBye:
+    if (!NT_SUCCESS(Status))
     {
     {
-      Status = NtReplyWaitReceivePort(MessagePortHandle,
-                                     0,
-                                     NULL,
-                                     &Request.Header);
-      if (!NT_SUCCESS(Status))
-       {
-         DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
-         break;
-       }
-
-      DPRINT("Received message\n");
-
-      if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED)
-       {
-         DPRINT("Port closed\n");
-
-         return STATUS_SUCCESS;
-       }
-      if (Request.Header.u2.s2.Type == LPC_REQUEST)
-       {
-         DPRINT("Received request\n");
-
-       }
-      else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
-       {
-         DPRINT("Received datagram\n");
-
-
-         Message = (PIO_ERROR_LOG_MESSAGE)&Request.Message;
-
-         DPRINT("Message->Type %hx\n", Message->Type);
-         DPRINT("Message->Size %hu\n", Message->Size);
-
-//#ifndef NDEBUG
-         DbgPrint("\n Error mesage:\n");
-         DbgPrint("Error code: %lx\n", Message->EntryData.ErrorCode);
-         DbgPrint("Retry count: %u\n", Message->EntryData.RetryCount);
-         DbgPrint("Sequence number: %lu\n", Message->EntryData.SequenceNumber);
-
-         if (Message->DriverNameLength != 0)
-           {
-             DbgPrint("Driver name: %.*S\n",
-                      Message->DriverNameLength / sizeof(WCHAR),
-                      (PWCHAR)((ULONG_PTR)Message + Message->DriverNameOffset));
-           }
-
-         if (Message->EntryData.NumberOfStrings != 0)
-           {
-             p = (PWSTR)((ULONG_PTR)&Message->EntryData + Message->EntryData.StringOffset);
-             for (i = 0; i < Message->EntryData.NumberOfStrings; i++)
-               {
-                 DbgPrint("String %lu: %S\n", i, p);
-                 p += wcslen(p) + 1;
-               }
-             DbgPrint("\n");
-           }
-
-//#endif
-
-         /* FIXME: Enqueue message */
-
-       }
-    }
+        if(ConnectPortHandle != NULL)
+            NtClose(ConnectPortHandle);
 
 
-  return Status;
+        if(MessagePortHandle != NULL)
+            NtClose(MessagePortHandle);
+    }
+    return Status;
 }
 
 
 }
 
 
-static NTSTATUS STDCALL
-PortThreadRoutine(PVOID Param)
+NTSTATUS ProcessPortMessage(VOID)
 {
 {
-  NTSTATUS Status = STATUS_SUCCESS;
-
-  Status = InitLogPort();
-  if (!NT_SUCCESS(Status))
-    return Status;
-
-  while (NT_SUCCESS(Status))
+    IO_ERROR_LPC Request;
+    PIO_ERROR_LOG_MESSAGE Message;
+       PEVENTLOGRECORD pRec;
+    ULONG ulRecNum, ulRecSize ;
+    NTSTATUS Status;
+       PLOGFILE SystemLog = NULL;
+    
+    DPRINT1("ProcessPortMessage() called\n");
+
+    Status = STATUS_SUCCESS;
+
+    while(TRUE)
     {
     {
-      Status = ProcessPortMessage();
+        Status = NtReplyWaitReceivePort(
+                        MessagePortHandle,
+                        0,
+                        NULL,
+                        &Request.Header);
+                        
+        if(!NT_SUCCESS(Status))
+        {
+            DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
+            break;
+        }
+
+        DPRINT("Received message\n");
+
+        if(Request.Header.u2.s2.Type == LPC_PORT_CLOSED)
+        {
+            DPRINT("Port closed\n");
+            return STATUS_SUCCESS;
+        }
+      
+        if(Request.Header.u2.s2.Type == LPC_REQUEST)
+        {
+            DPRINT("Received request\n");
+        }
+        else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
+        {
+            DPRINT("Received datagram\n");
+            Message = (PIO_ERROR_LOG_MESSAGE)&Request.Message;
+                       ulRecNum = SystemLog ? SystemLog->Header.NextRecord : 0;
+
+                       ulRecSize = LogfBuildNewRecord(NULL,
+                               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)));
+
+                       DPRINT("ulRecSize = %d\n", ulRecSize);
+
+                       pRec = HeapAlloc(MyHeap, 0, ulRecSize);
+
+                       if(pRec == NULL)
+                       {
+                               DPRINT("Can't allocate heap!\n");
+                               return STATUS_NO_MEMORY;
+                       }
+
+                       LogfBuildNewRecord((PBYTE)pRec,
+                               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)));
+                       
+                       DPRINT("\n --- EVENTLOG RECORD ---\n");
+                       PRINT_RECORD(pRec);
+                       DPRINT("\n");
+                       
+                       if(SystemLog)
+                       {
+                               if(!LogfWriteData(SystemLog, ulRecSize, (PBYTE)pRec))
+                                       DPRINT("LogfWriteData failed!\n");
+                               else DPRINT("Data written to Log!\n");
+                       }
+
+                       HeapFree(MyHeap, 0, pRec);
+        }
     }
     }
-
-  if (ConnectPortHandle != NULL)
-    NtClose(ConnectPortHandle);
-
-  if (MessagePortHandle != NULL)
-    NtClose(MessagePortHandle);
-
-  return Status;
-}
-
-
-BOOL
-StartPortThread(VOID)
-{
-  DWORD ThreadId;
-
-  PortThreadHandle = CreateThread(NULL,
-                                 0x1000,
-                                 (LPTHREAD_START_ROUTINE)PortThreadRoutine,
-                                 NULL,
-                                 0,
-                                 &ThreadId);
-
-  return (PortThreadHandle != NULL);
+    return Status;
 }
 
 }
 
-/* EOF */
diff --git a/reactos/services/eventlog/rpc.c b/reactos/services/eventlog/rpc.c
new file mode 100644 (file)
index 0000000..89ebc2d
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS
+ * FILE:             services/eventlog/rpc.c
+ * PURPOSE:          Event logging service
+ * PROGRAMMER:       Saveliy Tretiakov (savelity@mail.ru)
+ */
+#include "eventlog.h"
+
+DWORD STDCALL RpcThreadRoutine(LPVOID lpParameter)
+{
+    RPC_STATUS Status;
+
+    Status = RpcServerUseProtseqEpW(L"ncacn_np",
+                                    20,
+                                    L"\\pipe\\EventLog",
+                                    NULL);
+    if(Status != RPC_S_OK)
+    {
+        DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
+        return 0;
+    }
+
+    Status = RpcServerRegisterIf(eventlog_ServerIfHandle, NULL, NULL);
+    
+    if(Status != RPC_S_OK)
+    {
+        DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status);
+        return 0;
+    }
+
+    Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
+    
+    if(Status != RPC_S_OK)
+    {
+        DPRINT("RpcServerListen() failed (Status %lx)\n", Status);
+    }
+
+    return 0;
+}
+
+/* Function 0 */
+NTSTATUS EventLogClearW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       wchar_t *BackupName)
+{
+    DPRINT("EventLogClearW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 1 */
+NTSTATUS EventLogBackupW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       wchar_t *FileName)
+{
+    DPRINT("EventLogBackupW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+       
+/* Function 2 */
+NTSTATUS EventLogClose(
+       handle_t BindingHandle,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogClose UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+   
+
+/* Function 3 */
+NTSTATUS EventLogUnregSrc(
+       handle_t BindingHandle,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogUnregSrc UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 4 */
+NTSTATUS EventLogRecordsNumber(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long *RecordsNumber)
+{
+    DPRINT("EventLogRecordsNumber UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 5 */
+NTSTATUS EventLogGetOldestRec(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long *OldestRecNumber)
+{
+    DPRINT("EventLogGetOldestRec UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* FIXME */
+NTSTATUS Unknown6(handle_t BindingHandle)
+{
+    DPRINT("Unknown6() called\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 7 */
+NTSTATUS EventLogOpenW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *FileName, 
+       wchar_t *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogOpenW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+               
+/* Function 8 */
+NTSTATUS EventLogRegSrcW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *LogName, 
+       wchar_t *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogRegSrcW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+               
+/* Function 9 */
+NTSTATUS EventLogOpenBackupW(
+       handle_t BindingHandle,
+       LPWSTR ServerName,
+       wchar_t *BackupName, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogOpenBackupW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 10 */
+NTSTATUS EventLogReadW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Flags,
+       unsigned long Offset,
+       unsigned long BufSize,
+       unsigned char *Buffer,
+       unsigned long *BytesRead,
+       unsigned long *BytesNeeded)
+{
+    DPRINT("EventLogReadW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 11 */
+NTSTATUS EventLogReportEventW(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Time,
+       unsigned short Type,
+       unsigned short Category,
+       unsigned long ID,
+       unsigned short NumStrings,
+       unsigned long DataSize,
+       wchar_t *ComputerName,
+       unsigned char *SID,
+       wchar_t *Strings,
+       unsigned char *Data,
+       unsigned short Flags)
+{
+    DPRINT("EventLogReportEventW UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+               
+/* Function 12 */
+NTSTATUS EventLogClearA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       char *BackupName)
+{
+    DPRINT("EventLogClearA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 13 */
+NTSTATUS EventLogBackupA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       char *BackupName)
+{
+    DPRINT("EventLogBackupA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 14 */
+NTSTATUS EventLogOpenA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *LogName, 
+       char *NullStr, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogOpenA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 15 */
+NTSTATUS EventLogRegSrcA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *LogName, 
+       char *NullStr,
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogRegSrcA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 16 */
+NTSTATUS EventLogOpenBackupA(
+       handle_t BindingHandle,
+       LPSTR ServerName,
+       char *BackupName, 
+       unsigned long MajorVer,
+       unsigned long MinorVer,
+       PLOGHANDLE Handle)
+{
+    DPRINT("EventLogOpenBackupA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 17 */
+NTSTATUS EventLogReadA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Flags,
+       unsigned long Offset,
+       unsigned long BufSize,
+       unsigned char *Buffer,
+       unsigned long *BytesRead,
+       unsigned long *BytesNeeded)
+{
+    DPRINT("EventLogReadA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 18 */
+NTSTATUS EventLogReportEventA(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long Time,
+       unsigned short Type,
+       unsigned short Category,
+       unsigned long ID,
+       unsigned short NumStrings,
+       unsigned long DataSize,
+       char *ComputerName,
+       unsigned char *SID,
+       char* Strings,
+       unsigned char *Data,
+       unsigned short Flags)
+{
+    DPRINT("EventLogReportEventA UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* FIXME */
+NTSTATUS Unknown19(handle_t BindingHandle)
+{
+    DPRINT("Unknown19 called\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+       
+       
+/* FIXME */
+NTSTATUS Unknown20(handle_t BindingHandle)
+{
+    DPRINT("Unknown20 called\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* FIXME */
+NTSTATUS Unknown21(handle_t BindingHandle)
+{
+    DPRINT("Unknown21 called\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Function 22 */
+NTSTATUS EventLogGetInfo(
+       handle_t BindingHandle,
+       LOGHANDLE Handle,
+       unsigned long InfoLevel,
+       unsigned char *Buffer,
+       unsigned long BufSize,
+       unsigned long *BytesNeeded)
+{
+    DPRINT("EventLogGetInfo UNIMPLEMENTED\n");
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
+{
+    HeapFree(GetProcessHeap(), 0, ptr);
+}