2 * PROJECT: ReactOS kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: services/eventlog/rpc.c
5 * PURPOSE: Event logging service
6 * COPYRIGHT: Copyright 2005 Saveliy Tretiakov
7 * Copyright 2008 Michael Martin
10 /* INCLUDES *****************************************************************/
14 LIST_ENTRY LogHandleListHead
;
16 /* FUNCTIONS ****************************************************************/
18 DWORD WINAPI
RpcThreadRoutine(LPVOID lpParameter
)
22 InitializeListHead(&LogHandleListHead
);
24 Status
= RpcServerUseProtseqEpW(L
"ncacn_np", 20, L
"\\pipe\\EventLog", NULL
);
25 if (Status
!= RPC_S_OK
)
27 DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
31 Status
= RpcServerRegisterIf(eventlog_v0_0_s_ifspec
, NULL
, NULL
);
32 if (Status
!= RPC_S_OK
)
34 DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
38 Status
= RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, FALSE
);
39 if (Status
!= RPC_S_OK
)
41 DPRINT("RpcServerListen() failed (Status %lx)\n", Status
);
47 PLOGHANDLE
ElfCreateEventLogHandle(LPCWSTR Name
, BOOL Create
)
49 PLOGHANDLE lpLogHandle
;
50 PLOGFILE currentLogFile
= NULL
;
52 PEVENTSOURCE pEventSource
;
54 DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name
);
56 lpLogHandle
= HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE
)
57 + ((wcslen(Name
) + 1) * sizeof(WCHAR
)));
60 DPRINT1("Failed to allocate Heap!\n");
64 wcscpy(lpLogHandle
->szName
, Name
);
66 /* Get the number of Log Files the EventLog service found */
67 LogsActive
= LogfListItemCount();
70 DPRINT1("EventLog service reports no log files!\n");
74 /* If Creating, default to the Application Log in case we fail, as documented on MSDN */
77 pEventSource
= GetEventSourceByName(Name
);
78 DPRINT("EventSource: %p\n", pEventSource
);
81 DPRINT("EventSource LogFile: %p\n", pEventSource
->LogFile
);
82 lpLogHandle
->LogFile
= pEventSource
->LogFile
;
86 DPRINT("EventSource LogFile: Application log file\n");
87 lpLogHandle
->LogFile
= LogfListItemByName(L
"Application");
90 DPRINT("LogHandle LogFile: %p\n", lpLogHandle
->LogFile
);
94 lpLogHandle
->LogFile
= NULL
;
96 for (i
= 1; i
<= LogsActive
; i
++)
98 currentLogFile
= LogfListItemByIndex(i
);
100 if (_wcsicmp(Name
, currentLogFile
->LogName
) == 0)
102 lpLogHandle
->LogFile
= LogfListItemByIndex(i
);
103 lpLogHandle
->CurrentRecord
= LogfGetOldestRecord(lpLogHandle
->LogFile
);
109 if (!lpLogHandle
->LogFile
)
112 /* Append log handle */
113 InsertTailList(&LogHandleListHead
, &lpLogHandle
->LogHandleListEntry
);
118 HeapFree(GetProcessHeap(), 0, lpLogHandle
);
123 PLOGHANDLE
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle
)
125 PLOGHANDLE lpLogHandle
;
127 if (IsListEmpty(&LogHandleListHead
))
132 lpLogHandle
= CONTAINING_RECORD((PLOGHANDLE
)EventLogHandle
, LOGHANDLE
, LogHandleListEntry
);
137 BOOL
ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle
)
139 PLOGHANDLE lpLogHandle
= (PLOGHANDLE
)EventLogHandle
;
140 if (!ElfGetLogHandleEntryByHandle(lpLogHandle
))
145 RemoveEntryList(&lpLogHandle
->LogHandleListEntry
);
146 HeapFree(GetProcessHeap(),0,lpLogHandle
);
152 NTSTATUS
ElfrClearELFW(
153 IELF_HANDLE LogHandle
,
154 PRPC_UNICODE_STRING BackupFileName
)
157 return STATUS_NOT_IMPLEMENTED
;
162 NTSTATUS
ElfrBackupELFW(
163 IELF_HANDLE LogHandle
,
164 PRPC_UNICODE_STRING BackupFileName
)
167 return STATUS_NOT_IMPLEMENTED
;
171 NTSTATUS
ElfrCloseEL(
172 IELF_HANDLE
*LogHandle
)
174 if (!ElfDeleteEventLogHandle(*LogHandle
))
176 return STATUS_INVALID_HANDLE
;
179 return STATUS_SUCCESS
;
184 NTSTATUS
ElfrDeregisterEventSource(
185 IELF_HANDLE
*LogHandle
)
187 if (!ElfDeleteEventLogHandle(*LogHandle
))
189 return STATUS_INVALID_HANDLE
;
192 return STATUS_SUCCESS
;
197 NTSTATUS
ElfrNumberOfRecords(
198 IELF_HANDLE LogHandle
,
199 DWORD
*NumberOfRecords
)
201 PLOGHANDLE lpLogHandle
;
204 lpLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
207 return STATUS_INVALID_HANDLE
;
210 lpLogFile
= lpLogHandle
->LogFile
;
212 if (lpLogFile
->Header
.OldestRecordNumber
== 0)
213 *NumberOfRecords
= 0;
215 *NumberOfRecords
= lpLogFile
->Header
.CurrentRecordNumber
-
216 lpLogFile
->Header
.OldestRecordNumber
;
218 return STATUS_SUCCESS
;
223 NTSTATUS
ElfrOldestRecord(
224 IELF_HANDLE LogHandle
,
225 DWORD
*OldestRecordNumber
)
227 PLOGHANDLE lpLogHandle
;
229 lpLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
232 return STATUS_INVALID_HANDLE
;
235 if (!OldestRecordNumber
)
237 return STATUS_INVALID_PARAMETER
;
240 *OldestRecordNumber
= 0;
241 *OldestRecordNumber
= LogfGetOldestRecord(lpLogHandle
->LogFile
);
242 return STATUS_SUCCESS
;
247 NTSTATUS
ElfrChangeNotify(
248 IELF_HANDLE
*LogHandle
,
249 RPC_CLIENT_ID ClientId
,
253 return STATUS_NOT_IMPLEMENTED
;
258 NTSTATUS
ElfrOpenELW(
259 EVENTLOG_HANDLE_W UNCServerName
,
260 PRPC_UNICODE_STRING ModuleName
,
261 PRPC_UNICODE_STRING RegModuleName
,
264 IELF_HANDLE
*LogHandle
)
266 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
267 return STATUS_INVALID_PARAMETER
;
269 /* RegModuleName must be an empty string */
270 if (RegModuleName
->Length
> 0)
271 return STATUS_INVALID_PARAMETER
;
273 /*FIXME: UNCServerName must specify the server */
275 /*FIXME: Must verify that caller has read access */
277 *LogHandle
= ElfCreateEventLogHandle(ModuleName
->Buffer
, FALSE
);
279 if (*LogHandle
== NULL
)
281 return STATUS_INVALID_PARAMETER
;
284 return STATUS_SUCCESS
;
289 NTSTATUS
ElfrRegisterEventSourceW(
290 EVENTLOG_HANDLE_W UNCServerName
,
291 PRPC_UNICODE_STRING ModuleName
,
292 PRPC_UNICODE_STRING RegModuleName
,
295 IELF_HANDLE
*LogHandle
)
297 DPRINT1("ElfrRegisterEventSourceW()\n");
299 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
300 return STATUS_INVALID_PARAMETER
;
302 /* RegModuleName must be an empty string */
303 if (RegModuleName
->Length
> 0)
304 return STATUS_INVALID_PARAMETER
;
306 DPRINT1("ModuleName: %S\n", ModuleName
->Buffer
);
308 /*FIXME: UNCServerName must specify the server or empty for local */
310 /*FIXME: Must verify that caller has write access */
312 *LogHandle
= ElfCreateEventLogHandle(ModuleName
->Buffer
, TRUE
);
314 return STATUS_SUCCESS
;
319 NTSTATUS
ElfrOpenBELW(
320 EVENTLOG_HANDLE_W UNCServerName
,
321 PRPC_UNICODE_STRING BackupFileName
,
324 IELF_HANDLE
*LogHandle
)
327 return STATUS_NOT_IMPLEMENTED
;
332 NTSTATUS
ElfrReadELW(
333 IELF_HANDLE LogHandle
,
336 RULONG NumberOfBytesToRead
,
338 DWORD
*NumberOfBytesRead
,
339 DWORD
*MinNumberOfBytesNeeded
)
341 PLOGHANDLE lpLogHandle
;
345 lpLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
348 return STATUS_INVALID_HANDLE
;
352 return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER
);
354 /* If sequential read, retrieve the CurrentRecord from this log handle */
355 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
357 RecordNumber
= lpLogHandle
->CurrentRecord
;
361 RecordNumber
= RecordOffset
;
364 dwError
= LogfReadEvent(lpLogHandle
->LogFile
, ReadFlags
, &RecordNumber
,
365 NumberOfBytesToRead
, Buffer
, NumberOfBytesRead
, MinNumberOfBytesNeeded
);
367 /* Update the handles CurrentRecord if success*/
368 if (dwError
== ERROR_SUCCESS
)
370 lpLogHandle
->CurrentRecord
= RecordNumber
;
373 return I_RpcMapWin32Status(dwError
);
378 NTSTATUS
ElfrReportEventW(
379 IELF_HANDLE LogHandle
,
382 USHORT EventCategory
,
386 PRPC_UNICODE_STRING ComputerName
,
388 PRPC_UNICODE_STRING Strings
[],
396 PLOGHANDLE lpLogHandle
;
399 DWORD dwStringsSize
= 0;
400 DWORD dwUserSidLength
= 0;
401 DWORD dwError
= ERROR_SUCCESS
;
405 lpLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
408 return STATUS_INVALID_HANDLE
;
411 /* Flags must be 0 */
414 return STATUS_INVALID_PARAMETER
;
417 lastRec
= LogfGetCurrentRecord(lpLogHandle
->LogFile
);
419 for (i
= 0; i
< NumStrings
; i
++)
423 case EVENTLOG_SUCCESS
:
424 DPRINT("Success: %wZ\n", Strings
[i
]);
427 case EVENTLOG_ERROR_TYPE
:
428 DPRINT("Error: %wZ\n", Strings
[i
]);
431 case EVENTLOG_WARNING_TYPE
:
432 DPRINT("Warning: %wZ\n", Strings
[i
]);
435 case EVENTLOG_INFORMATION_TYPE
:
436 DPRINT("Info: %wZ\n", Strings
[i
]);
440 DPRINT1("Type %hu: %wZ\n", EventType
, Strings
[i
]);
443 dwStringsSize
+= Strings
[i
]->Length
+ sizeof UNICODE_NULL
;
446 lpStrings
= HeapAlloc(GetProcessHeap(), 0, dwStringsSize
);
449 DPRINT1("Failed to allocate heap\n");
450 return STATUS_NO_MEMORY
;
453 for (i
= 0; i
< NumStrings
; i
++)
455 CopyMemory(lpStrings
+ pos
, Strings
[i
]->Buffer
, Strings
[i
]->Length
);
456 pos
+= Strings
[i
]->Length
/ sizeof(WCHAR
);
457 lpStrings
[pos
] = UNICODE_NULL
;
458 pos
+= sizeof UNICODE_NULL
/ sizeof(WCHAR
);
462 dwUserSidLength
= FIELD_OFFSET(SID
, SubAuthority
[UserSID
->SubAuthorityCount
]);
463 LogBuffer
= LogfAllocAndBuildNewRecord(&recSize
,
469 ComputerName
->Buffer
,
477 dwError
= LogfWriteData(lpLogHandle
->LogFile
, recSize
, LogBuffer
);
480 DPRINT1("ERROR WRITING TO EventLog %S\n", lpLogHandle
->LogFile
->FileName
);
483 LogfFreeRecord(LogBuffer
);
485 HeapFree(GetProcessHeap(), 0, lpStrings
);
487 return I_RpcMapWin32Status(dwError
);
492 NTSTATUS
ElfrClearELFA(
493 IELF_HANDLE LogHandle
,
494 PRPC_STRING BackupFileName
)
497 return STATUS_NOT_IMPLEMENTED
;
502 NTSTATUS
ElfrBackupELFA(
503 IELF_HANDLE LogHandle
,
504 PRPC_STRING BackupFileName
)
507 return STATUS_NOT_IMPLEMENTED
;
512 NTSTATUS
ElfrOpenELA(
513 EVENTLOG_HANDLE_A UNCServerName
,
514 PRPC_STRING ModuleName
,
515 PRPC_STRING RegModuleName
,
518 IELF_HANDLE
*LogHandle
)
520 UNICODE_STRING ModuleNameW
;
522 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
523 return STATUS_INVALID_PARAMETER
;
525 /* RegModuleName must be an empty string */
526 if (RegModuleName
->Length
> 0)
527 return STATUS_INVALID_PARAMETER
;
529 RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
);
531 /* FIXME: Must verify that caller has read access */
533 *LogHandle
= ElfCreateEventLogHandle(ModuleNameW
.Buffer
, FALSE
);
535 RtlFreeUnicodeString(&ModuleNameW
);
537 if (*LogHandle
== NULL
)
539 return STATUS_INVALID_PARAMETER
;
542 return STATUS_SUCCESS
;
547 NTSTATUS
ElfrRegisterEventSourceA(
548 EVENTLOG_HANDLE_A UNCServerName
,
549 PRPC_STRING ModuleName
,
550 PRPC_STRING RegModuleName
,
553 IELF_HANDLE
*LogHandle
)
555 UNICODE_STRING ModuleNameW
= { 0, 0, NULL
};
558 !RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
))
560 return STATUS_NO_MEMORY
;
563 /* RegModuleName must be an empty string */
564 if (RegModuleName
->Length
> 0)
566 RtlFreeUnicodeString(&ModuleNameW
);
567 return STATUS_INVALID_PARAMETER
;
570 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
572 RtlFreeUnicodeString(&ModuleNameW
);
573 return STATUS_INVALID_PARAMETER
;
576 /* FIXME: Must verify that caller has write access */
578 *LogHandle
= ElfCreateEventLogHandle(ModuleNameW
.Buffer
,
581 RtlFreeUnicodeString(&ModuleNameW
);
583 return STATUS_SUCCESS
;
588 NTSTATUS
ElfrOpenBELA(
589 EVENTLOG_HANDLE_A UNCServerName
,
590 PRPC_STRING BackupFileName
,
593 IELF_HANDLE
*LogHandle
)
596 return STATUS_NOT_IMPLEMENTED
;
601 NTSTATUS
ElfrReadELA(
602 IELF_HANDLE LogHandle
,
605 RULONG NumberOfBytesToRead
,
607 DWORD
*NumberOfBytesRead
,
608 DWORD
*MinNumberOfBytesNeeded
)
611 return STATUS_NOT_IMPLEMENTED
;
616 NTSTATUS
ElfrReportEventA(
617 IELF_HANDLE LogHandle
,
620 USHORT EventCategory
,
624 PRPC_STRING ComputerName
,
626 PRPC_STRING Strings
[],
633 return STATUS_NOT_IMPLEMENTED
;
638 NTSTATUS
ElfrRegisterClusterSvc(
639 handle_t BindingHandle
)
642 return STATUS_NOT_IMPLEMENTED
;
647 NTSTATUS
ElfrDeregisterClusterSvc(
648 handle_t BindingHandle
)
651 return STATUS_NOT_IMPLEMENTED
;
656 NTSTATUS
ElfrWriteClusterEvents(
657 handle_t BindingHandle
)
660 return STATUS_NOT_IMPLEMENTED
;
665 NTSTATUS
ElfrGetLogInformation(
666 IELF_HANDLE LogHandle
,
670 DWORD
*pcbBytesNeeded
)
672 NTSTATUS Status
= STATUS_SUCCESS
;
674 /* FIXME: check handle first */
678 case EVENTLOG_FULL_INFO
:
680 LPEVENTLOG_FULL_INFORMATION efi
= (LPEVENTLOG_FULL_INFORMATION
)Buffer
;
682 *pcbBytesNeeded
= sizeof(EVENTLOG_FULL_INFORMATION
);
683 if (cbBufSize
< sizeof(EVENTLOG_FULL_INFORMATION
))
685 return STATUS_BUFFER_TOO_SMALL
;
688 efi
->dwFull
= 0; /* FIXME */
693 Status
= STATUS_INVALID_LEVEL
;
702 NTSTATUS
ElfrFlushEL(
703 IELF_HANDLE LogHandle
)
706 return STATUS_NOT_IMPLEMENTED
;
711 NTSTATUS
ElfrReportEventAndSourceW(
712 IELF_HANDLE LogHandle
,
715 USHORT EventCategory
,
717 PRPC_UNICODE_STRING SourceName
,
720 PRPC_UNICODE_STRING ComputerName
,
722 PRPC_UNICODE_STRING Strings
[],
729 return STATUS_NOT_IMPLEMENTED
;
733 void __RPC_FAR
*__RPC_USER
midl_user_allocate(SIZE_T len
)
735 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
739 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
741 HeapFree(GetProcessHeap(), 0, ptr
);
745 void __RPC_USER
IELF_HANDLE_rundown(IELF_HANDLE LogHandle
)