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