ReactOS Fundraising Campaign 2012
 
€ 3,303 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

eventlog.c

Go 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 doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.