2 * PROJECT: ReactOS EventLog Service
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/services/eventlog/logport.c
5 * PURPOSE: LPC Port Interface support
6 * COPYRIGHT: Copyright 2002 Eric Kohl
7 * Copyright 2005 Saveliy Tretiakov
10 /* INCLUDES *****************************************************************/
13 #include <ndk/lpcfuncs.h>
14 #include <iolog/iolog.h>
19 /* GLOBALS ******************************************************************/
21 static HANDLE ConnectPortHandle
= NULL
;
22 static HANDLE MessagePortHandle
= NULL
;
25 /* FUNCTIONS ****************************************************************/
27 NTSTATUS WINAPI
PortThreadRoutine(PVOID Param
)
29 NTSTATUS Status
= STATUS_SUCCESS
;
31 Status
= InitLogPort();
32 if (!NT_SUCCESS(Status
))
35 while (NT_SUCCESS(Status
))
36 Status
= ProcessPortMessage();
38 if (ConnectPortHandle
!= NULL
)
39 NtClose(ConnectPortHandle
);
41 if (MessagePortHandle
!= NULL
)
42 NtClose(MessagePortHandle
);
47 NTSTATUS
InitLogPort(VOID
)
50 UNICODE_STRING PortName
= RTL_CONSTANT_STRING(ELF_PORT_NAME
);
51 OBJECT_ATTRIBUTES ObjectAttributes
;
54 ConnectPortHandle
= NULL
;
55 MessagePortHandle
= NULL
;
57 InitializeObjectAttributes(&ObjectAttributes
, &PortName
, 0, NULL
, NULL
);
59 Status
= NtCreatePort(&ConnectPortHandle
,
62 PORT_MAXIMUM_MESSAGE_LENGTH
, // IO_ERROR_LOG_MESSAGE_LENGTH,
64 if (!NT_SUCCESS(Status
))
66 DPRINT1("NtCreatePort() failed (Status %lx)\n", Status
);
70 Status
= NtListenPort(ConnectPortHandle
, &Request
);
71 if (!NT_SUCCESS(Status
))
73 DPRINT1("NtListenPort() failed (Status %lx)\n", Status
);
77 Status
= NtAcceptConnectPort(&MessagePortHandle
, ConnectPortHandle
,
78 &Request
, TRUE
, NULL
, NULL
);
79 if (!NT_SUCCESS(Status
))
81 DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status
);
85 Status
= NtCompleteConnectPort(MessagePortHandle
);
86 if (!NT_SUCCESS(Status
))
88 DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status
);
93 if (!NT_SUCCESS(Status
))
95 if (ConnectPortHandle
!= NULL
)
96 NtClose(ConnectPortHandle
);
98 if (MessagePortHandle
!= NULL
)
99 NtClose(MessagePortHandle
);
104 NTSTATUS
ProcessPortMessage(VOID
)
107 PLOGFILE SystemLog
= NULL
;
108 UCHAR Buffer
[PORT_MAXIMUM_MESSAGE_LENGTH
]; // IO_ERROR_LOG_MESSAGE_LENGTH
109 PELF_API_MSG Message
= (PELF_API_MSG
)Buffer
;
110 PIO_ERROR_LOG_MESSAGE ErrorMessage
;
111 PEVENTLOGRECORD LogBuffer
;
115 UNICODE_STRING SourceName
, ComputerName
;
116 DWORD dwComputerNameLength
;
117 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
119 DPRINT("ProcessPortMessage() called\n");
121 SystemLog
= LogfListItemByName(L
"System");
125 Status
= NtReplyWaitReceivePort(MessagePortHandle
,
130 if (!NT_SUCCESS(Status
))
132 DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status
);
136 DPRINT("Received message\n");
138 if (Message
->Header
.u2
.s2
.Type
== LPC_PORT_CLOSED
)
140 DPRINT("Port closed\n");
141 return STATUS_SUCCESS
;
144 if (Message
->Header
.u2
.s2
.Type
== LPC_REQUEST
)
146 DPRINT("Received request\n");
148 else if (Message
->Header
.u2
.s2
.Type
== LPC_DATAGRAM
)
150 DPRINT("Received datagram (0x%x, 0x%x)\n",
151 Message
->Unknown
[0], Message
->Unknown
[1]);
152 ErrorMessage
= &Message
->IoErrorMessage
;
154 // ASSERT(ErrorMessage->Type == IO_TYPE_ERROR_MESSAGE);
156 RtlInitEmptyUnicodeString(&SourceName
, NULL
, 0);
157 if (ErrorMessage
->DriverNameLength
> sizeof(UNICODE_NULL
)) // DriverNameLength counts NULL-terminator
159 SourceName
.Buffer
= (PWSTR
)((ULONG_PTR
)ErrorMessage
+ ErrorMessage
->DriverNameOffset
);
160 SourceName
.MaximumLength
= ErrorMessage
->DriverNameLength
;
161 SourceName
.Length
= SourceName
.MaximumLength
- sizeof(UNICODE_NULL
);
164 dwComputerNameLength
= ARRAYSIZE(szComputerName
);
165 if (!GetComputerNameW(szComputerName
, &dwComputerNameLength
))
166 szComputerName
[0] = L
'\0';
168 RtlInitUnicodeString(&ComputerName
, szComputerName
);
170 RtlTimeToSecondsSince1970(&ErrorMessage
->TimeStamp
, &Time
);
172 /* Set the event type based on the error code severity */
173 EventType
= (USHORT
)(ErrorMessage
->EntryData
.ErrorCode
>> 30);
174 if (EventType
== STATUS_SEVERITY_SUCCESS
)
176 EventType
= EVENTLOG_SUCCESS
;
178 else if (EventType
== STATUS_SEVERITY_INFORMATIONAL
) // NT_INFORMATION
180 EventType
= EVENTLOG_INFORMATION_TYPE
;
182 else if (EventType
== STATUS_SEVERITY_WARNING
) // NT_WARNING
184 EventType
= EVENTLOG_WARNING_TYPE
;
186 else if (EventType
== STATUS_SEVERITY_ERROR
) // NT_ERROR
188 EventType
= EVENTLOG_ERROR_TYPE
;
192 /* Unknown severity, set to error */
193 EventType
= EVENTLOG_ERROR_TYPE
;
197 * The data being saved consists of the IO_ERROR_LOG_PACKET structure
198 * header, plus the additional raw data from the driver.
200 LogBuffer
= LogfAllocAndBuildNewRecord(
204 ErrorMessage
->EntryData
.EventCategory
,
205 ErrorMessage
->EntryData
.ErrorCode
,
210 ErrorMessage
->EntryData
.NumberOfStrings
,
211 (PWSTR
)((ULONG_PTR
)ErrorMessage
+
212 ErrorMessage
->EntryData
.StringOffset
),
213 FIELD_OFFSET(IO_ERROR_LOG_PACKET
, DumpData
) +
214 ErrorMessage
->EntryData
.DumpDataSize
,
215 (PVOID
)&ErrorMessage
->EntryData
);
216 if (LogBuffer
== NULL
)
218 DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
219 // return STATUS_NO_MEMORY;
223 if (!onLiveCD
&& SystemLog
)
225 Status
= LogfWriteRecord(SystemLog
, LogBuffer
, RecSize
);
226 if (!NT_SUCCESS(Status
))
228 DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
229 SystemLog
->LogName
, Status
);
234 DPRINT1("\n--- EVENTLOG RECORD ---\n");
235 PRINT_RECORD(LogBuffer
);
239 LogfFreeRecord(LogBuffer
);