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 WCHAR szTitleTemplate
[MAX_LOADSTRING
]; /* The logged-on title bar text */
61 HWND hwndMainWindow
; /* Main window */
62 HWND hwndListView
; /* ListView control */
63 HWND hwndStatus
; /* Status bar */
64 WCHAR szStatusBarTemplate
[MAX_LOADSTRING
]; /* The status bar text */
65 PEVENTLOGRECORD
*g_RecordPtrs
= NULL
;
66 DWORD g_TotalRecords
= 0;
68 LPWSTR lpSourceLogName
= NULL
;
69 LPWSTR lpComputerName
= NULL
;
71 /* Forward declarations of functions included in this code module: */
72 ATOM
MyRegisterClass(HINSTANCE hInstance
);
73 BOOL
InitInstance(HINSTANCE
, int);
74 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
75 INT_PTR CALLBACK
About(HWND
, UINT
, WPARAM
, LPARAM
);
76 INT_PTR CALLBACK
EventDetails(HWND
, UINT
, WPARAM
, LPARAM
);
77 static INT_PTR CALLBACK
StatusMessageWindowProc (HWND
, UINT
, WPARAM
, LPARAM
);
81 wWinMain(HINSTANCE hInstance
,
82 HINSTANCE hPrevInstance
,
88 INITCOMMONCONTROLSEX iccx
;
90 UNREFERENCED_PARAMETER(hPrevInstance
);
91 UNREFERENCED_PARAMETER(lpCmdLine
);
93 /* Whenever any of the common controls are used in your app,
94 * you must call InitCommonControlsEx() to register the classes
95 * for those controls. */
96 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
97 iccx
.dwICC
= ICC_LISTVIEW_CLASSES
;
98 InitCommonControlsEx(&iccx
);
100 /* Initialize global strings */
101 LoadStringW(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
102 LoadStringW(hInstance
, IDS_APP_TITLE_EX
, szTitleTemplate
, MAX_LOADSTRING
);
103 LoadStringW(hInstance
, IDS_STATUS_MSG
, szStatusBarTemplate
, MAX_LOADSTRING
);
104 MyRegisterClass(hInstance
);
106 /* Perform application initialization: */
107 if (!InitInstance(hInstance
, nCmdShow
))
112 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_EVENTVWR
));
114 /* Main message loop: */
115 while (GetMessageW(&msg
, NULL
, 0, 0))
117 if (!TranslateAcceleratorW(msg
.hwnd
, hAccelTable
, &msg
))
119 TranslateMessage(&msg
);
120 DispatchMessage(&msg
);
124 return (int)msg
.wParam
;
127 static void FreeRecords(void)
134 for (iIndex
= 0; iIndex
< g_TotalRecords
; iIndex
++)
135 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
[iIndex
]);
136 HeapFree(GetProcessHeap(), 0, g_RecordPtrs
);
141 EventTimeToSystemTime(DWORD EventTime
,
142 SYSTEMTIME
*pSystemTime
)
144 SYSTEMTIME st1970
= { 1970, 1, 0, 1, 0, 0, 0, 0 };
152 uUCT
.ft
.dwHighDateTime
= 0;
153 uUCT
.ft
.dwLowDateTime
= EventTime
;
154 SystemTimeToFileTime(&st1970
, &u1970
.ft
);
155 uUCT
.ll
= uUCT
.ll
* 10000000 + u1970
.ll
;
156 FileTimeToLocalFileTime(&uUCT
.ft
, &ftLocal
);
157 FileTimeToSystemTime(&ftLocal
, pSystemTime
);
168 c
= s
+ wcslen(s
) - 1;
169 while (c
>= s
&& iswspace(*c
))
177 GetEventMessageFileDLL(IN LPCWSTR lpLogName
,
178 IN LPCWSTR SourceName
,
179 IN LPCWSTR EntryName
,
180 OUT LPWSTR ExpandedName
)
183 BYTE szModuleName
[MAX_PATH
];
184 WCHAR szKeyName
[MAX_PATH
];
186 HKEY hSourceKey
= NULL
;
187 BOOL bReturn
= FALSE
;
189 wcscpy(szKeyName
, L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\");
190 wcscat(szKeyName
, lpLogName
);
192 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
196 &hAppKey
) == ERROR_SUCCESS
)
198 if (RegOpenKeyExW(hAppKey
,
202 &hSourceKey
) == ERROR_SUCCESS
)
205 if (RegQueryValueExW(hSourceKey
,
209 (LPBYTE
)szModuleName
,
210 &dwSize
) == ERROR_SUCCESS
)
212 /* Returns a string containing the requested substituted environment variable. */
213 ExpandEnvironmentStringsW((LPCWSTR
)szModuleName
, ExpandedName
, MAX_PATH
);
223 L
"Registry access failed!",
225 MB_OK
| MB_ICONINFORMATION
);
228 if (hSourceKey
!= NULL
)
229 RegCloseKey(hSourceKey
);
232 RegCloseKey(hAppKey
);
239 GetEventCategory(IN LPCWSTR KeyName
,
240 IN LPCWSTR SourceName
,
241 IN EVENTLOGRECORD
*pevlr
,
242 OUT LPWSTR CategoryName
)
244 HANDLE hLibrary
= NULL
;
245 WCHAR szMessageDLL
[MAX_PATH
];
246 LPVOID lpMsgBuf
= NULL
;
248 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_CATEGORY_MESSAGE_FILE
, szMessageDLL
))
250 hLibrary
= LoadLibraryExW(szMessageDLL
,
252 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
253 if (hLibrary
!= NULL
)
255 /* Retrieve the message string. */
256 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
258 pevlr
->EventCategory
,
259 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
261 EVENT_MESSAGE_FILE_BUFFER
,
266 /* Trim the string */
267 TrimNulls((LPWSTR
)lpMsgBuf
);
269 /* Copy the category name */
270 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
274 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
279 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
282 if (hLibrary
!= NULL
)
283 FreeLibrary(hLibrary
);
285 /* Free the buffer allocated by FormatMessage */
293 LoadStringW(hInst
, IDS_NONE
, CategoryName
, MAX_PATH
);
300 GetEventMessage(IN LPCWSTR KeyName
,
301 IN LPCWSTR SourceName
,
302 IN EVENTLOGRECORD
*pevlr
,
303 OUT LPWSTR EventText
)
306 HANDLE hLibrary
= NULL
;
307 WCHAR SourceModuleName
[1000];
308 WCHAR ParameterModuleName
[1000];
309 LPWSTR lpMsgBuf
= NULL
;
310 WCHAR szStringIDNotFound
[MAX_LOADSTRING
];
316 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
317 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_MESSAGE_FILE
, SourceModuleName
))
319 /* Get the event message */
320 szMessage
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->StringOffset
);
322 /* Allocate space for parameters */
323 szArguments
= malloc(sizeof(LPVOID
) * pevlr
->NumStrings
);
329 for (i
= 0; i
< pevlr
->NumStrings
; i
++)
331 if (wcsstr(szMessage
, L
"%%"))
333 if (GetEventMessageFileDLL(KeyName
, SourceName
, EVENT_PARAMETER_MESSAGE_FILE
, ParameterModuleName
))
335 /* Not yet support for reading messages from parameter message DLL */
339 szArguments
[i
] = szMessage
;
340 szMessage
+= wcslen(szMessage
) + 1;
343 szDll
= wcstok(SourceModuleName
, EVENT_DLL_SEPARATOR
);
344 while ((szDll
!= NULL
) && (!bDone
))
346 hLibrary
= LoadLibraryExW(szDll
,
348 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
349 if (hLibrary
== NULL
)
351 /* The DLL could not be loaded try the next one (if any) */
352 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
356 /* Retrieve the message string. */
357 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
|
358 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
359 FORMAT_MESSAGE_FROM_HMODULE
|
360 FORMAT_MESSAGE_ARGUMENT_ARRAY
,
363 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
366 (va_list*)szArguments
) == 0)
368 /* We haven't found the string , get next DLL (if any) */
369 szDll
= wcstok(NULL
, EVENT_DLL_SEPARATOR
);
375 /* The ID was found and the message was formated */
378 /* Trim the string */
379 TrimNulls((LPWSTR
)lpMsgBuf
);
381 /* Copy the event text */
382 wcscpy(EventText
,lpMsgBuf
);
386 FreeLibrary(hLibrary
);
392 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
393 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
398 /* No more dlls to try, return result */
402 LoadStringW(hInst
, IDS_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
403 swprintf(EventText
, szStringIDNotFound
, (pevlr
->EventID
& 0xFFFF), SourceName
);
410 GetEventType(IN WORD dwEventType
,
411 OUT LPWSTR eventTypeText
)
415 case EVENTLOG_ERROR_TYPE
:
416 LoadStringW(hInst
, IDS_EVENTLOG_ERROR_TYPE
, eventTypeText
, MAX_LOADSTRING
);
418 case EVENTLOG_WARNING_TYPE
:
419 LoadStringW(hInst
, IDS_EVENTLOG_WARNING_TYPE
, eventTypeText
, MAX_LOADSTRING
);
421 case EVENTLOG_INFORMATION_TYPE
:
422 LoadStringW(hInst
, IDS_EVENTLOG_INFORMATION_TYPE
, eventTypeText
, MAX_LOADSTRING
);
424 case EVENTLOG_AUDIT_SUCCESS
:
425 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
427 case EVENTLOG_AUDIT_FAILURE
:
428 LoadStringW(hInst
, IDS_EVENTLOG_AUDIT_FAILURE
, eventTypeText
, MAX_LOADSTRING
);
430 case EVENTLOG_SUCCESS
:
431 LoadStringW(hInst
, IDS_EVENTLOG_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
434 LoadStringW(hInst
, IDS_EVENTLOG_UNKNOWN_TYPE
, eventTypeText
, MAX_LOADSTRING
);
440 GetEventUserName(EVENTLOGRECORD
*pelr
,
445 WCHAR szDomain
[1024];
448 DWORD cbDomain
= 1024;
450 /* Point to the SID. */
451 lpSid
= (PSID
)((LPBYTE
)pelr
+ pelr
->UserSidOffset
);
454 if (pelr
->UserSidLength
> 0)
456 if (LookupAccountSidW(NULL
,
464 wcscpy(pszUser
, szName
);
474 ShowStatusMessageThread(IN LPVOID lpParameter
)
476 HWND
*phWnd
= (HWND
*)lpParameter
;
480 hWnd
= CreateDialogParam(hInst
,
481 MAKEINTRESOURCE(IDD_PROGRESSBOX
),
483 StatusMessageWindowProc
,
490 ShowWindow(hWnd
, SW_SHOW
);
492 /* Message loop for the Status window */
493 while (GetMessage(&Msg
, NULL
, 0, 0))
495 TranslateMessage(&Msg
);
496 DispatchMessage(&Msg
);
504 QueryEventMessages(LPWSTR lpMachineName
,
509 EVENTLOGRECORD
*pevlr
;
510 DWORD dwRead
, dwNeeded
, dwThisRecord
, dwTotalRecords
= 0, dwCurrentRecord
= 0, dwRecordsToRead
= 0, dwFlags
, dwMaxLength
;
512 LPWSTR lpComputerName
;
514 BOOL bResult
= TRUE
; /* Read succeeded. */
517 WCHAR szWindowTitle
[MAX_PATH
];
518 WCHAR szStatusText
[MAX_PATH
];
519 WCHAR szLocalDate
[MAX_PATH
];
520 WCHAR szLocalTime
[MAX_PATH
];
521 WCHAR szEventID
[MAX_PATH
];
522 WCHAR szEventTypeText
[MAX_PATH
];
523 WCHAR szCategoryID
[MAX_PATH
];
524 WCHAR szUsername
[MAX_PATH
];
525 WCHAR szEventText
[EVENT_MESSAGE_FILE_BUFFER
];
526 WCHAR szCategory
[MAX_PATH
];
527 WCHAR szData
[MAX_PATH
];
530 LVITEMW lviEventItem
;
532 dwFlags
= EVENTLOG_FORWARDS_READ
| EVENTLOG_SEQUENTIAL_READ
;
534 lpSourceLogName
= lpLogName
;
535 lpComputerName
= lpMachineName
;
537 /* Open the event log. */
538 hEventLog
= OpenEventLogW(lpMachineName
,
540 if (hEventLog
== NULL
)
543 L
"Could not open the event log.",
545 MB_OK
| MB_ICONINFORMATION
);
549 /* Disable listview redraw */
550 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
552 /* Clear the list view */
553 (void)ListView_DeleteAllItems (hwndListView
);
556 GetOldestEventLogRecord(hEventLog
, &dwThisRecord
);
558 /* Get the total number of event log records. */
559 GetNumberOfEventLogRecords (hEventLog
, &dwTotalRecords
);
560 g_TotalRecords
= dwTotalRecords
;
562 g_RecordPtrs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalRecords
* sizeof(PVOID
));
564 /* If we have at least 1000 records show the waiting dialog */
565 if (dwTotalRecords
> 1000)
567 CloseHandle(CreateThread(NULL
,
569 ShowStatusMessageThread
,
575 while (dwCurrentRecord
< dwTotalRecords
)
577 pevlr
= HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD
) * dwTotalRecords
);
578 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
580 bResult
= ReadEventLog(hEventLog
, // Event log handle
581 dwFlags
, // Sequential read
582 0, // Ignored for sequential read
583 pevlr
, // Pointer to buffer
584 sizeof(EVENTLOGRECORD
), // Size of buffer
585 &dwRead
, // Number of bytes read
586 &dwNeeded
); // Bytes in the next record
587 if((!bResult
) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER
))
589 HeapFree(GetProcessHeap(), 0, pevlr
);
590 pevlr
= HeapAlloc(GetProcessHeap(), 0, dwNeeded
);
591 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
593 ReadEventLogW(hEventLog
, // event log handle
594 dwFlags
, // read flags
595 0, // offset; default is 0
596 pevlr
, // pointer to buffer
597 dwNeeded
, // size of buffer
598 &dwRead
, // number of bytes read
599 &dwNeeded
); // bytes in next record
604 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szUsername
, MAX_PATH
);
605 LoadStringW(hInst
, IDS_NOT_AVAILABLE
, szEventText
, MAX_PATH
);
606 LoadStringW(hInst
, IDS_NONE
, szCategory
, MAX_PATH
);
608 // Get the event source name.
609 lpSourceName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
));
611 // Get the computer name
612 lpComputerName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
) + (wcslen(lpSourceName
) + 1) * sizeof(WCHAR
));
614 // This ist the data section of the current event
615 lpData
= (LPSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
);
617 // Compute the event type
618 EventTimeToSystemTime(pevlr
->TimeWritten
, &time
);
620 // Get the username that generated the event
621 GetEventUserName(pevlr
, szUsername
);
623 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &time
, NULL
, szLocalDate
, MAX_PATH
);
624 GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &time
, NULL
, szLocalTime
, MAX_PATH
);
626 GetEventType(pevlr
->EventType
, szEventTypeText
);
627 GetEventCategory(lpLogName
, lpSourceName
, pevlr
, szCategory
);
629 swprintf(szEventID
, L
"%u", (pevlr
->EventID
& 0xFFFF));
630 swprintf(szCategoryID
, L
"%u", pevlr
->EventCategory
);
632 lviEventItem
.mask
= LVIF_IMAGE
| LVIF_TEXT
| LVIF_PARAM
;
633 lviEventItem
.iItem
= 0;
634 lviEventItem
.iSubItem
= 0;
635 lviEventItem
.lParam
= (LPARAM
)pevlr
;
636 lviEventItem
.pszText
= szEventTypeText
;
638 switch (pevlr
->EventType
)
640 case EVENTLOG_ERROR_TYPE
:
641 lviEventItem
.iImage
= 2;
644 case EVENTLOG_AUDIT_FAILURE
:
645 lviEventItem
.iImage
= 2;
648 case EVENTLOG_WARNING_TYPE
:
649 lviEventItem
.iImage
= 1;
652 case EVENTLOG_INFORMATION_TYPE
:
653 lviEventItem
.iImage
= 0;
656 case EVENTLOG_AUDIT_SUCCESS
:
657 lviEventItem
.iImage
= 0;
660 case EVENTLOG_SUCCESS
:
661 lviEventItem
.iImage
= 0;
665 lviEventItem
.iItem
= ListView_InsertItem(hwndListView
, &lviEventItem
);
667 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 1, szLocalDate
);
668 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 2, szLocalTime
);
669 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 3, lpSourceName
);
670 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 4, szCategory
);
671 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 5, szEventID
);
672 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 6, szUsername
); //User
673 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 7, lpComputerName
); //Computer
674 MultiByteToWideChar(CP_ACP
,
680 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 8, szData
); //Event Text
682 dwRead
-= pevlr
->Length
;
683 pevlr
= (EVENTLOGRECORD
*)((LPBYTE
) pevlr
+ pevlr
->Length
);
691 EndDialog(hwndDlg
, 0);
694 i
= swprintf(szWindowTitle
, szTitleTemplate
, szTitle
, lpLogName
); /* i = number of characters written */
695 /* lpComputerName can be NULL here if no records was read */
696 dwMaxLength
= sizeof(szWindowTitle
) / sizeof(WCHAR
) - i
;
698 GetComputerNameW(szWindowTitle
+i
, &dwMaxLength
);
700 _snwprintf(szWindowTitle
+i
, dwMaxLength
, L
"%s", lpComputerName
);
702 swprintf(szStatusText
, szStatusBarTemplate
, lpLogName
, dwTotalRecords
);
704 // Update the status bar
705 SendMessageW(hwndStatus
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)szStatusText
);
707 // Set the window title
708 SetWindowTextW(hwndMainWindow
, szWindowTitle
);
710 // Resume list view redraw
711 SendMessageW(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
713 // Close the event log.
714 CloseEventLog(hEventLog
);
723 QueryEventMessages(lpComputerName
,
729 // FUNCTION: MyRegisterClass()
731 // PURPOSE: Registers the window class.
735 // This function and its usage are only necessary if you want this code
736 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
737 // function that was added to Windows 95. It is important to call this function
738 // so that the application will get 'well formed' small icons associated
742 MyRegisterClass(HINSTANCE hInstance
)
746 wcex
.cbSize
= sizeof(WNDCLASSEX
);
749 wcex
.lpfnWndProc
= WndProc
;
752 wcex
.hInstance
= hInstance
;
753 wcex
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_EVENTVWR
));
754 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
755 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
756 wcex
.lpszMenuName
= MAKEINTRESOURCE(IDC_EVENTVWR
);
757 wcex
.lpszClassName
= szWindowClass
;
758 wcex
.hIconSm
= LoadIcon(wcex
.hInstance
, MAKEINTRESOURCE(IDI_SMALL
));
760 return RegisterClassExW(&wcex
);
765 // FUNCTION: InitInstance(HINSTANCE, int)
767 // PURPOSE: Saves instance handle and creates main window
771 // In this function, we save the instance handle in a global variable and
772 // create and display the main program window.
775 InitInstance(HINSTANCE hInstance
,
782 hInst
= hInstance
; // Store instance handle in our global variable
784 hwndMainWindow
= CreateWindowW(szWindowClass
,
786 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
787 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
797 hwndStatus
= CreateWindowExW(0, // no extended styles
798 STATUSCLASSNAMEW
, // status bar
800 WS_CHILD
| WS_BORDER
| WS_VISIBLE
, // styles
801 0, 0, 0, 0, // x, y, cx, cy
802 hwndMainWindow
, // parent window
803 (HMENU
)100, // window ID
804 hInstance
, // instance
805 NULL
); // window data
807 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
808 // and WS_BORDER to create the normal "sunken" look. Also note that
809 // LVS_EX_ styles cannot be set in CreateWindowEx().
810 hwndListView
= CreateWindowExW(WS_EX_CLIENTEDGE
,
813 LVS_SHOWSELALWAYS
| WS_CHILD
| WS_VISIBLE
| LVS_REPORT
,
823 // After the ListView is created, we can add extended list view styles.
824 (void)ListView_SetExtendedListViewStyle (hwndListView
, LVS_EX_FULLROWSELECT
);
826 // Create the ImageList
827 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
828 GetSystemMetrics(SM_CYSMICON
),
833 // Add event type icons to ImageList
834 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_INFORMATIONICON
)));
835 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_WARNINGICON
)));
836 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ERRORICON
)));
838 // Assign ImageList to List View
839 (void)ListView_SetImageList (hwndListView
, hSmall
, LVSIL_SMALL
);
841 // Now set up the listview with its columns.
842 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
844 LoadStringW(hInstance
,
847 sizeof(szTemp
) / sizeof(WCHAR
));
848 lvc
.pszText
= szTemp
;
849 (void)ListView_InsertColumn(hwndListView
, 0, &lvc
);
852 LoadStringW(hInstance
,
855 sizeof(szTemp
) / sizeof(WCHAR
));
856 lvc
.pszText
= szTemp
;
857 (void)ListView_InsertColumn(hwndListView
, 1, &lvc
);
860 LoadStringW(hInstance
,
863 sizeof(szTemp
) / sizeof(WCHAR
));
864 lvc
.pszText
= szTemp
;
865 (void)ListView_InsertColumn(hwndListView
, 2, &lvc
);
868 LoadStringW(hInstance
,
871 sizeof(szTemp
) / sizeof(WCHAR
));
872 lvc
.pszText
= szTemp
;
873 (void)ListView_InsertColumn(hwndListView
, 3, &lvc
);
876 LoadStringW(hInstance
,
879 sizeof(szTemp
) / sizeof(WCHAR
));
880 lvc
.pszText
= szTemp
;
881 (void)ListView_InsertColumn(hwndListView
, 4, &lvc
);
884 LoadStringW(hInstance
,
887 sizeof(szTemp
) / sizeof(WCHAR
));
888 lvc
.pszText
= szTemp
;
889 (void)ListView_InsertColumn(hwndListView
, 5, &lvc
);
892 LoadStringW(hInstance
,
895 sizeof(szTemp
) / sizeof(WCHAR
));
896 lvc
.pszText
= szTemp
;
897 (void)ListView_InsertColumn(hwndListView
, 6, &lvc
);
900 LoadStringW(hInstance
,
903 sizeof(szTemp
) / sizeof(WCHAR
));
904 lvc
.pszText
= szTemp
;
905 (void)ListView_InsertColumn(hwndListView
, 7, &lvc
);
908 LoadStringW(hInstance
,
911 sizeof(szTemp
) / sizeof(WCHAR
));
912 lvc
.pszText
= szTemp
;
913 (void)ListView_InsertColumn(hwndListView
, 8, &lvc
);
915 ShowWindow(hwndMainWindow
, nCmdShow
);
916 UpdateWindow(hwndMainWindow
);
918 QueryEventMessages(lpComputerName
, // Use the local computer.
919 EVENT_SOURCE_APPLICATION
); // The event log category
926 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
928 // PURPOSE: Processes messages for the main window.
930 // WM_COMMAND - process the application menu
931 // WM_PAINT - Paint the main window
932 // WM_DESTROY - post a quit message and return
936 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
944 CheckMenuRadioItem(GetMenu(hWnd
),
952 switch (((LPNMHDR
)lParam
)->code
)
955 hdr
= (NMHDR FAR
*)lParam
;
956 if (hdr
->hwndFrom
== hwndListView
)
958 LPNMITEMACTIVATE lpnmitem
= (LPNMITEMACTIVATE
)lParam
;
960 if (lpnmitem
->iItem
!= -1)
963 MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG
),
973 // Parse the menu selections:
974 switch (LOWORD(wParam
))
976 case ID_LOG_APPLICATION
:
977 if (QueryEventMessages(lpComputerName
, // Use the local computer.
978 EVENT_SOURCE_APPLICATION
)) // The event log category
980 CheckMenuRadioItem(GetMenu(hWnd
),
988 case ID_LOG_SECURITY
:
989 if (QueryEventMessages(lpComputerName
, // Use the local computer.
990 EVENT_SOURCE_SECURITY
)) // The event log category
992 CheckMenuRadioItem(GetMenu(hWnd
),
1001 if (QueryEventMessages(lpComputerName
, // Use the local computer.
1002 EVENT_SOURCE_SYSTEM
)) // The event log category
1004 CheckMenuRadioItem(GetMenu(hWnd
),
1017 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
1022 L
"Help not implemented yet!",
1024 MB_OK
| MB_ICONINFORMATION
);
1028 DestroyWindow(hWnd
);
1032 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1038 // Gets the window rectangle
1039 GetClientRect(hWnd
, &rect
);
1041 // Relocate the listview
1042 MoveWindow(hwndListView
,
1049 // Resize the statusbar;
1050 SendMessage(hwndStatus
, message
, wParam
, lParam
);
1059 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1066 // Message handler for about box.
1068 About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1070 UNREFERENCED_PARAMETER(lParam
);
1075 return (INT_PTR
)TRUE
;
1079 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
1081 EndDialog(hDlg
, LOWORD(wParam
));
1082 return (INT_PTR
)TRUE
;
1087 return (INT_PTR
)FALSE
;
1091 DisplayEvent(HWND hDlg
)
1093 WCHAR szEventType
[MAX_PATH
];
1094 WCHAR szTime
[MAX_PATH
];
1095 WCHAR szDate
[MAX_PATH
];
1096 WCHAR szUser
[MAX_PATH
];
1097 WCHAR szComputer
[MAX_PATH
];
1098 WCHAR szSource
[MAX_PATH
];
1099 WCHAR szCategory
[MAX_PATH
];
1100 WCHAR szEventID
[MAX_PATH
];
1101 WCHAR szEventText
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
1102 WCHAR szEventData
[MAX_PATH
];
1103 BOOL bEventData
= FALSE
;
1105 EVENTLOGRECORD
* pevlr
;
1108 // Get index of selected item
1109 iIndex
= (int)SendMessage (hwndListView
, LVM_GETNEXTITEM
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
1111 li
.mask
= LVIF_PARAM
;
1115 (void)ListView_GetItem(hwndListView
, &li
);
1117 pevlr
= (EVENTLOGRECORD
*)li
.lParam
;
1121 ListView_GetItemText(hwndListView
, iIndex
, 0, szEventType
, sizeof(szEventType
) * sizeof(WCHAR
));
1122 ListView_GetItemText(hwndListView
, iIndex
, 1, szDate
, sizeof(szDate
) * sizeof(WCHAR
));
1123 ListView_GetItemText(hwndListView
, iIndex
, 2, szTime
, sizeof(szTime
) * sizeof(WCHAR
));
1124 ListView_GetItemText(hwndListView
, iIndex
, 3, szSource
, sizeof(szSource
) * sizeof(WCHAR
));
1125 ListView_GetItemText(hwndListView
, iIndex
, 4, szCategory
, sizeof(szCategory
) * sizeof(WCHAR
));
1126 ListView_GetItemText(hwndListView
, iIndex
, 5, szEventID
, sizeof(szEventID
) * sizeof(WCHAR
));
1127 ListView_GetItemText(hwndListView
, iIndex
, 6, szUser
, sizeof(szUser
) * sizeof(WCHAR
));
1128 ListView_GetItemText(hwndListView
, iIndex
, 7, szComputer
, sizeof(szComputer
) * sizeof(WCHAR
));
1130 bEventData
= !(pevlr
->DataLength
== 0);
1132 if (pevlr
->DataLength
> 0)
1134 MultiByteToWideChar(CP_ACP
,
1136 (LPCSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
),
1142 GetEventMessage(lpSourceLogName
, szSource
, pevlr
, szEventText
);
1144 EnableWindow(GetDlgItem(hDlg
, IDC_BYTESRADIO
), bEventData
);
1145 EnableWindow(GetDlgItem(hDlg
, IDC_WORDRADIO
), bEventData
);
1147 SetDlgItemTextW(hDlg
, IDC_EVENTDATESTATIC
, szDate
);
1148 SetDlgItemTextW(hDlg
, IDC_EVENTTIMESTATIC
, szTime
);
1150 SetDlgItemTextW(hDlg
, IDC_EVENTUSERSTATIC
, szUser
);
1151 SetDlgItemTextW(hDlg
, IDC_EVENTSOURCESTATIC
, szSource
);
1152 SetDlgItemTextW(hDlg
, IDC_EVENTCOMPUTERSTATIC
, szComputer
);
1153 SetDlgItemTextW(hDlg
, IDC_EVENTCATEGORYSTATIC
, szCategory
);
1154 SetDlgItemTextW(hDlg
, IDC_EVENTIDSTATIC
, szEventID
);
1155 SetDlgItemTextW(hDlg
, IDC_EVENTTYPESTATIC
, szEventType
);
1156 SetDlgItemTextW(hDlg
, IDC_EVENTTEXTEDIT
, szEventText
);
1157 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, szEventData
);
1162 L
"No Items in ListView",
1164 MB_OK
| MB_ICONINFORMATION
);
1171 StatusMessageWindowProc(IN HWND hwndDlg
,
1176 UNREFERENCED_PARAMETER(wParam
);
1189 // Message handler for event details box.
1191 EventDetails(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1193 UNREFERENCED_PARAMETER(lParam
);
1198 // Show event info on dialog box
1200 return (INT_PTR
)TRUE
;
1203 switch (LOWORD(wParam
))
1207 EndDialog(hDlg
, LOWORD(wParam
));
1208 return (INT_PTR
)TRUE
;
1211 SendMessage(hwndListView
, WM_KEYDOWN
, VK_UP
, 0);
1213 // Show event info on dialog box
1215 return (INT_PTR
)TRUE
;
1218 SendMessage(hwndListView
, WM_KEYDOWN
, VK_DOWN
, 0);
1220 // Show event info on dialog box
1222 return (INT_PTR
)TRUE
;
1224 case IDC_BYTESRADIO
:
1225 return (INT_PTR
)TRUE
;
1228 return (INT_PTR
)TRUE
;
1232 L
"Help not implemented yet!",
1234 MB_OK
| MB_ICONINFORMATION
);
1235 return (INT_PTR
)TRUE
;
1243 return (INT_PTR
)FALSE
;