xref: /reactos/base/services/tcpsvcs/log.c (revision 527f2f90)
1 /*
2  * PROJECT:     ReactOS simple TCP/IP services
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        /base/services/tcpsvcs/log.c
5  * PURPOSE:     Logging functionality for the service
6  * COPYRIGHT:   Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include "tcpsvcs.h"
11 
12 #define DEBUG
13 
14 static LPWSTR lpEventSource = L"tcpsvcs";
15 static LPCWSTR lpLogFileName = L"C:\\tcpsvcs_log.log";
16 static HANDLE hLogFile = NULL;
17 
18 static OVERLAPPED olWrite;
19 
20 
21 // needs work
22 static VOID
23 LogToEventLog(LPCWSTR lpMsg,
24               DWORD errNum,
25               DWORD exitCode,
26               UINT flags)
27 {
28     HANDLE hEventLog;
29 
30     hEventLog = RegisterEventSourceW(NULL, lpEventSource);
31     if (hEventLog)
32     {
33         ReportEventW(hEventLog,
34                      (flags & LOG_ERROR) ? EVENTLOG_ERROR_TYPE : EVENTLOG_SUCCESS,
35                      0,
36                      0,
37                      NULL,
38                      1,
39                      0,
40                      &lpMsg,
41                      NULL);
42 
43         CloseEventLog(hEventLog);
44     }
45 }
46 
47 static BOOL
48 OpenLogFile()
49 {
50     hLogFile = CreateFileW(lpLogFileName,
51                            GENERIC_WRITE,
52                            FILE_SHARE_READ,
53                            NULL,
54                            OPEN_ALWAYS,
55                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
56                            NULL);
57     if (hLogFile  == INVALID_HANDLE_VALUE)
58     {
59         hLogFile = NULL;
60         return FALSE;
61     }
62 
63     return TRUE;
64 }
65 
66 static VOID
67 LogToFile(LPCWSTR lpMsg,
68           DWORD errNum,
69           DWORD exitCode,
70           UINT flags)
71 {
72     LPWSTR lpFullMsg = NULL;
73     DWORD msgLen;
74 
75     msgLen = wcslen(lpMsg) + 1;
76 
77     if (flags & LOG_ERROR)
78     {
79         LPVOID lpSysMsg;
80         DWORD eMsgLen;
81 
82         eMsgLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
83                                  NULL,
84                                  errNum,
85                                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
86                                  (LPTSTR)&lpSysMsg,
87                                  0,
88                                  NULL);
89 
90         msgLen = msgLen + eMsgLen + 40;
91 
92         lpFullMsg = HeapAlloc(GetProcessHeap(),
93                               0,
94                               msgLen * sizeof(TCHAR));
95         if (lpFullMsg)
96         {
97             _snwprintf(lpFullMsg,
98                        msgLen,
99                        L"%s : %s\tErrNum = %lu ExitCode = %lu\r\n",
100                        lpMsg,
101                        lpSysMsg,
102                        errNum,
103                        exitCode);
104         }
105 
106         LocalFree(lpSysMsg);
107 
108     }
109     else
110     {
111         msgLen += 2;
112 
113         lpFullMsg = HeapAlloc(GetProcessHeap(),
114                               0,
115                               msgLen * sizeof(TCHAR));
116         if (lpFullMsg)
117         {
118             _snwprintf(lpFullMsg,
119                        msgLen,
120                       L"%s\r\n",
121                       lpMsg);
122         }
123     }
124 
125     if (lpFullMsg)
126     {
127         DWORD bytesWritten;
128         DWORD dwRet;
129         BOOL bRet;
130 
131         bRet = WriteFile(hLogFile,
132                          lpFullMsg,
133                          wcslen(lpFullMsg) * sizeof(WCHAR),
134                          &bytesWritten,
135                          &olWrite);
136         if (!bRet)
137         {
138             if (GetLastError() != ERROR_IO_PENDING)
139             {
140                 bRet = FALSE;
141             }
142             else
143             {
144                 // Write is pending
145                 dwRet = WaitForSingleObject(olWrite.hEvent, INFINITE);
146 
147                  switch (dwRet)
148                  {
149                     // event has been signaled
150                     case WAIT_OBJECT_0:
151                     {
152                          bRet = GetOverlappedResult(hLogFile,
153                                                     &olWrite,
154                                                     &bytesWritten,
155                                                     FALSE);
156                          break;
157                     }
158 
159                     default:
160                          // An error has occurred in WaitForSingleObject.
161                          // This usually indicates a problem with the
162                          // OVERLAPPED structure's event handle.
163                          bRet = FALSE;
164                          break;
165                  }
166             }
167         }
168 
169         if (!bRet || bytesWritten == 0)
170         {
171             LogToEventLog(L"Failed to write to log file",
172                           GetLastError(),
173                           0,
174                           LOG_EVENTLOG | LOG_ERROR);
175         }
176 
177         HeapFree(GetProcessHeap(),
178                  0,
179                  lpFullMsg);
180     }
181 
182     if (exitCode > 0)
183         ExitProcess(exitCode);
184 }
185 
186 
187 
188 VOID
189 LogEvent(LPCWSTR lpMsg,
190          DWORD errNum,
191          DWORD exitCode,
192          UINT flags)
193 {
194 #ifdef DEBUG
195     if (flags & LOG_FILE || flags & LOG_ERROR)
196         LogToFile(lpMsg, errNum, exitCode, flags);
197 #endif
198     if (flags & LOG_EVENTLOG)
199         LogToEventLog(lpMsg, errNum, exitCode, flags);
200 }
201 
202 BOOL
203 InitLogging()
204 {
205 #ifdef DEBUG
206     BOOL bRet = FALSE;
207 
208     ZeroMemory(&olWrite, sizeof(OVERLAPPED));
209     olWrite.Offset = 0xFFFFFFFF;
210     olWrite.OffsetHigh = 0xFFFFFFFF;
211     olWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
212     if (olWrite.hEvent)
213     {
214         DeleteFileW(lpLogFileName);
215 
216         if (OpenLogFile())
217         {
218             WCHAR wcBom = 0xFEFF;
219             DWORD bytesWritten;
220 
221             bRet = WriteFile(hLogFile,
222                              &wcBom,
223                              sizeof(WCHAR),
224                              &bytesWritten,
225                              &olWrite);
226             if (!bRet)
227             {
228                 if (GetLastError() != ERROR_IO_PENDING)
229                 {
230                     LogToEventLog(L"Failed to write to log file",
231                                   GetLastError(),
232                                   0,
233                                   LOG_EVENTLOG | LOG_ERROR);
234                 }
235                 else
236                 {
237                     bRet = TRUE;
238                 }
239             }
240         }
241     }
242 
243     return bRet;
244 #else
245     return TRUE;
246 #endif
247 }
248 
249 VOID
250 UninitLogging()
251 {
252     if (hLogFile)
253     {
254         FlushFileBuffers(hLogFile);
255         CloseHandle(hLogFile);
256     }
257 
258     if (olWrite.hEvent)
259     {
260         CloseHandle(olWrite.hEvent);
261     }
262 }
263