2 * ReactOS Win32 Applications
3 * Copyright (C) 2007 ReactOS Team
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.
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.
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.
20 * COPYRIGHT : See COPYING in the top level directory
21 * PROJECT : Event Log Viewer
23 * PROGRAMMER: Marc Piulachs (marc.piulachs at codexchange [dot] net)
40 #pragma warning(disable: 4996) /* 'strdup' was declared deprecated */
41 #define _CRT_SECURE_NO_DEPRECATE /* all deprecated unsafe string functions */
44 static const WCHAR szWindowClass
[] = L
"EVENTVWR"; /* the main window class name*/
45 static const WCHAR EVENTLOG_BASE_KEY
[] = L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
47 // MessageFile message buffer size
48 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10
49 #define EVENT_MESSAGE_FILE_BUFFER 1024*10
50 #define EVENT_DLL_SEPARATOR L";"
51 #define EVENT_MESSAGE_FILE L"EventMessageFile"
52 #define EVENT_CATEGORY_MESSAGE_FILE L"CategoryMessageFile"
53 #define EVENT_PARAMETER_MESSAGE_FILE L"ParameterMessageFile"
55 #define MAX_LOADSTRING 255
58 HINSTANCE hInst
; /* current instance */
59 WCHAR szTitle
[MAX_LOADSTRING
]; /* The title bar text */
60 WCHAR szTitleTemplate
[MAX_LOADSTRING
]; /* The logged-on title bar text */
61 WCHAR szSaveFilter
[MAX_LOADSTRING
]; /* Filter Mask for the save Dialog */
62 HWND hwndMainWindow
; /* Main window */
63 HWND hwndListView
; /* ListView control */
64 HWND hwndStatus
; /* Status bar */
65 HMENU hMainMenu
; /* The application's main menu */
66 WCHAR szStatusBarTemplate
[MAX_LOADSTRING
]; /* The status bar text */
67 PEVENTLOGRECORD
*g_RecordPtrs
= NULL
;
68 DWORD g_TotalRecords
= 0;
71 LPWSTR lpSourceLogName
= NULL
;
72 LPWSTR lpComputerName
= NULL
;
77 /* Forward declarations of functions included in this code module: */
78 ATOM
MyRegisterClass(HINSTANCE hInstance
);
79 BOOL
InitInstance(HINSTANCE
, int);
80 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
81 INT_PTR CALLBACK
About(HWND
, UINT
, WPARAM
, LPARAM
);
82 INT_PTR CALLBACK
EventDetails(HWND
, UINT
, WPARAM
, LPARAM
);
83 static INT_PTR CALLBACK
StatusMessageWindowProc (HWND
, UINT
, WPARAM
, LPARAM
);
87 wWinMain(HINSTANCE hInstance
,
88 HINSTANCE hPrevInstance
,
94 INITCOMMONCONTROLSEX iccx
;
96 UNREFERENCED_PARAMETER(hPrevInstance
);
97 UNREFERENCED_PARAMETER(lpCmdLine
);
99 /* Whenever any of the common controls are used in your app,
100 * you must call InitCommonControlsEx() to register the classes
101 * for those controls. */
102 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
103 iccx
.dwICC
= ICC_LISTVIEW_CLASSES
;
104 InitCommonControlsEx(&iccx
);
106 /* Initialize global strings */
107 LoadStringW(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
108 LoadStringW(hInstance
, IDS_APP_TITLE_EX
, szTitleTemplate
, MAX_LOADSTRING
);
109 LoadStringW(hInstance
, IDS_STATUS_MSG
, szStatusBarTemplate
, MAX_LOADSTRING
);
110 MyRegisterClass(hInstance
);
112 /* Perform application initialization: */
113 if (!InitInstance(hInstance
, nCmdShow
))
118 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_EVENTVWR
));
120 /* Main message loop: */
121 while (GetMessageW(&msg
, NULL
, 0, 0))
123 if (!TranslateAcceleratorW(msg
.hwnd
, hAccelTable
, &msg
))
125 TranslateMessage(&msg
);
126 DispatchMessage(&msg
);
130 return (int)msg
.wParam
;
133 static void FreeRecords(void)
140 for (iIndex
= 0; iIndex
< g_TotalRecords
; iIndex
++)
141 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
[iIndex
]);
142 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
);
147 ShowLastWin32Error(VOID
)
150 LPWSTR lpMessageBuffer
;
152 dwError
= GetLastError();
153 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
157 (LPWSTR
)&lpMessageBuffer
,
161 MessageBoxW(hwndMainWindow
, lpMessageBuffer
, szTitle
, MB_OK
| MB_ICONERROR
);
162 LocalFree(lpMessageBuffer
);
166 EventTimeToSystemTime(DWORD EventTime
,
167 SYSTEMTIME
*pSystemTime
)
169 SYSTEMTIME st1970
= { 1970, 1, 0, 1, 0, 0, 0, 0 };
177 uUCT
.ft
.dwHighDateTime
= 0;
178 uUCT
.ft
.dwLowDateTime
= EventTime
;
179 SystemTimeToFileTime(&st1970
, &u1970
.ft
);
180 uUCT
.ll
= uUCT
.ll
* 10000000 + u1970
.ll
;
181 FileTimeToLocalFileTime(&uUCT
.ft
, &ftLocal
);
182 FileTimeToSystemTime(&ftLocal
, pSystemTime
);
193 c
= s
+ wcslen(s
) - 1;
194 while (c
>= s
&& iswspace(*c
))
202 GetEventMessageFileDLL(IN LPCWSTR lpLogName
,
203 IN LPCWSTR SourceName
,
204 IN LPCWSTR EntryName
,
205 OUT LPWSTR ExpandedName
)
208 BYTE szModuleName
[MAX_PATH
];
209 WCHAR szKeyName
[MAX_PATH
];
211 HKEY hSourceKey
= NULL
;
212 BOOL bReturn
= FALSE
;
214 wcscpy(szKeyName
, L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\");
215 wcscat(szKeyName
, lpLogName
);
217 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
221 &hAppKey
) == ERROR_SUCCESS
)
223 if (RegOpenKeyExW(hAppKey
,
227 &hSourceKey
) == ERROR_SUCCESS
)
230 if (RegQueryValueExW(hSourceKey
,
234 (LPBYTE
)szModuleName
,
235 &dwSize
) == ERROR_SUCCESS
)
237 /* Returns a string containing the requested substituted environment variable. */
238 ExpandEnvironmentStringsW((LPCWSTR
)szModuleName
, ExpandedName
, MAX_PATH
);
247 ShowLastWin32Error();
250 if (hSourceKey
!= NULL
)
251 RegCloseKey(hSourceKey
);
254 RegCloseKey(hAppKey
);
261 GetEventCategory(IN LPCWSTR KeyName
,
262 IN LPCWSTR SourceName
,
263 IN EVENTLOGRECORD
*pevlr
,
264 OUT LPWSTR CategoryName
)
266 HANDLE hLibrary
= NULL
;
267 WCHAR szMessageDLL
[MAX_PATH
];
268 LPVOID lpMsgBuf
= NULL
;
270 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_CATEGORY_MESSAGE_FILE
, szMessageDLL
))
272 hLibrary
= LoadLibraryExW(szMessageDLL
,
274 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
275 if (hLibrary
!= NULL
)
277 /* Retrieve the message string. */
278 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
280 pevlr
->EventCategory
,
281 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
283 EVENT_MESSAGE_FILE_BUFFER
,
286 /* Trim the string */
289 /* Copy the category name */
290 wcscpy(CategoryName
, lpMsgBuf
);
294 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
297 if (hLibrary
!= NULL
)
298 FreeLibrary(hLibrary
);
300 /* Free the buffer allocated by FormatMessage */
308 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
315 GetEventMessage(IN LPCWSTR KeyName
,
316 IN LPCWSTR SourceName
,
317 IN EVENTLOGRECORD
*pevlr
,
318 OUT LPWSTR EventText
)
321 HANDLE hLibrary
= NULL
;
322 WCHAR SourceModuleName
[1000];
323 WCHAR ParameterModuleName
[1000];
324 LPWSTR lpMsgBuf
= NULL
;
325 WCHAR szStringIDNotFound
[MAX_LOADSTRING
];
331 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
332 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_MESSAGE_FILE
, SourceModuleName
))
334 /* Get the event message */
335 szMessage
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->StringOffset
);
337 /* Allocate space for parameters */
338 szArguments
= malloc(sizeof(LPVOID
) * pevlr
->NumStrings
);
344 for (i
= 0; i
< pevlr
->NumStrings
; i
++)
346 if (wcsstr(szMessage
, L
"%%"))
348 if (GetEventMessageFileDLL(KeyName
, SourceName
, EVENT_PARAMETER_MESSAGE_FILE
, ParameterModuleName
))
350 /* Not yet support for reading messages from parameter message DLL */
354 szArguments
[i
] = szMessage
;
355 szMessage
+= wcslen(szMessage
) + 1;
358 szDll
= wcstok(SourceModuleName
, EVENT_DLL_SEPARATOR
);
359 while ((szDll
!= NULL
) && (!bDone
))
361 hLibrary
= LoadLibraryExW(szDll
,
363 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
364 if (hLibrary
== NULL
)
366 /* The DLL could not be loaded try the next one (if any) */
367 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
371 /* Retrieve the message string. */
372 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
|
373 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
374 FORMAT_MESSAGE_FROM_HMODULE
|
375 FORMAT_MESSAGE_ARGUMENT_ARRAY
,
378 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
381 (va_list*)szArguments
) == 0)
383 /* We haven't found the string , get next DLL (if any) */
384 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
390 /* The ID was found and the message was formated */
393 /* Trim the string */
394 TrimNulls((LPWSTR
)lpMsgBuf
);
396 /* Copy the event text */
397 wcscpy(EventText
,lpMsgBuf
);
401 FreeLibrary(hLibrary
);
407 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
408 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
413 /* No more dlls to try, return result */
417 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
418 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
425 GetEventType(IN WORD dwEventType
,
426 OUT LPWSTR eventTypeText
)
430 case EVENTLOG_ERROR_TYPE
:
431 LoadStringW(hInst
, IDS_EVENTLOG_ERROR_TYPE
, eventTypeText
, MAX_LOADSTRING
);
433 case EVENTLOG_WARNING_TYPE
:
434 LoadStringW(hInst
, IDS_EVENTLOG_WARNING_TYPE
, eventTypeText
, MAX_LOADSTRING
);
436 case EVENTLOG_INFORMATION_TYPE
:
437 LoadStringW(hInst
, IDS_EVENTLOG_INFORMATION_TYPE
, eventTypeText
, MAX_LOADSTRING
);
439 case EVENTLOG_AUDIT_SUCCESS
:
440 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
442 case EVENTLOG_AUDIT_FAILURE
:
443 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_FAILURE
, eventTypeText
, MAX_LOADSTRING
);
445 case EVENTLOG_SUCCESS
:
446 LoadStringW(hInst
, IDS_EVENTLOG_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
449 LoadStringW(hInst
, IDS_EVENTLOG_UNKNOWN_TYPE
, eventTypeText
, MAX_LOADSTRING
);
455 GetEventUserName(EVENTLOGRECORD
*pelr
,
460 WCHAR szDomain
[1024];
463 DWORD cbDomain
= 1024;
465 /* Point to the SID. */
466 lpSid
= (PSID
)((LPBYTE
)pelr
+ pelr
->UserSidOffset
);
469 if (pelr
->UserSidLength
> 0)
471 if (LookupAccountSidW(NULL
,
479 wcscpy(pszUser
, szName
);
489 ShowStatusMessageThread(IN LPVOID lpParameter
)
491 HWND
*phWnd
= (HWND
*)lpParameter
;
495 hWnd
= CreateDialogParam(hInst
,
496 MAKEINTRESOURCE(IDD_PROGRESSBOX
),
498 StatusMessageWindowProc
,
505 ShowWindow(hWnd
, SW_SHOW
);
507 /* Message loop for the Status window */
508 while (GetMessage(&Msg
, NULL
, 0, 0))
510 TranslateMessage(&Msg
);
511 DispatchMessage(&Msg
);
519 QueryEventMessages(LPWSTR lpMachineName
,
524 EVENTLOGRECORD
*pevlr
;
525 DWORD dwRead
, dwNeeded
, dwThisRecord
, dwTotalRecords
= 0, dwCurrentRecord
= 0, dwRecordsToRead
= 0, dwFlags
, dwMaxLength
;
527 LPWSTR lpComputerName
;
529 BOOL bResult
= TRUE
; /* Read succeeded. */
532 WCHAR szWindowTitle
[MAX_PATH
];
533 WCHAR szStatusText
[MAX_PATH
];
534 WCHAR szLocalDate
[MAX_PATH
];
535 WCHAR szLocalTime
[MAX_PATH
];
536 WCHAR szEventID
[MAX_PATH
];
537 WCHAR szEventTypeText
[MAX_PATH
];
538 WCHAR szCategoryID
[MAX_PATH
];
539 WCHAR szUsername
[MAX_PATH
];
540 WCHAR szEventText
[EVENT_MESSAGE_FILE_BUFFER
];
541 WCHAR szCategory
[MAX_PATH
];
542 WCHAR szData
[MAX_PATH
];
545 LVITEMW lviEventItem
;
547 dwFlags
= EVENTLOG_FORWARDS_READ
| EVENTLOG_SEQUENTIAL_READ
;
549 /* Open the event log. */
550 hEventLog
= OpenEventLogW(lpMachineName
,
552 if (hEventLog
== NULL
)
554 ShowLastWin32Error();
558 lpSourceLogName
= lpLogName
;
559 lpComputerName
= lpMachineName
;
561 /* Disable listview redraw */
562 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
564 /* Clear the list view */
565 (void)ListView_DeleteAllItems (hwndListView
);
568 GetOldestEventLogRecord(hEventLog
, &dwThisRecord
);
570 /* Get the total number of event log records. */
571 GetNumberOfEventLogRecords (hEventLog
, &dwTotalRecords
);
572 g_TotalRecords
= dwTotalRecords
;
574 if (dwTotalRecords
> 0)
576 EnableMenuItem(hMainMenu
, ID_CLEAR_EVENTS
, MF_BYCOMMAND
| MF_ENABLED
);
577 EnableMenuItem(hMainMenu
, ID_SAVE_PROTOCOL
, MF_BYCOMMAND
| MF_ENABLED
);
581 EnableMenuItem(hMainMenu
, ID_CLEAR_EVENTS
, MF_BYCOMMAND
| MF_GRAYED
);
582 EnableMenuItem(hMainMenu
, ID_SAVE_PROTOCOL
, MF_BYCOMMAND
| MF_GRAYED
);
585 g_RecordPtrs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalRecords
* sizeof(PVOID
));
587 /* If we have at least 1000 records show the waiting dialog */
588 if (dwTotalRecords
> 1000)
590 CloseHandle(CreateThread(NULL
,
592 ShowStatusMessageThread
,
598 while (dwCurrentRecord
< dwTotalRecords
)
600 pevlr
= HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD
) * dwTotalRecords
);
601 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
603 bResult
= ReadEventLog(hEventLog
, // Event log handle
604 dwFlags
, // Sequential read
605 0, // Ignored for sequential read
606 pevlr
, // Pointer to buffer
607 sizeof(EVENTLOGRECORD
), // Size of buffer
608 &dwRead
, // Number of bytes read
609 &dwNeeded
); // Bytes in the next record
610 if((!bResult
) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER
))
612 HeapFree(GetProcessHeap(), 0, pevlr
);
613 pevlr
= HeapAlloc(GetProcessHeap(), 0, dwNeeded
);
614 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
616 ReadEventLogW(hEventLog
, // event log handle
617 dwFlags
, // read flags
618 0, // offset; default is 0
619 pevlr
, // pointer to buffer
620 dwNeeded
, // size of buffer
621 &dwRead
, // number of bytes read
622 &dwNeeded
); // bytes in next record
627 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szUsername
, MAX_PATH
);
628 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szEventText
, MAX_PATH
);
629 LoadStringW(hInst
, IDS_NONE
, szCategory
, MAX_PATH
);
631 // Get the event source name.
632 lpSourceName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
));
634 // Get the computer name
635 lpComputerName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
) + (wcslen(lpSourceName
) + 1) * sizeof(WCHAR
));
637 // This ist the data section of the current event
638 lpData
= (LPSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
);
640 // Compute the event type
641 EventTimeToSystemTime(pevlr
->TimeWritten
, &time
);
643 // Get the username that generated the event
644 GetEventUserName(pevlr
, szUsername
);
646 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &time
, NULL
, szLocalDate
, MAX_PATH
);
647 GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &time
, NULL
, szLocalTime
, MAX_PATH
);
649 GetEventType(pevlr
->EventType
, szEventTypeText
);
650 GetEventCategory(lpLogName
, lpSourceName
, pevlr
, szCategory
);
652 swprintf(szEventID
, L
"%u", (pevlr
->EventID
& 0xFFFF));
653 swprintf(szCategoryID
, L
"%u", pevlr
->EventCategory
);
655 lviEventItem
.mask
= LVIF_IMAGE
| LVIF_TEXT
| LVIF_PARAM
;
656 lviEventItem
.iItem
= 0;
657 lviEventItem
.iSubItem
= 0;
658 lviEventItem
.lParam
= (LPARAM
)pevlr
;
659 lviEventItem
.pszText
= szEventTypeText
;
661 switch (pevlr
->EventType
)
663 case EVENTLOG_ERROR_TYPE
:
664 lviEventItem
.iImage
= 2;
667 case EVENTLOG_AUDIT_FAILURE
:
668 lviEventItem
.iImage
= 2;
671 case EVENTLOG_WARNING_TYPE
:
672 lviEventItem
.iImage
= 1;
675 case EVENTLOG_INFORMATION_TYPE
:
676 lviEventItem
.iImage
= 0;
679 case EVENTLOG_AUDIT_SUCCESS
:
680 lviEventItem
.iImage
= 0;
683 case EVENTLOG_SUCCESS
:
684 lviEventItem
.iImage
= 0;
688 lviEventItem
.iItem
= ListView_InsertItem(hwndListView
, &lviEventItem
);
690 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 1, szLocalDate
);
691 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 2, szLocalTime
);
692 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 3, lpSourceName
);
693 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 4, szCategory
);
694 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 5, szEventID
);
695 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 6, szUsername
); //User
696 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 7, lpComputerName
); //Computer
697 MultiByteToWideChar(CP_ACP
,
703 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 8, szData
); //Event Text
705 dwRead
-= pevlr
->Length
;
706 pevlr
= (EVENTLOGRECORD
*)((LPBYTE
) pevlr
+ pevlr
->Length
);
714 EndDialog(hwndDlg
, 0);
717 i
= swprintf(szWindowTitle
, szTitleTemplate
, szTitle
, lpLogName
); /* i = number of characters written */
718 /* lpComputerName can be NULL here if no records was read */
719 dwMaxLength
= sizeof(szWindowTitle
) / sizeof(WCHAR
) - i
;
721 GetComputerNameW(szWindowTitle
+i
, &dwMaxLength
);
723 _snwprintf(szWindowTitle
+i
, dwMaxLength
, L
"%s", lpComputerName
);
725 swprintf(szStatusText
, szStatusBarTemplate
, lpLogName
, dwTotalRecords
);
727 // Update the status bar
728 SendMessageW(hwndStatus
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)szStatusText
);
730 // Set the window title
731 SetWindowTextW(hwndMainWindow
, szWindowTitle
);
733 // Resume list view redraw
734 SendMessageW(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
736 // Close the event log.
737 CloseEventLog(hEventLog
);
747 WCHAR szFileName
[MAX_PATH
];
749 ZeroMemory(szFileName
, sizeof(szFileName
));
751 sfn
.lpstrFile
= szFileName
;
752 sfn
.nMaxFile
= MAX_PATH
;
754 if (!GetSaveFileNameW(&sfn
))
759 hEventLog
= OpenEventLogW(lpComputerName
, lpSourceLogName
);
762 ShowLastWin32Error();
766 if (!BackupEventLogW(hEventLog
, szFileName
))
768 ShowLastWin32Error();
771 CloseEventLog(hEventLog
);
779 WCHAR szFileName
[MAX_PATH
];
780 WCHAR szMessage
[MAX_LOADSTRING
];
782 ZeroMemory(szFileName
, sizeof(szFileName
));
783 ZeroMemory(szMessage
, sizeof(szMessage
));
785 LoadStringW(hInst
, IDS_CLEAREVENTS_MSG
, szMessage
, MAX_LOADSTRING
);
787 sfn
.lpstrFile
= szFileName
;
788 sfn
.nMaxFile
= MAX_PATH
;
790 switch (MessageBoxW(hwndMainWindow
, szMessage
, szTitle
, MB_YESNOCANCEL
| MB_ICONINFORMATION
))
800 sfn
.lpstrFile
= NULL
;
806 if (!GetSaveFileNameW(&sfn
))
814 hEventLog
= OpenEventLogW(lpComputerName
, lpSourceLogName
);
817 ShowLastWin32Error();
821 if (!ClearEventLogW(hEventLog
, sfn
.lpstrFile
))
823 ShowLastWin32Error();
824 CloseEventLog(hEventLog
);
828 CloseEventLog(hEventLog
);
837 QueryEventMessages(lpComputerName
,
843 MyRegisterClass(HINSTANCE hInstance
)
847 wcex
.cbSize
= sizeof(WNDCLASSEX
);
850 wcex
.lpfnWndProc
= WndProc
;
853 wcex
.hInstance
= hInstance
;
854 wcex
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_EVENTVWR
));
855 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
856 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
857 wcex
.lpszMenuName
= MAKEINTRESOURCE(IDC_EVENTVWR
);
858 wcex
.lpszClassName
= szWindowClass
;
859 wcex
.hIconSm
= LoadIcon(wcex
.hInstance
, MAKEINTRESOURCE(IDI_SMALL
));
861 return RegisterClassExW(&wcex
);
866 GetDisplayNameFile(LPCWSTR lpLogName
, LPWSTR lpModuleName
)
870 WCHAR szModuleName
[MAX_PATH
];
874 KeyPath
= (WCHAR
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (wcslen(EVENTLOG_BASE_KEY
) + wcslen(lpLogName
) + 1) * sizeof(WCHAR
));
880 wcscpy(KeyPath
, EVENTLOG_BASE_KEY
);
881 wcscat(KeyPath
, lpLogName
);
883 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, KeyPath
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
885 HeapFree(GetProcessHeap(), 0, KeyPath
);
891 if (RegQueryValueExW(hKey
, L
"DisplayNameFile", NULL
, NULL
, (LPBYTE
)szModuleName
, &dwData
) == ERROR_SUCCESS
)
893 ExpandEnvironmentStringsW(szModuleName
, lpModuleName
, MAX_PATH
);
897 HeapFree(GetProcessHeap(), 0, KeyPath
);
902 GetDisplayNameID(LPCWSTR lpLogName
)
906 DWORD dwMessageID
= 0;
909 KeyPath
= (WCHAR
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (wcslen(EVENTLOG_BASE_KEY
) + wcslen(lpLogName
) + 1) * sizeof(WCHAR
));
915 wcscpy(KeyPath
, EVENTLOG_BASE_KEY
);
916 wcscat(KeyPath
, lpLogName
);
918 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, KeyPath
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
920 HeapFree(GetProcessHeap(), 0, KeyPath
);
924 dwData
= sizeof(dwMessageID
);
926 RegQueryValueExW(hKey
, L
"DisplayNameID", NULL
, NULL
, (LPBYTE
)&dwMessageID
, &dwData
);
929 HeapFree(GetProcessHeap(), 0, KeyPath
);
942 DWORD dwMaxKeyLength
;
943 WCHAR szModuleName
[MAX_PATH
];
944 LPWSTR lpDisplayName
;
945 HANDLE hLibrary
= NULL
;
947 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, EVENTLOG_BASE_KEY
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
952 if (RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, &dwNumLogs
, &dwMaxKeyLength
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
964 LogNames
= (WCHAR
**)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (dwNumLogs
+ 1) * sizeof(WCHAR
*));
972 for (dwIndex
= 0; dwIndex
< dwNumLogs
; dwIndex
++)
974 LogNames
[dwIndex
] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ((dwMaxKeyLength
+ 1) * sizeof(WCHAR
)));
976 if (LogNames
[dwIndex
] != NULL
)
978 lpcName
= dwMaxKeyLength
+ 1;
980 if (RegEnumKeyExW(hKey
, dwIndex
, LogNames
[dwIndex
], &lpcName
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
982 lpDisplayName
= NULL
;
984 ZeroMemory(szModuleName
, sizeof(szModuleName
));
985 GetDisplayNameFile(LogNames
[dwIndex
], szModuleName
);
986 dwMessageID
= GetDisplayNameID(LogNames
[dwIndex
]);
988 hLibrary
= LoadLibraryExW(szModuleName
, NULL
, DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
989 if (hLibrary
!= NULL
)
991 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE
, hLibrary
, dwMessageID
, 0, (LPWSTR
)&lpDisplayName
, 0, NULL
);
992 FreeLibrary(hLibrary
);
997 InsertMenuW(hMainMenu
, ID_SAVE_PROTOCOL
, MF_BYCOMMAND
| MF_STRING
, ID_FIRST_LOG
+ dwIndex
, lpDisplayName
);
1001 InsertMenuW(hMainMenu
, ID_SAVE_PROTOCOL
, MF_BYCOMMAND
| MF_STRING
, ID_FIRST_LOG
+ dwIndex
, LogNames
[dwIndex
]);
1004 LocalFree(lpDisplayName
);
1009 InsertMenuW(hMainMenu
, ID_SAVE_PROTOCOL
, MF_BYCOMMAND
| MF_SEPARATOR
, ID_FIRST_LOG
+ dwIndex
+ 1, NULL
);
1027 for (dwIndex
= 0; dwIndex
< dwNumLogs
; dwIndex
++)
1029 if (LogNames
[dwIndex
])
1031 HeapFree(GetProcessHeap(), 0, LogNames
[dwIndex
]);
1034 DeleteMenu(hMainMenu
, ID_FIRST_LOG
+ dwIndex
, MF_BYCOMMAND
);
1037 DeleteMenu(hMainMenu
, ID_FIRST_LOG
+ dwIndex
+ 1, MF_BYCOMMAND
);
1039 HeapFree(GetProcessHeap(), 0, LogNames
);
1048 InitInstance(HINSTANCE hInstance
,
1052 LVCOLUMNW lvc
= {0};
1055 hInst
= hInstance
; // Store instance handle in our global variable
1057 hwndMainWindow
= CreateWindowW(szWindowClass
,
1059 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
1060 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
1065 if (!hwndMainWindow
)
1070 hwndStatus
= CreateWindowExW(0, // no extended styles
1071 STATUSCLASSNAMEW
, // status bar
1072 L
"Done.", // no text
1073 WS_CHILD
| WS_BORDER
| WS_VISIBLE
, // styles
1074 0, 0, 0, 0, // x, y, cx, cy
1075 hwndMainWindow
, // parent window
1076 (HMENU
)100, // window ID
1077 hInstance
, // instance
1078 NULL
); // window data
1080 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
1081 // and WS_BORDER to create the normal "sunken" look. Also note that
1082 // LVS_EX_ styles cannot be set in CreateWindowEx().
1083 hwndListView
= CreateWindowExW(WS_EX_CLIENTEDGE
,
1086 LVS_SHOWSELALWAYS
| WS_CHILD
| WS_VISIBLE
| LVS_REPORT
,
1096 // After the ListView is created, we can add extended list view styles.
1097 (void)ListView_SetExtendedListViewStyle (hwndListView
, LVS_EX_FULLROWSELECT
);
1099 // Create the ImageList
1100 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
1101 GetSystemMetrics(SM_CYSMICON
),
1106 // Add event type icons to ImageList
1107 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_INFORMATIONICON
)));
1108 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_WARNINGICON
)));
1109 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ERRORICON
)));
1111 // Assign ImageList to List View
1112 (void)ListView_SetImageList (hwndListView
, hSmall
, LVSIL_SMALL
);
1114 // Now set up the listview with its columns.
1115 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
1117 LoadStringW(hInstance
,
1120 sizeof(szTemp
) / sizeof(WCHAR
));
1121 lvc
.pszText
= szTemp
;
1122 (void)ListView_InsertColumn(hwndListView
, 0, &lvc
);
1125 LoadStringW(hInstance
,
1128 sizeof(szTemp
) / sizeof(WCHAR
));
1129 lvc
.pszText
= szTemp
;
1130 (void)ListView_InsertColumn(hwndListView
, 1, &lvc
);
1133 LoadStringW(hInstance
,
1136 sizeof(szTemp
) / sizeof(WCHAR
));
1137 lvc
.pszText
= szTemp
;
1138 (void)ListView_InsertColumn(hwndListView
, 2, &lvc
);
1141 LoadStringW(hInstance
,
1144 sizeof(szTemp
) / sizeof(WCHAR
));
1145 lvc
.pszText
= szTemp
;
1146 (void)ListView_InsertColumn(hwndListView
, 3, &lvc
);
1149 LoadStringW(hInstance
,
1152 sizeof(szTemp
) / sizeof(WCHAR
));
1153 lvc
.pszText
= szTemp
;
1154 (void)ListView_InsertColumn(hwndListView
, 4, &lvc
);
1157 LoadStringW(hInstance
,
1160 sizeof(szTemp
) / sizeof(WCHAR
));
1161 lvc
.pszText
= szTemp
;
1162 (void)ListView_InsertColumn(hwndListView
, 5, &lvc
);
1165 LoadStringW(hInstance
,
1168 sizeof(szTemp
) / sizeof(WCHAR
));
1169 lvc
.pszText
= szTemp
;
1170 (void)ListView_InsertColumn(hwndListView
, 6, &lvc
);
1173 LoadStringW(hInstance
,
1176 sizeof(szTemp
) / sizeof(WCHAR
));
1177 lvc
.pszText
= szTemp
;
1178 (void)ListView_InsertColumn(hwndListView
, 7, &lvc
);
1181 LoadStringW(hInstance
,
1182 IDS_COLUMNEVENTDATA
,
1184 sizeof(szTemp
) / sizeof(WCHAR
));
1185 lvc
.pszText
= szTemp
;
1186 (void)ListView_InsertColumn(hwndListView
, 8, &lvc
);
1188 // Initialize the save Dialog
1189 ZeroMemory(&sfn
, sizeof(sfn
));
1190 ZeroMemory(szSaveFilter
, sizeof(szSaveFilter
));
1192 LoadStringW(hInst
, IDS_SAVE_FILTER
, szSaveFilter
, MAX_LOADSTRING
);
1194 sfn
.lStructSize
= sizeof(sfn
);
1195 sfn
.hwndOwner
= hwndMainWindow
;
1196 sfn
.hInstance
= hInstance
;
1197 sfn
.lpstrFilter
= szSaveFilter
;
1198 sfn
.lpstrInitialDir
= NULL
;
1199 sfn
.Flags
= OFN_HIDEREADONLY
| OFN_SHAREAWARE
;
1200 sfn
.lpstrDefExt
= NULL
;
1202 ShowWindow(hwndMainWindow
, nCmdShow
);
1203 UpdateWindow(hwndMainWindow
);
1207 QueryEventMessages(lpComputerName
, LogNames
[0]);
1209 CheckMenuRadioItem(GetMenu(hwndMainWindow
), ID_FIRST_LOG
, ID_FIRST_LOG
+ dwNumLogs
, ID_FIRST_LOG
, MF_BYCOMMAND
);
1216 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1224 hMainMenu
= GetMenu(hWnd
);
1228 switch (((LPNMHDR
)lParam
)->code
)
1231 hdr
= (NMHDR FAR
*)lParam
;
1232 if (hdr
->hwndFrom
== hwndListView
)
1234 LPNMITEMACTIVATE lpnmitem
= (LPNMITEMACTIVATE
)lParam
;
1236 if (lpnmitem
->iItem
!= -1)
1239 MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG
),
1249 // Parse the menu selections:
1251 if ((LOWORD(wParam
) >= ID_FIRST_LOG
) && (LOWORD(wParam
) <= ID_FIRST_LOG
+ dwNumLogs
))
1253 if (LogNames
[LOWORD(wParam
) - ID_FIRST_LOG
])
1255 if (QueryEventMessages(lpComputerName
, LogNames
[LOWORD(wParam
) - ID_FIRST_LOG
]))
1257 CheckMenuRadioItem(GetMenu(hWnd
), ID_FIRST_LOG
, ID_FIRST_LOG
+ dwNumLogs
, LOWORD(wParam
), MF_BYCOMMAND
);
1263 switch (LOWORD(wParam
))
1265 case ID_SAVE_PROTOCOL
:
1269 case ID_CLEAR_EVENTS
:
1281 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
1285 MessageBoxW(hwndMainWindow
,
1286 L
"Help not implemented yet!",
1288 MB_OK
| MB_ICONINFORMATION
);
1292 DestroyWindow(hWnd
);
1296 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1302 // Gets the window rectangle
1303 GetClientRect(hWnd
, &rect
);
1305 // Relocate the listview
1306 MoveWindow(hwndListView
,
1313 // Resize the statusbar;
1314 SendMessage(hwndStatus
, message
, wParam
, lParam
);
1324 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1331 // Message handler for about box.
1333 About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1335 UNREFERENCED_PARAMETER(lParam
);
1340 return (INT_PTR
)TRUE
;
1344 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
1346 EndDialog(hDlg
, LOWORD(wParam
));
1347 return (INT_PTR
)TRUE
;
1352 return (INT_PTR
)FALSE
;
1356 DisplayEvent(HWND hDlg
)
1358 WCHAR szEventType
[MAX_PATH
];
1359 WCHAR szTime
[MAX_PATH
];
1360 WCHAR szDate
[MAX_PATH
];
1361 WCHAR szUser
[MAX_PATH
];
1362 WCHAR szComputer
[MAX_PATH
];
1363 WCHAR szSource
[MAX_PATH
];
1364 WCHAR szCategory
[MAX_PATH
];
1365 WCHAR szEventID
[MAX_PATH
];
1366 WCHAR szEventText
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
1367 WCHAR szEventData
[MAX_PATH
];
1368 BOOL bEventData
= FALSE
;
1370 EVENTLOGRECORD
* pevlr
;
1373 // Get index of selected item
1374 iIndex
= (int)SendMessage (hwndListView
, LVM_GETNEXTITEM
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
1376 li
.mask
= LVIF_PARAM
;
1380 (void)ListView_GetItem(hwndListView
, &li
);
1382 pevlr
= (EVENTLOGRECORD
*)li
.lParam
;
1386 ListView_GetItemText(hwndListView
, iIndex
, 0, szEventType
, sizeof(szEventType
) / sizeof(WCHAR
));
1387 ListView_GetItemText(hwndListView
, iIndex
, 1, szDate
, sizeof(szDate
) / sizeof(WCHAR
));
1388 ListView_GetItemText(hwndListView
, iIndex
, 2, szTime
, sizeof(szTime
) / sizeof(WCHAR
));
1389 ListView_GetItemText(hwndListView
, iIndex
, 3, szSource
, sizeof(szSource
) / sizeof(WCHAR
));
1390 ListView_GetItemText(hwndListView
, iIndex
, 4, szCategory
, sizeof(szCategory
) / sizeof(WCHAR
));
1391 ListView_GetItemText(hwndListView
, iIndex
, 5, szEventID
, sizeof(szEventID
) / sizeof(WCHAR
));
1392 ListView_GetItemText(hwndListView
, iIndex
, 6, szUser
, sizeof(szUser
) / sizeof(WCHAR
));
1393 ListView_GetItemText(hwndListView
, iIndex
, 7, szComputer
, sizeof(szComputer
) / sizeof(WCHAR
));
1395 bEventData
= !(pevlr
->DataLength
== 0);
1397 if (pevlr
->DataLength
> 0)
1399 MultiByteToWideChar(CP_ACP
,
1401 (LPCSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
),
1407 GetEventMessage(lpSourceLogName
, szSource
, pevlr
, szEventText
);
1409 EnableWindow(GetDlgItem(hDlg
, IDC_BYTESRADIO
), bEventData
);
1410 EnableWindow(GetDlgItem(hDlg
, IDC_WORDRADIO
), bEventData
);
1412 SetDlgItemTextW(hDlg
, IDC_EVENTDATESTATIC
, szDate
);
1413 SetDlgItemTextW(hDlg
, IDC_EVENTTIMESTATIC
, szTime
);
1415 SetDlgItemTextW(hDlg
, IDC_EVENTUSERSTATIC
, szUser
);
1416 SetDlgItemTextW(hDlg
, IDC_EVENTSOURCESTATIC
, szSource
);
1417 SetDlgItemTextW(hDlg
, IDC_EVENTCOMPUTERSTATIC
, szComputer
);
1418 SetDlgItemTextW(hDlg
, IDC_EVENTCATEGORYSTATIC
, szCategory
);
1419 SetDlgItemTextW(hDlg
, IDC_EVENTIDSTATIC
, szEventID
);
1420 SetDlgItemTextW(hDlg
, IDC_EVENTTYPESTATIC
, szEventType
);
1421 SetDlgItemTextW(hDlg
, IDC_EVENTTEXTEDIT
, szEventText
);
1422 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, szEventData
);
1427 L
"No Items in ListView",
1429 MB_OK
| MB_ICONINFORMATION
);
1436 StatusMessageWindowProc(IN HWND hwndDlg
,
1441 UNREFERENCED_PARAMETER(wParam
);
1454 // Message handler for event details box.
1456 EventDetails(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1458 UNREFERENCED_PARAMETER(lParam
);
1463 // Show event info on dialog box
1465 return (INT_PTR
)TRUE
;
1468 switch (LOWORD(wParam
))
1472 EndDialog(hDlg
, LOWORD(wParam
));
1473 return (INT_PTR
)TRUE
;
1476 SendMessage(hwndListView
, WM_KEYDOWN
, VK_UP
, 0);
1478 // Show event info on dialog box
1480 return (INT_PTR
)TRUE
;
1483 SendMessage(hwndListView
, WM_KEYDOWN
, VK_DOWN
, 0);
1485 // Show event info on dialog box
1487 return (INT_PTR
)TRUE
;
1489 case IDC_BYTESRADIO
:
1490 return (INT_PTR
)TRUE
;
1493 return (INT_PTR
)TRUE
;
1497 L
"Help not implemented yet!",
1499 MB_OK
| MB_ICONINFORMATION
);
1500 return (INT_PTR
)TRUE
;
1508 return (INT_PTR
)FALSE
;