[EVENTVWR] Enhancements to the event log viewer.

- Initialize hwndMainWindow as it can be used before it is properly
  initialized with an existing window handle.
- Transform ShowLastWin32Error() to a more generic ShowWin32Error().
- Use iswdigit() instead of isdigit().
- Add extra heap buffer cleanup.
- Split OpenUserEventLog() in two: OpenUserEventLog() that displays
  an open-file dialog, and OpenUserEventLogFile() that does the real
  work of allocating internal structures and opening the log file using
  the event-log service. We also check that the file really exists
  before proceeding further.
- Force treeview repaint when *children* items are inserted, because
  otherwise the expand/collapse buttons do not display next to parent
  items (this problem happens on Windows too).
- Reshuffle the resource string IDs.
This commit is contained in:
Hermès Bélusca-Maïto 2018-04-12 02:32:37 +02:00
parent ef0f6861fb
commit eb2934df0e
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 148 additions and 115 deletions

View file

@ -77,7 +77,7 @@ BYTE bSplit = 0; /* Splitter state:
* 2: Horizontal splitting. * 2: Horizontal splitting.
*/ */
HWND hwndMainWindow; /* Main window */ HWND hwndMainWindow = NULL; /* Main window */
HWND hwndTreeView; /* TreeView control */ HWND hwndTreeView; /* TreeView control */
HWND hwndListView; /* ListView control */ // NOTE: Used by evtdetctl.c HWND hwndListView; /* ListView control */ // NOTE: Used by evtdetctl.c
HWND hwndEventDetails; /* Event details pane */ HWND hwndEventDetails; /* Event details pane */
@ -90,7 +90,7 @@ HTREEITEM htiSystemLogs = NULL, htiAppLogs = NULL, htiUserLogs = NULL;
/* Global event records cache for the current active event log filter */ /* Global event records cache for the current active event log filter */
DWORD g_TotalRecords = 0; DWORD g_TotalRecords = 0;
PEVENTLOGRECORD *g_RecordPtrs = NULL; PEVENTLOGRECORD* g_RecordPtrs = NULL;
/* Lists of event logs and event log filters */ /* Lists of event logs and event log filters */
LIST_ENTRY EventLogList; LIST_ENTRY EventLogList;
@ -129,6 +129,32 @@ INT_PTR EventLogProperties(HINSTANCE, HWND, PEVENTLOGFILTER);
INT_PTR CALLBACK EventDetails(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK EventDetails(HWND, UINT, WPARAM, LPARAM);
/* MAIN FUNCTIONS *************************************************************/
VOID
ShowWin32Error(IN DWORD dwError)
{
LPWSTR lpMessageBuffer;
if (dwError == ERROR_SUCCESS)
return;
if (!FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
LANG_USER_DEFAULT,
(LPWSTR)&lpMessageBuffer,
0, NULL))
{
return;
}
MessageBoxW(hwndMainWindow, lpMessageBuffer, szTitle, MB_OK | MB_ICONERROR);
LocalFree(lpMessageBuffer);
}
int APIENTRY int APIENTRY
wWinMain(HINSTANCE hInstance, wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, HINSTANCE hPrevInstance,
@ -158,6 +184,9 @@ wWinMain(HINSTANCE hInstance,
msg.wParam = (WPARAM)-1; msg.wParam = (WPARAM)-1;
/* Store the instance handle in the global variable */
hInst = hInstance;
/* Initialize global strings */ /* Initialize global strings */
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, ARRAYSIZE(szTitle)); LoadStringW(hInstance, IDS_APP_TITLE, szTitle, ARRAYSIZE(szTitle));
LoadStringW(hInstance, IDS_APP_TITLE_EX, szTitleTemplate, ARRAYSIZE(szTitleTemplate)); LoadStringW(hInstance, IDS_APP_TITLE_EX, szTitleTemplate, ARRAYSIZE(szTitleTemplate));
@ -235,32 +264,6 @@ Quit:
/* GENERIC HELPER FUNCTIONS ***************************************************/ /* GENERIC HELPER FUNCTIONS ***************************************************/
VOID
ShowLastWin32Error(VOID)
{
DWORD dwError;
LPWSTR lpMessageBuffer;
dwError = GetLastError();
if (dwError == ERROR_SUCCESS)
return;
if (!FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
LANG_USER_DEFAULT,
(LPWSTR)&lpMessageBuffer,
0, NULL))
{
return;
}
MessageBoxW(hwndMainWindow, lpMessageBuffer, szTitle, MB_OK | MB_ICONERROR);
LocalFree(lpMessageBuffer);
}
VOID VOID
EventTimeToSystemTime(IN DWORD EventTime, EventTimeToSystemTime(IN DWORD EventTime,
OUT PSYSTEMTIME pSystemTime) OUT PSYSTEMTIME pSystemTime)
@ -475,10 +478,10 @@ ApplyParameterStringsToMessage(
while ((pTempMessage = wcschr(pTempMessage, L'%'))) while ((pTempMessage = wcschr(pTempMessage, L'%')))
{ {
pTempMessage++; pTempMessage++;
if (isdigit(*pTempMessage)) if (iswdigit(*pTempMessage))
{ {
dwParamCount++; dwParamCount++;
while (isdigit(*++pTempMessage)) ; while (iswdigit(*++pTempMessage)) ;
} }
} }
} }
@ -487,10 +490,10 @@ ApplyParameterStringsToMessage(
while ((pTempMessage = wcsstr(pTempMessage, L"%%"))) while ((pTempMessage = wcsstr(pTempMessage, L"%%")))
{ {
pTempMessage += 2; pTempMessage += 2;
if (isdigit(*pTempMessage)) if (iswdigit(*pTempMessage))
{ {
dwParamCount++; dwParamCount++;
while (isdigit(*++pTempMessage)) ; while (iswdigit(*++pTempMessage)) ;
} }
} }
} }
@ -520,12 +523,12 @@ ApplyParameterStringsToMessage(
while ((pTempMessage = wcschr(pTempMessage, L'%')) && (i < dwParamCount)) while ((pTempMessage = wcschr(pTempMessage, L'%')) && (i < dwParamCount))
{ {
pTempMessage++; pTempMessage++;
if (isdigit(*pTempMessage)) if (iswdigit(*pTempMessage))
{ {
pParamData[i].pStartingAddress = pTempMessage-1; pParamData[i].pStartingAddress = pTempMessage-1;
pParamData[i].pParameterID = (DWORD)_wtol(pTempMessage); pParamData[i].pParameterID = (DWORD)_wtol(pTempMessage);
while (isdigit(*++pTempMessage)) ; while (iswdigit(*++pTempMessage)) ;
pParamData[i].pEndingAddress = pTempMessage; pParamData[i].pEndingAddress = pTempMessage;
i++; i++;
@ -537,12 +540,12 @@ ApplyParameterStringsToMessage(
while ((pTempMessage = wcsstr(pTempMessage, L"%%")) && (i < dwParamCount)) while ((pTempMessage = wcsstr(pTempMessage, L"%%")) && (i < dwParamCount))
{ {
pTempMessage += 2; pTempMessage += 2;
if (isdigit(*pTempMessage)) if (iswdigit(*pTempMessage))
{ {
pParamData[i].pStartingAddress = pTempMessage-2; pParamData[i].pStartingAddress = pTempMessage-2;
pParamData[i].pParameterID = (DWORD)_wtol(pTempMessage); pParamData[i].pParameterID = (DWORD)_wtol(pTempMessage);
while (isdigit(*++pTempMessage)) ; while (iswdigit(*++pTempMessage)) ;
pParamData[i].pEndingAddress = pTempMessage; pParamData[i].pEndingAddress = pTempMessage;
i++; i++;
@ -847,6 +850,8 @@ AllocEventLog(IN PCWSTR ComputerName OPTIONAL,
EventLog->LogName = HeapAlloc(GetProcessHeap(), 0, cchName * sizeof(WCHAR)); EventLog->LogName = HeapAlloc(GetProcessHeap(), 0, cchName * sizeof(WCHAR));
if (!EventLog->LogName) if (!EventLog->LogName)
{ {
if (EventLog->ComputerName)
HeapFree(GetProcessHeap(), 0, EventLog->ComputerName);
HeapFree(GetProcessHeap(), 0, EventLog); HeapFree(GetProcessHeap(), 0, EventLog);
return NULL; return NULL;
} }
@ -863,6 +868,9 @@ EventLog_Free(IN PEVENTLOG EventLog)
if (EventLog->LogName) if (EventLog->LogName)
HeapFree(GetProcessHeap(), 0, EventLog->LogName); HeapFree(GetProcessHeap(), 0, EventLog->LogName);
if (EventLog->ComputerName)
HeapFree(GetProcessHeap(), 0, EventLog->ComputerName);
if (EventLog->FileName) if (EventLog->FileName)
HeapFree(GetProcessHeap(), 0, EventLog->FileName); HeapFree(GetProcessHeap(), 0, EventLog->FileName);
@ -1164,7 +1172,7 @@ GetEventMessage(IN LPCWSTR KeyName,
lpMsgBuf = szMessage; lpMsgBuf = szMessage;
while ((lpMsgBuf = wcsstr(lpMsgBuf, L"%%"))) while ((lpMsgBuf = wcsstr(lpMsgBuf, L"%%")))
{ {
if (isdigit(lpMsgBuf[2])) if (iswdigit(lpMsgBuf[2]))
{ {
RtlMoveMemory(lpMsgBuf, lpMsgBuf+1, ((szStringArray + cch) - lpMsgBuf - 1) * sizeof(WCHAR)); RtlMoveMemory(lpMsgBuf, lpMsgBuf+1, ((szStringArray + cch) - lpMsgBuf - 1) * sizeof(WCHAR));
} }
@ -1493,7 +1501,7 @@ EnumEventsThread(IN LPVOID lpParameter)
if (hEventLog == NULL) if (hEventLog == NULL)
{ {
ShowLastWin32Error(); ShowWin32Error(GetLastError());
goto Cleanup; goto Cleanup;
} }
@ -1517,7 +1525,7 @@ EnumEventsThread(IN LPVOID lpParameter)
g_RecordPtrs = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, dwTotalRecords * sizeof(*g_RecordPtrs)); g_RecordPtrs = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, dwTotalRecords * sizeof(*g_RecordPtrs));
if (!g_RecordPtrs) if (!g_RecordPtrs)
{ {
// ShowLastWin32Error(); // ShowWin32Error(GetLastError());
goto Quit; goto Quit;
} }
g_TotalRecords = dwTotalRecords; g_TotalRecords = dwTotalRecords;
@ -1890,11 +1898,72 @@ GetSelectedFilter(OUT HTREEITEM* phti OPTIONAL)
VOID VOID
OpenUserEventLog(VOID) OpenUserEventLogFile(IN LPCWSTR lpszFileName)
{ {
WIN32_FIND_DATAW FindData;
HANDLE hFind;
PEVENTLOG EventLog; PEVENTLOG EventLog;
PEVENTLOGFILTER EventLogFilter; PEVENTLOGFILTER EventLogFilter;
SIZE_T cchFileName;
HTREEITEM hItem = NULL; HTREEITEM hItem = NULL;
/* Check whether the file actually exists */
hFind = FindFirstFileW(lpszFileName, &FindData);
if (hFind == INVALID_HANDLE_VALUE)
{
ShowWin32Error(GetLastError());
return;
}
FindClose(hFind);
/* Allocate a new event log entry */
EventLog = AllocEventLog(NULL, lpszFileName, FALSE);
if (EventLog == NULL)
{
ShowWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return;
}
/* Allocate a new event log filter entry for this event log */
EventLogFilter = AllocEventLogFilter(// LogName,
TRUE, TRUE, TRUE, TRUE, TRUE,
NULL, NULL, NULL,
1, &EventLog);
if (EventLogFilter == NULL)
{
ShowWin32Error(ERROR_NOT_ENOUGH_MEMORY);
EventLog_Free(EventLog);
return;
}
/* Add the event log and the filter into their lists */
InsertTailList(&EventLogList, &EventLog->ListEntry);
InsertTailList(&EventLogFilterList, &EventLogFilter->ListEntry);
/* Retrieve and cache the event log file */
cchFileName = wcslen(lpszFileName) + 1;
EventLog->FileName = HeapAlloc(GetProcessHeap(), 0, cchFileName * sizeof(WCHAR));
if (EventLog->FileName)
StringCchCopyW(EventLog->FileName, cchFileName, lpszFileName);
hItem = TreeViewAddItem(hwndTreeView, htiUserLogs,
(LPWSTR)lpszFileName,
2, 3, (LPARAM)EventLogFilter);
/* Select the event log */
if (hItem)
{
// TreeView_Expand(hwndTreeView, htiUserLogs, TVE_EXPAND);
TreeView_SelectItem(hwndTreeView, hItem);
TreeView_EnsureVisible(hwndTreeView, hItem);
}
InvalidateRect(hwndTreeView, NULL, FALSE);
SetFocus(hwndTreeView);
}
VOID
OpenUserEventLog(VOID)
{
WCHAR szFileName[MAX_PATH]; WCHAR szFileName[MAX_PATH];
ZeroMemory(szFileName, sizeof(szFileName)); ZeroMemory(szFileName, sizeof(szFileName));
@ -1906,43 +1975,7 @@ OpenUserEventLog(VOID)
return; return;
sfn.lpstrFile[sfn.nMaxFile-1] = UNICODE_NULL; sfn.lpstrFile[sfn.nMaxFile-1] = UNICODE_NULL;
/* Allocate a new event log entry */ OpenUserEventLogFile(sfn.lpstrFile);
EventLog = AllocEventLog(NULL, sfn.lpstrFile, FALSE);
if (EventLog == NULL)
return;
/* Allocate a new event log filter entry for this event log */
EventLogFilter = AllocEventLogFilter(// LogName,
TRUE, TRUE, TRUE, TRUE, TRUE,
NULL, NULL, NULL,
1, &EventLog);
if (EventLogFilter == NULL)
{
HeapFree(GetProcessHeap(), 0, EventLog);
return;
}
/* Add the event log and the filter into their lists */
InsertTailList(&EventLogList, &EventLog->ListEntry);
InsertTailList(&EventLogFilterList, &EventLogFilter->ListEntry);
/* Retrieve and cache the event log file */
EventLog->FileName = HeapAlloc(GetProcessHeap(), 0, sfn.nMaxFile * sizeof(WCHAR));
if (EventLog->FileName)
StringCchCopyW(EventLog->FileName, sfn.nMaxFile, sfn.lpstrFile);
hItem = TreeViewAddItem(hwndTreeView, htiUserLogs,
szFileName,
2, 3, (LPARAM)EventLogFilter);
/* Select the event log */
if (hItem)
{
// TreeView_Expand(hwndTreeView, htiUserLogs, TVE_EXPAND);
TreeView_SelectItem(hwndTreeView, hItem);
TreeView_EnsureVisible(hwndTreeView, hItem);
}
SetFocus(hwndTreeView);
} }
VOID VOID
@ -1973,12 +2006,12 @@ SaveEventLog(IN PEVENTLOGFILTER EventLogFilter)
if (!hEventLog) if (!hEventLog)
{ {
ShowLastWin32Error(); ShowWin32Error(GetLastError());
return; return;
} }
if (!BackupEventLogW(hEventLog, szFileName)) if (!BackupEventLogW(hEventLog, szFileName))
ShowLastWin32Error(); ShowWin32Error(GetLastError());
CloseEventLog(hEventLog); CloseEventLog(hEventLog);
} }
@ -2013,6 +2046,7 @@ CloseUserEventLog(IN PEVENTLOGFILTER EventLogFilter, IN HTREEITEM hti)
// // TreeView_Expand(hwndTreeView, htiUserLogs, TVE_EXPAND); // // TreeView_Expand(hwndTreeView, htiUserLogs, TVE_EXPAND);
// TreeView_SelectItem(hwndTreeView, hItem); // TreeView_SelectItem(hwndTreeView, hItem);
// TreeView_EnsureVisible(hwndTreeView, hItem); // TreeView_EnsureVisible(hwndTreeView, hItem);
InvalidateRect(hwndTreeView, NULL, FALSE);
SetFocus(hwndTreeView); SetFocus(hwndTreeView);
} }
@ -2062,13 +2096,13 @@ ClearEvents(IN PEVENTLOGFILTER EventLogFilter)
if (!hEventLog) if (!hEventLog)
{ {
ShowLastWin32Error(); ShowWin32Error(GetLastError());
return FALSE; return FALSE;
} }
Success = ClearEventLogW(hEventLog, sfn.lpstrFile); Success = ClearEventLogW(hEventLog, sfn.lpstrFile);
if (!Success) if (!Success)
ShowLastWin32Error(); ShowWin32Error(GetLastError());
CloseEventLog(hEventLog); CloseEventLog(hEventLog);
return Success; return Success;
@ -2254,7 +2288,7 @@ BuildLogListAndFilterList(IN LPCWSTR lpComputerName)
1, &EventLog); 1, &EventLog);
if (EventLogFilter == NULL) if (EventLogFilter == NULL)
{ {
HeapFree(GetProcessHeap(), 0, EventLog); EventLog_Free(EventLog);
continue; continue;
} }
@ -2369,6 +2403,7 @@ Quit:
TreeView_SelectItem(hwndTreeView, hItemDefault); TreeView_SelectItem(hwndTreeView, hItemDefault);
TreeView_EnsureVisible(hwndTreeView, hItemDefault); TreeView_EnsureVisible(hwndTreeView, hItemDefault);
} }
InvalidateRect(hwndTreeView, NULL, FALSE);
SetFocus(hwndTreeView); SetFocus(hwndTreeView);
return; return;
@ -2418,8 +2453,6 @@ InitInstance(HINSTANCE hInstance,
LVCOLUMNW lvc = {0}; LVCOLUMNW lvc = {0};
WCHAR szTemp[256]; WCHAR szTemp[256];
hInst = hInstance; // Store instance handle in our global variable
/* Create the main window */ /* Create the main window */
hwndMainWindow = CreateWindowW(szWindowClass, hwndMainWindow = CreateWindowW(szWindowClass,
szTitle, szTitle,

View file

@ -80,39 +80,39 @@
/* String IDs */ /* String IDs */
#define IDS_COPYRIGHT 102 #define IDS_COPYRIGHT 100
#define IDS_APP_TITLE 103 #define IDS_APP_TITLE 101
#define IDS_APP_TITLE_EX 104 #define IDS_APP_TITLE_EX 102
#define IDS_STATUS_MSG 105 #define IDS_STATUS_MSG 103
#define IDS_LOADING_WAIT 106 #define IDS_LOADING_WAIT 104
#define IDS_NO_ITEMS 107 #define IDS_NO_ITEMS 105
#define IDS_EVENTLOG_SYSTEM 108 #define IDS_EVENTLOG_SYSTEM 106
#define IDS_EVENTLOG_APP 109 #define IDS_EVENTLOG_APP 107
#define IDS_EVENTLOG_USER 110 #define IDS_EVENTLOG_USER 108
#define IDS_EVENTSTRINGIDNOTFOUND 209 #define IDS_EVENTSTRINGIDNOTFOUND 109
#define IDS_CLEAREVENTS_MSG 210 #define IDS_CLEAREVENTS_MSG 110
#define IDS_SAVE_FILTER 211 #define IDS_SAVE_FILTER 111
#define IDS_EVENTLOG_ERROR_TYPE 251 #define IDS_EVENTLOG_ERROR_TYPE 200
#define IDS_EVENTLOG_WARNING_TYPE 252 #define IDS_EVENTLOG_WARNING_TYPE 201
#define IDS_EVENTLOG_INFORMATION_TYPE 253 #define IDS_EVENTLOG_INFORMATION_TYPE 202
#define IDS_EVENTLOG_AUDIT_SUCCESS 254 #define IDS_EVENTLOG_AUDIT_SUCCESS 203
#define IDS_EVENTLOG_AUDIT_FAILURE 255 #define IDS_EVENTLOG_AUDIT_FAILURE 204
#define IDS_EVENTLOG_SUCCESS 256 #define IDS_EVENTLOG_SUCCESS 205
#define IDS_EVENTLOG_UNKNOWN_TYPE 257 #define IDS_EVENTLOG_UNKNOWN_TYPE 206
#define IDS_BYTES_FORMAT 260 #define IDS_BYTES_FORMAT 210
#define IDS_COLUMNTYPE 300 #define IDS_COLUMNTYPE 220
#define IDS_COLUMNDATE 301 #define IDS_COLUMNDATE 221
#define IDS_COLUMNTIME 302 #define IDS_COLUMNTIME 222
#define IDS_COLUMNSOURCE 303 #define IDS_COLUMNSOURCE 223
#define IDS_COLUMNCATEGORY 304 #define IDS_COLUMNCATEGORY 224
#define IDS_COLUMNEVENT 305 #define IDS_COLUMNEVENT 225
#define IDS_COLUMNUSER 306 #define IDS_COLUMNUSER 226
#define IDS_COLUMNCOMPUTER 307 #define IDS_COLUMNCOMPUTER 227
#define IDS_COPY 400 #define IDS_COPY 240
#define IDS_NONE 320 #define IDS_NONE 250
#define IDS_NOT_AVAILABLE 321 #define IDS_NOT_AVAILABLE 251