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)
38 #pragma warning(disable: 4996) /* 'strdup' was declared deprecated */
39 #define _CRT_SECURE_NO_DEPRECATE /* all deprecated unsafe string functions */
42 static const LPWSTR EVENT_SOURCE_APPLICATION
= L
"Application";
43 static const LPWSTR EVENT_SOURCE_SECURITY
= L
"Security";
44 static const LPWSTR EVENT_SOURCE_SYSTEM
= L
"System";
45 static const WCHAR szWindowClass
[] = L
"EVENTVWR"; /* the main window class name*/
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 HWND hwndMainWindow
; /* Main window */
61 HWND hwndListView
; /* ListView control */
62 HWND hwndStatus
; /* Status bar */
63 PEVENTLOGRECORD
*g_RecordPtrs
= NULL
;
64 DWORD g_TotalRecords
= 0;
66 LPWSTR lpSourceLogName
= NULL
;
67 LPWSTR lpComputerName
= NULL
;
69 /* Forward declarations of functions included in this code module: */
70 ATOM
MyRegisterClass(HINSTANCE hInstance
);
71 BOOL
InitInstance(HINSTANCE
, int);
72 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
73 INT_PTR CALLBACK
About(HWND
, UINT
, WPARAM
, LPARAM
);
74 INT_PTR CALLBACK
EventDetails(HWND
, UINT
, WPARAM
, LPARAM
);
75 static INT_PTR CALLBACK
StatusMessageWindowProc (HWND
, UINT
, WPARAM
, LPARAM
);
79 wWinMain(HINSTANCE hInstance
,
80 HINSTANCE hPrevInstance
,
86 INITCOMMONCONTROLSEX iccx
;
88 UNREFERENCED_PARAMETER(hPrevInstance
);
89 UNREFERENCED_PARAMETER(lpCmdLine
);
91 /* Whenever any of the common controls are used in your app,
92 * you must call InitCommonControlsEx() to register the classes
93 * for those controls. */
94 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
95 iccx
.dwICC
= ICC_LISTVIEW_CLASSES
;
96 InitCommonControlsEx(&iccx
);
98 /* Initialize global strings */
99 LoadStringW(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
100 MyRegisterClass(hInstance
);
102 /* Perform application initialization: */
103 if (!InitInstance(hInstance
, nCmdShow
))
108 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_EVENTVWR
));
110 /* Main message loop: */
111 while (GetMessageW(&msg
, NULL
, 0, 0))
113 if (!TranslateAcceleratorW(msg
.hwnd
, hAccelTable
, &msg
))
115 TranslateMessage(&msg
);
116 DispatchMessage(&msg
);
120 return (int)msg
.wParam
;
123 static void FreeRecords(void)
130 for (iIndex
= 0; iIndex
< g_TotalRecords
; iIndex
++)
131 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
[iIndex
]);
132 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
);
137 EventTimeToSystemTime(DWORD EventTime
,
138 SYSTEMTIME
*pSystemTime
)
140 SYSTEMTIME st1970
= { 1970, 1, 0, 1, 0, 0, 0, 0 };
148 uUCT
.ft
.dwHighDateTime
= 0;
149 uUCT
.ft
.dwLowDateTime
= EventTime
;
150 SystemTimeToFileTime(&st1970
, &u1970
.ft
);
151 uUCT
.ll
= uUCT
.ll
* 10000000 + u1970
.ll
;
152 FileTimeToLocalFileTime(&uUCT
.ft
, &ftLocal
);
153 FileTimeToSystemTime(&ftLocal
, pSystemTime
);
164 c
= s
+ wcslen(s
) - 1;
165 while (c
>= s
&& iswspace(*c
))
173 GetEventMessageFileDLL(IN LPCWSTR lpLogName
,
174 IN LPCWSTR SourceName
,
175 IN LPCWSTR EntryName
,
176 OUT LPWSTR ExpandedName
)
179 BYTE szModuleName
[MAX_PATH
];
180 WCHAR szKeyName
[MAX_PATH
];
182 HKEY hSourceKey
= NULL
;
183 BOOL bReturn
= FALSE
;
185 wcscpy(szKeyName
, L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\");
186 wcscat(szKeyName
, lpLogName
);
188 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
192 &hAppKey
) == ERROR_SUCCESS
)
194 if (RegOpenKeyExW(hAppKey
,
198 &hSourceKey
) == ERROR_SUCCESS
)
201 if (RegQueryValueExW(hSourceKey
,
205 (LPBYTE
)szModuleName
,
206 &dwSize
) == ERROR_SUCCESS
)
208 /* Returns a string containing the requested substituted environment variable. */
209 ExpandEnvironmentStringsW((LPCWSTR
)szModuleName
, ExpandedName
, MAX_PATH
);
219 L
"Registry access failed!",
221 MB_OK
| MB_ICONINFORMATION
);
224 if (hSourceKey
!= NULL
)
225 RegCloseKey(hSourceKey
);
228 RegCloseKey(hAppKey
);
235 GetEventCategory(IN LPCWSTR KeyName
,
236 IN LPCWSTR SourceName
,
237 IN EVENTLOGRECORD
*pevlr
,
238 OUT LPWSTR CategoryName
)
240 HANDLE hLibrary
= NULL
;
241 WCHAR szMessageDLL
[MAX_PATH
];
242 LPVOID lpMsgBuf
= NULL
;
244 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_CATEGORY_MESSAGE_FILE
, szMessageDLL
))
246 hLibrary
= LoadLibraryExW(szMessageDLL
,
248 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
249 if (hLibrary
!= NULL
)
251 /* Retrieve the message string. */
252 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
254 pevlr
->EventCategory
,
255 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
257 EVENT_MESSAGE_FILE_BUFFER
,
262 /* Trim the string */
263 TrimNulls((LPWSTR
)lpMsgBuf
);
265 /* Copy the category name */
266 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
270 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
275 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
278 if (hLibrary
!= NULL
)
279 FreeLibrary(hLibrary
);
281 /* Free the buffer allocated by FormatMessage */
289 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
296 GetEventMessage(IN LPCWSTR KeyName
,
297 IN LPCWSTR SourceName
,
298 IN EVENTLOGRECORD
*pevlr
,
299 OUT LPWSTR EventText
)
302 HANDLE hLibrary
= NULL
;
303 WCHAR SourceModuleName
[1000];
304 WCHAR ParameterModuleName
[1000];
305 LPWSTR lpMsgBuf
= NULL
;
306 WCHAR szStringIDNotFound
[MAX_LOADSTRING
];
312 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
313 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_MESSAGE_FILE
, SourceModuleName
))
315 /* Get the event message */
316 szMessage
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->StringOffset
);
318 /* Allocate space for parameters */
319 szArguments
= malloc(sizeof(LPVOID
) * pevlr
->NumStrings
);
325 for (i
= 0; i
< pevlr
->NumStrings
; i
++)
327 if (wcsstr(szMessage
, L
"%%"))
329 if (GetEventMessageFileDLL(KeyName
, SourceName
, EVENT_PARAMETER_MESSAGE_FILE
, ParameterModuleName
))
331 /* Not yet support for reading messages from parameter message DLL */
335 szArguments
[i
] = szMessage
;
336 szMessage
+= wcslen(szMessage
) + 1;
339 szDll
= wcstok(SourceModuleName
, EVENT_DLL_SEPARATOR
);
340 while ((szDll
!= NULL
) && (!bDone
))
342 hLibrary
= LoadLibraryExW(szDll
,
344 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
345 if (hLibrary
== NULL
)
347 /* The DLL could not be loaded try the next one (if any) */
348 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
352 /* Retrieve the message string. */
353 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
|
354 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
355 FORMAT_MESSAGE_FROM_HMODULE
|
356 FORMAT_MESSAGE_ARGUMENT_ARRAY
,
359 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
362 (va_list*)szArguments
) == 0)
364 /* We haven't found the string , get next DLL (if any) */
365 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
371 /* The ID was found and the message was formated */
374 /* Trim the string */
375 TrimNulls((LPWSTR
)lpMsgBuf
);
377 /* Copy the event text */
378 wcscpy(EventText
,lpMsgBuf
);
382 FreeLibrary(hLibrary
);
388 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
389 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
394 /* No more dlls to try, return result */
398 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
399 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
406 GetEventType(IN WORD dwEventType
,
407 OUT LPWSTR eventTypeText
)
411 case EVENTLOG_ERROR_TYPE
:
412 LoadStringW(hInst
, IDS_EVENTLOG_ERROR_TYPE
, eventTypeText
, MAX_LOADSTRING
);
414 case EVENTLOG_WARNING_TYPE
:
415 LoadStringW(hInst
, IDS_EVENTLOG_WARNING_TYPE
, eventTypeText
, MAX_LOADSTRING
);
417 case EVENTLOG_INFORMATION_TYPE
:
418 LoadStringW(hInst
, IDS_EVENTLOG_INFORMATION_TYPE
, eventTypeText
, MAX_LOADSTRING
);
420 case EVENTLOG_AUDIT_SUCCESS
:
421 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
423 case EVENTLOG_AUDIT_FAILURE
:
424 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_FAILURE
, eventTypeText
, MAX_LOADSTRING
);
426 case EVENTLOG_SUCCESS
:
427 LoadStringW(hInst
, IDS_EVENTLOG_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
430 LoadStringW(hInst
, IDS_EVENTLOG_UNKNOWN_TYPE
, eventTypeText
, MAX_LOADSTRING
);
436 GetEventUserName(EVENTLOGRECORD
*pelr
,
441 WCHAR szDomain
[1024];
444 DWORD cbDomain
= 1024;
446 /* Point to the SID. */
447 lpSid
= (PSID
)((LPBYTE
)pelr
+ pelr
->UserSidOffset
);
450 if (pelr
->UserSidLength
> 0)
452 if (LookupAccountSidW(NULL
,
460 wcscpy(pszUser
, szName
);
470 ShowStatusMessageThread(IN LPVOID lpParameter
)
472 HWND
*phWnd
= (HWND
*)lpParameter
;
476 hWnd
= CreateDialogParam(hInst
,
477 MAKEINTRESOURCE(IDD_PROGRESSBOX
),
479 StatusMessageWindowProc
,
486 ShowWindow(hWnd
, SW_SHOW
);
488 /* Message loop for the Status window */
489 while (GetMessage(&Msg
, NULL
, 0, 0))
491 TranslateMessage(&Msg
);
492 DispatchMessage(&Msg
);
500 QueryEventMessages(LPWSTR lpMachineName
,
505 EVENTLOGRECORD
*pevlr
;
506 DWORD dwRead
, dwNeeded
, dwThisRecord
, dwTotalRecords
= 0, dwCurrentRecord
= 0, dwRecordsToRead
= 0, dwFlags
, dwMaxLength
;
508 LPWSTR lpComputerName
;
510 BOOL bResult
= TRUE
; /* Read succeeded. */
513 WCHAR szWindowTitle
[MAX_PATH
];
514 WCHAR szStatusText
[MAX_PATH
];
515 WCHAR szLocalDate
[MAX_PATH
];
516 WCHAR szLocalTime
[MAX_PATH
];
517 WCHAR szEventID
[MAX_PATH
];
518 WCHAR szEventTypeText
[MAX_PATH
];
519 WCHAR szCategoryID
[MAX_PATH
];
520 WCHAR szUsername
[MAX_PATH
];
521 WCHAR szEventText
[EVENT_MESSAGE_FILE_BUFFER
];
522 WCHAR szCategory
[MAX_PATH
];
523 WCHAR szData
[MAX_PATH
];
526 LVITEMW lviEventItem
;
528 dwFlags
= EVENTLOG_FORWARDS_READ
| EVENTLOG_SEQUENTIAL_READ
;
530 lpSourceLogName
= lpLogName
;
531 lpComputerName
= lpMachineName
;
533 /* Open the event log. */
534 hEventLog
= OpenEventLogW(lpMachineName
,
536 if (hEventLog
== NULL
)
539 L
"Could not open the event log.",
541 MB_OK
| MB_ICONINFORMATION
);
545 /* Disable listview redraw */
546 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
548 /* Clear the list view */
549 (void)ListView_DeleteAllItems (hwndListView
);
552 GetOldestEventLogRecord(hEventLog
, &dwThisRecord
);
554 /* Get the total number of event log records. */
555 GetNumberOfEventLogRecords (hEventLog
, &dwTotalRecords
);
556 g_TotalRecords
= dwTotalRecords
;
558 g_RecordPtrs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalRecords
* sizeof(PVOID
));
560 /* If we have at least 1000 records show the waiting dialog */
561 if (dwTotalRecords
> 1000)
563 CloseHandle(CreateThread(NULL
,
565 ShowStatusMessageThread
,
571 while (dwCurrentRecord
< dwTotalRecords
)
573 pevlr
= HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD
) * dwTotalRecords
);
574 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
576 bResult
= ReadEventLog(hEventLog
, // Event log handle
577 dwFlags
, // Sequential read
578 0, // Ignored for sequential read
579 pevlr
, // Pointer to buffer
580 sizeof(EVENTLOGRECORD
), // Size of buffer
581 &dwRead
, // Number of bytes read
582 &dwNeeded
); // Bytes in the next record
583 if((!bResult
) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER
))
585 HeapFree(GetProcessHeap(), 0, pevlr
);
586 pevlr
= HeapAlloc(GetProcessHeap(), 0, dwNeeded
);
587 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
589 ReadEventLogW(hEventLog
, // event log handle
590 dwFlags
, // read flags
591 0, // offset; default is 0
592 pevlr
, // pointer to buffer
593 dwNeeded
, // size of buffer
594 &dwRead
, // number of bytes read
595 &dwNeeded
); // bytes in next record
600 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szUsername
, MAX_PATH
);
601 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szEventText
, MAX_PATH
);
602 LoadStringW(hInst
, IDS_NONE
, szCategory
, MAX_PATH
);
604 // Get the event source name.
605 lpSourceName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
));
607 // Get the computer name
608 lpComputerName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
) + (wcslen(lpSourceName
) + 1) * sizeof(WCHAR
));
610 // This ist the data section of the current event
611 lpData
= (LPSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
);
613 // Compute the event type
614 EventTimeToSystemTime(pevlr
->TimeWritten
, &time
);
616 // Get the username that generated the event
617 GetEventUserName(pevlr
, szUsername
);
619 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &time
, NULL
, szLocalDate
, MAX_PATH
);
620 GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &time
, NULL
, szLocalTime
, MAX_PATH
);
622 GetEventType(pevlr
->EventType
, szEventTypeText
);
623 GetEventCategory(lpLogName
, lpSourceName
, pevlr
, szCategory
);
625 swprintf(szEventID
, L
"%u", (pevlr
->EventID
& 0xFFFF));
626 swprintf(szCategoryID
, L
"%u", pevlr
->EventCategory
);
628 lviEventItem
.mask
= LVIF_IMAGE
| LVIF_TEXT
| LVIF_PARAM
;
629 lviEventItem
.iItem
= 0;
630 lviEventItem
.iSubItem
= 0;
631 lviEventItem
.lParam
= (LPARAM
)pevlr
;
632 lviEventItem
.pszText
= szEventTypeText
;
634 switch (pevlr
->EventType
)
636 case EVENTLOG_ERROR_TYPE
:
637 lviEventItem
.iImage
= 2;
640 case EVENTLOG_AUDIT_FAILURE
:
641 lviEventItem
.iImage
= 2;
644 case EVENTLOG_WARNING_TYPE
:
645 lviEventItem
.iImage
= 1;
648 case EVENTLOG_INFORMATION_TYPE
:
649 lviEventItem
.iImage
= 0;
652 case EVENTLOG_AUDIT_SUCCESS
:
653 lviEventItem
.iImage
= 0;
656 case EVENTLOG_SUCCESS
:
657 lviEventItem
.iImage
= 0;
661 lviEventItem
.iItem
= ListView_InsertItem(hwndListView
, &lviEventItem
);
663 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 1, szLocalDate
);
664 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 2, szLocalTime
);
665 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 3, lpSourceName
);
666 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 4, szCategory
);
667 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 5, szEventID
);
668 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 6, szUsername
); //User
669 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 7, lpComputerName
); //Computer
670 MultiByteToWideChar(CP_ACP
,
676 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 8, szData
); //Event Text
678 dwRead
-= pevlr
->Length
;
679 pevlr
= (EVENTLOGRECORD
*)((LPBYTE
) pevlr
+ pevlr
->Length
);
687 EndDialog(hwndDlg
, 0);
690 i
= swprintf(szWindowTitle
, L
"%s - %s Log on \\\\", szTitle
, lpLogName
); /* i = number of characters written */
691 /* lpComputerName can be NULL here if no records was read */
692 dwMaxLength
= sizeof(szWindowTitle
) / sizeof(WCHAR
) - i
;
694 GetComputerNameW(szWindowTitle
+i
, &dwMaxLength
);
696 _snwprintf(szWindowTitle
+i
, dwMaxLength
, L
"%s", lpComputerName
);
698 swprintf(szStatusText
, L
"%s has %d event(s)", lpLogName
, dwTotalRecords
);
700 // Update the status bar
701 SendMessageW(hwndStatus
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)szStatusText
);
703 // Set the window title
704 SetWindowTextW(hwndMainWindow
, szWindowTitle
);
706 // Resume list view redraw
707 SendMessageW(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
709 // Close the event log.
710 CloseEventLog(hEventLog
);
719 QueryEventMessages(lpComputerName
,
725 // FUNCTION: MyRegisterClass()
727 // PURPOSE: Registers the window class.
731 // This function and its usage are only necessary if you want this code
732 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
733 // function that was added to Windows 95. It is important to call this function
734 // so that the application will get 'well formed' small icons associated
738 MyRegisterClass(HINSTANCE hInstance
)
742 wcex
.cbSize
= sizeof(WNDCLASSEX
);
745 wcex
.lpfnWndProc
= WndProc
;
748 wcex
.hInstance
= hInstance
;
749 wcex
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_EVENTVWR
));
750 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
751 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
752 wcex
.lpszMenuName
= MAKEINTRESOURCE(IDC_EVENTVWR
);
753 wcex
.lpszClassName
= szWindowClass
;
754 wcex
.hIconSm
= LoadIcon(wcex
.hInstance
, MAKEINTRESOURCE(IDI_SMALL
));
756 return RegisterClassExW(&wcex
);
761 // FUNCTION: InitInstance(HINSTANCE, int)
763 // PURPOSE: Saves instance handle and creates main window
767 // In this function, we save the instance handle in a global variable and
768 // create and display the main program window.
771 InitInstance(HINSTANCE hInstance
,
778 hInst
= hInstance
; // Store instance handle in our global variable
780 hwndMainWindow
= CreateWindowW(szWindowClass
,
782 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
783 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
793 hwndStatus
= CreateWindowExW(0, // no extended styles
794 STATUSCLASSNAMEW
, // status bar
796 WS_CHILD
| WS_BORDER
| WS_VISIBLE
, // styles
797 0, 0, 0, 0, // x, y, cx, cy
798 hwndMainWindow
, // parent window
799 (HMENU
)100, // window ID
800 hInstance
, // instance
801 NULL
); // window data
803 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
804 // and WS_BORDER to create the normal "sunken" look. Also note that
805 // LVS_EX_ styles cannot be set in CreateWindowEx().
806 hwndListView
= CreateWindowExW(WS_EX_CLIENTEDGE
,
809 LVS_SHOWSELALWAYS
| WS_CHILD
| WS_VISIBLE
| LVS_REPORT
,
819 // After the ListView is created, we can add extended list view styles.
820 (void)ListView_SetExtendedListViewStyle (hwndListView
, LVS_EX_FULLROWSELECT
);
822 // Create the ImageList
823 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
824 GetSystemMetrics(SM_CYSMICON
),
829 // Add event type icons to ImageList
830 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_INFORMATIONICON
)));
831 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_WARNINGICON
)));
832 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ERRORICON
)));
834 // Assign ImageList to List View
835 (void)ListView_SetImageList (hwndListView
, hSmall
, LVSIL_SMALL
);
837 // Now set up the listview with its columns.
838 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
840 LoadStringW(hInstance
,
843 sizeof(szTemp
) / sizeof(WCHAR
));
844 lvc
.pszText
= szTemp
;
845 (void)ListView_InsertColumn(hwndListView
, 0, &lvc
);
848 LoadStringW(hInstance
,
851 sizeof(szTemp
) / sizeof(WCHAR
));
852 lvc
.pszText
= szTemp
;
853 (void)ListView_InsertColumn(hwndListView
, 1, &lvc
);
856 LoadStringW(hInstance
,
859 sizeof(szTemp
) / sizeof(WCHAR
));
860 lvc
.pszText
= szTemp
;
861 (void)ListView_InsertColumn(hwndListView
, 2, &lvc
);
864 LoadStringW(hInstance
,
867 sizeof(szTemp
) / sizeof(WCHAR
));
868 lvc
.pszText
= szTemp
;
869 (void)ListView_InsertColumn(hwndListView
, 3, &lvc
);
872 LoadStringW(hInstance
,
875 sizeof(szTemp
) / sizeof(WCHAR
));
876 lvc
.pszText
= szTemp
;
877 (void)ListView_InsertColumn(hwndListView
, 4, &lvc
);
880 LoadStringW(hInstance
,
883 sizeof(szTemp
) / sizeof(WCHAR
));
884 lvc
.pszText
= szTemp
;
885 (void)ListView_InsertColumn(hwndListView
, 5, &lvc
);
888 LoadStringW(hInstance
,
891 sizeof(szTemp
) / sizeof(WCHAR
));
892 lvc
.pszText
= szTemp
;
893 (void)ListView_InsertColumn(hwndListView
, 6, &lvc
);
896 LoadStringW(hInstance
,
899 sizeof(szTemp
) / sizeof(WCHAR
));
900 lvc
.pszText
= szTemp
;
901 (void)ListView_InsertColumn(hwndListView
, 7, &lvc
);
904 LoadStringW(hInstance
,
907 sizeof(szTemp
) / sizeof(WCHAR
));
908 lvc
.pszText
= szTemp
;
909 (void)ListView_InsertColumn(hwndListView
, 8, &lvc
);
911 ShowWindow(hwndMainWindow
, nCmdShow
);
912 UpdateWindow(hwndMainWindow
);
914 QueryEventMessages(lpComputerName
, // Use the local computer.
915 EVENT_SOURCE_APPLICATION
); // The event log category
922 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
924 // PURPOSE: Processes messages for the main window.
926 // WM_COMMAND - process the application menu
927 // WM_PAINT - Paint the main window
928 // WM_DESTROY - post a quit message and return
932 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
940 CheckMenuRadioItem(GetMenu(hWnd
),
948 switch (((LPNMHDR
)lParam
)->code
)
951 hdr
= (NMHDR FAR
*)lParam
;
952 if (hdr
->hwndFrom
== hwndListView
)
954 LPNMITEMACTIVATE lpnmitem
= (LPNMITEMACTIVATE
)lParam
;
956 if (lpnmitem
->iItem
!= -1)
959 MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG
),
969 // Parse the menu selections:
970 switch (LOWORD(wParam
))
972 case ID_LOG_APPLICATION
:
973 if (QueryEventMessages(lpComputerName
, // Use the local computer.
974 EVENT_SOURCE_APPLICATION
)) // The event log category
976 CheckMenuRadioItem(GetMenu(hWnd
),
984 case ID_LOG_SECURITY
:
985 if (QueryEventMessages(lpComputerName
, // Use the local computer.
986 EVENT_SOURCE_SECURITY
)) // The event log category
988 CheckMenuRadioItem(GetMenu(hWnd
),
997 if (QueryEventMessages(lpComputerName
, // Use the local computer.
998 EVENT_SOURCE_SYSTEM
)) // The event log category
1000 CheckMenuRadioItem(GetMenu(hWnd
),
1013 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
1018 L
"Help not implemented yet!",
1020 MB_OK
| MB_ICONINFORMATION
);
1024 DestroyWindow(hWnd
);
1028 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1034 // Gets the window rectangle
1035 GetClientRect(hWnd
, &rect
);
1037 // Relocate the listview
1038 MoveWindow(hwndListView
,
1045 // Resize the statusbar;
1046 SendMessage(hwndStatus
, message
, wParam
, lParam
);
1055 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1062 // Message handler for about box.
1064 About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1066 UNREFERENCED_PARAMETER(lParam
);
1071 return (INT_PTR
)TRUE
;
1075 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
1077 EndDialog(hDlg
, LOWORD(wParam
));
1078 return (INT_PTR
)TRUE
;
1083 return (INT_PTR
)FALSE
;
1087 DisplayEvent(HWND hDlg
)
1089 WCHAR szEventType
[MAX_PATH
];
1090 WCHAR szTime
[MAX_PATH
];
1091 WCHAR szDate
[MAX_PATH
];
1092 WCHAR szUser
[MAX_PATH
];
1093 WCHAR szComputer
[MAX_PATH
];
1094 WCHAR szSource
[MAX_PATH
];
1095 WCHAR szCategory
[MAX_PATH
];
1096 WCHAR szEventID
[MAX_PATH
];
1097 WCHAR szEventText
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
1098 WCHAR szEventData
[MAX_PATH
];
1099 BOOL bEventData
= FALSE
;
1101 EVENTLOGRECORD
* pevlr
;
1104 // Get index of selected item
1105 iIndex
= (int)SendMessage (hwndListView
, LVM_GETNEXTITEM
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
1107 li
.mask
= LVIF_PARAM
;
1111 (void)ListView_GetItem(hwndListView
, &li
);
1113 pevlr
= (EVENTLOGRECORD
*)li
.lParam
;
1117 ListView_GetItemText(hwndListView
, iIndex
, 0, szEventType
, sizeof(szEventType
) * sizeof(WCHAR
));
1118 ListView_GetItemText(hwndListView
, iIndex
, 1, szDate
, sizeof(szDate
) * sizeof(WCHAR
));
1119 ListView_GetItemText(hwndListView
, iIndex
, 2, szTime
, sizeof(szTime
) * sizeof(WCHAR
));
1120 ListView_GetItemText(hwndListView
, iIndex
, 3, szSource
, sizeof(szSource
) * sizeof(WCHAR
));
1121 ListView_GetItemText(hwndListView
, iIndex
, 4, szCategory
, sizeof(szCategory
) * sizeof(WCHAR
));
1122 ListView_GetItemText(hwndListView
, iIndex
, 5, szEventID
, sizeof(szEventID
) * sizeof(WCHAR
));
1123 ListView_GetItemText(hwndListView
, iIndex
, 6, szUser
, sizeof(szUser
) * sizeof(WCHAR
));
1124 ListView_GetItemText(hwndListView
, iIndex
, 7, szComputer
, sizeof(szComputer
) * sizeof(WCHAR
));
1126 bEventData
= !(pevlr
->DataLength
== 0);
1128 if (pevlr
->DataLength
> 0)
1130 MultiByteToWideChar(CP_ACP
,
1132 (LPCSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
),
1138 GetEventMessage(lpSourceLogName
, szSource
, pevlr
, szEventText
);
1140 EnableWindow(GetDlgItem(hDlg
, IDC_BYTESRADIO
), bEventData
);
1141 EnableWindow(GetDlgItem(hDlg
, IDC_WORDRADIO
), bEventData
);
1143 SetDlgItemTextW(hDlg
, IDC_EVENTDATESTATIC
, szDate
);
1144 SetDlgItemTextW(hDlg
, IDC_EVENTTIMESTATIC
, szTime
);
1146 SetDlgItemTextW(hDlg
, IDC_EVENTUSERSTATIC
, szUser
);
1147 SetDlgItemTextW(hDlg
, IDC_EVENTSOURCESTATIC
, szSource
);
1148 SetDlgItemTextW(hDlg
, IDC_EVENTCOMPUTERSTATIC
, szComputer
);
1149 SetDlgItemTextW(hDlg
, IDC_EVENTCATEGORYSTATIC
, szCategory
);
1150 SetDlgItemTextW(hDlg
, IDC_EVENTIDSTATIC
, szEventID
);
1151 SetDlgItemTextW(hDlg
, IDC_EVENTTYPESTATIC
, szEventType
);
1152 SetDlgItemTextW(hDlg
, IDC_EVENTTEXTEDIT
, szEventText
);
1153 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, szEventData
);
1158 L
"No Items in ListView",
1160 MB_OK
| MB_ICONINFORMATION
);
1167 StatusMessageWindowProc(IN HWND hwndDlg
,
1172 UNREFERENCED_PARAMETER(wParam
);
1185 // Message handler for event details box.
1187 EventDetails(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1189 UNREFERENCED_PARAMETER(lParam
);
1194 // Show event info on dialog box
1196 return (INT_PTR
)TRUE
;
1199 switch (LOWORD(wParam
))
1203 EndDialog(hDlg
, LOWORD(wParam
));
1204 return (INT_PTR
)TRUE
;
1207 SendMessage(hwndListView
, WM_KEYDOWN
, VK_UP
, 0);
1209 // Show event info on dialog box
1211 return (INT_PTR
)TRUE
;
1214 SendMessage(hwndListView
, WM_KEYDOWN
, VK_DOWN
, 0);
1216 // Show event info on dialog box
1218 return (INT_PTR
)TRUE
;
1220 case IDC_BYTESRADIO
:
1221 return (INT_PTR
)TRUE
;
1224 return (INT_PTR
)TRUE
;
1228 L
"Help not implemented yet!",
1230 MB_OK
| MB_ICONINFORMATION
);
1231 return (INT_PTR
)TRUE
;
1239 return (INT_PTR
)FALSE
;