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)
33 #pragma warning(disable: 4996) /* 'strdup' was declared deprecated */
34 #define _CRT_SECURE_NO_DEPRECATE /* all deprecated unsafe string functions */
37 static const LPWSTR EVENT_SOURCE_APPLICATION
= L
"Application";
38 static const LPWSTR EVENT_SOURCE_SECURITY
= L
"Security";
39 static const LPWSTR EVENT_SOURCE_SYSTEM
= L
"System";
40 static const WCHAR szWindowClass
[] = L
"EVENTVWR"; /* the main window class name*/
42 //MessageFile message buffer size
43 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10
44 #define EVENT_MESSAGE_FILE_BUFFER 1024*10
45 #define EVENT_DLL_SEPARATOR L";"
46 #define EVENT_MESSAGE_FILE L"EventMessageFile"
47 #define EVENT_CATEGORY_MESSAGE_FILE L"CategoryMessageFile"
48 #define EVENT_PARAMETER_MESSAGE_FILE L"ParameterMessageFile"
50 #define MAX_LOADSTRING 255
53 HINSTANCE hInst
; /* current instance */
54 WCHAR szTitle
[MAX_LOADSTRING
]; /* The title bar text */
55 HWND hwndMainWindow
; /* Main window */
56 HWND hwndListView
; /* ListView control */
57 HWND hwndStatus
; /* Status bar */
58 PEVENTLOGRECORD
*g_RecordPtrs
= NULL
;
59 DWORD g_TotalRecords
= 0;
61 LPWSTR lpSourceLogName
= NULL
;
62 LPWSTR lpComputerName
= NULL
;
64 /* Forward declarations of functions included in this code module: */
65 ATOM
MyRegisterClass(HINSTANCE hInstance
);
66 BOOL
InitInstance(HINSTANCE
, int);
67 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
68 INT_PTR CALLBACK
About(HWND
, UINT
, WPARAM
, LPARAM
);
69 INT_PTR CALLBACK
EventDetails(HWND
, UINT
, WPARAM
, LPARAM
);
70 static INT_PTR CALLBACK
StatusMessageWindowProc (HWND
, UINT
, WPARAM
, LPARAM
);
74 wWinMain(HINSTANCE hInstance
,
75 HINSTANCE hPrevInstance
,
81 INITCOMMONCONTROLSEX iccx
;
83 UNREFERENCED_PARAMETER(hPrevInstance
);
84 UNREFERENCED_PARAMETER(lpCmdLine
);
86 /* Whenever any of the common controls are used in your app,
87 * you must call InitCommonControlsEx() to register the classes
88 * for those controls. */
89 iccx
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
90 iccx
.dwICC
= ICC_LISTVIEW_CLASSES
;
91 InitCommonControlsEx(&iccx
);
93 /* Initialize global strings */
94 LoadStringW(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
95 MyRegisterClass(hInstance
);
97 /* Perform application initialization: */
98 if (!InitInstance(hInstance
, nCmdShow
))
103 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_EVENTVWR
));
105 /* Main message loop: */
106 while (GetMessageW(&msg
, NULL
, 0, 0))
108 if (!TranslateAcceleratorW(msg
.hwnd
, hAccelTable
, &msg
))
110 TranslateMessage(&msg
);
111 DispatchMessage(&msg
);
115 return (int)msg
.wParam
;
118 static void FreeRecords(void)
125 for (iIndex
= 0; iIndex
< g_TotalRecords
; iIndex
++)
126 HeapFree(GetProcessHeap(), 0, (PEVENTLOGRECORD
) g_RecordPtrs
[iIndex
]);
127 HeapFree(GetProcessHeap(), 0, (PEVENTLOGRECORD
) g_RecordPtrs
);
132 EventTimeToSystemTime(DWORD EventTime
,
133 SYSTEMTIME
*pSystemTime
)
135 SYSTEMTIME st1970
= { 1970, 1, 0, 1, 0, 0, 0, 0 };
143 uUCT
.ft
.dwHighDateTime
= 0;
144 uUCT
.ft
.dwLowDateTime
= EventTime
;
145 SystemTimeToFileTime(&st1970
, &u1970
.ft
);
146 uUCT
.ll
= uUCT
.ll
* 10000000 + u1970
.ll
;
147 FileTimeToLocalFileTime(&uUCT
.ft
, &ftLocal
);
148 FileTimeToSystemTime(&ftLocal
, pSystemTime
);
159 c
= s
+ wcslen(s
) - 1;
160 while (c
>= s
&& iswspace(*c
))
168 GetEventMessageFileDLL(IN LPCWSTR lpLogName
,
169 IN LPCWSTR SourceName
,
170 IN LPCWSTR EntryName
,
171 OUT LPWSTR ExpandedName
)
174 BYTE szModuleName
[MAX_PATH
];
175 WCHAR szKeyName
[MAX_PATH
];
177 HKEY hSourceKey
= NULL
;
178 BOOL bReturn
= FALSE
;
180 wcscpy(szKeyName
, L
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\");
181 wcscat(szKeyName
, lpLogName
);
183 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
187 &hAppKey
) == ERROR_SUCCESS
)
189 if (RegOpenKeyExW(hAppKey
,
193 &hSourceKey
) == ERROR_SUCCESS
)
196 if (RegQueryValueExW(hSourceKey
,
200 (LPBYTE
)szModuleName
,
201 &dwSize
) == ERROR_SUCCESS
)
203 /* Returns a string containing the requested substituted environment variable. */
204 ExpandEnvironmentStringsW((LPCWSTR
)szModuleName
, ExpandedName
, MAX_PATH
);
214 L
"Registry access failed!",
216 MB_OK
| MB_ICONINFORMATION
);
219 if (hSourceKey
!= NULL
)
220 RegCloseKey(hSourceKey
);
223 RegCloseKey(hAppKey
);
230 GetEventCategory(IN LPCWSTR KeyName
,
231 IN LPCWSTR SourceName
,
232 IN EVENTLOGRECORD
*pevlr
,
233 OUT LPWSTR CategoryName
)
235 HANDLE hLibrary
= NULL
;
236 WCHAR szMessageDLL
[MAX_PATH
];
237 LPVOID lpMsgBuf
= NULL
;
239 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_CATEGORY_MESSAGE_FILE
, szMessageDLL
))
241 hLibrary
= LoadLibraryExW(szMessageDLL
,
243 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
244 if (hLibrary
!= NULL
)
246 /* Retrieve the message string. */
247 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
249 pevlr
->EventCategory
,
250 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
252 EVENT_MESSAGE_FILE_BUFFER
,
257 /* Trim the string */
258 TrimNulls((LPWSTR
)lpMsgBuf
);
260 /* Copy the category name */
261 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
265 wcscpy(CategoryName
, (LPCWSTR
)lpMsgBuf
);
270 wcscpy(CategoryName
, L
"None");
273 if (hLibrary
!= NULL
)
274 FreeLibrary(hLibrary
);
276 /* Free the buffer allocated by FormatMessage */
284 wcscpy(CategoryName
, L
"None");
291 GetEventMessage(IN LPCWSTR KeyName
,
292 IN LPCWSTR SourceName
,
293 IN EVENTLOGRECORD
*pevlr
,
294 OUT LPWSTR EventText
)
297 HANDLE hLibrary
= NULL
;
298 WCHAR SourceModuleName
[1000];
299 WCHAR ParameterModuleName
[1000];
300 LPWSTR lpMsgBuf
= NULL
;
301 WCHAR szStringIDNotFound
[MAX_LOADSTRING
];
307 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */
308 if (GetEventMessageFileDLL (KeyName
, SourceName
, EVENT_MESSAGE_FILE
, SourceModuleName
))
310 /* Get the event message */
311 szMessage
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->StringOffset
);
313 /* Allocate space for parameters */
314 szArguments
= (LPWSTR
*)malloc(sizeof(LPVOID
) * pevlr
->NumStrings
);
320 for (i
= 0; i
< pevlr
->NumStrings
; i
++)
322 if (wcsstr(szMessage
, L
"%%"))
324 if (GetEventMessageFileDLL(KeyName
, SourceName
, EVENT_PARAMETER_MESSAGE_FILE
, ParameterModuleName
))
326 /* Not yet support for reading messages from parameter message DLL */
329 szArguments
[i
] = szMessage
;
330 szMessage
+= wcslen(szMessage
) + 1;
334 szArguments
[i
] = szMessage
;
335 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
, IDC_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
389 swprintf(EventText
, szStringIDNotFound
, (DWORD
)(pevlr
->EventID
& 0xFFFF), SourceName
);
394 /* No more dlls to try, return result */
398 LoadStringW(hInst
, IDC_EVENTSTRINGIDNOTFOUND
, szStringIDNotFound
, MAX_LOADSTRING
);
399 swprintf(EventText
, szStringIDNotFound
, (DWORD
)(pevlr
->EventID
& 0xFFFF), SourceName
);
406 GetEventType(IN WORD dwEventType
,
407 OUT LPWSTR eventTypeText
)
411 case EVENTLOG_ERROR_TYPE
:
412 LoadStringW(hInst
, IDC_EVENTLOG_ERROR_TYPE
, eventTypeText
, MAX_LOADSTRING
);
414 case EVENTLOG_WARNING_TYPE
:
415 LoadStringW(hInst
, IDC_EVENTLOG_WARNING_TYPE
, eventTypeText
, MAX_LOADSTRING
);
417 case EVENTLOG_INFORMATION_TYPE
:
418 LoadStringW(hInst
, IDC_EVENTLOG_INFORMATION_TYPE
, eventTypeText
, MAX_LOADSTRING
);
420 case EVENTLOG_AUDIT_SUCCESS
:
421 LoadStringW(hInst
, IDC_EVENTLOG_AUDIT_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
423 case EVENTLOG_AUDIT_FAILURE
:
424 LoadStringW(hInst
, IDC_EVENTLOG_AUDIT_FAILURE
, eventTypeText
, MAX_LOADSTRING
);
426 case EVENTLOG_SUCCESS
:
427 LoadStringW(hInst
, IDC_EVENTLOG_SUCCESS
, eventTypeText
, MAX_LOADSTRING
);
430 LoadStringW(hInst
, IDC_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
= 1, dwRecordsToRead
= 0, dwFlags
;
508 LPWSTR lpComputerName
;
511 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
];
525 LVITEMW lviEventItem
;
527 dwFlags
= EVENTLOG_FORWARDS_READ
| EVENTLOG_SEQUENTIAL_READ
;
529 lpSourceLogName
= lpLogName
;
530 lpComputerName
= lpMachineName
;
532 /* Open the event log. */
533 hEventLog
= OpenEventLogW(lpMachineName
,
535 if (hEventLog
== NULL
)
538 L
"Could not open the event log.",
540 MB_OK
| MB_ICONINFORMATION
);
544 /* Disable listview redraw */
545 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
547 /* Clear the list view */
548 (void)ListView_DeleteAllItems (hwndListView
);
551 GetOldestEventLogRecord(hEventLog
, &dwThisRecord
);
553 /* Get the total number of event log records. */
554 GetNumberOfEventLogRecords (hEventLog
, &dwTotalRecords
);
555 g_TotalRecords
= dwTotalRecords
;
557 g_RecordPtrs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalRecords
* sizeof(PEVENTLOGRECORD
));
559 /* If we have at least 1000 records show the waiting dialog */
560 if (dwTotalRecords
> 1000)
564 ShowStatusMessageThread
,
570 while (dwCurrentRecord
< dwTotalRecords
)
572 pevlr
= (EVENTLOGRECORD
*) HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD
) * dwTotalRecords
);
573 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
575 bResult
= ReadEventLog(hEventLog
, // Event log handle
576 dwFlags
, // Sequential read
577 0, // Ignored for sequential read
578 pevlr
, // Pointer to buffer
579 sizeof(EVENTLOGRECORD
), // Size of buffer
580 &dwRead
, // Number of bytes read
581 &dwNeeded
); // Bytes in the next record
582 if((!bResult
) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER
))
584 HeapFree(GetProcessHeap(), 0, pevlr
);
585 pevlr
= (EVENTLOGRECORD
*) HeapAlloc(GetProcessHeap(), 0, dwNeeded
);
586 g_RecordPtrs
[dwCurrentRecord
] = pevlr
;
588 ReadEventLogW(hEventLog
, // event log handle
589 dwFlags
, // read flags
590 0, // offset; default is 0
591 pevlr
, // pointer to buffer
592 dwNeeded
, // size of buffer
593 &dwRead
, // number of bytes read
594 &dwNeeded
); // bytes in next record
599 wcscpy(szUsername
, L
"N/A");
600 wcscpy(szEventText
, L
"N/A");
601 wcscpy(szCategory
, L
"None");
603 // Get the event source name.
604 lpSourceName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
));
606 // Get the computer name
607 lpComputerName
= (LPWSTR
)((LPBYTE
)pevlr
+ sizeof(EVENTLOGRECORD
) + (wcslen(lpSourceName
) + 1) * sizeof(WCHAR
));
609 // This ist the data section of the current event
610 lpData
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
);
612 // This is the text of the current event
613 lpEventStr
= (LPWSTR
)((LPBYTE
)pevlr
+ pevlr
->StringOffset
);
615 // Compute the event type
616 EventTimeToSystemTime(pevlr
->TimeWritten
, &time
);
618 // Get the username that generated the event
619 GetEventUserName(pevlr
, szUsername
);
621 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &time
, NULL
, szLocalDate
, MAX_PATH
);
622 GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &time
, NULL
, szLocalTime
, MAX_PATH
);
624 GetEventType(pevlr
->EventType
, szEventTypeText
);
625 GetEventCategory(lpLogName
, lpSourceName
, pevlr
, szCategory
);
627 swprintf(szEventID
, L
"%u", (DWORD
)(pevlr
->EventID
& 0xFFFF));
628 swprintf(szCategoryID
, L
"%u", (DWORD
)(pevlr
->EventCategory
));
630 lviEventItem
.mask
= LVIF_IMAGE
| LVIF_TEXT
| LVIF_PARAM
;
631 lviEventItem
.iItem
= 0;
632 lviEventItem
.iSubItem
= 0;
633 lviEventItem
.lParam
= (LPARAM
)pevlr
;
634 lviEventItem
.pszText
= szEventTypeText
;
636 switch (pevlr
->EventType
)
638 case EVENTLOG_ERROR_TYPE
:
639 lviEventItem
.iImage
= 2;
642 case EVENTLOG_AUDIT_FAILURE
:
643 lviEventItem
.iImage
= 2;
646 case EVENTLOG_WARNING_TYPE
:
647 lviEventItem
.iImage
= 1;
650 case EVENTLOG_INFORMATION_TYPE
:
651 lviEventItem
.iImage
= 0;
654 case EVENTLOG_AUDIT_SUCCESS
:
655 lviEventItem
.iImage
= 0;
658 case EVENTLOG_SUCCESS
:
659 lviEventItem
.iImage
= 0;
663 lviEventItem
.iItem
= ListView_InsertItem(hwndListView
, &lviEventItem
);
665 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 1, szLocalDate
);
666 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 2, szLocalTime
);
667 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 3, lpSourceName
);
668 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 4, szCategory
);
669 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 5, szEventID
);
670 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 6, szUsername
); //User
671 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 7, lpComputerName
); //Computer
672 ListView_SetItemText(hwndListView
, lviEventItem
.iItem
, 8, lpData
); //Event Text
674 dwRead
-= pevlr
->Length
;
675 pevlr
= (EVENTLOGRECORD
*)((LPBYTE
) pevlr
+ pevlr
->Length
);
683 EndDialog(hwndDlg
, 0);
685 swprintf(szWindowTitle
, L
"%s - %s Log on \\\\%s", szTitle
, lpLogName
, lpComputerName
);
686 swprintf(szStatusText
, L
"%s has %d event(s)", lpLogName
, dwTotalRecords
);
688 // Update the status bar
689 SendMessageW(hwndStatus
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)szStatusText
);
691 // Set the window title
692 SetWindowTextW(hwndMainWindow
, szWindowTitle
);
694 // Resume list view redraw
695 SendMessageW(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
697 // Close the event log.
698 CloseEventLog(hEventLog
);
707 QueryEventMessages(lpComputerName
,
713 // FUNCTION: MyRegisterClass()
715 // PURPOSE: Registers the window class.
719 // This function and its usage are only necessary if you want this code
720 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
721 // function that was added to Windows 95. It is important to call this function
722 // so that the application will get 'well formed' small icons associated
726 MyRegisterClass(HINSTANCE hInstance
)
730 wcex
.cbSize
= sizeof(WNDCLASSEX
);
732 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
733 wcex
.lpfnWndProc
= WndProc
;
736 wcex
.hInstance
= hInstance
;
737 wcex
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_EVENTVWR
));
738 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
739 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
740 wcex
.lpszMenuName
= MAKEINTRESOURCE(IDC_EVENTVWR
);
741 wcex
.lpszClassName
= szWindowClass
;
742 wcex
.hIconSm
= LoadIcon(wcex
.hInstance
, MAKEINTRESOURCE(IDI_SMALL
));
744 return RegisterClassExW(&wcex
);
749 // FUNCTION: InitInstance(HINSTANCE, int)
751 // PURPOSE: Saves instance handle and creates main window
755 // In this function, we save the instance handle in a global variable and
756 // create and display the main program window.
759 InitInstance(HINSTANCE hInstance
,
765 hInst
= hInstance
; // Store instance handle in our global variable
767 hwndMainWindow
= CreateWindowW(szWindowClass
,
770 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0,
780 hwndStatus
= CreateWindowExW(0, // no extended styles
781 STATUSCLASSNAMEW
, // status bar
783 WS_CHILD
| WS_BORDER
| WS_VISIBLE
, // styles
784 0, 0, 0, 0, // x, y, cx, cy
785 hwndMainWindow
, // parent window
786 (HMENU
)100, // window ID
787 hInstance
, // instance
788 NULL
); // window data
790 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE
791 // and WS_BORDER to create the normal "sunken" look. Also note that
792 // LVS_EX_ styles cannot be set in CreateWindowEx().
793 hwndListView
= CreateWindowExW(WS_EX_CLIENTEDGE
,
796 LVS_SHOWSELALWAYS
| WS_CHILD
| WS_VISIBLE
| LVS_REPORT
,
806 // After the ListView is created, we can add extended list view styles.
807 (void)ListView_SetExtendedListViewStyle (hwndListView
, LVS_EX_FULLROWSELECT
);
809 // Create the ImageList
810 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
811 GetSystemMetrics(SM_CYSMICON
),
816 // Add event type icons to ImageList
817 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_INFORMATIONICON
)));
818 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_WARNINGICON
)));
819 ImageList_AddIcon (hSmall
, LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ERRORICON
)));
821 // Assign ImageList to List View
822 (void)ListView_SetImageList (hwndListView
, hSmall
, LVSIL_SMALL
);
824 // Now set up the listview with its columns.
825 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
827 lvc
.pszText
= L
"Type";
828 (void)ListView_InsertColumn(hwndListView
, 0, &lvc
);
831 lvc
.pszText
= L
"Date";
832 (void)ListView_InsertColumn(hwndListView
, 1, &lvc
);
835 lvc
.pszText
= L
"Time";
836 (void)ListView_InsertColumn(hwndListView
, 2, &lvc
);
839 lvc
.pszText
= L
"Source";
840 (void)ListView_InsertColumn(hwndListView
, 3, &lvc
);
843 lvc
.pszText
= L
"Category";
844 (void)ListView_InsertColumn(hwndListView
, 4, &lvc
);
847 lvc
.pszText
= L
"Event";
848 (void)ListView_InsertColumn(hwndListView
, 5, &lvc
);
851 lvc
.pszText
= L
"User";
852 (void)ListView_InsertColumn(hwndListView
, 6, &lvc
);
855 lvc
.pszText
= L
"Computer";
856 (void)ListView_InsertColumn(hwndListView
, 7, &lvc
);
859 lvc
.pszText
= L
"Event Data";
860 (void)ListView_InsertColumn(hwndListView
, 8, &lvc
);
862 ShowWindow(hwndMainWindow
, nCmdShow
);
863 UpdateWindow(hwndMainWindow
);
865 QueryEventMessages(lpComputerName
, // Use the local computer.
866 EVENT_SOURCE_APPLICATION
); // The event log category
873 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
875 // PURPOSE: Processes messages for the main window.
877 // WM_COMMAND - process the application menu
878 // WM_PAINT - Paint the main window
879 // WM_DESTROY - post a quit message and return
883 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
891 CheckMenuRadioItem(GetMenu(hWnd
),
899 switch (((LPNMHDR
)lParam
)->code
)
902 hdr
= (NMHDR FAR
*)lParam
;
903 if (hdr
->hwndFrom
== hwndListView
)
905 LPNMITEMACTIVATE lpnmitem
= (LPNMITEMACTIVATE
)lParam
;
907 if (lpnmitem
->iItem
!= -1)
910 MAKEINTRESOURCE(IDD_EVENTDETAILDIALOG
),
920 // Parse the menu selections:
921 switch (LOWORD(wParam
))
923 case ID_LOG_APPLICATION
:
924 if (QueryEventMessages(lpComputerName
, // Use the local computer.
925 EVENT_SOURCE_APPLICATION
)) // The event log category
927 CheckMenuRadioItem(GetMenu(hWnd
),
935 case ID_LOG_SECURITY
:
936 if (QueryEventMessages(lpComputerName
, // Use the local computer.
937 EVENT_SOURCE_SECURITY
)) // The event log category
939 CheckMenuRadioItem(GetMenu(hWnd
),
948 if (QueryEventMessages(lpComputerName
, // Use the local computer.
949 EVENT_SOURCE_SYSTEM
)) // The event log category
951 CheckMenuRadioItem(GetMenu(hWnd
),
964 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, About
);
969 L
"Help not implemented yet!",
971 MB_OK
| MB_ICONINFORMATION
);
979 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
985 // Gets the window rectangle
986 GetClientRect(hWnd
, &rect
);
988 // Relocate the listview
989 MoveWindow(hwndListView
,
996 // Resize the statusbar;
997 SendMessage(hwndStatus
, message
, wParam
, lParam
);
1006 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
1013 // Message handler for about box.
1015 About(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1017 UNREFERENCED_PARAMETER(lParam
);
1022 return (INT_PTR
)TRUE
;
1026 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
1028 EndDialog(hDlg
, LOWORD(wParam
));
1029 return (INT_PTR
)TRUE
;
1034 return (INT_PTR
)FALSE
;
1038 DisplayEvent(HWND hDlg
)
1040 WCHAR szEventType
[MAX_PATH
];
1041 WCHAR szTime
[MAX_PATH
];
1042 WCHAR szDate
[MAX_PATH
];
1043 WCHAR szUser
[MAX_PATH
];
1044 WCHAR szComputer
[MAX_PATH
];
1045 WCHAR szSource
[MAX_PATH
];
1046 WCHAR szCategory
[MAX_PATH
];
1047 WCHAR szEventID
[MAX_PATH
];
1048 WCHAR szEventText
[EVENT_MESSAGE_EVENTTEXT_BUFFER
];
1049 WCHAR szEventData
[MAX_PATH
];
1050 BOOL bEventData
= FALSE
;
1052 EVENTLOGRECORD
* pevlr
;
1055 // Get index of selected item
1056 iIndex
= (int)SendMessage (hwndListView
, LVM_GETNEXTITEM
, -1, LVNI_SELECTED
| LVNI_FOCUSED
);
1058 li
.mask
= LVIF_PARAM
;
1062 (void)ListView_GetItem(hwndListView
, &li
);
1064 pevlr
= (EVENTLOGRECORD
*)li
.lParam
;
1068 ListView_GetItemText(hwndListView
, iIndex
, 0, szEventType
, sizeof(szEventType
) * sizeof(WCHAR
));
1069 ListView_GetItemText(hwndListView
, iIndex
, 1, szDate
, sizeof(szDate
) * sizeof(WCHAR
));
1070 ListView_GetItemText(hwndListView
, iIndex
, 2, szTime
, sizeof(szTime
) * sizeof(WCHAR
));
1071 ListView_GetItemText(hwndListView
, iIndex
, 3, szSource
, sizeof(szSource
) * sizeof(WCHAR
));
1072 ListView_GetItemText(hwndListView
, iIndex
, 4, szCategory
, sizeof(szCategory
) * sizeof(WCHAR
));
1073 ListView_GetItemText(hwndListView
, iIndex
, 5, szEventID
, sizeof(szEventID
) * sizeof(WCHAR
));
1074 ListView_GetItemText(hwndListView
, iIndex
, 6, szUser
, sizeof(szUser
) * sizeof(WCHAR
));
1075 ListView_GetItemText(hwndListView
, iIndex
, 7, szComputer
, sizeof(szComputer
) * sizeof(WCHAR
));
1077 bEventData
= !(pevlr
->DataLength
== 0);
1079 if (pevlr
->DataLength
> 0)
1081 MultiByteToWideChar(CP_ACP
,
1083 (LPCSTR
)((LPBYTE
)pevlr
+ pevlr
->DataOffset
),
1089 GetEventMessage(lpSourceLogName
, szSource
, pevlr
, szEventText
);
1091 EnableWindow(GetDlgItem(hDlg
, IDC_BYTESRADIO
), bEventData
);
1092 EnableWindow(GetDlgItem(hDlg
, IDC_WORDRADIO
), bEventData
);
1094 SetDlgItemTextW(hDlg
, IDC_EVENTDATESTATIC
, szDate
);
1095 SetDlgItemTextW(hDlg
, IDC_EVENTTIMESTATIC
, szTime
);
1096 SetDlgItemTextW(hDlg
, IDC_EVENTUSERSTATIC
, szUser
);
1097 SetDlgItemTextW(hDlg
, IDC_EVENTSOURCESTATIC
, szSource
);
1098 SetDlgItemTextW(hDlg
, IDC_EVENTCOMPUTERSTATIC
, szComputer
);
1099 SetDlgItemTextW(hDlg
, IDC_EVENTCATEGORYSTATIC
, szCategory
);
1100 SetDlgItemTextW(hDlg
, IDC_EVENTIDSTATIC
, szEventID
);
1101 SetDlgItemTextW(hDlg
, IDC_EVENTTYPESTATIC
, szEventType
);
1102 SetDlgItemTextW(hDlg
, IDC_EVENTTEXTEDIT
, szEventText
);
1103 SetDlgItemTextW(hDlg
, IDC_EVENTDATAEDIT
, szEventData
);
1108 L
"No Items in ListView",
1110 MB_OK
| MB_ICONINFORMATION
);
1117 StatusMessageWindowProc(IN HWND hwndDlg
,
1122 UNREFERENCED_PARAMETER(wParam
);
1135 // Message handler for event details box.
1137 EventDetails(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1139 UNREFERENCED_PARAMETER(lParam
);
1144 // Show event info on dialog box
1146 return (INT_PTR
)TRUE
;
1149 switch (LOWORD(wParam
))
1153 EndDialog(hDlg
, LOWORD(wParam
));
1154 return (INT_PTR
)TRUE
;
1157 SendMessage(hwndListView
, WM_KEYDOWN
, VK_UP
, 0);
1159 // Show event info on dialog box
1161 return (INT_PTR
)TRUE
;
1164 SendMessage(hwndListView
, WM_KEYDOWN
, VK_DOWN
, 0);
1166 // Show event info on dialog box
1168 return (INT_PTR
)TRUE
;
1170 case IDC_BYTESRADIO
:
1171 return (INT_PTR
)TRUE
;
1174 return (INT_PTR
)TRUE
;
1178 L
"Help not implemented yet!",
1180 MB_OK
| MB_ICONINFORMATION
);
1181 return (INT_PTR
)TRUE
;
1189 return (INT_PTR
)FALSE
;