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 EventSourceListHead
;
16 /* FUNCTIONS ****************************************************************/
18 DWORD WINAPI
RpcThreadRoutine(LPVOID lpParameter
)
22 InitializeListHead(&EventSourceListHead
);
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 PEVENTSOURCE
ElfCreateEventLogHandle(LPCWSTR Name
, BOOL Create
)
49 PEVENTSOURCE lpEventSource
;
50 PLOGFILE currentLogFile
= NULL
;
53 lpEventSource
= HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTSOURCE
)
54 + ((wcslen(Name
) + 1) * sizeof(WCHAR
)));
57 DPRINT1("Failed to allocate Heap!\n");
61 wcscpy(lpEventSource
->szName
, Name
);
63 /* Get the number of Log Files the EventLog service found */
64 LogsActive
= LogfListItemCount();
67 DPRINT1("EventLog service reports no log files!\n");
71 /* If Creating, default to the Application Log in case we fail, as documented on MSDN */
73 lpEventSource
->LogFile
= LogfListItemByName(L
"Application");
75 lpEventSource
->LogFile
= NULL
;
77 for (i
= 1; i
<= LogsActive
; i
++)
79 currentLogFile
= LogfListItemByIndex(i
);
81 if (_wcsicmp(Name
, currentLogFile
->LogName
) == 0)
83 lpEventSource
->LogFile
= LogfListItemByIndex(i
);
84 lpEventSource
->CurrentRecord
= LogfGetOldestRecord(lpEventSource
->LogFile
);
89 if (!lpEventSource
->LogFile
)
92 /* Append service record */
93 InsertTailList(&EventSourceListHead
, &lpEventSource
->EventSourceListEntry
);
98 HeapFree(GetProcessHeap(), 0, lpEventSource
);
103 PEVENTSOURCE
ElfGetEventLogSourceEntryByHandle(IELF_HANDLE EventLogHandle
)
105 PEVENTSOURCE CurrentEventSource
;
107 if (IsListEmpty(&EventSourceListHead
))
111 CurrentEventSource
= CONTAINING_RECORD((PEVENTSOURCE
)EventLogHandle
, EVENTSOURCE
, EventSourceListEntry
);
113 return CurrentEventSource
;
116 BOOL
ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle
)
118 PEVENTSOURCE lpEventSource
= (PEVENTSOURCE
)EventLogHandle
;
119 if (!ElfGetEventLogSourceEntryByHandle(lpEventSource
))
124 RemoveEntryList(&lpEventSource
->EventSourceListEntry
);
125 HeapFree(GetProcessHeap(),0,lpEventSource
);
131 NTSTATUS
ElfrClearELFW(
132 IELF_HANDLE LogHandle
,
133 PRPC_UNICODE_STRING BackupFileName
)
136 return STATUS_NOT_IMPLEMENTED
;
141 NTSTATUS
ElfrBackupELFW(
142 IELF_HANDLE LogHandle
,
143 PRPC_UNICODE_STRING BackupFileName
)
146 return STATUS_NOT_IMPLEMENTED
;
150 NTSTATUS
ElfrCloseEL(
151 IELF_HANDLE
*LogHandle
)
153 if (!ElfDeleteEventLogHandle(*LogHandle
))
155 return STATUS_INVALID_HANDLE
;
158 return STATUS_SUCCESS
;
163 NTSTATUS
ElfrDeregisterEventSource(
164 IELF_HANDLE
*LogHandle
)
166 if (!ElfDeleteEventLogHandle(*LogHandle
))
168 return STATUS_INVALID_HANDLE
;
171 return STATUS_SUCCESS
;
176 NTSTATUS
ElfrNumberOfRecords(
177 IELF_HANDLE LogHandle
,
178 DWORD
*NumberOfRecords
)
180 PEVENTSOURCE lpEventSource
;
182 lpEventSource
= ElfGetEventLogSourceEntryByHandle(LogHandle
);
185 return STATUS_INVALID_HANDLE
;
188 *NumberOfRecords
= lpEventSource
->LogFile
->Header
.CurrentRecordNumber
;
190 return STATUS_SUCCESS
;
195 NTSTATUS
ElfrOldestRecord(
196 IELF_HANDLE LogHandle
,
197 DWORD
*OldestRecordNumber
)
199 PEVENTSOURCE lpEventSource
;
201 lpEventSource
= ElfGetEventLogSourceEntryByHandle(LogHandle
);
204 return STATUS_INVALID_HANDLE
;
207 if (!OldestRecordNumber
)
209 return STATUS_INVALID_PARAMETER
;
212 *OldestRecordNumber
= 0;
213 *OldestRecordNumber
= LogfGetOldestRecord(lpEventSource
->LogFile
);
214 return STATUS_SUCCESS
;
219 NTSTATUS
ElfrChangeNotify(
220 IELF_HANDLE
*LogHandle
,
221 RPC_CLIENT_ID ClientId
,
225 return STATUS_NOT_IMPLEMENTED
;
230 NTSTATUS
ElfrOpenELW(
231 EVENTLOG_HANDLE_W UNCServerName
,
232 PRPC_UNICODE_STRING ModuleName
,
233 PRPC_UNICODE_STRING RegModuleName
,
236 IELF_HANDLE
*LogHandle
)
238 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
239 return STATUS_INVALID_PARAMETER
;
241 /* RegModuleName must be an empty string */
242 if (RegModuleName
->Length
> 0)
243 return STATUS_INVALID_PARAMETER
;
245 /*FIXME: UNCServerName must specify the server */
247 /*FIXME: Must verify that caller has read access */
249 *LogHandle
= ElfCreateEventLogHandle(ModuleName
->Buffer
, FALSE
);
251 if (*LogHandle
== NULL
)
253 return STATUS_INVALID_PARAMETER
;
256 return STATUS_SUCCESS
;
261 NTSTATUS
ElfrRegisterEventSourceW(
262 EVENTLOG_HANDLE_W UNCServerName
,
263 PRPC_UNICODE_STRING ModuleName
,
264 PRPC_UNICODE_STRING RegModuleName
,
267 IELF_HANDLE
*LogHandle
)
269 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
270 return STATUS_INVALID_PARAMETER
;
272 /* RegModuleName must be an empty string */
273 if (RegModuleName
->Length
> 0)
274 return STATUS_INVALID_PARAMETER
;
276 /*FIXME: UNCServerName must specify the server or empty for local */
278 /*FIXME: Must verify that caller has write access */
280 *LogHandle
= ElfCreateEventLogHandle(ModuleName
->Buffer
, TRUE
);
282 return STATUS_SUCCESS
;
287 NTSTATUS
ElfrOpenBELW(
288 EVENTLOG_HANDLE_W UNCServerName
,
289 PRPC_UNICODE_STRING BackupFileName
,
292 IELF_HANDLE
*LogHandle
)
295 return STATUS_NOT_IMPLEMENTED
;
300 NTSTATUS
ElfrReadELW(
301 IELF_HANDLE LogHandle
,
304 RULONG NumberOfBytesToRead
,
306 DWORD
*NumberOfBytesRead
,
307 DWORD
*MinNumberOfBytesNeeded
)
309 PEVENTSOURCE lpEventSource
;
313 lpEventSource
= ElfGetEventLogSourceEntryByHandle(LogHandle
);
316 return STATUS_INVALID_HANDLE
;
320 return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER
);
322 /* If sequential read, retrieve the CurrentRecord from this log handle */
323 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
325 RecordNumber
= lpEventSource
->CurrentRecord
;
329 RecordNumber
= RecordOffset
;
332 dwError
= LogfReadEvent(lpEventSource
->LogFile
, ReadFlags
, &RecordNumber
,
333 NumberOfBytesToRead
, Buffer
, NumberOfBytesRead
, MinNumberOfBytesNeeded
);
335 /* Update the handles CurrentRecord if success*/
336 if (dwError
== ERROR_SUCCESS
)
338 lpEventSource
->CurrentRecord
= RecordNumber
;
341 return I_RpcMapWin32Status(dwError
);
346 NTSTATUS
ElfrReportEventW(
347 IELF_HANDLE LogHandle
,
350 USHORT EventCategory
,
354 PRPC_UNICODE_STRING ComputerName
,
356 PRPC_UNICODE_STRING Strings
[],
364 PEVENTSOURCE lpEventSource
;
367 DWORD dwStringsSize
= 0;
368 DWORD dwError
= ERROR_SUCCESS
;
372 lpEventSource
= ElfGetEventLogSourceEntryByHandle(LogHandle
);
375 return STATUS_INVALID_HANDLE
;
378 /* Flags must be 0 */
381 return STATUS_INVALID_PARAMETER
;
384 lastRec
= LogfGetCurrentRecord(lpEventSource
->LogFile
);
386 for (i
= 0; i
< NumStrings
; i
++)
390 case EVENTLOG_SUCCESS
:
391 DPRINT("Success: %wZ\n", Strings
[i
]);
394 case EVENTLOG_ERROR_TYPE
:
395 DPRINT("Error: %wZ\n", Strings
[i
]);
398 case EVENTLOG_WARNING_TYPE
:
399 DPRINT("Warning: %wZ\n", Strings
[i
]);
402 case EVENTLOG_INFORMATION_TYPE
:
403 DPRINT("Info: %wZ\n", Strings
[i
]);
407 DPRINT1("Type %hu: %wZ\n", EventType
, Strings
[i
]);
410 dwStringsSize
+= (wcslen(Strings
[i
]->Buffer
) + 1) * sizeof(WCHAR
);
413 lpStrings
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
, dwStringsSize
* 2);
416 DPRINT1("Failed to allocate heap\n");
417 return STATUS_NO_MEMORY
;
420 for (i
= 0; i
< NumStrings
; i
++)
422 wcscpy((WCHAR
*)(lpStrings
+ pos
), Strings
[i
]->Buffer
);
423 pos
+= (wcslen(Strings
[i
]->Buffer
) + 1) * sizeof(WCHAR
);
426 LogBuffer
= LogfAllocAndBuildNewRecord(&recSize
,
431 lpEventSource
->szName
,
432 ComputerName
->Buffer
,
440 dwError
= LogfWriteData(lpEventSource
->LogFile
, recSize
, LogBuffer
);
443 DPRINT1("ERROR WRITING TO EventLog %S\n",lpEventSource
->LogFile
->FileName
);
446 LogfFreeRecord(LogBuffer
);
448 HeapFree(GetProcessHeap(), 0, lpStrings
);
450 return I_RpcMapWin32Status(dwError
);
455 NTSTATUS
ElfrClearELFA(
456 IELF_HANDLE LogHandle
,
457 PRPC_STRING BackupFileName
)
460 return STATUS_NOT_IMPLEMENTED
;
465 NTSTATUS
ElfrBackupELFA(
466 IELF_HANDLE LogHandle
,
467 PRPC_STRING BackupFileName
)
470 return STATUS_NOT_IMPLEMENTED
;
475 NTSTATUS
ElfrOpenELA(
476 EVENTLOG_HANDLE_A UNCServerName
,
477 PRPC_STRING ModuleName
,
478 PRPC_STRING RegModuleName
,
481 IELF_HANDLE
*LogHandle
)
483 UNICODE_STRING UNCServerNameW
= { 0, 0, NULL
};
484 UNICODE_STRING ModuleNameW
= { 0, 0, NULL
};
485 UNICODE_STRING RegModuleNameW
= { 0, 0, NULL
};
489 !RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW
, UNCServerName
))
491 return STATUS_NO_MEMORY
;
495 !RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
))
497 RtlFreeUnicodeString(&UNCServerNameW
);
498 return STATUS_NO_MEMORY
;
502 !RtlAnsiStringToUnicodeString(&RegModuleNameW
, (PANSI_STRING
)RegModuleName
, TRUE
))
504 RtlFreeUnicodeString(&UNCServerNameW
);
505 RtlFreeUnicodeString(&ModuleNameW
);
506 return STATUS_NO_MEMORY
;
509 Status
= ElfrOpenELW(
510 UNCServerName
? UNCServerNameW
.Buffer
: NULL
,
511 ModuleName
? (PRPC_UNICODE_STRING
)&ModuleNameW
: NULL
,
512 RegModuleName
? (PRPC_UNICODE_STRING
)&RegModuleNameW
: NULL
,
517 RtlFreeUnicodeString(&UNCServerNameW
);
518 RtlFreeUnicodeString(&ModuleNameW
);
519 RtlFreeUnicodeString(&RegModuleNameW
);
526 NTSTATUS
ElfrRegisterEventSourceA(
527 EVENTLOG_HANDLE_A UNCServerName
,
528 PRPC_STRING ModuleName
,
529 PRPC_STRING RegModuleName
,
532 IELF_HANDLE
*LogHandle
)
534 UNICODE_STRING UNCServerNameW
= { 0, 0, NULL
};
535 UNICODE_STRING ModuleNameW
= { 0, 0, NULL
};
538 !RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW
, UNCServerName
))
540 return STATUS_NO_MEMORY
;
544 !RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
))
546 RtlFreeUnicodeString(&UNCServerNameW
);
547 return STATUS_NO_MEMORY
;
550 /* RegModuleName must be an empty string */
551 if (RegModuleName
->Length
> 0)
553 RtlFreeUnicodeString(&UNCServerNameW
);
554 RtlFreeUnicodeString(&ModuleNameW
);
555 return STATUS_INVALID_PARAMETER
;
558 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
560 RtlFreeUnicodeString(&UNCServerNameW
);
561 RtlFreeUnicodeString(&ModuleNameW
);
562 return STATUS_INVALID_PARAMETER
;
565 /*FIXME: UNCServerName must specify the server or empty for local */
567 /*FIXME: Must verify that caller has write access */
569 *LogHandle
= ElfCreateEventLogHandle(ModuleNameW
.Buffer
,
572 RtlFreeUnicodeString(&UNCServerNameW
);
573 RtlFreeUnicodeString(&ModuleNameW
);
575 return STATUS_SUCCESS
;
580 NTSTATUS
ElfrOpenBELA(
581 EVENTLOG_HANDLE_A UNCServerName
,
582 PRPC_STRING BackupFileName
,
585 IELF_HANDLE
*LogHandle
)
588 return STATUS_NOT_IMPLEMENTED
;
593 NTSTATUS
ElfrReadELA(
594 IELF_HANDLE LogHandle
,
597 RULONG NumberOfBytesToRead
,
599 DWORD
*NumberOfBytesRead
,
600 DWORD
*MinNumberOfBytesNeeded
)
603 return STATUS_NOT_IMPLEMENTED
;
608 NTSTATUS
ElfrReportEventA(
609 IELF_HANDLE LogHandle
,
612 USHORT EventCategory
,
616 PRPC_STRING ComputerName
,
618 PRPC_STRING Strings
[],
625 return STATUS_NOT_IMPLEMENTED
;
630 NTSTATUS
ElfrRegisterClusterSvc(
631 handle_t BindingHandle
)
634 return STATUS_NOT_IMPLEMENTED
;
639 NTSTATUS
ElfrDeregisterClusterSvc(
640 handle_t BindingHandle
)
643 return STATUS_NOT_IMPLEMENTED
;
648 NTSTATUS
ElfrWriteClusterEvents(
649 handle_t BindingHandle
)
652 return STATUS_NOT_IMPLEMENTED
;
657 NTSTATUS
ElfrGetLogInformation(
658 IELF_HANDLE LogHandle
,
662 DWORD
*pcbBytesNeeded
)
665 return STATUS_NOT_IMPLEMENTED
;
670 NTSTATUS
ElfrFlushEL(
671 IELF_HANDLE LogHandle
)
674 return STATUS_NOT_IMPLEMENTED
;
679 NTSTATUS
ElfrReportEventAndSourceW(
680 IELF_HANDLE LogHandle
,
683 USHORT EventCategory
,
685 PRPC_UNICODE_STRING SourceName
,
688 PRPC_UNICODE_STRING ComputerName
,
690 PRPC_UNICODE_STRING Strings
[],
697 return STATUS_NOT_IMPLEMENTED
;
701 void __RPC_FAR
*__RPC_USER
midl_user_allocate(SIZE_T len
)
703 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
707 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
709 HeapFree(GetProcessHeap(), 0, ptr
);
713 void __RPC_USER
IELF_HANDLE_rundown(IELF_HANDLE LogHandle
)