2 * Win32 advapi functions
4 * Copyright 1995 Sven Verdoolaege
5 * Copyright 1998 Juergen Schmied
6 * Copyright 2003 Mike Hearn
7 * Copyright 2007 Hervé Poussineau
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.
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.
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
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
28 WINE_DECLARE_DEBUG_CHANNEL(eventlog
);
30 typedef struct _LOG_INFO
32 RPC_BINDING_HANDLE BindingHandle
;
33 IELF_HANDLE LogHandle
;
35 } LOG_INFO
, *PLOG_INFO
;
37 static RPC_UNICODE_STRING EmptyString
= { 0, 0, L
"" };
39 /******************************************************************************
40 * BackupEventLogA [ADVAPI32.@]
43 BackupEventLogA(IN HANDLE hEventLog
,
44 IN LPCSTR lpBackupFileName
)
48 RPC_STRING BackupFileName
;
50 TRACE("%p, %s\n", hEventLog
, lpBackupFileName
);
52 BackupFileName
.Buffer
= (LPSTR
)lpBackupFileName
;
53 BackupFileName
.Length
= BackupFileName
.MaximumLength
=
54 lpBackupFileName
? strlen(lpBackupFileName
) : 0;
56 pLog
= (PLOG_INFO
)hEventLog
;
59 SetLastError(ERROR_INVALID_HANDLE
);
63 Status
= ElfrBackupELFA(pLog
->BindingHandle
,
66 if (!NT_SUCCESS(Status
))
68 SetLastError(RtlNtStatusToDosError(Status
));
75 /******************************************************************************
76 * BackupEventLogW [ADVAPI32.@]
83 BackupEventLogW(IN HANDLE hEventLog
,
84 IN LPCWSTR lpBackupFileName
)
88 RPC_UNICODE_STRING BackupFileName
;
90 TRACE("%p, %s\n", hEventLog
, debugstr_w(lpBackupFileName
));
92 BackupFileName
.Buffer
= (LPWSTR
)lpBackupFileName
;
93 BackupFileName
.Length
= BackupFileName
.MaximumLength
=
94 lpBackupFileName
? wcslen(lpBackupFileName
) * sizeof(WCHAR
) : 0;
96 pLog
= (PLOG_INFO
)hEventLog
;
99 SetLastError(ERROR_INVALID_HANDLE
);
103 Status
= ElfrBackupELFW(pLog
->BindingHandle
,
106 if (!NT_SUCCESS(Status
))
108 SetLastError(RtlNtStatusToDosError(Status
));
116 /******************************************************************************
117 * ClearEventLogA [ADVAPI32.@]
120 ClearEventLogA(IN HANDLE hEventLog
,
121 IN LPCSTR lpBackupFileName
)
125 RPC_STRING BackupFileName
;
127 TRACE("%p, %s\n", hEventLog
, lpBackupFileName
);
129 BackupFileName
.Buffer
= (LPSTR
)lpBackupFileName
;
130 BackupFileName
.Length
= BackupFileName
.MaximumLength
=
131 lpBackupFileName
? strlen(lpBackupFileName
) : 0;
133 pLog
= (PLOG_INFO
)hEventLog
;
136 SetLastError(ERROR_INVALID_HANDLE
);
140 Status
= ElfrClearELFA(pLog
->BindingHandle
,
143 if (!NT_SUCCESS(Status
))
145 SetLastError(RtlNtStatusToDosError(Status
));
153 /******************************************************************************
154 * ClearEventLogW [ADVAPI32.@]
157 ClearEventLogW(IN HANDLE hEventLog
,
158 IN LPCWSTR lpBackupFileName
)
162 RPC_UNICODE_STRING BackupFileName
;
164 TRACE("%p, %s\n", hEventLog
, debugstr_w(lpBackupFileName
));
166 BackupFileName
.Buffer
= (LPWSTR
)lpBackupFileName
;
167 BackupFileName
.Length
= BackupFileName
.MaximumLength
=
168 lpBackupFileName
? wcslen(lpBackupFileName
) * sizeof(WCHAR
) : 0;
170 pLog
= (PLOG_INFO
)hEventLog
;
173 SetLastError(ERROR_INVALID_HANDLE
);
177 Status
= ElfrClearELFW(pLog
->BindingHandle
,
180 if (!NT_SUCCESS(Status
))
182 SetLastError(RtlNtStatusToDosError(Status
));
190 /******************************************************************************
191 * CloseEventLog [ADVAPI32.@]
194 CloseEventLog(IN HANDLE hEventLog
)
199 TRACE("%p\n", hEventLog
);
201 pLog
= (PLOG_INFO
)hEventLog
;
205 if (pLog
->bLocal
== FALSE
)
207 if (!EvtUnbindRpc(pLog
->BindingHandle
))
209 SetLastError(ERROR_ACCESS_DENIED
);
215 Status
= ElfrCloseEL(pLog
->BindingHandle
,
217 if (!NT_SUCCESS(Status
))
219 SetLastError(RtlNtStatusToDosError(Status
));
224 HeapFree(GetProcessHeap(), 0, pLog
);
230 /******************************************************************************
231 * DeregisterEventSource [ADVAPI32.@]
232 * Closes a handle to the specified event log
235 * hEventLog [I] Handle to event log
240 DeregisterEventSource(IN HANDLE hEventLog
)
245 TRACE("%p\n", hEventLog
);
247 pLog
= (PLOG_INFO
)hEventLog
;
251 Status
= ElfrDeregisterEventSource(pLog
->BindingHandle
,
253 if (!NT_SUCCESS(Status
))
255 SetLastError(RtlNtStatusToDosError(Status
));
263 /******************************************************************************
264 * GetNumberOfEventLogRecords [ADVAPI32.@]
271 GetNumberOfEventLogRecords(IN HANDLE hEventLog
,
272 OUT PDWORD NumberOfRecords
)
278 TRACE("%p, %p\n", hEventLog
, NumberOfRecords
);
280 pLog
= (PLOG_INFO
)hEventLog
;
283 SetLastError(ERROR_INVALID_HANDLE
);
287 Status
= ElfrNumberOfRecords(pLog
->BindingHandle
,
290 if (!NT_SUCCESS(Status
))
292 SetLastError(RtlNtStatusToDosError(Status
));
296 *NumberOfRecords
= Records
;
302 /******************************************************************************
303 * GetOldestEventLogRecord [ADVAPI32.@]
310 GetOldestEventLogRecord(IN HANDLE hEventLog
,
311 OUT PDWORD OldestRecord
)
317 TRACE("%p, %p\n", hEventLog
, OldestRecord
);
319 pLog
= (PLOG_INFO
)hEventLog
;
322 SetLastError(ERROR_INVALID_HANDLE
);
326 Status
= ElfrOldestRecord(pLog
->BindingHandle
,
329 if (!NT_SUCCESS(Status
))
331 SetLastError(RtlNtStatusToDosError(Status
));
335 *OldestRecord
= Oldest
;
341 /******************************************************************************
342 * NotifyChangeEventLog [ADVAPI32.@]
349 NotifyChangeEventLog(IN HANDLE hEventLog
,
352 /* Use ElfrChangeNotify */
354 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
359 /******************************************************************************
360 * OpenBackupEventLogA [ADVAPI32.@]
363 OpenBackupEventLogA(IN LPCSTR lpUNCServerName
,
364 IN LPCSTR lpFileName
)
366 UNICODE_STRING UNCServerName
;
367 UNICODE_STRING FileName
;
370 TRACE("%s, %s\n", lpUNCServerName
, lpFileName
);
372 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName
, lpUNCServerName
))
374 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
378 if (!RtlCreateUnicodeStringFromAsciiz(&FileName
, lpFileName
))
380 RtlFreeUnicodeString(&UNCServerName
);
381 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
385 Handle
= OpenBackupEventLogW(UNCServerName
.Buffer
,
388 RtlFreeUnicodeString(&UNCServerName
);
389 RtlFreeUnicodeString(&FileName
);
395 /******************************************************************************
396 * OpenBackupEventLogW [ADVAPI32.@]
403 OpenBackupEventLogW(IN LPCWSTR lpUNCServerName
,
404 IN LPCWSTR lpFileName
)
408 RPC_UNICODE_STRING FileName
;
410 TRACE("%s, %s\n", debugstr_w(lpUNCServerName
), debugstr_w(lpFileName
));
412 FileName
.Buffer
= (LPWSTR
)lpFileName
;
413 FileName
.Length
= FileName
.MaximumLength
=
414 lpFileName
? wcslen(lpFileName
) * sizeof(WCHAR
) : 0;
416 pLog
= HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO
));
419 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
423 ZeroMemory(pLog
, sizeof(LOG_INFO
));
425 if (lpUNCServerName
== NULL
|| *lpUNCServerName
== 0)
429 if (!EvtGetLocalHandle(&pLog
->BindingHandle
))
431 HeapFree(GetProcessHeap(), 0, pLog
);
432 SetLastError(ERROR_GEN_FAILURE
);
438 pLog
->bLocal
= FALSE
;
440 if (!EvtBindRpc(lpUNCServerName
, &pLog
->BindingHandle
))
442 HeapFree(GetProcessHeap(), 0, pLog
);
443 SetLastError(ERROR_INVALID_COMPUTERNAME
);
448 Status
= ElfrOpenBELW(pLog
->BindingHandle
,
449 (LPWSTR
)lpUNCServerName
,
454 if (!NT_SUCCESS(Status
))
456 SetLastError(RtlNtStatusToDosError(Status
));
457 HeapFree(GetProcessHeap(), 0, pLog
);
465 /******************************************************************************
466 * OpenEventLogA [ADVAPI32.@]
469 OpenEventLogA(IN LPCSTR lpUNCServerName
,
470 IN LPCSTR lpSourceName
)
472 UNICODE_STRING UNCServerName
;
473 UNICODE_STRING SourceName
;
476 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName
, lpUNCServerName
))
478 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
482 if (!RtlCreateUnicodeStringFromAsciiz(&SourceName
, lpSourceName
))
484 RtlFreeUnicodeString(&UNCServerName
);
485 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
489 Handle
= OpenEventLogW(UNCServerName
.Buffer
,
492 RtlFreeUnicodeString(&UNCServerName
);
493 RtlFreeUnicodeString(&SourceName
);
499 /******************************************************************************
500 * OpenEventLogW [ADVAPI32.@]
507 OpenEventLogW(IN LPCWSTR lpUNCServerName
,
508 IN LPCWSTR lpSourceName
)
512 RPC_UNICODE_STRING SourceName
;
514 TRACE("%s, %s\n", debugstr_w(lpUNCServerName
), debugstr_w(lpSourceName
));
516 SourceName
.Buffer
= (LPWSTR
)lpSourceName
;
517 SourceName
.Length
= SourceName
.MaximumLength
=
518 lpSourceName
? wcslen(lpSourceName
) * sizeof(WCHAR
) : 0;
520 pLog
= HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO
));
523 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
527 ZeroMemory(pLog
, sizeof(LOG_INFO
));
529 if (lpUNCServerName
== NULL
|| *lpUNCServerName
== 0)
533 if (!EvtGetLocalHandle(&pLog
->BindingHandle
))
535 HeapFree(GetProcessHeap(), 0, pLog
);
536 SetLastError(ERROR_GEN_FAILURE
);
542 pLog
->bLocal
= FALSE
;
544 if (!EvtBindRpc(lpUNCServerName
, &pLog
->BindingHandle
))
546 HeapFree(GetProcessHeap(), 0, pLog
);
547 SetLastError(ERROR_INVALID_COMPUTERNAME
);
552 Status
= ElfrOpenELW(pLog
->BindingHandle
,
553 (LPWSTR
)lpUNCServerName
,
559 if (!NT_SUCCESS(Status
))
561 SetLastError(RtlNtStatusToDosError(Status
));
562 HeapFree(GetProcessHeap(), 0, pLog
);
570 /******************************************************************************
571 * ReadEventLogA [ADVAPI32.@]
574 ReadEventLogA(IN HANDLE hEventLog
,
575 IN DWORD dwReadFlags
,
576 IN DWORD dwRecordOffset
,
578 IN DWORD nNumberOfBytesToRead
,
579 OUT DWORD
*pnBytesRead
,
580 OUT DWORD
*pnMinNumberOfBytesNeeded
)
584 DWORD bytesRead
, minNumberOfBytesNeeded
;
586 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
587 hEventLog
, dwReadFlags
, dwRecordOffset
, lpBuffer
,
588 nNumberOfBytesToRead
, pnBytesRead
, pnMinNumberOfBytesNeeded
);
590 pLog
= (PLOG_INFO
)hEventLog
;
593 SetLastError(ERROR_INVALID_HANDLE
);
597 Status
= ElfrReadELA(pLog
->BindingHandle
,
601 nNumberOfBytesToRead
,
604 &minNumberOfBytesNeeded
);
605 if (!NT_SUCCESS(Status
))
607 SetLastError(RtlNtStatusToDosError(Status
));
611 *pnBytesRead
= (DWORD
)bytesRead
;
612 *pnMinNumberOfBytesNeeded
= (DWORD
)minNumberOfBytesNeeded
;
618 /******************************************************************************
619 * ReadEventLogW [ADVAPI32.@]
626 * nNumberOfBytesToRead []
628 * pnMinNumberOfBytesNeeded []
631 ReadEventLogW(IN HANDLE hEventLog
,
632 IN DWORD dwReadFlags
,
633 IN DWORD dwRecordOffset
,
635 IN DWORD nNumberOfBytesToRead
,
636 OUT DWORD
*pnBytesRead
,
637 OUT DWORD
*pnMinNumberOfBytesNeeded
)
641 DWORD bytesRead
, minNumberOfBytesNeeded
;
643 TRACE("%p, %lu, %lu, %p, %lu, %p, %p\n",
644 hEventLog
, dwReadFlags
, dwRecordOffset
, lpBuffer
,
645 nNumberOfBytesToRead
, pnBytesRead
, pnMinNumberOfBytesNeeded
);
647 pLog
= (PLOG_INFO
)hEventLog
;
650 SetLastError(ERROR_INVALID_HANDLE
);
654 Status
= ElfrReadELW(pLog
->BindingHandle
,
658 nNumberOfBytesToRead
,
661 &minNumberOfBytesNeeded
);
662 if (!NT_SUCCESS(Status
))
664 SetLastError(RtlNtStatusToDosError(Status
));
668 *pnBytesRead
= (DWORD
)bytesRead
;
669 *pnMinNumberOfBytesNeeded
= (DWORD
)minNumberOfBytesNeeded
;
675 /******************************************************************************
676 * RegisterEventSourceA [ADVAPI32.@]
679 RegisterEventSourceA(IN LPCSTR lpUNCServerName
,
680 IN LPCSTR lpSourceName
)
682 UNICODE_STRING UNCServerName
;
683 UNICODE_STRING SourceName
;
686 TRACE("%s, %s\n", lpUNCServerName
, lpSourceName
);
688 if (!RtlCreateUnicodeStringFromAsciiz(&UNCServerName
, lpUNCServerName
))
690 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
694 if (!RtlCreateUnicodeStringFromAsciiz(&SourceName
, lpSourceName
))
696 RtlFreeUnicodeString(&UNCServerName
);
697 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
701 Handle
= RegisterEventSourceW(UNCServerName
.Buffer
,
704 RtlFreeUnicodeString(&UNCServerName
);
705 RtlFreeUnicodeString(&SourceName
);
711 /******************************************************************************
712 * RegisterEventSourceW [ADVAPI32.@]
713 * Returns a registered handle to an event log
716 * lpUNCServerName [I] Server name for source
717 * lpSourceName [I] Source name for registered handle
724 RegisterEventSourceW(IN LPCWSTR lpUNCServerName
,
725 IN LPCWSTR lpSourceName
)
729 RPC_UNICODE_STRING SourceName
;
731 TRACE("%s, %s\n", debugstr_w(lpUNCServerName
), debugstr_w(lpSourceName
));
733 SourceName
.Buffer
= (LPWSTR
)lpSourceName
;
734 SourceName
.Length
= SourceName
.MaximumLength
=
735 lpSourceName
? wcslen(lpSourceName
) * sizeof(WCHAR
) : 0;
737 pLog
= HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_INFO
));
740 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
744 ZeroMemory(pLog
, sizeof(LOG_INFO
));
746 if (lpUNCServerName
== NULL
|| *lpUNCServerName
== 0)
750 if (!EvtGetLocalHandle(&pLog
->BindingHandle
))
752 HeapFree(GetProcessHeap(), 0, pLog
);
753 SetLastError(ERROR_GEN_FAILURE
);
759 pLog
->bLocal
= FALSE
;
761 if (!EvtBindRpc(lpUNCServerName
, &pLog
->BindingHandle
))
763 HeapFree(GetProcessHeap(), 0, pLog
);
764 SetLastError(ERROR_INVALID_COMPUTERNAME
);
769 Status
= ElfrRegisterEventSourceW(pLog
->BindingHandle
,
770 (LPWSTR
)lpUNCServerName
,
776 if (!NT_SUCCESS(Status
))
778 SetLastError(RtlNtStatusToDosError(Status
));
779 HeapFree(GetProcessHeap(), 0, pLog
);
787 /******************************************************************************
788 * ReportEventA [ADVAPI32.@]
791 ReportEventA(IN HANDLE hEventLog
,
798 IN LPCSTR
*lpStrings
,
801 LPCWSTR
*wideStrArray
;
806 if (wNumStrings
== 0)
809 if (lpStrings
== NULL
)
812 wideStrArray
= HeapAlloc(GetProcessHeap(),
814 sizeof(LPCWSTR
) * wNumStrings
);
816 for (i
= 0; i
< wNumStrings
; i
++)
818 if (!RtlCreateUnicodeStringFromAsciiz(&str
, (PSTR
)lpStrings
[i
]))
820 wideStrArray
[i
] = str
.Buffer
;
823 if (i
== wNumStrings
)
825 ret
= ReportEventW(hEventLog
,
837 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
841 for (i
= 0; i
< wNumStrings
; i
++)
845 HeapFree(GetProcessHeap(),
847 (PVOID
)wideStrArray
[i
]);
851 HeapFree(GetProcessHeap(),
859 /******************************************************************************
860 * ReportEventW [ADVAPI32.@]
874 ReportEventW(IN HANDLE hEventLog
,
881 IN LPCWSTR
*lpStrings
,
887 UNICODE_STRING
*Strings
;
890 TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
891 hEventLog
, wType
, wCategory
, dwEventID
, lpUserSid
,
892 wNumStrings
, dwDataSize
, lpStrings
, lpRawData
);
894 pLog
= (PLOG_INFO
)hEventLog
;
897 SetLastError(ERROR_INVALID_HANDLE
);
901 Strings
= HeapAlloc(GetProcessHeap(),
903 wNumStrings
* sizeof(UNICODE_STRING
));
906 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
910 for (i
= 0; i
< wNumStrings
; i
++)
911 RtlInitUnicodeString(&Strings
[i
], lpStrings
[i
]);
913 Status
= ElfrReportEventW(pLog
->BindingHandle
,
921 L
"", /* FIXME: ComputerName */
923 (LPWSTR
*)lpStrings
, /* FIXME: should be Strings */
928 HeapFree(GetProcessHeap(), 0, Strings
);
930 if (!NT_SUCCESS(Status
))
932 SetLastError(RtlNtStatusToDosError(Status
));
942 if (wNumStrings
== 0)
945 if (lpStrings
== NULL
)
948 for (i
= 0; i
< wNumStrings
; i
++)
952 case EVENTLOG_SUCCESS
:
953 TRACE_(eventlog
)("Success: %S\n", lpStrings
[i
]);
956 case EVENTLOG_ERROR_TYPE
:
957 ERR_(eventlog
)("Error: %S\n", lpStrings
[i
]);
960 case EVENTLOG_WARNING_TYPE
:
961 WARN_(eventlog
)("Warning: %S\n", lpStrings
[i
]);
964 case EVENTLOG_INFORMATION_TYPE
:
965 TRACE_(eventlog
)("Info: %S\n", lpStrings
[i
]);
969 TRACE_(eventlog
)("Type %hu: %S\n", wType
, lpStrings
[i
]);