Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277/* * PROJECT: ReactOS EventLog Service * LICENSE: GPL - See COPYING in the top level directory * FILE: base/services/eventlog/rpc.c * PURPOSE: RPC Port Interface support * COPYRIGHT: Copyright 2005 Saveliy Tretiakov * Copyright 2008 Michael Martin * Copyright 2010-2011 Eric Kohl */
/* INCLUDES *****************************************************************/
#include "eventlog.h"
#define NDEBUG#include <debug.h>
static LIST_ENTRY LogHandleListHead;static CRITICAL_SECTION LogHandleListCs;
/* FUNCTIONS ****************************************************************/
static NTSTATUSElfDeleteEventLogHandle(PIELF_HANDLE LogHandle);
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter){ RPC_STATUS Status;
InitializeCriticalSection(&LogHandleListCs); InitializeListHead(&LogHandleListHead);
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL); if (Status != RPC_S_OK) { DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status); goto Quit; }
Status = RpcServerRegisterIf(eventlog_v0_0_s_ifspec, NULL, NULL); if (Status != RPC_S_OK) { DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status); goto Quit; }
Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE); if (Status != RPC_S_OK) { DPRINT("RpcServerListen() failed (Status %lx)\n", Status); }
EnterCriticalSection(&LogHandleListCs); while (!IsListEmpty(&LogHandleListHead)) { IELF_HANDLE LogHandle = (IELF_HANDLE)CONTAINING_RECORD(LogHandleListHead.Flink, LOGHANDLE, LogHandleListEntry); ElfDeleteEventLogHandle(&LogHandle); } LeaveCriticalSection(&LogHandleListCs);
Quit: DeleteCriticalSection(&LogHandleListCs);
return 0;}
static NTSTATUSElfCreateEventLogHandle(PLOGHANDLE* LogHandle, PUNICODE_STRING LogName, BOOLEAN Create){ NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE pLogHandle; PLOGFILE currentLogFile = NULL; DWORD i, LogsActive; PEVENTSOURCE pEventSource;
DPRINT("ElfCreateEventLogHandle(%wZ)\n", LogName);
*LogHandle = NULL;
i = (LogName->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR); pLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(LOGHANDLE, szName[i])); if (!pLogHandle) { DPRINT1("Failed to allocate Heap!\n"); return STATUS_NO_MEMORY; }
StringCchCopyW(pLogHandle->szName, i, LogName->Buffer);
/* Get the number of Log Files the EventLog service found */ // NOTE: We could just as well loop only once within the list of logs // and retrieve what the code below that calls LogfListItemByIndex, does!! LogsActive = LogfListItemCount(); if (LogsActive == 0) { DPRINT1("EventLog service reports no log files!\n"); Status = STATUS_UNSUCCESSFUL; goto Done; }
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */ if (Create) { pEventSource = GetEventSourceByName(LogName->Buffer); DPRINT("EventSource: %p\n", pEventSource); if (pEventSource) { DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile); pLogHandle->LogFile = pEventSource->LogFile; } else { DPRINT("EventSource LogFile: Application log file\n"); pLogHandle->LogFile = LogfListItemByName(L"Application"); }
DPRINT("LogHandle LogFile: %p\n", pLogHandle->LogFile); } else { pLogHandle->LogFile = NULL;
for (i = 1; i <= LogsActive; i++) { currentLogFile = LogfListItemByIndex(i);
if (_wcsicmp(LogName->Buffer, currentLogFile->LogName) == 0) { pLogHandle->LogFile = currentLogFile; break; } }
/* Use the application log if the desired log does not exist */ if (pLogHandle->LogFile == NULL) { pLogHandle->LogFile = LogfListItemByName(L"Application"); if (pLogHandle->LogFile == NULL) { DPRINT1("Application log is missing!\n"); Status = STATUS_UNSUCCESSFUL; goto Done; } }
/* Reset the current record */ pLogHandle->CurrentRecord = 0; }
if (!pLogHandle->LogFile) Status = STATUS_UNSUCCESSFUL;
Done: if (NT_SUCCESS(Status)) { /* Append log handle */ EnterCriticalSection(&LogHandleListCs); InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry); LeaveCriticalSection(&LogHandleListCs); *LogHandle = pLogHandle; } else { HeapFree(GetProcessHeap(), 0, pLogHandle); }
return Status;}
static NTSTATUSElfCreateBackupLogHandle(PLOGHANDLE* LogHandle, PUNICODE_STRING FileName){ NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE pLogHandle;
DPRINT("ElfCreateBackupLogHandle(%wZ)\n", FileName);
*LogHandle = NULL;
pLogHandle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGHANDLE)); if (pLogHandle == NULL) { DPRINT1("Failed to allocate Heap!\n"); return STATUS_NO_MEMORY; }
/* Create the log file */ Status = LogfCreate(&pLogHandle->LogFile, NULL, FileName, 0, 0, FALSE, TRUE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create the log file! (Status 0x%08lx)\n", Status); goto Done; }
/* Set the backup flag */ pLogHandle->Flags |= LOG_HANDLE_BACKUP_FILE;
/* Reset the current record */ pLogHandle->CurrentRecord = 0;
Done: if (NT_SUCCESS(Status)) { /* Append log handle */ EnterCriticalSection(&LogHandleListCs); InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry); LeaveCriticalSection(&LogHandleListCs); *LogHandle = pLogHandle; } else { HeapFree(GetProcessHeap(), 0, pLogHandle); }
return Status;}
static PLOGHANDLEElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle){ PLIST_ENTRY CurrentEntry; PLOGHANDLE Handle, pLogHandle = NULL;
EnterCriticalSection(&LogHandleListCs);
CurrentEntry = LogHandleListHead.Flink; while (CurrentEntry != &LogHandleListHead) { Handle = CONTAINING_RECORD(CurrentEntry, LOGHANDLE, LogHandleListEntry); CurrentEntry = CurrentEntry->Flink;
if (Handle == EventLogHandle) { pLogHandle = Handle; break; } }
LeaveCriticalSection(&LogHandleListCs);
return pLogHandle;}
static NTSTATUSElfDeleteEventLogHandle(PIELF_HANDLE LogHandle){ PLOGHANDLE pLogHandle;
pLogHandle = ElfGetLogHandleEntryByHandle(*LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
EnterCriticalSection(&LogHandleListCs); RemoveEntryList(&pLogHandle->LogHandleListEntry); LeaveCriticalSection(&LogHandleListCs);
LogfClose(pLogHandle->LogFile, FALSE);
HeapFree(GetProcessHeap(), 0, pLogHandle);
*LogHandle = NULL;
return STATUS_SUCCESS;}
/* Function 0 */NTSTATUSWINAPIElfrClearELFW( IELF_HANDLE LogHandle, PRPC_UNICODE_STRING BackupFileName){ PLOGHANDLE pLogHandle;
DPRINT("ElfrClearELFW()\n");
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
/* Fail, if the log file is a backup file */ if (pLogHandle->Flags & LOG_HANDLE_BACKUP_FILE) return STATUS_INVALID_HANDLE;
return LogfClearFile(pLogHandle->LogFile, (PUNICODE_STRING)BackupFileName);}
/* Function 1 */NTSTATUSWINAPIElfrBackupELFW( IELF_HANDLE LogHandle, PRPC_UNICODE_STRING BackupFileName){ PLOGHANDLE pLogHandle;
DPRINT("ElfrBackupELFW()\n");
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
return LogfBackupFile(pLogHandle->LogFile, (PUNICODE_STRING)BackupFileName);}
/* Function 2 */NTSTATUSWINAPIElfrCloseEL( PIELF_HANDLE LogHandle){ return ElfDeleteEventLogHandle(LogHandle);}
/* Function 3 */NTSTATUSWINAPIElfrDeregisterEventSource( PIELF_HANDLE LogHandle){ return ElfDeleteEventLogHandle(LogHandle);}
/* Function 4 */NTSTATUSWINAPIElfrNumberOfRecords( IELF_HANDLE LogHandle, PULONG NumberOfRecords){ PLOGHANDLE pLogHandle; PLOGFILE pLogFile; ULONG OldestRecordNumber, CurrentRecordNumber;
DPRINT("ElfrNumberOfRecords()\n");
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
if (!NumberOfRecords) return STATUS_INVALID_PARAMETER;
pLogFile = pLogHandle->LogFile;
/* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile); CurrentRecordNumber = ElfGetCurrentRecord(&pLogFile->LogFile);
/* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock);
DPRINT("Oldest: %lu Current: %lu\n", OldestRecordNumber, CurrentRecordNumber);
if (OldestRecordNumber == 0) { /* OldestRecordNumber == 0 when the log is empty */ *NumberOfRecords = 0; } else { /* The log contains events */ *NumberOfRecords = CurrentRecordNumber - OldestRecordNumber; }
return STATUS_SUCCESS;}
/* Function 5 */NTSTATUSWINAPIElfrOldestRecord( IELF_HANDLE LogHandle, PULONG OldestRecordNumber){ PLOGHANDLE pLogHandle; PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
if (!OldestRecordNumber) return STATUS_INVALID_PARAMETER;
pLogFile = pLogHandle->LogFile;
/* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
*OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile);
/* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock);
return STATUS_SUCCESS;}
/* Function 6 */NTSTATUSWINAPIElfrChangeNotify( IELF_HANDLE LogHandle, RPC_CLIENT_ID ClientId, ULONG Event){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* Function 7 */NTSTATUSWINAPIElfrOpenELW( EVENTLOG_HANDLE_W UNCServerName, PRPC_UNICODE_STRING ModuleName, PRPC_UNICODE_STRING RegModuleName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ if ((MajorVersion != 1) || (MinorVersion != 1)) return STATUS_INVALID_PARAMETER;
/* RegModuleName must be an empty string */ if (RegModuleName->Length > 0) return STATUS_INVALID_PARAMETER;
/* FIXME: UNCServerName must specify the server */
/* FIXME: Must verify that caller has read access */
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle, (PUNICODE_STRING)ModuleName, FALSE);}
/* Function 8 */NTSTATUSWINAPIElfrRegisterEventSourceW( EVENTLOG_HANDLE_W UNCServerName, PRPC_UNICODE_STRING ModuleName, PRPC_UNICODE_STRING RegModuleName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ DPRINT("ElfrRegisterEventSourceW()\n");
if ((MajorVersion != 1) || (MinorVersion != 1)) return STATUS_INVALID_PARAMETER;
/* RegModuleName must be an empty string */ if (RegModuleName->Length > 0) return STATUS_INVALID_PARAMETER;
DPRINT("ModuleName: %wZ\n", ModuleName);
/* FIXME: UNCServerName must specify the server or empty for local */
/* FIXME: Must verify that caller has write access */
return ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle, (PUNICODE_STRING)ModuleName, TRUE);}
/* Function 9 */NTSTATUSWINAPIElfrOpenBELW( EVENTLOG_HANDLE_W UNCServerName, PRPC_UNICODE_STRING BackupFileName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ DPRINT("ElfrOpenBELW(%wZ)\n", BackupFileName);
if ((MajorVersion != 1) || (MinorVersion != 1)) return STATUS_INVALID_PARAMETER;
/* FIXME: UNCServerName must specify the server */
/* FIXME: Must verify that caller has read access */
return ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle, (PUNICODE_STRING)BackupFileName);}
/* Function 10 */NTSTATUSWINAPIElfrReadELW( IELF_HANDLE LogHandle, ULONG ReadFlags, ULONG RecordOffset, RULONG NumberOfBytesToRead, PBYTE Buffer, PULONG NumberOfBytesRead, PULONG MinNumberOfBytesNeeded){ NTSTATUS Status; PLOGHANDLE pLogHandle; ULONG RecordNumber;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
if (!Buffer) return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */ if (ReadFlags & EVENTLOG_SEQUENTIAL_READ) { RecordNumber = pLogHandle->CurrentRecord; } else // (ReadFlags & EVENTLOG_SEEK_READ) { RecordNumber = RecordOffset; }
Status = LogfReadEvents(pLogHandle->LogFile, ReadFlags, &RecordNumber, NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded, FALSE);
/* Update the handle's CurrentRecord if success */ if (NT_SUCCESS(Status)) { pLogHandle->CurrentRecord = RecordNumber; }
return Status;}
/* Helper function for ElfrReportEventW/A and ElfrReportEventAndSourceW */NTSTATUSElfrIntReportEventW( IELF_HANDLE LogHandle, ULONG Time, USHORT EventType, USHORT EventCategory, ULONG EventID, PRPC_UNICODE_STRING SourceName OPTIONAL, USHORT NumStrings, ULONG DataSize, PRPC_UNICODE_STRING ComputerName, PRPC_SID UserSID, PRPC_UNICODE_STRING Strings[], PBYTE Data, USHORT Flags, PULONG RecordNumber, PULONG TimeWritten){ NTSTATUS Status; PLOGHANDLE pLogHandle; UNICODE_STRING LocalSourceName, LocalComputerName; PEVENTLOGRECORD LogBuffer; USHORT i; SIZE_T RecSize; ULONG dwStringsSize = 0; ULONG dwUserSidLength = 0; PWSTR lpStrings, str;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
/* Flags must be 0 */ if (Flags) return STATUS_INVALID_PARAMETER;
for (i = 0; i < NumStrings; i++) { switch (EventType) { case EVENTLOG_SUCCESS: DPRINT("Success: %wZ\n", Strings[i]); break;
case EVENTLOG_ERROR_TYPE: DPRINT("Error: %wZ\n", Strings[i]); break;
case EVENTLOG_WARNING_TYPE: DPRINT("Warning: %wZ\n", Strings[i]); break;
case EVENTLOG_INFORMATION_TYPE: DPRINT("Info: %wZ\n", Strings[i]); break;
case EVENTLOG_AUDIT_SUCCESS: DPRINT("Audit Success: %wZ\n", Strings[i]); break;
case EVENTLOG_AUDIT_FAILURE: DPRINT("Audit Failure: %wZ\n", Strings[i]); break;
default: DPRINT1("Type %hu: %wZ\n", EventType, Strings[i]); break; } dwStringsSize += Strings[i]->Length + sizeof(UNICODE_NULL); }
lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize); if (!lpStrings) { DPRINT1("Failed to allocate heap\n"); return STATUS_NO_MEMORY; }
str = lpStrings; for (i = 0; i < NumStrings; i++) { RtlCopyMemory(str, Strings[i]->Buffer, Strings[i]->Length); str += Strings[i]->Length / sizeof(WCHAR); *str = UNICODE_NULL; str++; }
if (UserSID) dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
if (SourceName && SourceName->Buffer) LocalSourceName = *(PUNICODE_STRING)SourceName; else RtlInitUnicodeString(&LocalSourceName, pLogHandle->szName);
LocalComputerName = *(PUNICODE_STRING)ComputerName;
LogBuffer = LogfAllocAndBuildNewRecord(&RecSize, Time, EventType, EventCategory, EventID, &LocalSourceName, &LocalComputerName, dwUserSidLength, UserSID, NumStrings, lpStrings, DataSize, Data); if (LogBuffer == NULL) { DPRINT1("LogfAllocAndBuildNewRecord failed!\n"); HeapFree(GetProcessHeap(), 0, lpStrings); return STATUS_NO_MEMORY; }
Status = LogfWriteRecord(pLogHandle->LogFile, LogBuffer, RecSize); if (!NT_SUCCESS(Status)) { DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n", pLogHandle->LogFile->LogName, Status); }
if (NT_SUCCESS(Status)) { /* Retrieve the two fields that were set by LogfWriteRecord into the record */ if (RecordNumber) *RecordNumber = LogBuffer->RecordNumber; if (TimeWritten) *TimeWritten = LogBuffer->TimeWritten; }
LogfFreeRecord(LogBuffer);
HeapFree(GetProcessHeap(), 0, lpStrings);
return Status;}
/* Function 11 */NTSTATUSWINAPIElfrReportEventW( IELF_HANDLE LogHandle, ULONG Time, USHORT EventType, USHORT EventCategory, ULONG EventID, USHORT NumStrings, ULONG DataSize, PRPC_UNICODE_STRING ComputerName, PRPC_SID UserSID, PRPC_UNICODE_STRING Strings[], PBYTE Data, USHORT Flags, PULONG RecordNumber, PULONG TimeWritten){ /* Call the helper function. The event source is provided via the log handle. */ return ElfrIntReportEventW(LogHandle, Time, EventType, EventCategory, EventID, NULL, NumStrings, DataSize, ComputerName, UserSID, Strings, Data, Flags, RecordNumber, TimeWritten);}
/* Function 12 */NTSTATUSWINAPIElfrClearELFA( IELF_HANDLE LogHandle, PRPC_STRING BackupFileName){ NTSTATUS Status; UNICODE_STRING BackupFileNameW;
Status = RtlAnsiStringToUnicodeString(&BackupFileNameW, (PANSI_STRING)BackupFileName, TRUE); if (!NT_SUCCESS(Status)) return Status;
Status = ElfrClearELFW(LogHandle, (PRPC_UNICODE_STRING)&BackupFileNameW);
RtlFreeUnicodeString(&BackupFileNameW);
return Status;}
/* Function 13 */NTSTATUSWINAPIElfrBackupELFA( IELF_HANDLE LogHandle, PRPC_STRING BackupFileName){ NTSTATUS Status; UNICODE_STRING BackupFileNameW;
Status = RtlAnsiStringToUnicodeString(&BackupFileNameW, (PANSI_STRING)BackupFileName, TRUE); if (!NT_SUCCESS(Status)) return Status;
Status = ElfrBackupELFW(LogHandle, (PRPC_UNICODE_STRING)&BackupFileNameW);
RtlFreeUnicodeString(&BackupFileNameW);
return Status;}
/* Function 14 */NTSTATUSWINAPIElfrOpenELA( EVENTLOG_HANDLE_A UNCServerName, PRPC_STRING ModuleName, PRPC_STRING RegModuleName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ NTSTATUS Status; UNICODE_STRING ModuleNameW;
if ((MajorVersion != 1) || (MinorVersion != 1)) return STATUS_INVALID_PARAMETER;
/* RegModuleName must be an empty string */ if (RegModuleName->Length > 0) return STATUS_INVALID_PARAMETER;
Status = RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE); if (!NT_SUCCESS(Status)) return Status;
/* FIXME: Must verify that caller has read access */
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle, &ModuleNameW, FALSE);
RtlFreeUnicodeString(&ModuleNameW);
return Status;}
/* Function 15 */NTSTATUSWINAPIElfrRegisterEventSourceA( EVENTLOG_HANDLE_A UNCServerName, PRPC_STRING ModuleName, PRPC_STRING RegModuleName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ NTSTATUS Status; UNICODE_STRING ModuleNameW;
Status = RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status); return Status; }
/* RegModuleName must be an empty string */ if (RegModuleName->Length > 0) { RtlFreeUnicodeString(&ModuleNameW); return STATUS_INVALID_PARAMETER; }
if ((MajorVersion != 1) || (MinorVersion != 1)) { RtlFreeUnicodeString(&ModuleNameW); return STATUS_INVALID_PARAMETER; }
/* FIXME: Must verify that caller has write access */
Status = ElfCreateEventLogHandle((PLOGHANDLE*)LogHandle, &ModuleNameW, TRUE);
RtlFreeUnicodeString(&ModuleNameW);
return Status;}
/* Function 16 */NTSTATUSWINAPIElfrOpenBELA( EVENTLOG_HANDLE_A UNCServerName, PRPC_STRING BackupFileName, ULONG MajorVersion, ULONG MinorVersion, PIELF_HANDLE LogHandle){ NTSTATUS Status; UNICODE_STRING BackupFileNameW;
DPRINT("ElfrOpenBELA(%Z)\n", BackupFileName);
Status = RtlAnsiStringToUnicodeString(&BackupFileNameW, (PANSI_STRING)BackupFileName, TRUE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status); return Status; }
if ((MajorVersion != 1) || (MinorVersion != 1)) { RtlFreeUnicodeString(&BackupFileNameW); return STATUS_INVALID_PARAMETER; }
/* FIXME: UNCServerName must specify the server */
/* FIXME: Must verify that caller has read access */
Status = ElfCreateBackupLogHandle((PLOGHANDLE*)LogHandle, &BackupFileNameW);
RtlFreeUnicodeString(&BackupFileNameW);
return Status;}
/* Function 17 */NTSTATUSWINAPIElfrReadELA( IELF_HANDLE LogHandle, ULONG ReadFlags, ULONG RecordOffset, RULONG NumberOfBytesToRead, PBYTE Buffer, PULONG NumberOfBytesRead, PULONG MinNumberOfBytesNeeded){ NTSTATUS Status; PLOGHANDLE pLogHandle; ULONG RecordNumber;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
if (!Buffer) return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */ if (ReadFlags & EVENTLOG_SEQUENTIAL_READ) { RecordNumber = pLogHandle->CurrentRecord; } else // (ReadFlags & EVENTLOG_SEEK_READ) { RecordNumber = RecordOffset; }
Status = LogfReadEvents(pLogHandle->LogFile, ReadFlags, &RecordNumber, NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded, TRUE);
/* Update the handle's CurrentRecord if success */ if (NT_SUCCESS(Status)) { pLogHandle->CurrentRecord = RecordNumber; }
return Status;}
/* Function 18 */NTSTATUSWINAPIElfrReportEventA( IELF_HANDLE LogHandle, ULONG Time, USHORT EventType, USHORT EventCategory, ULONG EventID, USHORT NumStrings, ULONG DataSize, PRPC_STRING ComputerName, PRPC_SID UserSID, PRPC_STRING Strings[], PBYTE Data, USHORT Flags, PULONG RecordNumber, PULONG TimeWritten){ NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING ComputerNameW; PUNICODE_STRING *StringsArrayW = NULL; USHORT i;
DPRINT("ElfrReportEventA(%hu)\n", NumStrings);
#if 0 for (i = 0; i < NumStrings; i++) { if (Strings[i] == NULL) { DPRINT1("String %hu is null\n", i); } else { DPRINT1("String %hu: %Z\n", i, Strings[i]); } }#endif
Status = RtlAnsiStringToUnicodeString((PUNICODE_STRING)&ComputerNameW, (PANSI_STRING)ComputerName, TRUE); if (!NT_SUCCESS(Status)) return Status;
if (NumStrings != 0) { StringsArrayW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NumStrings * sizeof(PUNICODE_STRING)); if (StringsArrayW == NULL) { Status = STATUS_NO_MEMORY; goto Done; }
for (i = 0; i < NumStrings; i++) { if (Strings[i] != NULL) { StringsArrayW[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UNICODE_STRING)); if (StringsArrayW[i] == NULL) { Status = STATUS_NO_MEMORY; break; }
Status = RtlAnsiStringToUnicodeString(StringsArrayW[i], (PANSI_STRING)Strings[i], TRUE); }
if (!NT_SUCCESS(Status)) break; } }
if (NT_SUCCESS(Status)) { Status = ElfrReportEventW(LogHandle, Time, EventType, EventCategory, EventID, NumStrings, DataSize, (PRPC_UNICODE_STRING)&ComputerNameW, UserSID, (PRPC_UNICODE_STRING*)StringsArrayW, Data, Flags, RecordNumber, TimeWritten); }
Done: if (StringsArrayW != NULL) { for (i = 0; i < NumStrings; i++) { if ((StringsArrayW[i] != NULL) && (StringsArrayW[i]->Buffer)) { RtlFreeUnicodeString(StringsArrayW[i]); HeapFree(GetProcessHeap(), 0, StringsArrayW[i]); } }
HeapFree(GetProcessHeap(), 0, StringsArrayW); }
RtlFreeUnicodeString(&ComputerNameW);
return Status;}
/* Function 19 */NTSTATUSWINAPIElfrRegisterClusterSvc( handle_t BindingHandle){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* Function 20 */NTSTATUSWINAPIElfrDeregisterClusterSvc( handle_t BindingHandle){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* Function 21 */NTSTATUSWINAPIElfrWriteClusterEvents( handle_t BindingHandle){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* Function 22 */NTSTATUSWINAPIElfrGetLogInformation( IELF_HANDLE LogHandle, ULONG InfoLevel, PBYTE Buffer, ULONG cbBufSize, PULONG pcbBytesNeeded){ NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE pLogHandle; PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
pLogFile = pLogHandle->LogFile;
/* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
switch (InfoLevel) { case EVENTLOG_FULL_INFO: { LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer;
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION); if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION)) { Status = STATUS_BUFFER_TOO_SMALL; break; }
efi->dwFull = !!(ElfGetFlags(&pLogFile->LogFile) & ELF_LOGFILE_LOGFULL_WRITTEN); break; }
default: Status = STATUS_INVALID_LEVEL; break; }
/* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock);
return Status;}
/* Function 23 */NTSTATUSWINAPIElfrFlushEL( IELF_HANDLE LogHandle){ NTSTATUS Status; PLOGHANDLE pLogHandle; PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE;
pLogFile = pLogHandle->LogFile;
/* Lock the log file exclusive */ RtlAcquireResourceExclusive(&pLogFile->Lock, TRUE);
Status = ElfFlushFile(&pLogFile->LogFile);
/* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock);
return Status;}
/* Function 24 */NTSTATUSWINAPIElfrReportEventAndSourceW( IELF_HANDLE LogHandle, ULONG Time, USHORT EventType, USHORT EventCategory, ULONG EventID, PRPC_UNICODE_STRING SourceName, USHORT NumStrings, ULONG DataSize, PRPC_UNICODE_STRING ComputerName, PRPC_SID UserSID, PRPC_UNICODE_STRING Strings[], PBYTE Data, USHORT Flags, PULONG RecordNumber, PULONG TimeWritten){ /* Call the helper function. The event source is specified by the caller. */ return ElfrIntReportEventW(LogHandle, Time, EventType, EventCategory, EventID, SourceName, NumStrings, DataSize, ComputerName, UserSID, Strings, Data, Flags, RecordNumber, TimeWritten);}
void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T len){ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr){ HeapFree(GetProcessHeap(), 0, ptr);}
void __RPC_USER IELF_HANDLE_rundown(IELF_HANDLE LogHandle){ /* Close the handle */ ElfDeleteEventLogHandle(&LogHandle); // ElfrCloseEL(&LogHandle);}