xref: /reactos/dll/win32/advapi32/service/eventlog.c (revision 12e94103)
1 /*
2  * Win32 advapi functions
3  *
4  * Copyright 1995 Sven Verdoolaege
5  * Copyright 1998 Juergen Schmied
6  * Copyright 2003 Mike Hearn
7  * Copyright 2007 Hervé Poussineau
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 /* INCLUDES ******************************************************************/
25 
26 #include <advapi32.h>
27 
28 #include <ndk/kefuncs.h>
29 #include <eventlogrpc_c.h>
30 
31 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
32 
33 static RPC_UNICODE_STRING EmptyStringU = { 0, 0, L"" };
34 static RPC_STRING EmptyStringA = { 0, 0, "" };
35 
36 
37 /* FUNCTIONS *****************************************************************/
38 
39 handle_t __RPC_USER
40 EVENTLOG_HANDLE_A_bind(EVENTLOG_HANDLE_A UNCServerName)
41 {
42     handle_t hBinding = NULL;
43     RPC_CSTR pszStringBinding;
44     RPC_STATUS Status;
45 
46     TRACE("EVENTLOG_HANDLE_A_bind() called\n");
47 
48     Status = RpcStringBindingComposeA(NULL,
49                                       (RPC_CSTR)"ncacn_np",
50                                       (RPC_CSTR)UNCServerName,
51                                       (RPC_CSTR)"\\pipe\\EventLog",
52                                       NULL,
53                                       &pszStringBinding);
54     if (Status)
55     {
56         ERR("RpcStringBindingCompose returned 0x%x\n", Status);
57         return NULL;
58     }
59 
60     /* Set the binding handle that will be used to bind to the server. */
61     Status = RpcBindingFromStringBindingA(pszStringBinding,
62                                           &hBinding);
63     if (Status != RPC_S_OK)
64     {
65         ERR("RpcBindingFromStringBinding returned 0x%x\n", Status);
66     }
67 
68     Status = RpcStringFreeA(&pszStringBinding);
69     if (Status != RPC_S_OK)
70     {
71         ERR("RpcStringFree returned 0x%x\n", Status);
72     }
73 
74     return hBinding;
75 }
76 
77 
78 void __RPC_USER
79 EVENTLOG_HANDLE_A_unbind(EVENTLOG_HANDLE_A UNCServerName,
80                          handle_t hBinding)
81 {
82     RPC_STATUS Status;
83 
84     TRACE("EVENTLOG_HANDLE_A_unbind() called\n");
85 
86     Status = RpcBindingFree(&hBinding);
87     if (Status != RPC_S_OK)
88     {
89         ERR("RpcBindingFree returned 0x%x\n", Status);
90     }
91 }
92 
93 
94 handle_t __RPC_USER
95 EVENTLOG_HANDLE_W_bind(EVENTLOG_HANDLE_W UNCServerName)
96 {
97     handle_t hBinding = NULL;
98     RPC_WSTR pszStringBinding;
99     RPC_STATUS Status;
100 
101     TRACE("EVENTLOG_HANDLE_W_bind() called\n");
102 
103     Status = RpcStringBindingComposeW(NULL,
104                                       L"ncacn_np",
105                                       UNCServerName,
106                                       L"\\pipe\\EventLog",
107                                       NULL,
108                                       &pszStringBinding);
109     if (Status != RPC_S_OK)
110     {
111         ERR("RpcStringBindingCompose returned 0x%x\n", Status);
112         return NULL;
113     }
114 
115     /* Set the binding handle that will be used to bind to the server. */
116     Status = RpcBindingFromStringBindingW(pszStringBinding,
117                                           &hBinding);
118     if (Status != RPC_S_OK)
119     {
120         ERR("RpcBindingFromStringBinding returned 0x%x\n", Status);
121     }
122 
123     Status = RpcStringFreeW(&pszStringBinding);
124     if (Status != RPC_S_OK)
125     {
126         ERR("RpcStringFree returned 0x%x\n", Status);
127     }
128 
129     return hBinding;
130 }
131 
132 
133 void __RPC_USER
134 EVENTLOG_HANDLE_W_unbind(EVENTLOG_HANDLE_W UNCServerName,
135                          handle_t hBinding)
136 {
137     RPC_STATUS Status;
138 
139     TRACE("EVENTLOG_HANDLE_W_unbind() called\n");
140 
141     Status = RpcBindingFree(&hBinding);
142     if (Status != RPC_S_OK)
143     {
144         ERR("RpcBindingFree returned 0x%x\n", Status);
145     }
146 }
147 
148 
149 /******************************************************************************
150  * BackupEventLogA [ADVAPI32.@]
151  */
152 NTSTATUS
153 NTAPI
154 ElfBackupEventLogFileA(IN HANDLE hEventLog,
155                        IN PANSI_STRING BackupFileNameA)
156 {
157     NTSTATUS Status;
158 
159     if (!BackupFileNameA || (BackupFileNameA->Length == 0))
160         return STATUS_INVALID_PARAMETER;
161 
162     RpcTryExcept
163     {
164         Status = ElfrBackupELFA(hEventLog,
165                                 (PRPC_STRING)BackupFileNameA);
166     }
167     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
168     {
169         Status = I_RpcMapWin32Status(RpcExceptionCode());
170     }
171     RpcEndExcept;
172 
173     return Status;
174 }
175 
176 BOOL WINAPI
177 BackupEventLogA(IN HANDLE hEventLog,
178                 IN LPCSTR lpBackupFileName)
179 {
180     BOOL Success;
181     NTSTATUS Status;
182     ANSI_STRING BackupFileNameA;
183     UNICODE_STRING BackupFileNameW;
184 
185     TRACE("%p, %s\n", hEventLog, lpBackupFileName);
186 
187     if (lpBackupFileName == NULL)
188     {
189         SetLastError(ERROR_INVALID_PARAMETER);
190         return FALSE;
191     }
192 
193     RtlInitAnsiString(&BackupFileNameA, lpBackupFileName);
194 
195     Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
196                                           &BackupFileNameA,
197                                           TRUE);
198     if (!NT_SUCCESS(Status))
199     {
200         SetLastError(RtlNtStatusToDosError(Status));
201         return FALSE;
202     }
203 
204     Success = BackupEventLogW(hEventLog,
205                               BackupFileNameW.Buffer);
206 
207     RtlFreeUnicodeString(&BackupFileNameW);
208 
209     return Success;
210 }
211 
212 
213 /******************************************************************************
214  * BackupEventLogW [ADVAPI32.@]
215  *
216  * PARAMS
217  *   hEventLog        []
218  *   lpBackupFileName []
219  */
220 NTSTATUS
221 NTAPI
222 ElfBackupEventLogFileW(IN HANDLE hEventLog,
223                        IN PUNICODE_STRING BackupFileNameU)
224 {
225     NTSTATUS Status;
226 
227     if (!BackupFileNameU || (BackupFileNameU->Length == 0))
228         return STATUS_INVALID_PARAMETER;
229 
230     RpcTryExcept
231     {
232         Status = ElfrBackupELFW(hEventLog,
233                                 (PRPC_UNICODE_STRING)BackupFileNameU);
234     }
235     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
236     {
237         Status = I_RpcMapWin32Status(RpcExceptionCode());
238     }
239     RpcEndExcept;
240 
241     return Status;
242 }
243 
244 BOOL WINAPI
245 BackupEventLogW(IN HANDLE hEventLog,
246                 IN LPCWSTR lpBackupFileName)
247 {
248     NTSTATUS Status;
249     UNICODE_STRING BackupFileName;
250 
251     TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
252 
253     if (lpBackupFileName == NULL)
254     {
255         SetLastError(ERROR_INVALID_PARAMETER);
256         return FALSE;
257     }
258 
259     if (!RtlDosPathNameToNtPathName_U(lpBackupFileName, &BackupFileName,
260                                       NULL, NULL))
261     {
262         SetLastError(ERROR_INVALID_PARAMETER);
263         return FALSE;
264     }
265 
266     Status = ElfBackupEventLogFileW(hEventLog, &BackupFileName);
267 
268     RtlFreeHeap(RtlGetProcessHeap(), 0, BackupFileName.Buffer);
269 
270     if (!NT_SUCCESS(Status))
271     {
272         SetLastError(RtlNtStatusToDosError(Status));
273         return FALSE;
274     }
275 
276     return TRUE;
277 }
278 
279 
280 /******************************************************************************
281  * ClearEventLogA [ADVAPI32.@]
282  */
283 NTSTATUS
284 NTAPI
285 ElfClearEventLogFileA(IN HANDLE hEventLog,
286                       IN PANSI_STRING BackupFileNameA)
287 {
288     NTSTATUS Status;
289 
290     RpcTryExcept
291     {
292         Status = ElfrClearELFA(hEventLog,
293                                (PRPC_STRING)BackupFileNameA);
294     }
295     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
296     {
297         Status = I_RpcMapWin32Status(RpcExceptionCode());
298     }
299     RpcEndExcept;
300 
301     return Status;
302 }
303 
304 BOOL WINAPI
305 ClearEventLogA(IN HANDLE hEventLog,
306                IN LPCSTR lpBackupFileName)
307 {
308     BOOL Success;
309     NTSTATUS Status;
310     ANSI_STRING BackupFileNameA;
311     UNICODE_STRING BackupFileNameW;
312 
313     TRACE("%p, %s\n", hEventLog, lpBackupFileName);
314 
315     if (lpBackupFileName == NULL)
316     {
317         RtlInitUnicodeString(&BackupFileNameW, NULL);
318     }
319     else
320     {
321         RtlInitAnsiString(&BackupFileNameA, lpBackupFileName);
322 
323         Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
324                                               &BackupFileNameA,
325                                               TRUE);
326         if (!NT_SUCCESS(Status))
327         {
328             SetLastError(RtlNtStatusToDosError(Status));
329             return FALSE;
330         }
331     }
332 
333     Success = ClearEventLogW(hEventLog,
334                              BackupFileNameW.Buffer);
335 
336     RtlFreeUnicodeString(&BackupFileNameW);
337 
338     return Success;
339 }
340 
341 
342 /******************************************************************************
343  * ClearEventLogW [ADVAPI32.@]
344  */
345 NTSTATUS
346 NTAPI
347 ElfClearEventLogFileW(IN HANDLE hEventLog,
348                       IN PUNICODE_STRING BackupFileNameU)
349 {
350     NTSTATUS Status;
351 
352     RpcTryExcept
353     {
354         Status = ElfrClearELFW(hEventLog,
355                                (PRPC_UNICODE_STRING)BackupFileNameU);
356     }
357     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
358     {
359         Status = I_RpcMapWin32Status(RpcExceptionCode());
360     }
361     RpcEndExcept;
362 
363     return Status;
364 }
365 
366 BOOL WINAPI
367 ClearEventLogW(IN HANDLE hEventLog,
368                IN LPCWSTR lpBackupFileName)
369 {
370     NTSTATUS Status;
371     UNICODE_STRING BackupFileName;
372 
373     TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
374 
375     if (lpBackupFileName == NULL)
376     {
377         RtlInitUnicodeString(&BackupFileName, NULL);
378     }
379     else
380     {
381         if (!RtlDosPathNameToNtPathName_U(lpBackupFileName, &BackupFileName,
382                                           NULL, NULL))
383         {
384             SetLastError(ERROR_INVALID_PARAMETER);
385             return FALSE;
386         }
387     }
388 
389     Status = ElfClearEventLogFileW(hEventLog, &BackupFileName);
390 
391     if (lpBackupFileName != NULL)
392         RtlFreeHeap(RtlGetProcessHeap(), 0, BackupFileName.Buffer);
393 
394     if (!NT_SUCCESS(Status))
395     {
396         SetLastError(RtlNtStatusToDosError(Status));
397         return FALSE;
398     }
399 
400     return TRUE;
401 }
402 
403 
404 /******************************************************************************
405  * CloseEventLog [ADVAPI32.@]
406  */
407 NTSTATUS
408 NTAPI
409 ElfCloseEventLog(IN HANDLE hEventLog)
410 {
411     NTSTATUS Status;
412 
413     RpcTryExcept
414     {
415         Status = ElfrCloseEL(&hEventLog);
416     }
417     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
418     {
419         Status = I_RpcMapWin32Status(RpcExceptionCode());
420     }
421     RpcEndExcept;
422 
423     return Status;
424 }
425 
426 BOOL WINAPI
427 CloseEventLog(IN HANDLE hEventLog)
428 {
429     NTSTATUS Status;
430 
431     TRACE("%p\n", hEventLog);
432 
433     Status = ElfCloseEventLog(hEventLog);
434     if (!NT_SUCCESS(Status))
435     {
436         SetLastError(RtlNtStatusToDosError(Status));
437         return FALSE;
438     }
439 
440     return TRUE;
441 }
442 
443 
444 /******************************************************************************
445  * DeregisterEventSource [ADVAPI32.@]
446  * Closes a handle to the specified event log
447  *
448  * PARAMS
449  *    hEventLog [I] Handle to event log
450  *
451  * RETURNS STD
452  */
453 NTSTATUS
454 NTAPI
455 ElfDeregisterEventSource(IN HANDLE hEventLog)
456 {
457     NTSTATUS Status;
458 
459     RpcTryExcept
460     {
461         Status = ElfrDeregisterEventSource(&hEventLog);
462     }
463     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
464     {
465         Status = I_RpcMapWin32Status(RpcExceptionCode());
466     }
467     RpcEndExcept;
468 
469     return Status;
470 }
471 
472 BOOL WINAPI
473 DeregisterEventSource(IN HANDLE hEventLog)
474 {
475     NTSTATUS Status;
476 
477     TRACE("%p\n", hEventLog);
478 
479     Status = ElfDeregisterEventSource(hEventLog);
480     if (!NT_SUCCESS(Status))
481     {
482         SetLastError(RtlNtStatusToDosError(Status));
483         return FALSE;
484     }
485 
486     return TRUE;
487 }
488 
489 
490 /******************************************************************************
491  * GetEventLogInformation [ADVAPI32.@]
492  *
493  * PARAMS
494  *   hEventLog      [I] Handle to event log
495  *   dwInfoLevel    [I] Level of event log information to return
496  *   lpBuffer       [O] Buffer that receives the event log information
497  *   cbBufSize      [I] Size of the lpBuffer buffer
498  *   pcbBytesNeeded [O] Required buffer size
499  */
500 BOOL WINAPI
501 GetEventLogInformation(IN HANDLE hEventLog,
502                        IN DWORD dwInfoLevel,
503                        OUT LPVOID lpBuffer,
504                        IN DWORD cbBufSize,
505                        OUT LPDWORD pcbBytesNeeded)
506 {
507     NTSTATUS Status;
508 
509     if (dwInfoLevel != EVENTLOG_FULL_INFO)
510     {
511         SetLastError(ERROR_INVALID_LEVEL);
512         return FALSE;
513     }
514 
515     RpcTryExcept
516     {
517         Status = ElfrGetLogInformation(hEventLog,
518                                        dwInfoLevel,
519                                        (LPBYTE)lpBuffer,
520                                        cbBufSize,
521                                        pcbBytesNeeded);
522     }
523     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
524     {
525         Status = I_RpcMapWin32Status(RpcExceptionCode());
526     }
527     RpcEndExcept;
528 
529     if (!NT_SUCCESS(Status))
530     {
531         SetLastError(RtlNtStatusToDosError(Status));
532         return FALSE;
533     }
534 
535     return TRUE;
536 }
537 
538 
539 /******************************************************************************
540  * GetNumberOfEventLogRecords [ADVAPI32.@]
541  *
542  * PARAMS
543  *   hEventLog       []
544  *   NumberOfRecords []
545  */
546 NTSTATUS
547 NTAPI
548 ElfNumberOfRecords(IN HANDLE hEventLog,
549                    OUT PULONG NumberOfRecords)
550 {
551     NTSTATUS Status;
552 
553     if (!NumberOfRecords)
554         return STATUS_INVALID_PARAMETER;
555 
556     RpcTryExcept
557     {
558         Status = ElfrNumberOfRecords(hEventLog, NumberOfRecords);
559     }
560     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
561     {
562         Status = I_RpcMapWin32Status(RpcExceptionCode());
563     }
564     RpcEndExcept;
565 
566     return Status;
567 }
568 
569 BOOL WINAPI
570 GetNumberOfEventLogRecords(IN HANDLE hEventLog,
571                            OUT PDWORD NumberOfRecords)
572 {
573     NTSTATUS Status;
574 
575     TRACE("%p, %p\n", hEventLog, NumberOfRecords);
576 
577     Status = ElfNumberOfRecords(hEventLog, NumberOfRecords);
578     if (!NT_SUCCESS(Status))
579     {
580         SetLastError(RtlNtStatusToDosError(Status));
581         return FALSE;
582     }
583 
584     return TRUE;
585 }
586 
587 
588 /******************************************************************************
589  * GetOldestEventLogRecord [ADVAPI32.@]
590  *
591  * PARAMS
592  *   hEventLog    []
593  *   OldestRecord []
594  */
595 NTSTATUS
596 NTAPI
597 ElfOldestRecord(IN HANDLE hEventLog,
598                 OUT PULONG OldestRecordNumber)
599 {
600     NTSTATUS Status;
601 
602     if (!OldestRecordNumber)
603         return STATUS_INVALID_PARAMETER;
604 
605     RpcTryExcept
606     {
607         Status = ElfrOldestRecord(hEventLog, OldestRecordNumber);
608     }
609     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
610     {
611         Status = I_RpcMapWin32Status(RpcExceptionCode());
612     }
613     RpcEndExcept;
614 
615     return Status;
616 }
617 
618 BOOL WINAPI
619 GetOldestEventLogRecord(IN HANDLE hEventLog,
620                         OUT PDWORD OldestRecord)
621 {
622     NTSTATUS Status;
623 
624     TRACE("%p, %p\n", hEventLog, OldestRecord);
625 
626     Status = ElfOldestRecord(hEventLog, OldestRecord);
627     if (!NT_SUCCESS(Status))
628     {
629         SetLastError(RtlNtStatusToDosError(Status));
630         return FALSE;
631     }
632 
633     return TRUE;
634 }
635 
636 
637 /******************************************************************************
638  * NotifyChangeEventLog [ADVAPI32.@]
639  *
640  * PARAMS
641  *   hEventLog []
642  *   hEvent    []
643  */
644 NTSTATUS
645 NTAPI
646 ElfChangeNotify(IN HANDLE hEventLog,
647                 IN HANDLE hEvent)
648 {
649     NTSTATUS Status;
650     CLIENT_ID ClientId = NtCurrentTeb()->ClientId;
651     RPC_CLIENT_ID RpcClientId;
652 
653     RpcClientId.UniqueProcess = HandleToUlong(ClientId.UniqueProcess);
654     RpcClientId.UniqueThread  = HandleToUlong(ClientId.UniqueThread);
655 
656     RpcTryExcept
657     {
658         Status = ElfrChangeNotify(hEventLog, RpcClientId, (DWORD)hEvent);
659     }
660     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
661     {
662         Status = I_RpcMapWin32Status(RpcExceptionCode());
663     }
664     RpcEndExcept;
665 
666     return Status;
667 }
668 
669 BOOL WINAPI
670 NotifyChangeEventLog(IN HANDLE hEventLog,
671                      IN HANDLE hEvent)
672 {
673     NTSTATUS Status;
674 
675     TRACE("%p, %p\n", hEventLog, hEvent);
676 
677     Status = ElfChangeNotify(hEventLog, hEvent);
678     if (!NT_SUCCESS(Status))
679     {
680         SetLastError(RtlNtStatusToDosError(Status));
681         return FALSE;
682     }
683 
684     return TRUE;
685 }
686 
687 
688 /******************************************************************************
689  * OpenBackupEventLogA [ADVAPI32.@]
690  */
691 NTSTATUS
692 NTAPI
693 ElfOpenBackupEventLogA(IN PANSI_STRING UNCServerNameA,
694                        IN PANSI_STRING BackupFileNameA,
695                        OUT PHANDLE phEventLog)
696 {
697     NTSTATUS Status;
698     PSTR pUNCServerName = NULL;
699 
700     if (!phEventLog || !BackupFileNameA || (BackupFileNameA->Length == 0))
701         return STATUS_INVALID_PARAMETER;
702 
703     if (UNCServerNameA && (UNCServerNameA->Length != 0))
704         pUNCServerName = UNCServerNameA->Buffer;
705 
706     *phEventLog = NULL;
707 
708     RpcTryExcept
709     {
710         Status = ElfrOpenBELA(pUNCServerName,
711                               (PRPC_STRING)BackupFileNameA,
712                               1, 1,
713                               (IELF_HANDLE*)phEventLog);
714     }
715     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
716     {
717         Status = I_RpcMapWin32Status(RpcExceptionCode());
718     }
719     RpcEndExcept;
720 
721     return Status;
722 }
723 
724 HANDLE WINAPI
725 OpenBackupEventLogA(IN LPCSTR lpUNCServerName,
726                     IN LPCSTR lpFileName)
727 {
728     NTSTATUS Status;
729     HANDLE LogHandle;
730     ANSI_STRING UNCServerNameA;
731     UNICODE_STRING UNCServerNameW;
732     ANSI_STRING FileNameA;
733     UNICODE_STRING FileNameW;
734 
735     TRACE("%s, %s\n", lpUNCServerName, lpFileName);
736 
737     /* Convert the server name to unicode */
738     if (lpUNCServerName == NULL)
739     {
740         RtlInitUnicodeString(&UNCServerNameW, NULL);
741     }
742     else
743     {
744         RtlInitAnsiString(&UNCServerNameA, lpUNCServerName);
745 
746         Status = RtlAnsiStringToUnicodeString(&UNCServerNameW,
747                                               &UNCServerNameA,
748                                               TRUE);
749         if (!NT_SUCCESS(Status))
750         {
751             SetLastError(RtlNtStatusToDosError(Status));
752             return NULL;
753         }
754     }
755 
756     /* Convert the file name to unicode */
757     if (lpFileName == NULL)
758     {
759         RtlInitUnicodeString(&FileNameW, NULL);
760     }
761     else
762     {
763         RtlInitAnsiString(&FileNameA, lpFileName);
764 
765         Status = RtlAnsiStringToUnicodeString(&FileNameW,
766                                               &FileNameA,
767                                               TRUE);
768         if (!NT_SUCCESS(Status))
769         {
770             RtlFreeUnicodeString(&UNCServerNameW);
771             SetLastError(RtlNtStatusToDosError(Status));
772             return NULL;
773         }
774     }
775 
776     /* Call the unicode function */
777     LogHandle = OpenBackupEventLogW(UNCServerNameW.Buffer,
778                                     FileNameW.Buffer);
779 
780     /* Free the unicode strings */
781     RtlFreeUnicodeString(&UNCServerNameW);
782     RtlFreeUnicodeString(&FileNameW);
783 
784     return LogHandle;
785 }
786 
787 
788 /******************************************************************************
789  * OpenBackupEventLogW [ADVAPI32.@]
790  *
791  * PARAMS
792  *   lpUNCServerName []
793  *   lpFileName      []
794  */
795 NTSTATUS
796 NTAPI
797 ElfOpenBackupEventLogW(IN PUNICODE_STRING UNCServerNameU,
798                        IN PUNICODE_STRING BackupFileNameU,
799                        OUT PHANDLE phEventLog)
800 {
801     NTSTATUS Status;
802     PWSTR pUNCServerName = NULL;
803 
804     if (!phEventLog || !BackupFileNameU || (BackupFileNameU->Length == 0))
805         return STATUS_INVALID_PARAMETER;
806 
807     if (UNCServerNameU && (UNCServerNameU->Length != 0))
808         pUNCServerName = UNCServerNameU->Buffer;
809 
810     *phEventLog = NULL;
811 
812     RpcTryExcept
813     {
814         Status = ElfrOpenBELW(pUNCServerName,
815                               (PRPC_UNICODE_STRING)BackupFileNameU,
816                               1, 1,
817                               (IELF_HANDLE*)phEventLog);
818     }
819     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
820     {
821         Status = I_RpcMapWin32Status(RpcExceptionCode());
822     }
823     RpcEndExcept;
824 
825     return Status;
826 }
827 
828 HANDLE WINAPI
829 OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
830                     IN LPCWSTR lpFileName)
831 {
832     NTSTATUS Status;
833     HANDLE hEventLog;
834     UNICODE_STRING UNCServerName, FileName;
835 
836     TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
837 
838     if (lpFileName == NULL)
839     {
840         SetLastError(ERROR_INVALID_PARAMETER);
841         return NULL;
842     }
843 
844     if (!RtlDosPathNameToNtPathName_U(lpFileName, &FileName,
845                                       NULL, NULL))
846     {
847         SetLastError(ERROR_INVALID_PARAMETER);
848         return NULL;
849     }
850 
851     RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
852 
853     Status = ElfOpenBackupEventLogW(&UNCServerName, &FileName, &hEventLog);
854 
855     if (FileName.Buffer != NULL)
856         RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
857 
858     if (!NT_SUCCESS(Status))
859     {
860         SetLastError(RtlNtStatusToDosError(Status));
861         return NULL;
862     }
863 
864     return hEventLog;
865 }
866 
867 
868 /******************************************************************************
869  * OpenEventLogA [ADVAPI32.@]
870  *
871  * Opens a handle to the specified event log.
872  *
873  * PARAMS
874  *  lpUNCServerName [I] UNC name of the server on which the event log is
875  *                      opened.
876  *  lpSourceName    [I] Name of the log.
877  *
878  * RETURNS
879  *  Success: Handle to an event log.
880  *  Failure: NULL
881  */
882 NTSTATUS
883 NTAPI
884 ElfOpenEventLogA(IN PANSI_STRING UNCServerNameA,
885                  IN PANSI_STRING SourceNameA,
886                  OUT PHANDLE phEventLog)
887 {
888     NTSTATUS Status;
889     PSTR pUNCServerName = NULL;
890 
891     if (!phEventLog || !SourceNameA || (SourceNameA->Length == 0))
892         return STATUS_INVALID_PARAMETER;
893 
894     if (UNCServerNameA && (UNCServerNameA->Length != 0))
895         pUNCServerName = UNCServerNameA->Buffer;
896 
897     *phEventLog = NULL;
898 
899     RpcTryExcept
900     {
901         Status = ElfrOpenELA(pUNCServerName,
902                              (PRPC_STRING)SourceNameA,
903                              &EmptyStringA,
904                              1, 1,
905                              (IELF_HANDLE*)phEventLog);
906     }
907     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
908     {
909         Status = I_RpcMapWin32Status(RpcExceptionCode());
910     }
911     RpcEndExcept;
912 
913     return Status;
914 }
915 
916 HANDLE WINAPI
917 OpenEventLogA(IN LPCSTR lpUNCServerName,
918               IN LPCSTR lpSourceName)
919 {
920     NTSTATUS Status;
921     HANDLE hEventLog;
922     ANSI_STRING UNCServerName, SourceName;
923 
924     TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
925 
926     RtlInitAnsiString(&UNCServerName, lpUNCServerName);
927     RtlInitAnsiString(&SourceName, lpSourceName);
928 
929     Status = ElfOpenEventLogA(&UNCServerName, &SourceName, &hEventLog);
930     if (!NT_SUCCESS(Status))
931     {
932         SetLastError(RtlNtStatusToDosError(Status));
933         return NULL;
934     }
935 
936     return hEventLog;
937 }
938 
939 
940 /******************************************************************************
941  * OpenEventLogW [ADVAPI32.@]
942  *
943  * PARAMS
944  *   lpUNCServerName []
945  *   lpSourceName    []
946  */
947 NTSTATUS
948 NTAPI
949 ElfOpenEventLogW(IN PUNICODE_STRING UNCServerNameU,
950                  IN PUNICODE_STRING SourceNameU,
951                  OUT PHANDLE phEventLog)
952 {
953     NTSTATUS Status;
954     PWSTR pUNCServerName = NULL;
955 
956     if (!phEventLog || !SourceNameU || (SourceNameU->Length == 0))
957         return STATUS_INVALID_PARAMETER;
958 
959     if (UNCServerNameU && (UNCServerNameU->Length != 0))
960         pUNCServerName = UNCServerNameU->Buffer;
961 
962     *phEventLog = NULL;
963 
964     RpcTryExcept
965     {
966         Status = ElfrOpenELW(pUNCServerName,
967                              (PRPC_UNICODE_STRING)SourceNameU,
968                              &EmptyStringU,
969                              1, 1,
970                              (IELF_HANDLE*)phEventLog);
971     }
972     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
973     {
974         Status = I_RpcMapWin32Status(RpcExceptionCode());
975     }
976     RpcEndExcept;
977 
978     return Status;
979 }
980 
981 HANDLE WINAPI
982 OpenEventLogW(IN LPCWSTR lpUNCServerName,
983               IN LPCWSTR lpSourceName)
984 {
985     NTSTATUS Status;
986     HANDLE hEventLog;
987     UNICODE_STRING UNCServerName, SourceName;
988 
989     TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
990 
991     RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
992     RtlInitUnicodeString(&SourceName, lpSourceName);
993 
994     Status = ElfOpenEventLogW(&UNCServerName, &SourceName, &hEventLog);
995     if (!NT_SUCCESS(Status))
996     {
997         SetLastError(RtlNtStatusToDosError(Status));
998         return NULL;
999     }
1000 
1001     return hEventLog;
1002 }
1003 
1004 
1005 /******************************************************************************
1006  * ReadEventLogA [ADVAPI32.@]
1007  */
1008 NTSTATUS
1009 NTAPI
1010 ElfReadEventLogA(IN HANDLE hEventLog,
1011                  IN ULONG ReadFlags,
1012                  IN ULONG RecordOffset,
1013                  OUT LPVOID Buffer,
1014                  IN ULONG NumberOfBytesToRead,
1015                  OUT PULONG NumberOfBytesRead,
1016                  OUT PULONG MinNumberOfBytesNeeded)
1017 {
1018     NTSTATUS Status;
1019     ULONG Flags;
1020 
1021     if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded)
1022     {
1023         return STATUS_INVALID_PARAMETER;
1024     }
1025 
1026     Flags = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
1027     if (Flags == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ))
1028     {
1029         return STATUS_INVALID_PARAMETER;
1030     }
1031 
1032     Flags = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
1033     if (Flags == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ))
1034     {
1035         return STATUS_INVALID_PARAMETER;
1036     }
1037 
1038     RpcTryExcept
1039     {
1040         Status = ElfrReadELA(hEventLog,
1041                              ReadFlags,
1042                              RecordOffset,
1043                              NumberOfBytesToRead,
1044                              Buffer,
1045                              NumberOfBytesRead,
1046                              MinNumberOfBytesNeeded);
1047     }
1048     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1049     {
1050         Status = I_RpcMapWin32Status(RpcExceptionCode());
1051     }
1052     RpcEndExcept;
1053 
1054     return Status;
1055 }
1056 
1057 BOOL WINAPI
1058 ReadEventLogA(IN HANDLE hEventLog,
1059               IN DWORD dwReadFlags,
1060               IN DWORD dwRecordOffset,
1061               OUT LPVOID lpBuffer,
1062               IN DWORD nNumberOfBytesToRead,
1063               OUT DWORD *pnBytesRead,
1064               OUT DWORD *pnMinNumberOfBytesNeeded)
1065 {
1066     NTSTATUS Status;
1067 
1068     TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
1069         hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
1070         nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
1071 
1072     Status = ElfReadEventLogA(hEventLog,
1073                               dwReadFlags,
1074                               dwRecordOffset,
1075                               lpBuffer,
1076                               nNumberOfBytesToRead,
1077                               pnBytesRead,
1078                               pnMinNumberOfBytesNeeded);
1079     if (!NT_SUCCESS(Status))
1080     {
1081         SetLastError(RtlNtStatusToDosError(Status));
1082         return FALSE;
1083     }
1084 
1085     return TRUE;
1086 }
1087 
1088 
1089 /******************************************************************************
1090  * ReadEventLogW [ADVAPI32.@]
1091  *
1092  * PARAMS
1093  *   hEventLog                []
1094  *   dwReadFlags              []
1095  *   dwRecordOffset           []
1096  *   lpBuffer                 []
1097  *   nNumberOfBytesToRead     []
1098  *   pnBytesRead              []
1099  *   pnMinNumberOfBytesNeeded []
1100  */
1101 NTSTATUS
1102 NTAPI
1103 ElfReadEventLogW(IN HANDLE hEventLog,
1104                  IN ULONG ReadFlags,
1105                  IN ULONG RecordOffset,
1106                  OUT LPVOID Buffer,
1107                  IN ULONG NumberOfBytesToRead,
1108                  OUT PULONG NumberOfBytesRead,
1109                  OUT PULONG MinNumberOfBytesNeeded)
1110 {
1111     NTSTATUS Status;
1112     ULONG Flags;
1113 
1114     if (!Buffer || !NumberOfBytesRead || !MinNumberOfBytesNeeded)
1115     {
1116         return STATUS_INVALID_PARAMETER;
1117     }
1118 
1119     Flags = ReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
1120     if (Flags == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ))
1121     {
1122         return STATUS_INVALID_PARAMETER;
1123     }
1124 
1125     Flags = ReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
1126     if (Flags == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ))
1127     {
1128         return STATUS_INVALID_PARAMETER;
1129     }
1130 
1131     RpcTryExcept
1132     {
1133         Status = ElfrReadELW(hEventLog,
1134                              ReadFlags,
1135                              RecordOffset,
1136                              NumberOfBytesToRead,
1137                              Buffer,
1138                              NumberOfBytesRead,
1139                              MinNumberOfBytesNeeded);
1140     }
1141     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1142     {
1143         Status = I_RpcMapWin32Status(RpcExceptionCode());
1144     }
1145     RpcEndExcept;
1146 
1147     return Status;
1148 }
1149 
1150 BOOL WINAPI
1151 ReadEventLogW(IN HANDLE hEventLog,
1152               IN DWORD dwReadFlags,
1153               IN DWORD dwRecordOffset,
1154               OUT LPVOID lpBuffer,
1155               IN DWORD nNumberOfBytesToRead,
1156               OUT DWORD *pnBytesRead,
1157               OUT DWORD *pnMinNumberOfBytesNeeded)
1158 {
1159     NTSTATUS Status;
1160 
1161     TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
1162         hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
1163         nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
1164 
1165     Status = ElfReadEventLogW(hEventLog,
1166                               dwReadFlags,
1167                               dwRecordOffset,
1168                               lpBuffer,
1169                               nNumberOfBytesToRead,
1170                               pnBytesRead,
1171                               pnMinNumberOfBytesNeeded);
1172     if (!NT_SUCCESS(Status))
1173     {
1174         SetLastError(RtlNtStatusToDosError(Status));
1175         return FALSE;
1176     }
1177 
1178     return TRUE;
1179 }
1180 
1181 
1182 /******************************************************************************
1183  * RegisterEventSourceA [ADVAPI32.@]
1184  */
1185 NTSTATUS
1186 NTAPI
1187 ElfRegisterEventSourceA(IN PANSI_STRING UNCServerNameA,
1188                         IN PANSI_STRING SourceNameA,
1189                         OUT PHANDLE phEventLog)
1190 {
1191     NTSTATUS Status;
1192     PSTR pUNCServerName = NULL;
1193 
1194     if (!phEventLog || !SourceNameA || (SourceNameA->Length == 0))
1195         return STATUS_INVALID_PARAMETER;
1196 
1197     if (UNCServerNameA && (UNCServerNameA->Length != 0))
1198         pUNCServerName = UNCServerNameA->Buffer;
1199 
1200     *phEventLog = NULL;
1201 
1202     RpcTryExcept
1203     {
1204         Status = ElfrRegisterEventSourceA(pUNCServerName,
1205                                           (PRPC_STRING)SourceNameA,
1206                                           &EmptyStringA,
1207                                           1, 1,
1208                                           (IELF_HANDLE*)phEventLog);
1209     }
1210     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1211     {
1212         Status = I_RpcMapWin32Status(RpcExceptionCode());
1213     }
1214     RpcEndExcept;
1215 
1216     return Status;
1217 }
1218 
1219 HANDLE WINAPI
1220 RegisterEventSourceA(IN LPCSTR lpUNCServerName,
1221                      IN LPCSTR lpSourceName)
1222 {
1223     NTSTATUS Status;
1224     HANDLE hEventLog;
1225     ANSI_STRING UNCServerName, SourceName;
1226 
1227     TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
1228 
1229     RtlInitAnsiString(&UNCServerName, lpUNCServerName);
1230     RtlInitAnsiString(&SourceName, lpSourceName);
1231 
1232     Status = ElfRegisterEventSourceA(&UNCServerName, &SourceName, &hEventLog);
1233     if (!NT_SUCCESS(Status))
1234     {
1235         SetLastError(RtlNtStatusToDosError(Status));
1236         return NULL;
1237     }
1238 
1239     return hEventLog;
1240 }
1241 
1242 
1243 /******************************************************************************
1244  * RegisterEventSourceW [ADVAPI32.@]
1245  * Returns a registered handle to an event log
1246  *
1247  * PARAMS
1248  *   lpUNCServerName [I] Server name for source
1249  *   lpSourceName    [I] Source name for registered handle
1250  *
1251  * RETURNS
1252  *    Success: Handle
1253  *    Failure: NULL
1254  */
1255 NTSTATUS
1256 NTAPI
1257 ElfRegisterEventSourceW(IN PUNICODE_STRING UNCServerNameU,
1258                         IN PUNICODE_STRING SourceNameU,
1259                         OUT PHANDLE phEventLog)
1260 {
1261     NTSTATUS Status;
1262     PWSTR pUNCServerName = NULL;
1263 
1264     if (!phEventLog || !SourceNameU || (SourceNameU->Length == 0))
1265         return STATUS_INVALID_PARAMETER;
1266 
1267     if (UNCServerNameU && (UNCServerNameU->Length != 0))
1268         pUNCServerName = UNCServerNameU->Buffer;
1269 
1270     *phEventLog = NULL;
1271 
1272     RpcTryExcept
1273     {
1274         Status = ElfrRegisterEventSourceW(pUNCServerName,
1275                                           (PRPC_UNICODE_STRING)SourceNameU,
1276                                           &EmptyStringU,
1277                                           1, 1,
1278                                           (IELF_HANDLE*)phEventLog);
1279     }
1280     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1281     {
1282         Status = I_RpcMapWin32Status(RpcExceptionCode());
1283     }
1284     RpcEndExcept;
1285 
1286     return Status;
1287 }
1288 
1289 HANDLE WINAPI
1290 RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
1291                      IN LPCWSTR lpSourceName)
1292 {
1293     NTSTATUS Status;
1294     HANDLE hEventLog;
1295     UNICODE_STRING UNCServerName, SourceName;
1296 
1297     TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
1298 
1299     RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
1300     RtlInitUnicodeString(&SourceName, lpSourceName);
1301 
1302     Status = ElfRegisterEventSourceW(&UNCServerName, &SourceName, &hEventLog);
1303     if (!NT_SUCCESS(Status))
1304     {
1305         SetLastError(RtlNtStatusToDosError(Status));
1306         return NULL;
1307     }
1308 
1309     return hEventLog;
1310 }
1311 
1312 
1313 /******************************************************************************
1314  * ReportEventA [ADVAPI32.@]
1315  */
1316 NTSTATUS
1317 NTAPI
1318 ElfReportEventA(IN HANDLE hEventLog,
1319                 IN USHORT EventType,
1320                 IN USHORT EventCategory,
1321                 IN ULONG EventID,
1322                 IN PSID UserSID,
1323                 IN USHORT NumStrings,
1324                 IN ULONG DataSize,
1325                 IN PANSI_STRING* Strings,
1326                 IN PVOID Data,
1327                 IN USHORT Flags,
1328                 IN OUT PULONG RecordNumber,
1329                 IN OUT PULONG TimeWritten)
1330 {
1331     NTSTATUS Status;
1332     LARGE_INTEGER SystemTime;
1333     ULONG Time;
1334     ULONG dwSize;
1335     ANSI_STRING ComputerName;
1336     CHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1337 
1338     dwSize = ARRAYSIZE(szComputerName);
1339     GetComputerNameA(szComputerName, &dwSize);
1340     RtlInitAnsiString(&ComputerName, szComputerName);
1341 
1342     NtQuerySystemTime(&SystemTime);
1343     RtlTimeToSecondsSince1970(&SystemTime, &Time);
1344 
1345     RpcTryExcept
1346     {
1347         Status = ElfrReportEventA(hEventLog,
1348                                   Time,
1349                                   EventType,
1350                                   EventCategory,
1351                                   EventID,
1352                                   NumStrings,
1353                                   DataSize,
1354                                   (PRPC_STRING)&ComputerName,
1355                                   (PRPC_SID)UserSID,
1356                                   (PRPC_STRING*)Strings,
1357                                   Data,
1358                                   Flags,
1359                                   RecordNumber,
1360                                   TimeWritten);
1361     }
1362     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1363     {
1364         Status = I_RpcMapWin32Status(RpcExceptionCode());
1365     }
1366     RpcEndExcept;
1367 
1368     return Status;
1369 }
1370 
1371 BOOL WINAPI
1372 ReportEventA(IN HANDLE hEventLog,
1373              IN WORD wType,
1374              IN WORD wCategory,
1375              IN DWORD dwEventID,
1376              IN PSID lpUserSid,
1377              IN WORD wNumStrings,
1378              IN DWORD dwDataSize,
1379              IN LPCSTR *lpStrings,
1380              IN LPVOID lpRawData)
1381 {
1382     NTSTATUS Status;
1383     PANSI_STRING *Strings;
1384     WORD i;
1385 
1386     TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
1387           hEventLog, wType, wCategory, dwEventID, lpUserSid,
1388           wNumStrings, dwDataSize, lpStrings, lpRawData);
1389 
1390     Strings = HeapAlloc(GetProcessHeap(),
1391                         HEAP_ZERO_MEMORY,
1392                         wNumStrings * sizeof(PANSI_STRING));
1393     if (!Strings)
1394     {
1395         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1396         return FALSE;
1397     }
1398 
1399     for (i = 0; i < wNumStrings; i++)
1400     {
1401         Strings[i] = HeapAlloc(GetProcessHeap(),
1402                                HEAP_ZERO_MEMORY,
1403                                sizeof(ANSI_STRING));
1404         if (Strings[i])
1405         {
1406             RtlInitAnsiString(Strings[i], lpStrings[i]);
1407         }
1408     }
1409 
1410     Status = ElfReportEventA(hEventLog,
1411                              wType,
1412                              wCategory,
1413                              dwEventID,
1414                              lpUserSid,
1415                              wNumStrings,
1416                              dwDataSize,
1417                              Strings,
1418                              lpRawData,
1419                              0,
1420                              NULL,
1421                              NULL);
1422 
1423     for (i = 0; i < wNumStrings; i++)
1424     {
1425         if (Strings[i] != NULL)
1426             HeapFree(GetProcessHeap(), 0, Strings[i]);
1427     }
1428 
1429     HeapFree(GetProcessHeap(), 0, Strings);
1430 
1431     if (!NT_SUCCESS(Status))
1432     {
1433         SetLastError(RtlNtStatusToDosError(Status));
1434         return FALSE;
1435     }
1436 
1437     return TRUE;
1438 }
1439 
1440 
1441 /******************************************************************************
1442  * ReportEventW [ADVAPI32.@]
1443  *
1444  * PARAMS
1445  *   hEventLog   []
1446  *   wType       []
1447  *   wCategory   []
1448  *   dwEventID   []
1449  *   lpUserSid   []
1450  *   wNumStrings []
1451  *   dwDataSize  []
1452  *   lpStrings   []
1453  *   lpRawData   []
1454  */
1455 NTSTATUS
1456 NTAPI
1457 ElfReportEventW(IN HANDLE hEventLog,
1458                 IN USHORT EventType,
1459                 IN USHORT EventCategory,
1460                 IN ULONG EventID,
1461                 IN PSID UserSID,
1462                 IN USHORT NumStrings,
1463                 IN ULONG DataSize,
1464                 IN PUNICODE_STRING* Strings,
1465                 IN PVOID Data,
1466                 IN USHORT Flags,
1467                 IN OUT PULONG RecordNumber,
1468                 IN OUT PULONG TimeWritten)
1469 {
1470     NTSTATUS Status;
1471     LARGE_INTEGER SystemTime;
1472     ULONG Time;
1473     ULONG dwSize;
1474     UNICODE_STRING ComputerName;
1475     WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1476 
1477     dwSize = ARRAYSIZE(szComputerName);
1478     GetComputerNameW(szComputerName, &dwSize);
1479     RtlInitUnicodeString(&ComputerName, szComputerName);
1480 
1481     NtQuerySystemTime(&SystemTime);
1482     RtlTimeToSecondsSince1970(&SystemTime, &Time);
1483 
1484     RpcTryExcept
1485     {
1486         Status = ElfrReportEventW(hEventLog,
1487                                   Time,
1488                                   EventType,
1489                                   EventCategory,
1490                                   EventID,
1491                                   NumStrings,
1492                                   DataSize,
1493                                   (PRPC_UNICODE_STRING)&ComputerName,
1494                                   (PRPC_SID)UserSID,
1495                                   (PRPC_UNICODE_STRING*)Strings,
1496                                   Data,
1497                                   Flags,
1498                                   RecordNumber,
1499                                   TimeWritten);
1500     }
1501     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1502     {
1503         Status = I_RpcMapWin32Status(RpcExceptionCode());
1504     }
1505     RpcEndExcept;
1506 
1507     return Status;
1508 }
1509 
1510 BOOL WINAPI
1511 ReportEventW(IN HANDLE hEventLog,
1512              IN WORD wType,
1513              IN WORD wCategory,
1514              IN DWORD dwEventID,
1515              IN PSID lpUserSid,
1516              IN WORD wNumStrings,
1517              IN DWORD dwDataSize,
1518              IN LPCWSTR *lpStrings,
1519              IN LPVOID lpRawData)
1520 {
1521     NTSTATUS Status;
1522     PUNICODE_STRING *Strings;
1523     WORD i;
1524 
1525     TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
1526           hEventLog, wType, wCategory, dwEventID, lpUserSid,
1527           wNumStrings, dwDataSize, lpStrings, lpRawData);
1528 
1529     Strings = HeapAlloc(GetProcessHeap(),
1530                         HEAP_ZERO_MEMORY,
1531                         wNumStrings * sizeof(PUNICODE_STRING));
1532     if (!Strings)
1533     {
1534         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1535         return FALSE;
1536     }
1537 
1538     for (i = 0; i < wNumStrings; i++)
1539     {
1540         Strings[i] = HeapAlloc(GetProcessHeap(),
1541                                HEAP_ZERO_MEMORY,
1542                                sizeof(UNICODE_STRING));
1543         if (Strings[i])
1544         {
1545             RtlInitUnicodeString(Strings[i], lpStrings[i]);
1546         }
1547     }
1548 
1549     Status = ElfReportEventW(hEventLog,
1550                              wType,
1551                              wCategory,
1552                              dwEventID,
1553                              lpUserSid,
1554                              wNumStrings,
1555                              dwDataSize,
1556                              Strings,
1557                              lpRawData,
1558                              0,
1559                              NULL,
1560                              NULL);
1561 
1562     for (i = 0; i < wNumStrings; i++)
1563     {
1564         if (Strings[i] != NULL)
1565             HeapFree(GetProcessHeap(), 0, Strings[i]);
1566     }
1567 
1568     HeapFree(GetProcessHeap(), 0, Strings);
1569 
1570     if (!NT_SUCCESS(Status))
1571     {
1572         SetLastError(RtlNtStatusToDosError(Status));
1573         return FALSE;
1574     }
1575 
1576     return TRUE;
1577 }
1578 
1579 NTSTATUS
1580 NTAPI
1581 ElfReportEventAndSourceW(IN HANDLE hEventLog,
1582                          IN ULONG Time,
1583                          IN PUNICODE_STRING ComputerName,
1584                          IN USHORT EventType,
1585                          IN USHORT EventCategory,
1586                          IN ULONG EventID,
1587                          IN PSID UserSID,
1588                          IN PUNICODE_STRING SourceName,
1589                          IN USHORT NumStrings,
1590                          IN ULONG DataSize,
1591                          IN PUNICODE_STRING* Strings,
1592                          IN PVOID Data,
1593                          IN USHORT Flags,
1594                          IN OUT PULONG RecordNumber,
1595                          IN OUT PULONG TimeWritten)
1596 {
1597     NTSTATUS Status;
1598 
1599     RpcTryExcept
1600     {
1601         Status = ElfrReportEventAndSourceW(hEventLog,
1602                                            Time,
1603                                            EventType,
1604                                            EventCategory,
1605                                            EventID,
1606                                            (PRPC_UNICODE_STRING)SourceName,
1607                                            NumStrings,
1608                                            DataSize,
1609                                            (PRPC_UNICODE_STRING)ComputerName,
1610                                            (PRPC_SID)UserSID,
1611                                            (PRPC_UNICODE_STRING*)Strings,
1612                                            (PBYTE)Data,
1613                                            Flags,
1614                                            RecordNumber,
1615                                            TimeWritten);
1616     }
1617     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1618     {
1619         Status = I_RpcMapWin32Status(RpcExceptionCode());
1620     }
1621     RpcEndExcept;
1622 
1623     return Status;
1624 }
1625 
1626 NTSTATUS
1627 NTAPI
1628 ElfFlushEventLog(IN HANDLE hEventLog)
1629 {
1630     NTSTATUS Status;
1631 
1632     RpcTryExcept
1633     {
1634         Status = ElfrFlushEL(hEventLog);
1635     }
1636     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1637     {
1638         Status = I_RpcMapWin32Status(RpcExceptionCode());
1639     }
1640     RpcEndExcept;
1641 
1642     return Status;
1643 }
1644