[EVENTVWR] Additions for the Event Viewer.
[reactos.git] / base / applications / mscutils / eventvwr / eventvwr.c
index 6801b27..01c416e 100644 (file)
@@ -37,8 +37,9 @@
 
 #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[] =
@@ -91,6 +92,7 @@ LPWSTR lpComputerName = NULL;       /* NULL: local user computer (default) */
 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;
@@ -100,7 +102,6 @@ PEVENTLOGRECORD* g_RecordPtrs = NULL;
 LIST_ENTRY EventLogList;
 LIST_ENTRY EventLogFilterList;
 PEVENTLOGFILTER ActiveFilter = NULL;
-BOOL NewestEventsFirst = TRUE;
 
 HANDLE hEnumEventsThread = NULL;
 HANDLE hStopEnumEvent    = NULL;
@@ -117,6 +118,21 @@ HANDLE hStartEnumEvent     = NULL;  // Command event
 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
@@ -129,7 +145,7 @@ VOID FreeLogList(VOID);
 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);
@@ -296,13 +312,18 @@ ProcessCmdLine(IN LPWSTR lpCmdLine)
             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 */
             }
@@ -339,6 +360,214 @@ Quit:
     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,
@@ -389,8 +618,11 @@ wWinMain(HINSTANCE hInstance,
     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));
@@ -442,6 +674,18 @@ wWinMain(HINSTANCE hInstance,
         }
     }
 
+    /* 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);
@@ -589,7 +833,14 @@ GetMessageStringFromDll(
     }
     else
     {
+        LPWSTR ptr;
+
         ASSERT(lpMsgBuf);
+
+        /* Trim any trailing whitespace */
+        ptr = lpMsgBuf + dwLength - 1;
+        while (iswspace(*ptr))
+            *ptr-- = UNICODE_NULL;
     }
 
     return lpMsgBuf;
@@ -1209,6 +1460,79 @@ TrimNulls(LPWSTR s)
     }
 }
 
