- Merge aicom-network-fixes up to r36740
[reactos.git] / reactos / base / applications / mscutils / eventvwr / eventvwr.c
1 /*
2 * ReactOS Win32 Applications
3 * Copyright (C) 2007 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 : Event Log Viewer
22 * FILE : eventvwr.c
23 * PROGRAMMER: Marc Piulachs (marc.piulachs at codexchange [dot] net)
24 */
25
26 #include "eventvwr.h"
27 #include <windows.h> // Standard windows include file
28 #include <commctrl.h> // For ListView control APIs
29 #include <tchar.h> // For TCHAR and string functions.
30 #include <stdio.h>
31 #include <time.h>
32
33 #if _MSC_VER
34 #pragma warning(disable: 4996) // 'strdup' was declared deprecated
35 #define _CRT_SECURE_NO_DEPRECATE // all deprecated 'unsafe string functions
36 #endif
37
38 static const LPSTR EVENT_SOURCE_APPLICATION = "Application";
39 static const LPSTR EVENT_SOURCE_SECURITY = "Security";
40 static const LPSTR EVENT_SOURCE_SYSTEM = "System";
41 static const TCHAR szWindowClass[] = _T("EVENTVWR"); // the main window class name
42
43 //MessageFile message buffer size
44 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10
45 #define EVENT_MESSAGE_FILE_BUFFER 1024*10
46 #define EVENT_DLL_SEPARATOR ";"
47 #define EVENT_MESSAGE_FILE "EventMessageFile"
48 #define EVENT_CATEGORY_MESSAGE_FILE "CategoryMessageFile"
49 #define EVENT_PARAMETER_MESSAGE_FILE "ParameterMessageFile"
50
51 #define MAX_LOADSTRING 255
52
53 // Global Variables:
54 HINSTANCE hInst; // current instance
55 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
56
57 // Globals
58 HWND hwndMainWindow; // Main window
59 HWND hwndListView; // ListView control
60 HWND hwndStatus; // Status bar
61
62 LPTSTR lpSourceLogName = NULL;
63 LPTSTR lpComputerName = NULL;
64
65 // Forward declarations of functions included in this code module:
66 ATOM MyRegisterClass(HINSTANCE hInstance);
67 BOOL InitInstance(HINSTANCE, int);
68 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
69 INT_PTR CALLBACK About (HWND, UINT, WPARAM, LPARAM);
70 INT_PTR CALLBACK EventDetails (HWND, UINT, WPARAM, LPARAM);
71 static INT_PTR CALLBACK StatusMessageWindowProc (HWND, UINT, WPARAM, LPARAM);
72
73 int APIENTRY _tWinMain(HINSTANCE hInstance,
74 HINSTANCE hPrevInstance,
75 LPTSTR lpCmdLine,
76 int nCmdShow)
77 {
78 MSG msg;
79 HACCEL hAccelTable;
80 INITCOMMONCONTROLSEX iccx;
81
82 UNREFERENCED_PARAMETER(hPrevInstance);
83 UNREFERENCED_PARAMETER(lpCmdLine);
84
85 // Whenever any of the common controls are used in your app,
86 // you must call InitCommonControlsEx() to register the classes
87 // for those controls.
88 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
89 iccx.dwICC = ICC_LISTVIEW_CLASSES;
90 InitCommonControlsEx(&iccx);
91
92 // Initialize global strings
93 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
94 MyRegisterClass(hInstance);
95
96 // Perform application initialization:
97 if (!InitInstance (hInstance, nCmdShow))
98 {
99 return FALSE;
100 }
101
102 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_EVENTVWR));
103
104 // Main message loop:
105 while (GetMessage(&msg, NULL, 0, 0))
106 {
107 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
108 {
109 TranslateMessage(&msg);
110 DispatchMessage(&msg);
111 }
112 }
113
114 return (int) msg.wParam;
115 }
116
117 VOID EventTimeToSystemTime (DWORD EventTime, SYSTEMTIME *pSystemTime)
118 {
119 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
120 FILETIME ftLocal;
121 union {
122 FILETIME ft;
123 ULONGLONG ll;
124 } u1970, uUCT;
125
126 uUCT.ft.dwHighDateTime = 0;
127 uUCT.ft.dwLowDateTime = EventTime;
128 SystemTimeToFileTime(&st1970, &u1970.ft);
129 uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
130 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
131 FileTimeToSystemTime(&ftLocal, pSystemTime);
132 }
133
134 void
135 TrimNulls ( LPSTR s )
136 {
137 char *c;
138
139 if ( s != (char *) NULL )
140 {
141 c = s + strlen ( s ) - 1;
142 while ( c >= s && isspace ( *c ) )
143 --c;
144 *++c = '\0';
145 }
146 }
147
148 BOOL GetEventMessageFileDLL(
149 IN LPCTSTR lpLogName,
150 IN LPCTSTR SourceName,
151 IN LPCTSTR EntryName,
152 OUT LPSTR ExpandedName)
153 {
154 DWORD dwSize;
155 BYTE szModuleName[MAX_PATH];
156 TCHAR szKeyName[MAX_PATH];
157 HKEY hAppKey = NULL;
158 HKEY hSourceKey = NULL;
159 BOOL bReturn = FALSE; // Return
160
161 _tcscpy(szKeyName, TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog"));
162 _tcscat(szKeyName, _T("\\"));
163 _tcscat(szKeyName, lpLogName);
164
165 if (RegOpenKeyEx(
166 HKEY_LOCAL_MACHINE,
167 szKeyName,
168 0,
169 KEY_READ,
170 &hAppKey) == ERROR_SUCCESS)
171 {
172 if (RegOpenKeyEx(
173 hAppKey,
174 SourceName,
175 0,
176 KEY_READ,
177 &hSourceKey) == ERROR_SUCCESS)
178 {
179 dwSize = MAX_PATH;
180 if (RegQueryValueEx(
181 hSourceKey,
182 EntryName,
183 NULL,
184 NULL,
185 (LPBYTE)szModuleName,
186 &dwSize) == ERROR_SUCCESS)
187 {
188 // Returns a string containing the requested substituted environment variable.
189 ExpandEnvironmentStrings ((LPCTSTR)szModuleName, ExpandedName, MAX_PATH);
190
191 // Succesfull
192 bReturn = TRUE;
193 }
194 }
195 }
196 else
197 {
198 MessageBox (NULL ,
199 _TEXT("Registry access failed!") ,
200 _TEXT("Event Log") ,
201 MB_OK | MB_ICONINFORMATION);
202 }
203
204 if (hSourceKey != NULL)
205 RegCloseKey(hSourceKey);
206
207 if (hAppKey != NULL)
208 RegCloseKey(hAppKey);
209
210 return bReturn;
211 }
212
213 BOOL GetEventCategory(
214 IN LPCTSTR KeyName,
215 IN LPCTSTR SourceName,
216 IN EVENTLOGRECORD *pevlr,
217 OUT LPTSTR CategoryName)
218 {
219 HANDLE hLibrary = NULL;
220 TCHAR szMessageDLL[MAX_PATH];
221 LPVOID lpMsgBuf = NULL;
222
223 if(GetEventMessageFileDLL (KeyName, SourceName, EVENT_CATEGORY_MESSAGE_FILE , szMessageDLL))
224 {
225 hLibrary = LoadLibraryEx(
226 szMessageDLL,
227 NULL,
228 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
229
230 if(hLibrary != NULL)
231 {
232 // Retrieve the message string.
233 if(FormatMessage(
234 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
235 hLibrary,
236 pevlr->EventCategory,
237 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
238 (LPTSTR)&lpMsgBuf,
239 EVENT_MESSAGE_FILE_BUFFER,
240 NULL) != 0)
241 {
242 if (lpMsgBuf)
243 {
244 //Trim the string
245 TrimNulls ((LPSTR)lpMsgBuf);
246
247 // Copy the category name
248 strcpy (CategoryName, (LPCTSTR)lpMsgBuf);
249 }
250 else
251 {
252 strcpy (CategoryName, (LPCTSTR)lpMsgBuf);
253 }
254 }else{
255 strcpy (CategoryName, "None");
256 }
257
258 if(hLibrary != NULL)
259 FreeLibrary(hLibrary);
260
261 // Free the buffer allocated by FormatMessage
262 if (lpMsgBuf)
263 LocalFree(lpMsgBuf);
264
265 return TRUE;
266 }
267 }
268
269 strcpy (CategoryName, "None");
270
271 return FALSE;
272 }
273
274 BOOL GetEventMessage(
275 IN LPCTSTR KeyName,
276 IN LPCTSTR SourceName,
277 IN EVENTLOGRECORD *pevlr,
278 OUT LPTSTR EventText)
279 {
280 DWORD i;
281 HANDLE hLibrary = NULL;
282 char SourceModuleName[1000];
283 char ParameterModuleName[1000];
284 LPTSTR lpMsgBuf = NULL;
285 TCHAR szStringIDNotFound[MAX_LOADSTRING];
286 LPTSTR szDll;
287 LPTSTR szMessage;
288 LPTSTR *szArguments;
289 BOOL bDone = FALSE;
290
291 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
292 if (GetEventMessageFileDLL (KeyName , SourceName, EVENT_MESSAGE_FILE , SourceModuleName))
293 {
294 // Get the event message
295 szMessage = (LPTSTR)((LPBYTE)pevlr + pevlr->StringOffset);
296
297 // Allocate space for parameters
298 szArguments = (LPTSTR*)malloc(sizeof(LPVOID)* pevlr->NumStrings);
299
300 for (i = 0; i < pevlr->NumStrings ; i++)
301 {
302 if (strstr(szMessage , "%%"))
303 {
304 if (GetEventMessageFileDLL (KeyName , SourceName, EVENT_PARAMETER_MESSAGE_FILE , ParameterModuleName))
305 {
306 //Not yet support for reading messages from parameter message DLL
307 }
308
309 szArguments[i] = szMessage;
310 szMessage += strlen(szMessage) + 1;
311 }
312 else
313 {
314 szArguments[i] = szMessage;
315 szMessage += strlen(szMessage) + 1;
316 }
317 }
318
319 szDll = strtok(SourceModuleName, EVENT_DLL_SEPARATOR);
320 while ((szDll != NULL) && (!bDone))
321 {
322 hLibrary = LoadLibraryEx(
323 szDll,
324 NULL,
325 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
326
327 if (hLibrary == NULL)
328 {
329 // The DLL could not be loaded try the next one (if any)
330 szDll = strtok (NULL, EVENT_DLL_SEPARATOR);
331 }
332 else
333 {
334 // Retrieve the message string.
335 if(FormatMessage(
336 FORMAT_MESSAGE_FROM_SYSTEM |
337 FORMAT_MESSAGE_ALLOCATE_BUFFER |
338 FORMAT_MESSAGE_FROM_HMODULE |
339 FORMAT_MESSAGE_ARGUMENT_ARRAY,
340 hLibrary,
341 pevlr->EventID,
342 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
343 (LPTSTR)&lpMsgBuf,
344 0,
345 szArguments) == 0)
346 {
347 // We haven't found the string , get next DLL (if any)
348 szDll = strtok (NULL, EVENT_DLL_SEPARATOR);
349 }
350 else
351 {
352 if (lpMsgBuf)
353 {
354 // The ID was found and the message was formated
355 bDone = TRUE;
356
357 //Trim the string
358 TrimNulls ((LPSTR)lpMsgBuf);
359
360 // Copy the event text
361 strcpy (EventText ,lpMsgBuf);
362 }
363 }
364
365 FreeLibrary (hLibrary);
366 }
367 }
368
369 if (!bDone)
370 {
371 LoadString(hInst, IDC_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING);
372 wsprintf (EventText, szStringIDNotFound , (DWORD)(pevlr->EventID & 0xFFFF) , SourceName );
373 }
374
375 // No more dlls to try , return result
376 return bDone;
377 }
378
379 LoadString(hInst, IDC_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING);
380 wsprintf (EventText, szStringIDNotFound , (DWORD)(pevlr->EventID & 0xFFFF) , SourceName );
381
382 return FALSE;
383 }
384
385 VOID
386 GetEventType (WORD dwEventType, OUT LPSTR eventTypeText)
387 {
388 switch(dwEventType)
389 {
390 case EVENTLOG_ERROR_TYPE:
391 LoadString(hInst, IDC_EVENTLOG_ERROR_TYPE, eventTypeText, MAX_LOADSTRING);
392 break;
393 case EVENTLOG_WARNING_TYPE:
394 LoadString(hInst, IDC_EVENTLOG_WARNING_TYPE, eventTypeText, MAX_LOADSTRING);
395 break;
396 case EVENTLOG_INFORMATION_TYPE:
397 LoadString(hInst, IDC_EVENTLOG_INFORMATION_TYPE, eventTypeText, MAX_LOADSTRING);
398 break;
399 case EVENTLOG_AUDIT_SUCCESS:
400 LoadString(hInst, IDC_EVENTLOG_AUDIT_SUCCESS, eventTypeText, MAX_LOADSTRING);
401 break;
402 case EVENTLOG_AUDIT_FAILURE:
403 LoadString(hInst, IDC_EVENTLOG_AUDIT_FAILURE, eventTypeText, MAX_LOADSTRING);
404 break;
405 case EVENTLOG_SUCCESS:
406 LoadString(hInst, IDC_EVENTLOG_SUCCESS, eventTypeText, MAX_LOADSTRING);
407 break;
408 default:
409 LoadString(hInst, IDC_EVENTLOG_UNKNOWN_TYPE, eventTypeText, MAX_LOADSTRING);
410 break;
411 }
412 }
413
414 BOOL
415 GetEventUserName (EVENTLOGRECORD *pelr, OUT LPSTR pszUser)
416 {
417 PSID lpSid;
418 char szName[1024];
419 char szDomain[1024];
420 SID_NAME_USE peUse;
421 DWORD cbName = 1024;
422 DWORD cbDomain = 1024;
423
424 // Point to the SID.
425 lpSid = (PSID)((LPBYTE) pelr + pelr->UserSidOffset);
426
427 // User SID
428 if(pelr->UserSidLength > 0)
429 {
430 if (LookupAccountSid(
431 NULL,
432 lpSid,
433 szName,
434 &cbName,
435 szDomain,
436 &cbDomain,
437 &peUse))
438 {
439 strcpy (pszUser , szName);
440 return TRUE;
441 }
442 }
443
444 return FALSE;
445 }
446
447 static DWORD WINAPI
448 ShowStatusMessageThread(
449 IN LPVOID lpParameter)
450 {
451 HWND *phWnd = (HWND *)lpParameter;
452 HWND hWnd;
453 MSG Msg;
454
455 hWnd = CreateDialogParam(
456 hInst,
457 MAKEINTRESOURCE(IDD_PROGRESSBOX),
458 GetDesktopWindow(),
459 StatusMessageWindowProc,
460 (LPARAM)NULL);
461 if (!hWnd)
462 return 0;
463 *phWnd = hWnd;
464
465 ShowWindow(hWnd, SW_SHOW);
466
467 /* Message loop for the Status window */
468 while (GetMessage(&Msg, NULL, 0, 0))
469 {
470 TranslateMessage(&Msg);
471 DispatchMessage(&Msg);
472 }
473
474 return 0;
475 }
476
477 VOID QueryEventMessages (
478 LPTSTR lpMachineName ,
479 LPTSTR lpLogName)
480 {
481 HWND hwndDlg;
482 HANDLE hEventLog;
483 EVENTLOGRECORD *pevlr;
484 BYTE bBuffer[MAX_PATH];
485 DWORD dwRead, dwNeeded, dwThisRecord , dwTotalRecords , dwCurrentRecord = 1 , dwRecordsToRead = 0 , dwFlags;
486 LPSTR lpSourceName;
487 LPSTR lpComputerName;
488 LPSTR lpEventStr;
489 LPSTR lpData;
490 BOOL bResult = TRUE; // Read succeeded.
491
492 char szWindowTitle[MAX_PATH];
493 char szStatusText[MAX_PATH];
494 char szLocalDate[MAX_PATH];
495 char szLocalTime[MAX_PATH];
496 char szEventID[MAX_PATH];
497 char szEventTypeText[MAX_PATH];
498 char szCategoryID[MAX_PATH];
499 char szUsername[MAX_PATH];
500 char szEventText[EVENT_MESSAGE_FILE_BUFFER];
501 char szCategory[MAX_PATH];
502
503 SYSTEMTIME time;
504 LVITEM lviEventItem;
505
506 dwFlags = EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ;
507
508 lpSourceLogName = lpLogName;
509 lpComputerName = lpMachineName;
510
511 // Open the event log.
512 hEventLog = OpenEventLog(
513 lpMachineName,
514 lpLogName);
515
516 if (hEventLog == NULL)
517 {
518 MessageBox (NULL ,
519 _TEXT("Could not open the event log.") ,
520 _TEXT("Event Log") ,
521 MB_OK | MB_ICONINFORMATION);
522 return;
523 }
524
525 //Disable listview redraw
526 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);
527
528 // Clear the list view
529 (void)ListView_DeleteAllItems (hwndListView);
530
531 // Initialize the event record buffer.
532 pevlr = (EVENTLOGRECORD *)&bBuffer;
533
534 // Get the record number of the oldest event log record.
535 GetOldestEventLogRecord(hEventLog, &dwThisRecord);
536
537 // Get the total number of event log records.
538 GetNumberOfEventLogRecords (hEventLog , &dwTotalRecords);
539
540 //If we have at least 1000 records show the waiting dialog
541 if (dwTotalRecords > 1000)
542 {
543 CreateThread(
544 NULL,
545 0,
546 ShowStatusMessageThread,
547 (LPVOID)&hwndDlg,
548 0,
549 NULL);
550 }
551
552 while (dwCurrentRecord < dwTotalRecords)
553 {
554 pevlr = (EVENTLOGRECORD*)malloc(MAX_PATH);
555
556 bResult = ReadEventLog(
557 hEventLog, // Event log handle
558 dwFlags, // Sequential read
559 0, // Ignored for sequential read
560 pevlr, // Pointer to buffer
561 MAX_PATH, // Size of buffer
562 &dwRead, // Number of bytes read
563 &dwNeeded); // Bytes in the next record
564
565 if((!bResult) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER))
566 {
567 pevlr = (EVENTLOGRECORD*)malloc (dwNeeded);
568
569 ReadEventLog(
570 hEventLog, // event log handle
571 dwFlags, // read flags
572 0, // offset; default is 0
573 pevlr, // pointer to buffer
574 dwNeeded, // size of buffer
575 &dwRead, // number of bytes read
576 &dwNeeded); // bytes in next record
577 }
578
579 while (dwRead > 0)
580 {
581 strcpy (szUsername , "N/A");
582 strcpy (szEventText , "N/A");
583 strcpy (szCategory , "None");
584
585 // Get the event source name.
586 lpSourceName = (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));
587
588 // Get the computer name
589 lpComputerName = (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD) + lstrlen(lpSourceName) + 1);
590
591 // This ist the data section of the current event
592 lpData = (LPSTR) ((LPBYTE)pevlr + pevlr->DataOffset);
593
594 // This is the text of the current event
595 lpEventStr = (LPSTR) ((LPBYTE) pevlr + pevlr->StringOffset);
596
597 // Compute the event type
598 EventTimeToSystemTime(pevlr->TimeWritten, &time);
599
600 // Get the username that generated the event
601 GetEventUserName (pevlr , szUsername);
602
603 GetDateFormat( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, szLocalDate, MAX_PATH );
604 GetTimeFormat( LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, szLocalTime, MAX_PATH );
605
606 GetEventType (pevlr->EventType , szEventTypeText);
607 GetEventCategory (lpLogName , lpSourceName , pevlr , szCategory);
608
609 wsprintf (szEventID, "%u", (DWORD)(pevlr->EventID & 0xFFFF));
610 wsprintf (szCategoryID, "%u", (DWORD)(pevlr->EventCategory));
611
612 lviEventItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
613 lviEventItem.iItem = 0;
614 lviEventItem.iSubItem = 0;
615 lviEventItem.lParam = (LPARAM)pevlr;
616 lviEventItem.pszText = szEventTypeText;
617
618 switch(pevlr->EventType)
619 {
620 case EVENTLOG_ERROR_TYPE:
621 lviEventItem.iImage = 2;
622 break;
623 case EVENTLOG_AUDIT_FAILURE:
624 lviEventItem.iImage = 2;
625 break;
626 case EVENTLOG_WARNING_TYPE:
627 lviEventItem.iImage = 1;
628 break;
629 case EVENTLOG_INFORMATION_TYPE:
630 lviEventItem.iImage = 0;
631 break;
632 case EVENTLOG_AUDIT_SUCCESS:
633 lviEventItem.iImage = 0;
634 break;
635 case EVENTLOG_SUCCESS:
636 lviEventItem.iImage = 0;
637 break;
638 }
639
640 lviEventItem.iItem = ListView_InsertItem(hwndListView, &lviEventItem);
641
642 ListView_SetItemText(hwndListView, lviEventItem.iItem, 1, szLocalDate);
643 ListView_SetItemText(hwndListView, lviEventItem.iItem, 2, szLocalTime);
644 ListView_SetItemText(hwndListView, lviEventItem.iItem, 3, lpSourceName);
645 ListView_SetItemText(hwndListView, lviEventItem.iItem, 4, szCategory);
646 ListView_SetItemText(hwndListView, lviEventItem.iItem, 5, szEventID);
647 ListView_SetItemText(hwndListView, lviEventItem.iItem, 6, szUsername); //User
648 ListView_SetItemText(hwndListView, lviEventItem.iItem, 7, lpComputerName); //Computer
649 ListView_SetItemText(hwndListView, lviEventItem.iItem, 8, lpData); //Event Text
650
651 dwRead -= pevlr->Length;
652 pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length);
653 }
654
655 dwRecordsToRead--;
656 dwCurrentRecord++;
657
658 pevlr = (EVENTLOGRECORD *) &bBuffer;
659 }
660
661 //All events loaded
662 EndDialog(hwndDlg, 0);
663
664 wsprintf (szWindowTitle, "%s - %s Log on \\\\%s", szTitle , lpLogName , lpComputerName);
665 wsprintf (szStatusText, "%s has %d event(s)", lpLogName , dwTotalRecords);
666
667 //Update the status bar
668 SendMessage (hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)szStatusText);
669
670 //Set the window title
671 SetWindowText ( hwndMainWindow , szWindowTitle);
672
673 //Resume list view redraw
674 SendMessage(hwndListView, WM_SETREDRAW, TRUE, 0);
675
676 // Close the event log.
677 CloseEventLog(hEventLog);
678 }
679
680 VOID
681 Refresh (VOID)
682 {
683 QueryEventMessages(
684 lpComputerName ,
685 lpSourceLogName);
686 }
687
688 //
689 // FUNCTION: MyRegisterClass()
690 //
691 // PURPOSE: Registers the window class.
692 //
693 // COMMENTS:
694 //
695 // This function and its usage are only necessary if you want this code
696 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
697 // function that was added to Windows 95. It is important to call this function
698 // so that the application will get 'well formed' small icons associated
699 // with it.
700 //
701 ATOM MyRegisterClass(HINSTANCE hInstance)
702 {
703 WNDCLASSEX wcex;
704
705 wcex.cbSize = sizeof(WNDCLASSEX);
706
707 wcex.style = CS_HREDRAW | CS_VREDRAW;
708 wcex.lpfnWndProc = WndProc;
709 wcex.cbClsExtra = 0;
710 wcex.cbWndExtra = 0;
711 wcex.hInstance = hInstance;
712 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_EVENTVWR));
713 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
714 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
715 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_EVENTVWR);
716 wcex.lpszClassName = szWindowClass;
717 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
718
719 return RegisterClassEx(&wcex);
720 }
721
722 //
723 // FUNCTION: InitInstance(HINSTANCE, int)
724 //
725 // PURPOSE: Saves instance handle and creates main window
726 //
727 // COMMENTS:
728 //
729 // In this function, we save the instance handle in a global variable and
730 // create and display the main program window.
731 //
732 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
733 {
734 HIMAGELIST hSmall;
735 LVCOLUMN lvc = {0};
736
737 hInst = hInstance; // Store instance handle in our global variable
738
739 hwndMainWindow = CreateWindow(
740 szWindowClass,
741 szTitle,
742 WS_OVERLAPPEDWINDOW,
743 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
744 NULL,
745 NULL,
746 hInstance,
747 NULL);
748
749 if (!hwndMainWindow)
750 {
751 return FALSE;
752 }
753
754 hwndStatus = CreateWindowEx(
755 0, // no extended styles
756 STATUSCLASSNAME, // status bar
757 "Done.", // no text
758 WS_CHILD | WS_BORDER | WS_VISIBLE, // styles
759 0, 0, 0, 0, // x, y, cx, cy
760 hwndMainWindow, // parent window
761 (HMENU)100, // window ID
762 hInstance, // instance
763 NULL); // window data
764
765 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
766 // and WS_BORDER to create the normal "sunken" look. Also note that
767 // LVS_EX_ styles cannot be set in CreateWindowEx().
768 hwndListView = CreateWindowEx(
769 WS_EX_CLIENTEDGE,
770 WC_LISTVIEW,
771 _T(""),
772 LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | LVS_REPORT,
773 0,
774 0,
775 243,
776 200,
777 hwndMainWindow,
778 NULL,
779 hInstance,
780 NULL);
781
782 // After the ListView is created, we can add extended list view styles.
783 (void)ListView_SetExtendedListViewStyle (hwndListView, LVS_EX_FULLROWSELECT);
784
785 // Create the ImageList
786 hSmall = ImageList_Create(
787 GetSystemMetrics(SM_CXSMICON),
788 GetSystemMetrics(SM_CYSMICON),
789 ILC_MASK,
790 1,
791 1);
792
793 // Add event type icons to ImageList
794 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INFORMATIONICON)));
795 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WARNINGICON)));
796 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ERRORICON)));
797
798 // Assign ImageList to List View
799 (void)ListView_SetImageList (hwndListView, hSmall, LVSIL_SMALL);
800
801 // Now set up the listview with its columns.
802 lvc.mask = LVCF_TEXT | LVCF_WIDTH;
803 lvc.cx = 90;
804 lvc.pszText = _T("Type");
805 (void)ListView_InsertColumn(hwndListView, 0, &lvc);
806
807 lvc.cx = 70;
808 lvc.pszText = _T("Date");
809 (void)ListView_InsertColumn(hwndListView, 1, &lvc);
810
811 lvc.cx = 70;
812 lvc.pszText = _T("Time");
813 (void)ListView_InsertColumn(hwndListView, 2, &lvc);
814
815 lvc.cx = 150;
816 lvc.pszText = _T("Source");
817 (void)ListView_InsertColumn(hwndListView, 3, &lvc);
818
819 lvc.cx = 100;
820 lvc.pszText = _T("Category");
821 (void)ListView_InsertColumn(hwndListView, 4, &lvc);
822
823 lvc.cx = 60;
824 lvc.pszText = _T("Event");
825 (void)ListView_InsertColumn(hwndListView, 5, &lvc);
826
827 lvc.cx = 120;
828 lvc.pszText = _T("User");
829 (void)ListView_InsertColumn(hwndListView, 6, &lvc);
830
831 lvc.cx = 100;
832 lvc.pszText = _T("Computer");
833 (void)ListView_InsertColumn(hwndListView, 7, &lvc);
834
835 lvc.cx = 0;
836 lvc.pszText = _T("Event Data");
837 (void)ListView_InsertColumn(hwndListView, 8, &lvc);
838
839 ShowWindow(hwndMainWindow, nCmdShow);
840 UpdateWindow(hwndMainWindow);
841
842 QueryEventMessages (
843 lpComputerName, // Use the local computer.
844 EVENT_SOURCE_APPLICATION); // The event log category
845
846 return TRUE;
847 }
848
849 //
850 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
851 //
852 // PURPOSE: Processes messages for the main window.
853 //
854 // WM_COMMAND - process the application menu
855 // WM_PAINT - Paint the main window
856 // WM_DESTROY - post a quit message and return
857 //
858 //
859 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
860 {
861 int wmId, wmEvent;
862 RECT rect;
863 NMHDR *hdr;
864 HMENU hMenu ;
865
866 switch (message)
867 {
868 case WM_NOTIFY :
869 switch(((LPNMHDR)lParam)->code)
870 {
871 case NM_DBLCLK :
872 hdr = (NMHDR FAR*)lParam;
873 if(hdr->hwndFrom == hwndListView)
874 {
875 LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
876
877 if(lpnmitem->iItem != -1)
878 {
879 DialogBox (hInst, MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG), hWnd, EventDetails);
880 }
881 }
882 break;
883 }
884 break;
885 case WM_COMMAND:
886 wmId = LOWORD(wParam);
887 wmEvent = HIWORD(wParam);
888
889 if ((wmId == ID_LOG_APPLICATION) ||
890 (wmId == ID_LOG_SYSTEM) ||
891 (wmId == ID_LOG_SECURITY))
892 {
893 hMenu = GetMenu (hWnd) ; // get the menu handle. Use it below
894
895 CheckMenuItem (hMenu, ID_LOG_APPLICATION , MF_UNCHECKED) ;
896 CheckMenuItem (hMenu, ID_LOG_SYSTEM , MF_UNCHECKED) ;
897 CheckMenuItem (hMenu, ID_LOG_SECURITY , MF_UNCHECKED) ;
898
899 if (hMenu)
900 {
901 CheckMenuItem (hMenu, wmId , MF_CHECKED) ;
902 }
903 }
904
905 // Parse the menu selections:
906 switch (wmId)
907 {
908 case ID_LOG_APPLICATION:
909 QueryEventMessages (
910 lpComputerName, // Use the local computer.
911 EVENT_SOURCE_APPLICATION); // The event log category
912 break;
913 case ID_LOG_SYSTEM:
914 QueryEventMessages (
915 lpComputerName, // Use the local computer.
916 EVENT_SOURCE_SYSTEM); // The event log category
917 break;
918 case ID_LOG_SECURITY:
919 QueryEventMessages (
920 lpComputerName, // Use the local computer.
921 EVENT_SOURCE_SECURITY); // The event log category
922 break;
923 case IDM_REFRESH:
924 Refresh ();
925 break;
926 case IDM_ABOUT:
927 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
928 break;
929 case IDM_HELP:
930 MessageBox (
931 NULL ,
932 _TEXT("Help not implemented yet!") ,
933 _TEXT("Event Log") ,
934 MB_OK | MB_ICONINFORMATION);
935 break;
936 case IDM_EXIT:
937 DestroyWindow(hWnd);
938 break;
939 default:
940 return DefWindowProc(hWnd, message, wParam, lParam);
941 }
942 break;
943 case WM_SIZE:
944 {
945 //Gets the window rectangle
946 GetClientRect(hWnd, &rect);
947
948 //Relocate the listview
949 MoveWindow(
950 hwndListView,
951 0,
952 0,
953 rect.right,
954 rect.bottom - 20,
955 1);
956
957 // Resize the statusbar;
958 SendMessage (hwndStatus, message, wParam, lParam);
959 }
960 break;
961 case WM_DESTROY:
962 PostQuitMessage(0);
963 break;
964 default:
965 return DefWindowProc(hWnd, message, wParam, lParam);
966 }
967 return 0;
968 }
969
970 // Message handler for about box.
971 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
972 {
973 UNREFERENCED_PARAMETER(lParam);
974 switch (message)
975 {
976 case WM_INITDIALOG:
977 {
978 return (INT_PTR)TRUE;
979 }
980 case WM_COMMAND:
981 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
982 {
983 EndDialog(hDlg, LOWORD(wParam));
984 return (INT_PTR)TRUE;
985 }
986
987 break;
988 }
989 return (INT_PTR)FALSE;
990 }
991
992 VOID
993 DisplayEvent (HWND hDlg)
994 {
995 char szEventType[MAX_PATH];
996 char szTime[MAX_PATH];
997 char szDate[MAX_PATH];
998 char szUser[MAX_PATH];
999 char szComputer[MAX_PATH];
1000 char szSource[MAX_PATH];
1001 char szCategory[MAX_PATH];
1002 char szEventID[MAX_PATH];
1003 char szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER];
1004 char szEventData[MAX_PATH];
1005 BOOL bEventData = FALSE;
1006 LVITEM li;
1007 EVENTLOGRECORD* pevlr;
1008
1009 // Get index of selected item
1010 int iIndex = (int)SendMessage (hwndListView ,LVM_GETNEXTITEM, -1 , LVNI_SELECTED | LVNI_FOCUSED);
1011
1012 li.mask = LVIF_PARAM;
1013 li.iItem = iIndex;
1014 li.iSubItem = 0;
1015
1016 (void)ListView_GetItem(hwndListView, &li);
1017
1018 pevlr = (EVENTLOGRECORD*)li.lParam;
1019
1020 if (iIndex != -1)
1021 {
1022 ListView_GetItemText (hwndListView , iIndex , 0 , szEventType , sizeof( szEventType ));
1023 ListView_GetItemText (hwndListView , iIndex , 1 , szDate , sizeof( szDate ));
1024 ListView_GetItemText (hwndListView , iIndex , 2 , szTime , sizeof( szTime ));
1025 ListView_GetItemText (hwndListView , iIndex , 3 , szSource , sizeof( szSource ));
1026 ListView_GetItemText (hwndListView , iIndex , 4 , szCategory , sizeof( szCategory ));
1027 ListView_GetItemText (hwndListView , iIndex , 5 , szEventID , sizeof( szEventID ));
1028 ListView_GetItemText (hwndListView , iIndex , 6 , szUser , sizeof( szUser ));
1029 ListView_GetItemText (hwndListView , iIndex , 7 , szComputer , sizeof( szComputer ));
1030 ListView_GetItemText (hwndListView , iIndex , 8 , szEventData , sizeof( szEventData ));
1031
1032 bEventData = !(strlen(szEventData) == 0);
1033
1034 GetEventMessage (lpSourceLogName , szSource , pevlr , szEventText);
1035
1036 EnableWindow(GetDlgItem(hDlg , IDC_BYTESRADIO) , bEventData);
1037 EnableWindow(GetDlgItem(hDlg , IDC_WORDRADIO) , bEventData);
1038
1039 SetDlgItemText (hDlg, IDC_EVENTDATESTATIC , szDate);
1040 SetDlgItemText (hDlg, IDC_EVENTTIMESTATIC , szTime);
1041 SetDlgItemText (hDlg, IDC_EVENTUSERSTATIC , szUser);
1042 SetDlgItemText (hDlg, IDC_EVENTSOURCESTATIC , szSource);
1043 SetDlgItemText (hDlg, IDC_EVENTCOMPUTERSTATIC , szComputer);
1044 SetDlgItemText (hDlg, IDC_EVENTCATEGORYSTATIC , szCategory);
1045 SetDlgItemText (hDlg, IDC_EVENTIDSTATIC , szEventID);
1046 SetDlgItemText (hDlg, IDC_EVENTTYPESTATIC , szEventType);
1047 SetDlgItemText (hDlg, IDC_EVENTTEXTEDIT , szEventText);
1048 SetDlgItemText (hDlg, IDC_EVENTDATAEDIT , szEventData);
1049 }
1050 else
1051 {
1052 MessageBox(
1053 NULL,
1054 "No Items in ListView",
1055 "Error",
1056 MB_OK | MB_ICONINFORMATION);
1057 }
1058 }
1059
1060 static
1061 INT_PTR CALLBACK StatusMessageWindowProc(
1062 IN HWND hwndDlg,
1063 IN UINT uMsg,
1064 IN WPARAM wParam,
1065 IN LPARAM lParam)
1066 {
1067 UNREFERENCED_PARAMETER(wParam);
1068
1069 switch (uMsg)
1070 {
1071 case WM_INITDIALOG:
1072 {
1073 return TRUE;
1074 }
1075 }
1076 return FALSE;
1077 }
1078
1079 // Message handler for event details box.
1080 INT_PTR CALLBACK EventDetails(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1081 {
1082 UNREFERENCED_PARAMETER(lParam);
1083 switch (message)
1084 {
1085 case WM_INITDIALOG:
1086 {
1087 // Show event info on dialog box
1088 DisplayEvent (hDlg);
1089 return (INT_PTR)TRUE;
1090 }
1091
1092 case WM_COMMAND:
1093 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
1094 {
1095 EndDialog(hDlg, LOWORD(wParam));
1096 return (INT_PTR)TRUE;
1097 }
1098 if (LOWORD(wParam) == IDPREVIOUS)
1099 {
1100 SendMessage (hwndListView, WM_KEYDOWN, VK_UP, 0);
1101
1102 // Show event info on dialog box
1103 DisplayEvent (hDlg);
1104 return (INT_PTR)TRUE;
1105 }
1106
1107 if (LOWORD(wParam) == IDNEXT)
1108 {
1109 SendMessage (hwndListView, WM_KEYDOWN, VK_DOWN, 0);
1110
1111 // Show event info on dialog box
1112 DisplayEvent (hDlg);
1113 return (INT_PTR)TRUE;
1114 }
1115
1116 if (LOWORD(wParam) == IDC_BYTESRADIO)
1117 {
1118 return (INT_PTR)TRUE;
1119 }
1120
1121 if (LOWORD(wParam) == IDC_WORDRADIO)
1122 {
1123 return (INT_PTR)TRUE;
1124 }
1125
1126 if (LOWORD(wParam) == IDHELP)
1127 {
1128 MessageBox (NULL ,
1129 _TEXT("Help not implemented yet!") ,
1130 _TEXT("Event Log") ,
1131 MB_OK | MB_ICONINFORMATION);
1132 return (INT_PTR)TRUE;
1133 }
1134 break;
1135 }
1136 return (INT_PTR)FALSE;
1137 }