/*1* Win32 advapi functions2*3* Copyright 1995 Sven Verdoolaege4* Copyright 1998 Juergen Schmied5* Copyright 2003 Mike Hearn6*7* This library is free software; you can redistribute it and/or8* modify it under the terms of the GNU Lesser General Public9* License as published by the Free Software Foundation; either10* version 2.1 of the License, or (at your option) any later version.11*12* This library is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU15* Lesser General Public License for more details.16*17* You should have received a copy of the GNU Lesser General Public18* License along with this library; if not, write to the Free Software19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA20*/2122#include <stdarg.h>2324#include "windef.h"25#include "winbase.h"26#include "winerror.h"27#include "winternl.h"28#include "wmistr.h"29#define _WMI_SOURCE_30#include "evntrace.h"31#include "evntprov.h"3233#include "wine/debug.h"3435#include "advapi32_misc.h"3637WINE_DEFAULT_DEBUG_CHANNEL(advapi);38WINE_DECLARE_DEBUG_CHANNEL(eventlog);3940/******************************************************************************41* BackupEventLogA [ADVAPI32.@]42*43* Saves the event log to a backup file.44*45* PARAMS46* hEventLog [I] Handle to event log to backup.47* lpBackupFileName [I] Name of the backup file.48*49* RETURNS50* Success: nonzero. File lpBackupFileName will contain the contents of51* hEvenLog.52* Failure: zero.53*/54BOOL WINAPI BackupEventLogA( HANDLE hEventLog, LPCSTR lpBackupFileName )55{56LPWSTR backupW;57BOOL ret;5859backupW = strdupAW(lpBackupFileName);60ret = BackupEventLogW(hEventLog, backupW);61free(backupW);6263return ret;64}6566/******************************************************************************67* BackupEventLogW [ADVAPI32.@]68*69* See BackupEventLogA.70*/71BOOL WINAPI BackupEventLogW( HANDLE hEventLog, LPCWSTR lpBackupFileName )72{73FIXME("(%p,%s) stub\n", hEventLog, debugstr_w(lpBackupFileName));7475if (!lpBackupFileName)76{77SetLastError(ERROR_INVALID_PARAMETER);78return FALSE;79}8081if (!hEventLog)82{83SetLastError(ERROR_INVALID_HANDLE);84return FALSE;85}8687if (GetFileAttributesW(lpBackupFileName) != INVALID_FILE_ATTRIBUTES)88{89SetLastError(ERROR_ALREADY_EXISTS);90return FALSE;91}9293return TRUE;94}9596/******************************************************************************97* ClearEventLogA [ADVAPI32.@]98*99* Clears the event log and optionally saves the log to a backup file.100*101* PARAMS102* hEvenLog [I] Handle to event log to clear.103* lpBackupFileName [I] Name of the backup file.104*105* RETURNS106* Success: nonzero. if lpBackupFileName != NULL, lpBackupFileName will107* contain the contents of hEvenLog and the log will be cleared.108* Failure: zero. Fails if the event log is empty or if lpBackupFileName109* exists.110*/111BOOL WINAPI ClearEventLogA( HANDLE hEventLog, LPCSTR lpBackupFileName )112{113LPWSTR backupW;114BOOL ret;115116backupW = strdupAW(lpBackupFileName);117ret = ClearEventLogW(hEventLog, backupW);118free(backupW);119120return ret;121}122123/******************************************************************************124* ClearEventLogW [ADVAPI32.@]125*126* See ClearEventLogA.127*/128BOOL WINAPI ClearEventLogW( HANDLE hEventLog, LPCWSTR lpBackupFileName )129{130FIXME("(%p,%s) stub\n", hEventLog, debugstr_w(lpBackupFileName));131132if (!hEventLog)133{134SetLastError(ERROR_INVALID_HANDLE);135return FALSE;136}137138return TRUE;139}140141/******************************************************************************142* CloseEventLog [ADVAPI32.@]143*144* Closes a read handle to the event log.145*146* PARAMS147* hEventLog [I/O] Handle of the event log to close.148*149* RETURNS150* Success: nonzero151* Failure: zero152*/153BOOL WINAPI CloseEventLog( HANDLE hEventLog )154{155FIXME("(%p) stub\n", hEventLog);156157if (!hEventLog)158{159SetLastError(ERROR_INVALID_HANDLE);160return FALSE;161}162163return TRUE;164}165166/******************************************************************************167* FlushTraceA [ADVAPI32.@]168*/169ULONG WINAPI FlushTraceA ( TRACEHANDLE hSession, LPCSTR SessionName, PEVENT_TRACE_PROPERTIES Properties )170{171return ControlTraceA( hSession, SessionName, Properties, EVENT_TRACE_CONTROL_FLUSH );172}173174/******************************************************************************175* FlushTraceW [ADVAPI32.@]176*/177ULONG WINAPI FlushTraceW ( TRACEHANDLE hSession, LPCWSTR SessionName, PEVENT_TRACE_PROPERTIES Properties )178{179return ControlTraceW( hSession, SessionName, Properties, EVENT_TRACE_CONTROL_FLUSH );180}181182183/******************************************************************************184* DeregisterEventSource [ADVAPI32.@]185*186* Closes a write handle to an event log187*188* PARAMS189* hEventLog [I/O] Handle of the event log.190*191* RETURNS192* Success: nonzero193* Failure: zero194*/195BOOL WINAPI DeregisterEventSource( HANDLE hEventLog )196{197FIXME("(%p) stub\n", hEventLog);198return TRUE;199}200201/******************************************************************************202* EnableTraceEx [ADVAPI32.@]203*/204ULONG WINAPI EnableTraceEx( LPCGUID provider, LPCGUID source, TRACEHANDLE hSession, ULONG enable,205UCHAR level, ULONGLONG anykeyword, ULONGLONG allkeyword, ULONG enableprop,206PEVENT_FILTER_DESCRIPTOR filterdesc )207{208FIXME("(%s, %s, %s, %lu, %u, %s, %s, %lu, %p): stub\n", debugstr_guid(provider),209debugstr_guid(source), wine_dbgstr_longlong(hSession), enable, level,210wine_dbgstr_longlong(anykeyword), wine_dbgstr_longlong(allkeyword),211enableprop, filterdesc);212213return ERROR_SUCCESS;214}215216/******************************************************************************217* EnableTrace [ADVAPI32.@]218*/219ULONG WINAPI EnableTrace( ULONG enable, ULONG flag, ULONG level, LPCGUID guid, TRACEHANDLE hSession )220{221FIXME("(%ld, 0x%lx, %ld, %s, %s): stub\n", enable, flag, level,222debugstr_guid(guid), wine_dbgstr_longlong(hSession));223224return ERROR_SUCCESS;225}226227/******************************************************************************228* GetEventLogInformation [ADVAPI32.@]229*230* Retrieve some information about an event log.231*232* PARAMS233* hEventLog [I] Handle to an open event log.234* dwInfoLevel [I] Level of information (only EVENTLOG_FULL_INFO)235* lpBuffer [I/O] The buffer for the returned information236* cbBufSize [I] The size of the buffer237* pcbBytesNeeded [O] The needed bytes to hold the information238*239* RETURNS240* Success: TRUE. lpBuffer will hold the information and pcbBytesNeeded shows241* the needed buffer size.242* Failure: FALSE.243*/244BOOL WINAPI GetEventLogInformation( HANDLE hEventLog, DWORD dwInfoLevel, LPVOID lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)245{246EVENTLOG_FULL_INFORMATION *efi;247248FIXME("(%p, %ld, %p, %ld, %p) stub\n", hEventLog, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);249250if (dwInfoLevel != EVENTLOG_FULL_INFO)251{252SetLastError(ERROR_INVALID_LEVEL);253return FALSE;254}255256if (!hEventLog)257{258SetLastError(ERROR_INVALID_HANDLE);259return FALSE;260}261262if (!lpBuffer || !pcbBytesNeeded)263{264/* FIXME: This will be handled properly when eventlog is moved265* to a higher level266*/267SetLastError(RPC_X_NULL_REF_POINTER);268return FALSE;269}270271*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);272if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))273{274SetLastError(ERROR_INSUFFICIENT_BUFFER);275return FALSE;276}277278/* Pretend the log is not full */279efi = (EVENTLOG_FULL_INFORMATION *)lpBuffer;280efi->dwFull = 0;281282return TRUE;283}284285/******************************************************************************286* GetNumberOfEventLogRecords [ADVAPI32.@]287*288* Retrieves the number of records in an event log.289*290* PARAMS291* hEventLog [I] Handle to an open event log.292* NumberOfRecords [O] Number of records in the log.293*294* RETURNS295* Success: nonzero. NumberOfRecords will contain the number of records in296* the log.297* Failure: zero298*/299BOOL WINAPI GetNumberOfEventLogRecords( HANDLE hEventLog, PDWORD NumberOfRecords )300{301FIXME("(%p,%p) stub\n", hEventLog, NumberOfRecords);302303if (!NumberOfRecords)304{305SetLastError(ERROR_INVALID_PARAMETER);306return FALSE;307}308309if (!hEventLog)310{311SetLastError(ERROR_INVALID_HANDLE);312return FALSE;313}314315*NumberOfRecords = 0;316317return TRUE;318}319320/******************************************************************************321* GetOldestEventLogRecord [ADVAPI32.@]322*323* Retrieves the absolute record number of the oldest record in an even log.324*325* PARAMS326* hEventLog [I] Handle to an open event log.327* OldestRecord [O] Absolute record number of the oldest record.328*329* RETURNS330* Success: nonzero. OldestRecord contains the record number of the oldest331* record in the log.332* Failure: zero333*/334BOOL WINAPI GetOldestEventLogRecord( HANDLE hEventLog, PDWORD OldestRecord )335{336FIXME("(%p,%p) stub\n", hEventLog, OldestRecord);337338if (!OldestRecord)339{340SetLastError(ERROR_INVALID_PARAMETER);341return FALSE;342}343344if (!hEventLog)345{346SetLastError(ERROR_INVALID_HANDLE);347return FALSE;348}349350*OldestRecord = 0;351352return TRUE;353}354355/******************************************************************************356* NotifyChangeEventLog [ADVAPI32.@]357*358* Enables an application to receive notification when an event is written359* to an event log.360*361* PARAMS362* hEventLog [I] Handle to an event log.363* hEvent [I] Handle to a manual-reset event object.364*365* RETURNS366* Success: nonzero367* Failure: zero368*/369BOOL WINAPI NotifyChangeEventLog( HANDLE hEventLog, HANDLE hEvent )370{371FIXME("(%p,%p) stub\n", hEventLog, hEvent);372return TRUE;373}374375/******************************************************************************376* OpenBackupEventLogA [ADVAPI32.@]377*378* Opens a handle to a backup event log.379*380* PARAMS381* lpUNCServerName [I] Universal Naming Convention name of the server on which382* this will be performed.383* lpFileName [I] Specifies the name of the backup file.384*385* RETURNS386* Success: Handle to the backup event log.387* Failure: NULL388*/389HANDLE WINAPI OpenBackupEventLogA( LPCSTR lpUNCServerName, LPCSTR lpFileName )390{391LPWSTR uncnameW, filenameW;392HANDLE handle;393394uncnameW = strdupAW(lpUNCServerName);395filenameW = strdupAW(lpFileName);396handle = OpenBackupEventLogW(uncnameW, filenameW);397free(uncnameW);398free(filenameW);399400return handle;401}402403/******************************************************************************404* OpenBackupEventLogW [ADVAPI32.@]405*406* See OpenBackupEventLogA.407*/408HANDLE WINAPI OpenBackupEventLogW( LPCWSTR lpUNCServerName, LPCWSTR lpFileName )409{410FIXME("(%s,%s) stub\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));411412if (!lpFileName)413{414SetLastError(ERROR_INVALID_PARAMETER);415return NULL;416}417418if (lpUNCServerName && lpUNCServerName[0])419{420FIXME("Remote server not supported\n");421SetLastError(RPC_S_SERVER_UNAVAILABLE);422return NULL;423}424425if (GetFileAttributesW(lpFileName) == INVALID_FILE_ATTRIBUTES)426{427SetLastError(ERROR_FILE_NOT_FOUND);428return NULL;429}430431return (HANDLE)0xcafe4242;432}433434/******************************************************************************435* OpenEventLogA [ADVAPI32.@]436*437* Opens a handle to the specified event log.438*439* PARAMS440* lpUNCServerName [I] UNC name of the server on which the event log is441* opened.442* lpSourceName [I] Name of the log.443*444* RETURNS445* Success: Handle to an event log.446* Failure: NULL447*/448HANDLE WINAPI OpenEventLogA( LPCSTR uncname, LPCSTR source )449{450LPWSTR uncnameW, sourceW;451HANDLE handle;452453uncnameW = strdupAW(uncname);454sourceW = strdupAW(source);455handle = OpenEventLogW(uncnameW, sourceW);456free(uncnameW);457free(sourceW);458459return handle;460}461462/******************************************************************************463* OpenEventLogW [ADVAPI32.@]464*465* See OpenEventLogA.466*/467HANDLE WINAPI OpenEventLogW( LPCWSTR uncname, LPCWSTR source )468{469FIXME("(%s,%s) stub\n", debugstr_w(uncname), debugstr_w(source));470471if (!source)472{473SetLastError(ERROR_INVALID_PARAMETER);474return NULL;475}476477if (uncname && uncname[0])478{479FIXME("Remote server not supported\n");480SetLastError(RPC_S_SERVER_UNAVAILABLE);481return NULL;482}483484return (HANDLE)0xcafe4242;485}486487/******************************************************************************488* ReadEventLogA [ADVAPI32.@]489*490* Reads a whole number of entries from an event log.491*492* PARAMS493* hEventLog [I] Handle of the event log to read.494* dwReadFlags [I] see MSDN doc.495* dwRecordOffset [I] Log-entry record number to start at.496* lpBuffer [O] Buffer for the data read.497* nNumberOfBytesToRead [I] Size of lpBuffer.498* pnBytesRead [O] Receives number of bytes read.499* pnMinNumberOfBytesNeeded [O] Receives number of bytes required for the500* next log entry.501*502* RETURNS503* Success: nonzero504* Failure: zero505*/506BOOL WINAPI ReadEventLogA( HANDLE hEventLog, DWORD dwReadFlags, DWORD dwRecordOffset,507LPVOID lpBuffer, DWORD nNumberOfBytesToRead, DWORD *pnBytesRead, DWORD *pnMinNumberOfBytesNeeded )508{509FIXME("(%p,0x%08lx,0x%08lx,%p,0x%08lx,%p,%p) stub\n", hEventLog, dwReadFlags,510dwRecordOffset, lpBuffer, nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);511512SetLastError(ERROR_HANDLE_EOF);513return FALSE;514}515516/******************************************************************************517* ReadEventLogW [ADVAPI32.@]518*519* See ReadEventLogA.520*/521BOOL WINAPI ReadEventLogW( HANDLE hEventLog, DWORD dwReadFlags, DWORD dwRecordOffset,522LPVOID lpBuffer, DWORD nNumberOfBytesToRead, DWORD *pnBytesRead, DWORD *pnMinNumberOfBytesNeeded )523{524FIXME("(%p,0x%08lx,0x%08lx,%p,0x%08lx,%p,%p) stub\n", hEventLog, dwReadFlags,525dwRecordOffset, lpBuffer, nNumberOfBytesToRead, pnBytesRead, pnMinNumberOfBytesNeeded);526527SetLastError(ERROR_HANDLE_EOF);528return FALSE;529}530531/******************************************************************************532* RegisterEventSourceA [ADVAPI32.@]533*534* Returns a registered handle to an event log.535*536* PARAMS537* lpUNCServerName [I] UNC name of the source server.538* lpSourceName [I] Specifies the name of the event source to retrieve.539*540* RETURNS541* Success: Handle to the event log.542* Failure: NULL. Returns ERROR_INVALID_HANDLE if lpSourceName specifies the543* Security event log.544*/545HANDLE WINAPI RegisterEventSourceA( LPCSTR lpUNCServerName, LPCSTR lpSourceName )546{547UNICODE_STRING lpUNCServerNameW;548UNICODE_STRING lpSourceNameW;549HANDLE ret;550551FIXME("(%s,%s): stub\n", debugstr_a(lpUNCServerName), debugstr_a(lpSourceName));552553RtlCreateUnicodeStringFromAsciiz(&lpUNCServerNameW, lpUNCServerName);554RtlCreateUnicodeStringFromAsciiz(&lpSourceNameW, lpSourceName);555ret = RegisterEventSourceW(lpUNCServerNameW.Buffer,lpSourceNameW.Buffer);556RtlFreeUnicodeString (&lpUNCServerNameW);557RtlFreeUnicodeString (&lpSourceNameW);558return ret;559}560561/******************************************************************************562* RegisterEventSourceW [ADVAPI32.@]563*564* See RegisterEventSourceA.565*/566HANDLE WINAPI RegisterEventSourceW( LPCWSTR lpUNCServerName, LPCWSTR lpSourceName )567{568FIXME("(%s,%s): stub\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));569return (HANDLE)0xcafe4242;570}571572/******************************************************************************573* ReportEventA [ADVAPI32.@]574*575* Writes an entry at the end of an event log.576*577* PARAMS578* hEventLog [I] Handle of an event log.579* wType [I] See MSDN doc.580* wCategory [I] Event category.581* dwEventID [I] Event identifier.582* lpUserSid [I] Current user's security identifier.583* wNumStrings [I] Number of insert strings in lpStrings.584* dwDataSize [I] Size of event-specific raw data to write.585* lpStrings [I] Buffer containing an array of string to be merged.586* lpRawData [I] Buffer containing the binary data.587*588* RETURNS589* Success: nonzero. Entry was written to the log.590* Failure: zero.591*592* NOTES593* The ReportEvent function adds the time, the entry's length, and the594* offsets before storing the entry in the log. If lpUserSid != NULL, the595* username is also logged.596*/597BOOL WINAPI ReportEventA ( HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID,598PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, LPCSTR *lpStrings, LPVOID lpRawData)599{600LPWSTR *wideStrArray;601UNICODE_STRING str;602UINT i;603BOOL ret;604605FIXME("(%p,0x%04x,0x%04x,0x%08lx,%p,0x%04x,0x%08lx,%p,%p): stub\n", hEventLog,606wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);607608if (wNumStrings == 0) return TRUE;609if (!lpStrings) return TRUE;610611wideStrArray = malloc(sizeof(WCHAR *) * wNumStrings);612for (i = 0; i < wNumStrings; i++)613{614RtlCreateUnicodeStringFromAsciiz(&str, lpStrings[i]);615wideStrArray[i] = str.Buffer;616}617ret = ReportEventW(hEventLog, wType, wCategory, dwEventID, lpUserSid,618wNumStrings, dwDataSize, (LPCWSTR *)wideStrArray, lpRawData);619for (i = 0; i < wNumStrings; i++)620free(wideStrArray[i]);621free(wideStrArray);622return ret;623}624625/******************************************************************************626* ReportEventW [ADVAPI32.@]627*628* See ReportEventA.629*/630BOOL WINAPI ReportEventW( HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dwEventID,631PSID lpUserSid, WORD wNumStrings, DWORD dwDataSize, LPCWSTR *lpStrings, LPVOID lpRawData )632{633UINT i;634635FIXME("(%p,0x%04x,0x%04x,0x%08lx,%p,0x%04x,0x%08lx,%p,%p): stub\n", hEventLog,636wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);637638/* partial stub */639640if (wNumStrings == 0) return TRUE;641if (!lpStrings) return TRUE;642643for (i = 0; i < wNumStrings; i++)644{645const WCHAR *line = lpStrings[i];646647while (*line)648{649const WCHAR *next = wcschr( line, '\n' );650651if (next)652++next;653else654next = line + wcslen( line );655656switch (wType)657{658case EVENTLOG_SUCCESS:659TRACE_(eventlog)("%s\n", debugstr_wn(line, next - line));660break;661case EVENTLOG_ERROR_TYPE:662ERR_(eventlog)("%s\n", debugstr_wn(line, next - line));663break;664case EVENTLOG_WARNING_TYPE:665WARN_(eventlog)("%s\n", debugstr_wn(line, next - line));666break;667default:668TRACE_(eventlog)("%s\n", debugstr_wn(line, next - line));669break;670}671672line = next;673}674}675return TRUE;676}677678/******************************************************************************679* StopTraceA [ADVAPI32.@]680*681* See StopTraceW.682*683*/684ULONG WINAPI StopTraceA( TRACEHANDLE session, LPCSTR session_name, PEVENT_TRACE_PROPERTIES properties )685{686FIXME("(%s, %s, %p) stub\n", wine_dbgstr_longlong(session), debugstr_a(session_name), properties);687return ERROR_SUCCESS;688}689690/******************************************************************************691* QueryTraceA [ADVAPI32.@]692*/693ULONG WINAPI QueryTraceA( TRACEHANDLE handle, LPCSTR sessionname, PEVENT_TRACE_PROPERTIES properties )694{695FIXME("%s %s %p: stub\n", wine_dbgstr_longlong(handle), debugstr_a(sessionname), properties);696return ERROR_WMI_INSTANCE_NOT_FOUND;697}698699/******************************************************************************700* QueryTraceW [ADVAPI32.@]701*/702ULONG WINAPI QueryTraceW( TRACEHANDLE handle, LPCWSTR sessionname, PEVENT_TRACE_PROPERTIES properties )703{704FIXME("%s %s %p: stub\n", wine_dbgstr_longlong(handle), debugstr_w(sessionname), properties);705return ERROR_CALL_NOT_IMPLEMENTED;706}707708/******************************************************************************709* OpenTraceA [ADVAPI32.@]710*/711TRACEHANDLE WINAPI OpenTraceA( PEVENT_TRACE_LOGFILEA logfile )712{713static int once;714715if (!once++) FIXME("%p: stub\n", logfile);716SetLastError(ERROR_ACCESS_DENIED);717return INVALID_PROCESSTRACE_HANDLE;718}719720/******************************************************************************721* EnumerateTraceGuids [ADVAPI32.@]722*/723ULONG WINAPI EnumerateTraceGuids(PTRACE_GUID_PROPERTIES *propertiesarray,724ULONG arraycount, PULONG guidcount)725{726FIXME("%p %ld %p: stub\n", propertiesarray, arraycount, guidcount);727return ERROR_INVALID_PARAMETER;728}729730731