Saveliy Tretiakov <saveliyt@mail.ru>:

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
This commit is contained in:
Gé van Geldorp 2005-09-20 07:58:28 +00:00
parent 8528b9b411
commit 7ec5b38020
8 changed files with 1954 additions and 253 deletions

View file

@ -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);
}

View file

@ -23,4 +23,16 @@
<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>

View 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
* 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"
#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] =
{
@ -48,36 +18,194 @@ SERVICE_TABLE_ENTRY ServiceTable[2] =
{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;
if (StartPortThread() == FALSE)
{
DPRINT("StartPortThread() failed\n");
}
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);
DPRINT("ServiceMain() done\n");
if(!hThread) DPRINT("Can't create RpcThread\n");
else CloseHandle(hThread);
}
int
main(int argc, char *argv[])
int main(int argc, char *argv[])
{
DPRINT("main() called\n");
WCHAR SysLogPath[MAX_PATH];
MyHeap = HeapCreate(0, 1024*256, 0);
StartServiceCtrlDispatcher(ServiceTable);
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");
DPRINT("main() done\n");
SystemLog = LogfCreate(L"System", SysLogPath);
ExitThread(0);
if(SystemLog == NULL)
{
DbgPrint("EventLog: FATAL ERROR, can't create %S\n", SysLogPath);
HeapDestroy(MyHeap);
return 1;
}
return 0;
StartServiceCtrlDispatcher(ServiceTable);
LogfClose(SystemLog);
HeapDestroy(MyHeap);
return 0;
}
/* EOF */
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);
}
VOID SystemTimeToEventTime(SYSTEMTIME *pSystemTime,
DWORD *pEventTime)
{
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;
}
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");
}
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));
}

View file

@ -1,17 +1,329 @@
/*
* 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__
#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;
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__ */
/* EOF */

View file

@ -1,12 +1,17 @@
<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>
<library>eventlog_server</library>
<library>rpcrt4</library>
<file>eventlog.c</file>
<file>logport.c</file>
<file>eventlog.rc</file>
<file>rpc.c</file>
<file>file.c</file>
</module>

View file

@ -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;
}

View file

@ -1,243 +1,220 @@
/*
* 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
* PURPOSE: Event logger service
* PURPOSE: Event logging service
* PROGRAMMER: Eric Kohl
* Saveliy Tretiakov (saveliyt@mail.ru)
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include "eventlog.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ******************************************************************/
HANDLE PortThreadHandle = NULL;
HANDLE ConnectPortHandle = NULL;
HANDLE MessagePortHandle = NULL;
extern PLOGFILE SystemLog;
extern HANDLE MyHeap;
/* FUNCTIONS ****************************************************************/
static NTSTATUS
InitLogPort(VOID)
NTSTATUS STDCALL PortThreadRoutine(PVOID Param)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PortName;
PORT_MESSAGE Request;
NTSTATUS Status;
NTSTATUS Status = STATUS_SUCCESS;
Status = InitLogPort();
if(!NT_SUCCESS(Status))
return 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))
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;
}
Status = NtCompleteConnectPort(MessagePortHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status);
goto ByeBye;
}
ByeBye:
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status))
{
if (ConnectPortHandle != NULL)
NtClose(ConnectPortHandle);
if(ConnectPortHandle != NULL)
NtClose(ConnectPortHandle);
if (MessagePortHandle != NULL)
NtClose(MessagePortHandle);
if(MessagePortHandle != NULL)
NtClose(MessagePortHandle);
}
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)
{
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 */
}
}
return Status;
}
static NTSTATUS STDCALL
PortThreadRoutine(PVOID Param)
{
NTSTATUS Status = STATUS_SUCCESS;
Status = InitLogPort();
if (!NT_SUCCESS(Status))
return Status;
while (NT_SUCCESS(Status))
{
Status = ProcessPortMessage();
}
if (ConnectPortHandle != NULL)
NtClose(ConnectPortHandle);
if (MessagePortHandle != NULL)
NtClose(MessagePortHandle);
return Status;
}
BOOL
StartPortThread(VOID)
NTSTATUS ProcessPortMessage(VOID)
{
DWORD ThreadId;
IO_ERROR_LPC Request;
PIO_ERROR_LOG_MESSAGE Message;
PEVENTLOGRECORD pRec;
ULONG ulRecNum, ulRecSize ;
NTSTATUS Status;
PLOGFILE SystemLog = NULL;
DPRINT1("ProcessPortMessage() called\n");
PortThreadHandle = CreateThread(NULL,
0x1000,
(LPTHREAD_START_ROUTINE)PortThreadRoutine,
NULL,
0,
&ThreadId);
Status = STATUS_SUCCESS;
return (PortThreadHandle != NULL);
while(TRUE)
{
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);
}
}
return Status;
}
/* EOF */

View file

@ -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);
}