[EVENTLOG]
[reactos.git] / reactos / base / services / eventlog / logport.c
1 /*
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
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "eventlog.h"
13 #include <ndk/lpcfuncs.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* GLOBALS ******************************************************************/
19
20 static HANDLE ConnectPortHandle = NULL;
21 static HANDLE MessagePortHandle = NULL;
22 extern BOOL onLiveCD;
23
24 /* FUNCTIONS ****************************************************************/
25
26 NTSTATUS WINAPI PortThreadRoutine(PVOID Param)
27 {
28 NTSTATUS Status = STATUS_SUCCESS;
29
30 Status = InitLogPort();
31 if (!NT_SUCCESS(Status))
32 return Status;
33
34 while (NT_SUCCESS(Status))
35 Status = ProcessPortMessage();
36
37 if (ConnectPortHandle != NULL)
38 NtClose(ConnectPortHandle);
39
40 if (MessagePortHandle != NULL)
41 NtClose(MessagePortHandle);
42
43 return Status;
44 }
45
46 NTSTATUS InitLogPort(VOID)
47 {
48 NTSTATUS Status;
49 UNICODE_STRING PortName;
50 OBJECT_ATTRIBUTES ObjectAttributes;
51 PORT_MESSAGE Request;
52
53 ConnectPortHandle = NULL;
54 MessagePortHandle = NULL;
55
56 RtlInitUnicodeString(&PortName, L"\\ErrorLogPort");
57 InitializeObjectAttributes(&ObjectAttributes, &PortName, 0, NULL, NULL);
58
59 Status = NtCreatePort(&ConnectPortHandle,
60 &ObjectAttributes,
61 0,
62 0x100,
63 0x2000);
64
65 if (!NT_SUCCESS(Status))
66 {
67 DPRINT1("NtCreatePort() failed (Status %lx)\n", Status);
68 goto ByeBye;
69 }
70
71 Status = NtListenPort(ConnectPortHandle, &Request);
72 if (!NT_SUCCESS(Status))
73 {
74 DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
75 goto ByeBye;
76 }
77
78 Status = NtAcceptConnectPort(&MessagePortHandle, ConnectPortHandle,
79 NULL, TRUE, NULL, NULL);
80 if (!NT_SUCCESS(Status))
81 {
82 DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
83 goto ByeBye;
84 }
85
86 Status = NtCompleteConnectPort(MessagePortHandle);
87 if (!NT_SUCCESS(Status))
88 {
89 DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status);
90 goto ByeBye;
91 }
92
93 ByeBye:
94 if (!NT_SUCCESS(Status))
95 {
96 if (ConnectPortHandle != NULL)
97 NtClose(ConnectPortHandle);
98
99 if (MessagePortHandle != NULL)
100 NtClose(MessagePortHandle);
101 }
102 return Status;
103 }
104
105 NTSTATUS ProcessPortMessage(VOID)
106 {
107 NTSTATUS Status;
108 IO_ERROR_LPC Request;
109 PIO_ERROR_LOG_MESSAGE Message;
110 ULONG Time;
111 PEVENTLOGRECORD pRec;
112 SIZE_T RecSize;
113 PLOGFILE SystemLog = NULL;
114 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
115 DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
116
117 DPRINT("ProcessPortMessage() called\n");
118
119 SystemLog = LogfListItemByName(L"System");
120
121 while (TRUE)
122 {
123 Status = NtReplyWaitReceivePort(MessagePortHandle,
124 0,
125 NULL,
126 &Request.Header);
127
128 if (!NT_SUCCESS(Status))
129 {
130 DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
131 break;
132 }
133
134 DPRINT("Received message\n");
135
136 if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED)
137 {
138 DPRINT("Port closed\n");
139 return STATUS_SUCCESS;
140 }
141
142 if (Request.Header.u2.s2.Type == LPC_REQUEST)
143 {
144 DPRINT("Received request\n");
145 }
146 else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
147 {
148 DPRINT("Received datagram\n");
149 // Message = (PIO_ERROR_LOG_MESSAGE)&Request.Message;
150 Message = &Request.Message;
151
152 if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
153 {
154 szComputerName[0] = L'\0';
155 }
156
157 RtlTimeToSecondsSince1970(&Message->TimeStamp, &Time);
158
159 // TODO: Log more information??
160
161 pRec = LogfAllocAndBuildNewRecord(
162 &RecSize,
163 Time,
164 Message->Type,
165 Message->EntryData.EventCategory,
166 Message->EntryData.ErrorCode,
167 (PWSTR)((ULONG_PTR)Message + Message->DriverNameOffset), // FIXME: Use DriverNameLength too!
168 szComputerName,
169 0,
170 NULL,
171 Message->EntryData.NumberOfStrings,
172 (PWSTR)((ULONG_PTR)Message + Message->EntryData.StringOffset),
173 Message->EntryData.DumpDataSize,
174 (PVOID)((ULONG_PTR)Message + FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData)));
175
176 if (pRec == NULL)
177 {
178 DPRINT("LogfAllocAndBuildNewRecord failed!\n");
179 return STATUS_NO_MEMORY;
180 }
181
182 DPRINT("RecSize = %d\n", RecSize);
183
184 DPRINT("\n --- EVENTLOG RECORD ---\n");
185 PRINT_RECORD(pRec);
186 DPRINT("\n");
187
188 if (!onLiveCD && SystemLog)
189 {
190 Status = LogfWriteRecord(SystemLog, RecSize, pRec);
191 if (!NT_SUCCESS(Status))
192 {
193 DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
194 SystemLog->FileName, Status);
195 }
196 }
197
198 LogfFreeRecord(pRec);
199 }
200 }
201
202 return Status;
203 }