* Sync up to trunk head (r65120).
[reactos.git] / 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 <stdio.h>
27 #include <stdlib.h>
28 #include <windef.h>
29 #include <winbase.h>
30 #include <winuser.h>
31 #include <wingdi.h>
32 #include <winnls.h>
33 #include <winreg.h>
34 #include <commctrl.h>
35 #include <commdlg.h>
36 #include <strsafe.h>
37
38 #include "resource.h"
39
40 #if _MSC_VER
41 #pragma warning(disable: 4996) /* 'strdup' was declared deprecated */
42 #define _CRT_SECURE_NO_DEPRECATE /* all deprecated unsafe string functions */
43 #endif
44
45 static const WCHAR szWindowClass[] = L"EVENTVWR"; /* the main window class name*/
46 static const WCHAR EVENTLOG_BASE_KEY[] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
47
48 // MessageFile message buffer size
49 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10
50 #define EVENT_MESSAGE_FILE_BUFFER 1024*10
51 #define EVENT_DLL_SEPARATOR L";"
52 #define EVENT_MESSAGE_FILE L"EventMessageFile"
53 #define EVENT_CATEGORY_MESSAGE_FILE L"CategoryMessageFile"
54 #define EVENT_PARAMETER_MESSAGE_FILE L"ParameterMessageFile"
55
56 #define MAX_LOADSTRING 255
57
58 /* Globals */
59 HINSTANCE hInst; /* current instance */
60 WCHAR szTitle[MAX_LOADSTRING]; /* The title bar text */
61 WCHAR szTitleTemplate[MAX_LOADSTRING]; /* The logged-on title bar text */
62 WCHAR szSaveFilter[MAX_LOADSTRING]; /* Filter Mask for the save Dialog */
63 HWND hwndMainWindow; /* Main window */
64 HWND hwndListView; /* ListView control */
65 HWND hwndStatus; /* Status bar */
66 HMENU hMainMenu; /* The application's main menu */
67 WCHAR szStatusBarTemplate[MAX_LOADSTRING]; /* The status bar text */
68 PEVENTLOGRECORD *g_RecordPtrs = NULL;
69 DWORD g_TotalRecords = 0;
70 OPENFILENAMEW sfn;
71
72 LPWSTR lpSourceLogName = NULL;
73 LPWSTR lpComputerName = NULL;
74
75 DWORD dwNumLogs = 0;
76 WCHAR **LogNames;
77
78 /* Forward declarations of functions included in this code module: */
79 ATOM MyRegisterClass(HINSTANCE hInstance);
80 BOOL InitInstance(HINSTANCE, int);
81 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
82 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
83 INT_PTR CALLBACK EventDetails(HWND, UINT, WPARAM, LPARAM);
84 static INT_PTR CALLBACK StatusMessageWindowProc (HWND, UINT, WPARAM, LPARAM);
85
86
87 int APIENTRY
88 wWinMain(HINSTANCE hInstance,
89 HINSTANCE hPrevInstance,
90 LPWSTR lpCmdLine,
91 int nCmdShow)
92 {
93 MSG msg;
94 HACCEL hAccelTable;
95 INITCOMMONCONTROLSEX iccx;
96
97 UNREFERENCED_PARAMETER(hPrevInstance);
98 UNREFERENCED_PARAMETER(lpCmdLine);
99
100 /* Whenever any of the common controls are used in your app,
101 * you must call InitCommonControlsEx() to register the classes
102 * for those controls. */
103 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
104 iccx.dwICC = ICC_LISTVIEW_CLASSES;
105 InitCommonControlsEx(&iccx);
106
107 /* Initialize global strings */
108 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
109 LoadStringW(hInstance, IDS_APP_TITLE_EX, szTitleTemplate, MAX_LOADSTRING);
110 LoadStringW(hInstance, IDS_STATUS_MSG, szStatusBarTemplate, MAX_LOADSTRING);
111 MyRegisterClass(hInstance);
112
113 /* Perform application initialization: */
114 if (!InitInstance(hInstance, nCmdShow))
115 {
116 return FALSE;
117 }
118
119 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_EVENTVWR));
120
121 /* Main message loop: */
122 while (GetMessageW(&msg, NULL, 0, 0))
123 {
124 if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg))
125 {
126 TranslateMessage(&msg);
127 DispatchMessage(&msg);
128 }
129 }
130
131 return (int)msg.wParam;
132 }
133
134 static void FreeRecords(void)
135 {
136 DWORD iIndex;
137
138 if (!g_RecordPtrs)
139 return;
140
141 for (iIndex = 0; iIndex < g_TotalRecords; iIndex++)
142 HeapFree(GetProcessHeap(), 0, g_RecordPtrs[iIndex]);
143 HeapFree(GetProcessHeap(), 0, g_RecordPtrs);
144 g_RecordPtrs = NULL;
145 }
146
147 VOID
148 ShowLastWin32Error(VOID)
149 {
150 DWORD dwError;
151 LPWSTR lpMessageBuffer;
152
153 dwError = GetLastError();
154 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
155 NULL,
156 dwError,
157 0,
158 (LPWSTR)&lpMessageBuffer,
159 0,
160 NULL);
161
162 MessageBoxW(hwndMainWindow, lpMessageBuffer, szTitle, MB_OK | MB_ICONERROR);
163 LocalFree(lpMessageBuffer);
164 }
165
166 VOID
167 EventTimeToSystemTime(DWORD EventTime,
168 SYSTEMTIME *pSystemTime)
169 {
170 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
171 FILETIME ftLocal;
172 union
173 {
174 FILETIME ft;
175 ULONGLONG ll;
176 } u1970, uUCT;
177
178 uUCT.ft.dwHighDateTime = 0;
179 uUCT.ft.dwLowDateTime = EventTime;
180 SystemTimeToFileTime(&st1970, &u1970.ft);
181 uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
182 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
183 FileTimeToSystemTime(&ftLocal, pSystemTime);
184 }
185
186
187 void
188 TrimNulls(LPWSTR s)
189 {
190 WCHAR *c;
191
192 if (s != NULL)
193 {
194 c = s + wcslen(s) - 1;
195 while (c >= s && iswspace(*c))
196 --c;
197 *++c = L'\0';
198 }
199 }
200
201
202 BOOL
203 GetEventMessageFileDLL(IN LPCWSTR lpLogName,
204 IN LPCWSTR SourceName,
205 IN LPCWSTR EntryName,
206 OUT PWCHAR ExpandedName)
207 {
208 DWORD dwSize;
209 BYTE szModuleName[MAX_PATH];
210 WCHAR szKeyName[MAX_PATH];
211 HKEY hAppKey = NULL;
212 HKEY hSourceKey = NULL;
213 BOOL bReturn = FALSE;
214
215 StringCbCopyW(szKeyName, sizeof(szKeyName), L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\");
216 StringCbCatW(szKeyName, sizeof(szKeyName), lpLogName);
217
218 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
219 szKeyName,
220 0,
221 KEY_READ,
222 &hAppKey) == ERROR_SUCCESS)
223 {
224 if (RegOpenKeyExW(hAppKey,
225 SourceName,
226 0,
227 KEY_READ,
228 &hSourceKey) == ERROR_SUCCESS)
229 {
230 dwSize = MAX_PATH;
231 if (RegQueryValueExW(hSourceKey,
232 EntryName,
233 NULL,
234 NULL,
235 (LPBYTE)szModuleName,
236 &dwSize) == ERROR_SUCCESS)
237 {
238 /* Returns a string containing the requested substituted environment variable. */
239 ExpandEnvironmentStringsW((LPCWSTR)szModuleName, ExpandedName, MAX_PATH);
240
241 /* Successful */
242 bReturn = TRUE;
243 }
244 }
245 }
246 else
247 {
248 ShowLastWin32Error();
249 }
250
251 if (hSourceKey != NULL)
252 RegCloseKey(hSourceKey);
253
254 if (hAppKey != NULL)
255 RegCloseKey(hAppKey);
256
257 return bReturn;
258 }
259
260
261 BOOL
262 GetEventCategory(IN LPCWSTR KeyName,
263 IN LPCWSTR SourceName,
264 IN EVENTLOGRECORD *pevlr,
265 OUT PWCHAR CategoryName)
266 {
267 HANDLE hLibrary = NULL;
268 WCHAR szMessageDLL[MAX_PATH];
269 LPVOID lpMsgBuf = NULL;
270
271 if (GetEventMessageFileDLL (KeyName, SourceName, EVENT_CATEGORY_MESSAGE_FILE , szMessageDLL))
272 {
273 hLibrary = LoadLibraryExW(szMessageDLL,
274 NULL,
275 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
276 if (hLibrary != NULL)
277 {
278 /* Retrieve the message string. */
279 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
280 hLibrary,
281 pevlr->EventCategory,
282 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
283 (LPWSTR)&lpMsgBuf,
284 EVENT_MESSAGE_FILE_BUFFER,
285 NULL) != 0)
286 {
287 /* Trim the string */
288 TrimNulls(lpMsgBuf);
289
290 /* Copy the category name */
291 StringCchCopyW(CategoryName, MAX_PATH, lpMsgBuf);
292 }
293 else
294 {
295 LoadStringW(hInst, IDS_NONE, CategoryName, MAX_PATH);
296 }
297
298 if (hLibrary != NULL)
299 FreeLibrary(hLibrary);
300
301 /* Free the buffer allocated by FormatMessage */
302 if (lpMsgBuf)
303 LocalFree(lpMsgBuf);
304
305 return TRUE;
306 }
307 }
308
309 LoadStringW(hInst, IDS_NONE, CategoryName, MAX_PATH);
310
311 return FALSE;
312 }
313
314
315 BOOL
316 GetEventMessage(IN LPCWSTR KeyName,
317 IN LPCWSTR SourceName,
318 IN EVENTLOGRECORD *pevlr,
319 OUT PWCHAR EventText)
320 {
321 DWORD i;
322 HANDLE hLibrary = NULL;
323 WCHAR SourceModuleName[1000];
324 WCHAR ParameterModuleName[1000];
325 LPWSTR lpMsgBuf = NULL;
326 WCHAR szStringIDNotFound[MAX_LOADSTRING];
327 LPWSTR szDll;
328 LPWSTR szMessage;
329 LPWSTR *szArguments;
330 BOOL bDone = FALSE;
331
332 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
333 if (GetEventMessageFileDLL (KeyName, SourceName, EVENT_MESSAGE_FILE, SourceModuleName))
334 {
335 /* Get the event message */
336 szMessage = (LPWSTR)((LPBYTE)pevlr + pevlr->StringOffset);
337
338 /* Allocate space for parameters */
339 szArguments = malloc(sizeof(LPVOID) * pevlr->NumStrings);
340 if (!szArguments)
341 {
342 return FALSE;
343 }
344
345 for (i = 0; i < pevlr->NumStrings ; i++)
346 {
347 if (wcsstr(szMessage , L"%%"))
348 {
349 if (GetEventMessageFileDLL(KeyName, SourceName, EVENT_PARAMETER_MESSAGE_FILE, ParameterModuleName))
350 {
351 /* Not yet support for reading messages from parameter message DLL */
352 }
353 }
354
355 szArguments[i] = szMessage;
356 szMessage += wcslen(szMessage) + 1;
357 }
358
359 szDll = wcstok(SourceModuleName, EVENT_DLL_SEPARATOR);
360 while ((szDll != NULL) && (!bDone))
361 {
362 hLibrary = LoadLibraryExW(szDll,
363 NULL,
364 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
365 if (hLibrary == NULL)
366 {
367 /* The DLL could not be loaded try the next one (if any) */
368 szDll = wcstok(NULL, EVENT_DLL_SEPARATOR);
369 }
370 else
371 {
372 /* Retrieve the message string. */
373 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
374 FORMAT_MESSAGE_ALLOCATE_BUFFER |
375 FORMAT_MESSAGE_FROM_HMODULE |
376 FORMAT_MESSAGE_ARGUMENT_ARRAY,
377 hLibrary,
378 pevlr->EventID,
379 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
380 (LPWSTR)&lpMsgBuf,
381 0,
382 (va_list*)szArguments) == 0)
383 {
384 /* We haven't found the string , get next DLL (if any) */
385 szDll = wcstok(NULL, EVENT_DLL_SEPARATOR);
386 }
387 else
388 {
389 if (lpMsgBuf)
390 {
391 /* The ID was found and the message was formated */
392 bDone = TRUE;
393
394 /* Trim the string */
395 TrimNulls((LPWSTR)lpMsgBuf);
396
397 /* Copy the event text */
398 StringCchCopyW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, lpMsgBuf);
399 }
400 }
401
402 FreeLibrary(hLibrary);
403 }
404 }
405
406 if (!bDone)
407 {
408 LoadStringW(hInst, IDS_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING);
409 StringCchPrintfW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, szStringIDNotFound, (pevlr->EventID & 0xFFFF), SourceName);
410 }
411
412 free(szArguments);
413
414 /* No more dlls to try, return result */
415 return bDone;
416 }
417
418 LoadStringW(hInst, IDS_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING);
419 StringCchPrintfW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, szStringIDNotFound, (pevlr->EventID & 0xFFFF), SourceName);
420
421 return FALSE;
422 }
423
424
425 VOID
426 GetEventType(IN WORD dwEventType,
427 OUT PWCHAR eventTypeText)
428 {
429 switch (dwEventType)
430 {
431 case EVENTLOG_ERROR_TYPE:
432 LoadStringW(hInst, IDS_EVENTLOG_ERROR_TYPE, eventTypeText, MAX_LOADSTRING);
433 break;
434 case EVENTLOG_WARNING_TYPE:
435 LoadStringW(hInst, IDS_EVENTLOG_WARNING_TYPE, eventTypeText, MAX_LOADSTRING);
436 break;
437 case EVENTLOG_INFORMATION_TYPE:
438 LoadStringW(hInst, IDS_EVENTLOG_INFORMATION_TYPE, eventTypeText, MAX_LOADSTRING);
439 break;
440 case EVENTLOG_AUDIT_SUCCESS:
441 LoadStringW(hInst, IDS_EVENTLOG_AUDIT_SUCCESS, eventTypeText, MAX_LOADSTRING);
442 break;
443 case EVENTLOG_AUDIT_FAILURE:
444 LoadStringW(hInst, IDS_EVENTLOG_AUDIT_FAILURE, eventTypeText, MAX_LOADSTRING);
445 break;
446 case EVENTLOG_SUCCESS:
447 LoadStringW(hInst, IDS_EVENTLOG_SUCCESS, eventTypeText, MAX_LOADSTRING);
448 break;
449 default:
450 LoadStringW(hInst, IDS_EVENTLOG_UNKNOWN_TYPE, eventTypeText, MAX_LOADSTRING);
451 break;
452 }
453 }
454
455 BOOL
456 GetEventUserName(EVENTLOGRECORD *pelr,
457 OUT PWCHAR pszUser)
458 {
459 PSID lpSid;
460 WCHAR szName[1024];
461 WCHAR szDomain[1024];
462 SID_NAME_USE peUse;
463 DWORD cbName = 1024;
464 DWORD cbDomain = 1024;
465
466 /* Point to the SID. */
467 lpSid = (PSID)((LPBYTE)pelr + pelr->UserSidOffset);
468
469 /* User SID */
470 if (pelr->UserSidLength > 0)
471 {
472 if (LookupAccountSidW(NULL,
473 lpSid,
474 szName,
475 &cbName,
476 szDomain,
477 &cbDomain,
478 &peUse))
479 {
480 StringCchCopyW(pszUser, MAX_PATH, szName);
481 return TRUE;
482 }
483 }
484
485 return FALSE;
486 }
487
488
489 static DWORD WINAPI
490 ShowStatusMessageThread(IN LPVOID lpParameter)
491 {
492 HWND *phWnd = (HWND *)lpParameter;
493 HWND hWnd;
494 MSG Msg;
495
496 hWnd = CreateDialogParam(hInst,
497 MAKEINTRESOURCE(IDD_PROGRESSBOX),
498 GetDesktopWindow(),
499 StatusMessageWindowProc,
500 (LPARAM)NULL);
501 if (!hWnd)
502 return 0;
503
504 *phWnd = hWnd;
505
506 ShowWindow(hWnd, SW_SHOW);
507
508 /* Message loop for the Status window */
509 while (GetMessage(&Msg, NULL, 0, 0))
510 {
511 TranslateMessage(&Msg);
512 DispatchMessage(&Msg);
513 }
514
515 return 0;
516 }
517
518
519 BOOL
520 QueryEventMessages(LPWSTR lpMachineName,
521 LPWSTR lpLogName)
522 {
523 HWND hwndDlg = NULL;
524 HANDLE hEventLog;
525 EVENTLOGRECORD *pevlr;
526 DWORD dwRead, dwNeeded, dwThisRecord, dwTotalRecords = 0, dwCurrentRecord = 0, dwRecordsToRead = 0, dwFlags, dwMaxLength;
527 size_t cchRemaining;
528 LPWSTR lpSourceName;
529 LPWSTR lpComputerName;
530 LPSTR lpData;
531 BOOL bResult = TRUE; /* Read succeeded. */
532
533 WCHAR szWindowTitle[MAX_PATH];
534 WCHAR szStatusText[MAX_PATH];
535 WCHAR szLocalDate[MAX_PATH];
536 WCHAR szLocalTime[MAX_PATH];
537 WCHAR szEventID[MAX_PATH];
538 WCHAR szEventTypeText[MAX_LOADSTRING];
539 WCHAR szCategoryID[MAX_PATH];
540 WCHAR szUsername[MAX_PATH];
541 WCHAR szEventText[EVENT_MESSAGE_FILE_BUFFER];
542 WCHAR szCategory[MAX_PATH];
543 WCHAR szData[MAX_PATH];
544 PWCHAR lpTitleTemplateEnd;
545
546 SYSTEMTIME time;
547 LVITEMW lviEventItem;
548
549 dwFlags = EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ;
550
551 /* Open the event log. */
552 hEventLog = OpenEventLogW(lpMachineName,
553 lpLogName);
554 if (hEventLog == NULL)
555 {
556 ShowLastWin32Error();
557 return FALSE;
558 }
559
560 lpSourceLogName = lpLogName;
561 lpComputerName = lpMachineName;
562
563 /* Disable listview redraw */
564 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);
565
566 /* Clear the list view */
567 (void)ListView_DeleteAllItems (hwndListView);
568 FreeRecords();
569
570 GetOldestEventLogRecord(hEventLog, &dwThisRecord);
571
572 /* Get the total number of event log records. */
573 GetNumberOfEventLogRecords (hEventLog , &dwTotalRecords);
574 g_TotalRecords = dwTotalRecords;
575
576 if (dwTotalRecords > 0)
577 {
578 EnableMenuItem(hMainMenu, ID_CLEAR_EVENTS, MF_BYCOMMAND | MF_ENABLED);
579 EnableMenuItem(hMainMenu, ID_SAVE_PROTOCOL, MF_BYCOMMAND | MF_ENABLED);
580 }
581 else
582 {
583 EnableMenuItem(hMainMenu, ID_CLEAR_EVENTS, MF_BYCOMMAND | MF_GRAYED);
584 EnableMenuItem(hMainMenu, ID_SAVE_PROTOCOL, MF_BYCOMMAND | MF_GRAYED);
585 }
586
587 g_RecordPtrs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwTotalRecords * sizeof(PVOID));
588
589 /* If we have at least 1000 records show the waiting dialog */
590 if (dwTotalRecords > 1000)
591 {
592 CloseHandle(CreateThread(NULL,
593 0,
594 ShowStatusMessageThread,
595 (LPVOID)&hwndDlg,
596 0,
597 NULL));
598 }
599
600 while (dwCurrentRecord < dwTotalRecords)
601 {
602 pevlr = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
603 g_RecordPtrs[dwCurrentRecord] = pevlr;
604
605 bResult = ReadEventLog(hEventLog, // Event log handle
606 dwFlags, // Sequential read
607 0, // Ignored for sequential read
608 pevlr, // Pointer to buffer
609 sizeof(EVENTLOGRECORD), // Size of buffer
610 &dwRead, // Number of bytes read
611 &dwNeeded); // Bytes in the next record
612 if((!bResult) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER))
613 {
614 HeapFree(GetProcessHeap(), 0, pevlr);
615 pevlr = HeapAlloc(GetProcessHeap(), 0, dwNeeded);
616 g_RecordPtrs[dwCurrentRecord] = pevlr;
617
618 ReadEventLogW(hEventLog, // event log handle
619 dwFlags, // read flags
620 0, // offset; default is 0
621 pevlr, // pointer to buffer
622 dwNeeded, // size of buffer
623 &dwRead, // number of bytes read
624 &dwNeeded); // bytes in next record
625 }
626
627 while (dwRead > 0)
628 {
629 LoadStringW(hInst, IDS_NOT_AVAILABLE, szUsername, MAX_PATH);
630 LoadStringW(hInst, IDS_NOT_AVAILABLE, szEventText, MAX_PATH);
631 LoadStringW(hInst, IDS_NONE, szCategory, MAX_PATH);
632
633 // Get the event source name.
634 lpSourceName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD));
635
636 // Get the computer name
637 lpComputerName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD) + (wcslen(lpSourceName) + 1) * sizeof(WCHAR));
638
639 // This ist the data section of the current event
640 lpData = (LPSTR)((LPBYTE)pevlr + pevlr->DataOffset);
641
642 // Compute the event type
643 EventTimeToSystemTime(pevlr->TimeWritten, &time);
644
645 // Get the username that generated the event
646 GetEventUserName(pevlr, szUsername);
647
648 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, szLocalDate, MAX_PATH);
649 GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, szLocalTime, MAX_PATH);
650
651 GetEventType(pevlr->EventType, szEventTypeText);
652 GetEventCategory(lpLogName, lpSourceName, pevlr, szCategory);
653
654 StringCbPrintfW(szEventID, sizeof(szEventID), L"%u", (pevlr->EventID & 0xFFFF));
655 StringCbPrintfW(szCategoryID, sizeof(szCategoryID), L"%u", pevlr->EventCategory);
656
657 lviEventItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
658 lviEventItem.iItem = 0;
659 lviEventItem.iSubItem = 0;
660 lviEventItem.lParam = (LPARAM)pevlr;
661 lviEventItem.pszText = szEventTypeText;
662
663 switch (pevlr->EventType)
664 {
665 case EVENTLOG_ERROR_TYPE:
666 lviEventItem.iImage = 2;
667 break;
668
669 case EVENTLOG_AUDIT_FAILURE:
670 lviEventItem.iImage = 2;
671 break;
672
673 case EVENTLOG_WARNING_TYPE:
674 lviEventItem.iImage = 1;
675 break;
676
677 case EVENTLOG_INFORMATION_TYPE:
678 lviEventItem.iImage = 0;
679 break;
680
681 case EVENTLOG_AUDIT_SUCCESS:
682 lviEventItem.iImage = 0;
683 break;
684
685 case EVENTLOG_SUCCESS:
686 lviEventItem.iImage = 0;
687 break;
688 }
689
690 lviEventItem.iItem = ListView_InsertItem(hwndListView, &lviEventItem);
691
692 ListView_SetItemText(hwndListView, lviEventItem.iItem, 1, szLocalDate);
693 ListView_SetItemText(hwndListView, lviEventItem.iItem, 2, szLocalTime);
694 ListView_SetItemText(hwndListView, lviEventItem.iItem, 3, lpSourceName);
695 ListView_SetItemText(hwndListView, lviEventItem.iItem, 4, szCategory);
696 ListView_SetItemText(hwndListView, lviEventItem.iItem, 5, szEventID);
697 ListView_SetItemText(hwndListView, lviEventItem.iItem, 6, szUsername); //User
698 ListView_SetItemText(hwndListView, lviEventItem.iItem, 7, lpComputerName); //Computer
699 MultiByteToWideChar(CP_ACP,
700 0,
701 lpData,
702 pevlr->DataLength,
703 szData,
704 MAX_PATH);
705 ListView_SetItemText(hwndListView, lviEventItem.iItem, 8, szData); //Event Text
706
707 dwRead -= pevlr->Length;
708 pevlr = (EVENTLOGRECORD *)((LPBYTE) pevlr + pevlr->Length);
709 }
710
711 dwRecordsToRead--;
712 dwCurrentRecord++;
713 }
714
715 // All events loaded
716 if(hwndDlg)
717 EndDialog(hwndDlg, 0);
718
719 StringCchPrintfExW(szWindowTitle,
720 sizeof(szWindowTitle) / sizeof(WCHAR),
721 &lpTitleTemplateEnd,
722 &cchRemaining,
723 0,
724 szTitleTemplate, szTitle, lpLogName); /* i = number of characters written */
725 /* lpComputerName can be NULL here if no records was read */
726 dwMaxLength = cchRemaining;
727 if (!lpComputerName)
728 GetComputerNameW(lpTitleTemplateEnd, &dwMaxLength);
729 else
730 StringCchCopyW(lpTitleTemplateEnd, dwMaxLength, lpComputerName);
731
732 StringCbPrintfW(szStatusText, sizeof(szStatusText), szStatusBarTemplate, lpLogName, dwTotalRecords);
733
734 // Update the status bar
735 SendMessageW(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)szStatusText);
736
737 // Set the window title
738 SetWindowTextW(hwndMainWindow, szWindowTitle);
739
740 // Resume list view redraw
741 SendMessageW(hwndListView, WM_SETREDRAW, TRUE, 0);
742
743 // Close the event log.
744 CloseEventLog(hEventLog);
745
746 return TRUE;
747 }
748
749
750 VOID
751 SaveProtocol(VOID)
752 {
753 HANDLE hEventLog;
754 WCHAR szFileName[MAX_PATH];
755
756 ZeroMemory(szFileName, sizeof(szFileName));
757
758 sfn.lpstrFile = szFileName;
759 sfn.nMaxFile = MAX_PATH;
760
761 if (!GetSaveFileNameW(&sfn))
762 {
763 return;
764 }
765
766 hEventLog = OpenEventLogW(lpComputerName, lpSourceLogName);
767 if (!hEventLog)
768 {
769 ShowLastWin32Error();
770 return;
771 }
772
773 if (!BackupEventLogW(hEventLog, szFileName))
774 {
775 ShowLastWin32Error();
776 }
777
778 CloseEventLog(hEventLog);
779 }
780
781
782 BOOL
783 ClearEvents(VOID)
784 {
785 HANDLE hEventLog;
786 WCHAR szFileName[MAX_PATH];
787 WCHAR szMessage[MAX_LOADSTRING];
788
789 ZeroMemory(szFileName, sizeof(szFileName));
790 ZeroMemory(szMessage, sizeof(szMessage));
791
792 LoadStringW(hInst, IDS_CLEAREVENTS_MSG, szMessage, MAX_LOADSTRING);
793
794 sfn.lpstrFile = szFileName;
795 sfn.nMaxFile = MAX_PATH;
796
797 switch (MessageBoxW(hwndMainWindow, szMessage, szTitle, MB_YESNOCANCEL | MB_ICONINFORMATION))
798 {
799 case IDCANCEL:
800 {
801 return FALSE;
802 }
803
804 case IDNO:
805 {
806 sfn.lpstrFile = NULL;
807 break;
808 }
809
810 case IDYES:
811 {
812 if (!GetSaveFileNameW(&sfn))
813 {
814 return FALSE;
815 }
816 break;
817 }
818 }
819
820 hEventLog = OpenEventLogW(lpComputerName, lpSourceLogName);
821 if (!hEventLog)
822 {
823 ShowLastWin32Error();
824 return FALSE;
825 }
826
827 if (!ClearEventLogW(hEventLog, sfn.lpstrFile))
828 {
829 ShowLastWin32Error();
830 CloseEventLog(hEventLog);
831 return FALSE;
832 }
833
834 CloseEventLog(hEventLog);
835
836 return TRUE;
837 }
838
839
840 VOID
841 Refresh(VOID)
842 {
843 QueryEventMessages(lpComputerName,
844 lpSourceLogName);
845 }
846
847
848 ATOM
849 MyRegisterClass(HINSTANCE hInstance)
850 {
851 WNDCLASSEXW wcex;
852
853 wcex.cbSize = sizeof(WNDCLASSEX);
854
855 wcex.style = 0;
856 wcex.lpfnWndProc = WndProc;
857 wcex.cbClsExtra = 0;
858 wcex.cbWndExtra = 0;
859 wcex.hInstance = hInstance;
860 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_EVENTVWR));
861 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
862 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
863 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_EVENTVWR);
864 wcex.lpszClassName = szWindowClass;
865 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
866
867 return RegisterClassExW(&wcex);
868 }
869
870
871 VOID
872 GetDisplayNameFile(IN LPCWSTR lpLogName,
873 OUT PWCHAR lpModuleName)
874 {
875 HKEY hKey;
876 WCHAR *KeyPath;
877 WCHAR szModuleName[MAX_PATH];
878 DWORD cbData;
879 DWORD cbKeyPath;
880
881 cbKeyPath = (wcslen(EVENTLOG_BASE_KEY) + wcslen(lpLogName) + 1) * sizeof(WCHAR);
882 KeyPath = HeapAlloc(GetProcessHeap(), 0, cbKeyPath);
883 if (!KeyPath)
884 {
885 return;
886 }
887
888 StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY);
889 StringCbCatW(KeyPath, cbKeyPath, lpLogName);
890
891 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
892 {
893 HeapFree(GetProcessHeap(), 0, KeyPath);
894 return;
895 }
896
897 cbData = sizeof(szModuleName);
898 if (RegQueryValueExW(hKey, L"DisplayNameFile", NULL, NULL, (LPBYTE)szModuleName, &cbData) == ERROR_SUCCESS)
899 {
900 ExpandEnvironmentStringsW(szModuleName, lpModuleName, MAX_PATH);
901 }
902
903 RegCloseKey(hKey);
904 HeapFree(GetProcessHeap(), 0, KeyPath);
905 }
906
907
908 DWORD
909 GetDisplayNameID(IN LPCWSTR lpLogName)
910 {
911 HKEY hKey;
912 WCHAR *KeyPath;
913 DWORD dwMessageID = 0;
914 DWORD cbData;
915 DWORD cbKeyPath;
916
917 cbKeyPath = (wcslen(EVENTLOG_BASE_KEY) + wcslen(lpLogName) + 1) * sizeof(WCHAR);
918 KeyPath = HeapAlloc(GetProcessHeap(), 0, cbKeyPath);
919 if (!KeyPath)
920 {
921 return 0;
922 }
923
924 StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY);
925 StringCbCatW(KeyPath, cbKeyPath, lpLogName);
926
927 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
928 {
929 HeapFree(GetProcessHeap(), 0, KeyPath);
930 return 0;
931 }
932
933 cbData = sizeof(dwMessageID);
934 RegQueryValueExW(hKey, L"DisplayNameID", NULL, NULL, (LPBYTE)&dwMessageID, &cbData);
935
936 RegCloseKey(hKey);
937 HeapFree(GetProcessHeap(), 0, KeyPath);
938
939 return dwMessageID;
940 }
941
942
943 VOID
944 BuildLogList(void)
945 {
946 HKEY hKey;
947 DWORD lpcName;
948 DWORD dwIndex;
949 DWORD dwMessageID;
950 DWORD dwMaxKeyLength;
951 WCHAR szModuleName[MAX_PATH];
952 LPWSTR lpDisplayName;
953 HANDLE hLibrary = NULL;
954
955 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, EVENTLOG_BASE_KEY, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
956 {
957 return;
958 }
959
960 if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwNumLogs, &dwMaxKeyLength, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
961 {
962 RegCloseKey(hKey);
963 return;
964 }
965
966 if (!dwNumLogs)
967 {
968 RegCloseKey(hKey);
969 return;
970 }
971
972 LogNames = HeapAlloc(GetProcessHeap(), 0, (dwNumLogs + 1) * sizeof(WCHAR*));
973
974 if (!LogNames)
975 {
976 RegCloseKey(hKey);
977 return;
978 }
979
980 for (dwIndex = 0; dwIndex < dwNumLogs; dwIndex++)
981 {
982 LogNames[dwIndex] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((dwMaxKeyLength + 1) * sizeof(WCHAR)));
983
984 if (LogNames[dwIndex] != NULL)
985 {
986 lpcName = dwMaxKeyLength + 1;
987
988 if (RegEnumKeyExW(hKey, dwIndex, LogNames[dwIndex], &lpcName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
989 {
990 lpDisplayName = NULL;
991
992 ZeroMemory(szModuleName, sizeof(szModuleName));
993 GetDisplayNameFile(LogNames[dwIndex], szModuleName);
994 dwMessageID = GetDisplayNameID(LogNames[dwIndex]);
995
996 hLibrary = LoadLibraryExW(szModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
997 if (hLibrary != NULL)
998 {
999 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, hLibrary, dwMessageID, 0, (LPWSTR)&lpDisplayName, 0, NULL);
1000 FreeLibrary(hLibrary);
1001 }
1002
1003 if (lpDisplayName)
1004 {
1005 InsertMenuW(hMainMenu, ID_SAVE_PROTOCOL, MF_BYCOMMAND | MF_STRING, ID_FIRST_LOG + dwIndex, lpDisplayName);
1006 }
1007 else
1008 {
1009 InsertMenuW(hMainMenu, ID_SAVE_PROTOCOL, MF_BYCOMMAND | MF_STRING, ID_FIRST_LOG + dwIndex, LogNames[dwIndex]);
1010 }
1011
1012 LocalFree(lpDisplayName);
1013 }
1014 }
1015 }
1016
1017 InsertMenuW(hMainMenu, ID_SAVE_PROTOCOL, MF_BYCOMMAND | MF_SEPARATOR, ID_FIRST_LOG + dwIndex + 1, NULL);
1018
1019 RegCloseKey(hKey);
1020
1021 return;
1022 }
1023
1024
1025 VOID
1026 FreeLogList(void)
1027 {
1028 DWORD dwIndex;
1029
1030 if (!LogNames)
1031 {
1032 return;
1033 }
1034
1035 for (dwIndex = 0; dwIndex < dwNumLogs; dwIndex++)
1036 {
1037 if (LogNames[dwIndex])
1038 {
1039 HeapFree(GetProcessHeap(), 0, LogNames[dwIndex]);
1040 }
1041
1042 DeleteMenu(hMainMenu, ID_FIRST_LOG + dwIndex, MF_BYCOMMAND);
1043 }
1044
1045 DeleteMenu(hMainMenu, ID_FIRST_LOG + dwIndex + 1, MF_BYCOMMAND);
1046
1047 HeapFree(GetProcessHeap(), 0, LogNames);
1048
1049 dwNumLogs = 0;
1050
1051 return;
1052 }
1053
1054
1055 BOOL
1056 InitInstance(HINSTANCE hInstance,
1057 int nCmdShow)
1058 {
1059 HIMAGELIST hSmall;
1060 LVCOLUMNW lvc = {0};
1061 WCHAR szTemp[256];
1062
1063 hInst = hInstance; // Store instance handle in our global variable
1064
1065 hwndMainWindow = CreateWindowW(szWindowClass,
1066 szTitle,
1067 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
1068 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
1069 NULL,
1070 NULL,
1071 hInstance,
1072 NULL);
1073 if (!hwndMainWindow)
1074 {
1075 return FALSE;
1076 }
1077
1078 hwndStatus = CreateWindowExW(0, // no extended styles
1079 STATUSCLASSNAMEW, // status bar
1080 L"Done.", // no text
1081 WS_CHILD | WS_BORDER | WS_VISIBLE, // styles
1082 0, 0, 0, 0, // x, y, cx, cy
1083 hwndMainWindow, // parent window
1084 (HMENU)100, // window ID
1085 hInstance, // instance
1086 NULL); // window data
1087
1088 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
1089 // and WS_BORDER to create the normal "sunken" look. Also note that
1090 // LVS_EX_ styles cannot be set in CreateWindowEx().
1091 hwndListView = CreateWindowExW(WS_EX_CLIENTEDGE,
1092 WC_LISTVIEWW,
1093 L"",
1094 LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | LVS_REPORT,
1095 0,
1096 0,
1097 243,
1098 200,
1099 hwndMainWindow,
1100 NULL,
1101 hInstance,
1102 NULL);
1103
1104 // After the ListView is created, we can add extended list view styles.
1105 (void)ListView_SetExtendedListViewStyle (hwndListView, LVS_EX_FULLROWSELECT);
1106
1107 // Create the ImageList
1108 hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
1109 GetSystemMetrics(SM_CYSMICON),
1110 ILC_MASK,
1111 1,
1112 1);
1113
1114 // Add event type icons to ImageList
1115 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INFORMATIONICON)));
1116 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WARNINGICON)));
1117 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ERRORICON)));
1118
1119 // Assign ImageList to List View
1120 (void)ListView_SetImageList (hwndListView, hSmall, LVSIL_SMALL);
1121
1122 // Now set up the listview with its columns.
1123 lvc.mask = LVCF_TEXT | LVCF_WIDTH;
1124 lvc.cx = 90;
1125 LoadStringW(hInstance,
1126 IDS_COLUMNTYPE,
1127 szTemp,
1128 sizeof(szTemp) / sizeof(WCHAR));
1129 lvc.pszText = szTemp;
1130 (void)ListView_InsertColumn(hwndListView, 0, &lvc);
1131
1132 lvc.cx = 70;
1133 LoadStringW(hInstance,
1134 IDS_COLUMNDATE,
1135 szTemp,
1136 sizeof(szTemp) / sizeof(WCHAR));
1137 lvc.pszText = szTemp;
1138 (void)ListView_InsertColumn(hwndListView, 1, &lvc);
1139
1140 lvc.cx = 70;
1141 LoadStringW(hInstance,
1142 IDS_COLUMNTIME,
1143 szTemp,
1144 sizeof(szTemp) / sizeof(WCHAR));
1145 lvc.pszText = szTemp;
1146 (void)ListView_InsertColumn(hwndListView, 2, &lvc);
1147
1148 lvc.cx = 150;
1149 LoadStringW(hInstance,
1150 IDS_COLUMNSOURCE,
1151 szTemp,
1152 sizeof(szTemp) / sizeof(WCHAR));
1153 lvc.pszText = szTemp;
1154 (void)ListView_InsertColumn(hwndListView, 3, &lvc);
1155
1156 lvc.cx = 100;
1157 LoadStringW(hInstance,
1158 IDS_COLUMNCATEGORY,
1159 szTemp,
1160 sizeof(szTemp) / sizeof(WCHAR));
1161 lvc.pszText = szTemp;
1162 (void)ListView_InsertColumn(hwndListView, 4, &lvc);
1163
1164 lvc.cx = 60;
1165 LoadStringW(hInstance,
1166 IDS_COLUMNEVENT,
1167 szTemp,
1168 sizeof(szTemp) / sizeof(WCHAR));
1169 lvc.pszText = szTemp;
1170 (void)ListView_InsertColumn(hwndListView, 5, &lvc);
1171
1172 lvc.cx = 120;
1173 LoadStringW(hInstance,
1174 IDS_COLUMNUSER,
1175 szTemp,
1176 sizeof(szTemp) / sizeof(WCHAR));
1177 lvc.pszText = szTemp;
1178 (void)ListView_InsertColumn(hwndListView, 6, &lvc);
1179
1180 lvc.cx = 100;
1181 LoadStringW(hInstance,
1182 IDS_COLUMNCOMPUTER,
1183 szTemp,
1184 sizeof(szTemp) / sizeof(WCHAR));
1185 lvc.pszText = szTemp;
1186 (void)ListView_InsertColumn(hwndListView, 7, &lvc);
1187
1188 lvc.cx = 0;
1189 LoadStringW(hInstance,
1190 IDS_COLUMNEVENTDATA,
1191 szTemp,
1192 sizeof(szTemp) / sizeof(WCHAR));
1193 lvc.pszText = szTemp;
1194 (void)ListView_InsertColumn(hwndListView, 8, &lvc);
1195
1196 // Initialize the save Dialog
1197 ZeroMemory(&sfn, sizeof(sfn));
1198 ZeroMemory(szSaveFilter, sizeof(szSaveFilter));
1199
1200 LoadStringW(hInst, IDS_SAVE_FILTER, szSaveFilter, MAX_LOADSTRING);
1201
1202 sfn.lStructSize = sizeof(sfn);
1203 sfn.hwndOwner = hwndMainWindow;
1204 sfn.hInstance = hInstance;
1205 sfn.lpstrFilter = szSaveFilter;
1206 sfn.lpstrInitialDir = NULL;
1207 sfn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE;
1208 sfn.lpstrDefExt = NULL;
1209
1210 ShowWindow(hwndMainWindow, nCmdShow);
1211 UpdateWindow(hwndMainWindow);
1212
1213 BuildLogList();
1214
1215 QueryEventMessages(lpComputerName, LogNames[0]);
1216
1217 CheckMenuRadioItem(GetMenu(hwndMainWindow), ID_FIRST_LOG, ID_FIRST_LOG + dwNumLogs, ID_FIRST_LOG, MF_BYCOMMAND);
1218
1219 return TRUE;
1220 }
1221
1222
1223 LRESULT CALLBACK
1224 WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1225 {
1226 RECT rect;
1227 NMHDR *hdr;
1228
1229 switch (message)
1230 {
1231 case WM_CREATE:
1232 hMainMenu = GetMenu(hWnd);
1233 break;
1234
1235 case WM_NOTIFY:
1236 switch (((LPNMHDR)lParam)->code)
1237 {
1238 case NM_DBLCLK :
1239 hdr = (NMHDR FAR*)lParam;
1240 if (hdr->hwndFrom == hwndListView)
1241 {
1242 LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
1243
1244 if (lpnmitem->iItem != -1)
1245 {
1246 DialogBox(hInst,
1247 MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG),
1248 hWnd,
1249 EventDetails);
1250 }
1251 }
1252 break;
1253 }
1254 break;
1255
1256 case WM_COMMAND:
1257 // Parse the menu selections:
1258
1259 if ((LOWORD(wParam) >= ID_FIRST_LOG) && (LOWORD(wParam) <= ID_FIRST_LOG + dwNumLogs))
1260 {
1261 if (LogNames[LOWORD(wParam) - ID_FIRST_LOG])
1262 {
1263 if (QueryEventMessages(lpComputerName, LogNames[LOWORD(wParam) - ID_FIRST_LOG]))
1264 {
1265 CheckMenuRadioItem(GetMenu(hWnd), ID_FIRST_LOG, ID_FIRST_LOG + dwNumLogs, LOWORD(wParam), MF_BYCOMMAND);
1266 }
1267 }
1268 }
1269 else
1270
1271 switch (LOWORD(wParam))
1272 {
1273 case ID_SAVE_PROTOCOL:
1274 SaveProtocol();
1275 break;
1276
1277 case ID_CLEAR_EVENTS:
1278 if (ClearEvents())
1279 {
1280 Refresh();
1281 }
1282 break;
1283
1284 case IDM_REFRESH:
1285 Refresh();
1286 break;
1287
1288 case IDM_ABOUT:
1289 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
1290 break;
1291
1292 case IDM_HELP:
1293 MessageBoxW(hwndMainWindow,
1294 L"Help not implemented yet!",
1295 L"Event Log",
1296 MB_OK | MB_ICONINFORMATION);
1297 break;
1298
1299 case IDM_EXIT:
1300 DestroyWindow(hWnd);
1301 break;
1302
1303 default:
1304 return DefWindowProc(hWnd, message, wParam, lParam);
1305 }
1306 break;
1307
1308 case WM_SIZE:
1309 {
1310 // Gets the window rectangle
1311 GetClientRect(hWnd, &rect);
1312
1313 // Relocate the listview
1314 MoveWindow(hwndListView,
1315 0,
1316 0,
1317 rect.right,
1318 rect.bottom - 20,
1319 1);
1320
1321 // Resize the statusbar;
1322 SendMessage(hwndStatus, message, wParam, lParam);
1323 }
1324 break;
1325 case WM_DESTROY:
1326 FreeRecords();
1327 FreeLogList();
1328 PostQuitMessage(0);
1329 break;
1330
1331 default:
1332 return DefWindowProc(hWnd, message, wParam, lParam);
1333 }
1334
1335 return 0;
1336 }
1337
1338
1339 // Message handler for about box.
1340 INT_PTR CALLBACK
1341 About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1342 {
1343 UNREFERENCED_PARAMETER(lParam);
1344 switch (message)
1345 {
1346 case WM_INITDIALOG:
1347 {
1348 return (INT_PTR)TRUE;
1349 }
1350
1351 case WM_COMMAND:
1352 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
1353 {
1354 EndDialog(hDlg, LOWORD(wParam));
1355 return (INT_PTR)TRUE;
1356 }
1357 break;
1358 }
1359
1360 return (INT_PTR)FALSE;
1361 }
1362
1363 VOID
1364 DisplayEvent(HWND hDlg)
1365 {
1366 WCHAR szEventType[MAX_PATH];
1367 WCHAR szTime[MAX_PATH];
1368 WCHAR szDate[MAX_PATH];
1369 WCHAR szUser[MAX_PATH];
1370 WCHAR szComputer[MAX_PATH];
1371 WCHAR szSource[MAX_PATH];
1372 WCHAR szCategory[MAX_PATH];
1373 WCHAR szEventID[MAX_PATH];
1374 WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER];
1375 WCHAR szEventData[MAX_PATH];
1376 BOOL bEventData = FALSE;
1377 LVITEMW li;
1378 EVENTLOGRECORD* pevlr;
1379 int iIndex;
1380
1381 // Get index of selected item
1382 iIndex = (int)SendMessage (hwndListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED | LVNI_FOCUSED);
1383
1384 li.mask = LVIF_PARAM;
1385 li.iItem = iIndex;
1386 li.iSubItem = 0;
1387
1388 (void)ListView_GetItem(hwndListView, &li);
1389
1390 pevlr = (EVENTLOGRECORD*)li.lParam;
1391
1392 if (iIndex != -1)
1393 {
1394 ListView_GetItemText(hwndListView, iIndex, 0, szEventType, sizeof(szEventType) / sizeof(WCHAR));
1395 ListView_GetItemText(hwndListView, iIndex, 1, szDate, sizeof(szDate) / sizeof(WCHAR));
1396 ListView_GetItemText(hwndListView, iIndex, 2, szTime, sizeof(szTime) / sizeof(WCHAR));
1397 ListView_GetItemText(hwndListView, iIndex, 3, szSource, sizeof(szSource) / sizeof(WCHAR));
1398 ListView_GetItemText(hwndListView, iIndex, 4, szCategory, sizeof(szCategory) / sizeof(WCHAR));
1399 ListView_GetItemText(hwndListView, iIndex, 5, szEventID, sizeof(szEventID) / sizeof(WCHAR));
1400 ListView_GetItemText(hwndListView, iIndex, 6, szUser, sizeof(szUser) / sizeof(WCHAR));
1401 ListView_GetItemText(hwndListView, iIndex, 7, szComputer, sizeof(szComputer) / sizeof(WCHAR));
1402
1403 bEventData = !(pevlr->DataLength == 0);
1404
1405 if (pevlr->DataLength > 0)
1406 {
1407 MultiByteToWideChar(CP_ACP,
1408 0,
1409 (LPCSTR)((LPBYTE)pevlr + pevlr->DataOffset),
1410 pevlr->DataLength,
1411 szEventData,
1412 MAX_PATH);
1413 }
1414
1415 GetEventMessage(lpSourceLogName, szSource, pevlr, szEventText);
1416
1417 EnableWindow(GetDlgItem(hDlg, IDC_BYTESRADIO), bEventData);
1418 EnableWindow(GetDlgItem(hDlg, IDC_WORDRADIO), bEventData);
1419
1420 SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate);
1421 SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime);
1422
1423 SetDlgItemTextW(hDlg, IDC_EVENTUSERSTATIC, szUser);
1424 SetDlgItemTextW(hDlg, IDC_EVENTSOURCESTATIC, szSource);
1425 SetDlgItemTextW(hDlg, IDC_EVENTCOMPUTERSTATIC, szComputer);
1426 SetDlgItemTextW(hDlg, IDC_EVENTCATEGORYSTATIC, szCategory);
1427 SetDlgItemTextW(hDlg, IDC_EVENTIDSTATIC, szEventID);
1428 SetDlgItemTextW(hDlg, IDC_EVENTTYPESTATIC, szEventType);
1429 SetDlgItemTextW(hDlg, IDC_EVENTTEXTEDIT, szEventText);
1430 SetDlgItemTextW(hDlg, IDC_EVENTDATAEDIT, szEventData);
1431 }
1432 else
1433 {
1434 MessageBoxW(NULL,
1435 L"No Items in ListView",
1436 L"Error",
1437 MB_OK | MB_ICONINFORMATION);
1438 }
1439 }
1440
1441
1442 static
1443 INT_PTR CALLBACK
1444 StatusMessageWindowProc(IN HWND hwndDlg,
1445 IN UINT uMsg,
1446 IN WPARAM wParam,
1447 IN LPARAM lParam)
1448 {
1449 UNREFERENCED_PARAMETER(wParam);
1450
1451 switch (uMsg)
1452 {
1453 case WM_INITDIALOG:
1454 {
1455 return TRUE;
1456 }
1457 }
1458 return FALSE;
1459 }
1460
1461
1462 // Message handler for event details box.
1463 INT_PTR CALLBACK
1464 EventDetails(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1465 {
1466 UNREFERENCED_PARAMETER(lParam);
1467
1468 switch (message)
1469 {
1470 case WM_INITDIALOG:
1471 // Show event info on dialog box
1472 DisplayEvent(hDlg);
1473 return (INT_PTR)TRUE;
1474
1475 case WM_COMMAND:
1476 switch (LOWORD(wParam))
1477 {
1478 case IDOK:
1479 case IDCANCEL:
1480 EndDialog(hDlg, LOWORD(wParam));
1481 return (INT_PTR)TRUE;
1482
1483 case IDPREVIOUS:
1484 SendMessage(hwndListView, WM_KEYDOWN, VK_UP, 0);
1485
1486 // Show event info on dialog box
1487 DisplayEvent(hDlg);
1488 return (INT_PTR)TRUE;
1489
1490 case IDNEXT:
1491 SendMessage(hwndListView, WM_KEYDOWN, VK_DOWN, 0);
1492
1493 // Show event info on dialog box
1494 DisplayEvent(hDlg);
1495 return (INT_PTR)TRUE;
1496
1497 case IDC_BYTESRADIO:
1498 return (INT_PTR)TRUE;
1499
1500 case IDC_WORDRADIO:
1501 return (INT_PTR)TRUE;
1502
1503 case IDHELP:
1504 MessageBoxW(hDlg,
1505 L"Help not implemented yet!",
1506 L"Event Log",
1507 MB_OK | MB_ICONINFORMATION);
1508 return (INT_PTR)TRUE;
1509
1510 default:
1511 break;
1512 }
1513 break;
1514 }
1515
1516 return (INT_PTR)FALSE;
1517 }