2 * PROJECT: ReactOS EventLog Service
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/services/eventlog/rpc.c
5 * PURPOSE: RPC Port Interface support
6 * COPYRIGHT: Copyright 2005 Saveliy Tretiakov
7 * Copyright 2008 Michael Martin
8 * Copyright 2010-2011 Eric Kohl
11 /* INCLUDES *****************************************************************/
18 static LIST_ENTRY LogHandleListHead
;
19 static CRITICAL_SECTION LogHandleListCs
;
21 /* FUNCTIONS ****************************************************************/
24 ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle
);
26 DWORD WINAPI
RpcThreadRoutine(LPVOID lpParameter
)
30 InitializeCriticalSection(&LogHandleListCs
);
31 InitializeListHead(&LogHandleListHead
);
33 Status
= RpcServerUseProtseqEpW(L
"ncacn_np", 20, L
"\\pipe\\EventLog", NULL
);
34 if (Status
!= RPC_S_OK
)
36 DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
40 Status
= RpcServerRegisterIf(eventlog_v0_0_s_ifspec
, NULL
, NULL
);
41 if (Status
!= RPC_S_OK
)
43 DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
47 Status
= RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, FALSE
);
48 if (Status
!= RPC_S_OK
)
50 DPRINT("RpcServerListen() failed (Status %lx)\n", Status
);
53 EnterCriticalSection(&LogHandleListCs
);
54 while (!IsListEmpty(&LogHandleListHead
))
56 IELF_HANDLE LogHandle
= (IELF_HANDLE
)CONTAINING_RECORD(LogHandleListHead
.Flink
, LOGHANDLE
, LogHandleListEntry
);
57 ElfDeleteEventLogHandle(&LogHandle
);
59 LeaveCriticalSection(&LogHandleListCs
);
62 DeleteCriticalSection(&LogHandleListCs
);
69 ElfCreateEventLogHandle(PLOGHANDLE
* LogHandle
,
70 PUNICODE_STRING LogName
,
73 NTSTATUS Status
= STATUS_SUCCESS
;
74 PLOGHANDLE pLogHandle
;
75 PLOGFILE currentLogFile
= NULL
;
77 PEVENTSOURCE pEventSource
;
79 DPRINT("ElfCreateEventLogHandle(%wZ)\n", LogName
);
83 i
= (LogName
->Length
+ sizeof(UNICODE_NULL
)) / sizeof(WCHAR
);
84 pLogHandle
= HeapAlloc(GetProcessHeap(),
86 FIELD_OFFSET(LOGHANDLE
, szName
[i
]));
89 DPRINT1("Failed to allocate Heap!\n");
90 return STATUS_NO_MEMORY
;
93 StringCchCopyW(pLogHandle
->szName
, i
, LogName
->Buffer
);
95 /* Get the number of Log Files the EventLog service found */
96 // NOTE: We could just as well loop only once within the list of logs
97 // and retrieve what the code below that calls LogfListItemByIndex, does!!
98 LogsActive
= LogfListItemCount();
101 DPRINT1("EventLog service reports no log files!\n");
102 Status
= STATUS_UNSUCCESSFUL
;
106 /* If Creating, default to the Application Log in case we fail, as documented on MSDN */
109 pEventSource
= GetEventSourceByName(LogName
->Buffer
);
110 DPRINT("EventSource: %p\n", pEventSource
);
113 DPRINT("EventSource LogFile: %p\n", pEventSource
->LogFile
);
114 pLogHandle
->LogFile
= pEventSource
->LogFile
;
118 DPRINT("EventSource LogFile: Application log file\n");
119 pLogHandle
->LogFile
= LogfListItemByName(L
"Application");
122 DPRINT("LogHandle LogFile: %p\n", pLogHandle
->LogFile
);
126 pLogHandle
->LogFile
= NULL
;
128 for (i
= 1; i
<= LogsActive
; i
++)
130 currentLogFile
= LogfListItemByIndex(i
);
132 if (_wcsicmp(LogName
->Buffer
, currentLogFile
->LogName
) == 0)
134 pLogHandle
->LogFile
= currentLogFile
;
139 /* Use the application log if the desired log does not exist */
140 if (pLogHandle
->LogFile
== NULL
)
142 pLogHandle
->LogFile
= LogfListItemByName(L
"Application");
143 if (pLogHandle
->LogFile
== NULL
)
145 DPRINT1("Application log is missing!\n");
146 Status
= STATUS_UNSUCCESSFUL
;
151 /* Reset the current record */
152 pLogHandle
->CurrentRecord
= 0;
155 if (!pLogHandle
->LogFile
)
156 Status
= STATUS_UNSUCCESSFUL
;
159 if (NT_SUCCESS(Status
))
161 /* Append log handle */
162 EnterCriticalSection(&LogHandleListCs
);
163 InsertTailList(&LogHandleListHead
, &pLogHandle
->LogHandleListEntry
);
164 LeaveCriticalSection(&LogHandleListCs
);
165 *LogHandle
= pLogHandle
;
169 HeapFree(GetProcessHeap(), 0, pLogHandle
);
177 ElfCreateBackupLogHandle(PLOGHANDLE
* LogHandle
,
178 PUNICODE_STRING FileName
)
180 NTSTATUS Status
= STATUS_SUCCESS
;
181 PLOGHANDLE pLogHandle
;
183 DPRINT("ElfCreateBackupLogHandle(%wZ)\n", FileName
);
187 pLogHandle
= HeapAlloc(GetProcessHeap(),
190 if (pLogHandle
== NULL
)
192 DPRINT1("Failed to allocate Heap!\n");
193 return STATUS_NO_MEMORY
;
196 /* Create the log file */
197 Status
= LogfCreate(&pLogHandle
->LogFile
,
204 if (!NT_SUCCESS(Status
))
206 DPRINT1("Failed to create the log file! (Status 0x%08lx)\n", Status
);
210 /* Set the backup flag */
211 pLogHandle
->Flags
|= LOG_HANDLE_BACKUP_FILE
;
213 /* Reset the current record */
214 pLogHandle
->CurrentRecord
= 0;
217 if (NT_SUCCESS(Status
))
219 /* Append log handle */
220 EnterCriticalSection(&LogHandleListCs
);
221 InsertTailList(&LogHandleListHead
, &pLogHandle
->LogHandleListEntry
);
222 LeaveCriticalSection(&LogHandleListCs
);
223 *LogHandle
= pLogHandle
;
227 HeapFree(GetProcessHeap(), 0, pLogHandle
);
235 ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle
)
237 PLIST_ENTRY CurrentEntry
;
238 PLOGHANDLE Handle
, pLogHandle
= NULL
;
240 EnterCriticalSection(&LogHandleListCs
);
242 CurrentEntry
= LogHandleListHead
.Flink
;
243 while (CurrentEntry
!= &LogHandleListHead
)
245 Handle
= CONTAINING_RECORD(CurrentEntry
,
248 CurrentEntry
= CurrentEntry
->Flink
;
250 if (Handle
== EventLogHandle
)
257 LeaveCriticalSection(&LogHandleListCs
);
264 ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle
)
266 PLOGHANDLE pLogHandle
;
268 pLogHandle
= ElfGetLogHandleEntryByHandle(*LogHandle
);
270 return STATUS_INVALID_HANDLE
;
272 EnterCriticalSection(&LogHandleListCs
);
273 RemoveEntryList(&pLogHandle
->LogHandleListEntry
);
274 LeaveCriticalSection(&LogHandleListCs
);
276 LogfClose(pLogHandle
->LogFile
, FALSE
);
278 HeapFree(GetProcessHeap(), 0, pLogHandle
);
282 return STATUS_SUCCESS
;
289 IELF_HANDLE LogHandle
,
290 PRPC_UNICODE_STRING BackupFileName
)
292 PLOGHANDLE pLogHandle
;
294 DPRINT("ElfrClearELFW()\n");
296 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
298 return STATUS_INVALID_HANDLE
;
300 /* Fail, if the log file is a backup file */
301 if (pLogHandle
->Flags
& LOG_HANDLE_BACKUP_FILE
)
302 return STATUS_INVALID_HANDLE
;
304 return LogfClearFile(pLogHandle
->LogFile
,
305 (PUNICODE_STRING
)BackupFileName
);
312 IELF_HANDLE LogHandle
,
313 PRPC_UNICODE_STRING BackupFileName
)
315 PLOGHANDLE pLogHandle
;
317 DPRINT("ElfrBackupELFW()\n");
319 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
321 return STATUS_INVALID_HANDLE
;
323 return LogfBackupFile(pLogHandle
->LogFile
,
324 (PUNICODE_STRING
)BackupFileName
);
331 PIELF_HANDLE LogHandle
)
333 return ElfDeleteEventLogHandle(LogHandle
);
339 ElfrDeregisterEventSource(
340 PIELF_HANDLE LogHandle
)
342 return ElfDeleteEventLogHandle(LogHandle
);
349 IELF_HANDLE LogHandle
,
350 PULONG NumberOfRecords
)
352 PLOGHANDLE pLogHandle
;
354 ULONG OldestRecordNumber
, CurrentRecordNumber
;
356 DPRINT("ElfrNumberOfRecords()\n");
358 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
360 return STATUS_INVALID_HANDLE
;
362 if (!NumberOfRecords
)
363 return STATUS_INVALID_PARAMETER
;
365 pLogFile
= pLogHandle
->LogFile
;
367 /* Lock the log file shared */
368 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
370 OldestRecordNumber
= ElfGetOldestRecord(&pLogFile
->LogFile
);
371 CurrentRecordNumber
= ElfGetCurrentRecord(&pLogFile
->LogFile
);
373 /* Unlock the log file */
374 RtlReleaseResource(&pLogFile
->Lock
);
376 DPRINT("Oldest: %lu Current: %lu\n",
377 OldestRecordNumber
, CurrentRecordNumber
);
379 if (OldestRecordNumber
== 0)
381 /* OldestRecordNumber == 0 when the log is empty */
382 *NumberOfRecords
= 0;
386 /* The log contains events */
387 *NumberOfRecords
= CurrentRecordNumber
- OldestRecordNumber
;
390 return STATUS_SUCCESS
;
397 IELF_HANDLE LogHandle
,
398 PULONG OldestRecordNumber
)
400 PLOGHANDLE pLogHandle
;
403 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
405 return STATUS_INVALID_HANDLE
;
407 if (!OldestRecordNumber
)
408 return STATUS_INVALID_PARAMETER
;
410 pLogFile
= pLogHandle
->LogFile
;
412 /* Lock the log file shared */
413 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
415 *OldestRecordNumber
= ElfGetOldestRecord(&pLogFile
->LogFile
);
417 /* Unlock the log file */
418 RtlReleaseResource(&pLogFile
->Lock
);
420 return STATUS_SUCCESS
;
427 IELF_HANDLE LogHandle
,
428 RPC_CLIENT_ID ClientId
,
432 return STATUS_NOT_IMPLEMENTED
;
439 EVENTLOG_HANDLE_W UNCServerName
,
440 PRPC_UNICODE_STRING ModuleName
,
441 PRPC_UNICODE_STRING RegModuleName
,
444 PIELF_HANDLE LogHandle
)
446 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
447 return STATUS_INVALID_PARAMETER
;
449 /* RegModuleName must be an empty string */
450 if (RegModuleName
->Length
> 0)
451 return STATUS_INVALID_PARAMETER
;
453 /* FIXME: UNCServerName must specify the server */
455 /* FIXME: Must verify that caller has read access */
457 return ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
458 (PUNICODE_STRING
)ModuleName
,
465 ElfrRegisterEventSourceW(
466 EVENTLOG_HANDLE_W UNCServerName
,
467 PRPC_UNICODE_STRING ModuleName
,
468 PRPC_UNICODE_STRING RegModuleName
,
471 PIELF_HANDLE LogHandle
)
473 DPRINT("ElfrRegisterEventSourceW()\n");
475 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
476 return STATUS_INVALID_PARAMETER
;
478 /* RegModuleName must be an empty string */
479 if (RegModuleName
->Length
> 0)
480 return STATUS_INVALID_PARAMETER
;
482 DPRINT("ModuleName: %wZ\n", ModuleName
);
484 /* FIXME: UNCServerName must specify the server or empty for local */
486 /* FIXME: Must verify that caller has write access */
488 return ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
489 (PUNICODE_STRING
)ModuleName
,
497 EVENTLOG_HANDLE_W UNCServerName
,
498 PRPC_UNICODE_STRING BackupFileName
,
501 PIELF_HANDLE LogHandle
)
503 DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName
);
505 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
506 return STATUS_INVALID_PARAMETER
;
508 /* FIXME: UNCServerName must specify the server */
510 /* FIXME: Must verify that caller has read access */
512 return ElfCreateBackupLogHandle((PLOGHANDLE
*)LogHandle
,
513 (PUNICODE_STRING
)BackupFileName
);
520 IELF_HANDLE LogHandle
,
523 RULONG NumberOfBytesToRead
,
525 PULONG NumberOfBytesRead
,
526 PULONG MinNumberOfBytesNeeded
)
529 PLOGHANDLE pLogHandle
;
532 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
534 return STATUS_INVALID_HANDLE
;
537 return STATUS_INVALID_PARAMETER
;
539 /* If sequential read, retrieve the CurrentRecord from this log handle */
540 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
542 RecordNumber
= pLogHandle
->CurrentRecord
;
544 else // (ReadFlags & EVENTLOG_SEEK_READ)
546 RecordNumber
= RecordOffset
;
549 Status
= LogfReadEvents(pLogHandle
->LogFile
,
555 MinNumberOfBytesNeeded
,
558 /* Update the handle's CurrentRecord if success */
559 if (NT_SUCCESS(Status
))
561 pLogHandle
->CurrentRecord
= RecordNumber
;
568 /* Helper function for ElfrReportEventW/A and ElfrReportEventAndSourceW */
571 IELF_HANDLE LogHandle
,
574 USHORT EventCategory
,
576 PRPC_UNICODE_STRING SourceName OPTIONAL
,
579 PRPC_UNICODE_STRING ComputerName
,
581 PRPC_UNICODE_STRING Strings
[],
588 PLOGHANDLE pLogHandle
;
589 UNICODE_STRING LocalSourceName
, LocalComputerName
;
590 PEVENTLOGRECORD LogBuffer
;
593 ULONG dwStringsSize
= 0;
594 ULONG dwUserSidLength
= 0;
595 PWSTR lpStrings
, str
;
597 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
599 return STATUS_INVALID_HANDLE
;
601 /* Flags must be 0 */
603 return STATUS_INVALID_PARAMETER
;
605 for (i
= 0; i
< NumStrings
; i
++)
609 case EVENTLOG_SUCCESS
:
610 DPRINT("Success: %wZ\n", Strings
[i
]);
613 case EVENTLOG_ERROR_TYPE
:
614 DPRINT("Error: %wZ\n", Strings
[i
]);
617 case EVENTLOG_WARNING_TYPE
:
618 DPRINT("Warning: %wZ\n", Strings
[i
]);
621 case EVENTLOG_INFORMATION_TYPE
:
622 DPRINT("Info: %wZ\n", Strings
[i
]);
625 case EVENTLOG_AUDIT_SUCCESS
:
626 DPRINT("Audit Success: %wZ\n", Strings
[i
]);
629 case EVENTLOG_AUDIT_FAILURE
:
630 DPRINT("Audit Failure: %wZ\n", Strings
[i
]);
634 DPRINT1("Type %hu: %wZ\n", EventType
, Strings
[i
]);
637 dwStringsSize
+= Strings
[i
]->Length
+ sizeof(UNICODE_NULL
);
640 lpStrings
= HeapAlloc(GetProcessHeap(), 0, dwStringsSize
);
643 DPRINT1("Failed to allocate heap\n");
644 return STATUS_NO_MEMORY
;
648 for (i
= 0; i
< NumStrings
; i
++)
650 RtlCopyMemory(str
, Strings
[i
]->Buffer
, Strings
[i
]->Length
);
651 str
+= Strings
[i
]->Length
/ sizeof(WCHAR
);
657 dwUserSidLength
= FIELD_OFFSET(SID
, SubAuthority
[UserSID
->SubAuthorityCount
]);
659 if (SourceName
&& SourceName
->Buffer
)
660 LocalSourceName
= *(PUNICODE_STRING
)SourceName
;
662 RtlInitUnicodeString(&LocalSourceName
, pLogHandle
->szName
);
664 LocalComputerName
= *(PUNICODE_STRING
)ComputerName
;
666 LogBuffer
= LogfAllocAndBuildNewRecord(&RecSize
,
679 if (LogBuffer
== NULL
)
681 DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
682 HeapFree(GetProcessHeap(), 0, lpStrings
);
683 return STATUS_NO_MEMORY
;
686 Status
= LogfWriteRecord(pLogHandle
->LogFile
, LogBuffer
, RecSize
);
687 if (!NT_SUCCESS(Status
))
689 DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
690 pLogHandle
->LogFile
->LogName
, Status
);
693 if (NT_SUCCESS(Status
))
695 /* Retrieve the two fields that were set by LogfWriteRecord into the record */
697 *RecordNumber
= LogBuffer
->RecordNumber
;
699 *TimeWritten
= LogBuffer
->TimeWritten
;
702 LogfFreeRecord(LogBuffer
);
704 HeapFree(GetProcessHeap(), 0, lpStrings
);
713 IELF_HANDLE LogHandle
,
716 USHORT EventCategory
,
720 PRPC_UNICODE_STRING ComputerName
,
722 PRPC_UNICODE_STRING Strings
[],
728 /* Call the helper function. The event source is provided via the log handle. */
729 return ElfrIntReportEventW(LogHandle
,
750 IELF_HANDLE LogHandle
,
751 PRPC_STRING BackupFileName
)
754 UNICODE_STRING BackupFileNameW
;
756 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
757 (PANSI_STRING
)BackupFileName
,
759 if (!NT_SUCCESS(Status
))
762 Status
= ElfrClearELFW(LogHandle
,
763 (PRPC_UNICODE_STRING
)&BackupFileNameW
);
765 RtlFreeUnicodeString(&BackupFileNameW
);
774 IELF_HANDLE LogHandle
,
775 PRPC_STRING BackupFileName
)
778 UNICODE_STRING BackupFileNameW
;
780 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
781 (PANSI_STRING
)BackupFileName
,
783 if (!NT_SUCCESS(Status
))
786 Status
= ElfrBackupELFW(LogHandle
,
787 (PRPC_UNICODE_STRING
)&BackupFileNameW
);
789 RtlFreeUnicodeString(&BackupFileNameW
);
798 EVENTLOG_HANDLE_A UNCServerName
,
799 PRPC_STRING ModuleName
,
800 PRPC_STRING RegModuleName
,
803 PIELF_HANDLE LogHandle
)
806 UNICODE_STRING ModuleNameW
;
808 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
809 return STATUS_INVALID_PARAMETER
;
811 /* RegModuleName must be an empty string */
812 if (RegModuleName
->Length
> 0)
813 return STATUS_INVALID_PARAMETER
;
815 Status
= RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
);
816 if (!NT_SUCCESS(Status
))
819 /* FIXME: Must verify that caller has read access */
821 Status
= ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
825 RtlFreeUnicodeString(&ModuleNameW
);
833 ElfrRegisterEventSourceA(
834 EVENTLOG_HANDLE_A UNCServerName
,
835 PRPC_STRING ModuleName
,
836 PRPC_STRING RegModuleName
,
839 PIELF_HANDLE LogHandle
)
842 UNICODE_STRING ModuleNameW
;
844 Status
= RtlAnsiStringToUnicodeString(&ModuleNameW
,
845 (PANSI_STRING
)ModuleName
,
847 if (!NT_SUCCESS(Status
))
849 DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status
);
853 /* RegModuleName must be an empty string */
854 if (RegModuleName
->Length
> 0)
856 RtlFreeUnicodeString(&ModuleNameW
);
857 return STATUS_INVALID_PARAMETER
;
860 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
862 RtlFreeUnicodeString(&ModuleNameW
);
863 return STATUS_INVALID_PARAMETER
;
866 /* FIXME: Must verify that caller has write access */
868 Status
= ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
872 RtlFreeUnicodeString(&ModuleNameW
);
881 EVENTLOG_HANDLE_A UNCServerName
,
882 PRPC_STRING BackupFileName
,
885 PIELF_HANDLE LogHandle
)
888 UNICODE_STRING BackupFileNameW
;
890 DPRINT("ElfrOpenBELA(%Z)\n", BackupFileName
);
892 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
893 (PANSI_STRING
)BackupFileName
,
895 if (!NT_SUCCESS(Status
))
897 DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status
);
901 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
903 RtlFreeUnicodeString(&BackupFileNameW
);
904 return STATUS_INVALID_PARAMETER
;
907 /* FIXME: UNCServerName must specify the server */
909 /* FIXME: Must verify that caller has read access */
911 Status
= ElfCreateBackupLogHandle((PLOGHANDLE
*)LogHandle
,
914 RtlFreeUnicodeString(&BackupFileNameW
);
923 IELF_HANDLE LogHandle
,
926 RULONG NumberOfBytesToRead
,
928 PULONG NumberOfBytesRead
,
929 PULONG MinNumberOfBytesNeeded
)
932 PLOGHANDLE pLogHandle
;
935 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
937 return STATUS_INVALID_HANDLE
;
940 return STATUS_INVALID_PARAMETER
;
942 /* If sequential read, retrieve the CurrentRecord from this log handle */
943 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
945 RecordNumber
= pLogHandle
->CurrentRecord
;
947 else // (ReadFlags & EVENTLOG_SEEK_READ)
949 RecordNumber
= RecordOffset
;
952 Status
= LogfReadEvents(pLogHandle
->LogFile
,
958 MinNumberOfBytesNeeded
,
961 /* Update the handle's CurrentRecord if success */
962 if (NT_SUCCESS(Status
))
964 pLogHandle
->CurrentRecord
= RecordNumber
;
974 IELF_HANDLE LogHandle
,
977 USHORT EventCategory
,
981 PRPC_STRING ComputerName
,
983 PRPC_STRING Strings
[],
989 NTSTATUS Status
= STATUS_SUCCESS
;
990 UNICODE_STRING ComputerNameW
;
991 PUNICODE_STRING
*StringsArrayW
= NULL
;
994 DPRINT("ElfrReportEventA(%hu)\n", NumStrings
);
997 for (i
= 0; i
< NumStrings
; i
++)
999 if (Strings
[i
] == NULL
)
1001 DPRINT1("String %hu is null\n", i
);
1005 DPRINT1("String %hu: %Z\n", i
, Strings
[i
]);
1010 Status
= RtlAnsiStringToUnicodeString((PUNICODE_STRING
)&ComputerNameW
,
1011 (PANSI_STRING
)ComputerName
,
1013 if (!NT_SUCCESS(Status
))
1016 if (NumStrings
!= 0)
1018 StringsArrayW
= HeapAlloc(GetProcessHeap(),
1020 NumStrings
* sizeof(PUNICODE_STRING
));
1021 if (StringsArrayW
== NULL
)
1023 Status
= STATUS_NO_MEMORY
;
1027 for (i
= 0; i
< NumStrings
; i
++)
1029 if (Strings
[i
] != NULL
)
1031 StringsArrayW
[i
] = HeapAlloc(GetProcessHeap(),
1033 sizeof(UNICODE_STRING
));
1034 if (StringsArrayW
[i
] == NULL
)
1036 Status
= STATUS_NO_MEMORY
;
1040 Status
= RtlAnsiStringToUnicodeString(StringsArrayW
[i
],
1041 (PANSI_STRING
)Strings
[i
],
1045 if (!NT_SUCCESS(Status
))
1050 if (NT_SUCCESS(Status
))
1052 Status
= ElfrReportEventW(LogHandle
,
1059 (PRPC_UNICODE_STRING
)&ComputerNameW
,
1061 (PRPC_UNICODE_STRING
*)StringsArrayW
,
1069 if (StringsArrayW
!= NULL
)
1071 for (i
= 0; i
< NumStrings
; i
++)
1073 if ((StringsArrayW
[i
] != NULL
) && (StringsArrayW
[i
]->Buffer
))
1075 RtlFreeUnicodeString(StringsArrayW
[i
]);
1076 HeapFree(GetProcessHeap(), 0, StringsArrayW
[i
]);
1080 HeapFree(GetProcessHeap(), 0, StringsArrayW
);
1083 RtlFreeUnicodeString(&ComputerNameW
);
1091 ElfrRegisterClusterSvc(
1092 handle_t BindingHandle
)
1095 return STATUS_NOT_IMPLEMENTED
;
1101 ElfrDeregisterClusterSvc(
1102 handle_t BindingHandle
)
1105 return STATUS_NOT_IMPLEMENTED
;
1111 ElfrWriteClusterEvents(
1112 handle_t BindingHandle
)
1115 return STATUS_NOT_IMPLEMENTED
;
1121 ElfrGetLogInformation(
1122 IELF_HANDLE LogHandle
,
1126 PULONG pcbBytesNeeded
)
1128 NTSTATUS Status
= STATUS_SUCCESS
;
1129 PLOGHANDLE pLogHandle
;
1132 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
1134 return STATUS_INVALID_HANDLE
;
1136 pLogFile
= pLogHandle
->LogFile
;
1138 /* Lock the log file shared */
1139 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
1143 case EVENTLOG_FULL_INFO
:
1145 LPEVENTLOG_FULL_INFORMATION efi
= (LPEVENTLOG_FULL_INFORMATION
)Buffer
;
1147 *pcbBytesNeeded
= sizeof(EVENTLOG_FULL_INFORMATION
);
1148 if (cbBufSize
< sizeof(EVENTLOG_FULL_INFORMATION
))
1150 Status
= STATUS_BUFFER_TOO_SMALL
;
1154 efi
->dwFull
= !!(ElfGetFlags(&pLogFile
->LogFile
) & ELF_LOGFILE_LOGFULL_WRITTEN
);
1159 Status
= STATUS_INVALID_LEVEL
;
1163 /* Unlock the log file */
1164 RtlReleaseResource(&pLogFile
->Lock
);
1173 IELF_HANDLE LogHandle
)
1176 PLOGHANDLE pLogHandle
;
1179 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
1181 return STATUS_INVALID_HANDLE
;
1183 pLogFile
= pLogHandle
->LogFile
;
1185 /* Lock the log file exclusive */
1186 RtlAcquireResourceExclusive(&pLogFile
->Lock
, TRUE
);
1188 Status
= ElfFlushFile(&pLogFile
->LogFile
);
1190 /* Unlock the log file */
1191 RtlReleaseResource(&pLogFile
->Lock
);
1199 ElfrReportEventAndSourceW(
1200 IELF_HANDLE LogHandle
,
1203 USHORT EventCategory
,
1205 PRPC_UNICODE_STRING SourceName
,
1208 PRPC_UNICODE_STRING ComputerName
,
1210 PRPC_UNICODE_STRING Strings
[],
1213 PULONG RecordNumber
,
1216 /* Call the helper function. The event source is specified by the caller. */
1217 return ElfrIntReportEventW(LogHandle
,
1235 void __RPC_FAR
*__RPC_USER
midl_user_allocate(SIZE_T len
)
1237 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1241 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1243 HeapFree(GetProcessHeap(), 0, ptr
);
1247 void __RPC_USER
IELF_HANDLE_rundown(IELF_HANDLE LogHandle
)
1249 /* Close the handle */
1250 ElfDeleteEventLogHandle(&LogHandle
); // ElfrCloseEL(&LogHandle);