/* Function 5 */ NTSTATUS ElfrOldestRecord( 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; }
BOOL ElfDeleteEventLogHandle(IELF_HANDLE EventLogHandle) { PLOGHANDLE lpLogHandle = (PLOGHANDLE)EventLogHandle; if (!ElfGetLogHandleEntryByHandle(lpLogHandle)) { return FALSE; } RemoveEntryList(&lpLogHandle->LogHandleListEntry); HeapFree(GetProcessHeap(),0,lpLogHandle); return TRUE; }
/* Function 23 */ NTSTATUS ElfrFlushEL( IELF_HANDLE LogHandle) { PLOGHANDLE lpLogHandle; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) return STATUS_INVALID_HANDLE; UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; }
/* Function 17 */ NTSTATUS ElfrReadELA( 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 22 */ NTSTATUS ElfrGetLogInformation( 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 1 */ NTSTATUS ElfrBackupELFW( 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 4 */ NTSTATUS ElfrNumberOfRecords( 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 */ NTSTATUS ElfrOldestRecord( IELF_HANDLE LogHandle, PULONG OldestRecordNumber) { PLOGHANDLE lpLogHandle; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) return STATUS_INVALID_HANDLE; if (!OldestRecordNumber) return STATUS_INVALID_PARAMETER; *OldestRecordNumber = lpLogHandle->LogFile->Header.OldestRecordNumber; return STATUS_SUCCESS; }
static NTSTATUS ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle) { PLOGHANDLE lpLogHandle; lpLogHandle = ElfGetLogHandleEntryByHandle(*LogHandle); if (!lpLogHandle) return STATUS_INVALID_HANDLE; RemoveEntryList(&lpLogHandle->LogHandleListEntry); LogfClose(lpLogHandle->LogFile, FALSE); HeapFree(GetProcessHeap(), 0, lpLogHandle); *LogHandle = NULL; return STATUS_SUCCESS; }
/* Function 22 */ NTSTATUS ElfrGetLogInformation( IELF_HANDLE LogHandle, ULONG InfoLevel, PBYTE Buffer, ULONG cbBufSize, PULONG pcbBytesNeeded) { NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE lpLogHandle; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) return STATUS_INVALID_HANDLE; 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; } /* * FIXME. To check whether an event log is "full" one needs * to compare its current size with respect to the maximum * size threshold "MaxSize" contained in its header. */ efi->dwFull = 0; break; } default: Status = STATUS_INVALID_LEVEL; break; } return Status; }
/* Function 10 */ NTSTATUS ElfrReadELW( IELF_HANDLE LogHandle, DWORD ReadFlags, DWORD RecordOffset, RULONG NumberOfBytesToRead, BYTE *Buffer, DWORD *NumberOfBytesRead, DWORD *MinNumberOfBytesNeeded) { PLOGHANDLE lpLogHandle; DWORD dwError; DWORD RecordNumber; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) { return STATUS_INVALID_HANDLE; } if (!Buffer) return I_RpcMapWin32Status(ERROR_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); /* Update the handles CurrentRecord if success*/ if (dwError == ERROR_SUCCESS) { lpLogHandle->CurrentRecord = RecordNumber; } return I_RpcMapWin32Status(dwError); }
/* Function 0 */ NTSTATUS ElfrClearELFW( 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 5 */ NTSTATUS ElfrOldestRecord( IELF_HANDLE LogHandle, DWORD *OldestRecordNumber) { PLOGHANDLE lpLogHandle; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) { return STATUS_INVALID_HANDLE; } if (!OldestRecordNumber) { return STATUS_INVALID_PARAMETER; } *OldestRecordNumber = 0; *OldestRecordNumber = LogfGetOldestRecord(lpLogHandle->LogFile); return STATUS_SUCCESS; }
static NTSTATUS ElfDeleteEventLogHandle(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 4 */ NTSTATUS ElfrNumberOfRecords( IELF_HANDLE LogHandle, DWORD *NumberOfRecords) { PLOGHANDLE lpLogHandle; PLOGFILE lpLogFile; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) { return STATUS_INVALID_HANDLE; } lpLogFile = lpLogHandle->LogFile; if (lpLogFile->Header.OldestRecordNumber == 0) *NumberOfRecords = 0; else *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber - lpLogFile->Header.OldestRecordNumber; return STATUS_SUCCESS; }
/* Function 4 */ NTSTATUS ElfrNumberOfRecords( IELF_HANDLE LogHandle, PULONG NumberOfRecords) { PLOGHANDLE lpLogHandle; PLOGFILE lpLogFile; DPRINT("ElfrNumberOfRecords()\n"); lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) return STATUS_INVALID_HANDLE; if (!NumberOfRecords) return STATUS_INVALID_PARAMETER; lpLogFile = lpLogHandle->LogFile; DPRINT("Oldest: %lu Current: %lu\n", lpLogFile->Header.OldestRecordNumber, lpLogFile->Header.CurrentRecordNumber); if (lpLogFile->Header.OldestRecordNumber == 0) { /* OldestRecordNumber == 0 when the log is empty */ *NumberOfRecords = 0; } else { /* The log contains events */ *NumberOfRecords = lpLogFile->Header.CurrentRecordNumber - lpLogFile->Header.OldestRecordNumber; } return STATUS_SUCCESS; }
/* Function 23 */ NTSTATUS ElfrFlushEL( 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 11 */ NTSTATUS ElfrReportEventW( IELF_HANDLE LogHandle, DWORD Time, USHORT EventType, USHORT EventCategory, DWORD EventID, USHORT NumStrings, DWORD DataSize, PRPC_UNICODE_STRING ComputerName, PRPC_SID UserSID, PRPC_UNICODE_STRING Strings[], BYTE *Data, USHORT Flags, DWORD *RecordNumber, DWORD *TimeWritten) { USHORT i; PBYTE LogBuffer; PLOGHANDLE lpLogHandle; DWORD lastRec; DWORD recSize; DWORD dwStringsSize = 0; DWORD dwUserSidLength = 0; DWORD dwError = ERROR_SUCCESS; WCHAR *lpStrings; int pos = 0; lpLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!lpLogHandle) { return STATUS_INVALID_HANDLE; } /* Flags must be 0 */ if (Flags) { return STATUS_INVALID_PARAMETER; } lastRec = LogfGetCurrentRecord(lpLogHandle->LogFile); 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; 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; } for (i = 0; i < NumStrings; i++) { 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, lpLogHandle->szName, ComputerName->Buffer, dwUserSidLength, UserSID, NumStrings, lpStrings, DataSize, Data); dwError = LogfWriteData(lpLogHandle->LogFile, recSize, LogBuffer); if (!dwError) { DPRINT1("ERROR WRITING TO EventLog %S\n", lpLogHandle->LogFile->FileName); } LogfFreeRecord(LogBuffer); HeapFree(GetProcessHeap(), 0, lpStrings); return I_RpcMapWin32Status(dwError); }
/* Helper function for ElfrReportEventW/A and ElfrReportEventAndSourceW */ NTSTATUS ElfrIntReportEventW( 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; }