Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeneventlog.cGo to the documentation of this file.00001 /* 00002 * PROJECT: ReactOS kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: services/eventlog/eventlog.c 00005 * PURPOSE: Event logging service 00006 * COPYRIGHT: Copyright 2002 Eric Kohl 00007 * Copyright 2005 Saveliy Tretiakov 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #include "eventlog.h" 00013 00014 /* GLOBALS ******************************************************************/ 00015 00016 static VOID CALLBACK ServiceMain(DWORD, LPWSTR *); 00017 static WCHAR ServiceName[] = L"EventLog"; 00018 static SERVICE_TABLE_ENTRYW ServiceTable[2] = 00019 { 00020 { ServiceName, ServiceMain }, 00021 { NULL, NULL } 00022 }; 00023 00024 SERVICE_STATUS ServiceStatus; 00025 SERVICE_STATUS_HANDLE ServiceStatusHandle; 00026 00027 BOOL onLiveCD = FALSE; // On livecd events will go to debug output only 00028 HANDLE MyHeap = NULL; 00029 00030 /* FUNCTIONS ****************************************************************/ 00031 00032 static VOID 00033 UpdateServiceStatus(DWORD dwState) 00034 { 00035 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 00036 ServiceStatus.dwCurrentState = dwState; 00037 ServiceStatus.dwControlsAccepted = 0; 00038 ServiceStatus.dwWin32ExitCode = 0; 00039 ServiceStatus.dwServiceSpecificExitCode = 0; 00040 ServiceStatus.dwCheckPoint = 0; 00041 00042 if (dwState == SERVICE_START_PENDING || 00043 dwState == SERVICE_STOP_PENDING || 00044 dwState == SERVICE_PAUSE_PENDING || 00045 dwState == SERVICE_CONTINUE_PENDING) 00046 ServiceStatus.dwWaitHint = 10000; 00047 else 00048 ServiceStatus.dwWaitHint = 0; 00049 00050 SetServiceStatus(ServiceStatusHandle, 00051 &ServiceStatus); 00052 } 00053 00054 static DWORD WINAPI 00055 ServiceControlHandler(DWORD dwControl, 00056 DWORD dwEventType, 00057 LPVOID lpEventData, 00058 LPVOID lpContext) 00059 { 00060 DPRINT("ServiceControlHandler() called\n"); 00061 00062 switch (dwControl) 00063 { 00064 case SERVICE_CONTROL_STOP: 00065 DPRINT(" SERVICE_CONTROL_STOP received\n"); 00066 00067 LogfReportEvent(EVENTLOG_INFORMATION_TYPE, 00068 0, 00069 EVENT_EventlogStopped, 0, NULL, 0, NULL); 00070 00071 00072 /* Stop listening to incoming RPC messages */ 00073 RpcMgmtStopServerListening(NULL); 00074 UpdateServiceStatus(SERVICE_STOPPED); 00075 return ERROR_SUCCESS; 00076 00077 case SERVICE_CONTROL_PAUSE: 00078 DPRINT(" SERVICE_CONTROL_PAUSE received\n"); 00079 UpdateServiceStatus(SERVICE_PAUSED); 00080 return ERROR_SUCCESS; 00081 00082 case SERVICE_CONTROL_CONTINUE: 00083 DPRINT(" SERVICE_CONTROL_CONTINUE received\n"); 00084 UpdateServiceStatus(SERVICE_RUNNING); 00085 return ERROR_SUCCESS; 00086 00087 case SERVICE_CONTROL_INTERROGATE: 00088 DPRINT(" SERVICE_CONTROL_INTERROGATE received\n"); 00089 SetServiceStatus(ServiceStatusHandle, 00090 &ServiceStatus); 00091 return ERROR_SUCCESS; 00092 00093 case SERVICE_CONTROL_SHUTDOWN: 00094 DPRINT(" SERVICE_CONTROL_SHUTDOWN received\n"); 00095 00096 LogfReportEvent(EVENTLOG_INFORMATION_TYPE, 00097 0, 00098 EVENT_EventlogStopped, 0, NULL, 0, NULL); 00099 00100 UpdateServiceStatus(SERVICE_STOPPED); 00101 return ERROR_SUCCESS; 00102 00103 default : 00104 DPRINT1(" Control %lu received\n"); 00105 return ERROR_CALL_NOT_IMPLEMENTED; 00106 } 00107 } 00108 00109 00110 static DWORD 00111 ServiceInit(VOID) 00112 { 00113 HANDLE hThread; 00114 00115 hThread = CreateThread(NULL, 00116 0, 00117 (LPTHREAD_START_ROUTINE) 00118 PortThreadRoutine, 00119 NULL, 00120 0, 00121 NULL); 00122 00123 if (!hThread) 00124 { 00125 DPRINT("Can't create PortThread\n"); 00126 return GetLastError(); 00127 } 00128 else 00129 CloseHandle(hThread); 00130 00131 hThread = CreateThread(NULL, 00132 0, 00133 (LPTHREAD_START_ROUTINE) 00134 RpcThreadRoutine, 00135 NULL, 00136 0, 00137 NULL); 00138 00139 if (!hThread) 00140 { 00141 DPRINT("Can't create RpcThread\n"); 00142 return GetLastError(); 00143 } 00144 else 00145 CloseHandle(hThread); 00146 00147 return ERROR_SUCCESS; 00148 } 00149 00150 00151 static VOID 00152 ReportProductInfoEvent(VOID) 00153 { 00154 OSVERSIONINFOW versionInfo; 00155 WCHAR szBuffer[512]; 00156 DWORD dwLength; 00157 HKEY hKey; 00158 DWORD dwValueLength; 00159 DWORD dwType; 00160 LONG lResult = ERROR_SUCCESS; 00161 00162 ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO)); 00163 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00164 00165 /* Get version information */ 00166 if (!GetVersionExW(&versionInfo)) 00167 return; 00168 00169 ZeroMemory(szBuffer, 512 * sizeof(WCHAR)); 00170 00171 /* Write version into the buffer */ 00172 dwLength = swprintf(szBuffer, 00173 L"%lu.%lu", 00174 versionInfo.dwMajorVersion, 00175 versionInfo.dwMinorVersion) + 1; 00176 00177 /* Write build number into the buffer */ 00178 dwLength += swprintf(&szBuffer[dwLength], 00179 L"%lu", 00180 versionInfo.dwBuildNumber) + 1; 00181 00182 /* Write service pack info into the buffer */ 00183 wcscpy(&szBuffer[dwLength], versionInfo.szCSDVersion); 00184 dwLength += wcslen(versionInfo.szCSDVersion) + 1; 00185 00186 /* Read 'CurrentType' from the registry and write it into the buffer */ 00187 lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00188 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 00189 0, 00190 KEY_QUERY_VALUE, 00191 &hKey); 00192 if (lResult == ERROR_SUCCESS) 00193 { 00194 dwValueLength = 512 - dwLength; 00195 lResult = RegQueryValueEx(hKey, 00196 L"CurrentType", 00197 NULL, 00198 &dwType, 00199 (LPBYTE)&szBuffer[dwLength], 00200 &dwValueLength); 00201 00202 RegCloseKey(hKey); 00203 } 00204 00205 /* Log the product information */ 00206 LogfReportEvent(EVENTLOG_INFORMATION_TYPE, 00207 0, 00208 EVENT_EventLogProductInfo, 00209 4, 00210 szBuffer, 00211 0, 00212 NULL); 00213 } 00214 00215 00216 static VOID CALLBACK 00217 ServiceMain(DWORD argc, 00218 LPWSTR *argv) 00219 { 00220 DWORD dwError; 00221 00222 UNREFERENCED_PARAMETER(argc); 00223 UNREFERENCED_PARAMETER(argv); 00224 00225 DPRINT("ServiceMain() called\n"); 00226 00227 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, 00228 ServiceControlHandler, 00229 NULL); 00230 if (!ServiceStatusHandle) 00231 { 00232 dwError = GetLastError(); 00233 DPRINT1("RegisterServiceCtrlHandlerW() failed! (Error %lu)\n", dwError); 00234 return; 00235 } 00236 00237 UpdateServiceStatus(SERVICE_START_PENDING); 00238 00239 dwError = ServiceInit(); 00240 if (dwError != ERROR_SUCCESS) 00241 { 00242 DPRINT("Service stopped (dwError: %lu\n", dwError); 00243 UpdateServiceStatus(SERVICE_START_PENDING); 00244 } 00245 else 00246 { 00247 DPRINT("Service started\n"); 00248 UpdateServiceStatus(SERVICE_RUNNING); 00249 00250 ReportProductInfoEvent(); 00251 00252 LogfReportEvent(EVENTLOG_INFORMATION_TYPE, 00253 0, 00254 EVENT_EventlogStarted, 00255 0, 00256 NULL, 00257 0, 00258 NULL); 00259 } 00260 00261 DPRINT("ServiceMain() done\n"); 00262 } 00263 00264 00265 PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName) 00266 { 00267 DWORD MaxValueLen, ValueLen, Type, ExpandedLen; 00268 WCHAR *Buf = NULL, *Expanded = NULL; 00269 LONG Result; 00270 PLOGFILE pLogf = NULL; 00271 UNICODE_STRING FileName; 00272 NTSTATUS Status; 00273 00274 DPRINT("LoadLogFile: %S\n", LogName); 00275 00276 RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, 00277 NULL, NULL, &MaxValueLen, NULL, NULL); 00278 00279 Buf = HeapAlloc(MyHeap, 0, MaxValueLen); 00280 if (!Buf) 00281 { 00282 DPRINT1("Can't allocate heap!\n"); 00283 return NULL; 00284 } 00285 00286 ValueLen = MaxValueLen; 00287 00288 Result = RegQueryValueEx(hKey, 00289 L"File", 00290 NULL, 00291 &Type, 00292 (LPBYTE) Buf, 00293 &ValueLen); 00294 if (Result != ERROR_SUCCESS) 00295 { 00296 DPRINT1("RegQueryValueEx failed: %d\n", GetLastError()); 00297 HeapFree(MyHeap, 0, Buf); 00298 return NULL; 00299 } 00300 00301 if (Type != REG_EXPAND_SZ && Type != REG_SZ) 00302 { 00303 DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type); 00304 HeapFree(MyHeap, 0, Buf); 00305 return NULL; 00306 } 00307 00308 ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0); 00309 Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR)); 00310 if (!Expanded) 00311 { 00312 DPRINT1("Can't allocate heap!\n"); 00313 HeapFree(MyHeap, 0, Buf); 00314 return NULL; 00315 } 00316 00317 ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen); 00318 00319 if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName, 00320 NULL, NULL)) 00321 { 00322 DPRINT1("Can't convert path!\n"); 00323 HeapFree(MyHeap, 0, Expanded); 00324 HeapFree(MyHeap, 0, Buf); 00325 return NULL; 00326 } 00327 00328 DPRINT("%S -> %S\n", Buf, Expanded); 00329 00330 Status = LogfCreate(&pLogf, LogName, &FileName, TRUE, FALSE); 00331 if (!NT_SUCCESS(Status)) 00332 { 00333 DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status); 00334 } 00335 00336 HeapFree(MyHeap, 0, Buf); 00337 HeapFree(MyHeap, 0, Expanded); 00338 return pLogf; 00339 } 00340 00341 BOOL LoadLogFiles(HKEY eventlogKey) 00342 { 00343 LONG result; 00344 DWORD MaxLognameLen, LognameLen; 00345 WCHAR *Buf = NULL; 00346 INT i; 00347 PLOGFILE pLogFile; 00348 00349 RegQueryInfoKey(eventlogKey, 00350 NULL, NULL, NULL, NULL, 00351 &MaxLognameLen, 00352 NULL, NULL, NULL, NULL, NULL, NULL); 00353 00354 MaxLognameLen++; 00355 00356 Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR)); 00357 00358 if (!Buf) 00359 { 00360 DPRINT1("Error: can't allocate heap!\n"); 00361 return FALSE; 00362 } 00363 00364 i = 0; 00365 LognameLen = MaxLognameLen; 00366 00367 while (RegEnumKeyEx(eventlogKey, 00368 i, 00369 Buf, 00370 &LognameLen, 00371 NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 00372 { 00373 HKEY SubKey; 00374 00375 DPRINT("%S\n", Buf); 00376 00377 result = RegOpenKeyEx(eventlogKey, Buf, 0, KEY_ALL_ACCESS, &SubKey); 00378 if (result != ERROR_SUCCESS) 00379 { 00380 DPRINT1("Failed to open %S key.\n", Buf); 00381 HeapFree(MyHeap, 0, Buf); 00382 return FALSE; 00383 } 00384 00385 pLogFile = LoadLogFile(SubKey, Buf); 00386 if (pLogFile != NULL) 00387 { 00388 DPRINT("Loaded %S\n", Buf); 00389 LoadEventSources(SubKey, pLogFile); 00390 } 00391 else 00392 { 00393 DPRINT1("Failed to load %S\n", Buf); 00394 } 00395 00396 RegCloseKey(SubKey); 00397 LognameLen = MaxLognameLen; 00398 i++; 00399 } 00400 00401 HeapFree(MyHeap, 0, Buf); 00402 return TRUE; 00403 } 00404 00405 INT wmain() 00406 { 00407 WCHAR LogPath[MAX_PATH]; 00408 INT RetCode = 0; 00409 LONG result; 00410 HKEY elogKey; 00411 00412 LogfListInitialize(); 00413 InitEventSourceList(); 00414 00415 MyHeap = HeapCreate(0, 1024 * 256, 0); 00416 00417 if (!MyHeap) 00418 { 00419 DPRINT1("FATAL ERROR, can't create heap.\n"); 00420 RetCode = 1; 00421 goto bye_bye; 00422 } 00423 00424 GetWindowsDirectory(LogPath, MAX_PATH); 00425 00426 if (GetDriveType(LogPath) == DRIVE_CDROM) 00427 { 00428 DPRINT("LiveCD detected\n"); 00429 onLiveCD = TRUE; 00430 } 00431 else 00432 { 00433 result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00434 L"SYSTEM\\CurrentControlSet\\Services\\EventLog", 00435 0, 00436 KEY_ALL_ACCESS, 00437 &elogKey); 00438 00439 if (result != ERROR_SUCCESS) 00440 { 00441 DPRINT1("Fatal error: can't open eventlog registry key.\n"); 00442 RetCode = 1; 00443 goto bye_bye; 00444 } 00445 00446 LoadLogFiles(elogKey); 00447 } 00448 00449 StartServiceCtrlDispatcher(ServiceTable); 00450 00451 bye_bye: 00452 LogfCloseAll(); 00453 00454 if (MyHeap) 00455 HeapDestroy(MyHeap); 00456 00457 return RetCode; 00458 } 00459 00460 VOID EventTimeToSystemTime(DWORD EventTime, SYSTEMTIME * pSystemTime) 00461 { 00462 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 }; 00463 FILETIME ftLocal; 00464 union 00465 { 00466 FILETIME ft; 00467 ULONGLONG ll; 00468 } u1970, uUCT; 00469 00470 uUCT.ft.dwHighDateTime = 0; 00471 uUCT.ft.dwLowDateTime = EventTime; 00472 SystemTimeToFileTime(&st1970, &u1970.ft); 00473 uUCT.ll = uUCT.ll * 10000000 + u1970.ll; 00474 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal); 00475 FileTimeToSystemTime(&ftLocal, pSystemTime); 00476 } 00477 00478 VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime) 00479 { 00480 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 }; 00481 union 00482 { 00483 FILETIME ft; 00484 ULONGLONG ll; 00485 } Time, u1970; 00486 00487 SystemTimeToFileTime(pSystemTime, &Time.ft); 00488 SystemTimeToFileTime(&st1970, &u1970.ft); 00489 *pEventTime = (DWORD)((Time.ll - u1970.ll) / 10000000ull); 00490 } 00491 00492 VOID PRINT_HEADER(PEVENTLOGHEADER header) 00493 { 00494 DPRINT("HeaderSize = %d\n", header->HeaderSize); 00495 DPRINT("Signature = 0x%x\n", header->Signature); 00496 DPRINT("MajorVersion = %d\n", header->MajorVersion); 00497 DPRINT("MinorVersion = %d\n", header->MinorVersion); 00498 DPRINT("StartOffset = %d\n", header->StartOffset); 00499 DPRINT("EndOffset = 0x%x\n", header->EndOffset); 00500 DPRINT("CurrentRecordNumber = %d\n", header->CurrentRecordNumber); 00501 DPRINT("OldestRecordNumber = %d\n", header->OldestRecordNumber); 00502 DPRINT("MaxSize = 0x%x\n", header->MaxSize); 00503 DPRINT("Retention = 0x%x\n", header->Retention); 00504 DPRINT("EndHeaderSize = %d\n", header->EndHeaderSize); 00505 DPRINT("Flags: "); 00506 if (header->Flags & ELF_LOGFILE_HEADER_DIRTY) DPRINT("ELF_LOGFILE_HEADER_DIRTY"); 00507 if (header->Flags & ELF_LOGFILE_HEADER_WRAP) DPRINT("| ELF_LOGFILE_HEADER_WRAP "); 00508 if (header->Flags & ELF_LOGFILE_LOGFULL_WRITTEN) DPRINT("| ELF_LOGFILE_LOGFULL_WRITTEN "); 00509 if (header->Flags & ELF_LOGFILE_ARCHIVE_SET) DPRINT("| ELF_LOGFILE_ARCHIVE_SET "); 00510 DPRINT("\n"); 00511 } 00512 00513 VOID PRINT_RECORD(PEVENTLOGRECORD pRec) 00514 { 00515 UINT i; 00516 WCHAR *str; 00517 SYSTEMTIME time; 00518 00519 DPRINT("Length = %d\n", pRec->Length); 00520 DPRINT("Reserved = 0x%x\n", pRec->Reserved); 00521 DPRINT("RecordNumber = %d\n", pRec->RecordNumber); 00522 00523 EventTimeToSystemTime(pRec->TimeGenerated, &time); 00524 DPRINT("TimeGenerated = %d.%d.%d %d:%d:%d\n", 00525 time.wDay, time.wMonth, time.wYear, 00526 time.wHour, time.wMinute, time.wSecond); 00527 00528 EventTimeToSystemTime(pRec->TimeWritten, &time); 00529 DPRINT("TimeWritten = %d.%d.%d %d:%d:%d\n", 00530 time.wDay, time.wMonth, time.wYear, 00531 time.wHour, time.wMinute, time.wSecond); 00532 00533 DPRINT("EventID = %d\n", pRec->EventID); 00534 00535 switch (pRec->EventType) 00536 { 00537 case EVENTLOG_ERROR_TYPE: 00538 DPRINT("EventType = EVENTLOG_ERROR_TYPE\n"); 00539 break; 00540 case EVENTLOG_WARNING_TYPE: 00541 DPRINT("EventType = EVENTLOG_WARNING_TYPE\n"); 00542 break; 00543 case EVENTLOG_INFORMATION_TYPE: 00544 DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n"); 00545 break; 00546 case EVENTLOG_AUDIT_SUCCESS: 00547 DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n"); 00548 break; 00549 case EVENTLOG_AUDIT_FAILURE: 00550 DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n"); 00551 break; 00552 default: 00553 DPRINT("EventType = %d\n", pRec->EventType); 00554 } 00555 00556 DPRINT("NumStrings = %d\n", pRec->NumStrings); 00557 DPRINT("EventCategory = %d\n", pRec->EventCategory); 00558 DPRINT("ReservedFlags = 0x%x\n", pRec->ReservedFlags); 00559 DPRINT("ClosingRecordNumber = %d\n", pRec->ClosingRecordNumber); 00560 DPRINT("StringOffset = %d\n", pRec->StringOffset); 00561 DPRINT("UserSidLength = %d\n", pRec->UserSidLength); 00562 DPRINT("UserSidOffset = %d\n", pRec->UserSidOffset); 00563 DPRINT("DataLength = %d\n", pRec->DataLength); 00564 DPRINT("DataOffset = %d\n", pRec->DataOffset); 00565 00566 DPRINT("SourceName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD))); 00567 00568 i = (lstrlenW((WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD))) + 1) * 00569 sizeof(WCHAR); 00570 00571 DPRINT("ComputerName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD) + i)); 00572 00573 if (pRec->StringOffset < pRec->Length && pRec->NumStrings) 00574 { 00575 DPRINT("Strings:\n"); 00576 str = (WCHAR *) (((PBYTE) pRec) + pRec->StringOffset); 00577 for (i = 0; i < pRec->NumStrings; i++) 00578 { 00579 DPRINT("[%d] %S\n", i, str); 00580 str = str + lstrlenW(str) + 1; 00581 } 00582 } 00583 00584 DPRINT("Length2 = %d\n", *(PDWORD) (((PBYTE) pRec) + pRec->Length - 4)); 00585 } Generated on Tue May 15 04:39:44 2012 for ReactOS by
1.6.3
|