#define LVM_PROGRESS (WM_APP + 1) // Used by the subclassed ListView
-static const LPCWSTR szWindowClass = L"EVENTVWR"; /* The main window class name */
-static const WCHAR EVENTLOG_BASE_KEY[] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
+static const LPCWSTR EVENTVWR_WNDCLASS = L"EVENTVWR"; /* The main window class name */
+static const LPCWSTR EVENTLOG_BASE_KEY = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
+static const LPCWSTR EVNTVWR_PARAM_KEY = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Event Viewer";
/* The 3 system logs that should always exist in the user's system */
static const LPCWSTR SystemLogs[] =
LPWSTR lpszzUserLogsToLoad = NULL; /* The list of user logs to load at startup (multi-string) */
SIZE_T cbUserLogsSize = 0;
+HKEY hkMachine = NULL; // Registry handle to the HKEY_LOCAL_MACHINE key of the remote computer registry.
/* Global event records cache for the current active event log filter */
DWORD g_TotalRecords = 0;
LIST_ENTRY EventLogList;
LIST_ENTRY EventLogFilterList;
PEVENTLOGFILTER ActiveFilter = NULL;
-BOOL NewestEventsFirst = TRUE;
HANDLE hEnumEventsThread = NULL;
HANDLE hStopEnumEvent = NULL;
OPENFILENAMEW sfn;
+/* Event Viewer Application Settings */
+typedef struct _SETTINGS
+{
+ BOOL bShowDetailsPane; /* Show (TRUE) or Hide (FALSE) the events details pane */
+ BOOL bShowGrid; /* Show (TRUE) or Hide (FALSE) the events view grid */
+ BOOL bSaveSettings; /* Save (TRUE) or do not save (FALSE) current settings on exit */
+ BOOL bNewestEventsFirst; /* Sort the displayed events the newest ones first (TRUE) or last (FALSE) */
+ INT nVSplitPos; /* Vertical splitter position */
+ INT nHSplitPos; /* Horizontal splitter position */
+ WINDOWPLACEMENT wpPos;
+} SETTINGS, *PSETTINGS;
+
+SETTINGS Settings;
+
+
/* Forward declarations of functions included in this code module */
static DWORD WINAPI
VOID FreeLogFilterList(VOID);
ATOM MyRegisterClass(HINSTANCE);
-BOOL InitInstance(HINSTANCE, int);
+BOOL InitInstance(HINSTANCE);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR EventLogProperties(HINSTANCE, HWND, PEVENTLOGFILTER);
INT_PTR CALLBACK EventDetails(HWND, UINT, WPARAM, LPARAM);
if (i == 1)
{
/* Store the computer name */
+ LPWSTR lpTemp = argv[i];
SIZE_T cbLength;
- cbLength = (wcslen(argv[i]) + 1) * sizeof(WCHAR);
+ /* Strip any leading backslashes */
+ while (*lpTemp == L'\\')
+ ++lpTemp;
+
+ cbLength = (wcslen(lpTemp) + 1) * sizeof(WCHAR);
lpComputerName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength);
if (lpComputerName)
{
- StringCbCopyW(lpComputerName, cbLength, argv[i]);
+ StringCbCopyW(lpComputerName, cbLength, lpTemp);
}
/* else, fall back to local computer */
}
return Success;
}
+BOOL
+LoadSettings(int nDefCmdShow)
+{
+ HKEY hKeyEventVwr;
+ LONG Result;
+ DWORD dwSize;
+ DWORD dwType;
+ DWORD Value;
+ UNICODE_STRING ValueU;
+ WCHAR buffer[100];
+
+ /* Load the default values */
+ Settings.bShowDetailsPane = TRUE;
+ Settings.bShowGrid = FALSE;
+ Settings.bSaveSettings = TRUE;
+ Settings.bNewestEventsFirst = TRUE;
+ Settings.nVSplitPos = 250; /* Splitter default positions */
+ Settings.nHSplitPos = 250;
+ ZeroMemory(&Settings.wpPos, sizeof(Settings.wpPos));
+ Settings.wpPos.length = sizeof(Settings.wpPos);
+ Settings.wpPos.rcNormalPosition.left = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.top = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.right = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.bottom = CW_USEDEFAULT;
+
+ /* Try to create/open the Event Viewer user key */
+ if (RegCreateKeyExW(HKEY_CURRENT_USER,
+ EVNTVWR_PARAM_KEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ NULL,
+ &hKeyEventVwr,
+ NULL) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ // Result = RegQueryValueExW(hKeyEventVwr, L"Filter", NULL, &dwType, (LPBYTE)&szFilter, &dwSize); // REG_SZ
+ // Result = RegQueryValueExW(hKeyEventVwr, L"Find", NULL, &dwType, (LPBYTE)&szFind, &dwSize); // REG_SZ
+ // Result = RegQueryValueExW(hKeyEventVwr, L"Module", NULL, &dwType, (LPBYTE)&szModule, &dwSize); // REG_SZ
+
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"DetailsPane", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.bShowDetailsPane = !!Value;
+ }
+
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"ShowGrid", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.bShowGrid = !!Value;
+ }
+
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"SortOrder", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.bNewestEventsFirst = !!Value;
+ }
+
+ /* Retrieve the splitter positions */
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"VSplitPos", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.nVSplitPos = Value;
+ }
+
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"HSplitPos", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.nHSplitPos = Value;
+ }
+
+ /* Retrieve the geometry of the main window */
+ dwSize = sizeof(buffer);
+ Result = RegQueryValueExW(hKeyEventVwr, L"Window", NULL, &dwType, (LPBYTE)buffer, &dwSize);
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_SZ))
+ buffer[0] = UNICODE_NULL;
+
+ if (swscanf(buffer, L"%d %d %d %d %d",
+ &Settings.wpPos.rcNormalPosition.left,
+ &Settings.wpPos.rcNormalPosition.top,
+ &Settings.wpPos.rcNormalPosition.right,
+ &Settings.wpPos.rcNormalPosition.bottom,
+ &Settings.wpPos.showCmd) != 5)
+ {
+ /* Parsing failed, use defaults */
+ Settings.wpPos.rcNormalPosition.left = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.top = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.right = CW_USEDEFAULT;
+ Settings.wpPos.rcNormalPosition.bottom = CW_USEDEFAULT;
+ Settings.wpPos.showCmd = nDefCmdShow; // SW_SHOWNORMAL;
+ }
+
+ dwSize = sizeof(Value);
+ Result = RegQueryValueExW(hKeyEventVwr, L"SaveSettings", NULL, &dwType, (LPBYTE)&Value, &dwSize);
+ if ((Result == ERROR_SUCCESS) && (dwType == REG_SZ || dwType == REG_DWORD))
+ {
+ if (dwType == REG_SZ)
+ {
+ ValueU.Buffer = (PWSTR)&Value;
+ ValueU.Length = ValueU.MaximumLength = dwSize;
+ RtlUnicodeStringToInteger(&ValueU, 10, &Value);
+ }
+ Settings.bSaveSettings = !!Value;
+ }
+
+ RegCloseKey(hKeyEventVwr);
+ return TRUE;
+}
+
+BOOL
+SaveSettings(VOID)
+{
+ HKEY hKeyEventVwr;
+ DWORD dwSize;
+ WCHAR buffer[100];
+
+ /* Try to create/open the Event Viewer user key */
+ if (RegCreateKeyExW(HKEY_CURRENT_USER,
+ EVNTVWR_PARAM_KEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ NULL,
+ &hKeyEventVwr,
+ NULL) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ dwSize = sizeof(Settings.bSaveSettings);
+ RegSetValueExW(hKeyEventVwr, L"SaveSettings", 0, REG_DWORD, (LPBYTE)&Settings.bSaveSettings, dwSize);
+
+ /* Do not save more settings if we are not asked to do so */
+ if (!Settings.bSaveSettings)
+ goto Quit;
+
+ dwSize = sizeof(Settings.bShowDetailsPane);
+ RegSetValueExW(hKeyEventVwr, L"DetailsPane", 0, REG_DWORD, (LPBYTE)&Settings.bShowDetailsPane, dwSize);
+
+ dwSize = sizeof(Settings.bShowGrid);
+ RegSetValueExW(hKeyEventVwr, L"ShowGrid", 0, REG_DWORD, (LPBYTE)&Settings.bShowGrid, dwSize);
+
+ dwSize = sizeof(Settings.bNewestEventsFirst);
+ RegSetValueExW(hKeyEventVwr, L"SortOrder", 0, REG_DWORD, (LPBYTE)&Settings.bNewestEventsFirst, dwSize);
+
+ Settings.nVSplitPos = nVSplitPos;
+ dwSize = sizeof(Settings.nVSplitPos);
+ RegSetValueExW(hKeyEventVwr, L"VSplitPos", 0, REG_DWORD, (LPBYTE)&Settings.nVSplitPos, dwSize);
+
+ Settings.nHSplitPos = nHSplitPos;
+ dwSize = sizeof(Settings.nHSplitPos);
+ RegSetValueExW(hKeyEventVwr, L"HSplitPos", 0, REG_DWORD, (LPBYTE)&Settings.nHSplitPos, dwSize);
+
+ StringCbPrintfW(buffer, sizeof(buffer),
+ L"%d %d %d %d %d",
+ Settings.wpPos.rcNormalPosition.left,
+ Settings.wpPos.rcNormalPosition.top,
+ Settings.wpPos.rcNormalPosition.right,
+ Settings.wpPos.rcNormalPosition.bottom,
+ Settings.wpPos.showCmd);
+
+ dwSize = wcslen(buffer) * sizeof(WCHAR);
+ RegSetValueExW(hKeyEventVwr, L"Window", 0, REG_SZ, (LPBYTE)buffer, dwSize);
+
+Quit:
+ RegCloseKey(hKeyEventVwr);
+ return TRUE;
+}
+
int APIENTRY
wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
if (!MyRegisterClass(hInstance))
goto Quit;
+ /* Load the settings */
+ LoadSettings(nCmdShow);
+
/* Perform application initialization */
- if (!InitInstance(hInstance, nCmdShow))
+ if (!InitInstance(hInstance))
goto Quit;
hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDA_EVENTVWR));
}
}
+ /* Save the settings */
+ SaveSettings();
+
+ /* Disconnect from computer */
+ if (hkMachine && hkMachine != HKEY_LOCAL_MACHINE)
+ {
+ /* We are connected to some other computer, close the old connection */
+ RegCloseKey(hkMachine);
+ hkMachine = NULL;
+ }
+
+ /* Stop the enumerator thread */
SetEvent(hStartStopEnumEvent);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
else
{
+ LPWSTR ptr;
+
ASSERT(lpMsgBuf);
+
+ /* Trim any trailing whitespace */
+ ptr = lpMsgBuf + dwLength - 1;
+ while (iswspace(*ptr))
+ *ptr-- = UNICODE_NULL;
}
return lpMsgBuf;
}
}
+DWORD
+GetExpandedFilePathName(
+ IN LPCWSTR ComputerName OPTIONAL,
+ IN LPCWSTR lpFileName,
+ OUT LPWSTR lpFullFileName OPTIONAL,
+ IN DWORD nSize)
+{
+ DWORD dwLength;
+
+ /* Determine the needed size after expansion of any environment strings */
+ dwLength = ExpandEnvironmentStringsW(lpFileName, NULL, 0);
+ if (dwLength == 0)
+ {
+ /* We failed, bail out */
+ return 0;
+ }
+
+ /* If the file path is on a remote computer, estimate its length */
+ // FIXME: Use WNetGetUniversalName instead?
+ if (ComputerName && *ComputerName)
+ {
+ /* Skip any leading backslashes */
+ while (*ComputerName == L'\\')
+ ++ComputerName;
+
+ if (*ComputerName)
+ {
+ /* Count 2 backslashes plus the computer name and one backslash separator */
+ dwLength += 2 + wcslen(ComputerName) + 1;
+ }
+ }
+
+ /* Check whether we have enough space */
+ if (dwLength > nSize)
+ {
+ /* No, return the needed size in characters (includes NULL-terminator) */
+ return dwLength;
+ }
+
+
+ /* Now expand the file path */
+ ASSERT(dwLength <= nSize);
+
+ /* Expand any existing environment strings */
+ if (ExpandEnvironmentStringsW(lpFileName, lpFullFileName, dwLength) == 0)
+ {
+ /* We failed, bail out */
+ return 0;
+ }
+
+ /* If the file path is on a remote computer, retrieve the network share form of the file name */
+ // FIXME: Use WNetGetUniversalName instead?
+ if (ComputerName && *ComputerName)
+ {
+ /* Note that we previously skipped any potential leading backslashes */
+
+ /* Replace ':' by '$' in the drive letter */
+ if (*lpFullFileName && lpFullFileName[1] == L':')
+ lpFullFileName[1] = L'$';
+
+ /* Prepend the computer name */
+ RtlMoveMemory(lpFullFileName + 2 + wcslen(ComputerName) + 1,
+ lpFullFileName, dwLength * sizeof(WCHAR) - (2 + wcslen(ComputerName) + 1) * sizeof(WCHAR));
+ lpFullFileName[0] = L'\\';
+ lpFullFileName[1] = L'\\';
+ wcsncpy(lpFullFileName + 2, ComputerName, wcslen(ComputerName));
+ lpFullFileName[2 + wcslen(ComputerName)] = L'\\';
+ }
+
+ /* Return the number of stored characters (includes NULL-terminator) */
+ return dwLength;
+}
+
BOOL
GetEventMessageFileDLL(IN LPCWSTR lpLogName,
IN LPCWSTR SourceName,
{
BOOL Success = FALSE;
LONG Result;
- DWORD Type, dwSize;
+ DWORD dwType, dwSize;
WCHAR szModuleName[MAX_PATH];
WCHAR szKeyName[MAX_PATH];
HKEY hLogKey = NULL;
StringCbCopyW(szKeyName, sizeof(szKeyName), EVENTLOG_BASE_KEY);
StringCbCatW(szKeyName, sizeof(szKeyName), lpLogName);
- Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ Result = RegOpenKeyExW(hkMachine,
szKeyName,
0,
KEY_READ,
Result = RegQueryValueExW(hSourceKey,
EntryName,
NULL,
- &Type,
+ &dwType,
(LPBYTE)szModuleName,
&dwSize);
- if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_EXPAND_SZ && dwType != REG_SZ))
{
szModuleName[0] = UNICODE_NULL;
}
{
/* NULL-terminate the string and expand it */
szModuleName[dwSize / sizeof(WCHAR) - 1] = UNICODE_NULL;
- ExpandEnvironmentStringsW(szModuleName, lpModuleName, ARRAYSIZE(szModuleName));
+ GetExpandedFilePathName(lpComputerName, szModuleName, lpModuleName, ARRAYSIZE(szModuleName));
Success = TRUE;
}
* string-form. It should not be bigger than the user-provided buffer
* 'pszUser', otherwise we return an error.
*/
- if (LookupAccountSidW(NULL, // FIXME: Use computer name? From the particular event?
+ if (LookupAccountSidW(lpComputerName,
pCurrentSid,
szName,
&cchName,
ProgressBar_SetRange(hwndStatusProgress, MAKELPARAM(0, 100));
uStepAt = (dwTotalRecords / 100) + 1;
- dwFlags = EVENTLOG_SEQUENTIAL_READ | (NewestEventsFirst ? EVENTLOG_FORWARDS_READ : EVENTLOG_BACKWARDS_READ);
+ dwFlags = EVENTLOG_SEQUENTIAL_READ | (Settings.bNewestEventsFirst ? EVENTLOG_FORWARDS_READ : EVENTLOG_BACKWARDS_READ);
/* 0x7ffff is the maximum buffer size ReadEventLog will accept */
dwWanted = 0x7ffff;
}
else if (!bResult)
{
- /* exit on other errors (ERROR_HANDLE_EOF) */
+ /* Exit on other errors (ERROR_HANDLE_EOF) */
break;
}
wcex.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW));
wcex.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); // COLOR_WINDOW + 1
wcex.lpszMenuName = MAKEINTRESOURCEW(IDM_EVENTVWR);
- wcex.lpszClassName = szWindowClass;
+ wcex.lpszClassName = EVENTVWR_WNDCLASS;
wcex.hIconSm = (HICON)LoadImageW(hInstance,
MAKEINTRESOURCEW(IDI_EVENTVWR),
IMAGE_ICON,
HKEY hLogKey;
WCHAR *KeyPath;
SIZE_T cbKeyPath;
- DWORD Type, cbData;
+ DWORD dwType, cbData;
DWORD dwMessageID = 0;
WCHAR szModuleName[MAX_PATH];
StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY);
StringCbCatW(KeyPath, cbKeyPath, lpLogName);
- Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_QUERY_VALUE, &hLogKey);
+ Result = RegOpenKeyExW(hkMachine, KeyPath, 0, KEY_QUERY_VALUE, &hLogKey);
HeapFree(GetProcessHeap(), 0, KeyPath);
if (Result != ERROR_SUCCESS)
return FALSE;
Result = RegQueryValueExW(hLogKey,
L"DisplayNameFile",
NULL,
- &Type,
+ &dwType,
(LPBYTE)szModuleName,
&cbData);
- if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_EXPAND_SZ && dwType != REG_SZ))
{
szModuleName[0] = UNICODE_NULL;
}
{
/* NULL-terminate the string and expand it */
szModuleName[cbData / sizeof(WCHAR) - 1] = UNICODE_NULL;
- ExpandEnvironmentStringsW(szModuleName, lpModuleName, ARRAYSIZE(szModuleName));
+ GetExpandedFilePathName(lpComputerName, szModuleName, lpModuleName, ARRAYSIZE(szModuleName));
Success = TRUE;
}
Result = RegQueryValueExW(hLogKey,
L"DisplayNameID",
NULL,
- &Type,
+ &dwType,
(LPBYTE)&dwMessageID,
&cbData);
- if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_DWORD))
dwMessageID = 0;
*pdwMessageID = dwMessageID;
HKEY hEventLogKey, hLogKey;
DWORD dwNumLogs = 0;
DWORD dwIndex, dwMaxKeyLength;
- DWORD Type;
+ DWORD dwType;
PEVENTLOG EventLog;
PEVENTLOGFILTER EventLogFilter;
LPWSTR LogName = NULL;
LPWSTR lpDisplayName;
HTREEITEM hRootNode = NULL, hItem = NULL, hItemDefault = NULL;
+ if (hkMachine && hkMachine != HKEY_LOCAL_MACHINE)
+ {
+ /* We are connected to some other computer, close the old connection */
+ RegCloseKey(hkMachine);
+ hkMachine = NULL;
+ }
+ if (!lpComputerName || !*lpComputerName)
+ {
+ /* Use the local computer registry */
+ hkMachine = HKEY_LOCAL_MACHINE;
+ }
+ else
+ {
+ /* Connect to the remote computer registry */
+ Result = RegConnectRegistry(lpComputerName, HKEY_LOCAL_MACHINE, &hkMachine);
+ if (Result != ERROR_SUCCESS)
+ {
+ /* Connection failed, display a message and bail out */
+ hkMachine = NULL;
+ ShowWin32Error(GetLastError());
+ return;
+ }
+ }
+
/* Open the EventLog key */
- // TODO: Implement connection to remote computer...
- // At the moment we only support the user local computer.
- // FIXME: Use local or remote computer
- Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, EVENTLOG_BASE_KEY, 0, KEY_READ, &hEventLogKey);
+ Result = RegOpenKeyExW(hkMachine, EVENTLOG_BASE_KEY, 0, KEY_READ, &hEventLogKey);
if (Result != ERROR_SUCCESS)
{
return;
Result = RegQueryValueExW(hLogKey,
L"File",
NULL,
- &Type,
+ &dwType,
NULL,
&lpcName);
- if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_EXPAND_SZ && dwType != REG_SZ))
{
// Windows' EventLog uses some kind of default value, we do not.
EventLog->FileName = NULL;
Result = RegQueryValueExW(hLogKey,
L"File",
NULL,
- &Type,
+ &dwType,
(LPBYTE)EventLog->FileName,
&lpcName);
if (Result != ERROR_SUCCESS)
}
BOOL
-InitInstance(HINSTANCE hInstance,
- int nCmdShow)
+InitInstance(HINSTANCE hInstance)
{
RECT rcClient, rs;
LONG StatusHeight;
WCHAR szTemp[256];
/* Create the main window */
- hwndMainWindow = CreateWindowW(szWindowClass,
+ rs = Settings.wpPos.rcNormalPosition;
+ hwndMainWindow = CreateWindowW(EVENTVWR_WNDCLASS,
szTitle,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ rs.left, rs.top,
+ (rs.right != CW_USEDEFAULT && rs.left != CW_USEDEFAULT) ? rs.right - rs.left : CW_USEDEFAULT,
+ (rs.bottom != CW_USEDEFAULT && rs.top != CW_USEDEFAULT) ? rs.bottom - rs.top : CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL, // no text
WS_CHILD | PBS_SMOOTH, // styles
rs.left, rs.top, // x, y
- rs.right-rs.left, rs.bottom-rs.top, // cx, cy
+ rs.right - rs.left, rs.bottom - rs.top, // cx, cy
hwndStatus, // parent window
NULL, // window ID
hInstance, // instance
NULL); // window data
+ /* Remove its static edge */
+ SetWindowLongPtrW(hwndStatusProgress, GWL_EXSTYLE,
+ GetWindowLongPtrW(hwndStatusProgress, GWL_EXSTYLE) & ~WS_EX_STATICEDGE);
ProgressBar_SetStep(hwndStatusProgress, 1);
/* Initialize the splitter default positions */
- nVSplitPos = 250;
- nHSplitPos = 250;
+ nVSplitPos = Settings.nVSplitPos;
+ nHSplitPos = Settings.nHSplitPos;
/* Create the TreeView */
hwndTreeView = CreateWindowExW(WS_EX_CLIENTEDGE,
/* Create the Event details pane (optional) */
hwndEventDetails = CreateEventDetailsCtrl(hInst, hwndMainWindow, (LPARAM)NULL);
- // hwndEventDetails = NULL;
if (hwndEventDetails)
{
- // SetWindowLongPtrW(hwndEventDetails, GWL_STYLE,
- // GetWindowLongPtrW(hwndEventDetails, GWL_STYLE) | WS_BORDER);
SetWindowLongPtrW(hwndEventDetails, GWL_EXSTYLE,
GetWindowLongPtrW(hwndEventDetails, GWL_EXSTYLE) | WS_EX_CLIENTEDGE);
SetWindowPos(hwndEventDetails, NULL,
nHSplitPos + SPLIT_WIDTH/2,
(rcClient.right - rcClient.left) - nVSplitPos - SPLIT_WIDTH/2,
(rcClient.bottom - rcClient.top) - nHSplitPos - SPLIT_WIDTH/2 - StatusHeight,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
+ SWP_NOZORDER | SWP_NOACTIVATE | (Settings.bShowDetailsPane ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
}
/* Create the ListView */
nVSplitPos + SPLIT_WIDTH/2,
0,
(rcClient.right - rcClient.left) - nVSplitPos - SPLIT_WIDTH/2,
- hwndEventDetails ? nHSplitPos - SPLIT_WIDTH/2
- : (rcClient.bottom - rcClient.top) - StatusHeight,
+ hwndEventDetails && Settings.bShowDetailsPane
+ ? nHSplitPos - SPLIT_WIDTH/2
+ : (rcClient.bottom - rcClient.top) - StatusHeight,
hwndMainWindow,
NULL,
hInstance,
NULL);
/* Add the extended ListView styles */
- ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT |LVS_EX_LABELTIP);
+ ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP | (Settings.bShowGrid ? LVS_EX_GRIDLINES : 0));
/* Create the ImageList */
hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
sfn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE;
sfn.lpstrDefExt = NULL;
- ShowWindow(hwndMainWindow, nCmdShow);
+ ShowWindow(hwndMainWindow, Settings.wpPos.showCmd);
UpdateWindow(hwndMainWindow);
return TRUE;
VOID ResizeWnd(INT cx, INT cy)
{
- HDWP hdwp;
RECT rs;
LONG StatusHeight;
+ LONG_PTR dwExStyle;
+ HDWP hdwp;
/* Resize the status bar -- now done in WM_SIZE */
// SendMessageW(hwndStatus, WM_SIZE, 0, 0);
GetWindowRect(hwndStatus, &rs);
StatusHeight = rs.bottom - rs.top;
- /* Move the progress bar */
+ /*
+ * Move the progress bar -- Take into account for extra size due to the static edge
+ * (AdjustWindowRectEx() does not seem to work for the progress bar).
+ */
StatusBar_GetItemRect(hwndStatus, 0, &rs);
+ dwExStyle = GetWindowLongPtrW(hwndStatusProgress, GWL_EXSTYLE);
+ SetWindowLongPtrW(hwndStatusProgress, GWL_EXSTYLE, dwExStyle | WS_EX_STATICEDGE);
MoveWindow(hwndStatusProgress,
- rs.left, rs.top, rs.right-rs.left, rs.bottom-rs.top,
+ rs.left, rs.top, rs.right - rs.left, rs.bottom - rs.top,
IsWindowVisible(hwndStatusProgress) ? TRUE : FALSE);
+ SetWindowLongPtrW(hwndStatusProgress, GWL_EXSTYLE, dwExStyle);
/*
* TODO: Adjust the splitter positions:
HWND_TOP,
nVSplitPos + SPLIT_WIDTH/2, 0,
cx - nVSplitPos - SPLIT_WIDTH/2,
- hwndEventDetails ? nHSplitPos - SPLIT_WIDTH/2
- : cy - StatusHeight,
+ hwndEventDetails && Settings.bShowDetailsPane
+ ? nHSplitPos - SPLIT_WIDTH/2
+ : cy - StatusHeight,
SWP_NOZORDER | SWP_NOACTIVATE);
- if (hwndEventDetails && hdwp)
+ if (hwndEventDetails && Settings.bShowDetailsPane && hdwp)
hdwp = DeferWindowPos(hdwp,
hwndEventDetails,
HWND_TOP,
break;
case WM_DESTROY:
+ {
+ GetWindowPlacement(hwndMainWindow, &Settings.wpPos);
PostQuitMessage(0);
break;
+ }
case WM_NOTIFY:
{
{
LPWSTR pszText = item.pszText;
- /* Trim all whitespace */
+ /* Trim leading whitespace */
while (*pszText && iswspace(*pszText))
++pszText;
case IDM_LIST_NEWEST:
{
CheckMenuRadioItem(hMainMenu, IDM_LIST_NEWEST, IDM_LIST_OLDEST, IDM_LIST_NEWEST, MF_BYCOMMAND);
- if (!NewestEventsFirst)
+ if (!Settings.bNewestEventsFirst)
{
- NewestEventsFirst = TRUE;
+ Settings.bNewestEventsFirst = TRUE;
Refresh(GetSelectedFilter(NULL));
}
break;
case IDM_LIST_OLDEST:
{
CheckMenuRadioItem(hMainMenu, IDM_LIST_NEWEST, IDM_LIST_OLDEST, IDM_LIST_OLDEST, MF_BYCOMMAND);
- if (NewestEventsFirst)
+ if (Settings.bNewestEventsFirst)
{
- NewestEventsFirst = FALSE;
+ Settings.bNewestEventsFirst = FALSE;
Refresh(GetSelectedFilter(NULL));
}
break;
Refresh(GetSelectedFilter(NULL));
break;
+ case IDM_EVENT_DETAILS_VIEW:
+ {
+ Settings.bShowDetailsPane = !Settings.bShowDetailsPane;
+ CheckMenuItem(hMainMenu, IDM_EVENT_DETAILS_VIEW,
+ MF_BYCOMMAND | (Settings.bShowDetailsPane ? MF_CHECKED : MF_UNCHECKED));
+
+ GetClientRect(hWnd, &rect);
+ if (Settings.bShowDetailsPane)
+ {
+ ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
+ ShowWindow(hwndEventDetails, SW_SHOW);
+ }
+ else
+ {
+ ShowWindow(hwndEventDetails, SW_HIDE);
+ ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
+ }
+
+ break;
+ }
+
+ case IDM_LIST_GRID_LINES:
+ {
+ Settings.bShowGrid = !Settings.bShowGrid;
+ CheckMenuItem(hMainMenu, IDM_LIST_GRID_LINES,
+ MF_BYCOMMAND | (Settings.bShowGrid ? MF_CHECKED : MF_UNCHECKED));
+
+ ListView_SetExtendedListViewStyleEx(hwndListView, LVS_EX_GRIDLINES, (Settings.bShowGrid ? LVS_EX_GRIDLINES : 0));
+ break;
+ }
+
+ case IDM_SAVE_SETTINGS:
+ {
+ Settings.bSaveSettings = !Settings.bSaveSettings;
+ CheckMenuItem(hMainMenu, IDM_SAVE_SETTINGS,
+ MF_BYCOMMAND | (Settings.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
+ break;
+ }
+
case IDM_ABOUT:
{
HICON hIcon;
break;
}
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT)
+ case WM_INITMENU:
+ {
+ if ((HMENU)wParam != hMainMenu)
+ break;
+
+ CheckMenuRadioItem(hMainMenu, IDM_LIST_NEWEST, IDM_LIST_OLDEST,
+ Settings.bNewestEventsFirst ? IDM_LIST_NEWEST : IDM_LIST_OLDEST,
+ MF_BYCOMMAND);
+
+ if (!hwndEventDetails)
{
- POINT pt;
- GetCursorPos(&pt);
- ScreenToClient(hWnd, &pt);
+ EnableMenuItem(hMainMenu, IDM_EVENT_DETAILS_VIEW,
+ MF_BYCOMMAND | MF_GRAYED);
+ }
+ CheckMenuItem(hMainMenu, IDM_EVENT_DETAILS_VIEW,
+ MF_BYCOMMAND | (Settings.bShowDetailsPane ? MF_CHECKED : MF_UNCHECKED));
- /* Set the cursor for the vertical splitter */
- if (pt.x >= nVSplitPos - SPLIT_WIDTH/2 && pt.x < nVSplitPos + SPLIT_WIDTH/2 + 1)
+ CheckMenuItem(hMainMenu, IDM_LIST_GRID_LINES,
+ MF_BYCOMMAND | (Settings.bShowGrid ? MF_CHECKED : MF_UNCHECKED));
+
+ CheckMenuItem(hMainMenu, IDM_SAVE_SETTINGS,
+ MF_BYCOMMAND | (Settings.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
+
+ break;
+ }
+
+#if 0
+ case WM_INITMENUPOPUP:
+ lParam = lParam;
+ break;
+
+ case WM_CONTEXTMENU:
+ lParam = lParam;
+ break;
+#endif
+
+ case WM_SETCURSOR:
+ {
+ POINT pt;
+
+ if (LOWORD(lParam) != HTCLIENT)
+ goto Default;
+
+ GetCursorPos(&pt);
+ ScreenToClient(hWnd, &pt);
+
+ /* Set the cursor for the vertical splitter */
+ if (pt.x >= nVSplitPos - SPLIT_WIDTH/2 && pt.x < nVSplitPos + SPLIT_WIDTH/2 + 1)
+ {
+ RECT rs;
+ GetClientRect(hWnd, &rect);
+ GetWindowRect(hwndStatus, &rs);
+ if (pt.y >= rect.top && pt.y < rect.bottom - (rs.bottom - rs.top))
{
- RECT rs;
- GetClientRect(hWnd, &rect);
- GetWindowRect(hwndStatus, &rs);
- if (pt.y >= rect.top && pt.y < rect.bottom - (rs.bottom - rs.top))
- {
- SetCursor(LoadCursorW(NULL, IDC_SIZEWE));
- return TRUE;
- }
+ SetCursor(LoadCursorW(NULL, IDC_SIZEWE));
+ return TRUE;
}
- else
- /* Set the cursor for the horizontal splitter, if the Event details pane is displayed */
- if (hwndEventDetails &&
- (pt.y >= nHSplitPos - SPLIT_WIDTH/2 && pt.y < nHSplitPos + SPLIT_WIDTH/2 + 1))
+ }
+ else
+ /* Set the cursor for the horizontal splitter, if the Event details pane is displayed */
+ if (hwndEventDetails && Settings.bShowDetailsPane &&
+ (pt.y >= nHSplitPos - SPLIT_WIDTH/2 && pt.y < nHSplitPos + SPLIT_WIDTH/2 + 1))
+ {
+ // RECT rs;
+ GetClientRect(hWnd, &rect);
+ // GetWindowRect(hwndStatus, &rs);
+ if (pt.x >= nVSplitPos + SPLIT_WIDTH/2 + 1 /* rect.left + (rs.bottom - rs.top) */ &&
+ pt.x < rect.right)
{
- // RECT rs;
- GetClientRect(hWnd, &rect);
- // GetWindowRect(hwndStatus, &rs);
- if (pt.x >= nVSplitPos + SPLIT_WIDTH/2 + 1 /* rect.left + (rs.bottom - rs.top) */ &&
- pt.x < rect.right)
- {
- SetCursor(LoadCursorW(NULL, IDC_SIZENS));
- return TRUE;
- }
+ SetCursor(LoadCursorW(NULL, IDC_SIZENS));
+ return TRUE;
}
}
goto Default;
+ }
case WM_LBUTTONDOWN:
{
}
else
/* Capture the cursor for the horizontal splitter, if the Event details pane is displayed */
- if (hwndEventDetails &&
+ if (hwndEventDetails && Settings.bShowDetailsPane &&
(y >= nHSplitPos - SPLIT_WIDTH/2 && y < nHSplitPos + SPLIT_WIDTH/2 + 1))
{
bSplit = 2;
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
- if (GetCapture() == hWnd)
- {
- /* Adjust the correct splitter position */
- if (bSplit == 1)
- nVSplitPos = GET_X_LPARAM(lParam);
- else if (bSplit == 2)
- nHSplitPos = GET_Y_LPARAM(lParam);
-
- /* If we are splitting, resize the windows */
- if (bSplit != 0)
- {
- GetClientRect(hWnd, &rect);
- ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
- }
+ {
+ if (GetCapture() != hWnd)
+ break;
- /* Reset the splitter state */
- bSplit = 0;
+ /* Adjust the correct splitter position */
+ if (bSplit == 1)
+ nVSplitPos = GET_X_LPARAM(lParam);
+ else if (bSplit == 2)
+ nHSplitPos = GET_Y_LPARAM(lParam);
- ReleaseCapture();
+ /* If we are splitting, resize the windows */
+ if (bSplit != 0)
+ {
+ GetClientRect(hWnd, &rect);
+ ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
}
+
+ /* Reset the splitter state */
+ bSplit = 0;
+
+ ReleaseCapture();
break;
+ }
case WM_MOUSEMOVE:
- if (GetCapture() == hWnd)
+ {
+ if (GetCapture() != hWnd)
+ break;
+
+ /* Move the correct splitter */
+ if (bSplit == 1)
{
- /* Move the correct splitter */
- if (bSplit == 1)
- {
- INT x = GET_X_LPARAM(lParam);
+ INT x = GET_X_LPARAM(lParam);
- GetClientRect(hWnd, &rect);
+ GetClientRect(hWnd, &rect);
- x = min(max(x, SPLIT_WIDTH/2), rect.right - rect.left - SPLIT_WIDTH/2);
- if (nVSplitPos != x)
- {
- nVSplitPos = x;
- ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
- }
- }
- else if (bSplit == 2)
+ x = min(max(x, SPLIT_WIDTH/2), rect.right - rect.left - SPLIT_WIDTH/2);
+ if (nVSplitPos != x)
{
- RECT rs;
- INT y = GET_Y_LPARAM(lParam);
+ nVSplitPos = x;
+ ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
+ }
+ }
+ else if (bSplit == 2)
+ {
+ RECT rs;
+ INT y = GET_Y_LPARAM(lParam);
- GetClientRect(hWnd, &rect);
- GetWindowRect(hwndStatus, &rs);
+ GetClientRect(hWnd, &rect);
+ GetWindowRect(hwndStatus, &rs);
- y = min(max(y, SPLIT_WIDTH/2), rect.bottom - rect.top - SPLIT_WIDTH/2 - (rs.bottom - rs.top));
- if (nHSplitPos != y)
- {
- nHSplitPos = y;
- ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
- }
+ y = min(max(y, SPLIT_WIDTH/2), rect.bottom - rect.top - SPLIT_WIDTH/2 - (rs.bottom - rs.top));
+ if (nHSplitPos != y)
+ {
+ nHSplitPos = y;
+ ResizeWnd(rect.right - rect.left, rect.bottom - rect.top);
}
}
break;
+ }
case WM_SIZE:
{
{
LPWSTR lpLogName = EventLog->LogName;
- DWORD Result, Type;
+ DWORD Result, dwType;
DWORD dwMaxSize = 0, dwRetention = 0;
BOOL Success;
WIN32_FIND_DATAW FileInfo; // WIN32_FILE_ATTRIBUTE_DATA
StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY);
StringCbCatW(KeyPath, cbKeyPath, lpLogName);
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_QUERY_VALUE, &hLogKey) != ERROR_SUCCESS)
+ if (RegOpenKeyExW(hkMachine, KeyPath, 0, KEY_QUERY_VALUE, &hLogKey) != ERROR_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, KeyPath);
goto Quit;
Result = RegQueryValueExW(hLogKey,
L"MaxSize",
NULL,
- &Type,
+ &dwType,
(LPBYTE)&dwMaxSize,
&cbData);
- if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_DWORD))
{
// dwMaxSize = 512 * 1024; /* 512 kBytes */
dwMaxSize = 0;
Result = RegQueryValueExW(hLogKey,
L"Retention",
NULL,
- &Type,
+ &dwType,
(LPBYTE)&dwRetention,
&cbData);
- if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
+ if ((Result != ERROR_SUCCESS) || (dwType != REG_DWORD))
{
/* On Windows 2003 it is 604800 (secs) == 7 days */
dwRetention = 0;
FileName = EventLog->FileName;
if (FileName && *FileName)
{
- ExpandEnvironmentStringsW(FileName, wszBuf, MAX_PATH);
+ /* Expand the file name. If the log file is on a remote computer, retrieve the network share form of the file name. */
+ GetExpandedFilePathName(EventLog->ComputerName, FileName, wszBuf, ARRAYSIZE(wszBuf));
FileName = wszBuf;
}
+ else
+ {
+ FileName = L"";
+ }
SetDlgItemTextW(hDlg, IDC_LOGFILE, FileName);
- /*
- * The general problem here (and in the shell as well) is that
- * GetFileAttributesEx fails for files that are opened without
- * shared access. To retrieve file information for those we need
- * to use something else: FindFirstFile, on the full file name.
- */
-
- Success = GetFileAttributesExW(FileName,
- GetFileExInfoStandard,
- (LPWIN32_FILE_ATTRIBUTE_DATA)&FileInfo);
- if (!Success)
+ if (FileName && *FileName)
+ {
+ /*
+ * The general problem here (and in the shell as well) is that
+ * GetFileAttributesEx fails for files that are opened without
+ * shared access. To retrieve file information for those we need
+ * to use something else: FindFirstFile, on the full file name.
+ */
+ Success = GetFileAttributesExW(FileName,
+ GetFileExInfoStandard,
+ (LPWIN32_FILE_ATTRIBUTE_DATA)&FileInfo);
+ if (!Success)
+ {
+ HANDLE hFind = FindFirstFileW(FileName, &FileInfo);
+ Success = (hFind != INVALID_HANDLE_VALUE);
+ if (Success)
+ FindClose(hFind);
+ }
+ }
+ else
{
- HANDLE hFind = FindFirstFileW(FileName, &FileInfo);
- Success = (hFind != INVALID_HANDLE_VALUE);
- if (Success)
- FindClose(hFind);
+ Success = FALSE;
}
- // Starting there, FileName is invalid (because it uses wszBuf)
+ /* Starting there, FileName becomes invalid because we are reusing wszBuf */
if (Success)
{