/* * PROJECT: ReactOS EventLog Service * LICENSE: GPL - See COPYING in the top level directory * FILE: base/services/eventlog/logport.c * PURPOSE: LPC Port Interface support * COPYRIGHT: Copyright 2002 Eric Kohl * Copyright 2005 Saveliy Tretiakov */ /* INCLUDES *****************************************************************/ #include "eventlog.h" #include #include #define NDEBUG #include /* GLOBALS ******************************************************************/ static HANDLE ConnectPortHandle = NULL; static HANDLE MessagePortHandle = NULL; extern BOOL onLiveCD; /* FUNCTIONS ****************************************************************/ NTSTATUS WINAPI PortThreadRoutine(PVOID Param) { NTSTATUS Status = STATUS_SUCCESS; Status = InitLogPort(); if (!NT_SUCCESS(Status)) return Status; while (NT_SUCCESS(Status)) Status = ProcessPortMessage(); if (ConnectPortHandle != NULL) NtClose(ConnectPortHandle); if (MessagePortHandle != NULL) NtClose(MessagePortHandle); return Status; } NTSTATUS InitLogPort(VOID) { NTSTATUS Status; UNICODE_STRING PortName = RTL_CONSTANT_STRING(ELF_PORT_NAME); OBJECT_ATTRIBUTES ObjectAttributes; PORT_MESSAGE Request; ConnectPortHandle = NULL; MessagePortHandle = NULL; InitializeObjectAttributes(&ObjectAttributes, &PortName, 0, NULL, NULL); Status = NtCreatePort(&ConnectPortHandle, &ObjectAttributes, 0, PORT_MAXIMUM_MESSAGE_LENGTH, // IO_ERROR_LOG_MESSAGE_LENGTH, 2 * PAGE_SIZE); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreatePort() failed (Status %lx)\n", Status); goto ByeBye; } Status = NtListenPort(ConnectPortHandle, &Request); if (!NT_SUCCESS(Status)) { DPRINT1("NtListenPort() failed (Status %lx)\n", Status); goto ByeBye; } Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle, &Request, TRUE, NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status); goto ByeBye; } Status = NtCompleteConnectPort(MessagePortHandle); if (!NT_SUCCESS(Status)) { DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status); goto ByeBye; } ByeBye: if (!NT_SUCCESS(Status)) { if (ConnectPortHandle != NULL) NtClose(ConnectPortHandle); if (MessagePortHandle != NULL) NtClose(MessagePortHandle); } return Status; } NTSTATUS ProcessPortMessage(VOID) { NTSTATUS Status; PLOGFILE SystemLog = NULL; UCHAR Buffer[PORT_MAXIMUM_MESSAGE_LENGTH]; // IO_ERROR_LOG_MESSAGE_LENGTH PELF_API_MSG Message = (PELF_API_MSG)Buffer; PIO_ERROR_LOG_MESSAGE ErrorMessage; PEVENTLOGRECORD LogBuffer; SIZE_T RecSize; ULONG Time; USHORT EventType; UNICODE_STRING SourceName, ComputerName; DWORD dwComputerNameLength; WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; DPRINT("ProcessPortMessage() called\n"); SystemLog = LogfListItemByName(L"System"); while (TRUE) { Status = NtReplyWaitReceivePort(MessagePortHandle, NULL, NULL, &Message->Header); if (!NT_SUCCESS(Status)) { DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status); break; } DPRINT("Received message\n"); if (Message->Header.u2.s2.Type == LPC_PORT_CLOSED) { DPRINT("Port closed\n"); return STATUS_SUCCESS; } if (Message->Header.u2.s2.Type == LPC_REQUEST) { DPRINT("Received request\n"); } else if (Message->Header.u2.s2.Type == LPC_DATAGRAM) { DPRINT("Received datagram (0x%x, 0x%x)\n", Message->Unknown[0], Message->Unknown[1]); ErrorMessage = &Message->IoErrorMessage; // ASSERT(ErrorMessage->Type == IO_TYPE_ERROR_MESSAGE); RtlInitEmptyUnicodeString(&SourceName, NULL, 0); if (ErrorMessage->DriverNameLength > sizeof(UNICODE_NULL)) // DriverNameLength counts NULL-terminator { SourceName.Buffer = (PWSTR)((ULONG_PTR)ErrorMessage + ErrorMessage->DriverNameOffset); SourceName.MaximumLength = ErrorMessage->DriverNameLength; SourceName.Length = SourceName.MaximumLength - sizeof(UNICODE_NULL); } dwComputerNameLength = ARRAYSIZE(szComputerName); if (!GetComputerNameW(szComputerName, &dwComputerNameLength)) szComputerName[0] = L'\0'; RtlInitUnicodeString(&ComputerName, szComputerName); RtlTimeToSecondsSince1970(&ErrorMessage->TimeStamp, &Time); /* Set the event type based on the error code severity */ EventType = (USHORT)(ErrorMessage->EntryData.ErrorCode >> 30); if (EventType == STATUS_SEVERITY_SUCCESS) { EventType = EVENTLOG_SUCCESS; } else if (EventType == STATUS_SEVERITY_INFORMATIONAL) // NT_INFORMATION { EventType = EVENTLOG_INFORMATION_TYPE; } else if (EventType == STATUS_SEVERITY_WARNING) // NT_WARNING { EventType = EVENTLOG_WARNING_TYPE; } else if (EventType == STATUS_SEVERITY_ERROR) // NT_ERROR { EventType = EVENTLOG_ERROR_TYPE; } else { /* Unknown severity, set to error */ EventType = EVENTLOG_ERROR_TYPE; } /* * The data being saved consists of the IO_ERROR_LOG_PACKET structure * header, plus the additional raw data from the driver. */ LogBuffer = LogfAllocAndBuildNewRecord( &RecSize, Time, EventType, ErrorMessage->EntryData.EventCategory, ErrorMessage->EntryData.ErrorCode, &SourceName, &ComputerName, 0, NULL, ErrorMessage->EntryData.NumberOfStrings, (PWSTR)((ULONG_PTR)ErrorMessage + ErrorMessage->EntryData.StringOffset), FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + ErrorMessage->EntryData.DumpDataSize, (PVOID)&ErrorMessage->EntryData); if (LogBuffer == NULL) { DPRINT1("LogfAllocAndBuildNewRecord failed!\n"); // return STATUS_NO_MEMORY; continue; } if (!onLiveCD && SystemLog) { Status = LogfWriteRecord(SystemLog, LogBuffer, RecSize); if (!NT_SUCCESS(Status)) { DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n", SystemLog->LogName, Status); } } else { DPRINT1("\n--- EVENTLOG RECORD ---\n"); PRINT_RECORD(LogBuffer); DPRINT1("\n"); } LogfFreeRecord(LogBuffer); } } return Status; }