a136bc6e7fb5042de14314e0e6cbfd719ca5b164
[reactos.git] / reactos / services / eventlog / logport.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: services/eventlog/logport.c
23 * PURPOSE: Event logger service
24 * PROGRAMMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include <windows.h>
30 #define NTOS_MODE_USER
31 #include <ndk/ntndk.h>
32
33 #include "eventlog.h"
34
35 #define NDEBUG
36 #include <debug.h>
37
38
39 /* GLOBALS ******************************************************************/
40
41 HANDLE PortThreadHandle = NULL;
42 HANDLE ConnectPortHandle = NULL;
43 HANDLE MessagePortHandle = NULL;
44
45
46 /* FUNCTIONS ****************************************************************/
47
48 static NTSTATUS
49 InitLogPort(VOID)
50 {
51 OBJECT_ATTRIBUTES ObjectAttributes;
52 UNICODE_STRING PortName;
53 PORT_MESSAGE Request;
54 NTSTATUS Status;
55
56 ConnectPortHandle = NULL;
57 MessagePortHandle = NULL;
58
59 RtlInitUnicodeString(&PortName,
60 L"\\ErrorLogPort");
61 InitializeObjectAttributes(&ObjectAttributes,
62 &PortName,
63 0,
64 NULL,
65 NULL);
66
67 Status = NtCreatePort(&ConnectPortHandle,
68 &ObjectAttributes,
69 0,
70 0x100,
71 0x2000);
72 if (!NT_SUCCESS(Status))
73 {
74 DPRINT1("NtCreatePort() failed (Status %lx)\n", Status);
75 goto ByeBye;
76 }
77
78 Status = NtListenPort(ConnectPortHandle,
79 &Request);
80 if (!NT_SUCCESS(Status))
81 {
82 DPRINT1("NtListenPort() failed (Status %lx)\n", Status);
83 goto ByeBye;
84 }
85
86 Status = NtAcceptConnectPort(&MessagePortHandle,
87 ConnectPortHandle,
88 NULL,
89 TRUE,
90 NULL,
91 NULL);
92 if (!NT_SUCCESS(Status))
93 {
94 DPRINT1("NtAcceptConnectPort() failed (Status %lx)\n", Status);
95 goto ByeBye;
96 }
97
98 Status = NtCompleteConnectPort(MessagePortHandle);
99 if (!NT_SUCCESS(Status))
100 {
101 DPRINT1("NtCompleteConnectPort() failed (Status %lx)\n", Status);
102 goto ByeBye;
103 }
104
105 ByeBye:
106 if (!NT_SUCCESS(Status))
107 {
108 if (ConnectPortHandle != NULL)
109 NtClose(ConnectPortHandle);
110
111 if (MessagePortHandle != NULL)
112 NtClose(MessagePortHandle);
113 }
114
115 return Status;
116 }
117
118 static NTSTATUS
119 ProcessPortMessage(VOID)
120 {
121 IO_ERROR_LPC Request;
122 PIO_ERROR_LOG_MESSAGE Message;
123 //#ifndef NDEBUG
124 ULONG i;
125 PWSTR p;
126 //#endif
127 NTSTATUS Status;
128
129
130 DPRINT1("ProcessPortMessage() called\n");
131
132 Status = STATUS_SUCCESS;
133
134 while (TRUE)
135 {
136 Status = NtReplyWaitReceivePort(MessagePortHandle,
137 0,
138 NULL,
139 &Request.Header);
140 if (!NT_SUCCESS(Status))
141 {
142 DPRINT1("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
143 break;
144 }
145
146 DPRINT("Received message\n");
147
148 if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED)
149 {
150 DPRINT("Port closed\n");
151
152 return STATUS_SUCCESS;
153 }
154 if (Request.Header.u2.s2.Type == LPC_REQUEST)
155 {
156 DPRINT("Received request\n");
157
158 }
159 else if (Request.Header.u2.s2.Type == LPC_DATAGRAM)
160 {
161 DPRINT("Received datagram\n");
162
163
164 Message = (PIO_ERROR_LOG_MESSAGE)&Request.Message;
165
166 DPRINT("Message->Type %hx\n", Message->Type);
167 DPRINT("Message->Size %hu\n", Message->Size);
168
169 //#ifndef NDEBUG
170 DbgPrint("\n Error mesage:\n");
171 DbgPrint("Error code: %lx\n", Message->EntryData.ErrorCode);
172 DbgPrint("Retry count: %u\n", Message->EntryData.RetryCount);
173 DbgPrint("Sequence number: %lu\n", Message->EntryData.SequenceNumber);
174
175 if (Message->DriverNameLength != 0)
176 {
177 DbgPrint("Driver name: %.*S\n",
178 Message->DriverNameLength / sizeof(WCHAR),
179 (PWCHAR)((ULONG_PTR)Message + Message->DriverNameOffset));
180 }
181
182 if (Message->EntryData.NumberOfStrings != 0)
183 {
184 p = (PWSTR)((ULONG_PTR)&Message->EntryData + Message->EntryData.StringOffset);
185 for (i = 0; i < Message->EntryData.NumberOfStrings; i++)
186 {
187 DbgPrint("String %lu: %S\n", i, p);
188 p += wcslen(p) + 1;
189 }
190 DbgPrint("\n");
191 }
192
193 //#endif
194
195 /* FIXME: Enqueue message */
196
197 }
198 }
199
200 return Status;
201 }
202
203
204 static NTSTATUS STDCALL
205 PortThreadRoutine(PVOID Param)
206 {
207 NTSTATUS Status = STATUS_SUCCESS;
208
209 Status = InitLogPort();
210 if (!NT_SUCCESS(Status))
211 return Status;
212
213 while (NT_SUCCESS(Status))
214 {
215 Status = ProcessPortMessage();
216 }
217
218 if (ConnectPortHandle != NULL)
219 NtClose(ConnectPortHandle);
220
221 if (MessagePortHandle != NULL)
222 NtClose(MessagePortHandle);
223
224 return Status;
225 }
226
227
228 BOOL
229 StartPortThread(VOID)
230 {
231 DWORD ThreadId;
232
233 PortThreadHandle = CreateThread(NULL,
234 0x1000,
235 (LPTHREAD_START_ROUTINE)PortThreadRoutine,
236 NULL,
237 0,
238 &ThreadId);
239
240 return (PortThreadHandle != NULL);
241 }
242
243 /* EOF */