Bring back ext2 code from branch
[reactos.git] / reactos / 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include <advapi32.h>
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
28 WINE_DECLARE_DEBUG_CHANNEL(eventlog);
29
30 typedef struct _LOG_INFO
31 {
32 RPC_BINDING_HANDLE BindingHandle;
33 LOGHANDLE LogHandle;
34 BOOL bLocal;
35 } LOG_INFO, *PLOG_INFO;
36
37 /******************************************************************************
38 * BackupEventLogA [ADVAPI32.@]
39 */
40 BOOL WINAPI
41 BackupEventLogA(
42 IN HANDLE hEventLog,
43 IN LPCSTR lpBackupFileName)
44 {
45 PLOG_INFO pLog;
46 NTSTATUS Status;
47 ANSI_STRING BackupFileName;
48
49 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
50
51 RtlInitAnsiString(&BackupFileName, lpBackupFileName);
52
53 pLog = (PLOG_INFO)hEventLog;
54 if (!pLog)
55 {
56 SetLastError(ERROR_INVALID_HANDLE);
57 return FALSE;
58 }
59 Status = ElfrBackupELFA(
60 pLog->BindingHandle,
61 pLog->LogHandle,
62 BackupFileName.Buffer);
63
64 if (!NT_SUCCESS(Status))
65 {
66 SetLastError(RtlNtStatusToDosError(Status));
67 return FALSE;
68 }
69 return TRUE;
70 }
71
72 /******************************************************************************
73 * BackupEventLogW [ADVAPI32.@]
74 *
75 * PARAMS
76 * hEventLog []
77 * lpBackupFileName []
78 */
79 BOOL WINAPI
80 BackupEventLogW(
81 IN HANDLE hEventLog,
82 IN LPCWSTR lpBackupFileName)
83 {
84 PLOG_INFO pLog;
85 NTSTATUS Status;
86 UNICODE_STRING BackupFileName;
87
88 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
89
90 RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
91
92 pLog = (PLOG_INFO)hEventLog;
93 if (!pLog)
94 {
95 SetLastError(ERROR_INVALID_HANDLE);
96 return FALSE;
97 }
98 Status = ElfrBackupELFW(
99 pLog->BindingHandle,
100 pLog->LogHandle,
101 BackupFileName.Buffer);
102
103 if (!NT_SUCCESS(Status))
104 {
105 SetLastError(RtlNtStatusToDosError(Status));
106 return FALSE;
107 }
108 return TRUE;
109 }
110
111
112 /******************************************************************************
113 * ClearEventLogA [ADVAPI32.@]
114 */
115 BOOL WINAPI
116 ClearEventLogA(
117 IN HANDLE hEventLog,
118 IN LPCSTR lpBackupFileName)
119 {
120 PLOG_INFO pLog;
121 NTSTATUS Status;
122 ANSI_STRING BackupFileName;
123
124 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
125
126 RtlInitAnsiString(&BackupFileName, lpBackupFileName);
127
128 pLog = (PLOG_INFO)hEventLog;
129 if (!pLog)
130 {
131 SetLastError(ERROR_INVALID_HANDLE);
132 return FALSE;
133 }
134 Status = ElfrClearELFA(
135 pLog->BindingHandle,
136 pLog->LogHandle,
137 BackupFileName.Buffer);
138
139 if (!NT_SUCCESS(Status))
140 {
141 SetLastError(RtlNtStatusToDosError(Status));
142 return FALSE;
143 }
144 return TRUE;
145 }
146
147
148 /******************************************************************************
149 * ClearEventLogW [ADVAPI32.@]
150 */
151 BOOL WINAPI
152 ClearEventLogW(
153 IN HANDLE hEventLog,
154 IN LPCWSTR lpBackupFileName)
155 {
156 PLOG_INFO pLog;
157 NTSTATUS Status;
158 UNICODE_STRING BackupFileName;
159
160 TRACE("%p, %s\n", hEventLog, lpBackupFileName);
161
162 RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
163
164 pLog = (PLOG_INFO)hEventLog;
165 if (!pLog)
166 {
167 SetLastError(ERROR_INVALID_HANDLE);
168 return FALSE;
169 }
170 Status = ElfrClearELFW(
171 pLog->BindingHandle,
172 pLog->LogHandle,
173 BackupFileName.Buffer);
174
175 if (!NT_SUCCESS(Status))
176 {
177 SetLastError(RtlNtStatusToDosError(Status));
178 return FALSE;
179 }
180 return TRUE;
181 }
182
183
184 /******************************************************************************
185 * CloseEventLog [ADVAPI32.@]
186 */
187 BOOL WINAPI
188 CloseEventLog(
189 IN HANDLE hEventLog)
190 {
191 PLOG_INFO pLog;
192 NTSTATUS Status;
193
194 TRACE("%p", hEventLog);
195
196 pLog = (PLOG_INFO)hEventLog;
197 if (!pLog)
198 return TRUE;
199
200 if (pLog->bLocal == FALSE)
201 {
202 if (!EvtUnbindRpc(pLog->BindingHandle))
203 {
204 SetLastError(ERROR_ACCESS_DENIED);
205 return FALSE;
206 }
207 }
208 else
209 {
210 Status = ElfrCloseEL(
211 pLog->BindingHandle,
212 &pLog->LogHandle);
213 if (!NT_SUCCESS(Status))
214 {
215 SetLastError(RtlNtStatusToDosError(Status));
216 return FALSE;
217 }
218 }
219
220 HeapFree(GetProcessHeap(), 0, pLog);
221
222 return TRUE;
223 }
224
225
226 /******************************************************************************
227 * DeregisterEventSource [ADVAPI32.@]
228 * Closes a handle to the specified event log
229 *
230 * PARAMS
231 * hEventLog [I] Handle to event log
232 *
233 * RETURNS STD
234 */
235 BOOL WINAPI
236 DeregisterEventSource(
237 IN HANDLE hEventLog)
238 {
239 PLOG_INFO pLog;
240 NTSTATUS Status;
241
242 TRACE("%p\n", hEventLog);
243
244 pLog = (PLOG_INFO)hEventLog;
245 if (!pLog)
246 return TRUE;
247
248 Status = ElfrDeregisterEventSource(
249 pLog->BindingHandle,
250 &pLog->LogHandle);
251 if (!NT_SUCCESS(Status))
252 {
253 SetLastError(RtlNtStatusToDosError(Status));
254 return FALSE;
255 }
256 return TRUE;
257 }
258
259
260 /******************************************************************************
261 * GetNumberOfEventLogRecords [ADVAPI32.@]
262 *
263 * PARAMS
264 * hEventLog []
265 * NumberOfRecords []
266 */
267 BOOL WINAPI
268 GetNumberOfEventLogRecords(
269 IN HANDLE hEventLog,
270 OUT PDWORD NumberOfRecords)
271 {
272 PLOG_INFO pLog;
273 NTSTATUS Status;
274 long Records;
275
276 TRACE("%p, %p\n", hEventLog, NumberOfRecords);
277
278 pLog = (PLOG_INFO)hEventLog;
279 if (!pLog)
280 {
281 SetLastError(ERROR_INVALID_HANDLE);
282 return FALSE;
283 }
284 Status = ElfrNumberOfRecords(
285 pLog->BindingHandle,
286 pLog->LogHandle,
287 &Records);
288 if (!NT_SUCCESS(Status))
289 {
290 SetLastError(RtlNtStatusToDosError(Status));
291 return FALSE;
292 }
293
294 *NumberOfRecords = Records;
295 return TRUE;
296 }
297
298
299 /******************************************************************************
300 * GetOldestEventLogRecord [ADVAPI32.@]
301 *
302 * PARAMS
303 * hEventLog []
304 * OldestRecord []
305 */
306 BOOL WINAPI
307 GetOldestEventLogRecord(
308 IN HANDLE hEventLog,
309 OUT PDWORD OldestRecord)
310 {
311 PLOG_INFO pLog;
312 NTSTATUS Status;
313 long Oldest;
314
315 TRACE("%p, %p\n", hEventLog, OldestRecord);
316
317 pLog = (PLOG_INFO)hEventLog;
318 if (!pLog)
319 {
320 SetLastError(ERROR_INVALID_HANDLE);
321 return FALSE;
322 }
323 Status = ElfrOldestRecord(
324 pLog->BindingHandle,
325 pLog->LogHandle,
326 &Oldest);
327 if (!NT_SUCCESS(Status))
328 {
329 SetLastError(RtlNtStatusToDosError(Status));
330 return FALSE;
331 }
332
333 *OldestRecord = Oldest;
334 return TRUE;
335 }
336
337
338 /******************************************************************************
339 * NotifyChangeEventLog [ADVAPI32.@]
340 *
341 * PARAMS
342 * hEventLog []
343 * hEvent []
344 */
345 BOOL WINAPI
346 NotifyChangeEventLog(
347 IN HANDLE hEventLog,
348 IN HANDLE hEvent)
349 {
350 /* Use ElfrChangeNotify */
351 UNIMPLEMENTED;
352 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
353 return FALSE;
354 }
355
356
357 /******************************************************************************
358 * OpenBackupEventLogA [ADVAPI32.@]
359 */
360 HANDLE WINAPI
361 OpenBackupEventLogA(
362 IN LPCSTR lpUNCServerName,
363 IN LPCSTR lpFileName)
364 {
365 UNICODE_STRING UNCServerName;
366 UNICODE_STRING FileName;
367 HANDLE Handle;
368
369 TRACE("%s, %s\n", lpUNCServerName, lpFileName);
370
371 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName, lpUNCServerName))
372 {
373 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
374 return NULL;
375 }
376 if (!RtlCreateUnicodeStringFromAsciiz(&FileName, lpFileName))
377 {
378 RtlFreeUnicodeString(&UNCServerName);
379 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
380 return NULL;
381 }
382
383 Handle = OpenBackupEventLogW(
384 UNCServerName.Buffer,
385 FileName.Buffer);
386
387 RtlFreeUnicodeString(&UNCServerName);
388 RtlFreeUnicodeString(&FileName);
389
390 return Handle;
391 }
392
393
394 /******************************************************************************
395 * OpenBackupEventLogW [ADVAPI32.@]
396 *
397 * PARAMS
398 * lpUNCServerName []
399 * lpFileName []
400 */
401 HANDLE WINAPI
402 OpenBackupEventLogW(
403 IN LPCWSTR lpUNCServerName,
404 IN LPCWSTR lpFileName)
405 {
406 PLOG_INFO pLog;
407 NTSTATUS Status;
408 UNICODE_STRING UNCServerName;
409 UNICODE_STRING FileName;
410
411 TRACE("%s, %s\n", lpUNCServerName, lpFileName);
412
413 RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
414 RtlInitUnicodeString(&FileName, lpFileName);
415
416 pLog = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO));
417 if (!pLog)
418 {
419 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
420 return NULL;
421 }
422 ZeroMemory(pLog, sizeof(LOG_INFO));
423
424 if (lpUNCServerName == NULL || *lpUNCServerName == 0)
425 {
426 pLog->bLocal = TRUE;
427
428 if (!EvtGetLocalHandle(&pLog->BindingHandle))
429 {
430 HeapFree(GetProcessHeap(), 0, pLog);
431 SetLastError(ERROR_GEN_FAILURE);
432 return NULL;
433 }
434 }
435 else
436 {
437 pLog->bLocal = FALSE;
438
439 if (!EvtBindRpc(lpUNCServerName, &pLog->BindingHandle))
440 {
441 HeapFree(GetProcessHeap(), 0, pLog);
442 SetLastError(ERROR_INVALID_COMPUTERNAME);
443 return NULL;
444 }
445 }
446
447 Status = ElfrOpenBELW(
448 pLog->BindingHandle,
449 UNCServerName.Buffer,
450 FileName.Buffer,
451 0,
452 0,
453 &pLog->LogHandle);
454
455 if (!NT_SUCCESS(Status))
456 {
457 SetLastError(RtlNtStatusToDosError(Status));
458 HeapFree(GetProcessHeap(), 0, pLog);
459 return NULL;
460 }
461 return pLog;
462 }
463
464
465 /******************************************************************************
466 * OpenEventLogA [ADVAPI32.@]
467 */
468 HANDLE WINAPI
469 OpenEventLogA(
470 IN LPCSTR lpUNCServerName,
471 IN LPCSTR lpSourceName)
472 {
473 UNICODE_STRING UNCServerName;
474 UNICODE_STRING SourceName;
475 HANDLE Handle;
476
477 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName, lpUNCServerName))
478 {
479 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
480 return NULL;
481 }
482 if (!RtlCreateUnicodeStringFromAsciiz(&SourceName, lpSourceName))
483 {
484 RtlFreeUnicodeString(&UNCServerName);
485 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
486 return NULL;
487 }
488
489 Handle = OpenEventLogW(UNCServerName.Buffer, SourceName.Buffer);
490
491 RtlFreeUnicodeString(&UNCServerName);
492 RtlFreeUnicodeString(&SourceName);
493
494 return Handle;
495 }
496
497
498 /******************************************************************************
499 * OpenEventLogW [ADVAPI32.@]
500 *
501 * PARAMS
502 * lpUNCServerName []
503 * lpSourceName []
504 */
505 HANDLE WINAPI
506 OpenEventLogW(
507 IN LPCWSTR lpUNCServerName,
508 IN LPCWSTR lpSourceName)
509 {
510 PLOG_INFO pLog;
511 NTSTATUS Status;
512 UNICODE_STRING UNCServerName;
513 UNICODE_STRING SourceName;
514
515 TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
516
517 RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
518 RtlInitUnicodeString(&SourceName, lpSourceName);
519
520 pLog = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO));
521 if (!pLog)
522 {
523 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
524 return NULL;
525 }
526 ZeroMemory(pLog, sizeof(LOG_INFO));
527
528 if (lpUNCServerName == NULL || *lpUNCServerName == 0)
529 {
530 pLog->bLocal = TRUE;
531
532 if (!EvtGetLocalHandle(&pLog->BindingHandle))
533 {
534 HeapFree(GetProcessHeap(), 0, pLog);
535 SetLastError(ERROR_GEN_FAILURE);
536 return NULL;
537 }
538 }
539 else
540 {
541 pLog->bLocal = FALSE;
542
543 if (!EvtBindRpc(lpUNCServerName, &pLog->BindingHandle))
544 {
545 HeapFree(GetProcessHeap(), 0, pLog);
546 SetLastError(ERROR_INVALID_COMPUTERNAME);
547 return NULL;
548 }
549 }
550
551 Status = ElfrOpenELW(
552 pLog->BindingHandle,
553 UNCServerName.Buffer,
554 SourceName.Buffer,
555 NULL,
556 0,
557 0,
558 &pLog->LogHandle);
559
560 if (!NT_SUCCESS(Status))
561 {
562 SetLastError(RtlNtStatusToDosError(Status));
563 HeapFree(GetProcessHeap(), 0, pLog);
564 return NULL;
565 }
566 return pLog;
567 }
568
569
570 /******************************************************************************
571 * ReadEventLogA [ADVAPI32.@]
572 */
573 BOOL WINAPI
574 ReadEventLogA(
575 IN HANDLE hEventLog,
576 IN DWORD dwReadFlags,
577 IN DWORD dwRecordOffset,
578 OUT LPVOID lpBuffer,
579 IN DWORD nNumberOfBytesToRead,
580 OUT DWORD *pnBytesRead,
581 OUT DWORD *pnMinNumberOfBytesNeeded)
582 {
583 PLOG_INFO pLog;
584 NTSTATUS Status;
585 long bytesRead, minNumberOfBytesNeeded;
586
587 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
588 hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
589 nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
590
591 pLog = (PLOG_INFO)hEventLog;
592 if (!pLog)
593 {
594 SetLastError(ERROR_INVALID_HANDLE);
595 return FALSE;
596 }
597 Status = ElfrReadELA(
598 pLog->BindingHandle,
599 pLog->LogHandle,
600 dwReadFlags,
601 dwRecordOffset,
602 nNumberOfBytesToRead,
603 lpBuffer,
604 &bytesRead,
605 &minNumberOfBytesNeeded);
606 if (!NT_SUCCESS(Status))
607 {
608 SetLastError(RtlNtStatusToDosError(Status));
609 return FALSE;
610 }
611
612 *pnBytesRead = (DWORD)bytesRead;
613 *pnMinNumberOfBytesNeeded = (DWORD)minNumberOfBytesNeeded;
614 return TRUE;
615 }
616
617
618 /******************************************************************************
619 * ReadEventLogW [ADVAPI32.@]
620 *
621 * PARAMS
622 * hEventLog []
623 * dwReadFlags []
624 * dwRecordOffset []
625 * lpBuffer []
626 * nNumberOfBytesToRead []
627 * pnBytesRead []
628 * pnMinNumberOfBytesNeeded []
629 */
630 BOOL WINAPI
631 ReadEventLogW(
632 IN HANDLE hEventLog,
633 IN DWORD dwReadFlags,
634 IN DWORD dwRecordOffset,
635 OUT LPVOID lpBuffer,
636 IN DWORD nNumberOfBytesToRead,
637 OUT DWORD *pnBytesRead,
638 OUT DWORD *pnMinNumberOfBytesNeeded)
639 {
640 PLOG_INFO pLog;
641 NTSTATUS Status;
642 long bytesRead, minNumberOfBytesNeeded;
643
644 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
645 hEventLog, dwReadFlags, dwRecordOffset, lpBuffer,
646 nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);
647
648 pLog = (PLOG_INFO)hEventLog;
649 if (!pLog)
650 {
651 SetLastError(ERROR_INVALID_HANDLE);
652 return FALSE;
653 }
654 Status = ElfrReadELW(
655 pLog->BindingHandle,
656 pLog->LogHandle,
657 dwReadFlags,
658 dwRecordOffset,
659 nNumberOfBytesToRead,
660 lpBuffer,
661 &bytesRead,
662 &minNumberOfBytesNeeded);
663 if (!NT_SUCCESS(Status))
664 {
665 SetLastError(RtlNtStatusToDosError(Status));
666 return FALSE;
667 }
668
669 *pnBytesRead = (DWORD)bytesRead;
670 *pnMinNumberOfBytesNeeded = (DWORD)minNumberOfBytesNeeded;
671 return TRUE;
672 }
673
674
675 /******************************************************************************
676 * RegisterEventSourceA [ADVAPI32.@]
677 */
678 HANDLE WINAPI
679 RegisterEventSourceA(
680 IN LPCSTR lpUNCServerName,
681 IN LPCSTR lpSourceName)
682 {
683 UNICODE_STRING UNCServerName;
684 UNICODE_STRING SourceName;
685 HANDLE Handle;
686
687 TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
688
689 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName, lpUNCServerName))
690 {
691 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
692 return NULL;
693 }
694 if (!RtlCreateUnicodeStringFromAsciiz(&SourceName, lpSourceName))
695 {
696 RtlFreeUnicodeString(&UNCServerName);
697 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
698 return NULL;
699 }
700
701 Handle = RegisterEventSourceW(UNCServerName.Buffer, SourceName.Buffer);
702
703 RtlFreeUnicodeString(&UNCServerName);
704 RtlFreeUnicodeString(&SourceName);
705
706 return Handle;
707 }
708
709
710 /******************************************************************************
711 * RegisterEventSourceW [ADVAPI32.@]
712 * Returns a registered handle to an event log
713 *
714 * PARAMS
715 * lpUNCServerName [I] Server name for source
716 * lpSourceName [I] Source name for registered handle
717 *
718 * RETURNS
719 * Success: Handle
720 * Failure: NULL
721 */
722 HANDLE WINAPI
723 RegisterEventSourceW(
724 IN LPCWSTR lpUNCServerName,
725 IN LPCWSTR lpSourceName)
726 {
727 PLOG_INFO pLog;
728 NTSTATUS Status;
729 UNICODE_STRING UNCServerName;
730 UNICODE_STRING SourceName;
731
732 TRACE("%s, %s\n", lpUNCServerName, lpSourceName);
733
734 RtlInitUnicodeString(&UNCServerName, lpUNCServerName);
735 RtlInitUnicodeString(&SourceName, lpSourceName);
736
737 pLog = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO));
738 if (!pLog)
739 {
740 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
741 return NULL;
742 }
743 ZeroMemory(pLog, sizeof(LOG_INFO));
744
745 if (lpUNCServerName == NULL || *lpUNCServerName == 0)
746 {
747 pLog->bLocal = TRUE;
748
749 if (!EvtGetLocalHandle(&pLog->BindingHandle))
750 {
751 HeapFree(GetProcessHeap(), 0, pLog);
752 SetLastError(ERROR_GEN_FAILURE);
753 return NULL;
754 }
755 }
756 else
757 {
758 pLog->bLocal = FALSE;
759
760 if (!EvtBindRpc(lpUNCServerName, &pLog->BindingHandle))
761 {
762 HeapFree(GetProcessHeap(), 0, pLog);
763 SetLastError(ERROR_INVALID_COMPUTERNAME);
764 return NULL;
765 }
766 }
767
768 Status = ElfrRegisterEventSourceW(
769 pLog->BindingHandle,
770 UNCServerName.Buffer,
771 SourceName.Buffer,
772 L"",
773 0,
774 0,
775 &pLog->LogHandle);
776
777 if (!NT_SUCCESS(Status))
778 {
779 SetLastError(RtlNtStatusToDosError(Status));
780 HeapFree(GetProcessHeap(), 0, pLog);
781 return NULL;
782 }
783 return pLog;
784 }
785
786
787 /******************************************************************************
788 * ReportEventA [ADVAPI32.@]
789 */
790 BOOL WINAPI
791 ReportEventA(
792 IN HANDLE hEventLog,
793 IN WORD wType,
794 IN WORD wCategory,
795 IN DWORD dwEventID,
796 IN PSID lpUserSid,
797 IN WORD wNumStrings,
798 IN DWORD dwDataSize,
799 IN LPCSTR *lpStrings,
800 IN LPVOID lpRawData)
801 {
802 LPCWSTR *wideStrArray;
803 UNICODE_STRING str;
804 WORD i;
805 BOOL ret;
806
807 if (wNumStrings == 0)
808 return TRUE;
809
810 if (lpStrings == NULL)
811 return TRUE;
812
813 wideStrArray = HeapAlloc(
814 GetProcessHeap(),
815 HEAP_ZERO_MEMORY,
816 sizeof(LPCWSTR) * wNumStrings);
817
818 for (i = 0; i < wNumStrings; i++)
819 {
820 if (!RtlCreateUnicodeStringFromAsciiz(&str, (PSTR)lpStrings[i]))
821 break;
822 wideStrArray[i] = str.Buffer;
823 }
824
825 if (i == wNumStrings)
826 {
827 ret = ReportEventW(
828 hEventLog,
829 wType,
830 wCategory,
831 dwEventID,
832 lpUserSid,
833 wNumStrings,
834 dwDataSize,
835 wideStrArray,
836 lpRawData);
837 }
838 else
839 {
840 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
841 ret = FALSE;
842 }
843
844 for (i = 0; i < wNumStrings; i++)
845 {
846 if (wideStrArray[i])
847 {
848 HeapFree(
849 GetProcessHeap(),
850 0,
851 (PVOID)wideStrArray[i]);
852 }
853 }
854
855 HeapFree(
856 GetProcessHeap(),
857 0,
858 wideStrArray);
859
860 return ret;
861 }
862
863
864 /******************************************************************************
865 * ReportEventW [ADVAPI32.@]
866 *
867 * PARAMS
868 * hEventLog []
869 * wType []
870 * wCategory []
871 * dwEventID []
872 * lpUserSid []
873 * wNumStrings []
874 * dwDataSize []
875 * lpStrings []
876 * lpRawData []
877 */
878 BOOL WINAPI
879 ReportEventW(
880 IN HANDLE hEventLog,
881 IN WORD wType,
882 IN WORD wCategory,
883 IN DWORD dwEventID,
884 IN PSID lpUserSid,
885 IN WORD wNumStrings,
886 IN DWORD dwDataSize,
887 IN LPCWSTR *lpStrings,
888 IN LPVOID lpRawData)
889 {
890 #if 0
891 PLOG_INFO pLog;
892 NTSTATUS Status;
893 UNICODE_STRING *Strings;
894 WORD i;
895
896 TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
897 hEventLog, wType, wCategory, dwEventID, lpUserSid,
898 wNumStrings, dwDataSize, lpStrings, lpRawData);
899
900 pLog = (PLOG_INFO)hEventLog;
901 if (!pLog)
902 {
903 SetLastError(ERROR_INVALID_HANDLE);
904 return FALSE;
905 }
906
907 Strings = HeapAlloc(
908 GetProcessHeap(),
909 0,
910 wNumStrings * sizeof(UNICODE_STRING));
911 if (!Strings)
912 {
913 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
914 return FALSE;
915 }
916 for (i = 0; i < wNumStrings; i++)
917 RtlInitUnicodeString(&Strings[i], lpStrings[i]);
918
919 Status = ElfrReportEventW(
920 pLog->BindingHandle,
921 pLog->LogHandle,
922 0, /* FIXME: Time */
923 wType,
924 wCategory,
925 dwEventID,
926 wNumStrings,
927 dwDataSize,
928 L"", /* FIXME: ComputerName */
929 lpUserSid,
930 (LPWSTR *)lpStrings, /* FIXME: should be Strings */
931 lpRawData,
932 0,
933 NULL,
934 NULL);
935 HeapFree(GetProcessHeap(), 0, Strings);
936
937 if (!NT_SUCCESS(Status))
938 {
939 SetLastError(RtlNtStatusToDosError(Status));
940 return FALSE;
941 }
942 return TRUE;
943 #else
944 int i;
945
946 /* partial stub */
947
948 if (wNumStrings == 0)
949 return TRUE;
950
951 if (lpStrings == NULL)
952 return TRUE;
953
954 for (i = 0; i < wNumStrings; i++)
955 {
956 switch (wType)
957 {
958 case EVENTLOG_SUCCESS:
959 TRACE_(eventlog)("Success: %S\n", lpStrings[i]);
960 break;
961
962 case EVENTLOG_ERROR_TYPE:
963 ERR_(eventlog)("Error: %S\n", lpStrings[i]);
964 break;
965
966 case EVENTLOG_WARNING_TYPE:
967 WARN_(eventlog)("Warning: %S\n", lpStrings[i]);
968 break;
969
970 case EVENTLOG_INFORMATION_TYPE:
971 TRACE_(eventlog)("Info: %S\n", lpStrings[i]);
972 break;
973
974 default:
975 TRACE_(eventlog)("Type %hu: %S\n", wType, lpStrings[i]);
976 break;
977 }
978 }
979
980 return TRUE;
981 #endif
982 }