+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,
@@ -1217,7 +1541,7 @@ GetEventMessageFileDLL(IN LPCWSTR lpLogName,
 {
     BOOL Success = FALSE;
     LONG Result;
-    DWORD Type, dwSize;
+    DWORD dwType, dwSize;
     WCHAR szModuleName[MAX_PATH];
     WCHAR szKeyName[MAX_PATH];
     HKEY hLogKey = NULL;
@@ -1226,7 +1550,7 @@ GetEventMessageFileDLL(IN LPCWSTR lpLogName,
     StringCbCopyW(szKeyName, sizeof(szKeyName), EVENTLOG_BASE_KEY);
     StringCbCatW(szKeyName, sizeof(szKeyName), lpLogName);
 
-    Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+    Result = RegOpenKeyExW(hkMachine,
                            szKeyName,
                            0,
                            KEY_READ,
@@ -1249,10 +1573,10 @@ GetEventMessageFileDLL(IN LPCWSTR lpLogName,
     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;
     }
@@ -1260,7 +1584,7 @@ GetEventMessageFileDLL(IN LPCWSTR lpLogName,
     {
         /* 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;
     }
 
@@ -1517,7 +1841,7 @@ GetEventUserName(IN PEVENTLOGRECORD pelr,
          * 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,
@@ -1800,7 +2124,7 @@ EnumEventsThread(IN LPVOID lpParameter)
     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;
@@ -1829,7 +2153,7 @@ EnumEventsThread(IN LPVOID lpParameter)
         }
         else if (!bResult)
         {
-            /* exit on other errors (ERROR_HANDLE_EOF) */
+            /* Exit on other errors (ERROR_HANDLE_EOF) */
             break;
         }
 
@@ -2378,7 +2702,7 @@ MyRegisterClass(HINSTANCE hInstance)
     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,
@@ -2400,7 +2724,7 @@ GetDisplayNameFileAndID(IN LPCWSTR lpLogName,
     HKEY hLogKey;
     WCHAR *KeyPath;
     SIZE_T cbKeyPath;
-    DWORD Type, cbData;
+    DWORD dwType, cbData;
     DWORD dwMessageID = 0;
     WCHAR szModuleName[MAX_PATH];
 
@@ -2415,7 +2739,7 @@ GetDisplayNameFileAndID(IN LPCWSTR lpLogName,
     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;
@@ -2424,10 +2748,10 @@ GetDisplayNameFileAndID(IN LPCWSTR lpLogName,
     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;
     }
@@ -2435,7 +2759,7 @@ GetDisplayNameFileAndID(IN LPCWSTR lpLogName,
     {
         /* 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;
     }
 
@@ -2449,10 +2773,10 @@ GetDisplayNameFileAndID(IN LPCWSTR lpLogName,
         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;
@@ -2471,7 +2795,7 @@ BuildLogListAndFilterList(IN LPCWSTR lpComputerName)
     HKEY hEventLogKey, hLogKey;
     DWORD dwNumLogs = 0;
     DWORD dwIndex, dwMaxKeyLength;
-    DWORD Type;
+    DWORD dwType;
     PEVENTLOG EventLog;
     PEVENTLOGFILTER EventLogFilter;
     LPWSTR LogName = NULL;
@@ -2481,11 +2805,32 @@ BuildLogListAndFilterList(IN LPCWSTR lpComputerName)
     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;
@@ -2554,10 +2899,10 @@ BuildLogListAndFilterList(IN LPCWSTR lpComputerName)
             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;
@@ -2571,7 +2916,7 @@ BuildLogListAndFilterList(IN LPCWSTR lpComputerName)
                     Result = RegQueryValueExW(hLogKey,
                                               L"File",
                                               NULL,
-                                              &Type,
+                                              &dwType,
                                               (LPBYTE)EventLog->FileName,
                                               &lpcName);
                     if (Result != ERROR_SUCCESS)
@@ -2688,8 +3033,7 @@ FreeLogFilterList(VOID)
 }
 
 BOOL
-InitInstance(HINSTANCE hInstance,
-             int nCmdShow)
+InitInstance(HINSTANCE hInstance)
 {
     RECT rcClient, rs;
     LONG StatusHeight;
@@ -2698,10 +3042,13 @@ InitInstance(HINSTANCE hInstance,
     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,
@@ -2731,16 +3078,19 @@ InitInstance(HINSTANCE 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,
@@ -2784,11 +3134,8 @@ InitInstance(HINSTANCE hInstance,
 
     /* 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,
@@ -2796,7 +3143,7 @@ InitInstance(HINSTANCE hInstance,
                  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 */
@@ -2807,15 +3154,16 @@ InitInstance(HINSTANCE hInstance,
                                    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),
@@ -2913,7 +3261,7 @@ InitInstance(HINSTANCE hInstance,
     sfn.Flags           = OFN_HIDEREADONLY | OFN_SHAREAWARE;
     sfn.lpstrDefExt     = NULL;
 
-    ShowWindow(hwndMainWindow, nCmdShow);
+    ShowWindow(hwndMainWindow, Settings.wpPos.showCmd);
     UpdateWindow(hwndMainWindow);
 
     return TRUE;
@@ -2921,20 +3269,27 @@ InitInstance(HINSTANCE hInstance,
 
 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:
@@ -2961,11 +3316,12 @@ VOID ResizeWnd(INT cx, INT cy)
                               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,
@@ -2992,8 +3348,11 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
             break;
 
         case WM_DESTROY:
+        {
+            GetWindowPlacement(hwndMainWindow, &Settings.wpPos);
             PostQuitMessage(0);
             break;
+        }
 
         case WM_NOTIFY:
         {
@@ -3053,7 +3412,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                         {
                             LPWSTR pszText = item.pszText;
 
-                            /* Trim all whitespace */
+                            /* Trim leading whitespace */
                             while (*pszText && iswspace(*pszText))
                                 ++pszText;
 
@@ -3164,9 +3523,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                 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;
@@ -3175,9 +3534,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                 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;
@@ -3204,6 +3563,45 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                     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;
@@ -3233,42 +3631,81 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
             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:
         {
@@ -3286,7 +3723,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
             }
             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;
@@ -3297,62 +3734,66 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
         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:
         {
@@ -3379,7 +3820,7 @@ InitPropertiesDlg(HWND hDlg, PEVENTLOG EventLog)
 {
     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
@@ -3406,7 +3847,7 @@ InitPropertiesDlg(HWND hDlg, PEVENTLOG EventLog)
     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;
@@ -3418,10 +3859,10 @@ InitPropertiesDlg(HWND hDlg, PEVENTLOG EventLog)
     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;
@@ -3433,10 +3874,10 @@ InitPropertiesDlg(HWND hDlg, PEVENTLOG EventLog)
     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;
@@ -3459,30 +3900,41 @@ Quit:
     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)
     {