Author: hbelusca
Date: Mon Nov 7 13:29:09 2016
New Revision: 73167
URL:
http://svn.reactos.org/svn/reactos?rev=73167&view=rev
Log:
[NTOS:IO][INCLUDES][EVENTLOG]: Fix support for event logging through the
"ErrorLogPort" LPC. See the details in CORE-12301 #resolve
Added:
trunk/reactos/sdk/include/reactos/subsys/iolog/
trunk/reactos/sdk/include/reactos/subsys/iolog/iolog.h (with props)
Modified:
trunk/reactos/base/services/eventlog/CMakeLists.txt
trunk/reactos/base/services/eventlog/eventlog.c
trunk/reactos/base/services/eventlog/eventlog.h
trunk/reactos/base/services/eventlog/file.c
trunk/reactos/base/services/eventlog/logport.c
trunk/reactos/base/services/eventlog/rpc.c
trunk/reactos/ntoskrnl/include/internal/io.h
trunk/reactos/ntoskrnl/io/iomgr/error.c
Modified: trunk/reactos/base/services/eventlog/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/CMa…
==============================================================================
--- trunk/reactos/base/services/eventlog/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/CMakeLists.txt [iso-8859-1] Mon Nov 7 13:29:09
2016
@@ -1,6 +1,7 @@
include_directories(
${REACTOS_SOURCE_DIR}/sdk/lib/evtlib
+ ${REACTOS_SOURCE_DIR}/sdk/include/reactos/subsys
${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl
${CMAKE_CURRENT_BINARY_DIR})
Modified: trunk/reactos/base/services/eventlog/eventlog.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/eve…
==============================================================================
--- trunk/reactos/base/services/eventlog/eventlog.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/eventlog.c [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -548,71 +548,73 @@
LARGE_INTEGER SystemTime;
TIME_FIELDS Time;
- DPRINT("Length = %lu\n", pRec->Length);
- DPRINT("Reserved = 0x%x\n", pRec->Reserved);
- DPRINT("RecordNumber = %lu\n", pRec->RecordNumber);
+ DPRINT1("PRINT_RECORD(0x%p)\n", pRec);
+
+ DbgPrint("Length = %lu\n", pRec->Length);
+ DbgPrint("Reserved = 0x%x\n", pRec->Reserved);
+ DbgPrint("RecordNumber = %lu\n", pRec->RecordNumber);
RtlSecondsSince1970ToTime(pRec->TimeGenerated, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
- DPRINT("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
- Time.Day, Time.Month, Time.Year,
- Time.Hour, Time.Minute, Time.Second);
+ DbgPrint("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
+ Time.Day, Time.Month, Time.Year,
+ Time.Hour, Time.Minute, Time.Second);
RtlSecondsSince1970ToTime(pRec->TimeWritten, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
- DPRINT("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
- Time.Day, Time.Month, Time.Year,
- Time.Hour, Time.Minute, Time.Second);
-
- DPRINT("EventID = %lu\n", pRec->EventID);
+ DbgPrint("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
+ Time.Day, Time.Month, Time.Year,
+ Time.Hour, Time.Minute, Time.Second);
+
+ DbgPrint("EventID = %lu\n", pRec->EventID);
switch (pRec->EventType)
{
case EVENTLOG_ERROR_TYPE:
- DPRINT("EventType = EVENTLOG_ERROR_TYPE\n");
+ DbgPrint("EventType = EVENTLOG_ERROR_TYPE\n");
break;
case EVENTLOG_WARNING_TYPE:
- DPRINT("EventType = EVENTLOG_WARNING_TYPE\n");
+ DbgPrint("EventType = EVENTLOG_WARNING_TYPE\n");
break;
case EVENTLOG_INFORMATION_TYPE:
- DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n");
+ DbgPrint("EventType = EVENTLOG_INFORMATION_TYPE\n");
break;
case EVENTLOG_AUDIT_SUCCESS:
- DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n");
+ DbgPrint("EventType = EVENTLOG_AUDIT_SUCCESS\n");
break;
case EVENTLOG_AUDIT_FAILURE:
- DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n");
+ DbgPrint("EventType = EVENTLOG_AUDIT_FAILURE\n");
break;
default:
- DPRINT("EventType = %hu\n", pRec->EventType);
- }
-
- DPRINT("NumStrings = %hu\n", pRec->NumStrings);
- DPRINT("EventCategory = %hu\n", pRec->EventCategory);
- DPRINT("ReservedFlags = 0x%x\n", pRec->ReservedFlags);
- DPRINT("ClosingRecordNumber = %lu\n", pRec->ClosingRecordNumber);
- DPRINT("StringOffset = %lu\n", pRec->StringOffset);
- DPRINT("UserSidLength = %lu\n", pRec->UserSidLength);
- DPRINT("UserSidOffset = %lu\n", pRec->UserSidOffset);
- DPRINT("DataLength = %lu\n", pRec->DataLength);
- DPRINT("DataOffset = %lu\n", pRec->DataOffset);
-
- DPRINT("SourceName: %S\n", (PWSTR)((ULONG_PTR)pRec +
sizeof(EVENTLOGRECORD)));
-
- i = (wcslen((PWSTR)((ULONG_PTR)pRec + sizeof(EVENTLOGRECORD))) + 1) * sizeof(WCHAR);
-
- DPRINT("ComputerName: %S\n", (PWSTR)((ULONG_PTR)pRec +
sizeof(EVENTLOGRECORD) + i));
+ DbgPrint("EventType = %hu\n", pRec->EventType);
+ }
+
+ DbgPrint("NumStrings = %hu\n", pRec->NumStrings);
+ DbgPrint("EventCategory = %hu\n", pRec->EventCategory);
+ DbgPrint("ReservedFlags = 0x%x\n", pRec->ReservedFlags);
+ DbgPrint("ClosingRecordNumber = %lu\n", pRec->ClosingRecordNumber);
+ DbgPrint("StringOffset = %lu\n", pRec->StringOffset);
+ DbgPrint("UserSidLength = %lu\n", pRec->UserSidLength);
+ DbgPrint("UserSidOffset = %lu\n", pRec->UserSidOffset);
+ DbgPrint("DataLength = %lu\n", pRec->DataLength);
+ DbgPrint("DataOffset = %lu\n", pRec->DataOffset);
+
+ i = sizeof(EVENTLOGRECORD);
+ DbgPrint("SourceName: %S\n", (PWSTR)((ULONG_PTR)pRec + i));
+
+ i += (wcslen((PWSTR)((ULONG_PTR)pRec + i)) + 1) * sizeof(WCHAR);
+ DbgPrint("ComputerName: %S\n", (PWSTR)((ULONG_PTR)pRec + i));
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
{
- DPRINT("Strings:\n");
+ DbgPrint("Strings:\n");
str = (PWSTR)((ULONG_PTR)pRec + pRec->StringOffset);
for (i = 0; i < pRec->NumStrings; i++)
{
- DPRINT("[%u] %S\n", i, str);
+ DbgPrint("[%u] %S\n", i, str);
str += wcslen(str) + 1;
}
}
- DPRINT("Length2 = %lu\n", *(PULONG)((ULONG_PTR)pRec + pRec->Length -
4));
-}
+ DbgPrint("Length2 = %lu\n", *(PULONG)((ULONG_PTR)pRec + pRec->Length -
4));
+}
Modified: trunk/reactos/base/services/eventlog/eventlog.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/eve…
==============================================================================
--- trunk/reactos/base/services/eventlog/eventlog.h [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/eventlog.h [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -27,15 +27,6 @@
#include <eventlogrpc_s.h>
#include <strsafe.h>
-
-// FIXME: For that we may directly include NTOS header??
-typedef struct _IO_ERROR_LPC
-{
- PORT_MESSAGE Header;
- IO_ERROR_LOG_MESSAGE Message;
-} IO_ERROR_LPC, *PIO_ERROR_LPC;
-
-// C_ASSERT(sizeof(IO_ERROR_LPC) == 0x100);
/* Defined in evtlib.h */
// #define LOGFILE_SIGNATURE 0x654c664c // "LfLe"
@@ -140,8 +131,8 @@
USHORT wType,
USHORT wCategory,
ULONG dwEventId,
- PCWSTR SourceName,
- PCWSTR ComputerName,
+ PUNICODE_STRING SourceName,
+ PUNICODE_STRING ComputerName,
ULONG dwSidLength,
PSID pUserSid,
USHORT wNumStrings,
Modified: trunk/reactos/base/services/eventlog/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/fil…
==============================================================================
--- trunk/reactos/base/services/eventlog/file.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/file.c [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -898,8 +898,8 @@
USHORT wType,
USHORT wCategory,
ULONG dwEventId,
- PCWSTR SourceName,
- PCWSTR ComputerName,
+ PUNICODE_STRING SourceName,
+ PUNICODE_STRING ComputerName,
ULONG dwSidLength,
PSID pUserSid,
USHORT wNumStrings,
@@ -908,16 +908,17 @@
PVOID pRawData)
{
SIZE_T RecSize;
+ SIZE_T SourceNameSize, ComputerNameSize, StringLen;
PBYTE Buffer;
PEVENTLOGRECORD pRec;
PWSTR str;
UINT i, pos;
- SIZE_T SourceNameLen, ComputerNameLen, StringLen;
-
- SourceNameLen = (SourceName ? wcslen(SourceName) : 0) + 1;
- ComputerNameLen = (ComputerName ? wcslen(ComputerName) : 0) + 1;
-
- RecSize = sizeof(EVENTLOGRECORD) + (SourceNameLen + ComputerNameLen) *
sizeof(WCHAR);
+
+ SourceNameSize = (SourceName && SourceName->Buffer) ?
SourceName->Length : 0;
+ ComputerNameSize = (ComputerName && ComputerName->Buffer) ?
ComputerName->Length : 0;
+
+ RecSize = sizeof(EVENTLOGRECORD) + /* Add the sizes of the strings, NULL-terminated
*/
+ SourceNameSize + ComputerNameSize + 2*sizeof(UNICODE_NULL);
/* Align on DWORD boundary for the SID */
RecSize = ROUND_UP(RecSize, sizeof(ULONG));
@@ -975,12 +976,19 @@
pos = sizeof(EVENTLOGRECORD);
- if (SourceName)
- StringCchCopyW((PWSTR)(Buffer + pos), SourceNameLen, SourceName);
- pos += SourceNameLen * sizeof(WCHAR);
- if (ComputerName)
- StringCchCopyW((PWSTR)(Buffer + pos), ComputerNameLen, ComputerName);
- pos += ComputerNameLen * sizeof(WCHAR);
+ /* NOTE: Equivalents of RtlStringCbCopyUnicodeString calls */
+ if (SourceNameSize)
+ {
+ StringCbCopyNW((PWSTR)(Buffer + pos), SourceNameSize + sizeof(UNICODE_NULL),
+ SourceName->Buffer, SourceNameSize);
+ }
+ pos += SourceNameSize + sizeof(UNICODE_NULL);
+ if (ComputerNameSize)
+ {
+ StringCbCopyNW((PWSTR)(Buffer + pos), ComputerNameSize + sizeof(UNICODE_NULL),
+ ComputerName->Buffer, ComputerNameSize);
+ }
+ pos += ComputerNameSize + sizeof(UNICODE_NULL);
/* Align on DWORD boundary for the SID */
pos = ROUND_UP(pos, sizeof(ULONG));
@@ -1035,20 +1043,24 @@
PVOID pRawData)
{
NTSTATUS Status;
- WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
+ UNICODE_STRING SourceName, ComputerName;
PEVENTLOGRECORD LogBuffer;
LARGE_INTEGER SystemTime;
ULONG Time;
SIZE_T RecSize;
+ DWORD dwComputerNameLength;
+ WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
if (!EventLogSource)
return;
+ RtlInitUnicodeString(&SourceName, EventLogSource->szName);
+
+ dwComputerNameLength = ARRAYSIZE(szComputerName);
if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
- {
szComputerName[0] = L'\0';
- }
+
+ RtlInitUnicodeString(&ComputerName, szComputerName);
NtQuerySystemTime(&SystemTime);
RtlTimeToSecondsSince1970(&SystemTime, &Time);
@@ -1058,14 +1070,19 @@
wType,
wCategory,
dwEventId,
- EventLogSource->szName,
- szComputerName,
+ &SourceName,
+ &ComputerName,
0,
NULL,
wNumStrings,
pStrings,
dwDataSize,
pRawData);
+ if (LogBuffer == NULL)
+ {
+ DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
+ return;
+ }
Status = LogfWriteRecord(EventLogSource->LogFile, LogBuffer, RecSize);
if (!NT_SUCCESS(Status))
Modified: trunk/reactos/base/services/eventlog/logport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/log…
==============================================================================
--- trunk/reactos/base/services/eventlog/logport.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/logport.c [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -11,6 +11,7 @@
#include "eventlog.h"
#include <ndk/lpcfuncs.h>
+#include <iolog/iolog.h>
#define NDEBUG
#include <debug.h>
@@ -46,22 +47,20 @@
NTSTATUS InitLogPort(VOID)
{
NTSTATUS Status;
- UNICODE_STRING PortName;
+ UNICODE_STRING PortName = RTL_CONSTANT_STRING(ELF_PORT_NAME);
OBJECT_ATTRIBUTES ObjectAttributes;
PORT_MESSAGE Request;
ConnectPortHandle = NULL;
MessagePortHandle = NULL;
- RtlInitUnicodeString(&PortName, L"\\ErrorLogPort");
InitializeObjectAttributes(&ObjectAttributes, &PortName, 0, NULL, NULL);
Status = NtCreatePort(&ConnectPortHandle,
&ObjectAttributes,
0,
- 0x100,
- 0x2000);
-
+ PORT_MAXIMUM_MESSAGE_LENGTH, // IO_ERROR_LOG_MESSAGE_LENGTH,
+ 2 * PAGE_SIZE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreatePort() failed (Status %lx)\n", Status);
@@ -76,7 +75,7 @@
}
Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
- NULL, TRUE, NULL, NULL);
+ &Request, TRUE, NULL, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
@@ -105,14 +104,17 @@
NTSTATUS ProcessPortMessage(VOID)
{
NTSTATUS Status;
- IO_ERROR_LPC Request;
- PIO_ERROR_LOG_MESSAGE Message;
+ 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;
- PEVENTLOGRECORD pRec;
- SIZE_T RecSize;
- PLOGFILE SystemLog = NULL;
+ USHORT EventType;
+ UNICODE_STRING SourceName, ComputerName;
+ DWORD dwComputerNameLength;
WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
DPRINT("ProcessPortMessage() called\n");
@@ -121,9 +123,9 @@
while (TRUE)
{
Status = NtReplyWaitReceivePort(MessagePortHandle,
- 0,
NULL,
- &Request.Header);
+ NULL,
+ &Message->Header);
if (!NT_SUCCESS(Status))
{
@@ -133,69 +135,108 @@
DPRINT("Received message\n");
- if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED)
+ if (Message->Header.u2.s2.Type == LPC_PORT_CLOSED)
{
DPRINT("Port closed\n");
return STATUS_SUCCESS;
}
- if (Request.Header.u2.s2.Type == LPC_REQUEST)
+ if (Message->Header.u2.s2.Type == LPC_REQUEST)
{
DPRINT("Received request\n");
}
- else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
- {
- DPRINT("Received datagram\n");
- // Message = (PIO_ERROR_LOG_MESSAGE)&Request.Message;
- Message = &Request.Message;
-
+ 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';
- }
-
- RtlTimeToSecondsSince1970(&Message->TimeStamp, &Time);
-
- // TODO: Log more information??
-
- pRec = LogfAllocAndBuildNewRecord(
- &RecSize,
- Time,
- Message->Type,
- Message->EntryData.EventCategory,
- Message->EntryData.ErrorCode,
- (PWSTR)((ULONG_PTR)Message + Message->DriverNameOffset), //
FIXME: Use DriverNameLength too!
- szComputerName,
- 0,
- NULL,
- Message->EntryData.NumberOfStrings,
- (PWSTR)((ULONG_PTR)Message +
Message->EntryData.StringOffset),
- Message->EntryData.DumpDataSize,
- (PVOID)((ULONG_PTR)Message + FIELD_OFFSET(IO_ERROR_LOG_PACKET,
DumpData)));
-
- if (pRec == NULL)
- {
- DPRINT("LogfAllocAndBuildNewRecord failed!\n");
- return STATUS_NO_MEMORY;
- }
-
- DPRINT("RecSize = %d\n", RecSize);
-
- DPRINT("\n --- EVENTLOG RECORD ---\n");
- PRINT_RECORD(pRec);
- DPRINT("\n");
+
+ 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, pRec, RecSize);
+ Status = LogfWriteRecord(SystemLog, LogBuffer, RecSize);
if (!NT_SUCCESS(Status))
{
DPRINT1("ERROR writing to event log `%S' (Status
0x%08lx)\n",
SystemLog->LogName, Status);
}
}
-
- LogfFreeRecord(pRec);
+ else
+ {
+ DPRINT1("\n--- EVENTLOG RECORD ---\n");
+ PRINT_RECORD(LogBuffer);
+ DPRINT1("\n");
+ }
+
+ LogfFreeRecord(LogBuffer);
}
}
Modified: trunk/reactos/base/services/eventlog/rpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/eventlog/rpc…
==============================================================================
--- trunk/reactos/base/services/eventlog/rpc.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/eventlog/rpc.c [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -586,6 +586,7 @@
{
NTSTATUS Status;
PLOGHANDLE pLogHandle;
+ UNICODE_STRING LocalSourceName, LocalComputerName;
PEVENTLOGRECORD LogBuffer;
USHORT i;
SIZE_T RecSize;
@@ -655,21 +656,32 @@
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,
- (SourceName && SourceName->Buffer)
- ? SourceName->Buffer
- : pLogHandle->szName,
- ComputerName->Buffer,
+ &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))
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -5,6 +5,7 @@
* PURPOSE: Internal header for the I/O Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
*/
+
#include "ntdddisk.h"
//
@@ -331,16 +332,6 @@
PDRIVER_OBJECT DriverObject;
LARGE_INTEGER TimeStamp;
} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
-
-//
-// Event Log LPC Message
-//
-typedef struct _ELF_API_MSG
-{
- PORT_MESSAGE h;
- ULONG Unknown[2];
- IO_ERROR_LOG_MESSAGE IoErrorMessage;
-} ELF_API_MSG, *PELF_API_MSG;
//
// To simplify matters, the kernel is made to support both the checked and free
Modified: trunk/reactos/ntoskrnl/io/iomgr/error.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/error.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/error.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/error.c [iso-8859-1] Mon Nov 7 13:29:09 2016
@@ -6,9 +6,12 @@
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
* Eric Kohl
*/
+
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
+#include <subsys/iolog/iolog.h>
+
#define NDEBUG
#include <debug.h>
@@ -22,6 +25,7 @@
/* GLOBALS *******************************************************************/
+#define IOP_MAXIMUM_LOG_SIZE (100 * PAGE_SIZE)
LONG IopTotalLogSize;
LIST_ENTRY IopErrorLogListHead;
KSPIN_LOCK IopLogListLock;
@@ -105,16 +109,23 @@
NTAPI
IopConnectLogPort(VOID)
{
- UNICODE_STRING PortName = RTL_CONSTANT_STRING(L"\\ErrorLogPort");
NTSTATUS Status;
+ UNICODE_STRING PortName = RTL_CONSTANT_STRING(ELF_PORT_NAME);
+ SECURITY_QUALITY_OF_SERVICE SecurityQos;
/* Make sure we're not already connected */
if (IopLogPortConnected) return TRUE;
+
+ /* Setup the QoS structure */
+ SecurityQos.Length = sizeof(SecurityQos);
+ SecurityQos.ImpersonationLevel = SecurityIdentification;
+ SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+ SecurityQos.EffectiveOnly = TRUE;
/* Connect the port */
Status = ZwConnectPort(&IopLogPort,
&PortName,
- NULL,
+ &SecurityQos,
NULL,
NULL,
NULL,
@@ -136,6 +147,9 @@
NTAPI
IopLogWorker(IN PVOID Parameter)
{
+#define IO_ERROR_OBJECT_NAMES_LENGTH 100
+
+ NTSTATUS Status;
PELF_API_MSG Message;
PIO_ERROR_LOG_MESSAGE ErrorMessage;
PLIST_ENTRY ListEntry;
@@ -144,22 +158,24 @@
PCHAR StringBuffer;
ULONG RemainingLength;
PDRIVER_OBJECT DriverObject;
- ULONG DriverNameLength = 0, DeviceNameLength;
- UNICODE_STRING DriverNameString;
- NTSTATUS Status;
- UCHAR Buffer[256];
+ PWCHAR NameString;
+ ULONG DriverNameLength, DeviceNameLength;
+ UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + IO_ERROR_OBJECT_NAMES_LENGTH];
POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
- POBJECT_NAME_INFORMATION PoolObjectNameInfo = NULL;
+ POBJECT_NAME_INFORMATION PoolObjectNameInfo;
ULONG ReturnedLength, MessageLength;
+ ULONG ExtraStringLength;
PWCHAR p;
- ULONG ExtraStringLength;
+
PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Parameter);
/* Connect to the port */
if (!IopConnectLogPort()) return;
/* Allocate the message */
- Message = ExAllocatePool(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH);
+ Message = ExAllocatePoolWithTag(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH, TAG_IO);
if (!Message)
{
/* Couldn't allocate, try again */
@@ -167,10 +183,8 @@
return;
}
- /* Copy the message */
- RtlZeroMemory(Message, sizeof(ELF_API_MSG));
-
- /* Get the actual I/O Structure */
+ /* Zero out the message and get the actual I/O structure */
+ RtlZeroMemory(Message, sizeof(*Message));
ErrorMessage = &Message->IoErrorMessage;
/* Start loop */
@@ -225,21 +239,28 @@
IO_ERROR_LOG_MESSAGE_LENGTH -
(ULONG_PTR)StringBuffer);
+ NameString = NULL;
+ DriverNameLength = 0; DeviceNameLength = 0;
+ PoolObjectNameInfo = NULL;
+ ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
+
/* Now check if there is a driver object */
DriverObject = LogEntry->DriverObject;
if (DriverObject)
{
- /* Check if the driver has a name */
+ /* Check if the driver has a name, and use it if so */
if (DriverObject->DriverName.Buffer)
{
- /* Use its name */
- DriverNameString.Buffer = DriverObject->DriverName.Buffer;
+ NameString = DriverObject->DriverName.Buffer;
DriverNameLength = DriverObject->DriverName.Length;
}
else
- DriverNameString.Buffer = NULL;
-
- /* Check if there isn't a valid name*/
+ {
+ NameString = NULL;
+ DriverNameLength = 0;
+ }
+
+ /* Check if there isn't a valid name */
if (!DriverNameLength)
{
/* Query the name directly */
@@ -247,30 +268,35 @@
ObjectNameInfo,
sizeof(Buffer),
&ReturnedLength);
- if (!(NT_SUCCESS(Status)) || !(ObjectNameInfo->Name.Length))
+ if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
{
/* We don't have a name */
DriverNameLength = 0;
}
+ else
+ {
+ NameString = ObjectNameInfo->Name.Buffer;
+ DriverNameLength = ObjectNameInfo->Name.Length;
+ }
}
}
else
{
/* Use default name */
- DriverNameString.Buffer = L"Application Popup";
- DriverNameLength = (ULONG)wcslen(DriverNameString.Buffer) * sizeof(WCHAR);
- }
-
- /* Check if we have a driver name by here */
+ NameString = L"Application Popup";
+ DriverNameLength = (ULONG)wcslen(NameString) * sizeof(WCHAR);
+ }
+
+ /* Check if we have a driver name */
if (DriverNameLength)
{
/* Skip to the end of the driver's name */
- p = &DriverNameString.Buffer[DriverNameLength / sizeof(WCHAR)];
+ p = &NameString[DriverNameLength / sizeof(WCHAR)];
/* Now we'll walk backwards and assume the minimum size */
DriverNameLength = sizeof(WCHAR);
p--;
- while ((*p != L'\\') && (p != DriverNameString.Buffer))
+ while ((*p != L'\\') && (p != NameString))
{
/* No backslash found, keep going */
p--;
@@ -285,8 +311,9 @@
}
/*
- * Now make sure that the driver name fits in our buffer, minus 3
- * NULL chars, and copy the name in our string buffer
+ * Now make sure that the driver name fits in the buffer, minus
+ * 3 NULL chars (driver name, device name, and remaining strings),
+ * and copy the driver name in the string buffer.
*/
DriverNameLength = min(DriverNameLength,
RemainingLength - 3 * sizeof(UNICODE_NULL));
@@ -294,29 +321,29 @@
}
/* Null-terminate the driver name */
- *((PWSTR)(StringBuffer + DriverNameLength)) = L'\0';
+ *((PWSTR)(StringBuffer + DriverNameLength)) = UNICODE_NULL;
DriverNameLength += sizeof(WCHAR);
/* Go to the next string buffer position */
StringBuffer += DriverNameLength;
RemainingLength -= DriverNameLength;
- /* Update the string offset and check if we have a device object */
- ErrorMessage->EntryData.StringOffset = (USHORT)
- ((ULONG_PTR)StringBuffer -
- (ULONG_PTR)ErrorMessage);
+ /* Update the string offset */
+ ErrorMessage->EntryData.StringOffset =
+ (USHORT)((ULONG_PTR)StringBuffer - (ULONG_PTR)ErrorMessage);
+
+ /* Check if we have a device object */
if (LogEntry->DeviceObject)
{
/* We do, query its name */
Status = ObQueryNameString(LogEntry->DeviceObject,
ObjectNameInfo,
- sizeof(Buffer),
+ sizeof(Buffer) - DriverNameLength,
&ReturnedLength);
if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
{
/* Setup an empty name */
- ObjectNameInfo->Name.Length = 0;
- ObjectNameInfo->Name.Buffer = L"";
+ RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, L"",
0);
/* Check if we failed because our buffer wasn't large enough */
if (Status == STATUS_INFO_LENGTH_MISMATCH)
@@ -337,39 +364,40 @@
{
/* Success, update the information */
ObjectNameInfo->Name.Length =
- 100 - (USHORT)DriverNameLength;
+ IO_ERROR_OBJECT_NAMES_LENGTH - (USHORT)DriverNameLength;
}
}
}
}
+
+ NameString = ObjectNameInfo->Name.Buffer;
+ DeviceNameLength = ObjectNameInfo->Name.Length;
}
else
{
/* No device object, setup an empty name */
- ObjectNameInfo->Name.Length = 0;
- ObjectNameInfo->Name.Buffer = L"";
+ NameString = L"";
+ DeviceNameLength = 0;
}
/*
- * Now make sure that the device name fits in our buffer, minus 2
- * NULL chars, and copy the name in our string buffer
+ * Now make sure that the device name fits in the buffer, minus
+ * 2 NULL chars (device name, and remaining strings), and copy
+ * the device name in the string buffer.
*/
- DeviceNameLength = min(ObjectNameInfo->Name.Length,
+ DeviceNameLength = min(DeviceNameLength,
RemainingLength - 2 * sizeof(UNICODE_NULL));
- RtlCopyMemory(StringBuffer,
- ObjectNameInfo->Name.Buffer,
- DeviceNameLength);
+ RtlCopyMemory(StringBuffer, NameString, DeviceNameLength);
/* Null-terminate the device name */
- *((PWSTR)(StringBuffer + DeviceNameLength)) = L'\0';
+ *((PWSTR)(StringBuffer + DeviceNameLength)) = UNICODE_NULL;
DeviceNameLength += sizeof(WCHAR);
/* Free the buffer if we had one */
if (PoolObjectNameInfo)
{
- ExFreePool(PoolObjectNameInfo);
+ ExFreePoolWithTag(PoolObjectNameInfo, TAG_IO);
PoolObjectNameInfo = NULL;
- ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
}
/* Go to the next string buffer position */
@@ -384,6 +412,9 @@
ExtraStringLength = LogEntry->Size -
sizeof(ERROR_LOG_ENTRY) -
Packet->StringOffset;
+
+ /* Round up the length */
+ ExtraStringLength = ROUND_UP(ExtraStringLength, sizeof(WCHAR));
/* Make sure that the extra strings fit in our buffer */
if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
@@ -399,50 +430,58 @@
ExtraStringLength);
/* Null-terminate them */
- *((PWSTR)(StringBuffer + ExtraStringLength)) = L'\0';
+ *((PWSTR)(StringBuffer + ExtraStringLength)) = UNICODE_NULL;
}
/* Set the driver name length */
ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;
- /* Update the message length to include the device and driver names */
- MessageLength += DeviceNameLength + DriverNameLength;
+ /* Update the message length to include the driver and device names */
+ MessageLength += DriverNameLength + DeviceNameLength;
ErrorMessage->Size = (USHORT)MessageLength;
- /* Now update it again, internally, for the size of the actual LPC */
+ /* Now update it again for the size of the actual LPC */
MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
FIELD_OFFSET(ELF_API_MSG, Unknown[0]));
/* Set the total and data lengths */
- Message->h.u1.s1.TotalLength = (USHORT)(sizeof(PORT_MESSAGE) +
- MessageLength);
- Message->h.u1.s1.DataLength = (USHORT)(MessageLength);
+ Message->Header.u1.s1.TotalLength =
+ (USHORT)(sizeof(PORT_MESSAGE) + MessageLength);
+ Message->Header.u1.s1.DataLength = (USHORT)MessageLength;
/* Send the message */
- Status = NtRequestPort(IopLogPort, (PPORT_MESSAGE)Message);
+ Status = ZwRequestPort(IopLogPort, &Message->Header);
if (!NT_SUCCESS(Status))
{
- /* Requeue log message and restart the worker */
- ExInterlockedInsertTailList(&IopErrorLogListHead,
+ /*
+ * An error happened while sending the message on the port.
+ * Close the port, requeue the log message on top of the list
+ * and restart the worker.
+ */
+ ZwClose(IopLogPort);
+ IopLogPortConnected = FALSE;
+
+ ExInterlockedInsertHeadList(&IopErrorLogListHead,
&LogEntry->ListEntry,
&IopLogListLock);
- IopLogWorkerRunning = FALSE;
+
IopRestartLogWorker();
break;
}
- /* Dereference the device object */
+ /* NOTE: The following is basically 'IoFreeErrorLogEntry(Packet)' */
+
+ /* Dereference both objects */
if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
- if (DriverObject) ObDereferenceObject(LogEntry->DriverObject);
-
- /* Update size */
- InterlockedExchangeAdd(&IopTotalLogSize,
- -(LONG)(LogEntry->Size -
- sizeof(ERROR_LOG_ENTRY)));
+ if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
+
+ /* Decrease the total allocation size and free the entry */
+ InterlockedExchangeAdd(&IopTotalLogSize, -(LONG)LogEntry->Size);
+ ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
}
/* Free the LPC Message */
- ExFreePool(Message);
+ ExFreePoolWithTag(Message, TAG_IO);
}
VOID
@@ -495,17 +534,15 @@
/* Make sure we have an object */
if (!IoObject) return NULL;
- /* Check if we're past our buffer */
- if (IopTotalLogSize > PAGE_SIZE) return NULL;
-
/* Check if this is a device object or driver object */
- if (((PDEVICE_OBJECT)IoObject)->Type == IO_TYPE_DEVICE)
+ DeviceObject = (PDEVICE_OBJECT)IoObject;
+ if (DeviceObject->Type == IO_TYPE_DEVICE)
{
/* It's a device, get the driver */
- DeviceObject = (PDEVICE_OBJECT)IoObject;
+ // DeviceObject = (PDEVICE_OBJECT)IoObject;
DriverObject = DeviceObject->DriverObject;
}
- else if (((PDEVICE_OBJECT)IoObject)->Type == IO_TYPE_DRIVER)
+ else if (DeviceObject->Type == IO_TYPE_DRIVER)
{
/* It's a driver, so we don't have a device */
DeviceObject = NULL;
@@ -516,6 +553,21 @@
/* Fail */
return NULL;
}
+
+ /* Check if we're past our buffer */
+ // FIXME/TODO: Perform the checks by taking into account EntrySize.
+ if (IopTotalLogSize > IOP_MAXIMUM_LOG_SIZE) return NULL;
+
+ /* Check whether the size is too small or too large */
+ if ((EntrySize < sizeof(IO_ERROR_LOG_PACKET)) ||
+ (EntrySize > ERROR_LOG_MAXIMUM_SIZE))
+ {
+ /* Fail */
+ return NULL;
+ }
+
+ /* Round up the size */
+ EntrySize = ROUND_UP(EntrySize, sizeof(PVOID));
/* Calculate the total size and allocate it */
LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize;
@@ -529,12 +581,12 @@
if (DriverObject) ObReferenceObject(DriverObject);
/* Update log size */
- InterlockedExchangeAdd(&IopTotalLogSize, EntrySize);
+ InterlockedExchangeAdd(&IopTotalLogSize, LogEntrySize);
/* Clear the entry and set it up */
- RtlZeroMemory(LogEntry, EntrySize);
+ RtlZeroMemory(LogEntry, LogEntrySize);
LogEntry->Type = IO_TYPE_ERROR_LOG;
- LogEntry->Size = EntrySize;
+ LogEntry->Size = LogEntrySize;
LogEntry->DeviceObject = DeviceObject;
LogEntry->DriverObject = DriverObject;
@@ -551,7 +603,7 @@
{
PERROR_LOG_ENTRY LogEntry;
- /* Make sure there's an entry */
+ /* Make sure there is an entry */
if (!ElEntry) return;
/* Get the actual header */
@@ -561,10 +613,9 @@
if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
- /* Decrease total allocation size and free the entry */
- InterlockedExchangeAdd(&IopTotalLogSize,
- -(LONG)(LogEntry->Size - sizeof(ERROR_LOG_ENTRY)));
- ExFreePool(LogEntry);
+ /* Decrease the total allocation size and free the entry */
+ InterlockedExchangeAdd(&IopTotalLogSize, -(LONG)LogEntry->Size);
+ ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
}
/*
@@ -577,9 +628,11 @@
PERROR_LOG_ENTRY LogEntry;
KIRQL Irql;
- /* Get the main header */
- LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry -
- sizeof(ERROR_LOG_ENTRY));
+ /* Make sure there is an entry */
+ if (!ElEntry) return;
+
+ /* Get the actual header */
+ LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
/* Get time stamp */
KeQuerySystemTime(&LogEntry->TimeStamp);
@@ -591,14 +644,10 @@
/* Check if the worker is running */
if (!IopLogWorkerRunning)
{
-#if 0
/* It's not, initialize it and queue it */
- ExInitializeWorkItem(&IopErrorLogWorkItem,
- IopLogWorker,
- &IopErrorLogWorkItem);
+ IopLogWorkerRunning = TRUE;
+ ExInitializeWorkItem(&IopErrorLogWorkItem, IopLogWorker, NULL);
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
- IopLogWorkerRunning = TRUE;
-#endif
}
/* Release the lock and return */
Added: trunk/reactos/sdk/include/reactos/subsys/iolog/iolog.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/reactos/subsys…
==============================================================================
--- trunk/reactos/sdk/include/reactos/subsys/iolog/iolog.h (added)
+++ trunk/reactos/sdk/include/reactos/subsys/iolog/iolog.h [iso-8859-1] Mon Nov 7
13:29:09 2016
@@ -0,0 +1,31 @@
+/*
+ * PROJECT: ReactOS EventLog Service
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: include/reactos/subsys/iolog/iolog.h
+ * PURPOSE: EventLog LPC API definitions
+ */
+
+#ifndef _IOLOG_H
+#define _IOLOG_H
+
+#pragma once
+
+// #include <iotypes.h> // For IO_ERROR_LOG_MESSAGE and associated
+
+#define ELF_PORT_NAME L"\\ErrorLogPort"
+
+typedef struct _ELF_API_MSG
+{
+ PORT_MESSAGE Header;
+ ULONG Unknown[2]; // FIXME
+ IO_ERROR_LOG_MESSAGE IoErrorMessage;
+} ELF_API_MSG, *PELF_API_MSG;
+
+/*
+ * NOTE: The maximum data size sent to the EventLog LPC port
+ * is equal to: PORT_MAXIMUM_MESSAGE_LENGTH == 0x100 .
+ */
+
+#endif // _IOLOG_H
+
+/* EOF */
Propchange: trunk/reactos/sdk/include/reactos/subsys/iolog/iolog.h
------------------------------------------------------------------------------
svn:eol-style = native