diff --git a/LegacyUpdate/LegacyUpdate.vcxproj b/LegacyUpdate/LegacyUpdate.vcxproj
index 76ca3f5..688d5a6 100644
--- a/LegacyUpdate/LegacyUpdate.vcxproj
+++ b/LegacyUpdate/LegacyUpdate.vcxproj
@@ -477,14 +477,6 @@
CompileAsCpp
CompileAsCpp
-
- CompileAsCpp
- CompileAsCpp
- CompileAsCpp
- CompileAsCpp
- CompileAsCpp
- CompileAsCpp
-
CompileAsCpp
CompileAsCpp
@@ -575,7 +567,6 @@
-
diff --git a/LegacyUpdate/LegacyUpdate.vcxproj.filters b/LegacyUpdate/LegacyUpdate.vcxproj.filters
index 628f48d..cd6b79c 100644
--- a/LegacyUpdate/LegacyUpdate.vcxproj.filters
+++ b/LegacyUpdate/LegacyUpdate.vcxproj.filters
@@ -81,9 +81,6 @@
Shared
-
- Shared
-
Shared
@@ -146,9 +143,6 @@
Shared
-
- Shared
-
Shared
diff --git a/LegacyUpdate/LegacyUpdateCtrl.cpp b/LegacyUpdate/LegacyUpdateCtrl.cpp
index d4d048f..0d05302 100644
--- a/LegacyUpdate/LegacyUpdateCtrl.cpp
+++ b/LegacyUpdate/LegacyUpdateCtrl.cpp
@@ -10,7 +10,6 @@
#include "User.h"
#include "Utils.h"
#include "VersionInfo.h"
-#include "Wow64.h"
#include
#include
#include
@@ -340,6 +339,7 @@ STDMETHODIMP CLegacyUpdateCtrl::GetUserType(UserType *retval) {
// The control has no admin rights (although it may not have requested them yet).
*retval = e_nonAdmin;
}
+
return S_OK;
}
@@ -454,32 +454,37 @@ STDMETHODIMP CLegacyUpdateCtrl::ViewWindowsUpdateLog(void) {
STDMETHODIMP CLegacyUpdateCtrl::OpenWindowsUpdateSettings(void) {
DoIsPermittedCheck();
- // Some issues arise from the working directory being SysWOW64 rather than System32. Notably,
- // Windows Vista - 8.1 don't have wuauclt.exe in SysWOW64. Disable WOW64 redirection temporarily
- // to work around this.
- PVOID oldValue;
- BOOL isRedirected = DisableWow64FsRedirection(&oldValue);
-
- if (AtLeastWin10()) {
- // Windows 10+: Open Settings app
- Exec(NULL, L"ms-settings:windowsupdate-options", NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
- } else if (AtLeastWinVista()) {
- // Windows Vista, 7, 8: Open Windows Update control panel
- WCHAR wuauclt[MAX_PATH];
- ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuauclt.exe", wuauclt, ARRAYSIZE(wuauclt));
- Exec(NULL, wuauclt, L"/ShowOptions", NULL, SW_SHOWDEFAULT, FALSE, NULL);
- } else {
- // Windows 2000, XP: Open Automatic Updates control panel
- WCHAR wuaucpl[MAX_PATH];
- ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuaucpl.cpl", wuaucpl, ARRAYSIZE(wuaucpl));
- Exec(NULL, wuaucpl, NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
+ hr = GetInstallPath(&path);
+ if (!SUCCEEDED(hr)) {
+ goto end;
}
- // Revert WOW64 redirection if we changed it.
- if (isRedirected) {
- RevertWow64FsRedirection(oldValue);
+ PathAppend(path, L"LegacyUpdate.exe");
+
+ DWORD code;
+ hr = Exec(L"open", path, L"/options", NULL, SW_SHOW, TRUE, &code);
+ if (SUCCEEDED(hr)) {
+ hr = HRESULT_FROM_WIN32(code);
}
- return S_OK;
+
+ if (!SUCCEEDED(hr)) {
+ TRACE(L"OpenWindowsUpdateSettings() failed: %ls\n", GetMessageForHresult(hr));
+
+ // Might happen if the site isn't trusted, and the user rejected the IE medium integrity prompt.
+ // Use the basic Automatic Updates dialog directly from COM.
+ CComPtr automaticUpdates;
+ hr = automaticUpdates.CoCreateInstance(CLSID_AutomaticUpdates, NULL, CLSCTX_INPROC_SERVER);
+
+ if (SUCCEEDED(hr)) {
+ hr = automaticUpdates->ShowSettingsDialog();
+ }
+
+ if (!SUCCEEDED(hr)) {
+ TRACE(L"OpenWindowsUpdateSettings() failed: %ls\n", GetMessageForHresult(hr));
+ }
+ }
+
+ return hr;
}
STDMETHODIMP CLegacyUpdateCtrl::get_IsUsingWsusServer(VARIANT_BOOL *retval) {
diff --git a/launcher/Options.c b/launcher/Options.c
new file mode 100644
index 0000000..4f502d5
--- /dev/null
+++ b/launcher/Options.c
@@ -0,0 +1,40 @@
+#include
+#include "Exec.h"
+#include "VersionInfo.h"
+#include "Wow64.h"
+
+void LaunchOptions(int nCmdShow) {
+#if !_WIN64
+ // Some issues arise from the working directory being SysWOW64 rather than System32. Notably,
+ // Windows Vista - 8.1 don't have wuauclt.exe in SysWOW64. Disable WOW64 redirection temporarily
+ // to work around this.
+ PVOID oldValue;
+ BOOL isRedirected = DisableWow64FsRedirection(&oldValue);
+#endif
+
+ HRESULT hr;
+
+ if (AtLeastWin10()) {
+ // Windows 10+: Open Settings app
+ hr = Exec(NULL, L"ms-settings:windowsupdate-options", NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
+ } else if (AtLeastWinVista()) {
+ // Windows Vista, 7, 8: Open Windows Update control panel
+ WCHAR wuauclt[MAX_PATH];
+ ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuauclt.exe", wuauclt, ARRAYSIZE(wuauclt));
+ hr = Exec(NULL, wuauclt, L"/ShowOptions", NULL, SW_SHOWDEFAULT, FALSE, NULL);
+ } else {
+ // Windows 2000, XP: Open Automatic Updates control panel
+ WCHAR wuaucpl[MAX_PATH];
+ ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\wuaucpl.cpl", wuaucpl, ARRAYSIZE(wuaucpl));
+ hr = Exec(NULL, wuaucpl, NULL, NULL, SW_SHOWDEFAULT, FALSE, NULL);
+ }
+
+#if !_WIN64
+ // Revert WOW64 redirection if we changed it
+ if (isRedirected) {
+ RevertWow64FsRedirection(oldValue);
+ }
+#endif
+
+ PostQuitMessage(hr);
+}
diff --git a/launcher/RegisterServer.c b/launcher/RegisterServer.c
index 9a78198..1391d9e 100644
--- a/launcher/RegisterServer.c
+++ b/launcher/RegisterServer.c
@@ -78,11 +78,6 @@ HRESULT RegisterServer(HWND hwnd, BOOL state, BOOL forLaunch) {
goto end;
}
-#if _WIN64
- PVOID oldValue;
- DisableWow64FsRedirection(&oldValue);
-#endif
-
hr = GetInstallPath(&installPath);
if (!SUCCEEDED(hr)) {
goto end;
@@ -132,8 +127,6 @@ HRESULT RegisterServer(HWND hwnd, BOOL state, BOOL forLaunch) {
#endif
hr = RegisterDllExternal(dllPath, state);
-
- RevertWow64FsRedirection(oldValue);
#endif
end:
diff --git a/launcher/main.c b/launcher/main.c
index 2ad0e21..fac20b8 100644
--- a/launcher/main.c
+++ b/launcher/main.c
@@ -10,8 +10,26 @@
HINSTANCE g_hInstance;
extern void LaunchUpdateSite(int argc, LPWSTR *argv, int nCmdShow);
+extern void LaunchOptions(int nCmdShow);
extern void RunOnce();
+typedef enum Action {
+ ActionLaunch,
+ ActionOptions,
+ ActionRunOnce,
+ ActionRegServer,
+ ActionUnregServer
+} Action;
+
+static const LPWSTR actions[] = {
+ L"/launch",
+ L"/options",
+ L"/runonce",
+ L"/regserver",
+ L"/unregserver",
+ NULL
+};
+
EXTERN_C __declspec(dllexport)
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
g_hInstance = hInstance;
@@ -20,9 +38,9 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
int argc;
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
- LPWSTR action = L"/launch";
+ LPWSTR actionFlag = L"/launch";
if (argc > 1) {
- action = argv[1];
+ actionFlag = argv[1];
}
// All remaining args past the action
@@ -33,21 +51,46 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
flagsCount = argc - 2;
}
- if (wcscmp(action, L"/launch") == 0) {
+ Action action = -1;
+
+ for (int i = 0; actions[i] != NULL; i++) {
+ if (wcscmp(actionFlag, actions[i]) == 0) {
+ action = i;
+ break;
+ }
+ }
+
+ switch (action) {
+ case ActionLaunch:
LaunchUpdateSite(flagsCount, flags, nCmdShow);
- } else if (wcscmp(action, L"/runonce") == 0) {
+ break;
+
+ case ActionOptions:
+ LaunchOptions(nCmdShow);
+ break;
+
+ case ActionRunOnce:
RunOnce();
- } else if (wcscmp(action, L"/regserver") == 0 || wcscmp(action, L"/unregserver") == 0) {
- BOOL state = wcscmp(action, L"/regserver") == 0;
+ break;
+
+ case ActionRegServer:
+ case ActionUnregServer: {
+ BOOL state = action == ActionRegServer;
HWND hwnd = flagsCount > 0 ? (HWND)(intptr_t)wcstol(flags[0], NULL, 10) : 0;
RegisterServer(hwnd, state, FALSE);
- } else {
+ break;
+ }
+
+ default: {
const LPWSTR usage = L""
L"LegacyUpdate.exe [/launch|/regserver|/unregserver]\n"
L"\n"
L"/launch\n"
L" Launch Legacy Update website in Internet Explorer\n"
L"\n"
+ L"/options\n"
+ L" Open the Windows Update Options control panel\n"
+ L"\n"
L"/regserver\n"
L" Register ActiveX control\n"
L"\n"
@@ -57,6 +100,8 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
L"If no parameters are provided, /launch is assumed.";
MsgBox(NULL, L"LegacyUpdate.exe usage", usage, MB_OK);
PostQuitMessage(1);
+ break;
+ }
}
MSG msg;
diff --git a/setup/Constants.nsh b/setup/Constants.nsh
index 18101bc..1b88179 100644
--- a/setup/Constants.nsh
+++ b/setup/Constants.nsh
@@ -45,6 +45,9 @@
!define CPL_GUID "{FFBE8D44-E9CF-4DD8-9FD6-976802C94D9C}"
!define CPL_APPNAME "LegacyUpdate"
+; IE elevation policy
+!define ELEVATIONPOLICY_GUID "{3D800943-0434-49F2-89A1-472A259AD982}"
+
; Legacy Update keys
!define REGPATH_LEGACYUPDATE_SETUP "Software\Hashbang Productions\Legacy Update\Setup"
!define REGPATH_UNINSTSUBKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
@@ -85,6 +88,9 @@
!define REGPATH_ZONEDOMAINS "${REGPATH_INETSETTINGS}\ZoneMap\Domains"
!define REGPATH_ZONEESCDOMAINS "${REGPATH_INETSETTINGS}\ZoneMap\EscDomains"
+; IE elevation policy keys
+!define REGPATH_ELEVATIONPOLICY "Software\Microsoft\Internet Explorer\Low Rights\ElevationPolicy"
+
; SChannel protocol keys
!define REGPATH_SCHANNEL_PROTOCOLS "System\CurrentControlSet\Control\SecurityProviders\SChannel\Protocols"
!define REGPATH_DOTNET "Software\Microsoft\.NETFramework"
diff --git a/setup/setup.nsi b/setup/setup.nsi
index ae876d6..e0b998f 100644
--- a/setup/setup.nsi
+++ b/setup/setup.nsi
@@ -417,6 +417,15 @@ ${MementoSection} "$(^Name)" LEGACYUPDATE
WriteRegDword HKCU "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" "http" 2
WriteRegDword HKCU "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" "https" 2
+ ; Add low rights elevation policy
+ WriteRegDword HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "Policy" 3
+ WriteRegStr HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "AppPath" "$OUTDIR"
+ WriteRegStr HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "AppName" "LegacyUpdate.exe"
+
+ WriteRegDword HKCU "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "Policy" 3
+ WriteRegStr HKCU "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "AppPath" "$OUTDIR"
+ WriteRegStr HKCU "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" "AppName" "LegacyUpdate.exe"
+
; Delete LegacyUpdate.dll in System32 from 1.0 installer
${If} ${FileExists} $WINDIR\System32\LegacyUpdate.dll
Delete $WINDIR\System32\LegacyUpdate.dll
@@ -503,6 +512,10 @@ Section "-un.Legacy Update website" un.ACTIVEX
DeleteRegKey HKLM "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}"
DeleteRegKey HKCU "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}"
+ ; Remove IE elevation policy
+ DeleteRegKey HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}"
+ DeleteRegKey HKCU "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}"
+
; Restart service
!insertmacro RestartWUAUService
SectionEnd
diff --git a/shared/Wow64.c b/shared/Wow64.c
index 102560d..ac133c7 100644
--- a/shared/Wow64.c
+++ b/shared/Wow64.c
@@ -8,6 +8,11 @@ static BOOL _loadedWow64;
static _Wow64DisableWow64FsRedirection $Wow64DisableWow64FsRedirection;
static _Wow64RevertWow64FsRedirection $Wow64RevertWow64FsRedirection;
+#if _WIN64
+// Not needed
+#define DisableWow64FsRedirection(OldValue) TRUE
+#define RevertWow64FsRedirection(OldValue) TRUE
+#else
static void LoadWow64Symbols() {
if (!_loadedWow64) {
_loadedWow64 = TRUE;
@@ -37,3 +42,4 @@ BOOL RevertWow64FsRedirection(PVOID OldValue) {
return TRUE;
}
}
+#endif