* Sync up to trunk HEAD (r62286).
[reactos.git] / dll / win32 / advapi32 / service / eventlog.c
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 #include <advapi32.h>
25
26 #include <ndk/kefuncs.h>
27 #include <eventlogrpc_c.h>
28
29 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
30
31 static RPC_UNICODE_STRING EmptyStringU = { 0, 0, L"" };
32 static RPC_STRING EmptyStringA = { 0, 0, "" };
33
34
35 handle_t __RPC_USER
36 EVENTLOG_HANDLE_A_bind(EVENTLOG_HANDLE_A UNCServerName)
37 {
38 handle_t hBinding = NULL;
39 UCHAR *pszStringBinding;
40 RPC_STATUS status;
41
42 TRACE("EVENTLOG_HANDLE_A_bind() called\n");
43
44 status = RpcStringBindingComposeA(NULL,
45 (UCHAR *)"ncacn_np",
46 (UCHAR *)UNCServerName,
47 (UCHAR *)"\\pipe\\EventLog",
48 NULL,
49 (UCHAR **)&pszStringBinding);
50 if (status)
51 {
52 ERR("RpcStringBindingCompose returned 0x%x\n", status);
53 return NULL;
54 }
55
56 /* Set the binding handle that will be used to bind to the server. */
57 status = RpcBindingFromStringBindingA(pszStringBinding,
58 &hBinding);
59 if (status)
60 {
61 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
62 }
63
64 status = RpcStringFreeA(&pszStringBinding);
65 if (status)
66 {
67 ERR("RpcStringFree returned 0x%x\n", status);
68 }
69
70 return hBinding;
71 }
72
73
74 void __RPC_USER
75 EVENTLOG_HANDLE_A_unbind(EVENTLOG_HANDLE_A UNCServerName,
76 handle_t hBinding)
77 {
78 RPC_STATUS status;
79
80 TRACE("EVENTLOG_HANDLE_A_unbind() called\n");
81
82 status = RpcBindingFree(&hBinding);
83 if (status)
84 {
85 ERR("RpcBindingFree returned 0x%x\n", status);
86 }
87 }
88
89
90 handle_t __RPC_USER
91 EVENTLOG_HANDLE_W_bind(EVENTLOG_HANDLE_W UNCServerName)
92 {
93 handle_t hBinding = NULL;
94 LPWSTR pszStringBinding;
95 RPC_STATUS status;
96
97 TRACE("EVENTLOG_HANDLE_W_bind() called\n");
98
99 status = RpcStringBindingComposeW(NULL,
100 L"ncacn_np",
101 (LPWSTR)UNCServerName,
102 L"\\pipe\\EventLog",
103 NULL,
104 &pszStringBinding);
105 if (status)
106 {
107 ERR("RpcStringBindingCompose returned 0x%x\n", status);
108 return NULL;
109 }
110
111 /* Set the binding handle that will be used to bind to the server. */
112 status = RpcBindingFromStringBindingW(pszStringBinding,
113 &hBinding);
114 if (status)
115 {
116 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
117 }
118
119 status = RpcStringFreeW(&pszStringBinding);
120 if (status)
121 {
122 ERR("RpcStringFree returned 0x%x\n", status);
123 }
124
125 return hBinding;
126 }
127
128
129 void __RPC_USER
130 EVENTLOG_HANDLE_W_unbind(EVENTLOG_HANDLE_W UNCServerName,
131 handle_t hBinding)
132 {
133 RPC_STATUS status;
134
135 TRACE("EVENTLOG_HANDLE_W_unbind() called\n");
136
137 status = RpcBindingFree(&hBinding);
138 if (status)
139 {
140 ERR("RpcBindingFree returned 0x%x\n", status);
141 }
142 }
143
144
145 /******************************************************************************
146 * BackupEventLogA [ADVAPI32.@]
147 */
148 BOOL WINAPI
149 BackupEventLogA(IN HANDLE hEventLog,
150 IN LPCSTR lpBackupFileName)
151 {
152 ANSI_STRING BackupFileNameA;
153 UNICODE_STRING BackupFileNameW;
154 NTSTATUS Status;
155 BOOL Result;
156
157 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
158
159 if (lpBackupFileName == NULL)
160 {
161 SetLastError(ERROR_INVALID_PARAMETER);
162 return FALSE;
163 }
164
165 RtlInitAnsiString(&BackupFileNameA, lpBackupFileName);
166
167 Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
168 &BackupFileNameA,
169 TRUE);
170 if (!NT_SUCCESS(Status))
171 {
172 SetLastError(RtlNtStatusToDosError(Status));
173 return FALSE;
174 }
175
176 Result = BackupEventLogW(hEventLog,
177 BackupFileNameW.Buffer);
178
179 RtlFreeUnicodeString(&BackupFileNameW);
180
181 return(Result);
182 }
183
184
185 /******************************************************************************
186 * BackupEventLogW [ADVAPI32.@]
187 *
188 * PARAMS
189 * hEventLog []
190 * lpBackupFileName []
191 */
192 BOOL WINAPI
193 BackupEventLogW(IN HANDLE hEventLog,
194 IN LPCWSTR lpBackupFileName)
195 {
196 UNICODE_STRING BackupFileNameW;
197 NTSTATUS Status;
198
199 TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
200
201 if (lpBackupFileName == NULL)
202 {
203 SetLastError(ERROR_INVALID_PARAMETER);
204 return FALSE;
205 }
206
207 if (!RtlDosPathNameToNtPathName_U(lpBackupFileName, &BackupFileNameW,
208 NULL, NULL))
209 {
210 SetLastError(ERROR_INVALID_PARAMETER);
211 return FALSE;
212 }
213
214 RpcTryExcept
215 {
216 Status = ElfrBackupELFW(hEventLog,
217 (PRPC_UNICODE_STRING)&BackupFileNameW);
218 }
219 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
220 {
221 Status = I_RpcMapWin32Status(RpcExceptionCode());
222 }
223 RpcEndExcept;
224
225 RtlFreeHeap(RtlGetProcessHeap(), 0, BackupFileNameW.Buffer);
226
227 if (!NT_SUCCESS(Status))
228 {
229 SetLastError(RtlNtStatusToDosError(Status));
230 return FALSE;
231 }
232
233 return TRUE;
234 }
235
236
237 /******************************************************************************
238 * ClearEventLogA [ADVAPI32.@]
239 */
240 BOOL WINAPI
241 ClearEventLogA(IN HANDLE hEventLog,
242 IN LPCSTR lpBackupFileName)
243 {
244 ANSI_STRING BackupFileNameA;
245 UNICODE_STRING BackupFileNameW;
246 NTSTATUS Status;
247 BOOL Result;
248
249 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
250
251 if (lpBackupFileName == NULL)
252 {
253 RtlInitUnicodeString(&BackupFileNameW, NULL);
254 }
255 else
256 {
257 RtlInitAnsiString(&BackupFileNameA, lpBackupFileName);
258
259 Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
260 &BackupFileNameA,
261 TRUE);
262 if (!NT_SUCCESS(Status))
263 {
264 SetLastError(RtlNtStatusToDosError(Status));
265 return FALSE;
266 }
267 }
268
269 Result = ClearEventLogW(hEventLog,
270 BackupFileNameW.Buffer);
271
272 RtlFreeUnicodeString(&BackupFileNameW);
273
274 return Result;
275 }
276
277
278 /******************************************************************************
279 * ClearEventLogW [ADVAPI32.@]
280 */
281 BOOL WINAPI
282 ClearEventLogW(IN HANDLE hEventLog,
283 IN LPCWSTR lpBackupFileName)
284 {
285 UNICODE_STRING BackupFileNameW;
286 NTSTATUS Status;
287
288 TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
289
290 if (lpBackupFileName == NULL)
291 {
292 RtlInitUnicodeString(&BackupFileNameW, NULL);
293 }
294 else
295 {
296 if (!RtlDosPathNameToNtPathName_U(lpBackupFileName, &BackupFileNameW,
297 NULL, NULL))
298 {
299 SetLastError(ERROR_INVALID_PARAMETER);
300 return FALSE;
301 }
302 }
303
304 RpcTryExcept
305 {
306 Status = ElfrClearELFW(hEventLog,
307 (PRPC_UNICODE_STRING)&BackupFileNameW);
308 }
309 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
310 {
311 Status = I_RpcMapWin32Status(RpcExceptionCode());
312 }
313 RpcEndExcept;
314
315 if (lpBackupFileName != NULL)
316 RtlFreeHeap(RtlGetProcessHeap(), 0, BackupFileNameW.Buffer);
317
318 if (!NT_SUCCESS(Status))
319 {
320 SetLastError(RtlNtStatusToDosError(Status));
321 return FALSE;
322 }
323
324 return TRUE;
325 }
326
327
328 /******************************************************************************
329 * CloseEventLog [ADVAPI32.@]
330 */
331 BOOL WINAPI
332 CloseEventLog(IN HANDLE hEventLog)
333 {
334 NTSTATUS Status;
335
336 TRACE("%p\n", hEventLog);
337
338 RpcTryExcept
339 {
340 Status = ElfrCloseEL(&hEventLog);
341 }
342 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
343 {
344 Status = I_RpcMapWin32Status(RpcExceptionCode());
345 }
346 RpcEndExcept;
347
348 if (!NT_SUCCESS(Status))
349 {
350 SetLastError(RtlNtStatusToDosError(Status));
351 return FALSE;
352 }
353
354 return TRUE;
355 }
356
357
358 /******************************************************************************
359 * DeregisterEventSource [ADVAPI32.@]
360 * Closes a handle to the specified event log
361 *
362 * PARAMS
363 * hEventLog [I] Handle to event log
364 *
365 * RETURNS STD
366 */
367 BOOL WINAPI
368 DeregisterEventSource(IN HANDLE hEventLog)
369 {
370 NTSTATUS Status;
371
372 TRACE("%p\n", hEventLog);
373
374 RpcTryExcept
375 {
376 Status = ElfrDeregisterEventSource(&hEventLog);
377 }
378 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
379 {
380 Status = I_RpcMapWin32Status(RpcExceptionCode());
381 }
382 RpcEndExcept;
383
384 if (!NT_SUCCESS(Status))
385 {
386 SetLastError(RtlNtStatusToDosError(Status));
387 return FALSE;
388 }
389
390 return TRUE;
391 }
392
393
394 /******************************************************************************
395 * GetEventLogInformation [ADVAPI32.@]
396 *
397 * PARAMS
398 * hEventLog [I] Handle to event log
399 * dwInfoLevel [I] Level of event log information to return
400 * lpBuffer [O] Buffer that receives the event log information
401 * cbBufSize [I] Size of the lpBuffer buffer
402 * pcbBytesNeeded [O] Required buffer size
403 */
404 BOOL WINAPI
405 GetEventLogInformation(IN HANDLE hEventLog,
406 IN DWORD dwInfoLevel,
407 OUT LPVOID lpBuffer,
408 IN DWORD cbBufSize,
409 OUT LPDWORD pcbBytesNeeded)
410 {
411 NTSTATUS Status;
412
413 if (dwInfoLevel != EVENTLOG_FULL_INFO)
414 {
415 SetLastError(ERROR_INVALID_LEVEL);
416 return FALSE;
417 }
418
419 RpcTryExcept
420 {
421 Status = ElfrGetLogInformation(hEventLog,
422 dwInfoLevel,
423 (LPBYTE)lpBuffer,
424 cbBufSize,
425 pcbBytesNeeded);
426 }
427 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
428 {
429 Status = I_RpcMapWin32Status(RpcExceptionCode());
430 }
431 RpcEndExcept;
432
433 if (!NT_SUCCESS(Status))
434 {
435 SetLastError(RtlNtStatusToDosError(Status));
436 return FALSE;
437 }
438
439 return TRUE;
440 }
441
442
443 /******************************************************************************
444 * GetNumberOfEventLogRecords [ADVAPI32.@]
445 *
446 * PARAMS
447 * hEventLog []
448 * NumberOfRecords []
449 */
450 BOOL WINAPI
451 GetNumberOfEventLogRecords(IN HANDLE hEventLog,
452 OUT PDWORD NumberOfRecords)
453 {
454 NTSTATUS Status;
455 DWORD Records;
456
457 TRACE("%p, %p\n", hEventLog, NumberOfRecords);
458
459 if (NumberOfRecords == NULL)
460 {
461 SetLastError(ERROR_INVALID_PARAMETER);
462 return FALSE;
463 }
464
465 RpcTryExcept
466 {
467 Status = ElfrNumberOfRecords(hEventLog,
468 &Records);
469 }
470 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
471 {
472 Status = I_RpcMapWin32Status(RpcExceptionCode());
473 }
474 RpcEndExcept;
475
476 if (!NT_SUCCESS(Status))
477 {
478 SetLastError(RtlNtStatusToDosError(Status));
479 return FALSE;
480 }
481
482 *NumberOfRecords = Records;
483
484 return TRUE;
485 }
486
487
488 /******************************************************************************
489 * GetOldestEventLogRecord [ADVAPI32.@]
490 *
491 * PARAMS
492 * hEventLog []
493 * OldestRecord []
494 */
495 BOOL WINAPI
496 GetOldestEventLogRecord(IN HANDLE hEventLog,
497 OUT PDWORD OldestRecord)
498 {
499 NTSTATUS Status;
500 DWORD Oldest;
501
502 TRACE("%p, %p\n", hEventLog, OldestRecord);
503
504 if (OldestRecord == NULL)
505 {
506 SetLastError(ERROR_INVALID_PARAMETER);
507 return FALSE;
508 }
509
510 RpcTryExcept
511 {
512 Status = ElfrOldestRecord(hEventLog,
513 &Oldest);
514 }
515 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
516 {
517 Status = I_RpcMapWin32Status(RpcExceptionCode());
518 }
519 RpcEndExcept;
520
521 if (!NT_SUCCESS(Status))
522 {
523 SetLastError(RtlNtStatusToDosError(Status));
524 return FALSE;
525 }
526
527 *OldestRecord = Oldest;
528
529 return TRUE;
530 }
531
532
533 /******************************************************************************
534 * NotifyChangeEventLog [ADVAPI32.@]
535 *
536 * PARAMS
537 * hEventLog []
538 * hEvent []
539 */
540 BOOL WINAPI
541 NotifyChangeEventLog(IN HANDLE hEventLog,
542 IN HANDLE hEvent)
543 {
544 /* Use ElfrChangeNotify */
545 UNIMPLEMENTED;
546 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
547 return FALSE;
548 }
549
550
551 /******************************************************************************
552 * OpenBackupEventLogA [ADVAPI32.@]
553 */
554 HANDLE WINAPI
555 OpenBackupEventLogA(IN LPCSTR lpUNCServerName,
556 IN LPCSTR lpFileName)
557 {
558 ANSI_STRING UNCServerNameA;
559 UNICODE_STRING UNCServerNameW;
560 ANSI_STRING FileNameA;
561 UNICODE_STRING FileNameW;
562 HANDLE LogHandle;
563 NTSTATUS Status;
564
565 TRACE("%s, %s\n", lpUNCServerName, lpFileName);
566
567 /* Convert the server name to unicode */
568 if (lpUNCServerName == NULL)
569 {
570 RtlInitUnicodeString(&UNCServerNameW, NULL);
571 }
572 else
573 {
574 RtlInitAnsiString(&UNCServerNameA, lpUNCServerName);
575
576 Status = RtlAnsiStringToUnicodeString(&UNCServerNameW,
577 &UNCServerNameA,
578 TRUE);
579 if (!NT_SUCCESS(Status))
580 {
581 SetLastError(RtlNtStatusToDosError(Status));
582 return NULL;
583 }
584 }
585
586 /* Convert the file name to unicode */
587 if (lpFileName == NULL)
588 {
589 RtlInitUnicodeString(&FileNameW, NULL);
590 }
591 else
592 {
593 RtlInitAnsiString(&FileNameA, lpFileName);
594
595 Status = RtlAnsiStringToUnicodeString(&FileNameW,
596 &FileNameA,
597 TRUE);
598 if (!NT_SUCCESS(Status))
599 {
600 RtlFreeUnicodeString(&UNCServerNameW);
601 SetLastError(RtlNtStatusToDosError(Status));
602 return NULL;
603 }
604 }
605
606 /* Call the unicode function */
607 LogHandle = OpenBackupEventLogW(UNCServerNameW.Buffer,
608 FileNameW.Buffer);
609
610 /* Free the unicode strings */
611 RtlFreeUnicodeString(&UNCServerNameW);
612 RtlFreeUnicodeString(&FileNameW);
613
614 return LogHandle;
615 }
616
617
618 /******************************************************************************
619 * OpenBackupEventLogW [ADVAPI32.@]
620 *
621 * PARAMS
622 * lpUNCServerName []
623 * lpFileName []
624 */
625 HANDLE WINAPI
626 OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
627 IN LPCWSTR lpFileName)
628 {
629 UNICODE_STRING FileNameW;
630 IELF_HANDLE LogHandle;
631 NTSTATUS Status;
632
633 TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
634
635 if (lpFileName == NULL)
636 {
637 SetLastError(ERROR_INVALID_PARAMETER);
638 return NULL;
639 }
640
641 if (!RtlDosPathNameToNtPathName_U(lpFileName, &FileNameW,
642 NULL, NULL))
643 {
644 SetLastError(ERROR_INVALID_PARAMETER);
645 return NULL;
646 }
647
648 RpcTryExcept
649 {
650 Status = ElfrOpenBELW((LPWSTR)lpUNCServerName,
651 (PRPC_UNICODE_STRING)&FileNameW,
652 1,
653 1,
654 &LogHandle);
655 }
656 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
657 {
658 Status = I_RpcMapWin32Status(RpcExceptionCode());
659 }
660 RpcEndExcept;
661
662 if (FileNameW.Buffer != NULL)
663 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameW.Buffer);
664
665 if (!NT_SUCCESS(Status))
666 {
667 SetLastError(RtlNtStatusToDosError(Status));
668 return NULL;
669 }
670
671 return (HANDLE)LogHandle;
672 }
673
674
675 /******************************************************************************
676 * OpenEventLogA [ADVAPI32.@]
677 *
678 * Opens a handle to the specified event log.
679 *
680 * PARAMS
681 * lpUNCServerName [I] UNC name of the server on which the event log is
682 * opened.
683 * lpSourceName [I] Name of the log.
684 *
685 * RETURNS
686 * Success: Handle to an event log.
687 * Failure: NULL
688 */
689 HANDLE WINAPI
690 OpenEventLogA(IN LPCSTR lpUNCServerName,
691 IN LPCSTR lpSourceName)
692 {
693 LPSTR UNCServerName;
694 ANSI_STRING SourceName;
695 IELF_HANDLE LogHandle = NULL;
696 NTSTATUS Status;
697
698 TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
699
700 if (lpSourceName == NULL)
701 {
702 SetLastError(ERROR_INVALID_PARAMETER);
703 return NULL;
704 }
705
706 if (lpUNCServerName == NULL || *lpUNCServerName == 0)
707 UNCServerName = NULL;
708 else
709 UNCServerName = (LPSTR)lpUNCServerName;
710
711 RtlInitAnsiString(&SourceName, lpSourceName);
712
713 RpcTryExcept
714 {
715 Status = ElfrOpenELA(UNCServerName,
716 (PRPC_STRING)&SourceName,
717 &EmptyStringA,
718 1,
719 1,
720 &LogHandle);
721 }
722 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
723 {
724 Status = I_RpcMapWin32Status(RpcExceptionCode());
725 }
726 RpcEndExcept;
727
728 if (!NT_SUCCESS(Status))
729 {
730 SetLastError(RtlNtStatusToDosError(Status));
731 return NULL;
732 }
733
734 return (HANDLE)LogHandle;
735 }
736
737
738 /******************************************************************************
739 * OpenEventLogW [ADVAPI32.@]
740 *
741 * PARAMS
742 * lpUNCServerName []
743 * lpSourceName []
744 */
745 HANDLE WINAPI
746 OpenEventLogW(IN LPCWSTR lpUNCServerName,
747 IN LPCWSTR lpSourceName)
748 {
749 LPWSTR UNCServerName;
750 UNICODE_STRING SourceName;
751 IELF_HANDLE LogHandle;
752 NTSTATUS Status;
753
754 TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
755
756 if (lpSourceName == NULL)
757 {
758 SetLastError(ERROR_INVALID_PARAMETER);
759 return NULL;
760 }
761
762 if (lpUNCServerName == NULL || *lpUNCServerName == 0)
763 UNCServerName = NULL;
764 else
765 UNCServerName = (LPWSTR)lpUNCServerName;
766
767 RtlInitUnicodeString(&SourceName, lpSourceName);
768
769 RpcTryExcept
770 {
771 Status = ElfrOpenELW(UNCServerName,
772 (PRPC_UNICODE_STRING)&SourceName,
773 &EmptyStringU,
774 1,
775 1,
776 &LogHandle);
777 }
778 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
779 {
780 Status = I_RpcMapWin32Status(RpcExceptionCode());
781 }
782 RpcEndExcept;
783
784 if (!NT_SUCCESS(Status))
785 {
786 SetLastError(RtlNtStatusToDosError(Status));
787 return NULL;
788 }
789
790 return (HANDLE)LogHandle;
791 }
792
793
794 /******************************************************************************
795 * ReadEventLogA [ADVAPI32.@]
796 */
797 BOOL WINAPI
798 ReadEventLogA(IN HANDLE hEventLog,
799 IN DWORD dwReadFlags,
800 IN DWORD dwRecordOffset,
801 OUT LPVOID lpBuffer,
802 IN DWORD nNumberOfBytesToRead,
803 OUT DWORD *pnBytesRead,
804 OUT DWORD *pnMinNumberOfBytesNeeded)
805 {
806 NTSTATUS Status;
807 DWORD bytesRead, minNumberOfBytesNeeded;
808 DWORD dwFlags;
809
810 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
811 hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
812 nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
813
814 if (lpBuffer == NULL ||
815 pnBytesRead == NULL ||
816 pnMinNumberOfBytesNeeded == NULL)
817 {
818 SetLastError(ERROR_INVALID_PARAMETER);
819 return FALSE;
820 }
821
822 dwFlags = dwReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
823 if (dwFlags == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ))
824 {
825 SetLastError(ERROR_INVALID_PARAMETER);
826 return FALSE;
827 }
828
829 dwFlags = dwReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
830 if (dwFlags == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ))
831 {
832 SetLastError(ERROR_INVALID_PARAMETER);
833 return FALSE;
834 }
835
836 RpcTryExcept
837 {
838 Status = ElfrReadELA(hEventLog,
839 dwReadFlags,
840 dwRecordOffset,
841 nNumberOfBytesToRead,
842 lpBuffer,
843 &bytesRead,
844 &minNumberOfBytesNeeded);
845 }
846 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
847 {
848 Status = I_RpcMapWin32Status(RpcExceptionCode());
849 }
850 RpcEndExcept;
851
852 *pnBytesRead = (DWORD)bytesRead;
853 *pnMinNumberOfBytesNeeded = (DWORD)minNumberOfBytesNeeded;
854
855 if (!NT_SUCCESS(Status))
856 {
857 SetLastError(RtlNtStatusToDosError(Status));
858 return FALSE;
859 }
860
861 return TRUE;
862 }
863
864
865 /******************************************************************************
866 * ReadEventLogW [ADVAPI32.@]
867 *
868 * PARAMS
869 * hEventLog []
870 * dwReadFlags []
871 * dwRecordOffset []
872 * lpBuffer []
873 * nNumberOfBytesToRead []
874 * pnBytesRead []
875 * pnMinNumberOfBytesNeeded []
876 */
877 BOOL WINAPI
878 ReadEventLogW(IN HANDLE hEventLog,
879 IN DWORD dwReadFlags,
880 IN DWORD dwRecordOffset,
881 OUT LPVOID lpBuffer,
882 IN DWORD nNumberOfBytesToRead,
883 OUT DWORD *pnBytesRead,
884 OUT DWORD *pnMinNumberOfBytesNeeded)
885 {
886 NTSTATUS Status;
887 DWORD bytesRead, minNumberOfBytesNeeded;
888 DWORD dwFlags;
889
890 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
891 hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
892 nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
893
894 if (lpBuffer == NULL ||
895 pnBytesRead == NULL ||
896 pnMinNumberOfBytesNeeded == NULL)
897 {
898 SetLastError(ERROR_INVALID_PARAMETER);
899 return FALSE;
900 }
901
902 dwFlags = dwReadFlags & (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ);
903 if (dwFlags == (EVENTLOG_SEQUENTIAL_READ | EVENTLOG_SEEK_READ))
904 {
905 SetLastError(ERROR_INVALID_PARAMETER);
906 return FALSE;
907 }
908
909 dwFlags = dwReadFlags & (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ);
910 if (dwFlags == (EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ))
911 {
912 SetLastError(ERROR_INVALID_PARAMETER);
913 return FALSE;
914 }
915
916 RpcTryExcept
917 {
918 Status = ElfrReadELW(hEventLog,
919 dwReadFlags,
920 dwRecordOffset,
921 nNumberOfBytesToRead,
922 lpBuffer,
923 &bytesRead,
924 &minNumberOfBytesNeeded);
925 }
926 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
927 {
928 Status = I_RpcMapWin32Status(RpcExceptionCode());
929 }
930 RpcEndExcept;
931
932 *pnBytesRead = (DWORD)bytesRead;
933 *pnMinNumberOfBytesNeeded = (DWORD)minNumberOfBytesNeeded;
934
935 if (!NT_SUCCESS(Status))
936 {
937 SetLastError(RtlNtStatusToDosError(Status));
938 return FALSE;
939 }
940
941 return TRUE;
942 }
943
944
945 /******************************************************************************
946 * RegisterEventSourceA [ADVAPI32.@]
947 */
948 HANDLE WINAPI
949 RegisterEventSourceA(IN LPCSTR lpUNCServerName,
950 IN LPCSTR lpSourceName)
951 {
952 ANSI_STRING SourceName;
953 IELF_HANDLE LogHandle;
954 NTSTATUS Status;
955
956 TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
957
958 RtlInitAnsiString(&SourceName, lpSourceName);
959
960 RpcTryExcept
961 {
962 Status = ElfrRegisterEventSourceA((LPSTR)lpUNCServerName,
963 (PRPC_STRING)&SourceName,
964 &EmptyStringA,
965 1,
966 1,
967 &LogHandle);
968 }
969 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
970 {
971 Status = I_RpcMapWin32Status(RpcExceptionCode());
972 }
973 RpcEndExcept;
974
975 if (!NT_SUCCESS(Status))
976 {
977 SetLastError(RtlNtStatusToDosError(Status));
978 return NULL;
979 }
980
981 return (HANDLE)LogHandle;
982 }
983
984
985 /******************************************************************************
986 * RegisterEventSourceW [ADVAPI32.@]
987 * Returns a registered handle to an event log
988 *
989 * PARAMS
990 * lpUNCServerName [I] Server name for source
991 * lpSourceName [I] Source name for registered handle
992 *
993 * RETURNS
994 * Success: Handle
995 * Failure: NULL
996 */
997 HANDLE WINAPI
998 RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
999 IN LPCWSTR lpSourceName)
1000 {
1001 UNICODE_STRING SourceName;
1002 IELF_HANDLE LogHandle;
1003 NTSTATUS Status;
1004
1005 TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
1006
1007 RtlInitUnicodeString(&SourceName, lpSourceName);
1008
1009 RpcTryExcept
1010 {
1011 Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName,
1012 (PRPC_UNICODE_STRING)&SourceName,
1013 &EmptyStringU,
1014 1,
1015 1,
1016 &LogHandle);
1017 }
1018 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1019 {
1020 Status = I_RpcMapWin32Status(RpcExceptionCode());
1021 }
1022 RpcEndExcept;
1023
1024 if (!NT_SUCCESS(Status))
1025 {
1026 SetLastError(RtlNtStatusToDosError(Status));
1027 return NULL;
1028 }
1029
1030 return (HANDLE)LogHandle;
1031 }
1032
1033
1034 /******************************************************************************
1035 * ReportEventA [ADVAPI32.@]
1036 */
1037 BOOL WINAPI
1038 ReportEventA(IN HANDLE hEventLog,
1039 IN WORD wType,
1040 IN WORD wCategory,
1041 IN DWORD dwEventID,
1042 IN PSID lpUserSid,
1043 IN WORD wNumStrings,
1044 IN DWORD dwDataSize,
1045 IN LPCSTR *lpStrings,
1046 IN LPVOID lpRawData)
1047 {
1048 NTSTATUS Status;
1049 PANSI_STRING *Strings;
1050 ANSI_STRING ComputerName;
1051 WORD i;
1052 CHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1053 DWORD dwSize;
1054 LARGE_INTEGER SystemTime;
1055 ULONG Seconds;
1056
1057 TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
1058 hEventLog, wType, wCategory, dwEventID, lpUserSid,
1059 wNumStrings, dwDataSize, lpStrings, lpRawData);
1060
1061 Strings = HeapAlloc(GetProcessHeap(),
1062 HEAP_ZERO_MEMORY,
1063 wNumStrings * sizeof(PANSI_STRING));
1064 if (!Strings)
1065 {
1066 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1067 return FALSE;
1068 }
1069
1070 for (i = 0; i < wNumStrings; i++)
1071 {
1072 Strings[i] = HeapAlloc(GetProcessHeap(),
1073 HEAP_ZERO_MEMORY,
1074 sizeof(ANSI_STRING));
1075 if (Strings[i])
1076 {
1077 RtlInitAnsiString(Strings[i], lpStrings[i]);
1078 }
1079 }
1080
1081 dwSize = MAX_COMPUTERNAME_LENGTH + 1;
1082 GetComputerNameA(szComputerName, &dwSize);
1083 RtlInitAnsiString(&ComputerName, szComputerName);
1084
1085 NtQuerySystemTime(&SystemTime);
1086 RtlTimeToSecondsSince1970(&SystemTime, &Seconds);
1087
1088 RpcTryExcept
1089 {
1090 Status = ElfrReportEventA(hEventLog,
1091 Seconds,
1092 wType,
1093 wCategory,
1094 dwEventID,
1095 wNumStrings,
1096 dwDataSize,
1097 (PRPC_STRING)&ComputerName,
1098 lpUserSid,
1099 (PRPC_STRING*)Strings,
1100 lpRawData,
1101 0,
1102 NULL,
1103 NULL);
1104 }
1105 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1106 {
1107 Status = I_RpcMapWin32Status(RpcExceptionCode());
1108 }
1109 RpcEndExcept;
1110
1111 for (i = 0; i < wNumStrings; i++)
1112 {
1113 if (Strings[i] != NULL)
1114 HeapFree(GetProcessHeap(), 0, Strings[i]);
1115 }
1116
1117 HeapFree(GetProcessHeap(), 0, Strings);
1118
1119 if (!NT_SUCCESS(Status))
1120 {
1121 SetLastError(RtlNtStatusToDosError(Status));
1122 return FALSE;
1123 }
1124
1125 return TRUE;
1126 }
1127
1128
1129 /******************************************************************************
1130 * ReportEventW [ADVAPI32.@]
1131 *
1132 * PARAMS
1133 * hEventLog []
1134 * wType []
1135 * wCategory []
1136 * dwEventID []
1137 * lpUserSid []
1138 * wNumStrings []
1139 * dwDataSize []
1140 * lpStrings []
1141 * lpRawData []
1142 */
1143 BOOL WINAPI
1144 ReportEventW(IN HANDLE hEventLog,
1145 IN WORD wType,
1146 IN WORD wCategory,
1147 IN DWORD dwEventID,
1148 IN PSID lpUserSid,
1149 IN WORD wNumStrings,
1150 IN DWORD dwDataSize,
1151 IN LPCWSTR *lpStrings,
1152 IN LPVOID lpRawData)
1153 {
1154 NTSTATUS Status;
1155 PUNICODE_STRING *Strings;
1156 UNICODE_STRING ComputerName;
1157 WORD i;
1158 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1159 DWORD dwSize;
1160 LARGE_INTEGER SystemTime;
1161 ULONG Seconds;
1162
1163 TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
1164 hEventLog, wType, wCategory, dwEventID, lpUserSid,
1165 wNumStrings, dwDataSize, lpStrings, lpRawData);
1166
1167 Strings = HeapAlloc(GetProcessHeap(),
1168 0,
1169 wNumStrings * sizeof(PUNICODE_STRING));
1170 if (!Strings)
1171 {
1172 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1173 return FALSE;
1174 }
1175
1176 for (i = 0; i < wNumStrings; i++)
1177 {
1178 Strings[i] = HeapAlloc(GetProcessHeap(),
1179 HEAP_ZERO_MEMORY,
1180 sizeof(ANSI_STRING));
1181 if (Strings[i])
1182 {
1183 RtlInitUnicodeString(Strings[i], lpStrings[i]);
1184 }
1185 }
1186
1187 dwSize = MAX_COMPUTERNAME_LENGTH + 1;
1188 GetComputerNameW(szComputerName, &dwSize);
1189 RtlInitUnicodeString(&ComputerName, szComputerName);
1190
1191 NtQuerySystemTime(&SystemTime);
1192 RtlTimeToSecondsSince1970(&SystemTime, &Seconds);
1193
1194 RpcTryExcept
1195 {
1196 Status = ElfrReportEventW(hEventLog,
1197 Seconds,
1198 wType,
1199 wCategory,
1200 dwEventID,
1201 wNumStrings,
1202 dwDataSize,
1203 (PRPC_UNICODE_STRING)&ComputerName,
1204 lpUserSid,
1205 (PRPC_UNICODE_STRING*)Strings,
1206 lpRawData,
1207 0,
1208 NULL,
1209 NULL);
1210 }
1211 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1212 {
1213 Status = I_RpcMapWin32Status(RpcExceptionCode());
1214 }
1215 RpcEndExcept;
1216
1217 for (i = 0; i < wNumStrings; i++)
1218 {
1219 if (Strings[i] != NULL)
1220 HeapFree(GetProcessHeap(), 0, Strings[i]);
1221 }
1222
1223 HeapFree(GetProcessHeap(), 0, Strings);
1224
1225 if (!NT_SUCCESS(Status))
1226 {
1227 SetLastError(RtlNtStatusToDosError(Status));
1228 return FALSE;
1229 }
1230
1231 return TRUE;
1232 }
1233