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
;
290 IELF_HANDLE LogHandle
,
291 PRPC_UNICODE_STRING BackupFileName
)
293 PLOGHANDLE pLogHandle
;
295 DPRINT("ElfrClearELFW()\n");
297 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
299 return STATUS_INVALID_HANDLE
;
301 /* Fail, if the log file is a backup file */
302 if (pLogHandle
->Flags
& LOG_HANDLE_BACKUP_FILE
)
303 return STATUS_INVALID_HANDLE
;
305 return LogfClearFile(pLogHandle
->LogFile
,
306 (PUNICODE_STRING
)BackupFileName
);
314 IELF_HANDLE LogHandle
,
315 PRPC_UNICODE_STRING BackupFileName
)
317 PLOGHANDLE pLogHandle
;
319 DPRINT("ElfrBackupELFW()\n");
321 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
323 return STATUS_INVALID_HANDLE
;
325 return LogfBackupFile(pLogHandle
->LogFile
,
326 (PUNICODE_STRING
)BackupFileName
);
334 PIELF_HANDLE LogHandle
)
336 return ElfDeleteEventLogHandle(LogHandle
);
343 ElfrDeregisterEventSource(
344 PIELF_HANDLE LogHandle
)
346 return ElfDeleteEventLogHandle(LogHandle
);
354 IELF_HANDLE LogHandle
,
355 PULONG NumberOfRecords
)
357 PLOGHANDLE pLogHandle
;
359 ULONG OldestRecordNumber
, CurrentRecordNumber
;
361 DPRINT("ElfrNumberOfRecords()\n");
363 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
365 return STATUS_INVALID_HANDLE
;
367 if (!NumberOfRecords
)
368 return STATUS_INVALID_PARAMETER
;
370 pLogFile
= pLogHandle
->LogFile
;
372 /* Lock the log file shared */
373 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
375 OldestRecordNumber
= ElfGetOldestRecord(&pLogFile
->LogFile
);
376 CurrentRecordNumber
= ElfGetCurrentRecord(&pLogFile
->LogFile
);
378 /* Unlock the log file */
379 RtlReleaseResource(&pLogFile
->Lock
);
381 DPRINT("Oldest: %lu Current: %lu\n",
382 OldestRecordNumber
, CurrentRecordNumber
);
384 if (OldestRecordNumber
== 0)
386 /* OldestRecordNumber == 0 when the log is empty */
387 *NumberOfRecords
= 0;
391 /* The log contains events */
392 *NumberOfRecords
= CurrentRecordNumber
- OldestRecordNumber
;
395 return STATUS_SUCCESS
;
403 IELF_HANDLE LogHandle
,
404 PULONG OldestRecordNumber
)
406 PLOGHANDLE pLogHandle
;
409 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
411 return STATUS_INVALID_HANDLE
;
413 if (!OldestRecordNumber
)
414 return STATUS_INVALID_PARAMETER
;
416 pLogFile
= pLogHandle
->LogFile
;
418 /* Lock the log file shared */
419 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
421 *OldestRecordNumber
= ElfGetOldestRecord(&pLogFile
->LogFile
);
423 /* Unlock the log file */
424 RtlReleaseResource(&pLogFile
->Lock
);
426 return STATUS_SUCCESS
;
434 IELF_HANDLE LogHandle
,
435 RPC_CLIENT_ID ClientId
,
439 return STATUS_NOT_IMPLEMENTED
;
447 EVENTLOG_HANDLE_W UNCServerName
,
448 PRPC_UNICODE_STRING ModuleName
,
449 PRPC_UNICODE_STRING RegModuleName
,
452 PIELF_HANDLE LogHandle
)
454 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
455 return STATUS_INVALID_PARAMETER
;
457 /* RegModuleName must be an empty string */
458 if (RegModuleName
->Length
> 0)
459 return STATUS_INVALID_PARAMETER
;
461 /* FIXME: UNCServerName must specify the server */
463 /* FIXME: Must verify that caller has read access */
465 return ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
466 (PUNICODE_STRING
)ModuleName
,
474 ElfrRegisterEventSourceW(
475 EVENTLOG_HANDLE_W UNCServerName
,
476 PRPC_UNICODE_STRING ModuleName
,
477 PRPC_UNICODE_STRING RegModuleName
,
480 PIELF_HANDLE LogHandle
)
482 DPRINT("ElfrRegisterEventSourceW()\n");
484 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
485 return STATUS_INVALID_PARAMETER
;
487 /* RegModuleName must be an empty string */
488 if (RegModuleName
->Length
> 0)
489 return STATUS_INVALID_PARAMETER
;
491 DPRINT("ModuleName: %wZ\n", ModuleName
);
493 /* FIXME: UNCServerName must specify the server or empty for local */
495 /* FIXME: Must verify that caller has write access */
497 return ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
498 (PUNICODE_STRING
)ModuleName
,
507 EVENTLOG_HANDLE_W UNCServerName
,
508 PRPC_UNICODE_STRING BackupFileName
,
511 PIELF_HANDLE LogHandle
)
513 DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName
);
515 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
516 return STATUS_INVALID_PARAMETER
;
518 /* FIXME: UNCServerName must specify the server */
520 /* FIXME: Must verify that caller has read access */
522 return ElfCreateBackupLogHandle((PLOGHANDLE
*)LogHandle
,
523 (PUNICODE_STRING
)BackupFileName
);
531 IELF_HANDLE LogHandle
,
534 RULONG NumberOfBytesToRead
,
536 PULONG NumberOfBytesRead
,
537 PULONG MinNumberOfBytesNeeded
)
540 PLOGHANDLE pLogHandle
;
543 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
545 return STATUS_INVALID_HANDLE
;
548 return STATUS_INVALID_PARAMETER
;
550 /* If sequential read, retrieve the CurrentRecord from this log handle */
551 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
553 RecordNumber
= pLogHandle
->CurrentRecord
;
555 else // (ReadFlags & EVENTLOG_SEEK_READ)
557 RecordNumber
= RecordOffset
;
560 Status
= LogfReadEvents(pLogHandle
->LogFile
,
566 MinNumberOfBytesNeeded
,
569 /* Update the handle's CurrentRecord if success */
570 if (NT_SUCCESS(Status
))
572 pLogHandle
->CurrentRecord
= RecordNumber
;
579 /* Helper function for ElfrReportEventW/A and ElfrReportEventAndSourceW */
582 IELF_HANDLE LogHandle
,
585 USHORT EventCategory
,
587 PRPC_UNICODE_STRING SourceName OPTIONAL
,
590 PRPC_UNICODE_STRING ComputerName
,
592 PRPC_UNICODE_STRING Strings
[],
599 PLOGHANDLE pLogHandle
;
600 UNICODE_STRING LocalSourceName
, LocalComputerName
;
601 PEVENTLOGRECORD LogBuffer
;
604 ULONG dwStringsSize
= 0;
605 ULONG dwUserSidLength
= 0;
606 PWSTR lpStrings
, str
;
608 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
610 return STATUS_INVALID_HANDLE
;
612 /* Flags must be 0 */
614 return STATUS_INVALID_PARAMETER
;
616 for (i
= 0; i
< NumStrings
; i
++)
620 case EVENTLOG_SUCCESS
:
621 DPRINT("Success: %wZ\n", Strings
[i
]);
624 case EVENTLOG_ERROR_TYPE
:
625 DPRINT("Error: %wZ\n", Strings
[i
]);
628 case EVENTLOG_WARNING_TYPE
:
629 DPRINT("Warning: %wZ\n", Strings
[i
]);
632 case EVENTLOG_INFORMATION_TYPE
:
633 DPRINT("Info: %wZ\n", Strings
[i
]);
636 case EVENTLOG_AUDIT_SUCCESS
:
637 DPRINT("Audit Success: %wZ\n", Strings
[i
]);
640 case EVENTLOG_AUDIT_FAILURE
:
641 DPRINT("Audit Failure: %wZ\n", Strings
[i
]);
645 DPRINT1("Type %hu: %wZ\n", EventType
, Strings
[i
]);
648 dwStringsSize
+= Strings
[i
]->Length
+ sizeof(UNICODE_NULL
);
651 lpStrings
= HeapAlloc(GetProcessHeap(), 0, dwStringsSize
);
654 DPRINT1("Failed to allocate heap\n");
655 return STATUS_NO_MEMORY
;
659 for (i
= 0; i
< NumStrings
; i
++)
661 RtlCopyMemory(str
, Strings
[i
]->Buffer
, Strings
[i
]->Length
);
662 str
+= Strings
[i
]->Length
/ sizeof(WCHAR
);
668 dwUserSidLength
= FIELD_OFFSET(SID
, SubAuthority
[UserSID
->SubAuthorityCount
]);
670 if (SourceName
&& SourceName
->Buffer
)
671 LocalSourceName
= *(PUNICODE_STRING
)SourceName
;
673 RtlInitUnicodeString(&LocalSourceName
, pLogHandle
->szName
);
675 LocalComputerName
= *(PUNICODE_STRING
)ComputerName
;
677 LogBuffer
= LogfAllocAndBuildNewRecord(&RecSize
,
690 if (LogBuffer
== NULL
)
692 DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
693 HeapFree(GetProcessHeap(), 0, lpStrings
);
694 return STATUS_NO_MEMORY
;
697 Status
= LogfWriteRecord(pLogHandle
->LogFile
, LogBuffer
, RecSize
);
698 if (!NT_SUCCESS(Status
))
700 DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
701 pLogHandle
->LogFile
->LogName
, Status
);
704 if (NT_SUCCESS(Status
))
706 /* Retrieve the two fields that were set by LogfWriteRecord into the record */
708 *RecordNumber
= LogBuffer
->RecordNumber
;
710 *TimeWritten
= LogBuffer
->TimeWritten
;
713 LogfFreeRecord(LogBuffer
);
715 HeapFree(GetProcessHeap(), 0, lpStrings
);
725 IELF_HANDLE LogHandle
,
728 USHORT EventCategory
,
732 PRPC_UNICODE_STRING ComputerName
,
734 PRPC_UNICODE_STRING Strings
[],
740 /* Call the helper function. The event source is provided via the log handle. */
741 return ElfrIntReportEventW(LogHandle
,
763 IELF_HANDLE LogHandle
,
764 PRPC_STRING BackupFileName
)
767 UNICODE_STRING BackupFileNameW
;
769 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
770 (PANSI_STRING
)BackupFileName
,
772 if (!NT_SUCCESS(Status
))
775 Status
= ElfrClearELFW(LogHandle
,
776 (PRPC_UNICODE_STRING
)&BackupFileNameW
);
778 RtlFreeUnicodeString(&BackupFileNameW
);
788 IELF_HANDLE LogHandle
,
789 PRPC_STRING BackupFileName
)
792 UNICODE_STRING BackupFileNameW
;
794 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
795 (PANSI_STRING
)BackupFileName
,
797 if (!NT_SUCCESS(Status
))
800 Status
= ElfrBackupELFW(LogHandle
,
801 (PRPC_UNICODE_STRING
)&BackupFileNameW
);
803 RtlFreeUnicodeString(&BackupFileNameW
);
813 EVENTLOG_HANDLE_A UNCServerName
,
814 PRPC_STRING ModuleName
,
815 PRPC_STRING RegModuleName
,
818 PIELF_HANDLE LogHandle
)
821 UNICODE_STRING ModuleNameW
;
823 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
824 return STATUS_INVALID_PARAMETER
;
826 /* RegModuleName must be an empty string */
827 if (RegModuleName
->Length
> 0)
828 return STATUS_INVALID_PARAMETER
;
830 Status
= RtlAnsiStringToUnicodeString(&ModuleNameW
, (PANSI_STRING
)ModuleName
, TRUE
);
831 if (!NT_SUCCESS(Status
))
834 /* FIXME: Must verify that caller has read access */
836 Status
= ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
840 RtlFreeUnicodeString(&ModuleNameW
);
849 ElfrRegisterEventSourceA(
850 EVENTLOG_HANDLE_A UNCServerName
,
851 PRPC_STRING ModuleName
,
852 PRPC_STRING RegModuleName
,
855 PIELF_HANDLE LogHandle
)
858 UNICODE_STRING ModuleNameW
;
860 Status
= RtlAnsiStringToUnicodeString(&ModuleNameW
,
861 (PANSI_STRING
)ModuleName
,
863 if (!NT_SUCCESS(Status
))
865 DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status
);
869 /* RegModuleName must be an empty string */
870 if (RegModuleName
->Length
> 0)
872 RtlFreeUnicodeString(&ModuleNameW
);
873 return STATUS_INVALID_PARAMETER
;
876 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
878 RtlFreeUnicodeString(&ModuleNameW
);
879 return STATUS_INVALID_PARAMETER
;
882 /* FIXME: Must verify that caller has write access */
884 Status
= ElfCreateEventLogHandle((PLOGHANDLE
*)LogHandle
,
888 RtlFreeUnicodeString(&ModuleNameW
);
898 EVENTLOG_HANDLE_A UNCServerName
,
899 PRPC_STRING BackupFileName
,
902 PIELF_HANDLE LogHandle
)
905 UNICODE_STRING BackupFileNameW
;
907 DPRINT("ElfrOpenBELA(%Z)\n", BackupFileName
);
909 Status
= RtlAnsiStringToUnicodeString(&BackupFileNameW
,
910 (PANSI_STRING
)BackupFileName
,
912 if (!NT_SUCCESS(Status
))
914 DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status
);
918 if ((MajorVersion
!= 1) || (MinorVersion
!= 1))
920 RtlFreeUnicodeString(&BackupFileNameW
);
921 return STATUS_INVALID_PARAMETER
;
924 /* FIXME: UNCServerName must specify the server */
926 /* FIXME: Must verify that caller has read access */
928 Status
= ElfCreateBackupLogHandle((PLOGHANDLE
*)LogHandle
,
931 RtlFreeUnicodeString(&BackupFileNameW
);
941 IELF_HANDLE LogHandle
,
944 RULONG NumberOfBytesToRead
,
946 PULONG NumberOfBytesRead
,
947 PULONG MinNumberOfBytesNeeded
)
950 PLOGHANDLE pLogHandle
;
953 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
955 return STATUS_INVALID_HANDLE
;
958 return STATUS_INVALID_PARAMETER
;
960 /* If sequential read, retrieve the CurrentRecord from this log handle */
961 if (ReadFlags
& EVENTLOG_SEQUENTIAL_READ
)
963 RecordNumber
= pLogHandle
->CurrentRecord
;
965 else // (ReadFlags & EVENTLOG_SEEK_READ)
967 RecordNumber
= RecordOffset
;
970 Status
= LogfReadEvents(pLogHandle
->LogFile
,
976 MinNumberOfBytesNeeded
,
979 /* Update the handle's CurrentRecord if success */
980 if (NT_SUCCESS(Status
))
982 pLogHandle
->CurrentRecord
= RecordNumber
;
993 IELF_HANDLE LogHandle
,
996 USHORT EventCategory
,
1000 PRPC_STRING ComputerName
,
1002 PRPC_STRING Strings
[],
1005 PULONG RecordNumber
,
1008 NTSTATUS Status
= STATUS_SUCCESS
;
1009 UNICODE_STRING ComputerNameW
;
1010 PUNICODE_STRING
*StringsArrayW
= NULL
;
1013 DPRINT("ElfrReportEventA(%hu)\n", NumStrings
);
1016 for (i
= 0; i
< NumStrings
; i
++)
1018 if (Strings
[i
] == NULL
)
1020 DPRINT1("String %hu is null\n", i
);
1024 DPRINT1("String %hu: %Z\n", i
, Strings
[i
]);
1029 Status
= RtlAnsiStringToUnicodeString((PUNICODE_STRING
)&ComputerNameW
,
1030 (PANSI_STRING
)ComputerName
,
1032 if (!NT_SUCCESS(Status
))
1035 if (NumStrings
!= 0)
1037 StringsArrayW
= HeapAlloc(GetProcessHeap(),
1039 NumStrings
* sizeof(PUNICODE_STRING
));
1040 if (StringsArrayW
== NULL
)
1042 Status
= STATUS_NO_MEMORY
;
1046 for (i
= 0; i
< NumStrings
; i
++)
1048 if (Strings
[i
] != NULL
)
1050 StringsArrayW
[i
] = HeapAlloc(GetProcessHeap(),
1052 sizeof(UNICODE_STRING
));
1053 if (StringsArrayW
[i
] == NULL
)
1055 Status
= STATUS_NO_MEMORY
;
1059 Status
= RtlAnsiStringToUnicodeString(StringsArrayW
[i
],
1060 (PANSI_STRING
)Strings
[i
],
1064 if (!NT_SUCCESS(Status
))
1069 if (NT_SUCCESS(Status
))
1071 Status
= ElfrReportEventW(LogHandle
,
1078 (PRPC_UNICODE_STRING
)&ComputerNameW
,
1080 (PRPC_UNICODE_STRING
*)StringsArrayW
,
1088 if (StringsArrayW
!= NULL
)
1090 for (i
= 0; i
< NumStrings
; i
++)
1092 if ((StringsArrayW
[i
] != NULL
) && (StringsArrayW
[i
]->Buffer
))
1094 RtlFreeUnicodeString(StringsArrayW
[i
]);
1095 HeapFree(GetProcessHeap(), 0, StringsArrayW
[i
]);
1099 HeapFree(GetProcessHeap(), 0, StringsArrayW
);
1102 RtlFreeUnicodeString(&ComputerNameW
);
1111 ElfrRegisterClusterSvc(
1112 handle_t BindingHandle
)
1115 return STATUS_NOT_IMPLEMENTED
;
1122 ElfrDeregisterClusterSvc(
1123 handle_t BindingHandle
)
1126 return STATUS_NOT_IMPLEMENTED
;
1133 ElfrWriteClusterEvents(
1134 handle_t BindingHandle
)
1137 return STATUS_NOT_IMPLEMENTED
;
1144 ElfrGetLogInformation(
1145 IELF_HANDLE LogHandle
,
1149 PULONG pcbBytesNeeded
)
1151 NTSTATUS Status
= STATUS_SUCCESS
;
1152 PLOGHANDLE pLogHandle
;
1155 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
1157 return STATUS_INVALID_HANDLE
;
1159 pLogFile
= pLogHandle
->LogFile
;
1161 /* Lock the log file shared */
1162 RtlAcquireResourceShared(&pLogFile
->Lock
, TRUE
);
1166 case EVENTLOG_FULL_INFO
:
1168 LPEVENTLOG_FULL_INFORMATION efi
= (LPEVENTLOG_FULL_INFORMATION
)Buffer
;
1170 *pcbBytesNeeded
= sizeof(EVENTLOG_FULL_INFORMATION
);
1171 if (cbBufSize
< sizeof(EVENTLOG_FULL_INFORMATION
))
1173 Status
= STATUS_BUFFER_TOO_SMALL
;
1177 efi
->dwFull
= !!(ElfGetFlags(&pLogFile
->LogFile
) & ELF_LOGFILE_LOGFULL_WRITTEN
);
1182 Status
= STATUS_INVALID_LEVEL
;
1186 /* Unlock the log file */
1187 RtlReleaseResource(&pLogFile
->Lock
);
1197 IELF_HANDLE LogHandle
)
1200 PLOGHANDLE pLogHandle
;
1203 pLogHandle
= ElfGetLogHandleEntryByHandle(LogHandle
);
1205 return STATUS_INVALID_HANDLE
;
1207 pLogFile
= pLogHandle
->LogFile
;
1209 /* Lock the log file exclusive */
1210 RtlAcquireResourceExclusive(&pLogFile
->Lock
, TRUE
);
1212 Status
= ElfFlushFile(&pLogFile
->LogFile
);
1214 /* Unlock the log file */
1215 RtlReleaseResource(&pLogFile
->Lock
);
1224 ElfrReportEventAndSourceW(
1225 IELF_HANDLE LogHandle
,
1228 USHORT EventCategory
,
1230 PRPC_UNICODE_STRING SourceName
,
1233 PRPC_UNICODE_STRING ComputerName
,
1235 PRPC_UNICODE_STRING Strings
[],
1238 PULONG RecordNumber
,
1241 /* Call the helper function. The event source is specified by the caller. */
1242 return ElfrIntReportEventW(LogHandle
,
1260 void __RPC_FAR
*__RPC_USER
midl_user_allocate(SIZE_T len
)
1262 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1266 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1268 HeapFree(GetProcessHeap(), 0, ptr
);
1272 void __RPC_USER
IELF_HANDLE_rundown(IELF_HANDLE LogHandle
)
1274 /* Close the handle */
1275 ElfDeleteEventLogHandle(&LogHandle
); // ElfrCloseEL(&LogHandle);