#include "eventlog.h"
-LIST_ENTRY EventSourceListHead;
+LIST_ENTRY LogHandleListHead;
/* FUNCTIONS ****************************************************************/
{
RPC_STATUS Status;
- InitializeListHead(&EventSourceListHead);
+ InitializeListHead(&LogHandleListHead);
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL);
if (Status != RPC_S_OK)
return 0;
}
-PEVENTSOURCE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
+PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
{
- PEVENTSOURCE lpEventSource;
+ PLOGHANDLE lpLogHandle;
PLOGFILE currentLogFile = NULL;
INT i, LogsActive;
+ PEVENTSOURCE pEventSource;
- lpEventSource = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTSOURCE)
+ DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
+
+ lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
+ ((wcslen(Name) + 1) * sizeof(WCHAR)));
- if (!lpEventSource)
+ if (!lpLogHandle)
{
DPRINT1("Failed to allocate Heap!\n");
return NULL;
}
- wcscpy(lpEventSource->szName, Name);
+ wcscpy(lpLogHandle->szName, Name);
/* Get the number of Log Files the EventLog service found */
LogsActive = LogfListItemCount();
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */
if (Create == TRUE)
- lpEventSource->LogFile = LogfListItemByName(L"Application");
- else
- lpEventSource->LogFile = NULL;
+ {
+ pEventSource = GetEventSourceByName(Name);
+ DPRINT("EventSource: %p\n", pEventSource);
+ if (pEventSource)
+ {
+ DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile);
+ lpLogHandle->LogFile = pEventSource->LogFile;
+ }
+ else
+ {
+ DPRINT("EventSource LogFile: Application log file\n");
+ lpLogHandle->LogFile = LogfListItemByName(L"Application");
+ }
- for (i = 1; i <= LogsActive; i++)
+ DPRINT("LogHandle LogFile: %p\n", lpLogHandle->LogFile);
+ }
+ else
{
- currentLogFile = LogfListItemByIndex(i);
+ lpLogHandle->LogFile = NULL;
- if (_wcsicmp(Name, currentLogFile->LogName) == 0)
+ for (i = 1; i <= LogsActive; i++)
{
- lpEventSource->LogFile = LogfListItemByIndex(i);
- lpEventSource->CurrentRecord = LogfGetOldestRecord(lpEventSource->LogFile);
- break;
+ currentLogFile = LogfListItemByIndex(i);
+
+ if (_wcsicmp(Name, currentLogFile->LogName) == 0)
+ {
+ lpLogHandle->LogFile = LogfListItemByIndex(i);
+ lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
+ break;
+ }
+ }
+
+ /* Use the application log if the desired log does not exist */
+ if (lpLogHandle->LogFile == NULL)
+ {
+ lpLogHandle->LogFile = LogfListItemByName(L"Application");
+ lpLogHandle->CurrentRecord = LogfGetOldestRecord(lpLogHandle->LogFile);
}
}
- if (!lpEventSource->LogFile)
+ if (!lpLogHandle->LogFile)
goto Cleanup;
- /* Append service record */
- InsertTailList(&EventSourceListHead, &lpEventSource->EventSourceListEntry);
+ /* Append log handle */
+ InsertTailList(&LogHandleListHead, &lpLogHandle->LogHandleListEntry);
- return lpEventSource;
+ return lpLogHandle;
Cleanup:
- HeapFree(GetProcessHeap(), 0, lpEventSource);
+ HeapFree(GetProcessHeap(), 0, lpLogHandle);
return NULL;
}
-PEVENTSOURCE ElfGetEventLogSourceEntryByHandle(IELF_HANDLE EventLogHandle)
+PLOGHANDLE ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
{
- PEVENTSOURCE CurrentEventSource;
+ PLOGHANDLE lpLogHandle;
- if (IsListEmpty(&EventSourceListHead))
+ if (IsListEmpty(&LogHandleListHead))
{
return NULL;
}
- CurrentEventSource = CONTAINING_RECORD((PEVENTSOURCE)EventLogHandle, EVENTSOURCE, EventSourceListEntry);
- return CurrentEventSource;
+ lpLogHandle = CONTAINING_RECORD((PLOGHANDLE)EventLogHandle, LOGHANDLE, LogHandleListEntry);
+
+ return lpLogHandle;
}
BOOL ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle)
{
- PEVENTSOURCE lpEventSource = (PEVENTSOURCE)EventLogHandle;
- if (!ElfGetEventLogSourceEntryByHandle(lpEventSource))
+ PLOGHANDLE lpLogHandle = (PLOGHANDLE)EventLogHandle;
+ if (!ElfGetLogHandleEntryByHandle(lpLogHandle))
{
return FALSE;
}
- RemoveEntryList(&lpEventSource->EventSourceListEntry);
- HeapFree(GetProcessHeap(),0,lpEventSource);
+ RemoveEntryList(&lpLogHandle->LogHandleListEntry);
+ HeapFree(GetProcessHeap(),0,lpLogHandle);
return TRUE;
}
IELF_HANDLE LogHandle,
PRPC_UNICODE_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLOGHANDLE lpLogHandle;
+
+ DPRINT("ElfrClearELFW()\n");
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
+ {
+ return STATUS_INVALID_HANDLE;
+ }
+
+ return LogfClearFile(lpLogHandle->LogFile,
+ (PUNICODE_STRING)BackupFileName);
}
IELF_HANDLE LogHandle,
PRPC_UNICODE_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLOGHANDLE lpLogHandle;
+
+ DPRINT("ElfrBackupELFW()\n");
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
+ {
+ return STATUS_INVALID_HANDLE;
+ }
+
+ return LogfBackupFile(lpLogHandle->LogFile,
+ (PUNICODE_STRING)BackupFileName);
}
+
/* Function 2 */
NTSTATUS ElfrCloseEL(
IELF_HANDLE *LogHandle)
IELF_HANDLE LogHandle,
DWORD *NumberOfRecords)
{
- PEVENTSOURCE lpEventSource;
+ PLOGHANDLE lpLogHandle;
+ PLOGFILE lpLogFile;
+
+ DPRINT("ElfrNumberOfRecords()");
- lpEventSource = ElfGetEventLogSourceEntryByHandle(LogHandle);
- if (!lpEventSource)
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
- *NumberOfRecords = lpEventSource->LogFile->Header.CurrentRecordNumber;
+ lpLogFile = lpLogHandle->LogFile;
+
+ DPRINT("Oldest: %lu Current: %lu\n",
+ lpLogFile->Header.OldestRecordNumber,
+ lpLogFile->Header.CurrentRecordNumber);
+
+ *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber -
+ lpLogFile->Header.OldestRecordNumber;
return STATUS_SUCCESS;
}
IELF_HANDLE LogHandle,
DWORD *OldestRecordNumber)
{
- PEVENTSOURCE lpEventSource;
+ PLOGHANDLE lpLogHandle;
- lpEventSource = ElfGetEventLogSourceEntryByHandle(LogHandle);
- if (!lpEventSource)
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
return STATUS_INVALID_PARAMETER;
}
- *OldestRecordNumber = 0;
- *OldestRecordNumber = LogfGetOldestRecord(lpEventSource->LogFile);
+ *OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile);
+
return STATUS_SUCCESS;
}
RPC_CLIENT_ID ClientId,
DWORD Event)
{
+ DPRINT("ElfrChangeNotify()");
+
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
+ DPRINT("ElfrRegisterEventSourceW()\n");
+
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
+ DPRINT("ModuleName: %S\n", ModuleName->Buffer);
+
/*FIXME: UNCServerName must specify the server or empty for local */
/*FIXME: Must verify that caller has write access */
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
{
- PEVENTSOURCE lpEventSource;
+ PLOGHANDLE lpLogHandle;
DWORD dwError;
DWORD RecordNumber;
- lpEventSource = ElfGetEventLogSourceEntryByHandle(LogHandle);
- if (!lpEventSource)
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
- if (!Buffer)
- return I_RpcMapWin32Status(ERROR_INVALID_PARAMETER);
+ if (!Buffer)
+ return STATUS_INVALID_PARAMETER;
/* If sequential read, retrieve the CurrentRecord from this log handle */
if (ReadFlags & EVENTLOG_SEQUENTIAL_READ)
{
- RecordNumber = lpEventSource->CurrentRecord;
+ RecordNumber = lpLogHandle->CurrentRecord;
}
else
{
RecordNumber = RecordOffset;
}
- dwError = LogfReadEvent(lpEventSource->LogFile, ReadFlags, &RecordNumber,
- NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded);
+ dwError = LogfReadEvent(lpLogHandle->LogFile, ReadFlags, &RecordNumber,
+ NumberOfBytesToRead, Buffer, NumberOfBytesRead, MinNumberOfBytesNeeded,
+ FALSE);
/* Update the handles CurrentRecord if success*/
if (dwError == ERROR_SUCCESS)
{
- lpEventSource->CurrentRecord = RecordNumber;
+ lpLogHandle->CurrentRecord = RecordNumber;
}
+ /* HACK!!! */
+ if (dwError == ERROR_HANDLE_EOF)
+ return STATUS_END_OF_FILE;
+
return I_RpcMapWin32Status(dwError);
}
{
USHORT i;
PBYTE LogBuffer;
- PEVENTSOURCE lpEventSource;
+ PLOGHANDLE lpLogHandle;
DWORD lastRec;
DWORD recSize;
DWORD dwStringsSize = 0;
+ DWORD dwUserSidLength = 0;
DWORD dwError = ERROR_SUCCESS;
WCHAR *lpStrings;
int pos = 0;
- lpEventSource = ElfGetEventLogSourceEntryByHandle(LogHandle);
- if (!lpEventSource)
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
{
return STATUS_INVALID_HANDLE;
}
return STATUS_INVALID_PARAMETER;
}
- lastRec = LogfGetCurrentRecord(lpEventSource->LogFile);
+ lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile);
for (i = 0; i < NumStrings; i++)
{
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 += (wcslen(Strings[i]->Buffer) + 1) * sizeof(WCHAR);
+ dwStringsSize += Strings[i]->Length + sizeof UNICODE_NULL;
}
- lpStrings = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, dwStringsSize * 2);
+ lpStrings = HeapAlloc(GetProcessHeap(), 0, dwStringsSize);
if (!lpStrings)
{
DPRINT1("Failed to allocate heap\n");
for (i = 0; i < NumStrings; i++)
{
- wcscpy((WCHAR*)(lpStrings + pos), Strings[i]->Buffer);
- pos += (wcslen(Strings[i]->Buffer) + 1) * sizeof(WCHAR);
+ CopyMemory(lpStrings + pos, Strings[i]->Buffer, Strings[i]->Length);
+ pos += Strings[i]->Length / sizeof(WCHAR);
+ lpStrings[pos] = UNICODE_NULL;
+ pos += sizeof UNICODE_NULL / sizeof(WCHAR);
}
+ if (UserSID)
+ dwUserSidLength = FIELD_OFFSET(SID, SubAuthority[UserSID->SubAuthorityCount]);
LogBuffer = LogfAllocAndBuildNewRecord(&recSize,
lastRec,
EventType,
EventCategory,
EventID,
- lpEventSource->szName,
+ lpLogHandle->szName,
ComputerName->Buffer,
- sizeof(UserSID),
- &UserSID,
+ dwUserSidLength,
+ UserSID,
NumStrings,
- (WCHAR*)lpStrings,
+ lpStrings,
DataSize,
Data);
- dwError = LogfWriteData(lpEventSource->LogFile, recSize, LogBuffer);
+ dwError = LogfWriteData(lpLogHandle->LogFile, recSize, LogBuffer);
if (!dwError)
{
- DPRINT1("ERROR WRITING TO EventLog %S\n",lpEventSource->LogFile->FileName);
+ DPRINT1("ERROR WRITING TO EventLog %S\n", lpLogHandle->LogFile->FileName);
}
LogfFreeRecord(LogBuffer);
IELF_HANDLE LogHandle,
PRPC_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING BackupFileNameW;
+ NTSTATUS Status;
+
+ Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
+ (PANSI_STRING)BackupFileName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = ElfrClearELFW(LogHandle,
+ (PRPC_UNICODE_STRING)&BackupFileNameW);
+
+ RtlFreeUnicodeString(&BackupFileNameW);
+
+ return Status;
}
IELF_HANDLE LogHandle,
PRPC_STRING BackupFileName)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING BackupFileNameW;
+ NTSTATUS Status;
+
+ Status = RtlAnsiStringToUnicodeString(&BackupFileNameW,
+ (PANSI_STRING)BackupFileName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = ElfrBackupELFW(LogHandle,
+ (PRPC_UNICODE_STRING)&BackupFileNameW);
+
+ RtlFreeUnicodeString(&BackupFileNameW);
+
+ return Status;
}
IELF_HANDLE *LogHandle)
{
UNICODE_STRING ModuleNameW;
+ NTSTATUS Status;
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
- RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
+ Status = RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
+ if (!NT_SUCCESS(Status))
+ return Status;
/* FIXME: Must verify that caller has read access */
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
- UNICODE_STRING ModuleNameW = { 0, 0, NULL };
+ UNICODE_STRING ModuleNameW;
+ NTSTATUS Status;
- if (ModuleName &&
- !RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
+ Status = RtlAnsiStringToUnicodeString(&ModuleNameW,
+ (PANSI_STRING)ModuleName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
{
- return STATUS_NO_MEMORY;
+ DPRINT1("RtlAnsiStringToUnicodeString failed (Status 0x%08lx)\n", Status);
+ return Status;
}
/* RegModuleName must be an empty string */
DWORD *NumberOfBytesRead,
DWORD *MinNumberOfBytesNeeded)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PLOGHANDLE lpLogHandle;
+ DWORD dwError;
+ DWORD RecordNumber;
+
+ lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
+ if (!lpLogHandle)
+ {
+ 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 = lpLogHandle->CurrentRecord;
+ }
+ else
+ {
+ RecordNumber = RecordOffset;
+ }
+
+ dwError = LogfReadEvent(lpLogHandle->LogFile,
+ ReadFlags,
+ &RecordNumber,
+ NumberOfBytesToRead,
+ Buffer,
+ NumberOfBytesRead,
+ MinNumberOfBytesNeeded,
+ TRUE);
+
+ /* Update the handles CurrentRecord if success*/
+ if (dwError == ERROR_SUCCESS)
+ {
+ lpLogHandle->CurrentRecord = RecordNumber;
+ }
+
+ /* HACK!!! */
+ if (dwError == ERROR_HANDLE_EOF)
+ return STATUS_END_OF_FILE;
+
+ return I_RpcMapWin32Status(dwError);
}
DWORD *RecordNumber,
DWORD *TimeWritten)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNICODE_STRING ComputerNameW;
+ PUNICODE_STRING *StringsArrayW = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ 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(MyHeap,
+ 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(MyHeap,
+ 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:
+ for (i = 0; i < NumStrings; i++)
+ {
+ if (StringsArrayW[i] != NULL)
+ {
+ if (StringsArrayW[i]->Buffer)
+ {
+ RtlFreeUnicodeString(StringsArrayW[i]);
+ HeapFree(MyHeap, 0, StringsArrayW[i]);
+ }
+ }
+ }
+
+ if (StringsArrayW != NULL)
+ HeapFree(MyHeap, 0, StringsArrayW);
+
+ RtlFreeUnicodeString(&ComputerNameW);
+
+ return Status;
}