diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 4a6ad78..0000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: WUIsBack Nightly AutoBuilder - -on: - push: - branches: - - main - -jobs: - build: - runs-on: windows-latest - steps: - - name: Download repository - uses: actions/checkout@v3 - - name: Install NSIS - run: | - iwr -useb get.scoop.sh -outfile 'install.ps1' - .\install.ps1 -RunAsAdmin - scoop update - scoop bucket add extras - scoop install nsis - - name: Download latest DLL - run: | - md .\Release - md .\x64\Release - iwr https://vichingo455-website.000webhostapp.com/DLL/LegacyUpdate32.dll -outfile '.\Release\LegacyUpdate.dll' - iwr https://vichingo455-website.000webhostapp.com/DLL/LegacyUpdate64.dll -outfile '.\x64\Release\LegacyUpdate.dll' - - name: Compile WUIsBack - run: | - makensis "setup\setup.nsi" - - name: Upload Nightly Build - uses: actions/upload-artifact@v4 - with: - name: WUIsBack-nightly - path: setup/WUIsBack-latest.exe diff --git a/LegacyUpdate/Compat.cpp b/LegacyUpdate/Compat.cpp index 0d601d2..1ef7004 100644 --- a/LegacyUpdate/Compat.cpp +++ b/LegacyUpdate/Compat.cpp @@ -2,15 +2,22 @@ #include #include "Utils.h" -typedef BOOL (WINAPI *_Wow64DisableWow64FsRedirection)(PVOID *OldValue); -typedef BOOL (WINAPI *_Wow64RevertWow64FsRedirection)(PVOID OldValue); +#ifndef PROCESS_PER_MONITOR_DPI_AWARE +typedef int PROCESS_DPI_AWARENESS; +#define PROCESS_PER_MONITOR_DPI_AWARE 2 +#endif + +#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 +typedef int DPI_AWARENESS_CONTEXT; +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) +#endif + typedef BOOL (WINAPI *_GetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); -// XP+ -_Wow64DisableWow64FsRedirection $Wow64DisableWow64FsRedirection = (_Wow64DisableWow64FsRedirection)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "Wow64DisableWow64FsRedirection"); -_Wow64RevertWow64FsRedirection $Wow64RevertWow64FsRedirection = (_Wow64RevertWow64FsRedirection)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "Wow64RevertWow64FsRedirection"); +typedef BOOL (WINAPI *_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); +typedef HRESULT (WINAPI *_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); +typedef void (WINAPI *_SetProcessDPIAware)(); -// Vista+ _GetProductInfo $GetProductInfo = (_GetProductInfo)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetProductInfo"); BOOL GetVistaProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType) { @@ -22,18 +29,25 @@ BOOL GetVistaProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD d } } -BOOL DisableWow64FsRedirection(PVOID *OldValue) { - if ($Wow64DisableWow64FsRedirection) { - return $Wow64DisableWow64FsRedirection(OldValue); - } else { - return TRUE; +void BecomeDPIAware() { + // Make the process DPI-aware... hopefully + // Windows 10 1703+ per-monitor v2 + _SetProcessDpiAwarenessContext $SetProcessDpiAwarenessContext = (_SetProcessDpiAwarenessContext)GetProcAddress(LoadLibrary(L"user32.dll"), "SetProcessDpiAwarenessContext"); + if ($SetProcessDpiAwarenessContext) { + $SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + return; } -} -BOOL RevertWow64FsRedirection(PVOID OldValue) { - if ($Wow64RevertWow64FsRedirection) { - return $Wow64RevertWow64FsRedirection(OldValue); - } else { - return TRUE; + // Windows 8.1 - 10 1607 per-monitor v1 + _SetProcessDpiAwareness $SetProcessDpiAwareness = (_SetProcessDpiAwareness)GetProcAddress(LoadLibrary(L"shcore.dll"), "SetProcessDpiAwareness"); + if ($SetProcessDpiAwareness) { + $SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); + return; + } + + // Windows Vista - 8 + _SetProcessDPIAware $SetProcessDPIAware = (_SetProcessDPIAware)GetProcAddress(LoadLibrary(L"user32.dll"), "SetProcessDPIAware"); + if ($SetProcessDPIAware) { + $SetProcessDPIAware(); } } diff --git a/LegacyUpdate/Compat.h b/LegacyUpdate/Compat.h index fb6e816..88750f7 100644 --- a/LegacyUpdate/Compat.h +++ b/LegacyUpdate/Compat.h @@ -1,6 +1,4 @@ #pragma once BOOL GetVistaProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType); - -BOOL DisableWow64FsRedirection(PVOID *OldValue); -BOOL RevertWow64FsRedirection(PVOID OldValue); +void BecomeDPIAware(); diff --git a/LegacyUpdate/CplTasks.xml b/LegacyUpdate/CplTasks.xml deleted file mode 100644 index c9b4626..0000000 --- a/LegacyUpdate/CplTasks.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - @"%ProgramFiles%\Legacy Update\LegacyUpdate.dll",-3 - legacy update;legacyupdate;update;windows;microsoft;driver;security;software; - %windir%\system32\rundll32.exe "%ProgramFiles%\Legacy Update\LegacyUpdate.dll",LaunchUpdateSite - - - - - - - - - - - diff --git a/LegacyUpdate/ElevationHelper.cpp b/LegacyUpdate/ElevationHelper.cpp index f8ea24e..0866972 100644 --- a/LegacyUpdate/ElevationHelper.cpp +++ b/LegacyUpdate/ElevationHelper.cpp @@ -1,6 +1,8 @@ // ElevationHelper.cpp : Implementation of CElevationHelper #include "stdafx.h" +#include "Compat.h" #include "ElevationHelper.h" +#include "HResult.h" #include "Utils.h" #include @@ -8,18 +10,18 @@ const BSTR permittedProgIDs[] = { L"Microsoft.Update.", NULL }; -const int permittedProgIDsMax = 1; BOOL ProgIDIsPermitted(PWSTR progID) { if (progID == NULL) { return FALSE; } - for (int i = 0; i < permittedProgIDsMax; i++) { + for (int i = 0; permittedProgIDs[i] != NULL; i++) { if (wcsncmp(progID, permittedProgIDs[i], wcslen(permittedProgIDs[i])) == 0) { return TRUE; } } + return FALSE; } @@ -41,7 +43,11 @@ STDMETHODIMP CoCreateInstanceAsAdmin(HWND hwnd, __in REFCLSID rclsid, __in REFII return CoGetObject(monikerName, &bindOpts, riid, ppv); } -HRESULT CElevationHelper::CreateObject(BSTR progID, IDispatch **retval) { +CElevationHelper::CElevationHelper() { + BecomeDPIAware(); +} + +STDMETHODIMP CElevationHelper::CreateObject(BSTR progID, IDispatch **retval) { if (progID == NULL) { return E_INVALIDARG; } @@ -72,3 +78,7 @@ end: } return hr; } + +STDMETHODIMP CElevationHelper::Reboot(void) { + return ::Reboot(); +} diff --git a/LegacyUpdate/ElevationHelper.h b/LegacyUpdate/ElevationHelper.h index e81bb26..3b91578 100644 --- a/LegacyUpdate/ElevationHelper.h +++ b/LegacyUpdate/ElevationHelper.h @@ -17,7 +17,7 @@ class ATL_NO_VTABLE CElevationHelper : public IDispatchImpl { public: - CElevationHelper() {} + CElevationHelper(); DECLARE_REGISTRY_RESOURCEID(IDR_ELEVATIONHELPER) @@ -39,6 +39,7 @@ public: void FinalRelease() {} STDMETHODIMP CreateObject(BSTR progID, IDispatch **retval); + STDMETHODIMP Reboot(void); }; OBJECT_ENTRY_AUTO(__uuidof(ElevationHelper), CElevationHelper) diff --git a/LegacyUpdate/ElevationHelper.rgs b/LegacyUpdate/ElevationHelper.rgs index 696e2a9..381426c 100644 --- a/LegacyUpdate/ElevationHelper.rgs +++ b/LegacyUpdate/ElevationHelper.rgs @@ -19,13 +19,12 @@ HKCR val ThreadingModel = s 'Apartment' } val AppID = s '%APPID%' - val LocalizedString = s '@%MODULE%,-2' + val LocalizedString = s '@%MODULE%,-1' TypeLib = s '{05D22F33-C7C3-4C90-BDD9-CEDC86EA8FBE}' Version = s '1.0' Elevation { val Enabled = d '1' - val IconReference = s '@%MODULE%,-201' } } } diff --git a/LegacyUpdate/LaunchUpdateSite.cpp b/LegacyUpdate/LaunchUpdateSite.cpp index 129e8ac..87ead92 100644 --- a/LegacyUpdate/LaunchUpdateSite.cpp +++ b/LegacyUpdate/LaunchUpdateSite.cpp @@ -1,174 +1,36 @@ #include "stdafx.h" -#include -#include -#include -#include -#include -#include "Utils.h" -#include "LegacyUpdate_i.h" -#include "dllmain.h" - -const LPCSTR UpdateSiteHostname = "legacyupdate.net"; -const LPWSTR UpdateSiteURLHttp = L"http://legacyupdate.net/windowsupdate/v6/"; -const LPWSTR UpdateSiteURLHttps = L"https://legacyupdate.net/windowsupdate/v6/"; -const LPWSTR UpdateSiteFirstRunFlag = L"?firstrun=true"; - -static BOOL CanUseSSLConnection() { - // Get the Windows Update website URL set by Legacy Update setup - LPWSTR data; - DWORD size; - HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate", L"URL", NULL, &data, &size); - if (!SUCCEEDED(hr)) { - goto end; - } - - // Return based on the URL value - if (StrCmpW(data, UpdateSiteURLHttps) == 0) { - return TRUE; - } else if (StrCmpW(data, UpdateSiteURLHttp) == 0) { - return FALSE; - } - -end: - // Fallback: Use SSL only on Vista and up - OSVERSIONINFOEX *versionInfo = GetVersionInfo(); - return versionInfo->dwMajorVersion > 5; -} +#include "Exec.h" +#include "HResult.h" +#include "LegacyUpdate.h" +#include // Function signature required by Rundll32.exe. void CALLBACK LaunchUpdateSite(HWND hwnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - CComPtr browser; - CComVariant url; - CComVariant flags(0); - CComVariant nullVariant; + LPWSTR path; + if (!SUCCEEDED(hr)) { goto end; } - // If running on 2k/XP, make sure we're elevated. If not, show Run As prompt. - if (GetVersionInfo()->dwMajorVersion < 6 && !IsUserAnAdmin()) { - LPWSTR filename; - DWORD filenameSize; - GetOwnFileName(&filename, &filenameSize); - WCHAR args[MAX_PATH + 20]; - StringCchPrintfW(args, filenameSize + 20, L"\"%ls\",LaunchUpdateSite", filename); - - // Ignore C4311 and C4302, which is for typecasts. It is due to ShellExec and should be safe to bypass. - #pragma warning(disable: 4311 4302) - int execResult = (int)ShellExecute(NULL, L"runas", L"rundll32.exe", args, NULL, SW_SHOWDEFAULT); - #pragma warning(default: 4311 4302) - - // Access denied happens when the user clicks No/Cancel. - if (execResult <= 32 && execResult != SE_ERR_ACCESSDENIED) { - hr = E_FAIL; - } - goto end; - } - - // Spawn an IE window via the COM interface. This ensures the page opens in IE (ShellExecute uses - // default browser), and avoids hardcoding a path to iexplore.exe. Also conveniently allows testing - // on Windows 11 (iexplore.exe redirects to Edge, but COM still works). Same strategy as used by - // Wupdmgr.exe and Muweb.dll,LaunchMUSite. - hr = browser.CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER); - if (hr == REGDB_E_CLASSNOTREG) { - // Handle case where the user has uninstalled Internet Explorer using Programs and Features. - OSVERSIONINFOEX *versionInfo = GetVersionInfo(); - - // Windows 8+: Directly prompt to reinstall IE using Fondue.exe. - SYSTEM_INFO systemInfo; - GetSystemInfo(&systemInfo); - LPWSTR archSuffix = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ? L"amd64" : L"x86"; - - WCHAR fondueArgs[256]; - StringCchPrintfW(fondueArgs, 256, L"/enable-feature:Internet-Explorer-Optional-%ls", archSuffix); - #pragma warning(disable: 4311 4302) - int execResult = (int)ShellExecute(NULL, L"open", L"fondue.exe", fondueArgs, NULL, SW_SHOWDEFAULT); - #pragma warning(default: 4311 4302) - - if (execResult <= 32) { - // Tell the user what they need to do, then open the Optional Features dialog. - WCHAR message[4096]; - LoadString(g_hInstance, IDS_IENOTINSTALLED, message, ARRAYSIZE(message)); - MessageBox(hwnd, message, L"Legacy Update", MB_OK | MB_ICONEXCLAMATION); - ShellExecute(NULL, L"open", L"OptionalFeatures.exe", NULL, NULL, SW_SHOWDEFAULT); - } - hr = S_OK; - goto end; - } else if (!SUCCEEDED(hr)) { - goto end; - } - - // Can we connect with https? WinInet will throw an error if not. - LPWSTR siteURL = CanUseSSLConnection() ? UpdateSiteURLHttps : UpdateSiteURLHttp; - - // Is this a first run launch? Append first run flag if so. - if (strcmp(lpszCmdLine, "firstrun") == 0) { - WCHAR newSiteURL[256]; - StringCchPrintfW(newSiteURL, 256, L"%s%s", siteURL, UpdateSiteFirstRunFlag); - siteURL = newSiteURL; - } - - url = siteURL; - hr = browser->Navigate2(&url, &flags, &nullVariant, &nullVariant, &nullVariant); + // This just calls LegacyUpdate.exe now for backwards compatibility. + hr = GetInstallPath(&path); if (!SUCCEEDED(hr)) { goto end; } - HWND ieHwnd; - hr = browser->get_HWND((SHANDLE_PTR *)&ieHwnd); - if (!SUCCEEDED(hr)) { - goto end; + PathAppend(path, L"LegacyUpdate.exe"); + + DWORD code; + hr = Exec(L"open", path, NULL, NULL, nCmdShow, TRUE, &code); + if (SUCCEEDED(hr)) { + hr = HRESULT_FROM_WIN32(code); } - // Are we on a small display? If so, resize and maximise the window. - HMONITOR monitor = MonitorFromWindow(ieHwnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO monitorInfo; - monitorInfo.cbSize = sizeof(MONITORINFO); - - if (GetMonitorInfo(monitor, &monitorInfo) > 0) { - LONG workWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - LONG workHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - LONG width, height; - browser->get_Width(&width); - browser->get_Height(&height); - - if (width < 800) { - width = min(800, workWidth); - browser->put_Width(width); - } - if (height < 600) { - height = min(600, workHeight); - browser->put_Height(height); - } - - LONG left, top; - browser->get_Left(&left); - browser->get_Top(&top); - - if (left + width > workWidth) { - browser->put_Left(0); - } - if (top + height > workHeight) { - browser->put_Top(0); - } - - if (workWidth <= 1152) { - ShowWindow(ieHwnd, SW_MAXIMIZE); - } - } - - browser->put_Visible(TRUE); - - // Focus the window, since it seems to not always get focus as it should. - SetForegroundWindow(ieHwnd); - end: if (!SUCCEEDED(hr)) { - MessageBox(NULL, GetMessageForHresult(hr), L"Legacy Update", MB_OK | MB_ICONEXCLAMATION); + MessageBox(NULL, GetMessageForHresult(hr), L"Legacy Update", MB_OK | MB_ICONERROR); } - browser = NULL; CoUninitialize(); } diff --git a/LegacyUpdate/LegacyUpdate.def b/LegacyUpdate/LegacyUpdate.def index 30ba241..92305f8 100644 --- a/LegacyUpdate/LegacyUpdate.def +++ b/LegacyUpdate/LegacyUpdate.def @@ -1,8 +1,14 @@ ; LegacyUpdate.def : Declares the module parameters. EXPORTS - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - LaunchUpdateSite PRIVATE + ; Registration + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + + ; Rundll32 + LaunchUpdateSite PRIVATE + + ; Internal use + GetMessageForHresult diff --git a/LegacyUpdate/LegacyUpdate.idl b/LegacyUpdate/LegacyUpdate.idl index f75306c..ed1e581 100644 --- a/LegacyUpdate/LegacyUpdate.idl +++ b/LegacyUpdate/LegacyUpdate.idl @@ -8,8 +8,9 @@ #include import "oaidl.idl"; import "ocidl.idl"; +import "wuapi.idl"; -typedef enum { +typedef enum OSVersionField { e_majorVer = 0, e_minorVer = 1, e_buildNumber = 2, @@ -27,7 +28,7 @@ typedef enum { e_maxOSVersionFieldValue = 13 } OSVersionField; -typedef enum { +typedef enum UserType { e_nonAdmin = 0, e_admin = 2, e_elevated = 3 @@ -47,6 +48,7 @@ interface ILegacyUpdateCtrl : IDispatch { [id(3)] HRESULT GetOSVersionInfo(OSVersionField osField, LONG systemMetric, [out, retval] VARIANT *retval); [id(14)] HRESULT RequestElevation(void); [id(4)] HRESULT CreateObject(BSTR progID, [out, retval] IDispatch **retval); + [id(15)] HRESULT SetBrowserHwnd(IUpdateInstaller *installer); [id(5)] HRESULT GetUserType([out, retval] UserType *retval); [id(8)] HRESULT RebootIfRequired(void); [id(9)] HRESULT ViewWindowsUpdateLog(void); @@ -83,6 +85,7 @@ interface IProgressBarControl : IDispatch interface IElevationHelper : IDispatch { [id(1)] HRESULT CreateObject(BSTR progID, [out, retval] IDispatch **retval); + [id(2)] HRESULT Reboot(void); }; [ diff --git a/LegacyUpdate/LegacyUpdate.rc b/LegacyUpdate/LegacyUpdate.rc index 90e2e15..2e10e50 100644 --- a/LegacyUpdate/LegacyUpdate.rc +++ b/LegacyUpdate/LegacyUpdate.rc @@ -1,6 +1,7 @@ // Microsoft Visual C++ generated resource script. // #include "resource.h" +#include "Version.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -57,8 +58,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,0,0 - PRODUCTVERSION 1,9,0,0 + FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD + PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -75,12 +76,12 @@ BEGIN BEGIN VALUE "CompanyName", "Hashbang Productions" VALUE "FileDescription", "Legacy Update" - VALUE "FileVersion", "1.9.0.0" + VALUE "FileVersion", VERSION_STRING VALUE "InternalName", "LegacyUpdate.dll" VALUE "LegalCopyright", "© Hashbang Productions. All rights reserved." VALUE "OriginalFilename", "LegacyUpdate.dll" VALUE "ProductName", "Legacy Update" - VALUE "ProductVersion", "1.9.0.0" + VALUE "ProductVersion", VERSION_STRING END END BLOCK "VarFileInfo" @@ -90,16 +91,6 @@ BEGIN END -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "icon.ico" - - ///////////////////////////////////////////////////////////////////////////// // // REGISTRY @@ -114,14 +105,6 @@ IDR_PROGRESSBARCONTROL REGISTRY "ProgressBarControl.rgs" IDR_ELEVATIONHELPER REGISTRY "ElevationHelper.rgs" -///////////////////////////////////////////////////////////////////////////// -// -// XML -// - -IDR_CPLTASKS XML "CplTasks.xml" - - ///////////////////////////////////////////////////////////////////////////// // // String Table @@ -129,11 +112,7 @@ IDR_CPLTASKS XML "CplTasks.xml" STRINGTABLE BEGIN - IDS_LEGACYUPDATEOCX "Legacy Update Control" IDS_LEGACYUPDATE "Legacy Update" - IDS_CHECKFORUPDATES "Check for updates" - IDS_CHECKFORUPDATES_ALT "Check for software and driver updates via Legacy Update." - IDS_IENOTINSTALLED "Internet Explorer is not installed. Use Optional Features in Control Panel to install it before using Legacy Update." END #endif // English (United States) resources @@ -148,6 +127,8 @@ END // 1 TYPELIB "LegacyUpdate.tlb" +#include "wuerror.rc" + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/LegacyUpdate/LegacyUpdate.vcxproj b/LegacyUpdate/LegacyUpdate.vcxproj index af43476..6acf74c 100644 --- a/LegacyUpdate/LegacyUpdate.vcxproj +++ b/LegacyUpdate/LegacyUpdate.vcxproj @@ -38,26 +38,28 @@ true Unicode v90 - Dynamic + Static DynamicLibrary true Unicode v90 - Dynamic + Static DynamicLibrary true Unicode v141_xp + false DynamicLibrary true Unicode v141_xp + false DynamicLibrary @@ -66,7 +68,7 @@ Unicode v90 Static - Static + false DynamicLibrary @@ -74,8 +76,9 @@ true Unicode v141_xp + false Static - Static + false @@ -137,12 +140,16 @@ WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + false + MultiThreadedDebug Windows true .\LegacyUpdate.def $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) + false _DEBUG;%(PreprocessorDefinitions) @@ -167,7 +174,7 @@ - cmd /c start "" taskkill /im iexplore.exe + cmd /c start /min "" taskkill /im iexplore.exe @@ -178,12 +185,16 @@ WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + false + MultiThreadedDebug Windows true .\LegacyUpdate.def $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) + false _DEBUG;%(PreprocessorDefinitions) @@ -206,7 +217,7 @@ - cmd /c start "" taskkill /im iexplore.exe + cmd /c start /min "" taskkill /im iexplore.exe @@ -217,12 +228,15 @@ WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + MultiThreadedDebug Windows true .\LegacyUpdate.def $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) + false _DEBUG;%(PreprocessorDefinitions) @@ -247,7 +261,7 @@ - cmd /c start "" taskkill /im iexplore.exe + cmd /c start /min "" taskkill /im iexplore.exe @@ -258,12 +272,15 @@ WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + MultiThreadedDebug Windows true .\LegacyUpdate.def $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) + false _DEBUG;%(PreprocessorDefinitions) @@ -286,19 +303,23 @@ - cmd /c start "" taskkill /im iexplore.exe + cmd /c start /min "" taskkill /im iexplore.exe Level3 Use - MaxSpeed + + true - true + + WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + Size + MultiThreaded Windows @@ -309,6 +330,7 @@ $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) _DEBUG;%(PreprocessorDefinitions) @@ -329,19 +351,23 @@ $(IntDir);%(AdditionalIncludeDirectories) - cmd /c start "" taskkill /im iexplore.exe + cmd /c start /min "" taskkill /im iexplore.exe Level3 Use - MaxSpeed + + true - true + + WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;%(PreprocessorDefinitions) true + Size + MultiThreaded Windows @@ -352,6 +378,7 @@ $(OutDir)$(ProjectName).dll + /filealign:0x200 %(AdditionalOptions) _DEBUG;%(PreprocessorDefinitions) @@ -371,7 +398,6 @@ - @@ -381,10 +407,87 @@ true + + false + Document + false + mc %(FullPath) -r $(IntDir) -h $(IntDir) + Compiling Message Table + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + mc %(FullPath) -r $(IntDir) -h $(IntDir) + Compiling Message Table + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + + + + + mc %(FullPath) -r $(IntDir) -h $(IntDir) + mc %(FullPath) -r $(IntDir) -h $(IntDir) + mc %(FullPath) -r $(IntDir) -h $(IntDir) + mc %(FullPath) -r $(IntDir) -h $(IntDir) + Compiling Message Table + Compiling Message Table + Compiling Message Table + Compiling Message Table + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + $(IntDir)%(Identity).rc;$(IntDir)%(Identity).h;$(IntDir)MSG0409.bin + false + false + false + false + - - + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + @@ -461,10 +564,15 @@ + + + + + @@ -490,4 +598,4 @@ - \ No newline at end of file + diff --git a/LegacyUpdate/LegacyUpdate.vcxproj.filters b/LegacyUpdate/LegacyUpdate.vcxproj.filters index 2c8792c..cd6b79c 100644 --- a/LegacyUpdate/LegacyUpdate.vcxproj.filters +++ b/LegacyUpdate/LegacyUpdate.vcxproj.filters @@ -34,9 +34,6 @@ Resource Files - - Resource Files - Resource Files @@ -72,10 +69,22 @@ Source Files - + Shared - + + Shared + + + Shared + + + Shared + + + Shared + + Shared @@ -122,6 +131,21 @@ Shared + + Shared + + + Shared + + + Header Files + + + Shared + + + Shared + @@ -132,5 +156,13 @@ Source Files + + Source Files + + + + + Resource Files + \ No newline at end of file diff --git a/LegacyUpdate/LegacyUpdateCtrl.cpp b/LegacyUpdate/LegacyUpdateCtrl.cpp index ca3cb6b..3939e51 100644 --- a/LegacyUpdate/LegacyUpdateCtrl.cpp +++ b/LegacyUpdate/LegacyUpdateCtrl.cpp @@ -2,13 +2,20 @@ #include "stdafx.h" #include "LegacyUpdateCtrl.h" -#include "Utils.h" #include "Compat.h" #include "ElevationHelper.h" +#include "Exec.h" +#include "HResult.h" +#include "LegacyUpdate.h" +#include "Registry.h" +#include "User.h" +#include "Utils.h" +#include "VersionInfo.h" +#include "WULog.h" #include -#include -#include #include +#include +#include "IUpdateInstaller4.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -19,7 +26,6 @@ const BSTR permittedHosts[] = { L"test.legacyupdate.net", NULL }; -const int permittedHostsMax = 2; // CLegacyUpdateCtrl message handlers @@ -39,7 +45,7 @@ IHTMLDocument2 *CLegacyUpdateCtrl::GetHTMLDocument() { } CComPtr document; - hr = container->QueryInterface(IID_IHTMLDocument2, (void**)&document); + hr = container->QueryInterface(IID_IHTMLDocument2, (void **)&document); if (!SUCCEEDED(hr) || document == NULL) { TRACE("GetDocument() failed: %ls\n", GetMessageForHresult(hr)); return NULL; @@ -50,7 +56,7 @@ IHTMLDocument2 *CLegacyUpdateCtrl::GetHTMLDocument() { HWND CLegacyUpdateCtrl::GetIEWindowHWND() { CComPtr oleWindow; - HRESULT hr = QueryInterface(IID_IOleWindow, (void**)&oleWindow); + HRESULT hr = QueryInterface(IID_IOleWindow, (void **)&oleWindow); if (!SUCCEEDED(hr) || !oleWindow) { goto end; } @@ -94,7 +100,7 @@ BOOL CLegacyUpdateCtrl::IsPermitted(void) { goto end; } - for (int i = 0; i < permittedHostsMax; i++) { + for (int i = 0; permittedHosts[i] != NULL; i++) { if (wcscmp(host, permittedHosts[i]) == 0) { return TRUE; } @@ -107,22 +113,49 @@ end: return FALSE; } +STDMETHODIMP CLegacyUpdateCtrl::GetElevatedHelper(CComPtr &retval) { + CComPtr elevatedHelper = m_elevatedHelper ? m_elevatedHelper : m_nonElevatedHelper; + if (elevatedHelper == NULL) { + // Use the helper directly, without elevation. It's the responsibility of the caller to ensure it + // is already running as admin on 2k/XP, or that it has requested elevation on Vista+. + HRESULT hr = m_nonElevatedHelper.CoCreateInstance(CLSID_ElevationHelper, NULL, CLSCTX_INPROC_SERVER); + if (!SUCCEEDED(hr)) { + return hr; + } + + elevatedHelper = m_nonElevatedHelper; + } + + retval = elevatedHelper; + return S_OK; +} + #define DoIsPermittedCheck() \ if (!IsPermitted()) { \ return E_ACCESSDENIED; \ } +STDMETHODIMP CLegacyUpdateCtrl::SetClientSite(IOleClientSite *pClientSite) { + HRESULT hr = IOleObjectImpl::SetClientSite(pClientSite); + if (!SUCCEEDED(hr)) { + return hr; + } + + DoIsPermittedCheck(); + return S_OK; +} + STDMETHODIMP CLegacyUpdateCtrl::CheckControl(VARIANT_BOOL *retval) { DoIsPermittedCheck(); // Just return true so the site can confirm the control is working. - *retval = TRUE; + *retval = VARIANT_TRUE; return S_OK; } STDMETHODIMP CLegacyUpdateCtrl::MessageForHresult(LONG inHresult, BSTR *retval) { DoIsPermittedCheck(); - *retval = GetMessageForHresult(inHresult); + *retval = SysAllocString(GetMessageForHresult(inHresult)); return S_OK; } @@ -130,71 +163,78 @@ STDMETHODIMP CLegacyUpdateCtrl::GetOSVersionInfo(OSVersionField osField, LONG sy DoIsPermittedCheck(); VariantInit(retval); - retval->vt = VT_I4; OSVERSIONINFOEX *versionInfo = GetVersionInfo(); switch (osField) { case e_majorVer: - retval->lVal = versionInfo->dwMajorVersion; + retval->vt = VT_UI4; + retval->ulVal = versionInfo->dwMajorVersion; break; case e_minorVer: - retval->lVal = versionInfo->dwMinorVersion; + retval->vt = VT_UI4; + retval->ulVal = versionInfo->dwMinorVersion; break; case e_buildNumber: - retval->lVal = versionInfo->dwBuildNumber; + retval->vt = VT_UI4; + retval->ulVal = versionInfo->dwBuildNumber; break; case e_platform: - retval->lVal = versionInfo->dwPlatformId; + retval->vt = VT_UI4; + retval->ulVal = versionInfo->dwPlatformId; break; case e_SPMajor: + retval->vt = VT_I4; retval->lVal = versionInfo->wServicePackMajor; break; case e_SPMinor: + retval->vt = VT_I4; retval->lVal = versionInfo->wServicePackMinor; break; case e_productSuite: + retval->vt = VT_I4; retval->lVal = versionInfo->wSuiteMask; break; case e_productType: + retval->vt = VT_I4; retval->lVal = versionInfo->wProductType; break; case e_systemMetric: + retval->vt = VT_I4; retval->lVal = GetSystemMetrics(systemMetric); break; case e_SPVersionString: { LPWSTR data; DWORD size; - HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"BuildLab", NULL, &data, &size); - if (SUCCEEDED(hr)) { - retval->vt = VT_BSTR; - retval->bstrVal = SysAllocStringLen(data, size - 1); - } else { + HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"BuildLab", 0, &data, &size); + retval->vt = VT_BSTR; + retval->bstrVal = SUCCEEDED(hr) + ? SysAllocStringLen(data, size - 1) // BuildLab doesn't exist on Windows 2000. - retval->vt = VT_BSTR; - retval->bstrVal = SysAllocString(versionInfo->szCSDVersion); + : SysAllocString(versionInfo->szCSDVersion); + if (data) { + LocalFree(data); } break; } case e_controlVersionString: { LPWSTR data; - DWORD size; - HRESULT hr = GetOwnVersion(&data, &size); + HRESULT hr = GetOwnVersion(&data); if (!SUCCEEDED(hr)) { return hr; } retval->vt = VT_BSTR; - retval->bstrVal = SysAllocStringLen(data, size - 1); + retval->bstrVal = SysAllocString(data); break; } @@ -211,12 +251,10 @@ STDMETHODIMP CLegacyUpdateCtrl::GetOSVersionInfo(OSVersionField osField, LONG sy if (!SUCCEEDED(hr)) { LPWSTR data; DWORD size; - hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ProductName", NULL, &data, &size); + hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ProductName", 0, &data, &size); if (SUCCEEDED(hr)) { retval->vt = VT_BSTR; retval->bstrVal = SysAllocStringLen(data, size - 1); - } else { - VariantClear(retval); } } break; @@ -225,12 +263,11 @@ STDMETHODIMP CLegacyUpdateCtrl::GetOSVersionInfo(OSVersionField osField, LONG sy case e_displayVersion: { LPWSTR data; DWORD size; - HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"DisplayVersion", NULL, &data, &size); + HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"DisplayVersion", 0, &data, &size); if (SUCCEEDED(hr)) { retval->vt = VT_BSTR; retval->bstrVal = SysAllocStringLen(data, size - 1); - } else { - VariantClear(retval); + LocalFree(data); } break; } @@ -242,7 +279,7 @@ STDMETHODIMP CLegacyUpdateCtrl::GetOSVersionInfo(OSVersionField osField, LONG sy STDMETHODIMP CLegacyUpdateCtrl::RequestElevation() { DoIsPermittedCheck(); - if (m_elevatedHelper != NULL || GetVersionInfo()->dwMajorVersion < 6) { + if (m_elevatedHelper != NULL || !AtLeastWinVista()) { return S_OK; } @@ -269,15 +306,9 @@ STDMETHODIMP CLegacyUpdateCtrl::CreateObject(BSTR progID, IDispatch **retval) { goto end; } - elevatedHelper = m_elevatedHelper ? m_elevatedHelper : m_nonElevatedHelper; - if (elevatedHelper == NULL) { - // Use the helper directly, without elevation. It's the responsibility of the caller to ensure it - // is already running as admin on 2k/XP, or that it has requested elevation on Vista+. - m_nonElevatedHelper.CoCreateInstance(CLSID_ElevationHelper, NULL, CLSCTX_INPROC_SERVER); - if (!SUCCEEDED(hr)) { - goto end; - } - elevatedHelper = m_nonElevatedHelper; + hr = GetElevatedHelper(elevatedHelper); + if (!SUCCEEDED(hr)) { + goto end; } return elevatedHelper->CreateObject(progID, retval); @@ -289,10 +320,27 @@ end: return hr; } +STDMETHODIMP CLegacyUpdateCtrl::SetBrowserHwnd(IUpdateInstaller *installer) { + DoIsPermittedCheck(); + + if (installer == NULL) { + return E_INVALIDARG; + } + + CComPtr updateInstaller = NULL; + HRESULT hr = installer->QueryInterface(IID_IUpdateInstaller, (void **)&updateInstaller); + if (!SUCCEEDED(hr)) { + return hr; + } + + updateInstaller->put_ParentHwnd(GetIEWindowHWND()); + return S_OK; +} + STDMETHODIMP CLegacyUpdateCtrl::GetUserType(UserType *retval) { DoIsPermittedCheck(); - if (IsUserAnAdmin()) { + if (IsUserAdmin()) { // Entire process is elevated. *retval = e_admin; } else if (m_elevatedHelper != NULL) { @@ -302,115 +350,147 @@ 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; } STDMETHODIMP CLegacyUpdateCtrl::get_IsRebootRequired(VARIANT_BOOL *retval) { DoIsPermittedCheck(); - HKEY subkey; - HRESULT hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired", 0, KEY_READ, &subkey); - *retval = subkey != NULL; - if (subkey != NULL) { - RegCloseKey(subkey); + // Ask WU itself whether a reboot is required + CComPtr systemInfo; + if (SUCCEEDED(systemInfo.CoCreateInstance(CLSID_SystemInformation, NULL, CLSCTX_INPROC_SERVER))) { + if (SUCCEEDED(systemInfo->get_RebootRequired(retval)) && *retval == VARIANT_TRUE) { + return S_OK; + } } + + // Check reboot flag in registry + HKEY subkey; + HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired", KEY_WOW64_64KEY, KEY_READ, &subkey)); + if (SUCCEEDED(hr)) { + RegCloseKey(subkey); + *retval = VARIANT_TRUE; + return S_OK; + } + + *retval = VARIANT_FALSE; return S_OK; } STDMETHODIMP CLegacyUpdateCtrl::get_IsWindowsUpdateDisabled(VARIANT_BOOL *retval) { DoIsPermittedCheck(); - DWORD noWU; - HRESULT hr = GetRegistryDword(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", L"NoWindowsUpdate", NULL, &noWU); - if (SUCCEEDED(hr) && noWU == 1) { - *retval = TRUE; + // Future note: These are in HKCU on NT; HKLM on 9x. + // Remove links and access to Windows Update + DWORD value; + HRESULT hr = GetRegistryDword(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", L"NoWindowsUpdate", KEY_WOW64_64KEY, &value); + if (SUCCEEDED(hr) && value == 1) { + *retval = VARIANT_TRUE; return S_OK; } - DWORD disableWUAccess; - hr = GetRegistryDword(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\WindowsUpdate", L"DisableWindowsUpdateAccess", NULL, &disableWUAccess); - if (SUCCEEDED(hr) && disableWUAccess == 1) { - *retval = TRUE; + // Remove access to use all Windows Update features + hr = GetRegistryDword(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\WindowsUpdate", L"DisableWindowsUpdateAccess", KEY_WOW64_64KEY, &value); + if (SUCCEEDED(hr) && value == 1) { + *retval = VARIANT_TRUE; return S_OK; } - *retval = FALSE; + *retval = VARIANT_FALSE; return S_OK; } STDMETHODIMP CLegacyUpdateCtrl::RebootIfRequired(void) { DoIsPermittedCheck(); + HRESULT hr = S_OK; VARIANT_BOOL isRebootRequired; - if (SUCCEEDED(get_IsRebootRequired(&isRebootRequired)) && isRebootRequired) { - Reboot(); + if (SUCCEEDED(get_IsRebootRequired(&isRebootRequired)) && isRebootRequired == VARIANT_TRUE) { + // Calling Commit() is recommended on Windows 10, to ensure feature updates are properly prepared + // prior to the reboot. If IUpdateInstaller4 doesn't exist, we can skip this. + CComPtr installer; + hr = installer.CoCreateInstance(CLSID_UpdateInstaller, NULL, CLSCTX_INPROC_SERVER); + if (SUCCEEDED(hr) && hr != REGDB_E_CLASSNOTREG) { + hr = installer->Commit(0); + if (!SUCCEEDED(hr)) { + return hr; + } + } + + + CComPtr elevatedHelper; + hr = GetElevatedHelper(elevatedHelper); + if (!SUCCEEDED(hr)) { + return hr; + } + + hr = elevatedHelper->Reboot(); } - return S_OK; + + return hr; +} + +static HRESULT StartLauncher(LPWSTR params, BOOL wait) { + LPWSTR path; + HRESULT hr = GetInstallPath(&path); + if (!SUCCEEDED(hr)) { + return hr; + } + + PathAppend(path, L"LegacyUpdate.exe"); + + DWORD code; + hr = Exec(L"open", path, params, NULL, SW_SHOW, wait, &code); + if (SUCCEEDED(hr)) { + hr = HRESULT_FROM_WIN32(code); + } + + return hr; } STDMETHODIMP CLegacyUpdateCtrl::ViewWindowsUpdateLog(void) { DoIsPermittedCheck(); - WCHAR windir[MAX_PATH]; - HRESULT hr = SHGetFolderPath(0, CSIDL_WINDOWS, NULL, 0, windir); + HRESULT hr = StartLauncher(L"/log", FALSE); if (!SUCCEEDED(hr)) { - TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr)); - return hr; + // Try directly + hr = ::ViewWindowsUpdateLog(SW_SHOWDEFAULT); } - // Try Windows Server 2003 Resource Kit (or MSYS/Cygwin/etc) tail.exe, falling back to directly - // opening the file (most likely in Notepad). - // Ignore C4311 and C4302, which is for typecasts. It is due to ShellExec and should be safe to bypass. - #pragma warning(disable: 4311 4302) - if ((int)ShellExecute(NULL, L"open", L"tail.exe", L"-f WindowsUpdate.log", windir, SW_SHOWDEFAULT) > 32) { - return S_OK; - } - ShellExecute(NULL, L"open", L"WindowsUpdate.log", NULL, windir, SW_SHOWDEFAULT); - #pragma warning(default: 4311 4302) - return S_OK; + return hr; } 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); - - WCHAR systemDir[MAX_PATH]; - HRESULT hr = SHGetFolderPath(0, CSIDL_SYSTEM, NULL, 0, systemDir); + HRESULT hr = StartLauncher(L"/options", FALSE); if (!SUCCEEDED(hr)) { - TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr)); - return hr; + TRACE(L"OpenWindowsUpdateSettings() failed, falling back: %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)); + } } - DWORD majorVersion = GetVersionInfo()->dwMajorVersion; - if (majorVersion >= 10) { - // Windows 10+: Open Settings app - ShellExecute(NULL, NULL, L"ms-settings:windowsupdate-options", NULL, systemDir, SW_SHOWDEFAULT); - } else if (majorVersion >= 6) { - // Windows Vista, 7, 8: Open Windows Update control panel - ShellExecute(NULL, NULL, L"wuauclt.exe", L"/ShowOptions", systemDir, SW_SHOWDEFAULT); - } else { - // Windows 2000, XP: Open Automatic Updates control panel - ShellExecute(NULL, NULL, L"wuaucpl.cpl", NULL, systemDir, SW_SHOWDEFAULT); - } - - // Revert WOW64 redirection if we changed it. - if (isRedirected) { - RevertWow64FsRedirection(oldValue); - } - return S_OK; + return hr; } STDMETHODIMP CLegacyUpdateCtrl::get_IsUsingWsusServer(VARIANT_BOOL *retval) { DoIsPermittedCheck(); DWORD useWUServer; - HRESULT hr = GetRegistryDword(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU", L"UseWUServer", NULL, &useWUServer); - *retval = SUCCEEDED(hr) && useWUServer == 1; + HRESULT hr = GetRegistryDword(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU", L"UseWUServer", 0, &useWUServer); + *retval = SUCCEEDED(hr) && useWUServer == 1 ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; } @@ -419,8 +499,11 @@ STDMETHODIMP CLegacyUpdateCtrl::get_WsusServerUrl(BSTR *retval) { LPWSTR data; DWORD size; - HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate", L"WUServer", NULL, &data, &size); + HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate", L"WUServer", 0, &data, &size); *retval = SUCCEEDED(hr) ? SysAllocStringLen(data, size - 1) : NULL; + if (data) { + LocalFree(data); + } return S_OK; } @@ -429,7 +512,10 @@ STDMETHODIMP CLegacyUpdateCtrl::get_WsusStatusServerUrl(BSTR *retval) { LPWSTR data; DWORD size; - HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate", L"WUStatusServer", NULL, &data, &size); + HRESULT hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate", L"WUStatusServer", 0, &data, &size); *retval = SUCCEEDED(hr) ? SysAllocStringLen(data, size - 1) : NULL; + if (data) { + LocalFree(data); + } return S_OK; } diff --git a/LegacyUpdate/LegacyUpdateCtrl.h b/LegacyUpdate/LegacyUpdateCtrl.h index 8a53fb7..34d421d 100644 --- a/LegacyUpdate/LegacyUpdateCtrl.h +++ b/LegacyUpdate/LegacyUpdateCtrl.h @@ -6,6 +6,7 @@ #include #include +#include #include "resource.h" #include "LegacyUpdate_i.h" @@ -93,13 +94,17 @@ private: IHTMLDocument2 *GetHTMLDocument(); HWND GetIEWindowHWND(); BOOL IsPermitted(); + STDMETHODIMP GetElevatedHelper(CComPtr &retval); public: + STDMETHODIMP SetClientSite(IOleClientSite *pClientSite); + STDMETHODIMP CheckControl(VARIANT_BOOL *retval); STDMETHODIMP MessageForHresult(LONG inHresult, BSTR *retval); STDMETHODIMP GetOSVersionInfo(OSVersionField osField, LONG systemMetric, VARIANT *retval); STDMETHODIMP RequestElevation(); STDMETHODIMP CreateObject(BSTR progID, IDispatch **retval); + STDMETHODIMP SetBrowserHwnd(IUpdateInstaller *installer); STDMETHODIMP GetUserType(UserType *retval); STDMETHODIMP get_IsRebootRequired(VARIANT_BOOL *retval); STDMETHODIMP get_IsWindowsUpdateDisabled(VARIANT_BOOL *retval); diff --git a/LegacyUpdate/Makefile b/LegacyUpdate/Makefile index e93e85f..f0fe990 100644 --- a/LegacyUpdate/Makefile +++ b/LegacyUpdate/Makefile @@ -1,9 +1,31 @@ +override DEBUG := $(or $(DEBUG),1) + +MSBUILDCONFIG32 = $(if $(filter 1,$(DEBUG)),Debug-VC08,Release) +MSBUILDCONFIG64 = $(if $(filter 1,$(DEBUG)),Debug-VC17,Release) + +MSBUILDFLAGS = /v:minimal /m + ifeq ($(CI),1) +ifeq ($(DEBUG),1) + MSBUILDCONFIG32 = Debug-VC17 +endif MSBUILDFLAGS += /p:PlatformToolset=v141_xp endif +MSBUILDFLAGS32 = $(MSBUILDFLAGS) /p:Configuration=$(MSBUILDCONFIG32) /p:Platform=Win32 +MSBUILDFLAGS64 = $(MSBUILDFLAGS) /p:Configuration=$(MSBUILDCONFIG64) /p:Platform=x64 + +VSPATH ?= $(shell wslpath "$(shell '/mnt/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe' -latest -property installationPath)") +PATH := $(VSPATH)/MSBuild/Current/Bin:$(PATH) + +MSBUILD = msbuild.exe + all: - cmd.exe /c build.cmd $(MSBUILDFLAGS) + @# Workaround for "dlldatax.obj: LNK2001: unresolved external symbol _LegacyUpdate_ProxyFileInfo" + rm -f LegacyUpdate_p.c + cd ..; $(MSBUILD) $(MSBUILDFLAGS32) LegacyUpdate.sln + rm -f LegacyUpdate_p.c + cd ..; $(MSBUILD) $(MSBUILDFLAGS64) LegacyUpdate.sln ifeq ($(SIGN),1) ../build/sign.sh \ @@ -12,6 +34,10 @@ ifeq ($(SIGN),1) endif clean: - @# Not needed, build.cmd cleans before it builds + rm -rf \ + Debug-VC08 Debug-VC17 Release x64 \ + LegacyUpdate_i.c LegacyUpdate_i.h LegacyUpdate_p.c LegacyUpdateidl.h + cd ..; $(MSBUILD) $(MSBUILDFLAGS32) LegacyUpdate.sln /t:Clean + cd ..; $(MSBUILD) $(MSBUILDFLAGS64) LegacyUpdate.sln /t:Clean .PHONY: all clean diff --git a/LegacyUpdate/Resource.h b/LegacyUpdate/Resource.h index 0c7bedd..913bcb1 100644 --- a/LegacyUpdate/Resource.h +++ b/LegacyUpdate/Resource.h @@ -2,20 +2,14 @@ // Microsoft Visual C++ generated include file. // Used by LegacyUpdate.rc // -#define IDS_LEGACYUPDATEOCX 1 -#define IDS_LEGACYUPDATE 2 -#define IDS_CHECKFORUPDATES 3 -#define IDS_CHECKFORUPDATES_ALT 4 -#define IDS_IENOTINSTALLED 5 +#define IDS_LEGACYUPDATE 1 #define IDR_LEGACYUPDATEOCX 101 #define IDR_LEGACYUPDATECTRL 102 #define IDR_PROGRESSBARCONTROL 103 #define IDR_ELEVATIONHELPER 104 -#define IDI_ICON1 201 -#define IDR_CPLTASKS 202 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 204 diff --git a/LegacyUpdate/Utils.cpp b/LegacyUpdate/Utils.cpp index fd7bd35..fb9629d 100644 --- a/LegacyUpdate/Utils.cpp +++ b/LegacyUpdate/Utils.cpp @@ -1,176 +1,166 @@ #include "stdafx.h" #include #include +#include +#include "HResult.h" #include "WMI.h" +#include "VersionInfo.h" -#pragma comment(lib, "version.lib") #pragma comment(lib, "advapi32.lib") +#pragma comment(lib, "shlwapi.lib") +#pragma comment(lib, "version.lib") -// Defined as being Vista+, older versions ignore the flag. -#ifndef EWX_RESTARTAPPS -#define EWX_RESTARTAPPS 0x00000040 -#endif - -extern "C" IMAGE_DOS_HEADER __ImageBase; - -#define OwnModule ((HMODULE)&__ImageBase) +typedef DWORD (WINAPI *_InitiateShutdownW)(LPWSTR lpMachineName, LPWSTR lpMessage, DWORD dwGracePeriod, DWORD dwShutdownFlags, DWORD dwReason); static BOOL _loadedProductName = FALSE; static CComVariant _productName; -static BOOL _loadedOwnVersion = FALSE; -static LPWSTR _version; -static UINT _versionSize; +typedef struct { + DWORD version; + DWORD osFlag; + LPWSTR library; + UINT stringIDs[3]; +} WinNT5Variant; -void GetOwnFileName(LPWSTR *filename, LPDWORD size) { - *filename = (LPWSTR)malloc(MAX_PATH); - *size = GetModuleFileName(OwnModule, *filename, MAX_PATH); -} +static const WinNT5Variant nt5Variants[] = { + // XP + {0x0501, OS_TABLETPC, L"winbrand.dll", { 180, 2000}}, + {0x0501, OS_MEDIACENTER, L"winbrand.dll", { 180, 2001}}, + {0x0501, OS_STARTER, L"winbrand.dll", { 180, 2002}}, + {0x0501, OS_EMBPOS, L"winbrand.dll", { 180, 2003}}, + {0x0501, OS_WINFLP, L"winbrand.dll", { 180, 2004}}, + {0x0501, OS_EMBSTD2009, L"winbrand.dll", { 180, 2005}}, + {0x0501, OS_EMBPOS2009, L"winbrand.dll", { 180, 2006}}, + // Check for XP Embedded last as WES2009 also identifies as OS_EMBEDDED. + {0x0501, OS_EMBEDDED, L"sysdm.cpl", { 180, 189}}, -HRESULT GetOwnVersion(LPWSTR *version, LPDWORD size) { - if (!_loadedOwnVersion) { - LPWSTR filename; - DWORD filenameSize; - GetOwnFileName(&filename, &filenameSize); + // Server 2003 + {0x0502, OS_APPLIANCE, L"winbrand.dll", { 181, 2002}}, + {0x0502, OS_STORAGESERVER, L"wssbrand.dll", {1101, 1102}}, + {0x0502, OS_COMPUTECLUSTER, L"hpcbrand.dll", {1101, 1102, 1103}}, + {0x0502, OS_HOMESERVER, L"whsbrand.dll", {1101, 1102}}, +}; - DWORD verHandle; - DWORD verInfoSize = GetFileVersionInfoSize(filename, &verHandle); - if (verInfoSize == 0) { - return AtlHresultFromLastError(); - } +HRESULT GetOSProductName(LPVARIANT productName) { + if (!_loadedProductName) { + _loadedProductName = TRUE; + VariantInit(&_productName); - LPVOID verInfo = new BYTE[verInfoSize]; - if (!GetFileVersionInfo(filename, verHandle, verInfoSize, verInfo)) { - return AtlHresultFromLastError(); - } - - if (!VerQueryValue(verInfo, L"\\StringFileInfo\\040904B0\\ProductVersion", (LPVOID *)&_version, &_versionSize)) { - return AtlHresultFromLastError(); - } - } - - *version = _version; - *size = _versionSize; - return _version == NULL ? E_FAIL : NOERROR; -} - -HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, LPDWORD type, LPWSTR *data, LPDWORD size) { - HKEY subkey; - HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, KEY_READ, &subkey)); - if (!SUCCEEDED(hr)) { - goto end; - } - - if (data != NULL && size != NULL) { - DWORD length = 512 * sizeof(WCHAR); - LPWSTR buffer = (LPWSTR)malloc(length); - LSTATUS status; - do { - status = RegQueryValueEx(subkey, valueName, NULL, type, (BYTE *)buffer, &length); - if (status == ERROR_MORE_DATA) { - length += 256 * sizeof(WCHAR); - buffer = (LPWSTR)realloc(buffer, length); - } else if (status != ERROR_SUCCESS) { - hr = HRESULT_FROM_WIN32(status); - goto end; + // Handle the absolute disaster of Windows XP/Server 2003 edition branding + WORD winver = GetWinVer(); + if (HIBYTE(winver) == 5) { + WinNT5Variant variant = {}; + for (DWORD i = 0; i < ARRAYSIZE(nt5Variants); i++) { + if (winver == nt5Variants[i].version && IsOS(nt5Variants[i].osFlag)) { + variant = nt5Variants[i]; + break; + } } - } while (status == ERROR_MORE_DATA); - *data = buffer; - *size = length / sizeof(WCHAR); - } + if (variant.version) { + HMODULE brandDll = LoadLibraryEx(variant.library, NULL, LOAD_LIBRARY_AS_DATAFILE); + if (brandDll) { + WCHAR brandStr[1024]; + ZeroMemory(brandStr, ARRAYSIZE(brandStr)); -end: - if (subkey != NULL) { - RegCloseKey(subkey); - } - if (!SUCCEEDED(hr)) { - if (data != NULL) { - *data = NULL; + DWORD j = 0; + while (variant.stringIDs[j] != 0) { + UINT id = variant.stringIDs[j]; + WCHAR str[340]; + if (id == 180 || id == 181) { + // Get "Microsoft Windows XP" or "Microsoft Windows Server 2003" string + HMODULE sysdm = LoadLibraryEx(L"sysdm.cpl", NULL, LOAD_LIBRARY_AS_DATAFILE); + if (sysdm) { + LoadString(sysdm, id, str, ARRAYSIZE(str)); + FreeLibrary(sysdm); + } + } else { + LoadString(brandDll, id, str, ARRAYSIZE(str)); + } + + if (j > 0) { + wcscat(brandStr, L" "); + } + + wcscat(brandStr, str); + j++; + } + + _productName.vt = VT_BSTR; + _productName.bstrVal = SysAllocString(brandStr); + FreeLibrary(brandDll); + } + } } - if (size != NULL) { - *size = 0; - } - } - return hr; -} -HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, LPDWORD type, LPDWORD data) { - HKEY subkey; - HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, KEY_READ, &subkey)); - if (!SUCCEEDED(hr)) { - goto end; - } - - if (data != NULL) { - DWORD length = sizeof(DWORD); - hr = HRESULT_FROM_WIN32(RegQueryValueEx(subkey, valueName, NULL, type, (LPBYTE)data, &length)); - if (!SUCCEEDED(hr)) { - goto end; + if (_productName.vt == VT_EMPTY) { + // Get from WMI + HRESULT hr = QueryWMIProperty(L"SELECT Caption FROM Win32_OperatingSystem", L"Caption", &_productName); + if (!SUCCEEDED(hr)) { + return hr; + } } } -end: - if (subkey != NULL) { - RegCloseKey(subkey); - } - return hr; -} - -LPWSTR GetMessageForHresult(HRESULT hr) { - _com_error *error = new _com_error(hr); - CString message = error->ErrorMessage(); - BSTR outMessage = message.AllocSysString(); - return outMessage; -} - -HRESULT GetOSProductName(VARIANT *pProductName) { - if (_loadedProductName) { - VariantCopy(pProductName, &_productName); - return S_OK; - } - - VariantInit(&_productName); - _loadedProductName = true; - return QueryWMIProperty(L"SELECT Caption FROM Win32_OperatingSystem", L"Caption", &_productName); + VariantCopy(productName, &_productName); + return S_OK; } HRESULT Reboot() { HRESULT hr = E_FAIL; - // Make sure we have permission to shut down. + // Make sure we have permission to shut down HANDLE token; - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - LUID shutdownLuid; - if (LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &shutdownLuid) != 0) { - // Ask the system nicely to give us shutdown privilege. - TOKEN_PRIVILEGES privileges; - privileges.PrivilegeCount = 1; - privileges.Privileges[0].Luid = shutdownLuid; - privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (!AdjustTokenPrivileges(token, FALSE, &privileges, 0, NULL, NULL)) { - hr = AtlHresultFromLastError(); - TRACE("AdjustTokenPrivileges() failed: %ls\n", GetMessageForHresult(hr)); - } - } - } else { + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { hr = AtlHresultFromLastError(); TRACE("OpenProcessToken() failed: %ls\n", GetMessageForHresult(hr)); + goto end; } - // Reboot with reason "Operating System: Security fix (Unplanned)" - if (!InitiateSystemShutdownEx(NULL, NULL, 0, FALSE, TRUE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX)) { + LUID shutdownLuid; + if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &shutdownLuid)) { hr = AtlHresultFromLastError(); - TRACE("InitiateSystemShutdownExW() failed: %ls\n", GetMessageForHresult(hr)); + TRACE("LookupPrivilegeValue() failed: %ls\n", GetMessageForHresult(hr)); + goto end; + } - // Try ExitWindowsEx instead - // Win2k: Use ExitWindowsEx, which is only guaranteed to work for the current logged in user - if (!ExitWindowsEx(EWX_REBOOT | EWX_RESTARTAPPS | EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX)) { + // Ask the system nicely to give us shutdown privilege + TOKEN_PRIVILEGES privileges; + privileges.PrivilegeCount = 1; + privileges.Privileges[0].Luid = shutdownLuid; + privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (!AdjustTokenPrivileges(token, FALSE, &privileges, 0, NULL, NULL)) { + hr = AtlHresultFromLastError(); + TRACE("AdjustTokenPrivileges() failed: %ls\n", GetMessageForHresult(hr)); + goto end; + } + + // Reboot with reason "Operating System: Security fix (Unplanned)", ensuring to install updates. + // Try InitiateShutdown first (Vista+) + _InitiateShutdownW $InitiateShutdownW = (_InitiateShutdownW)GetProcAddress(GetModuleHandle(L"advapi32.dll"), "InitiateShutdownW"); + if ($InitiateShutdownW) { + hr = HRESULT_FROM_WIN32($InitiateShutdownW(NULL, NULL, 0, SHUTDOWN_RESTART | SHUTDOWN_INSTALL_UPDATES, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX)); + } + + // Try InitiateSystemShutdownEx (2k/XP) + if (!SUCCEEDED(hr)) { + TRACE("InitiateShutdown() failed: %ls\n", GetMessageForHresult(hr)); + + if (InitiateSystemShutdownEx(NULL, NULL, 0, FALSE, TRUE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX) == 0) { hr = AtlHresultFromLastError(); - TRACE("ExitWindowsEx() failed: %ls\n", GetMessageForHresult(hr)); + TRACE("InitiateSystemShutdownExW() failed: %ls\n", GetMessageForHresult(hr)); } - } else { - hr = S_OK; + } + + // Last-ditch attempt ExitWindowsEx (only guaranteed to work for the current logged in user) + if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX)) { + hr = AtlHresultFromLastError(); + TRACE("ExitWindowsEx() failed: %ls\n", GetMessageForHresult(hr)); + } + +end: + if (token) { + CloseHandle(token); } return hr; diff --git a/LegacyUpdate/Utils.h b/LegacyUpdate/Utils.h index 6d623a1..8bb63c7 100644 --- a/LegacyUpdate/Utils.h +++ b/LegacyUpdate/Utils.h @@ -1,15 +1,5 @@ #pragma once -OSVERSIONINFOEX *GetVersionInfo(); - -void GetOwnFileName(LPWSTR *filename, LPDWORD size); -HRESULT GetOwnVersion(LPWSTR *version, LPDWORD size); - -HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, LPDWORD type, LPWSTR *data, LPDWORD size); -HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, LPDWORD type, LPDWORD data); - -LPWSTR GetMessageForHresult(HRESULT hresult); - -HRESULT GetOSProductName(VARIANT* pProductName); +HRESULT GetOSProductName(LPVARIANT productName); HRESULT Reboot(); diff --git a/LegacyUpdate/dlldatax.c b/LegacyUpdate/dlldatax.c index 74878f6..3c4a30d 100644 --- a/LegacyUpdate/dlldatax.c +++ b/LegacyUpdate/dlldatax.c @@ -4,7 +4,7 @@ #define REGISTER_PROXY_DLL //DllRegisterServer, etc. -#define _WIN32_WINNT 0x0500 //for WinNT 4.0 or Win95 with DCOM +#define _WIN32_WINNT _WIN32_WINNT_WIN2K //for WinNT 4.0 or Win95 with DCOM #define USE_STUBLESS_PROXY //defined only with MIDL switch /Oicf #pragma comment(lib, "rpcns4.lib") diff --git a/LegacyUpdate/dllmain.cpp b/LegacyUpdate/dllmain.cpp index 78c4a7a..9e32cdc 100644 --- a/LegacyUpdate/dllmain.cpp +++ b/LegacyUpdate/dllmain.cpp @@ -1,10 +1,14 @@ // dllmain.cpp : Implementation of DLL Exports. #include "stdafx.h" -#include "resource.h" #include "LegacyUpdate_i.h" #include "dllmain.h" + +#include + #include "dlldatax.h" +#include "Registry.h" +#include "LegacyUpdate.h" CLegacyUpdateModule _AtlModule; HINSTANCE g_hInstance; @@ -17,13 +21,13 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpRes #endif switch (dwReason) { - case DLL_PROCESS_ATTACH: - g_hInstance = hInstance; - break; + case DLL_PROCESS_ATTACH: + g_hInstance = hInstance; + break; - case DLL_PROCESS_DETACH: - g_hInstance = NULL; - break; + case DLL_PROCESS_DETACH: + g_hInstance = NULL; + break; } return _AtlModule.DllMain(dwReason, lpReserved); @@ -57,10 +61,42 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { STDAPI DllRegisterServer(void) { // registers object, typelib and all interfaces in typelib HRESULT hr = _AtlModule.DllRegisterServer(); -#ifdef _MERGE_PROXYSTUB - if (FAILED(hr)) { + if (!SUCCEEDED(hr)) { return hr; } + + // Fix the icon path + HKEY subkey; + hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID\\{84F517AD-6438-478F-BEA8-F0B808DC257F}\\Elevation", 0, KEY_WRITE, &subkey)); + if (!SUCCEEDED(hr)) { + return hr; + } + + LPWSTR installPath; + hr = GetInstallPath(&installPath); + if (!SUCCEEDED(hr)) { + return hr; + } + + WCHAR iconRef[512]; + hr = StringCchPrintf((LPWSTR)&iconRef, ARRAYSIZE(iconRef), L"@%ls\\LegacyUpdate.exe,-100", installPath); + LocalFree(installPath); + if (!SUCCEEDED(hr)) { + return hr; + } + + hr = HRESULT_FROM_WIN32(RegSetValueEx(subkey, L"IconReference", 0, REG_SZ, (LPBYTE)iconRef, (DWORD)(lstrlen(iconRef) + 1) * sizeof(TCHAR))); + if (!SUCCEEDED(hr)) { + return hr; + } + + hr = RegCloseKey(subkey); + +#ifdef _MERGE_PROXYSTUB + if (!SUCCEEDED(hr)) { + return hr; + } + hr = PrxDllRegisterServer(); #endif return hr; diff --git a/LegacyUpdate/targetver.h b/LegacyUpdate/targetver.h index 36dec11..bb1ce9f 100644 --- a/LegacyUpdate/targetver.h +++ b/LegacyUpdate/targetver.h @@ -2,10 +2,10 @@ #if _MSC_VER > 1599 // VC17: Windows XP - #define WINVER 0x0501 - #define _WIN32_WINNT 0x0501 + #define WINVER _WIN32_WINNT_WINXP + #define _WIN32_WINNT _WIN32_WINNT_WINXP #else // VC08: Windows 2000 RTM - #define WINVER 0x0500 - #define _WIN32_WINNT 0x0500 + #define WINVER _WIN32_WINNT_WIN2K + #define _WIN32_WINNT _WIN32_WINNT_WIN2K #endif diff --git a/Makefile b/Makefile index 089b774..845a4b5 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,19 @@ +export CI ?= 0 export SIGN ?= 0 - -SUBPROJECTS = LegacyUpdate nsisplugin setup +export DEBUG ?= 1 all: - set -e; \ - for i in $(SUBPROJECTS); do \ - $(MAKE) -C $$i; \ - done +ifeq ($(DEBUG),0) + +$(MAKE) clean +endif + + +$(MAKE) -C LegacyUpdate + +$(MAKE) -C launcher + +$(MAKE) -C setup clean: - set -e; \ - for i in $(SUBPROJECTS); do \ - $(MAKE) -C $$i clean; \ - done + +$(MAKE) -C LegacyUpdate clean + +$(MAKE) -C launcher clean + +$(MAKE) -C setup clean .PHONY: all clean diff --git a/README.md b/README.md index 853729f..536bb56 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,121 @@ -# [WUIsBack](http://vichingo455.atwebpages.com/) +# [Legacy Update](http://legacyupdate.net/) -[![WUIsBack Nightly AutoBuilder](https://github.com/usefulstuffs/WUIsBack/actions/workflows/nightly.yml/badge.svg)](https://github.com/usefulstuffs/WUIsBack/actions/workflows/nightly.yml) +[![wakatime](https://wakatime.com/badge/user/b9fcf8ba-3fce-41a4-a480-d3fe6074a1ad/project/c9516ff1-10b9-41da-82fb-b86b24b0acc8.svg)](https://wakatime.com/badge/user/b9fcf8ba-3fce-41a4-a480-d3fe6074a1ad/project/c9516ff1-10b9-41da-82fb-b86b24b0acc8) +[![Build](https://github.com/LegacyUpdate/LegacyUpdate/actions/workflows/build.yml/badge.svg)](https://github.com/LegacyUpdate/LegacyUpdate/actions/workflows/build.yml) -Since Windows XP was discontinued in 2014, followed by Windows 7 in 2020, Microsoft’s support for their earlier OSes has significantly dwindled. As XP and earlier don’t officially support modern security improvements, such as the SHA256 hash algorithm required by modern SSL and Authenticode certificates [as of 2019](https://support.microsoft.com/en-us/topic/2019-sha-2-code-signing-support-requirement-for-windows-and-wsus-64d1c82d-31ee-c273-3930-69a4cde8e64f), much of the internet has become inaccessible to these devices. Adding insult to injury, Microsoft [actively removed](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/sha-1-windows-content-to-be-retired-august-3-2020/ba-p/1544373) many downloads for XP and earlier versions in 2020. In effect, working with these OSes is now incredibly difficult. +Since Windows XP was discontinued in 2014, followed by Windows 7 in 2020, Microsoft has closed services they depend on, such as Windows Update. There are also design flaws with these earlier versions of Windows Update, which make them difficult to get working on new installations. -To address this, [**WUIsBack**](http://vichingo455.atwebpages.com) hosts a patched instance of the Windows Update website. This works because the original Windows Update website simply accesses an ActiveX control that connects to the Windows Update service running on your computer. +Legacy Update can install all relevant updates necessary to fix access to the Windows Update service on unsupported versions of Windows. These versions of Windows may display the error “Windows could not search for new updates: Windows Update encountered an unknown error” with error code **80072EFE**, or may simply never finish checking for updates. Legacy Update identifies the updates your system lacks, and installs them automatically, restoring the Windows Update service to full functionality. + +Windows Update provides many optional and recommended updates, in addition to drivers for your system, but Windows XP and 2000 can only install critical security updates through the built-in Automatic Updates feature. **Legacy Update** revives the original Windows Update website - the only way to see and install every update available for your system. Legacy Update also restores access to **Windows Ultimate Extras** on Windows Vista Ultimate. + +Legacy Update also restores connectivity to some websites in Internet Explorer, and other programs that use the Windows built-in networking functionality. This includes **Windows Product Activation** on Windows XP and Windows Server 2003, allowing you to activate these versions of Windows online in seconds (a legitimate product key is [still required](https://legacyupdate.net/faq/security)). + +Just want to appreciate the nostalgia of the classic Windows Update website? Legacy Update can also be installed on Windows 10 and 11. This works even on versions of these OSes that have removed Internet Explorer. Legacy Update won’t modify your Windows 10 or 11 installation. + +> *If this website helped you to update your old PCs, please consider [leaving a tip](https://ko-fi.com/adamdemasi) to help me pay for the server costs. Thank you!* ## Download -Download the latest version from the [official website](http://vichingo455.atwebpages.com/) -You can also download the [latest nightly build](https://nightly.link/usefulstuffs/WUIsBack/workflows/nightly/main/WUIsBack-nightly.zip), based on the current development work. Nightly builds are not guaranteed to be stable, and unlike release builds, require at least Windows 2000 SP4 or Windows XP SP2. You may also need to accept extra SmartScreen and other security warnings since these executables are unique to each build. If you’re not sure what to download, you probably want the [stable release](http://vichingo455.atwebpages.com/). +Download the latest version from the [Releases](https://github.com/LegacyUpdate/LegacyUpdate/releases) page of this repo, or from [**legacyupdate.net**](https://legacyupdate.net/). + +You can also download the [latest nightly build](https://nightly.link/LegacyUpdate/LegacyUpdate/workflows/build/main/artifact.zip), based on the current development work. Nightly builds are not guaranteed to be stable, and unlike release builds, require at least Windows 2000 SP4 or Windows XP SP2. You may also need to accept extra SmartScreen and other security warnings since these executables are unique to each build. If you’re not sure what to download, you probably want the [stable release](https://legacyupdate.net/). ## The ActiveX Control -This repo hosts an ActiveX control used as a replica of the original one developed by Microsoft for the official Windows Update website. The original version of Legacy Update required using a proxy autoconfiguration file (.pac) and some additional configuration of IE security settings to intercept requests to the **update.microsoft.com** site, because the Microsoft Wuweb.dll control validates that it is being used on the official update.microsoft.com domain. With the custom Legacy Update ActiveX control, proxying is no longer required, because we have full control over the validation logic. This also allows adding additional convenient features not possible with JavaScript alone. + +This repo hosts an ActiveX control used as a replica of the original one developed by Microsoft for the official Windows Update website. The original version of Legacy Update required using a proxy autoconfiguration file (.pac) and some additional configuration of Internet Explorer security settings to intercept requests to the **update.microsoft.com** domain, because the Microsoft Wuweb.dll control has safety measures ensuring it can only be used by the official update.microsoft.com domain. With the custom Legacy Update ActiveX control, proxying is no longer required, because we have full control over the validation logic. + +This also allows us to extend it with convenient features not possible with JavaScript alone. Particularly, we have “forward-ported” the control to add support for Windows Vista and later, which introduces extra challenges such as User Account Control (UAC) and Internet Explorer’s Protected Mode. ### Building -The project can be built on Windows 10/11 with [WSL 2](https://aka.ms/wslinstall) installed. You’ll ideally want to also set up an XP VM for testing. + +The project is built on Windows 10/11 with [WSL 2](https://aka.ms/wslinstall). You can test much of the project using your running version of Windows, although for best results you should test using a virtual machine of Windows XP, Windows Vista, and Windows 7. Take snapshots of your VMs - this will make it far easier to test update scenarios. You will need to install: -* [Visual Studio](https://visualstudio.microsoft.com/vs/) - select the following individual components: - * Desktop development with C++ - * C++ Windows XP Support for VS 2017 (v141) tools - * C++ ATL for v141 build tools (x86 & x64) -* [Visual Studio 2008](https://my.visualstudio.com/Downloads?q=Visual%20Studio%20Express%202008%20with%20Service%20Pack%201&pgroup=) for compiling a build that works on XP RTM and 2000 SP4 - not required if you only want to build for XP SP2 and later (Visual Studio 2010 might be required also for VS to detect Visual Studio 2008) -* [NSIS](https://nsis.sourceforge.io/) +* On Windows: + * [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) - select the following individual components: + * Desktop development with C++ + * C++ Windows XP Support for VS 2017 (v141) tools + * C++ ATL for v141 build tools (x86 & x64) + * C++/CLI support for v141 build tools (14.16) + * [Visual Studio 2008 SP1](https://my.visualstudio.com/Downloads?q=Visual%20Studio%20Express%202008%20with%20Service%20Pack%201&pgroup=) for compiling a build that works on XP RTM and 2000 SP4 - not required if you only want to build for XP SP2 and later + * You will also need [Visual Studio 2010](https://my.visualstudio.com/Downloads?q=Visual%20Studio%202010&pgroup=), which provides bridging from 2008’s VSBuild system to the modern MSBuild. +* On Linux: + * [MinGW-w64](https://www.mingw-w64.org/) for i686 and x86_64 + * [NSIS](https://nsis.sourceforge.io/) + * [UPX](https://upx.github.io/) -In the WSL environment, run the following command to install build dependencies. This command is for Ubuntu - if you use a different distro, you will need to find and install the equivalent packages from your package manager. +Run the following command to install Linux build dependencies. This command specific to Ubuntu - if you use a different distro, you will need to find and install the equivalent packages from your package manager. ```bash -sudo apt install make nsis nsis-pluginapi mingw-w64-i686-dev +sudo apt install make nsis upx-ucl mingw-w64-i686-dev mingw-w64-x86-64-dev ``` -You will also need to extract a copy of updroots.exe from [this update](http://download.windowsupdate.com/d/msdownload/update/software/secu/2015/03/rvkroots_3f2ce4676450c06f109b5b4e68bec252873ccc21.exe). You can do this manually using 7-Zip, placing the exe at `setup/updroots.exe`, or run the following in WSL: +If you use Debian/Ubuntu’s build of NSIS, please note that it is compiled for Pentium II and later, and will fail to launch on Pentium, AMD K6, and other CPUs lacking SSE instructions. If you want to support these CPUs, run `./build/fix-nsis.sh` to patch the NSIS exehead binaries with a build that supports these CPUs. -```bash -sudo apt install cabextract -curl -L http://download.windowsupdate.com/d/msdownload/update/software/secu/2015/03/rvkroots_3f2ce4676450c06f109b5b4e68bec252873ccc21.exe -o /tmp/rvkroots.exe -cabextract -d setup -F updroots.exe /tmp/rvkroots.exe -rm /tmp/rvkroots.exe -``` +When opening the solution for the first time in Visual Studio 2022, it will suggest to retarget it against the latest Windows SDK. Cancel this dialog. -When opening the solution for the first time, Visual Studio will ask if you want to retarget it against the latest Windows SDK. Select No Upgrade. +If you get “unexpected precompiled header error” when building, install [KB976656](https://content.legacyupdate.net/support.microsoft.com/kb/976656/VS90SP1-KB976656-x86.exe), or merge `build\fix-vc08-aslr.reg`, which disables ASLR for `cl.exe`. ### Testing -For debugging, if running on XP with IE8, install [Utilu IE Collection](https://www.utilu.com/iecollection/). IE6/IE7 is much more useful for debugging the native code, because of its simplistic single-process model. Visual Studio is able to launch it and directly attach to the process the code is running in. + +For debugging, if running on Windows XP with IE8, consider installing [Utilu IE Collection](https://www.utilu.com/iecollection/). IE6/IE7 are more convenient for debugging the native code because of their simplistic single-process model. Visual Studio is able to launch it and directly attach to the process the code is running in. Otherwise, you will need to manually find and attach the debugger to the IE child process hosting the website and ActiveX control. To configure the debugger: -1. Right click LegacyUpdate in the Solution Explorer → Properties +1. Right-click LegacyUpdate in the Solution Explorer → Properties 2. In the Debugging tab, set the Command field to: - * For system IE install: `$(ProgramW6432)\Internet Explorer\iexplore.exe` - * For Utilu IE6 RTM: `$(ProgramW6432)\Utilu IE Collection\IE600\iexplore.exe` - * For Utilu IE6 SP2: `$(ProgramW6432)\Utilu IE Collection\IE600XPSP2\iexplore.exe` - * For Utilu IE7: `$(ProgramW6432)\Utilu IE Collection\IE700\iexplore.exe` -3. Set the Command Arguments field to `http://legacyupdate.net/windowsupdate/v6/`, or any other URL you want to use for debugging -4. If running on XP, in the Debugger tab, set Register Output to Yes. - If running on Vista or later, this will throw a permission denied error due to UAC. You’ll need to manually register the control using `regsvr32 LegacyUpdate.dll` in an administrator command prompt. + * For system IE install: `$(ProgramW6432)\Internet Explorer\iexplore.exe` + * For Utilu IE6 RTM: `$(ProgramW6432)\Utilu IE Collection\IE600\iexplore.exe` + * For Utilu IE6 SP2: `$(ProgramW6432)\Utilu IE Collection\IE600XPSP2\iexplore.exe` + * For Utilu IE7: `$(ProgramW6432)\Utilu IE Collection\IE700\iexplore.exe` + * For PowerShell: `$(SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe` (or SysWOW64 to test the 32-bit build on 64-bit Windows) +3. If using IE, set the Command Arguments field to `http://legacyupdate.net/windowsupdate/v6/`, or any other URL you want to use for debugging +4. In the Debugger tab, set Register Output to Yes. (If running on Windows Vista or later, start Visual Studio as administrator to ensure the rights needed for this.) + +You can directly test the ActiveX control using PowerShell: + +```powershell +PS> $lu = New-Object -ComObject LegacyUpdate.Control +PS> $lu.CheckControl() +True +``` + +If set up correctly, `CheckControl()` should return `True`. This is only supported in debug builds - release builds throw `E_ACCESSDENIED`. + +## Setup and Launcher + +Legacy Update makes use of the [Nullsoft Scriptable Install System](https://nsis.sourceforge.io/) (NSIS) for its setup program. NSIS provides a scripting language we use to install prerequisite updates. We extend NSIS with a custom plugin to provide features that improve the setup user experience. + +As of 1.10, Legacy Update includes a “launcher” program, responsible for tasks including launching the website in Internet Explorer, repairing a broken installation of Legacy Update, and continuing setup when the system restarts into Winlogon “setup mode”. + +Both are compiled using MinGW-w64 and are written in C to keep things simple. ## Website source code -I haven’t yet open sourced the website. This is because the vast majority of it is Microsoft code - just with a handful of patches I’ve made to remove Microsoft trademark branding, switch it to the Legacy Update ActiveX control, and make some slight bug fixes/improvements. It doesn’t feel appropriate to put an open source license on something I don’t own. However, if you would like to review it, you can right click → View Source on the website and take a poke around, mainly in the JavaScript files. You might find [DebugBar](https://www.debugbar.com/download.php) and [CompanionJS](https://www.my-debugbar.com/wiki/CompanionJS/HomePage) (requires Visual Studio or standalone [Microsoft Script Debugger](https://web.archive.org/web/20131113042519/http://download.microsoft.com/download/7/7/d/77d8df05-6fbc-4718-a319-be14317a6811/scd10en.exe)) useful. -I’ve tinkered with writing a [ground-up replacement](https://twitter.com/hbkirb/status/1584537446716350466) of the Microsoft-developed Windows Update website, which I’ll open source when I feel it’s ready for public use (there are currently a number of bugs and missing features). +I haven’t yet open sourced the website. This is because much of it is Microsoft code - just with patches I’ve made to remove Microsoft trademark branding, switch it to the Legacy Update ActiveX control, and make some quality-of-life improvements. It doesn’t feel appropriate to put an open source license on something I don’t own. Since it’s almost entirely client-side HTML and JavaScript, you can still review it by poking around the source on the website. You might find [DebugBar](https://www.debugbar.com/download.php) and [CompanionJS](https://www.my-debugbar.com/wiki/CompanionJS/HomePage) (requires Visual Studio or standalone [Microsoft Script Debugger](https://web.archive.org/web/20131113042519/http://download.microsoft.com/download/7/7/d/77d8df05-6fbc-4718-a319-be14317a6811/scd10en.exe)) useful. + +I’ve tinkered with writing a [ground-up replacement](https://twitter.com/hbkirb/status/1584537446716350466) of the Microsoft-developed Windows Update website. I haven’t worked on this in a while, but I’ll open source it when I feel it’s ready enough. ## Disclaimer + The existence of this project shouldn’t be taken as an endorsement to continue using unsupported OSes. You should stick to a supported OS such as Windows 10 or 11 (or, try Linux?!). However, this service exists anyway in recognition that using these OSes is sometimes necessary to run legacy hardware/software, or just interesting to play around with. This project is not affiliated with or endorsed by Microsoft. This software is provided “as is”, without warranty of any kind. We don’t believe anything should go wrong, but please ensure you have backups of any important data anyway. +## Credits + +Legacy Update was started and is primarily developed by [Adam Demasi (@kirb)](https://kirb.me/), with contributions from: + +* [Douglas R. Reno (@renodr)](https://github.com/renodr): Build system improvements and other project maintenance. Check out his awesome work on [Linux From Scratch](https://www.linuxfromscratch.org/)! +* [@stdin82](https://github.com/stdin82): Helped us find some patches on the Windows Update server, and other general help on the issue trackerf +* The [Windows Update Restored](https://windowsupdaterestored.com/) team: [@CaptainTER06](https://github.com/CaptainTER06), [@TheOneGoofAli](https://github.com/TheOneGoofAli), [et al.](https://windowsupdaterestored.com/) + +We make use of some portions of the Windows SDK, [MinGW-w64](https://www.mingw-w64.org/), and [NSIS](https://nsis.sourceforge.io/). + ## License -Licensed under the Apache License, version 2.0. Refer to [LICENSE.md](https://github.com/usefulstuffs/WUIsBack/blob/main/LICENSE.md). -The repository includes a compiled copy of my fork of [NSxfer](https://github.com/kirb/nsis-nsxfer), licensed under the [zlib/libpng license](https://github.com/kirb/nsis-nsxfer/blob/master/LICENSE). +Licensed under the Apache License, version 2.0. Refer to [LICENSE.md](https://github.com/LegacyUpdate/LegacyUpdate/blob/main/LICENSE.md). -Some rights go to [kirb](https://github.com/kirb) for the original project [Legacy Update](https://legacyupdate.net) which gave me the idea to start this. +The repository includes some portions of NSIS, licensed under the [zlib/libpng license](https://nsis.sourceforge.io/License). It also includes a compiled copy of my fork of [NSxfer](https://github.com/kirb/nsis-nsxfer), licensed under the [zlib/libpng license](https://github.com/kirb/nsis-nsxfer/blob/master/LICENSE). diff --git a/include/atlcomcli.h b/include/atlcomcli.h deleted file mode 100644 index e765574..0000000 --- a/include/atlcomcli.h +++ /dev/null @@ -1,959 +0,0 @@ -/* - * ReactOS ATL - * - * Copyright 2009 Andrew Hill - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "atlcore.h" - - -#ifdef _MSC_VER -// It is common to use this in ATL constructors. They only store this for later use, so the usage is safe. -#pragma warning(disable:4355) -#endif - -#ifndef _ATL_PACKING -#define _ATL_PACKING 8 -#endif - -#ifndef _ATL_FREE_THREADED -#ifndef _ATL_APARTMENT_THREADED -#ifndef _ATL_SINGLE_THREADED -#define _ATL_FREE_THREADED -#endif -#endif -#endif - -#ifndef ATLTRY -#define ATLTRY(x) x; -#endif - -#ifdef _ATL_DISABLE_NO_VTABLE -#define ATL_NO_VTABLE -#else -#define ATL_NO_VTABLE __declspec(novtable) -#endif - -namespace ATL -{ - -inline HRESULT AtlHresultFromLastError() throw() -{ - DWORD dwError = ::GetLastError(); - return HRESULT_FROM_WIN32(dwError); -} - -template -class _NoAddRefReleaseOnCComPtr : public T -{ - private: - virtual ULONG STDMETHODCALLTYPE AddRef() = 0; - virtual ULONG STDMETHODCALLTYPE Release() = 0; -}; - -// Begin code borrowed from Microsoft -//CComPtrBase provides the basis for all other smart pointers -//The other smartpointers add their own constructors and operators -template -class CComPtrBase -{ -protected: - CComPtrBase() throw() - { - p = NULL; - } - CComPtrBase(_Inout_opt_ T* lp) throw() - { - p = lp; - if (p != NULL) - p->AddRef(); - } - void Swap(CComPtrBase& other) - { - T* pTemp = p; - p = other.p; - other.p = pTemp; - } -public: - typedef T _PtrClass; - ~CComPtrBase() throw() - { - if (p) - p->Release(); - } - operator T*() const throw() - { - return p; - } - T& operator*() const - { - ATLENSURE(p!=NULL); - return *p; - } - //The assert on operator& usually indicates a bug. If this is really - //what is needed, however, take the address of the p member explicitly. - T** operator&() throw() - { - ATLASSERT(p==NULL); - return &p; - } - _NoAddRefReleaseOnCComPtr* operator->() const throw() - { - ATLASSERT(p!=NULL); - return (_NoAddRefReleaseOnCComPtr*)p; - } - bool operator!() const throw() - { - return (p == NULL); - } - bool operator<(_In_opt_ T* pT) const throw() - { - return p < pT; - } - bool operator!=(_In_opt_ T* pT) const - { - return !operator==(pT); - } - bool operator==(_In_opt_ T* pT) const throw() - { - return p == pT; - } - - // Release the interface and set to NULL - void Release() throw() - { - T* pTemp = p; - if (pTemp) - { - p = NULL; - pTemp->Release(); - } - } - // Compare two objects for equivalence - inline bool IsEqualObject(_Inout_opt_ IUnknown* pOther) throw(); - - // Attach to an existing interface (does not AddRef) - void Attach(_In_opt_ T* p2) throw() - { - if (p) - { - ULONG ref = p->Release(); - (ref); - // Attaching to the same object only works if duplicate references are being coalesced. Otherwise - // re-attaching will cause the pointer to be released and may cause a crash on a subsequent dereference. - ATLASSERT(ref != 0 || p2 != p); - } - p = p2; - } - // Detach the interface (does not Release) - T* Detach() throw() - { - T* pt = p; - p = NULL; - return pt; - } - _Check_return_ HRESULT CopyTo(_COM_Outptr_result_maybenull_ T** ppT) throw() - { - ATLASSERT(ppT != NULL); - if (ppT == NULL) - return E_POINTER; - *ppT = p; - if (p) - p->AddRef(); - return S_OK; - } - _Check_return_ HRESULT SetSite(_Inout_opt_ IUnknown* punkParent) throw() - { - return AtlSetChildSite(p, punkParent); - } - _Check_return_ HRESULT Advise( - _Inout_ IUnknown* pUnk, - _In_ const IID& iid, - _Out_ LPDWORD pdw) throw() - { - return AtlAdvise(p, pUnk, iid, pdw); - } - _Check_return_ HRESULT CoCreateInstance( - _In_ REFCLSID rclsid, - _Inout_opt_ LPUNKNOWN pUnkOuter = NULL, - _In_ DWORD dwClsContext = CLSCTX_ALL) throw() - { - ATLASSERT(p == NULL); - return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); - } -#ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP - _Check_return_ HRESULT CoCreateInstance( - _In_z_ LPCOLESTR szProgID, - _Inout_opt_ LPUNKNOWN pUnkOuter = NULL, - _In_ DWORD dwClsContext = CLSCTX_ALL) throw() - { - CLSID clsid; - HRESULT hr = CLSIDFromProgID(szProgID, &clsid); - ATLASSERT(p == NULL); - if (SUCCEEDED(hr)) - hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p); - return hr; - } -#endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP - template - _Check_return_ HRESULT QueryInterface(_Outptr_ Q** pp) const throw() - { - ATLASSERT(pp != NULL); - return p->QueryInterface(__uuidof(Q), (void**)pp); - } - T* p; -}; -// End code borrowed from Microsoft - -template -class CComPtr : - public CComPtrBase -{ -public: - T *p; -public: - CComPtr() - { - p = NULL; - } - - CComPtr(T *lp) - { - p = lp; - if (p != NULL) - p->AddRef(); - } - - CComPtr(const CComPtr &lp) - { - p = lp.p; - if (p != NULL) - p->AddRef(); - } - - ~CComPtr() - { - if (p != NULL) - p->Release(); - } - - T *operator = (T *lp) - { - T* pOld = p; - - p = lp; - if (p != NULL) - p->AddRef(); - - if (pOld != NULL) - pOld->Release(); - - return *this; - } - - T *operator = (const CComPtr &lp) - { - T* pOld = p; - - p = lp.p; - if (p != NULL) - p->AddRef(); - - if (pOld != NULL) - pOld->Release(); - - return *this; - } - - // We cannot enable this until gcc starts supporting __uuidof - // See CORE-12710 -#if 0 - template - T* operator=(const CComPtr& lp) - { - T* pOld = p; - - if (!lp.p || FAILED(lp.p->QueryInterface(__uuidof(T), (void**)(IUnknown**)&p))) - p = NULL; - - if (pOld != NULL) - pOld->Release(); - - return *this; - } -#endif - - void Release() - { - if (p != NULL) - { - p->Release(); - p = NULL; - } - } - - void Attach(T *lp) - { - if (p != NULL) - p->Release(); - p = lp; - } - - T *Detach() - { - T *saveP; - - saveP = p; - p = NULL; - return saveP; - } - - T **operator & () - { - ATLASSERT(p == NULL); - return &p; - } - - operator T * () - { - return p; - } - - _NoAddRefReleaseOnCComPtr *operator -> () const - { - ATLASSERT(p != NULL); - return (_NoAddRefReleaseOnCComPtr *)p; - } -}; - -// Begin code borrowed from Microsoft -//specialization for IDispatch -template <> -class CComPtr : - public CComPtrBase -{ -public: - CComPtr() throw() - { - } - CComPtr(_Inout_opt_ IDispatch* lp) throw() : - CComPtrBase(lp) - { - } - CComPtr(_Inout_ const CComPtr& lp) throw() : - CComPtrBase(lp.p) - { - } - IDispatch* operator=(_Inout_opt_ IDispatch* lp) throw() - { - if(*this!=lp) - { - CComPtr(lp).Swap(*this); - } - return *this; - } - IDispatch* operator=(_Inout_ const CComPtr& lp) throw() - { - if(*this!=lp) - { - CComPtr(lp).Swap(*this); - } - return *this; - } - CComPtr(_Inout_ CComPtr&& lp) throw() : - CComPtrBase() - { - this->p = lp.p; - lp.p = NULL; - } - IDispatch* operator=(_Inout_ CComPtr&& lp) throw() - { - CComPtr(static_cast(lp)).Swap(*this); - return *this; - } - _Check_return_ HRESULT GetPropertyByName( - _In_z_ LPCOLESTR lpsz, - _Out_ VARIANT* pVar) throw() - { - ATLASSERT(this->p); - ATLASSERT(pVar); - DISPID dwDispID; - HRESULT hr = GetIDOfName(lpsz, &dwDispID); - if (SUCCEEDED(hr)) - hr = GetProperty(dwDispID, pVar); - return hr; - } - _Check_return_ HRESULT GetProperty( - _In_ DISPID dwDispID, - _Out_ VARIANT* pVar) throw() - { - return GetProperty(this->p, dwDispID, pVar); - } - _Check_return_ HRESULT PutPropertyByName( - _In_z_ LPCOLESTR lpsz, - _In_ VARIANT* pVar) throw() - { - ATLASSERT(this->p); - ATLASSERT(pVar); - DISPID dwDispID; - HRESULT hr = GetIDOfName(lpsz, &dwDispID); - if (SUCCEEDED(hr)) - hr = PutProperty(dwDispID, pVar); - return hr; - } - _Check_return_ HRESULT PutProperty( - _In_ DISPID dwDispID, - _In_ VARIANT* pVar) throw() - { - return PutProperty(this->p, dwDispID, pVar); - } - _Check_return_ HRESULT GetIDOfName( - _In_z_ LPCOLESTR lpsz, - _Out_ DISPID* pdispid) throw() - { - return this->p->GetIDsOfNames(IID_NULL, const_cast(&lpsz), 1, LOCALE_USER_DEFAULT, pdispid); - } - // Invoke a method by DISPID with no parameters - _Check_return_ HRESULT Invoke0( - _In_ DISPID dispid, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - DISPPARAMS dispparams = { NULL, NULL, 0, 0}; - return this->p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL); - } - // Invoke a method by name with no parameters - _Check_return_ HRESULT Invoke0( - _In_z_ LPCOLESTR lpszName, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - HRESULT hr; - DISPID dispid; - hr = GetIDOfName(lpszName, &dispid); - if (SUCCEEDED(hr)) - hr = Invoke0(dispid, pvarRet); - return hr; - } - // Invoke a method by DISPID with a single parameter - _Check_return_ HRESULT Invoke1( - _In_ DISPID dispid, - _In_ VARIANT* pvarParam1, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - DISPPARAMS dispparams = { pvarParam1, NULL, 1, 0}; - return this->p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL); - } - // Invoke a method by name with a single parameter - _Check_return_ HRESULT Invoke1( - _In_z_ LPCOLESTR lpszName, - _In_ VARIANT* pvarParam1, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - DISPID dispid; - HRESULT hr = GetIDOfName(lpszName, &dispid); - if (SUCCEEDED(hr)) - hr = Invoke1(dispid, pvarParam1, pvarRet); - return hr; - } - // Invoke a method by DISPID with two parameters - _Check_return_ HRESULT Invoke2( - _In_ DISPID dispid, - _In_ VARIANT* pvarParam1, - _In_ VARIANT* pvarParam2, - _Out_opt_ VARIANT* pvarRet = NULL) throw(); - // Invoke a method by name with two parameters - _Check_return_ HRESULT Invoke2( - _In_z_ LPCOLESTR lpszName, - _In_ VARIANT* pvarParam1, - _In_ VARIANT* pvarParam2, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - DISPID dispid; - HRESULT hr = GetIDOfName(lpszName, &dispid); - if (SUCCEEDED(hr)) - hr = Invoke2(dispid, pvarParam1, pvarParam2, pvarRet); - return hr; - } - // Invoke a method by DISPID with N parameters - _Check_return_ HRESULT InvokeN( - _In_ DISPID dispid, - _In_ VARIANT* pvarParams, - _In_ int nParams, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - DISPPARAMS dispparams = {pvarParams, NULL, (unsigned int)nParams, 0}; - return this->p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL); - } - // Invoke a method by name with Nparameters - _Check_return_ HRESULT InvokeN( - _In_z_ LPCOLESTR lpszName, - _In_ VARIANT* pvarParams, - _In_ int nParams, - _Out_opt_ VARIANT* pvarRet = NULL) throw() - { - HRESULT hr; - DISPID dispid; - hr = GetIDOfName(lpszName, &dispid); - if (SUCCEEDED(hr)) - hr = InvokeN(dispid, pvarParams, nParams, pvarRet); - return hr; - } - - _Check_return_ static HRESULT PutProperty( - _In_ IDispatch* pDispatch, - _In_ DISPID dwDispID, - _In_ VARIANT* pVar) throw() - { - ATLASSERT(pDispatch); - ATLASSERT(pVar != NULL); - if (pVar == NULL) - return E_POINTER; - - if (pDispatch == NULL) - return E_INVALIDARG; - - DISPPARAMS dispparams = {NULL, NULL, 1, 1}; - dispparams.rgvarg = pVar; - DISPID dispidPut = DISPID_PROPERTYPUT; - dispparams.rgdispidNamedArgs = &dispidPut; - - if (pVar->vt == VT_UNKNOWN || pVar->vt == VT_DISPATCH || - (pVar->vt & VT_ARRAY) || (pVar->vt & VT_BYREF)) - { - HRESULT hr = pDispatch->Invoke(dwDispID, IID_NULL, - LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, - &dispparams, NULL, NULL, NULL); - if (SUCCEEDED(hr)) - return hr; - } - return pDispatch->Invoke(dwDispID, IID_NULL, - LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, - &dispparams, NULL, NULL, NULL); - } - - _Check_return_ static HRESULT GetProperty( - _In_ IDispatch* pDispatch, - _In_ DISPID dwDispID, - _Out_ VARIANT* pVar) throw() - { - ATLASSERT(pDispatch); - ATLASSERT(pVar != NULL); - if (pVar == NULL) - return E_POINTER; - - if (pDispatch == NULL) - return E_INVALIDARG; - - DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; - return pDispatch->Invoke(dwDispID, IID_NULL, - LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, - &dispparamsNoArgs, pVar, NULL, NULL); - } -}; -// End code borrowed from Microsoft - - -//CComQIIDPtr is the gcc compatible version of CComQIPtr -#define I_ID(Itype) Itype,&IID_##Itype - -template -class CComQIIDPtr : - public CComPtr -{ -public: - // Let's tell GCC how to find a symbol. - using CComPtr::p; - - CComQIIDPtr() - { - } - CComQIIDPtr(_Inout_opt_ T* lp) : - CComPtr(lp) - { - } - CComQIIDPtr(_Inout_ const CComQIIDPtr& lp): - CComPtr(lp.p) - { - } - CComQIIDPtr(_Inout_opt_ IUnknown* lp) - { - if (lp != NULL) - { - if (FAILED(lp->QueryInterface(*piid, (void**)(IUnknown**)&p))) - p = NULL; - } - } - T *operator = (T *lp) - { - T* pOld = p; - - p = lp; - if (p != NULL) - p->AddRef(); - - if (pOld != NULL) - pOld->Release(); - - return *this; - } - - T *operator = (const CComQIIDPtr &lp) - { - T* pOld = p; - - p = lp.p; - if (p != NULL) - p->AddRef(); - - if (pOld != NULL) - pOld->Release(); - - return *this; - } - - T * operator=(IUnknown* lp) - { - T* pOld = p; - - if (!lp || FAILED(lp->QueryInterface(*piid, (void**)(IUnknown**)&p))) - p = NULL; - - if (pOld != NULL) - pOld->Release(); - - return *this; - } -}; - - -class CComBSTR -{ -public: - BSTR m_str; -public: - CComBSTR() : - m_str(NULL) - { - } - - CComBSTR(LPCOLESTR pSrc) - { - if (pSrc == NULL) - m_str = NULL; - else - m_str = ::SysAllocString(pSrc); - } - - CComBSTR(int length) - { - if (length == 0) - m_str = NULL; - else - m_str = ::SysAllocStringLen(NULL, length); - } - - CComBSTR(int length, LPCOLESTR pSrc) - { - if (length == 0) - m_str = NULL; - else - m_str = ::SysAllocStringLen(pSrc, length); - } - - CComBSTR(PCSTR pSrc) - { - if (pSrc) - { - int len = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, NULL, 0); - m_str = ::SysAllocStringLen(NULL, len - 1); - if (m_str) - { - int res = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, m_str, len); - ATLASSERT(res == len); - if (res != len) - { - ::SysFreeString(m_str); - m_str = NULL; - } - } - } - else - { - m_str = NULL; - } - } - - CComBSTR(const CComBSTR &other) - { - m_str = other.Copy(); - } - - CComBSTR(REFGUID guid) - { - OLECHAR szGuid[40]; - ::StringFromGUID2(guid, szGuid, 40); - m_str = ::SysAllocString(szGuid); - } - - ~CComBSTR() - { - ::SysFreeString(m_str); - m_str = NULL; - } - - operator BSTR () const - { - return m_str; - } - - BSTR *operator & () - { - return &m_str; - } - - CComBSTR &operator = (const CComBSTR &other) - { - ::SysFreeString(m_str); - m_str = other.Copy(); - return *this; - } - - void Attach(BSTR bstr) - { - ::SysFreeString(m_str); - m_str = bstr; - } - - BSTR Detach() - { - BSTR str = m_str; - m_str = NULL; - return str; - } - - BSTR Copy() const - { - if (!m_str) - return NULL; - return ::SysAllocStringLen(m_str, ::SysStringLen(m_str)); - } - - HRESULT CopyTo(BSTR *other) const - { - if (!other) - return E_POINTER; - *other = Copy(); - return S_OK; - } - - bool LoadString(HMODULE module, DWORD uID) - { - ::SysFreeString(m_str); - m_str = NULL; - const wchar_t *ptr = NULL; - int len = ::LoadStringW(module, uID, (PWSTR)&ptr, 0); - if (len) - m_str = ::SysAllocStringLen(ptr, len); - return m_str != NULL; - } - - unsigned int Length() const - { - return ::SysStringLen(m_str); - } - - unsigned int ByteLength() const - { - return ::SysStringByteLen(m_str); - } -}; - - -class CComVariant : public tagVARIANT -{ -public: - CComVariant() - { - ::VariantInit(this); - } - - CComVariant(const CComVariant& other) - { - V_VT(this) = VT_EMPTY; - Copy(&other); - } - - ~CComVariant() - { - Clear(); - } - - CComVariant(LPCOLESTR lpStr) - { - V_VT(this) = VT_BSTR; - V_BSTR(this) = ::SysAllocString(lpStr); - } - - CComVariant(LPCSTR lpStr) - { - V_VT(this) = VT_BSTR; - CComBSTR str(lpStr); - V_BSTR(this) = str.Detach(); - } - - CComVariant(bool value) - { - V_VT(this) = VT_BOOL; - V_BOOL(this) = value ? VARIANT_TRUE : VARIANT_FALSE; - } - - CComVariant(char value) - { - V_VT(this) = VT_I1; - V_I1(this) = value; - } - - CComVariant(BYTE value) - { - V_VT(this) = VT_UI1; - V_UI1(this) = value; - } - - CComVariant(short value) - { - V_VT(this) = VT_I2; - V_I2(this) = value; - } - - CComVariant(unsigned short value) - { - V_VT(this) = VT_UI2; - V_UI2(this) = value; - } - - CComVariant(int value, VARENUM type = VT_I4) - { - if (type == VT_I4 || type == VT_INT) - { - V_VT(this) = type; - V_I4(this) = value; - } - else - { - V_VT(this) = VT_ERROR; - V_ERROR(this) = E_INVALIDARG; - } - } - - CComVariant(unsigned int value, VARENUM type = VT_UI4) - { - if (type == VT_UI4 || type == VT_UINT) - { - V_VT(this) = type; - V_UI4(this) = value; - } - else - { - V_VT(this) = VT_ERROR; - V_ERROR(this) = E_INVALIDARG; - } - } - - CComVariant(long value, VARENUM type = VT_I4) - { - if (type == VT_I4 || type == VT_ERROR) - { - V_VT(this) = type; - V_I4(this) = value; - } - else - { - V_VT(this) = VT_ERROR; - V_ERROR(this) = E_INVALIDARG; - } - } - - CComVariant(unsigned long value) - { - V_VT(this) = VT_UI4; - V_UI4(this) = value; - } - - CComVariant(float value) - { - V_VT(this) = VT_R4; - V_R4(this) = value; - } - - CComVariant(double value, VARENUM type = VT_R8) - { - if (type == VT_R8 || type == VT_DATE) - { - V_VT(this) = type; - V_R8(this) = value; - } - else - { - V_VT(this) = VT_ERROR; - V_ERROR(this) = E_INVALIDARG; - } - } - - CComVariant(const LONGLONG& value) - { - V_VT(this) = VT_I8; - V_I8(this) = value; - } - - CComVariant(const ULONGLONG& value) - { - V_VT(this) = VT_UI8; - V_UI8(this) = value; - } - - CComVariant(const CY& value) - { - V_VT(this) = VT_CY; - V_I8(this) = value.int64; - } - - - HRESULT Clear() - { - return ::VariantClear(this); - } - - HRESULT Copy(_In_ const VARIANT* src) - { - return ::VariantCopy(this, const_cast(src)); - } - - HRESULT ChangeType(_In_ VARTYPE newType, _In_opt_ const LPVARIANT src = NULL) - { - const LPVARIANT lpSrc = src ? src : this; - return ::VariantChangeType(this, lpSrc, 0, newType); - } -}; - - - -}; // namespace ATL - -#ifndef _ATL_NO_AUTOMATIC_NAMESPACE -using namespace ATL; -#endif //!_ATL_NO_AUTOMATIC_NAMESPACE diff --git a/include/atlcore.h b/include/atlcore.h deleted file mode 100644 index 26f3ced..0000000 --- a/include/atlcore.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * ReactOS ATL - * - * Copyright 2009 Andrew Hill - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include - -#ifdef __REACTOS__ - #define WIN32_NO_STATUS - #define _INC_WINDOWS - #define COM_NO_WINDOWS_H - #include - #include - #include - #include - #include -#else - #include -#endif -#include -#include -#include - -#ifndef ATLASSERT -#define ATLASSERT(expr) _ASSERTE(expr) -#endif // ATLASSERT - -namespace ATL -{ - -class CComCriticalSection -{ -public: - CRITICAL_SECTION m_sec; -public: - CComCriticalSection() - { - memset(&m_sec, 0, sizeof(CRITICAL_SECTION)); - } - - virtual ~CComCriticalSection() - { - } - - HRESULT Lock() - { - EnterCriticalSection(&m_sec); - return S_OK; - } - - HRESULT Unlock() - { - LeaveCriticalSection(&m_sec); - return S_OK; - } - - HRESULT Init() - { - InitializeCriticalSection(&m_sec); - return S_OK; - } - - HRESULT Term() - { - DeleteCriticalSection(&m_sec); - return S_OK; - } -}; - -class CComFakeCriticalSection -{ -public: - HRESULT Lock() - { - return S_OK; - } - - HRESULT Unlock() - { - return S_OK; - } - - HRESULT Init() - { - return S_OK; - } - - HRESULT Term() - { - return S_OK; - } -}; - -class CComAutoCriticalSection : public CComCriticalSection -{ -public: - CComAutoCriticalSection() - { - HRESULT hResult __MINGW_ATTRIB_UNUSED; - - hResult = CComCriticalSection::Init(); - ATLASSERT(SUCCEEDED(hResult)); - } - ~CComAutoCriticalSection() - { - CComCriticalSection::Term(); - } -}; - -class CComSafeDeleteCriticalSection : public CComCriticalSection -{ -private: - bool m_bInitialized; -public: - CComSafeDeleteCriticalSection() - { - m_bInitialized = false; - } - - ~CComSafeDeleteCriticalSection() - { - Term(); - } - - HRESULT Lock() - { - ATLASSERT(m_bInitialized); - return CComCriticalSection::Lock(); - } - - HRESULT Init() - { - HRESULT hResult; - - ATLASSERT(!m_bInitialized); - hResult = CComCriticalSection::Init(); - if (SUCCEEDED(hResult)) - m_bInitialized = true; - return hResult; - } - - HRESULT Term() - { - if (!m_bInitialized) - return S_OK; - m_bInitialized = false; - return CComCriticalSection::Term(); - } -}; - -class CComAutoDeleteCriticalSection : public CComSafeDeleteCriticalSection -{ -private: - // CComAutoDeleteCriticalSection::Term should never be called - HRESULT Term(); -}; - -struct _ATL_BASE_MODULE70 -{ - UINT cbSize; - HINSTANCE m_hInst; - HINSTANCE m_hInstResource; - bool m_bNT5orWin98; - DWORD dwAtlBuildVer; - GUID *pguidVer; - CRITICAL_SECTION m_csResource; -#ifdef NOTYET - CSimpleArray m_rgResourceInstance; -#endif -}; -typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE; - -class CAtlBaseModule : public _ATL_BASE_MODULE -{ -public : - static bool m_bInitFailed; -public: - CAtlBaseModule() - { - cbSize = sizeof(_ATL_BASE_MODULE); - GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)this, &m_hInst); - m_hInstResource = m_hInst; - } - - HINSTANCE GetModuleInstance() - { - return m_hInst; - } - - HINSTANCE GetResourceInstance() - { - return m_hInstResource; - } - - HINSTANCE SetResourceInstance(HINSTANCE hInst) - { - return static_cast< HINSTANCE >(InterlockedExchangePointer((void**)&m_hInstResource, hInst)); - } - - HINSTANCE GetHInstanceAt(int i); -}; - -__declspec(selectany) CAtlBaseModule _AtlBaseModule; -__declspec(selectany) bool CAtlBaseModule::m_bInitFailed = false; - - -/// -// String Resource helper functions -// -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4200) -#endif -struct ATLSTRINGRESOURCEIMAGE -{ - WORD nLength; - WCHAR achString[]; -}; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage( - _In_ HINSTANCE hInstance, - _In_ HRSRC hResource, - _In_ UINT id) -{ - const ATLSTRINGRESOURCEIMAGE* pImage; - const ATLSTRINGRESOURCEIMAGE* pImageEnd; - ULONG nResourceSize; - HGLOBAL hGlobal; - UINT iIndex; - - hGlobal = ::LoadResource(hInstance, hResource); - if (hGlobal == NULL) return NULL; - - pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource(hGlobal); - if (pImage == NULL) return NULL; - - nResourceSize = ::SizeofResource(hInstance, hResource); - pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + nResourceSize); - iIndex = id & 0x000f; - - while ((iIndex > 0) && (pImage < pImageEnd)) - { - pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + (sizeof(ATLSTRINGRESOURCEIMAGE) + (pImage->nLength * sizeof(WCHAR)))); - iIndex--; - } - - if (pImage >= pImageEnd) return NULL; - if (pImage->nLength == 0) return NULL; - - return pImage; -} - -inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( - _In_ HINSTANCE hInstance, - _In_ UINT id) throw() -{ - HRSRC hResource; - hResource = ::FindResourceW(hInstance, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast(~0))), (LPWSTR)RT_STRING); - if (hResource == NULL) return NULL; - return _AtlGetStringResourceImage(hInstance, hResource, id); -} - -inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage( - _In_ HINSTANCE hInstance, - _In_ UINT id, - _In_ WORD wLanguage) -{ - HRSRC hResource; - hResource = ::FindResourceExW(hInstance, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast(~0))), wLanguage); - if (hResource == NULL) return NULL; - return _AtlGetStringResourceImage(hInstance, hResource, id); -} - -inline HINSTANCE AtlFindStringResourceInstance( - UINT nID, - WORD wLanguage = 0) -{ - const ATLSTRINGRESOURCEIMAGE* strRes = NULL; - HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0); - - for (int i = 1; hInst != NULL && strRes == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++)) - { - strRes = AtlGetStringResourceImage(hInst, nID, wLanguage); - if (strRes != NULL) return hInst; - } - - return NULL; -} - -}; // namespace ATL diff --git a/nsisplugin/EnableMicrosoftUpdate.c b/nsisplugin/EnableMicrosoftUpdate.c index 9ae2b7a..262ef54 100644 --- a/nsisplugin/EnableMicrosoftUpdate.c +++ b/nsisplugin/EnableMicrosoftUpdate.c @@ -1,39 +1,33 @@ -#define CINTERFACE -#define COBJMACROS #include #include #include #include "main.h" -static const GUID our_CLSID_UpdateServiceManager = { 0xf8d253d9, 0x89a4, 0x4daa, { 0x87, 0xb6, 0x11, 0x68, 0x36, 0x9f, 0x0b, 0x21 } }; -static const GUID our_IID_IUpdateServiceManager2 = { 0x0bb8531d, 0x7e8d, 0x424f, { 0x98, 0x6c, 0xa0, 0xb8, 0xf6, 0x0a, 0x3e, 0x7b } }; - static const LPWSTR MicrosoftUpdateServiceID = L"7971f918-a847-4430-9279-4a52d1efe18d"; -EXTERN_C __declspec(dllexport) -void __cdecl EnableMicrosoftUpdate(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { - EXDLL_INIT(); - g_hwndParent = hwndParent; +PLUGIN_METHOD(EnableMicrosoftUpdate) { + PLUGIN_INIT(); IUpdateServiceManager2 *serviceManager; IUpdateServiceRegistration *registration; - HRESULT hr = CoCreateInstance(our_CLSID_UpdateServiceManager, NULL, CLSCTX_INPROC_SERVER, our_IID_IUpdateServiceManager2, (void **)&serviceManager); + HRESULT hr = CoCreateInstance(&CLSID_UpdateServiceManager, NULL, CLSCTX_INPROC_SERVER, &IID_IUpdateServiceManager2, (void **)&serviceManager); if (!SUCCEEDED(hr)) { goto end; } - hr = IUpdateServiceManager2_AddService2(serviceManager, SysAllocString(MicrosoftUpdateServiceID), asfAllowPendingRegistration | asfAllowOnlineRegistration | asfRegisterServiceWithAU, SysAllocString(L""), ®istration); - if (!SUCCEEDED(hr)) { - goto end; - } + BSTR serviceID = SysAllocString(MicrosoftUpdateServiceID); + BSTR serviceCab = SysAllocString(L""); + hr = IUpdateServiceManager2_AddService2(serviceManager, serviceID, asfAllowPendingRegistration | asfAllowOnlineRegistration | asfRegisterServiceWithAU, serviceCab, ®istration); + SysFreeString(serviceID); + SysFreeString(serviceCab); end: - if (registration != NULL) { + if (registration) { IUpdateServiceManager2_Release(registration); } - if (serviceManager != NULL) { + if (serviceManager) { IUpdateServiceManager2_Release(serviceManager); } diff --git a/nsisplugin/IsProcessRunning.c b/nsisplugin/IsProcessRunning.c deleted file mode 100644 index ba8fda0..0000000 --- a/nsisplugin/IsProcessRunning.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include "main.h" - -EXTERN_C __declspec(dllexport) -void __cdecl IsProcessRunning(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { - EXDLL_INIT(); - g_hwndParent = hwndParent; - - LPTSTR process = (LPTSTR)malloc(string_size * sizeof(TCHAR)); - popstring(process); - CharLowerBuffW(process, wcslen(process)); - - // Yes, eat all of our SHRTs! - DWORD pids[SHRT_MAX]; - DWORD bytesReturned; - if (!EnumProcesses(pids, sizeof(pids), &bytesReturned)) { - pushstring(L"0"); - return; - } - - DWORD count = bytesReturned / sizeof(DWORD); - for (DWORD i = 0; i < count; ++i) { - HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pids[i]); - if (handle) { - WCHAR path[MAX_PATH]; - if (GetProcessImageFileName(handle, path, ARRAYSIZE(path))) { - LPWSTR basename = wcsrchr(path, L'\\'); - if (basename != NULL) { - basename += 1; - CharLowerBuffW(basename, wcslen(basename)); - if (_wcsicmp(process, basename) == 0) { - pushstring(L"1"); - CloseHandle(handle); - return; - } - } - } - CloseHandle(handle); - } - } - - pushstring(L"0"); -} diff --git a/nsisplugin/Makefile b/nsisplugin/Makefile index d131958..1be0795 100644 --- a/nsisplugin/Makefile +++ b/nsisplugin/Makefile @@ -1,17 +1,20 @@ FILES = \ $(wildcard *.c) \ ../include/nsis/pluginapi.c \ - ../Shared/HResult.c \ - ../Shared/WUErrors.c + ../shared/HResult.c \ + ../shared/LegacyUpdate.c \ + ../shared/LoadImage.c \ + ../shared/Registry.c RCFILES = resource.rc +TAG = i686 +PREFIX = i686-w64-mingw32- + BIN = obj/LegacyUpdateNSIS.dll DEF = $(patsubst %.dll,%.def,$(BIN)) STATIC = $(patsubst %.dll,%.a,$(BIN)) -OBJ = $(foreach file,$(FILES),obj/$(notdir $(basename $(file)).o)) -RES = $(foreach file,$(RCFILES),obj/$(notdir $(basename $(file)).res)) - -PREFIX = i686-w64-mingw32- +OBJ = $(foreach file,$(FILES),obj/$(notdir $(basename $(file)).$(TAG).o)) +RES = $(foreach file,$(RCFILES),obj/$(notdir $(basename $(file)).$(TAG).res)) CC = $(PREFIX)g++ RC = $(PREFIX)windres @@ -19,14 +22,12 @@ RC = $(PREFIX)windres override DEBUG := $(or $(DEBUG),1) CFLAGS = \ - -std=c++11 \ -march=i486 \ -mdll \ -municode \ -DUNICODE \ -D_UNICODE \ $(if $(filter 1,$(DEBUG)),-D_DEBUG -g,-DNDEBUG -Os) \ - -D__USE_MINGW_ANSI_STDIO=0 \ -D_USRDLL \ -s \ -fPIE \ @@ -35,13 +36,17 @@ CFLAGS = \ -fno-unwind-tables \ -fno-asynchronous-unwind-tables \ -fno-exceptions \ - -fno-rtti \ -flto \ -Wno-write-strings \ -I../include \ -I../shared \ -include stdafx.h +CXXFLAGS = \ + $(CFLAGS) \ + -std=c++11 \ + -fno-rtti + LDFLAGS = \ -nodefaultlibs \ -nostartfiles \ @@ -61,49 +66,52 @@ LDFLAGS = \ -lkernel32 \ -luser32 \ -lole32 \ - -loleaut32 + -loleaut32 \ + -ladvapi32 \ + -lgdi32 \ + -lmsimg32 \ + -lcrypt32 RCFLAGS = \ -F pe-i386 \ - -O coff + -O coff \ + -I../shared all: before-all $(BIN) after-all - -before-all: - mkdir -p obj - -after-all: ifeq ($(SIGN),1) ../build/sign.sh $(BIN) endif cp $(BIN) ../setup/x86-unicode/ +before-all: + mkdir -p obj + $(BIN): $(OBJ) $(RES) $(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@ -obj/%.o: %.c - $(CC) $< $(CFLAGS) -c -o $@ +obj/%.$(TAG).o: %.c + $(CC) -x c $< $(CFLAGS) -c -o $@ -obj/%.o: %.cpp - $(CC) $< $(CFLAGS) -c -o $@ +obj/%.$(TAG).o: %.cpp + $(CC) -x c++ $< $(CXXFLAGS) -c -o $@ -obj/%.o: ../shared/%.c - $(CC) $< $(CFLAGS) -c -o $@ +obj/%.$(TAG).o: ../shared/%.c + $(CC) -x c $< $(CFLAGS) -c -o $@ -obj/%.o: ../shared/%.cpp - $(CC) $< $(CFLAGS) -c -o $@ +obj/%.$(TAG).o: ../shared/%.cpp + $(CC) -x c++ $< $(CXXFLAGS) -c -o $@ -obj/%.o: ../include/nsis/%.c - $(CC) $< $(CFLAGS) -c -o $@ +obj/%.$(TAG).o: ../include/nsis/%.c + $(CC) -x c $< $(CFLAGS) -c -o $@ -obj/%.res: %.rc +obj/%.$(TAG).res: %.rc $(RC) $< $(RCFLAGS) -o $@ clean: rm -rf obj test: - $(MAKE) DEBUG=$(DEBUG) + +$(MAKE) DEBUG=$(DEBUG) cd ../setup && makensis test.nsi cd ../setup && explorer.exe test.exe diff --git a/nsisplugin/MessageForHresult.c b/nsisplugin/MessageForHresult.c index 02367e8..0b29ff9 100644 --- a/nsisplugin/MessageForHresult.c +++ b/nsisplugin/MessageForHresult.c @@ -2,12 +2,15 @@ #include #include "../shared/HResult.h" -EXTERN_C __declspec(dllexport) -void __cdecl MessageForHresult(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { - EXDLL_INIT(); - g_hwndParent = hwndParent; +PLUGIN_METHOD(MessageForHresult) { + PLUGIN_INIT(); HRESULT hr = popint(); + if (hr == 0) { + pushstring(L"Unknown error"); + return; + } + LPWSTR message = GetMessageForHresult(hr); pushstring(message); LocalFree(message); diff --git a/nsisplugin/TaskbarProgress.c b/nsisplugin/TaskbarProgress.c index 181acef..5c0ce32 100644 --- a/nsisplugin/TaskbarProgress.c +++ b/nsisplugin/TaskbarProgress.c @@ -1,23 +1,23 @@ // Based on https://nsis.sourceforge.io/TaskbarProgress_plug-in - zlib licensed // Cleaned up and refactored into C by Legacy Update -#define CINTERFACE -#define COBJMACROS +#undef _WIN32_WINNT +#define _WIN32_WINNT _WIN32_WINNT_WIN7 #include #include #include #include #include #include "main.h" +#include "VersionInfo.h" -static const GUID our_CLSID_ITaskbarList = { 0x56fdf344, 0xfd6d, 0x11d0, { 0x95, 0x8a, 0x00, 0x60, 0x97, 0xc9, 0xa0, 0x90 } }; -static const GUID our_IID_ITaskbarList3 = { 0xea1afb91, 0x9e28, 0x4b86, { 0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf } }; +static extra_parameters *g_extra; +static ITaskbarList3 *g_taskbarList; +static UINT g_totalRange; +static WNDPROC g_progressOrigWndProc; +static WNDPROC g_dialogOrigWndProc; -ITaskbarList3 *g_taskbarList; -UINT g_totalRange; -WNDPROC g_origWndProc; - -LRESULT ProgressBarWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if (g_origWndProc == NULL) { +LRESULT CALLBACK ProgressBarWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (!g_progressOrigWndProc) { return 0; } @@ -31,40 +31,73 @@ LRESULT ProgressBarWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { break; case PBM_SETPOS: - if (g_taskbarList != NULL) { + if (g_taskbarList) { ITaskbarList3_SetProgressValue(g_taskbarList, g_hwndParent, wParam, g_totalRange); } break; case WM_DESTROY: - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)g_origWndProc); + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)g_progressOrigWndProc); - if (g_taskbarList != NULL) { + if (g_taskbarList) { ITaskbarList3_SetProgressState(g_taskbarList, g_hwndParent, TBPF_NOPROGRESS); ITaskbarList3_Release(g_taskbarList); g_taskbarList = NULL; } - g_origWndProc = NULL; + g_progressOrigWndProc = NULL; break; } - return CallWindowProc(g_origWndProc, hwnd, uMsg, wParam, lParam); + return CallWindowProc(g_progressOrigWndProc, hwnd, uMsg, wParam, lParam); } -UINT_PTR NSISPluginCallback(enum NSPIM event) { +static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (!g_dialogOrigWndProc) { + return 0; + } + + switch (uMsg) { + case WM_NOTIFY_OUTER_NEXT: + if (g_extra->exec_flags->abort) { + // Set the progress bar to error state (red) + HWND innerWindow = FindWindowEx(hwnd, NULL, L"#32770", NULL); + HWND progressBar = FindWindowEx(innerWindow, NULL, L"msctls_progress32", NULL); + if (progressBar) { + SendMessage(progressBar, PBM_SETSTATE, PBST_ERROR, 0); + } + + if (g_taskbarList) { + ITaskbarList3_SetProgressState(g_taskbarList, g_hwndParent, TBPF_ERROR); + } + } + break; + + case WM_DESTROY: + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)g_dialogOrigWndProc); + g_dialogOrigWndProc = NULL; + break; + } + + return CallWindowProc(g_dialogOrigWndProc, hwnd, uMsg, wParam, lParam); +} + +static UINT_PTR NSISPluginCallback(enum NSPIM event) { // Does nothing, but keeping a callback registered prevents NSIS from unloading the plugin return 0; } -EXTERN_C __declspec(dllexport) -void __cdecl InitTaskbarProgress(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { - EXDLL_INIT(); - g_hwndParent = hwndParent; +PLUGIN_METHOD(InitTaskbarProgress) { + PLUGIN_INIT(); + if (!AtLeastWinVista()) { + return; + } + + g_extra = extra; extra->RegisterPluginCallback(g_hInstance, NSISPluginCallback); - if (g_taskbarList != NULL && g_origWndProc != NULL) { + if (g_progressOrigWndProc) { // Already initialised return; } @@ -74,11 +107,11 @@ void __cdecl InitTaskbarProgress(HWND hwndParent, int string_size, TCHAR *variab PBRANGE range; HRESULT hr; - if (progressBar == NULL) { + if (!progressBar) { goto fail; } - hr = CoCreateInstance(our_CLSID_ITaskbarList, NULL, CLSCTX_INPROC_SERVER, our_IID_ITaskbarList3, (void**)&g_taskbarList); + hr = CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (void **)&g_taskbarList); if (!SUCCEEDED(hr)) { goto fail; } @@ -93,17 +126,19 @@ void __cdecl InitTaskbarProgress(HWND hwndParent, int string_size, TCHAR *variab g_totalRange = range.iLow + range.iHigh; // Add our own window procedure so we can respond to progress bar updates - g_origWndProc = (WNDPROC)SetWindowLongPtr(progressBar, GWLP_WNDPROC, (LONG_PTR)ProgressBarWndProc); - if (g_origWndProc == NULL) { + g_progressOrigWndProc = (WNDPROC)SetWindowLongPtr(progressBar, GWLP_WNDPROC, (LONG_PTR)ProgressBarWndProc); + g_dialogOrigWndProc = (WNDPROC)SetWindowLongPtr(g_hwndParent, GWLP_WNDPROC, (LONG_PTR)MainWndProc); + if (!g_progressOrigWndProc || !g_dialogOrigWndProc) { goto fail; } return; fail: - if (g_taskbarList != NULL) { + if (g_taskbarList) { ITaskbarList3_Release(g_taskbarList); g_taskbarList = NULL; } - g_origWndProc = NULL; + g_progressOrigWndProc = NULL; + g_dialogOrigWndProc = NULL; } diff --git a/nsisplugin/main.c b/nsisplugin/main.c index 4bf78f6..f559afe 100644 --- a/nsisplugin/main.c +++ b/nsisplugin/main.c @@ -1,10 +1,22 @@ #include #include +#include "Startup.h" -HMODULE g_hInstance; +HINSTANCE g_hInstance; HWND g_hwndParent; -EXTERN_C BOOL WINAPI DllMain(HMODULE hInstance, UINT iReason, LPVOID lpReserved) { - g_hInstance = hInstance; +EXTERN_C __declspec(dllexport) +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { + switch (dwReason) { + case DLL_PROCESS_ATTACH: + g_hInstance = hInstance; + Startup(); + break; + + case DLL_PROCESS_DETACH: + g_hInstance = NULL; + break; + } + return TRUE; } diff --git a/nsisplugin/main.h b/nsisplugin/main.h index 8cc23f6..0c0ba29 100644 --- a/nsisplugin/main.h +++ b/nsisplugin/main.h @@ -1,4 +1,4 @@ #include -EXTERN_C HMODULE g_hInstance; +EXTERN_C HINSTANCE g_hInstance; EXTERN_C HWND g_hwndParent; diff --git a/nsisplugin/resource.rc b/nsisplugin/resource.rc index c665022..32060a3 100644 --- a/nsisplugin/resource.rc +++ b/nsisplugin/resource.rc @@ -2,6 +2,7 @@ #define APSTUDIO_READONLY_SYMBOLS #include +#include "Version.h" #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -17,8 +18,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,0,0 - PRODUCTVERSION 1,9,0,0 + FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD + PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_BUILD FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -35,12 +36,12 @@ BEGIN BEGIN VALUE "CompanyName", "Hashbang Productions" VALUE "FileDescription", "Legacy Update Setup Helper" - VALUE "FileVersion", "1.9.0.0" + VALUE "FileVersion", VERSION_STRING VALUE "InternalName", "LegacyUpdateNSIS.dll" VALUE "LegalCopyright", "© Hashbang Productions. All rights reserved." VALUE "OriginalFilename", "LegacyUpdateNSIS.dll" VALUE "ProductName", "Legacy Update" - VALUE "ProductVersion", "1.9.0.0" + VALUE "ProductVersion", VERSION_STRING END END BLOCK "VarFileInfo" diff --git a/nsisplugin/stdafx.h b/nsisplugin/stdafx.h index d6480c0..ad1dee8 100644 --- a/nsisplugin/stdafx.h +++ b/nsisplugin/stdafx.h @@ -4,13 +4,33 @@ #define STRICT #endif -#define WINVER 0x0500 -#define _WIN32_WINNT 0x0500 +#define WINVER _WIN32_WINNT_WIN2K +#define _WIN32_WINNT _WIN32_WINNT_WIN2K -#define ISOLATION_AWARE_ENABLED 1 // Enable comctl 6.0 (visual styles) +// Use msvcrt stdio functions +#define __USE_MINGW_ANSI_STDIO 0 + +// Enable comctl 6.0 (visual styles) +#define ISOLATION_AWARE_ENABLED 1 + +// Enable COM C interfaces +#define CINTERFACE +#define COBJMACROS +#define INITGUID #include "resource.h" - #include +#include "Trace.h" EXTERN_C HWND g_hwndParent; + +#define PLUGIN_METHOD(name) \ + EXTERN_C __declspec(dllexport) \ + void __cdecl name(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) + +#define PLUGIN_INIT() \ + if (extra && extra->exec_flags && (extra->exec_flags->plugin_api_version != NSISPIAPIVER_CURR)) { \ + return; \ + } \ + EXDLL_INIT(); \ + g_hwndParent = hwndParent; diff --git a/setup/7z.exe b/setup/7z.exe deleted file mode 100644 index fad2cfa..0000000 Binary files a/setup/7z.exe and /dev/null differ diff --git a/setup/7zip.nsh b/setup/7zip.nsh deleted file mode 100644 index d95c882..0000000 --- a/setup/7zip.nsh +++ /dev/null @@ -1,4 +0,0 @@ -Function Install7Zip - File 7z.exe - !insertmacro Install "7-Zip" "7z.exe" "/S" -FunctionEnd \ No newline at end of file diff --git a/setup/AeroWizard.nsh b/setup/AeroWizard.nsh index 80e2962..c8eecfa 100644 --- a/setup/AeroWizard.nsh +++ b/setup/AeroWizard.nsh @@ -12,7 +12,13 @@ !insertmacro SetControlColor ${parent} ${control} SYSCLR:WINDOWTEXT !macroend +; These are PE resources because there's no benefit to LZMA compressing PNGs +PEAddResource "banner-wordmark-light.png" "PNG" "#1337" +PEAddResource "banner-wordmark-dark.png" "PNG" "#1338" +PEAddResource "banner-wordmark-glow.png" "PNG" "#1339" + Var /GLOBAL ChildHwnd +Var /GLOBAL AeroWizard.Font !macro -AeroWizardOnShow ; Get the child window where the wizard page is @@ -26,55 +32,44 @@ Var /GLOBAL ChildHwnd CreateFont $3 "Segoe UI Variable Display Semibold" 14 600 !insertmacro SetControlColor $HWNDPARENT 1037 SYSCLR:WINDOWTEXT ${Else} + ; Aero style CreateFont $3 "Segoe UI" 12 400 !insertmacro SetControlColor $HWNDPARENT 1037 0x003399 ${EndIf} - CreateFont $2 "Segoe UI" 8 400 + CreateFont $AeroWizard.Font "Segoe UI" 8 400 !insertmacro SetFont $3 $HWNDPARENT 1037 - !insertmacro SetFont $2 $HWNDPARENT 1 - !insertmacro SetFont $2 $HWNDPARENT 2 - !insertmacro SetFont $2 $HWNDPARENT 3 - !insertmacro SetFont $2 $HWNDPARENT 1028 - !insertmacro SetFont $2 $ChildHwnd 1000 - !insertmacro SetFont $2 $ChildHwnd 1004 - !insertmacro SetFont $2 $ChildHwnd 1006 - !insertmacro SetFont $2 $ChildHwnd 1016 - !insertmacro SetFont $2 $ChildHwnd 1022 - !insertmacro SetFont $2 $ChildHwnd 1023 - !insertmacro SetFont $2 $ChildHwnd 1029 - !insertmacro SetFont $2 $ChildHwnd 1027 - !insertmacro SetFont $2 $ChildHwnd 1032 - !insertmacro SetFont $2 $ChildHwnd 1043 + !insertmacro SetFont $AeroWizard.Font $HWNDPARENT 1028 + ${For} $4 1 3 + !insertmacro SetFont $AeroWizard.Font $HWNDPARENT $4 + ${Next} + ${For} $4 1000 1043 + !insertmacro SetFont $AeroWizard.Font $ChildHwnd $4 + ${Next} ${Else} - ; Wizard97 style + ; Wizard97ish style ${If} ${FileExists} "$FONTS\framd.ttf" CreateFont $2 "Franklin Gothic Medium" 13 400 - !insertmacro SetFont $2 $HWNDPARENT 1037 !insertmacro SetControlColor $HWNDPARENT 1037 0x003399 ${Else} CreateFont $2 "Verdana" 12 800 - !insertmacro SetFont $2 $HWNDPARENT 1037 !insertmacro SetControlColor $HWNDPARENT 1037 SYSCLR:WINDOWTEXT ${EndIf} + !insertmacro SetFont $2 $HWNDPARENT 1037 + CreateFont $AeroWizard.Font "MS Shell Dlg 2" 8 400 ${EndIf} ; Set white background SetCtlColors $HWNDPARENT SYSCLR:WINDOWTEXT SYSCLR:WINDOW SetCtlColors $ChildHwnd SYSCLR:WINDOWTEXT SYSCLR:WINDOW - !insertmacro SetBackground $ChildHwnd 1020 - !insertmacro SetBackground $ChildHwnd 1028 - !insertmacro SetBackground $ChildHwnd 1006 - !insertmacro SetBackground $ChildHwnd 1022 - !insertmacro SetBackground $ChildHwnd 1023 - !insertmacro SetBackground $ChildHwnd 1027 - !insertmacro SetBackground $ChildHwnd 1029 - !insertmacro SetBackground $ChildHwnd 1032 - !insertmacro SetBackground $ChildHwnd 1043 + ${For} $4 1000 1043 + !insertmacro SetBackground $ChildHwnd $4 + ${Next} + + ; Set up banner and glass + LegacyUpdateNSIS::DialogInit ; Activate taskbar progress bar plugin - ${If} ${AtLeastWin7} - LegacyUpdateNSIS::InitTaskbarProgress - ${EndIf} + LegacyUpdateNSIS::InitTaskbarProgress !macroend Function AeroWizardOnShow @@ -84,3 +79,10 @@ FunctionEnd Function un.AeroWizardOnShow !insertmacro -AeroWizardOnShow FunctionEnd + +!macro -AeroWizardDialogControl hwnd + SendMessage ${hwnd} ${WM_SETFONT} $AeroWizard.Font 0 + SetCtlColors ${hwnd} SYSCLR:WINDOWTEXT SYSCLR:WINDOW +!macroend + +!define AeroWizardDialogControl '!insertmacro -AeroWizardDialogControl' diff --git a/setup/Common.nsh b/setup/Common.nsh index 83a82e8..0938531 100644 --- a/setup/Common.nsh +++ b/setup/Common.nsh @@ -2,13 +2,33 @@ SetPluginUnload alwaysoff +!if ${DEBUG} == 0 + !packhdr upx.tmp 'upx --lzma -9 upx.tmp' +!endif + !if ${SIGN} == 1 !finalize '../build/sign.sh "%1"' !uninstfinalize '../build/sign.sh "%1"' !endif +!macro -Trace msg + !if ${DEBUG} == 1 + !insertmacro _LOGICLIB_TEMP + !ifdef __FUNCTION__ + StrCpy $_LOGICLIB_TEMP "${__FUNCTION__}" + !else + StrCpy $_LOGICLIB_TEMP "${__SECTION__}" + !endif + MessageBox MB_OK `${__FILE__}(${__LINE__}): $_LOGICLIB_TEMP: ${msg}` + !endif +!macroend +!define TRACE '!insertmacro -Trace' + !define IsNativeIA64 '${IsNativeMachineArchitecture} ${IMAGE_FILE_MACHINE_IA64}' +!undef RunningX64 +!define RunningX64 `"$PROGRAMFILES64" != "$PROGRAMFILES32"` + Function GetArch Var /GLOBAL Arch ${If} $Arch == "" @@ -33,31 +53,71 @@ FunctionEnd IfErrors `${_f}` `${_t}` !macroend -!define IsActiveXInstall `"" HasFlag "/activex"` -!define IsHelp `"" HasFlag "/?"` +!define IsPassive `"" HasFlag "/passive"` +!define IsActiveX `"" HasFlag "/activex"` +!define IsHelp `"" HasFlag "/?"` +!define IsVerbose `"" HasFlag "/v"` -!macro DetailPrint text +!if ${DEBUG} == 1 +!define TestRunOnce `"" HasFlag "/testrunonce"` +!endif + +!macro _NeedsPatch _a _b _t _f + !insertmacro _LOGICLIB_TEMP + Call Needs${_b} + Pop $_LOGICLIB_TEMP + StrCmp $_LOGICLIB_TEMP 1 `${_t}` `${_f}` +!macroend + +!define NeedsPatch `"" NeedsPatch` + +!macro -DetailPrint level text +!if ${level} == 0 + ${If} ${IsVerbose} + DetailPrint "${text}" + ${EndIf} +!else SetDetailsPrint both DetailPrint "${text}" SetDetailsPrint listonly +!endif !macroend +!define VerbosePrint `!insertmacro -DetailPrint 0` +!define DetailPrint `!insertmacro -DetailPrint 1` + Var /GLOBAL Download.ID -!macro DownloadRequest url local extra +Function DownloadRequest + ; TODO: This is broken on XP for some reason + ; Var /GLOBAL Download.UserAgent + ; ${If} $Download.UserAgent == "" + ; GetWinVer $R8 Major + ; GetWinVer $R9 Minor + ; StrCpy $Download.UserAgent "Mozilla/4.0 (${NAME} ${VERSION}; Windows NT $R8.$R9)" + ; ${EndIf} + ; /HEADER "User-Agent: $Download.UserAgent" + NSxfer::Request \ /TIMEOUTCONNECT 60000 \ /TIMEOUTRECONNECT 60000 \ /OPTCONNECTTIMEOUT 60000 \ /OPTRECEIVETIMEOUT 60000 \ /OPTSENDTIMEOUT 60000 \ - /URL "${url}" \ - /LOCAL "${local}" \ + /URL "$R0" \ + /LOCAL "$R1" \ /INTERNETFLAGS ${INTERNET_FLAG_RELOAD}|${INTERNET_FLAG_NO_CACHE_WRITE}|${INTERNET_FLAG_KEEP_CONNECTION}|${INTERNET_FLAG_NO_COOKIES}|${INTERNET_FLAG_NO_UI} \ /SECURITYFLAGS ${SECURITY_FLAG_STRENGTH_STRONG} \ - ${extra} \ + $R2 \ /END Pop $Download.ID +FunctionEnd + +!macro DownloadRequest url local extra + StrCpy $R0 "${url}" + StrCpy $R1 "${local}" + StrCpy $R2 "${extra}" + Call DownloadRequest !macroend Function DownloadWaitSilent @@ -67,27 +127,37 @@ FunctionEnd Function DownloadWait NSxfer::Wait /ID $Download.ID /MODE PAGE \ - /STATUSTEXT \ - "{TIMEREMAINING} left - {RECVSIZE} of {FILESIZE} ({SPEED})" \ - "{TIMEREMAINING} left - {TOTALRECVSIZE} of {TOTALFILESIZE} ({SPEED})" \ - /ABORT "Legacy Update" "Cancelling will terminate Legacy Update setup." \ + /STATUSTEXT "$(DownloadStatusSingle)" "$(DownloadStatusMulti)" \ + /ABORT "$(^Name)" "$(MsgBoxDownloadAbort)" \ /END NSxfer::Query /ID $Download.ID /ERRORCODE /ERRORTEXT /END FunctionEnd !macro -Download name url filename verbose - !insertmacro DetailPrint "Downloading ${name}..." +!if ${verbose} == 1 + ${DetailPrint} "$(Downloading)${name}..." +!endif + ${If} ${IsVerbose} + ${DetailPrint} "$(Downloading)${name}..." + ${VerbosePrint} "From: ${url}" + ${VerbosePrint} "To: ${filename}" + ${EndIf} !insertmacro DownloadRequest "${url}" "${filename}" "" - ${If} ${verbose} == 1 +!if ${verbose} == 1 + Call DownloadWait +!else + ${If} ${IsVerbose} Call DownloadWait ${Else} Call DownloadWaitSilent ${EndIf} +!endif Pop $1 Pop $0 ${If} $0 != "OK" ${If} $1 != ${ERROR_INTERNET_OPERATION_CANCELLED} - MessageBox MB_USERICON "${name} failed to download.$\r$\n$\r$\n$0 ($1)" /SD IDOK + StrCpy $2 "${name}" + MessageBox MB_USERICON "$(MsgBoxDownloadFailed)" /SD IDOK ${EndIf} Delete /REBOOTOK "${filename}" SetErrorLevel 1 @@ -96,75 +166,69 @@ FunctionEnd !macroend !macro Download name url filename verbose - ${If} ${FileExists} "$EXEDIR\${filename}" - ${If} $OUTDIR != "$EXEDIR" - SetOutPath "$EXEDIR" + ${IfNot} ${FileExists} "${RUNONCEDIR}\${filename}" + ${If} ${FileExists} "$EXEDIR\${filename}" + CopyFiles /SILENT "$EXEDIR\${filename}" "${RUNONCEDIR}\${filename}" + ${Else} + !insertmacro -Download '${name}' '${url}' '${RUNONCEDIR}\${filename}' ${verbose} ${EndIf} - StrCpy $0 "$EXEDIR\${filename}" - ${Else} - ${If} $OUTDIR != "$RunOnceDir" - SetOutPath "$RunOnceDir" - ${EndIf} - ${IfNot} ${FileExists} "$RunOnceDir\${filename}" - !insertmacro -Download '${name}' '${url}' '$RunOnceDir\${filename}' ${verbose} - ${EndIf} - StrCpy $0 "$RunOnceDir\${filename}" ${EndIf} + StrCpy $0 "${RUNONCEDIR}\${filename}" !macroend Var /GLOBAL Exec.Command +Var /GLOBAL Exec.Patch Var /GLOBAL Exec.Name -Var /GLOBAL Exec.IsWusa Function ExecWithErrorHandling - Push $0 - ExecWait '$Exec.Command' $0 - ${If} $0 == ${ERROR_SUCCESS_REBOOT_REQUIRED} + ${VerbosePrint} "$(^Exec)$Exec.Command" + LegacyUpdateNSIS::ExecToLog `$Exec.Command` + Pop $R0 + ${VerbosePrint} "$(ExitCode)$R0" + + ${If} $R0 == ${ERROR_SUCCESS_REBOOT_REQUIRED} + ${VerbosePrint} "$(RestartRequired)" SetRebootFlag true - ${ElseIf} $0 == ${ERROR_INSTALL_USEREXIT} + ${ElseIf} $R0 == ${ERROR_INSTALL_USEREXIT} SetErrorLevel ${ERROR_INSTALL_USEREXIT} Abort - ${ElseIf} $Exec.IsWusa == 1 - ${AndIf} $0 == 1 - ; wusa exits with 1 if the patch is already installed. Treat this as success. - DetailPrint "Installation skipped - already installed" - ${ElseIf} $Exec.IsWusa == 1 - ${AndIf} $0 == ${WU_S_ALREADY_INSTALLED} - DetailPrint "Installation skipped - already installed" - ${ElseIf} $Exec.IsWusa == 1 - ${AndIf} $0 == ${WU_E_NOT_APPLICABLE} - DetailPrint "Installation skipped - not applicable" - ${ElseIf} $0 != 0 - LegacyUpdateNSIS::MessageForHresult $0 + ${ElseIf} $R0 == ${WU_S_ALREADY_INSTALLED} + ${DetailPrint} "$(AlreadyInstalled)" + ${ElseIf} $R0 == ${WU_E_NOT_APPLICABLE} + ${DetailPrint} "$(NotApplicable)" + ${ElseIf} $R0 != 0 + StrCpy $0 $R0 + LegacyUpdateNSIS::MessageForHresult $R0 Pop $1 - MessageBox MB_USERICON "$Exec.Name failed to install.$\r$\n$\r$\n$1 ($0)" /SD IDOK - SetErrorLevel $0 + ${DetailPrint} "$1 ($0)" + StrCpy $2 "$Exec.Name" + MessageBox MB_USERICON "$(MsgBoxInstallFailed)" /SD IDOK + SetErrorLevel $R0 Abort ${EndIf} - Pop $0 FunctionEnd -!macro ExecWithErrorHandling name command iswusa +!macro ExecWithErrorHandling name command StrCpy $Exec.Command '${command}' StrCpy $Exec.Name '${name}' - StrCpy $Exec.IsWusa '${iswusa}' Call ExecWithErrorHandling !macroend !macro Install name filename args - !insertmacro DetailPrint "Installing ${name}..." - !insertmacro ExecWithErrorHandling '${name}' '"$0" ${args}' 0 + ${DetailPrint} "$(Installing)${name}..." + !insertmacro ExecWithErrorHandling '${name}' '"$0" ${args}' !macroend !macro InstallSP name filename ; SPInstall.exe /norestart seems to be broken. We let it do a delayed restart, then cancel it. - !insertmacro DetailPrint "Extracting ${name}..." - !insertmacro ExecWithErrorHandling '${name}' '"$0" /X:"$PLUGINSDIR\${filename}"' 0 - !insertmacro DetailPrint "Installing ${name}..." - !insertmacro ExecWithErrorHandling '${name}' '"$PLUGINSDIR\${filename}\spinstall.exe" /unattend /nodialog /warnrestart:600' 0 + ${DetailPrint} "$(Extracting)${name}..." + !insertmacro ExecWithErrorHandling '${name}' '"$0" /X:"$PLUGINSDIR\${filename}"' + ${DetailPrint} "$(Installing)${name}..." + !insertmacro ExecWithErrorHandling '${name}' '"$WINDIR\system32\cmd.exe" /c "$PLUGINSDIR\${filename}\spinstall.exe" /unattend /nodialog /warnrestart:600' ; If we successfully abort a shutdown, we'll get exit code 0, so we know a reboot is required. - ExecWait "$WINDIR\system32\shutdown.exe /a" $0 + LegacyUpdateNSIS::Exec '"$WINDIR\system32\shutdown.exe" /a' + Pop $0 ${If} $0 == 0 SetRebootFlag true ${EndIf} @@ -174,85 +238,84 @@ FunctionEnd !insertmacro Download '${name} (${kbid})' '${url}' '${kbid}.msu' 1 !macroend +Function InstallMSU + ${DetailPrint} "$(Extracting)$Exec.Name..." + ${IfNot} ${IsVerbose} + SetDetailsPrint none + ${EndIf} + CreateDirectory "$PLUGINSDIR\$Exec.Patch" + CreateDirectory "$PLUGINSDIR\$Exec.Patch\Temp" + StrCpy $Exec.Command '"$WINDIR\system32\expand.exe" -F:* "$0" "$PLUGINSDIR\$Exec.Patch"' + Call ExecWithErrorHandling + ${IfNot} ${IsVerbose} + SetDetailsPrint lastused + ${EndIf} + + ${DetailPrint} "$(Installing)$Exec.Name..." + ${DisableX64FSRedirection} + FindFirst $0 $1 "$PLUGINSDIR\$Exec.Patch\*.xml" + ${Do} + ${If} $1 == "" + FindClose $R0 + ${Break} + ${EndIf} + + ; We prefer Dism, but need to fall back to Pkgmgr for Vista. + ${If} ${IsWinVista} + StrCpy $Exec.Command '"$WINDIR\system32\pkgmgr.exe" \ + /n:"$PLUGINSDIR\$Exec.Patch\$1" \ + /s:"$PLUGINSDIR\$Exec.Patch\Temp" \ + /quiet /norestart' + ${Else} + StrCpy $Exec.Command '"$WINDIR\system32\dism.exe" \ + /Online \ + /Apply-Unattend:"$PLUGINSDIR\$Exec.Patch\$1" \ + /ScratchDir:"$PLUGINSDIR\$Exec.Patch\Temp" \ + /LogPath:"$TEMP\LegacyUpdate-Dism.log" \ + /Quiet /NoRestart' + ${EndIf} + Call ExecWithErrorHandling + + FindNext $0 $1 + ${Loop} + ${EnableX64FSRedirection} +FunctionEnd + !macro InstallMSU kbid name - ; Stop AU service before running wusa so it doesn't try checking for updates online first (which - ; may never complete before we install our patches). - !insertmacro DetailPrint "Installing ${name} (${kbid})..." - SetDetailsPrint none - ExecShellWait "" "$WINDIR\system32\net.exe" "stop wuauserv" SW_HIDE - SetDetailsPrint listonly - !insertmacro ExecWithErrorHandling '${name} (${kbid})' '$WINDIR\system32\wusa.exe /quiet /norestart "$0"' 1 + StrCpy $Exec.Patch '${kbid}' + StrCpy $Exec.Name '${name} (${kbid})' + Call InstallMSU !macroend !macro EnsureAdminRights ${IfNot} ${AtLeastWin2000} - MessageBox MB_USERICON "Legacy Update requires at least Windows 2000." /SD IDOK + MessageBox MB_USERICON|MB_OKCANCEL "$(MsgBoxOldWinVersion)" /SD IDCANCEL \ + IDCANCEL +2 + ExecShell "" "${WUR_WEBSITE}" SetErrorLevel ${ERROR_OLD_WIN_VERSION} Quit ${EndIf} - System::Call '${IsUserAnAdmin}() .r0' + ClearErrors + LegacyUpdateNSIS::IsAdmin + ${If} ${Errors} + MessageBox MB_USERICON "$(MsgBoxPluginFailed)" /SD IDOK + SetErrorLevel 1 + Quit + ${EndIf} + + Pop $0 ${If} $0 == 0 - MessageBox MB_USERICON "Log on as an administrator to install Legacy Update." /SD IDOK + MessageBox MB_USERICON "$(MsgBoxElevationRequired)" /SD IDOK SetErrorLevel ${ERROR_ELEVATION_REQUIRED} Quit ${EndIf} !macroend !macro InhibitSleep state - ${If} ${state} == 1 - System::Call '${SetThreadExecutionState}(${ES_CONTINUOUS}|${ES_SYSTEM_REQUIRED})' - ${Else} - System::Call '${SetThreadExecutionState}(${ES_CONTINUOUS})' - ${EndIf} -!macroend - -!macro TryWithRetry command error - ClearErrors - ${command} - IfErrors 0 +3 - MessageBox MB_RETRYCANCEL|MB_USERICON \ - '${error}$\r$\n$\r$\nIf Internet Explorer is open, close it and click Retry.' \ - /SD IDCANCEL \ - IDRETRY -3 - Abort -!macroend - -!macro TryFile file oname - !insertmacro TryWithRetry `File "/ONAME=${oname}" "${file}"` 'Unable to write to "${oname}".' -!macroend - -!macro TryDelete file - !insertmacro TryWithRetry `Delete "${file}"` 'Unable to delete "${file}".' -!macroend - -!macro TryRename src dest - !insertmacro TryWithRetry `Rename "${src}" "${dest}"` 'Unable to write to "${dest}".' -!macroend - -!macro RegisterDLL un arch file - ${If} "${un}" == "Un" - StrCpy $0 "/u" - ${Else} - StrCpy $0 "" - ${EndIf} - - ${If} "${arch}" == "x64" - ${DisableX64FSRedirection} - ${EndIf} - - ClearErrors - ExecWait '"$WINDIR\system32\regsvr32.exe" /s $0 "${file}"' - ${If} ${Errors} - ; Do it again non-silently so the user can see the error. - ExecWait '"$WINDIR\system32\regsvr32.exe" $0 "${file}"' - ${If} "${arch}" == "x64" - ${EnableX64FSRedirection} - ${EndIf} - Abort - ${EndIf} - - ${If} "${arch}" == "x64" - ${EnableX64FSRedirection} - ${EndIf} +!if ${state} == 1 + System::Call '${SetThreadExecutionState}(${ES_CONTINUOUS}|${ES_SYSTEM_REQUIRED})' +!else + System::Call '${SetThreadExecutionState}(${ES_CONTINUOUS})' +!endif !macroend diff --git a/setup/Constants.nsh b/setup/Constants.nsh index 7d5771d..bee0aee 100644 --- a/setup/Constants.nsh +++ b/setup/Constants.nsh @@ -1,13 +1,34 @@ ; Product -!define NAME "WUIsBack" +!define NAME "Legacy Update (Vichingo455's Mod)" !define DOMAIN "legacyupdate.net" -; Version -!getdllversion "..\Release\LegacyUpdate.dll" DLLVersion_ -!define LONGVERSION "${DLLVersion_1}.${DLLVersion_2}.${DLLVersion_3}.${DLLVersion_4}" -!define VERSION "${DLLVersion_1}.${DLLVersion_2}.${DLLVersion_3}" +; Build +!if ${DEBUG} == 1 + !define VSBUILD32 "Debug-VC08" + !define VSBUILD64 "Debug-VC17" +!else + !define VSBUILD32 "Release" + !define VSBUILD64 "Release" +!endif -!if ${DLLVersion_3} == 0 +; NSIS target +!ifdef NSIS_UNICODE + !define NSIS_CHARSET "unicode" +!else + !define NSIS_CHARSET "ansi" +!endif +!define NSIS_TARGET "${NSIS_CPU}-${NSIS_CHARSET}" + +; Version +!getdllversion "..\${VSBUILD32}\LegacyUpdate.dll" DLLVersion_ +!define LONGVERSION "${DLLVersion_1}.${DLLVersion_2}.${DLLVersion_3}.${DLLVersion_4}" +!define VERSION "${LONGVERSION}" + +!if ${DLLVersion_4} == 0 + !define /redef VERSION "${DLLVersion_1}.${DLLVersion_2}.${DLLVersion_3}" +!endif + +!if ${DLLVersion_3}.${DLLVersion_4} == 0.0 !define /redef VERSION "${DLLVersion_1}.${DLLVersion_2}" !endif @@ -15,37 +36,68 @@ !define WEBSITE "http://legacyupdate.net/" !define UPDATE_URL "http://legacyupdate.net/windowsupdate/v6/" !define UPDATE_URL_HTTPS "https://legacyupdate.net/windowsupdate/v6/" -!define WSUS_SERVER "http://update.oldwindows.de" -!define WSUS_SERVER_HTTPS "http://update.oldwindows.de" +!define WSUS_SERVER "http://vichingo455.ddns.net/v6" +!define WSUS_SERVER_HTTPS "https://vichingo455.ddns.net/v6" +!define WUR_WEBSITE "http://windowsupdaterestored.com/" !define TRUSTEDR "http://download.windowsupdate.com/msdownload/update/v3/static/trustedr/en" -!define WIN81UPGRADE_URL "https://go.microsoft.com/fwlink/?LinkId=798437" ; Control Panel entry !define CPL_GUID "{FFBE8D44-E9CF-4DD8-9FD6-976802C94D9C}" !define CPL_APPNAME "LegacyUpdate" -; RunOnce -!define RUNONCE_USERNAME "LegacyUpdateTemp" -!define RUNONCE_PASSWORD "Legacy_Update0" +; IE elevation policy +!define ELEVATIONPOLICY_GUID "{3D800943-0434-49F2-89A1-472A259AD982}" -; Registry keys +; Legacy Update keys !define REGPATH_LEGACYUPDATE_SETUP "Software\Hashbang Productions\Legacy Update\Setup" !define REGPATH_UNINSTSUBKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" -!define REGPATH_WUPOLICY "Software\Policies\Microsoft\Windows\WindowsUpdate" -!define REGPATH_WUAUPOLICY "${REGPATH_WUPOLICY}\AU" + +; Control Panel entry +!define REGPATH_CPLNAMESPACE "Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\${CPL_GUID}" +!define REGPATH_HKCR_CPLCLSID "CLSID\${CPL_GUID}" + +; System +!define REGPATH_HARDWARE_SYSTEM "Hardware\Description\System" +!define REGPATH_CONTROL_LANGUAGE "System\CurrentControlSet\Control\Nls\Language" +!define REGPATH_CONTROL_WINDOWS "System\CurrentControlSet\Control\Windows" + +; XP POSReady hack +!define REGPATH_POSREADY "System\WPA\PosReady" + +; RunOnce +!define REGPATH_SETUP "System\Setup" +!define REGPATH_RUNONCE "Software\Microsoft\Windows\CurrentVersion\RunOnce" +!define REGPATH_POLICIES_SYSTEM "Software\Microsoft\Windows\CurrentVersion\Policies\System" +!define REGPATH_SECURITYCENTER "Software\Microsoft\Security Center" + +; Windows Update keys !define REGPATH_WU "Software\Microsoft\Windows\CurrentVersion\WindowsUpdate" !define REGPATH_WU_SERVICES "${REGPATH_WU}\Services" + +; Windows Update policies +!define REGPATH_WUPOLICY "Software\Policies\Microsoft\Windows\WindowsUpdate" +!define REGPATH_WUAUPOLICY "${REGPATH_WUPOLICY}\AU" + +; CBS keys +!define REGPATH_CBS "Software\Microsoft\Windows\CurrentVersion\Component Based Servicing" +!define REGPATH_CBS_REBOOTPENDING "${REGPATH_CBS}\RebootPending" +!define REGPATH_CBS_PACKAGESPENDING "${REGPATH_CBS}\PackagesPending" +!define REGPATH_CBS_REBOOTINPROGRESS "${REGPATH_CBS}\RebootInProgress" + +; IE zone keys !define REGPATH_INETSETTINGS "Software\Microsoft\Windows\CurrentVersion\Internet Settings" !define REGPATH_ZONEDOMAINS "${REGPATH_INETSETTINGS}\ZoneMap\Domains" !define REGPATH_ZONEESCDOMAINS "${REGPATH_INETSETTINGS}\ZoneMap\EscDomains" -!define REGPATH_CPLNAMESPACE "Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\${CPL_GUID}" -!define REGPATH_CPLCLSID "CLSID\${CPL_GUID}" -!define REGPATH_WINLOGON "Software\Microsoft\Windows NT\CurrentVersion\Winlogon" -!define REGPATH_POSREADY "System\WPA\PosReady" + +; 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_V2 "Software\Microsoft\.NETFramework\v2.0.50727" -!define REGPATH_DOTNET_V4 "Software\Microsoft\.NETFramework\v4.0.30319" -!define REGPATH_RUNONCE "Software\Microsoft\Windows\CurrentVersion\RunOnce" -!define REGPATH_PACKAGEINDEX "Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackageIndex" -!define REGPATH_SERVICING_SHA2 "Software\Microsoft\Windows\CurrentVersion\Servicing\Codesigning\SHA2" -!define REGPATH_COMPONENT_THEMES "Software\Microsoft\Active Setup\Installed Components\{2C7339CF-2B09-4501-B3F3-F3508C9228ED}" +!define REGPATH_DOTNET "Software\Microsoft\.NETFramework" +!define REGPATH_DOTNET_V2 "${REGPATH_DOTNET}\v2.0.50727" +!define REGPATH_DOTNET_V4 "${REGPATH_DOTNET}\v4.0.30319" + +; Roots update keys +!define ROOTSUPDATE_GUID "{EF289A85-8E57-408d-BE47-73B55609861A}" +!define REGPATH_COMPONENTS "Software\Microsoft\Active Setup\Installed Components" diff --git a/setup/Download2KXP.nsh b/setup/Download2KXP.nsh index eee57f2..25085be 100644 --- a/setup/Download2KXP.nsh +++ b/setup/Download2KXP.nsh @@ -1,11 +1,11 @@ Function GetUpdateLanguage Var /GLOBAL UpdateLanguage ${If} $UpdateLanguage == "" - ReadRegStr $UpdateLanguage HKLM "Hardware\Description\System" "Identifier" + ReadRegStr $UpdateLanguage HKLM "${REGPATH_HARDWARE_SYSTEM}" "Identifier" ${If} $UpdateLanguage == "NEC PC-98" StrCpy $UpdateLanguage "NEC98" ${Else} - ReadRegStr $UpdateLanguage HKLM "System\CurrentControlSet\Control\Nls\Language" "InstallLanguage" + ReadRegStr $UpdateLanguage HKLM "${REGPATH_CONTROL_LANGUAGE}" "InstallLanguage" ReadINIStr $UpdateLanguage $PLUGINSDIR\Patches.ini Language $UpdateLanguage ${EndIf} ${EndIf} @@ -51,19 +51,34 @@ Function -PatchHandler ClearErrors ReadINIStr $0 $PLUGINSDIR\Patches.ini "$Patch.Key" $1 ${If} ${Errors} - MessageBox MB_USERICON "$Patch.Title could not be installed.$\r$\n$\r$\nThe installed Windows language and/or architecture is not supported." /SD IDOK + StrCpy $0 "$Patch.Title" + MessageBox MB_USERICON "$(MsgBoxPatchNotFound)" /SD IDOK SetErrorLevel 1 Abort ${EndIf} ${EndIf} - !insertmacro Download "$Patch.Title" "$0" "$Patch.File" 1 + ReadINIStr $1 $PLUGINSDIR\Patches.ini "$Patch.Key" Prefix + !insertmacro Download "$Patch.Title" "$1$0" "$Patch.File" 1 FunctionEnd -!macro PatchHandler kbid title params +!define PATCH_FLAGS_OTHER 0 +!define PATCH_FLAGS_NT4 1 +!define PATCH_FLAGS_SHORT 2 +!define PATCH_FLAGS_LONG 3 + +!macro -PatchHandlerFlags params cleanup +!if ${DEBUG} == 1 + ; To make testing go faster + StrCpy $R0 "${params} ${cleanup}" +!else + ; NT4 branch will add a SkipSPUninstall setting. For now, we ignore the cleanup param. + StrCpy $R0 "${params}" +!endif +!macroend + +!macro PatchHandler kbid title type params Function Download${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 + ${If} ${NeedsPatch} ${kbid} StrCpy $Patch.Key "${kbid}" StrCpy $Patch.File "${kbid}.exe" StrCpy $Patch.Title "${title}" @@ -72,51 +87,70 @@ FunctionEnd FunctionEnd Function Install${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 - Call Download${kbid} - !insertmacro Install "${title}" "${kbid}.exe" "${params}" + ${IfNot} ${NeedsPatch} ${kbid} + Return ${EndIf} + + Call Download${kbid} +!if ${type} == ${PATCH_FLAGS_OTHER} + StrCpy $R0 "" +!endif +!if ${type} == ${PATCH_FLAGS_NT4} + !insertmacro -PatchHandlerFlags "-z" "-n -o" +!endif +!if ${type} == ${PATCH_FLAGS_SHORT} + !insertmacro -PatchHandlerFlags "-u -z" "-n -o" +!endif +!if ${type} == ${PATCH_FLAGS_LONG} + !insertmacro -PatchHandlerFlags "/passive /norestart" "/n /o" +!endif + !insertmacro Install "${title}" "${kbid}.exe" "$R0 ${params}" FunctionEnd !macroend !insertmacro NeedsSPHandler "W2KSP4" "Win2000" 2 -!insertmacro NeedsSPHandler "XPSP2" "WinXP2002" 0 +!insertmacro NeedsSPHandler "XPSP1a" "WinXP2002" 0 !insertmacro NeedsSPHandler "XPSP3" "WinXP2002" 2 !insertmacro NeedsSPHandler "XPESP3" "WinXP2002" 2 !insertmacro NeedsSPHandler "2003SP2" "WinXP2003" 1 -!insertmacro NeedsFileVersionHandler "KB835732" "kernel32.dll" "5.00.2195.6897" -!insertmacro NeedsFileVersionHandler "IE6" "mshtml.dll" "6.0.2600.0" +!insertmacro NeedsFileVersionHandler "W2KUR1" "kernel32.dll" "5.00.2195.7006" +!insertmacro NeedsFileVersionHandler "IE6" "mshtml.dll" "6.0.2600.0" -!insertmacro PatchHandler "W2KSP4" "Windows 2000 Service Pack 4" "-u -z" -!insertmacro PatchHandler "KB835732" "Windows 2000 KB835732 Update" "/passive /norestart" -!insertmacro PatchHandler "XPSP2" "Windows XP Service Pack 2" "/passive /norestart" -!insertmacro PatchHandler "XPSP3" "Windows XP Service Pack 3" "/passive /norestart" -!insertmacro PatchHandler "2003SP2" "Windows XP x64 Edition/Server 2003 Service Pack 2" "/passive /norestart" -!insertmacro PatchHandler "XPESP3" "Windows XP Embedded Service Pack 3" "/passive /norestart" +!insertmacro PatchHandler "W2KSP4" "Windows 2000 $(SP) 4" ${PATCH_FLAGS_SHORT} "" +!insertmacro PatchHandler "W2KUR1" "$(SectionW2KUR1)" ${PATCH_FLAGS_LONG} "" +!insertmacro PatchHandler "XPSP1a" "Windows XP $(SP) 1a" ${PATCH_FLAGS_SHORT} "" +!insertmacro PatchHandler "XPSP3" "Windows XP $(SP) 3" ${PATCH_FLAGS_LONG} "" +!insertmacro PatchHandler "2003SP2" "Windows XP $(P64)/$(SRV) 2003 $(SP) 2" ${PATCH_FLAGS_LONG} "" +!insertmacro PatchHandler "XPESP3" "Windows XP $(EMB) $(SP) 3" ${PATCH_FLAGS_LONG} "" Function DownloadIE6 - Call NeedsIE6 - Pop $0 - ${If} $0 == 1 + ${If} ${NeedsPatch} IE6 StrCpy $Patch.Key "W2KIE6" StrCpy $Patch.File "ie6sp1.cab" - StrCpy $Patch.Title "Internet Explorer 6 SP1" + StrCpy $Patch.Title "$(IE) 6 $(SP) 1 $(Setup)" Call -PatchHandler + + ${IfNot} ${FileExists} "$PLUGINSDIR\W2KIE6\ie6setup.exe" + ${DetailPrint} "$(Extracting)$(IE) 6 $(SP) 1 $(Setup)..." + CreateDirectory "$PLUGINSDIR\W2KIE6" + !insertmacro ExecWithErrorHandling '$(IE) 6 $(SP) 1' '"$WINDIR\system32\expand.exe" -F:* ie6sp1.cab "$PLUGINSDIR\W2KIE6"' + ${DetailPrint} "$(Downloading)$(IE) 6 $(SP) 1..." + !insertmacro ExecWithErrorHandling '$(IE) 6 $(SP) 1' '"$PLUGINSDIR\W2KIE6\ie6setup.exe" /c:"ie6wzd.exe /q /d /s:""#e"""' + ${EndIf} ${EndIf} FunctionEnd Function InstallIE6 - Call NeedsIE6 - Pop $0 - ${If} $0 == 1 + ${If} ${NeedsPatch} IE6 Call DownloadIE6 - !insertmacro DetailPrint "Extracting Internet Explorer 6 SP1..." - ExecShellWait "" "$WINDIR\system32\expand.exe" '"$OUTDIR\ie6sp1.cab" -F:ie6setup.exe "$PLUGINSDIR"' SW_HIDE - ExecShellWait "" "$WINDIR\system32\expand.exe" '"$OUTDIR\ie6sp1.cab" -F:iebatch.txt "$PLUGINSDIR"' SW_HIDE - !insertmacro DetailPrint "Installing Internet Explorer 6 SP1..." - !insertmacro ExecWithErrorHandling 'Internet Explorer 6 SP1' '"$PLUGINSDIR\ie6setup.exe" /q' 0 + ${DetailPrint} "$(Installing)$(IE) 6 $(SP) 1..." + StrCpy $RunOnce.UseFallback 1 + !insertmacro ExecWithErrorHandling '$(IE) 6 $(SP) 1' '"$PLUGINSDIR\W2KIE6\ie6setup.exe" /c:"ie6wzd.exe /q /r:n /s:""#e"""' ${EndIf} FunctionEnd + +Function FixW2KUR1 + ; Fix idling on multi-CPU systems when Update Rollup 1 is installed + WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\HAL" "14140000FFFFFFFF" 0x10 +FunctionEnd diff --git a/setup/Download8.nsh b/setup/Download8.nsh deleted file mode 100644 index a6d2558..0000000 --- a/setup/Download8.nsh +++ /dev/null @@ -1,46 +0,0 @@ -; Windows 8 Servicing Stack -!insertmacro MSUHandler "KB4598297" "2021-01 Servicing Stack Update for Windows Server 2012" "Package_for_KB4598297" - -; Windows 8.1 Servicing Stack -!insertmacro MSUHandler "KB3021910" "2015-04 Servicing Stack Update for Windows 8.1" "Package_for_KB3021910" - -; Windows 8.1 Update 1 -!insertmacro MSUHandler "KB2919355" "Windows 8.1 Update 1" "Package_for_KB2919355" -!insertmacro MSUHandler "KB2932046" "Windows 8.1 Update 1" "Package_for_KB2932046" -!insertmacro MSUHandler "KB2959977" "Windows 8.1 Update 1" "Package_for_KB2959977" -!insertmacro MSUHandler "KB2937592" "Windows 8.1 Update 1" "Package_for_KB2937592" -!insertmacro MSUHandler "KB2934018" "Windows 8.1 Update 1" "Package_for_KB2934018" - -Function NeedsWin81Update1 - Call NeedsKB2919355 - Call NeedsKB2932046 - Call NeedsKB2937592 - Call NeedsKB2934018 - Pop $0 - Pop $1 - Pop $2 - Pop $3 - Pop $4 - - ${If} $0 == 1 - ${OrIf} $1 == 1 - ${OrIf} $2 == 1 - ${OrIf} $3 == 1 - Push 1 - ${Else} - Push 0 - ${EndIf} -FunctionEnd - -; Weird prerequisite to Update 1 that fixes the main KB2919355 update failing to install -Function DownloadClearCompressionFlag - Call GetArch - Pop $0 - ReadINIStr $0 $PLUGINSDIR\Patches.ini ClearCompressionFlag $0 - !insertmacro Download "Windows 8.1 Update 1 Preparation Tool" "$0" "ClearCompressionFlag.exe" 1 -FunctionEnd - -Function InstallClearCompressionFlag - Call DownloadClearCompressionFlag - !insertmacro Install "Windows 8.1 Update 1 Preparation Tool" "ClearCompressionFlag.exe" "" -FunctionEnd diff --git a/setup/DownloadVista7.nsh b/setup/DownloadVista7.nsh deleted file mode 100644 index 2ab58b2..0000000 --- a/setup/DownloadVista7.nsh +++ /dev/null @@ -1,149 +0,0 @@ -Function GetComponentArch - Var /GLOBAL ComponentArch - ${If} $ComponentArch == "" - ${If} ${IsNativeIA32} - StrCpy $ComponentArch "x86" - ${ElseIf} ${IsNativeAMD64} - StrCpy $ComponentArch "amd64" - ${ElseIf} ${IsNativeIA64} - StrCpy $ComponentArch "ia64" - ${Else} - StrCpy $ComponentArch "" - ${EndIf} - ${EndIf} - Push $ComponentArch -FunctionEnd - -!macro SPHandler kbid title os sp - !insertmacro NeedsSPHandler "${kbid}" "${os}" "${sp}" - - Function Download${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 - Call GetArch - Pop $0 - ReadINIStr $0 $PLUGINSDIR\Patches.ini "${kbid}" $0 - !insertmacro Download "${title}" "$0" "${kbid}.exe" 1 - ${EndIf} - FunctionEnd - - Function Install${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 - Call Download${kbid} - !insertmacro InstallSP "${title}" "${kbid}.exe" - ${EndIf} - FunctionEnd -!macroend - -!macro MSUHandler kbid title packagename - Function Needs${kbid} - Call GetComponentArch - Pop $0 - ClearErrors - EnumRegKey $1 HKLM "${REGPATH_PACKAGEINDEX}\${packagename}~31bf3856ad364e35~$0~~0.0.0.0" 0 - ${If} ${Errors} - Push 1 - ${Else} - Push 0 - ${EndIf} - FunctionEnd - - Function Download${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 - Call GetArch - Pop $0 - ReadINIStr $1 $PLUGINSDIR\Patches.ini "${kbid}" $0 - !insertmacro DownloadMSU "${kbid}" "${title}" "$1" - ${EndIf} - FunctionEnd - - Function Install${kbid} - Call Needs${kbid} - Pop $0 - ${If} $0 == 1 - Call Download${kbid} - !insertmacro InstallMSU "${kbid}" "${title}" - ${EndIf} - FunctionEnd -!macroend - -; Service Packs -!insertmacro SPHandler "VistaSP1" "Windows Vista Service Pack 1" "WinVista" 0 -!insertmacro SPHandler "VistaSP2" "Windows Vista Service Pack 2" "WinVista" 1 -!insertmacro SPHandler "Win7SP1" "Windows 7 Service Pack 1" "Win7" 0 - -; Windows Vista post-SP2 update combination that fixes WU indefinitely checking for updates -!insertmacro MSUHandler "KB3205638" "Security Update for Windows Vista" "Package_for_KB3205638" -!insertmacro MSUHandler "KB4012583" "Security Update for Windows Vista" "Package_for_KB4012583" -!insertmacro MSUHandler "KB4015195" "Security Update for Windows Vista" "Package_for_KB4015195" -!insertmacro MSUHandler "KB4015380" "Security Update for Windows Vista" "Package_for_KB4015380" - -; Vista IE9 -!insertmacro MSUHandler "KB971512" "Update for Windows Vista" "Package_for_KB971512" -!insertmacro MSUHandler "KB2117917" "Platform Update Supplement for Windows Vista" "Package_for_KB2117917" - -!insertmacro NeedsFileVersionHandler "IE9" "mshtml.dll" "9.0.8112.16421" -!insertmacro PatchHandler "IE9" "Internet Explorer 9 for Windows Vista" "/passive /norestart /update-no /closeprograms" - -; Windows Vista Servicing Stack Update -!insertmacro MSUHandler "KB4493730" "2019-04 Servicing Stack Update for Windows Server 2008" "Package_1_for_KB4493730" - -; Windows 7 Servicing Stack Update -!insertmacro MSUHandler "KB3102810" "Update for Windows 7" "Package_for_KB3102810" -!insertmacro MSUHandler "KB3138612" "2016-03 Servicing Stack Update for Windows 7" "Package_for_KB3138612" -!insertmacro MSUHandler "KB4474419" "SHA-2 Code Signing Support Update for Windows 7" "Package_for_KB4474419" -!insertmacro MSUHandler "KB4490628" "2019-03 Servicing Stack Update for Windows 7" "Package_for_KB3138612" - -; Windows Home Server 2011 Update Rollup 4 -!insertmacro MSUHandler "KB2757011" "Windows Home Server 2011 Update Rollup 4" "Package_for_KB2757011" - -Function NeedsVistaPostSP2 - Call NeedsKB3205638 - Call NeedsKB4012583 - Call NeedsKB4015195 - Call NeedsKB4015380 - Call NeedsKB4493730 - Pop $0 - Pop $1 - Pop $2 - Pop $3 - Pop $4 - ${If} $0 == 1 - ${OrIf} $1 == 1 - ${OrIf} $2 == 1 - ${OrIf} $3 == 1 - ${OrIf} $4 == 1 - Push 1 - ${Else} - Push 0 - ${EndIf} -FunctionEnd - -Function NeedsWin7SHA2 - ReadRegDWORD $0 HKLM "${REGPATH_SERVICING_SHA2}" "SHA2-Codesigning-Support" - ${If} $0 == 1 - Push 0 - ${Else} - Call NeedsKB3102810 - Call NeedsKB3138612 - Call NeedsKB4474419 - Call NeedsKB4490628 - Pop $0 - Pop $1 - Pop $2 - Pop $3 - ${If} $0 == 1 - ${OrIf} $1 == 1 - ${OrIf} $2 == 1 - ${OrIf} $3 == 1 - Push 1 - ${Else} - Push 0 - ${EndIf} - ${EndIf} -FunctionEnd diff --git a/setup/DownloadWUA.nsh b/setup/DownloadWUA.nsh index 00db8ea..5c4566d 100644 --- a/setup/DownloadWUA.nsh +++ b/setup/DownloadWUA.nsh @@ -1,40 +1,51 @@ Function DetermineWUAVersion - ; Hardcoded special case for XP Home/Embedded SP3, because the WUA 7.6.7600.256 setup SFX is - ; seriously broken on it, potentially causing an unbootable Windows install due to it entering an - ; infinite loop of creating folders in the root of C:. - ${If} ${IsWinXP2002} - ${AndIf} ${AtLeastServicePack} 3 - ${AndIf} ${IsHomeEdition} - ${OrIf} ${IsEmbedded} - StrCpy $1 "5.1.3-home" - ${Else} - GetWinVer $1 Major - GetWinVer $2 Minor - GetWinVer $3 ServicePack - StrCpy $1 "$1.$2.$3" - ${EndIf} - - StrCpy $0 "" - - ClearErrors - ReadINIStr $2 $PLUGINSDIR\Patches.ini WUA $1 - ${If} ${Errors} + ; WUA refuses to install on 2000 Datacenter Server. Maybe we can hack around this in future. + ${If} ${IsWin2000} + ${AndIf} ${IsDatacenter} + StrCpy $0 "" Return ${EndIf} - ${GetFileVersion} "$SYSDIR\wuapi.dll" $1 + GetWinVer $1 Major + GetWinVer $2 Minor + GetWinVer $3 ServicePack + StrCpy $1 "$1.$2.$3" + + ; Hardcoded special case for XP Home/Embedded SP3, because the WUA 7.6.7600.256 setup SFX is seriously broken on it, + ; potentially causing an unbootable Windows install due to it entering an infinite loop of creating folders in the + ; root of C:. + ${If} $1 == "5.1.3" + ${If} ${IsHomeEdition} + ${OrIf} ${IsEmbedded} + StrCpy $1 "$1-home" + ${EndIf} + ${EndIf} + + StrCpy $0 "" + ReadINIStr $2 $PLUGINSDIR\Patches.ini WUA $1 + ${If} $2 == "" + Return + ${EndIf} + + ${GetFileVersion} "$SYSDIR\wuaueng.dll" $1 ${VersionCompare} $1 $2 $3 ${If} $3 == 2 Call GetArch Pop $0 ReadINIStr $0 $PLUGINSDIR\Patches.ini WUA $2-$0 + ${If} $0 == "" + Return + ${EndIf} + + ReadINIStr $1 $PLUGINSDIR\Patches.ini WUA Prefix + StrCpy $0 "$1$0" ${EndIf} FunctionEnd Function DownloadWUA Call DetermineWUAVersion ${If} $0 != "" - !insertmacro Download "Windows Update Agent" "$0" "WindowsUpdateAgent.exe" 1 + !insertmacro Download "$(WUA)" "$0" "WindowsUpdateAgent.exe" 1 ${EndIf} FunctionEnd @@ -42,6 +53,6 @@ Function InstallWUA Call DetermineWUAVersion ${If} $0 != "" Call DownloadWUA - !insertmacro Install "Windows Update Agent" "WindowsUpdateAgent.exe" "/quiet /norestart" + !insertmacro Install "$(WUA)" "WindowsUpdateAgent.exe" "/quiet /norestart" ${EndIf} FunctionEnd diff --git a/setup/GWXWebWindows.exe b/setup/GWXWebWindows.exe deleted file mode 100644 index ac1bed0..0000000 Binary files a/setup/GWXWebWindows.exe and /dev/null differ diff --git a/setup/Patches.ini b/setup/Patches.ini index a15b46f..61701b6 100644 --- a/setup/Patches.ini +++ b/setup/Patches.ini @@ -38,143 +38,148 @@ ; Windows 2000 [W2KSP4] -ARA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_ar_d2a46163d29f14829f230729e2c0821.exe -CHH-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_hk_89b5425007c388c1c146756557915ab.exe -CHS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_cn_a6d8fab4fe598cf1d5c3cf257b11fc8.exe -CHT-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_tw_baf16f1aaae8be095127f4a46dded69.exe -CSY-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_cs_d055279f80e684debdac3f4a230ab2c.exe -DAN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_da_e9afc8657e31b34730ea2cda85ece36.exe -DEU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_de_00d4912b4703c77c46cf53a8a8f2027.exe -ELL-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_el_55eeec8b3b303e61cb0ddab4d943cd1.exe -ENU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_en_7f12d2da3d7c5b6a62ec4fde9a4b1e6.exe -ESN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_es_51bae94c83adcf9f0ad3155bcf3ddfc.exe -FIN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_fi_794e2bba5a5286287dccf7943055e46.exe -FRA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_fr_4556797dfc88fdd4be13d638bcfb655.exe -HEB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_he_b8e8519d7ae067f49ce742b59e8bcce.exe -HUN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_hu_1de3d254582472c714af315c85bf2b3.exe -ITA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_it_6395c3848397fa6cf05e0c3d1923205.exe -JPN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_ja_beb10c6f96ac4bb93f6e192b419a50f.exe -KOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_ko_8bd7a0eedfaf1fb30439abdad43c347.exe -NLD-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_nl_07596ad911493b966a18b6626e4a1c4.exe -NOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_no_64602c5f513d7244dd5790c6a11577e.exe -PLK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_pl_5248f4f8262d599079f5ee246cafc28.exe -PTB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_br_a90a49821bf9b5e37810e4c453a5128.exe -PTG-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_pt_cdf5d5ecd163862ff6f641b0a4d4168.exe -RUS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_ru_980742b1376cf5614a9e10705952dcd.exe -SVE-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_sv_c46814adb550c5184297a290acd9d25.exe -TRK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_tr_3d5c002a300e271049b18acdc569d83.exe -NEC98-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/w2ksp4_ja_7cf59dd6babe7afcf1d7489b40941a8.exe +Prefix=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ +ARA-x86=w2ksp4_ar_d2a46163d29f14829f230729e2c0821.exe +CHH-x86=w2ksp4_hk_89b5425007c388c1c146756557915ab.exe +CHS-x86=w2ksp4_cn_a6d8fab4fe598cf1d5c3cf257b11fc8.exe +CHT-x86=w2ksp4_tw_baf16f1aaae8be095127f4a46dded69.exe +CSY-x86=w2ksp4_cs_d055279f80e684debdac3f4a230ab2c.exe +DAN-x86=w2ksp4_da_e9afc8657e31b34730ea2cda85ece36.exe +DEU-x86=w2ksp4_de_00d4912b4703c77c46cf53a8a8f2027.exe +ELL-x86=w2ksp4_el_55eeec8b3b303e61cb0ddab4d943cd1.exe +ENU-x86=w2ksp4_en_7f12d2da3d7c5b6a62ec4fde9a4b1e6.exe +ESN-x86=w2ksp4_es_51bae94c83adcf9f0ad3155bcf3ddfc.exe +FIN-x86=w2ksp4_fi_794e2bba5a5286287dccf7943055e46.exe +FRA-x86=w2ksp4_fr_4556797dfc88fdd4be13d638bcfb655.exe +HEB-x86=w2ksp4_he_b8e8519d7ae067f49ce742b59e8bcce.exe +HUN-x86=w2ksp4_hu_1de3d254582472c714af315c85bf2b3.exe +ITA-x86=w2ksp4_it_6395c3848397fa6cf05e0c3d1923205.exe +JPN-x86=w2ksp4_ja_beb10c6f96ac4bb93f6e192b419a50f.exe +KOR-x86=w2ksp4_ko_8bd7a0eedfaf1fb30439abdad43c347.exe +NLD-x86=w2ksp4_nl_07596ad911493b966a18b6626e4a1c4.exe +NOR-x86=w2ksp4_no_64602c5f513d7244dd5790c6a11577e.exe +PLK-x86=w2ksp4_pl_5248f4f8262d599079f5ee246cafc28.exe +PTB-x86=w2ksp4_br_a90a49821bf9b5e37810e4c453a5128.exe +PTG-x86=w2ksp4_pt_cdf5d5ecd163862ff6f641b0a4d4168.exe +RUS-x86=w2ksp4_ru_980742b1376cf5614a9e10705952dcd.exe +SVE-x86=w2ksp4_sv_c46814adb550c5184297a290acd9d25.exe +TRK-x86=w2ksp4_tr_3d5c002a300e271049b18acdc569d83.exe +NEC98-x86=w2ksp4_ja_7cf59dd6babe7afcf1d7489b40941a8.exe -[KB835732] -ARA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-ara_caf56d0f9606b68387a228f7aae57d5.exe -CHH-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-cht_c3991c4bde0e9996c3d0727cd3fdbc1.exe -CHS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-chs_779d1b67c993ed5edaeeb6706f37a0d.exe -CHT-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-cht_c3991c4bde0e9996c3d0727cd3fdbc1.exe -CSY-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-csy_c4f86e2d69be35ba780c4f930b43e63.exe -DAN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-dan_3a6d22e0daccb7fe2d77ccda8624283.exe -DEU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-deu_62210b6322e8370917f00fb0eb40bf1.exe -ELL-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-ell_5f2073b1f1cad898c61bea003084320.exe -ENU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-enu_7b7d1dffd9347af2c166bfcecc4782c.exe -ESN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-esn_d62fd2652c870e4a06766638a4b119b.exe -FIN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-fin_08a377df67f697ce14d53d1d9f8dab1.exe -FRA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-fra_85fb76a002b43ad7f8bf236a4469ad4.exe -HEB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-heb_4c1f72024873e31a37fad21b9194dfc.exe -HUN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-hun_538b15f6b13aba4549248313cfa4c7c.exe -ITA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-ita_10e1ca8aec2249cca79a2dd6f7d05ff.exe -JPN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-jpn_2602d9d56b3995923611494ea90f535.exe -KOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-kor_852d1690cd8c36ecf681a454fac484a.exe -NLD-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-nld_742d6aadbbe08ca67b755e0abaaeb8c.exe -NOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-nor_99fac6bc7b291e7bc6d7655ea8da446.exe -PLK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-plk_27a55ddbb55db37b9e15e9975b3f106.exe -PTB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-ptb_f7d297c52fd7ef6006d3b2798a10025.exe -PTG-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-ptg_67c7095f1db29bb1b4ecb3d253fdde7.exe -RUS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-rus_0d1eca332ca7543d4cf80846eee3a80.exe -SVE-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-sve_087a446929bed6a79649a7c5a418220.exe -TRK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-x86-trk_8dc398f69b7c8c59466511aa21eb67c.exe -NEC98-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windows2000-kb835732-nec98-jpn_8fb43a1fa0f40115cae8f3ea72d52bc.exe +[W2KUR1] +Prefix=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ +ARA-x86=windows2000-kb891861-v2-x86-ara_73c7fa3d013476d3a2b8ff8569e3bc82f1ad1582.exe +CHH-x86=windows2000-kb891861-v2-x86-cht_4b7c5abb4e313f5cbd5f139ea7094145e2a80b5a.exe +CHS-x86=windows2000-kb891861-v2-x86-chs_fe99e12ef1944cc43ad2891797ac9a7698e194d9.exe +CHT-x86=windows2000-kb891861-v2-x86-cht_4b7c5abb4e313f5cbd5f139ea7094145e2a80b5a.exe +CSY-x86=windows2000-kb891861-v2-x86-csy_a18b67cb73d57b03d9ae276097e33ae870acc77d.exe +DAN-x86=windows2000-kb891861-v2-x86-dan_0b5521ef897e7859fefd1ceace978ba06a67caf6.exe +DEU-x86=windows2000-kb891861-v2-x86-deu_e2c13be516127d3b1de17a60b9fadfb11862b86b.exe +ELL-x86=windows2000-kb891861-v2-x86-ell_e04a73c2761a323c0b266f766c5cc3e6f9389b76.exe +ENU-x86=windows2000-kb891861-v2-x86-enu_f118bd276f4211929719961a2e929b620c1a2234.exe +ESN-x86=windows2000-kb891861-v2-x86-esn_b9f1a26cc909adca730ed20344cf712480c9877e.exe +FIN-x86=windows2000-kb891861-v2-x86-fin_318d6b6a1ac04e9c9c033d53d7fcd47748e7f75f.exe +FRA-x86=windows2000-kb891861-v2-x86-fra_8d036d92d4895bf23b0e9b714937b5b211b1d592.exe +HEB-x86=windows2000-kb891861-v2-x86-heb_3f08f4037db77733e5de5e1cb89e5bedebb4d249.exe +HUN-x86=windows2000-kb891861-v2-x86-hun_d94efec685c682825592e04130ea1b0bf3c4e532.exe +ITA-x86=windows2000-kb891861-v2-x86-ita_aaf013cd7a046d6069c0250e8e7f0bf8582c3e31.exe +JPN-x86=windows2000-kb891861-v2-x86-jpn_d5fa54ab3547a38fae6260e28227a6fb0ed4a827.exe +KOR-x86=windows2000-kb891861-v2-x86-kor_10db79be10624535fb3926781db5a02efb2b5503.exe +NLD-x86=windows2000-kb891861-v2-x86-nld_33cbe9c7dedc85d22f6fc281aefef77b9d26ce6f.exe +NOR-x86=windows2000-kb891861-v2-x86-nor_6dce467272a1cb3375bc74bec901a581d55661e6.exe +PLK-x86=windows2000-kb891861-v2-x86-plk_1cded665d65ea7614b7b33989efb81a4b91cf674.exe +PTB-x86=windows2000-kb891861-v2-x86-ptb_d1a5c2bf1c9393f64748bab275339d09f767a1d9.exe +PTG-x86=windows2000-kb891861-v2-x86-ptg_ad4fd8ab12ee20236a44cf3e550ee55a3e8019ec.exe +RUS-x86=windows2000-kb891861-v2-x86-rus_2d2b365faf8fc71be99122fa89b8eea97ae40abd.exe +SVE-x86=windows2000-kb891861-v2-x86-sve_e694a39661f9a6531c1b9367ed6fc9458ae536fb.exe +TRK-x86=windows2000-kb891861-v2-x86-trk_31ee7902955f771a63b8bd6165fa41119624ac23.exe +NEC98-x86=windows2000-kb891861-v2-nec98-jpn_ca1372faeb77c66ded958bd3dc8e3344e1cd4260.exe [W2KIE6] -ARA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-ara_b1720a72becd05142cb4ccbb23205c76b51d29e2.cab -CHH-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-cht_1899bffb8ebf36c0a58686f04cc1d721c419792d.cab -CHS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-chs_6d93ab8525d3b6f775faf692caaa4c8267c8a22b.cab -CHT-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-cht_1899bffb8ebf36c0a58686f04cc1d721c419792d.cab -CSY-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-csy_2789a030bba2128fc90e0475e2530c300ed5defc.cab -DAN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-dan_0c178b2634a97a4879c172797b21a59e567d18e6.cab -DEU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-deu_2a13ac14e403ad4a1c6877fe478067e81ac20da8.cab -ELL-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-ell_15a4e43c8922f658eddd5d57d23c11e0fa55dce9.cab -ENU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-enu_91192253c8d3cf7beff22e68ae1fdff9638bf546.cab -ESN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-esn_a9c53ad93bae78becf2b06f6d317ef7ef66a2abe.cab -FIN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-fin_1a369fcc86e803128144e17246e16d0a27a8c35b.cab -FRA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-fra_0bc4219b3119a127503cd93863cfedfb1e37bd55.cab -HEB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-heb_70518dd1d09d702975b8e44a22c88e139f168975.cab -HUN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-hun_1eeed3e7b3e6bd311c17c0d97f67ec12df8b4b85.cab -ITA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-ita_2c6ab20b41114e53646ebb56ff6d269fd86fba36.cab -JPN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-jpn_b1e1e8b9dbbf440d8964ec375348674502ef0728.cab -KOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-kor_f61474b056ae37c5e9670978c6d3b24f4800d7f5.cab -NLD-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-nld_3fd676fe34f93471f4db9a0a1f3ef5c3ed8e5f43.cab -NOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-nor_72a81d06462c5a66f9531f4f226b13463698dd24.cab -PLK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-plk_14889750985a9d29490886c2e901ef3bc69c4ff5.cab -PTB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-ptb_448df44aea5d853e4954d48411b1953569df23c2.cab -PTG-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-ptg_5892593c72f702ba6c7d88b47c2bd7c5707081fd.cab -RUS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-rus_842c289d0887bbe2e4edea1ff3763addc8d77db5.cab -SVE-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-sve_db8dcfef073f2df327fc3706d9a141b6124cfed0.cab -TRK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-trk_64479241feb2f783f851b16791d5d1c684d94a66.cab -NEC98-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ie6sp1-wucab-jpn_b1e1e8b9dbbf440d8964ec375348674502ef0728.cab +Prefix=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ +ARA-x86=ie6sp1-wucab-ara_b1720a72becd05142cb4ccbb23205c76b51d29e2.cab +CHH-x86=ie6sp1-wucab-cht_1899bffb8ebf36c0a58686f04cc1d721c419792d.cab +CHS-x86=ie6sp1-wucab-chs_6d93ab8525d3b6f775faf692caaa4c8267c8a22b.cab +CHT-x86=ie6sp1-wucab-cht_1899bffb8ebf36c0a58686f04cc1d721c419792d.cab +CSY-x86=ie6sp1-wucab-csy_2789a030bba2128fc90e0475e2530c300ed5defc.cab +DAN-x86=ie6sp1-wucab-dan_0c178b2634a97a4879c172797b21a59e567d18e6.cab +DEU-x86=ie6sp1-wucab-deu_2a13ac14e403ad4a1c6877fe478067e81ac20da8.cab +ELL-x86=ie6sp1-wucab-ell_15a4e43c8922f658eddd5d57d23c11e0fa55dce9.cab +ENU-x86=ie6sp1-wucab-enu_91192253c8d3cf7beff22e68ae1fdff9638bf546.cab +ESN-x86=ie6sp1-wucab-esn_a9c53ad93bae78becf2b06f6d317ef7ef66a2abe.cab +FIN-x86=ie6sp1-wucab-fin_1a369fcc86e803128144e17246e16d0a27a8c35b.cab +FRA-x86=ie6sp1-wucab-fra_0bc4219b3119a127503cd93863cfedfb1e37bd55.cab +HEB-x86=ie6sp1-wucab-heb_70518dd1d09d702975b8e44a22c88e139f168975.cab +HUN-x86=ie6sp1-wucab-hun_1eeed3e7b3e6bd311c17c0d97f67ec12df8b4b85.cab +ITA-x86=ie6sp1-wucab-ita_2c6ab20b41114e53646ebb56ff6d269fd86fba36.cab +JPN-x86=ie6sp1-wucab-jpn_b1e1e8b9dbbf440d8964ec375348674502ef0728.cab +KOR-x86=ie6sp1-wucab-kor_f61474b056ae37c5e9670978c6d3b24f4800d7f5.cab +NLD-x86=ie6sp1-wucab-nld_3fd676fe34f93471f4db9a0a1f3ef5c3ed8e5f43.cab +NOR-x86=ie6sp1-wucab-nor_72a81d06462c5a66f9531f4f226b13463698dd24.cab +PLK-x86=ie6sp1-wucab-plk_14889750985a9d29490886c2e901ef3bc69c4ff5.cab +PTB-x86=ie6sp1-wucab-ptb_448df44aea5d853e4954d48411b1953569df23c2.cab +PTG-x86=ie6sp1-wucab-ptg_5892593c72f702ba6c7d88b47c2bd7c5707081fd.cab +RUS-x86=ie6sp1-wucab-rus_842c289d0887bbe2e4edea1ff3763addc8d77db5.cab +SVE-x86=ie6sp1-wucab-sve_db8dcfef073f2df327fc3706d9a141b6124cfed0.cab +TRK-x86=ie6sp1-wucab-trk_64479241feb2f783f851b16791d5d1c684d94a66.cab +NEC98-x86=ie6sp1-wucab-jpn_b1e1e8b9dbbf440d8964ec375348674502ef0728.cab ; Windows XP 2002 -[XPSP2] -ARA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_a001b2b27b0f748ab89bd28fa45359f28f95ffb6.exe -CHH-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_546c11a0a5a41e90ae5f021f234d9abad5a0a25a.exe -CHS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_554ee954bae0f65e88b706cf9b9fd733c02fa397.exe -CHT-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_66d8ba2cbf90737010a45e2b5969c9a779ab1d35.exe -CSY-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_767f81c9d0154bfa21d19a49e0b27ede9f93190a.exe -DAN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_e60a2b567fda2ab2cf4629700cf65cd3f4d46b0d.exe -DEU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_ac8d3101744ff56f74a4de941dc04a7e567c8ba7.exe -ELL-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_fd86a331f91bc16185e88e6706db859cb27264d1.exe -ENU-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_33a8fef60d48ae1f2c4feea27111af5ceca3c4f6.exe -ESN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_8e7e8de62676d994a7412df190fcdce848f25cf0.exe -FIN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_2feacc1ad5a703d508e9aee4c2fca1e0b9ca9962.exe -FRA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_da94a031147ebd6f8d02eadb7972801843a533bb.exe -HEB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_76096ed9f2218ac7a14472cbf435f380ffc1c2f6.exe -HUN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_bd03a3d2a28de2de9e58da3e5dec888ffae25aca.exe -ITA-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_1334fdd285666bfd821eef8590914f188b1bcc0c.exe -JPN-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_d36c0a7046f2dbe29dfff33b6dbb6bb4574bbd7d.exe -KOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_4a6b32f007fe94a2a8b4542fc6778582ef4245e3.exe -NLD-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_64551a535981fbcd9c2bac3f91df30c6b3610725.exe -NOR-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_ace2994463597f9cb7cb059e1dca2a87c12bf278.exe -PLK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_8aefc12abade033f2f093786646206fbb70cbb5d.exe -PTB-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_bcbc1bbb2c493dd0a942d13695b18da0400188f8.exe -PTG-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_db1f7c486f0eda249d77ae91c858a162cefb769b.exe -RUS-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_72946fbe955201f2387430963d4372cda7cac392.exe -SVE-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_3ff578d759e77df91effefe34a42030b8ada1c24.exe -TRK-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/xpsp2_68cfeb8fda746b900f9c3ce313d7348c812fd30d.exe +[XPSP1a] +Prefix=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/ +ARA-x86=xpsp1a_e31fa91a89a658f3d586aa1c9992b01af3e11fe0.exe +CHH-x86=xpsp1a_8bd1bde300df00e7bd6831ac37cb87e437e2b729.exe +CHS-x86=xpsp1a_8bd1bde300df00e7bd6831ac37cb87e437e2b729.exe +CHT-x86=xpsp1a_98472ed83897ec104c8496fcd661e6f289ef5090.exe +CSY-x86=xpsp1a_57f0caa259089b1477a162f220d08b1c4bc86010.exe +DAN-x86=xpsp1a_619cc6cf6a98f75d18f4d6eddb662ebfe4a44223.exe +DEU-x86=xpsp1a_cb7d182645ea1019741d9d94732c29251294acdc.exe +ELL-x86=xpsp1a_47666b37340d6224eeb40f67ae16da3e457e64e0.exe +ENU-x86=xpsp1a_8441053935adbfc760b966e5e413d3415a753213.exe +ESN-x86=xpsp1a_e675d08b12d20ca372ba6d3b502074000981870f.exe +FIN-x86=xpsp1a_8a254d89daeb22f4f4ccb9b0861e83cb5ea66196.exe +FRA-x86=xpsp1a_fe557a68aed45003151f647189767aeb2bed53a9.exe +HEB-x86=xpsp1a_499ee7440dba140909fe4d3a86fffd8ec4a1d473.exe +HUN-x86=xpsp1a_9f24000eb4b69aaa975edeb578b4cd22f971318b.exe +ITA-x86=xpsp1a_4f5aa5833bee00c3309fc03d6eafcc6e6f4e2eea.exe +JPN-x86=xpsp1a_a03d9d2ad30a478ca4c2a51c1de26eaca021e4d1.exe +KOR-x86=xpsp1a_e79e224ef297b77c0a23a9440f919c8d64e6554a.exe +NLD-x86=xpsp1a_f1a0183ddc01376d27f374b69fa9364647b336b2.exe +NOR-x86=xpsp1a_487a5bbfcf9164a0cda2bbe31f9d4aed6c5455a2.exe +PLK-x86=xpsp1a_d2a89787c9ac8ed660684686930513663bc723ba.exe +PTB-x86=xpsp1a_87ec9b54ce8b93f7319b2158cbb0fa1de47d48df.exe +PTG-x86=xpsp1a_625bc5ebcc1306c2632c1b1a60a6f8f30f230cb9.exe +RUS-x86=xpsp1a_b5151f669462b3154faf93d48e10beae1b0339aa.exe +SVE-x86=xpsp1a_8f11213e01d65c883a95b8871b6134e179e09941.exe +TRK-x86=xpsp1a_a2bc3da0f0a3d366c78d4c51ea6aabbb2dd0d545.exe [XPSP3] -ARA-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/04/windowsxp-kb936929-sp3-x86-ara_4e82a87cea3b9643fd57b39393a88061614cdae6.exe -CHH-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-chh_2663fb610f29e65a10be176740ea6757ca1f22d5.exe -CHS-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-chs_d7067e86abd4257454200d0c398d71c4ce6cd33e.exe -CHT-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-cht_8a0625e10b8c6cb88d9d1952f1a189fbd761b744.exe -CSY-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-csy_7af606916b887dba9dd38ae282505ce2c2b81b08.exe -DAN-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-dan_37e03a7d43ad65bc4b71f3947c76bd2fc0fe44d6.exe -DEU-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-deu_f2dcd2211384a78df215c696a7fd1a7949dc794b.exe -ELL-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-ell_cec2ed1c3097e44e62dcb1f2a473a64a58e031fe.exe -ENU-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/04/windowsxp-kb936929-sp3-x86-enu_c81472f7eeea2eca421e116cd4c03e2300ebfde4.exe -ESN-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-esn_e305becfc6fd5a8199368ceffc496397247ac60f.exe -FIN-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-fin_5654c021a03bfb10543a2c673bdfc42a853e347a.exe -FRA-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-fra_414b61bbc86e09579d8447baa23eb1b867f9ca93.exe -HEB-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-heb_eb8fc9ff0890279346661dde065c14b5c696e423.exe -HUN-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-hun_77b70fe421baeebb115c2f378b8a1fc274db9867.exe -ITA-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-ita_2162c1d419d1e462a7dc34294528b2daf593302c.exe -JPN-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-jpn_e0fc34cfa52d270b3c79a68af8fa358244f7419e.exe -KOR-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-kor_8ca7e862bfc2742ad9c4c58df0b0cd5ad4b700ae.exe -NLD-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-nld_b2576b4d1972583a3b776fdf963b914341d34058.exe -NOR-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-nor_67c9167275a2c3e3884a38c2ad7387556ad4713a.exe -PLK-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-plk_7cbe718131e9c71b322f1149e86bedba351ba11c.exe -PTB-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-ptb_02900ef11f5a982a93de5f927997ce92d5a81a86.exe -PTG-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-ptg_bc5189c05e93cd0e5742712d84f0b5f5ffcbb7e4.exe -RUS-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-rus_850cda9f57033a17d046a56d422547ea80dcaf61.exe -SVE-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-sve_13c5ecca22e12224934a1faa1190ee34db3995ae.exe -TRK-x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windowsxp-kb936929-sp3-x86-trk_5aaf60501636af08c97ef1c18f1315f4ed6fbcdf.exe +Prefix=http://download.windowsupdate.com/msdownload/update/software/ +ARA-x86=dflt/2008/04/windowsxp-kb936929-sp3-x86-ara_4e82a87cea3b9643fd57b39393a88061614cdae6.exe +CHH-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-chh_2663fb610f29e65a10be176740ea6757ca1f22d5.exe +CHS-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-chs_d7067e86abd4257454200d0c398d71c4ce6cd33e.exe +CHT-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-cht_8a0625e10b8c6cb88d9d1952f1a189fbd761b744.exe +CSY-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-csy_7af606916b887dba9dd38ae282505ce2c2b81b08.exe +DAN-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-dan_37e03a7d43ad65bc4b71f3947c76bd2fc0fe44d6.exe +DEU-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-deu_f2dcd2211384a78df215c696a7fd1a7949dc794b.exe +ELL-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-ell_cec2ed1c3097e44e62dcb1f2a473a64a58e031fe.exe +ENU-x86=dflt/2008/04/windowsxp-kb936929-sp3-x86-enu_c81472f7eeea2eca421e116cd4c03e2300ebfde4.exe +ESN-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-esn_e305becfc6fd5a8199368ceffc496397247ac60f.exe +FIN-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-fin_5654c021a03bfb10543a2c673bdfc42a853e347a.exe +FRA-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-fra_414b61bbc86e09579d8447baa23eb1b867f9ca93.exe +HEB-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-heb_eb8fc9ff0890279346661dde065c14b5c696e423.exe +HUN-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-hun_77b70fe421baeebb115c2f378b8a1fc274db9867.exe +ITA-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-ita_2162c1d419d1e462a7dc34294528b2daf593302c.exe +JPN-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-jpn_e0fc34cfa52d270b3c79a68af8fa358244f7419e.exe +KOR-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-kor_8ca7e862bfc2742ad9c4c58df0b0cd5ad4b700ae.exe +NLD-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-nld_b2576b4d1972583a3b776fdf963b914341d34058.exe +NOR-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-nor_67c9167275a2c3e3884a38c2ad7387556ad4713a.exe +PLK-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-plk_7cbe718131e9c71b322f1149e86bedba351ba11c.exe +PTB-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-ptb_02900ef11f5a982a93de5f927997ce92d5a81a86.exe +PTG-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-ptg_bc5189c05e93cd0e5742712d84f0b5f5ffcbb7e4.exe +RUS-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-rus_850cda9f57033a17d046a56d422547ea80dcaf61.exe +SVE-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-sve_13c5ecca22e12224934a1faa1190ee34db3995ae.exe +TRK-x86=svpk/2008/04/windowsxp-kb936929-sp3-x86-trk_5aaf60501636af08c97ef1c18f1315f4ed6fbcdf.exe [XPESP3] ; Only seems to be available in English. @@ -182,43 +187,45 @@ x86=http://web.archive.org/web/20140813085714/http://download.microsoft.com/down ; Windows XP 2003 [2003SP2] -CHH-x86=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003-kb914961-sp2-x86-chh_2de4fb187533e226cd615bcda30b9a8a2836e197.exe -CHS-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-chs_c3e7772c6ad063bac3cb6ca05ea6e1b39c5bb35d.exe -CHT-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-cht_65a62b8ef051bf93d0ccd78900fe8d6709d37a92.exe -CSY-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-csy_fa0c18ba0a265001778e9d2691086742fc4efeb6.exe -DEU-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-deu_f9a055504e882bb06ce2c7e83319000d905f7917.exe -ENU-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-enu_51e1759a1fda6cd588660324abaed59dd3bbe86b.exe -ESN-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-esn_38d7fba08bdebdaf567ae626042e860bf525306e.exe -FRA-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-fra_51f76d9ebb01806f905199f83a16715e8026c095.exe -HUN-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-hun_0ac4aaf8685d74132da6256439ed5f74337cb7f5.exe -ITA-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ita_75aa7220b0e226330a723cd27cb0f8b56e9b5f22.exe -JPN-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-jpn_af70b74d70df32c530352b75e42ce772e9bb68d2.exe -KOR-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-kor_65bcd5be738a08046f0714a108a5fa334ef08fd0.exe -NLD-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-nld_12014e84ae5c8a41cd918a6e2c97586bdee030f7.exe -PLK-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-plk_213469cc7ac58cfa82215f1e5ca6753675061b57.exe -PTB-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ptb_73a2c9a9a28f1203aba9f1852c64247467494652.exe -PTG-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ptg_d8b921ee4bb0e0d2831f249e99c64264ae9098db.exe -RUS-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-rus_b53c66c6cec98327d1a25b77a252dc82d984f959.exe -SVE-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-sve_fba6d5c90dc7c15ae750c98cf407a0f148bbfee5.exe -TRK-x86=http://download.windowsupdate.com/msdownload/update/software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-trk_428236b66433ce6b08c9d7a6aa6c523874a340ae.exe -ENU-x64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003.windowsxp-kb914961-sp2-x64-enu_7f8e909c52d23ac8b5dbfd73f1f12d3ee0fe794c.exe -JPN-x64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003.windowsxp-kb914961-sp2-x64-jpn_c725a8c4e03803b12a9ac8820e964dbc377a80dc.exe -DEU-ia64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-deu_f6857c1bb8fc03798541a78cdc1f5bb98b456333.exe -ENU-ia64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-enu_8856af0aa0f198a8aad2de2c1ca68240d1d49bf3.exe -FRA-ia64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-fra_0289b81fe7ed5c1c36f87232f87b25cdb21d331d.exe -JPN-ia64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-jpn_3216b1978fd418181ecbf77eef67398edb97a106.exe +Prefix=http://download.windowsupdate.com/msdownload/update/ +CHH-x86=v3-19990518/cabpool/windowsserver2003-kb914961-sp2-x86-chh_2de4fb187533e226cd615bcda30b9a8a2836e197.exe +CHS-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-chs_c3e7772c6ad063bac3cb6ca05ea6e1b39c5bb35d.exe +CHT-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-cht_65a62b8ef051bf93d0ccd78900fe8d6709d37a92.exe +CSY-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-csy_fa0c18ba0a265001778e9d2691086742fc4efeb6.exe +DEU-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-deu_f9a055504e882bb06ce2c7e83319000d905f7917.exe +ENU-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-enu_51e1759a1fda6cd588660324abaed59dd3bbe86b.exe +ESN-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-esn_38d7fba08bdebdaf567ae626042e860bf525306e.exe +FRA-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-fra_51f76d9ebb01806f905199f83a16715e8026c095.exe +HUN-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-hun_0ac4aaf8685d74132da6256439ed5f74337cb7f5.exe +ITA-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ita_75aa7220b0e226330a723cd27cb0f8b56e9b5f22.exe +JPN-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-jpn_af70b74d70df32c530352b75e42ce772e9bb68d2.exe +KOR-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-kor_65bcd5be738a08046f0714a108a5fa334ef08fd0.exe +NLD-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-nld_12014e84ae5c8a41cd918a6e2c97586bdee030f7.exe +PLK-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-plk_213469cc7ac58cfa82215f1e5ca6753675061b57.exe +PTB-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ptb_73a2c9a9a28f1203aba9f1852c64247467494652.exe +PTG-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-ptg_d8b921ee4bb0e0d2831f249e99c64264ae9098db.exe +RUS-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-rus_b53c66c6cec98327d1a25b77a252dc82d984f959.exe +SVE-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-sve_fba6d5c90dc7c15ae750c98cf407a0f148bbfee5.exe +TRK-x86=software/dflt/2008/02/windowsserver2003-kb914961-sp2-x86-trk_428236b66433ce6b08c9d7a6aa6c523874a340ae.exe +ENU-x64=v3-19990518/cabpool/windowsserver2003.windowsxp-kb914961-sp2-x64-enu_7f8e909c52d23ac8b5dbfd73f1f12d3ee0fe794c.exe +JPN-x64=v3-19990518/cabpool/windowsserver2003.windowsxp-kb914961-sp2-x64-jpn_c725a8c4e03803b12a9ac8820e964dbc377a80dc.exe +DEU-ia64=v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-deu_f6857c1bb8fc03798541a78cdc1f5bb98b456333.exe +ENU-ia64=v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-enu_8856af0aa0f198a8aad2de2c1ca68240d1d49bf3.exe +FRA-ia64=v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-fra_0289b81fe7ed5c1c36f87232f87b25cdb21d331d.exe +JPN-ia64=v3-19990518/cabpool/windowsserver2003-kb914961-sp2-ia64-jpn_3216b1978fd418181ecbf77eef67398edb97a106.exe ; Windows Update Agent standalone installer [WUA] +Prefix=http://download.windowsupdate.com/windowsupdate/redist/standalone/ ; Pay no attention to the version numbers in the urls, they're all over the place. The keys have the ; actual versions of dlls that gets installed. -7.2.6001.788-x86=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.2.6001.788/WindowsUpdateAgent30-x86.exe -7.2.6001.788-x64=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.2.6001.788/WindowsUpdateAgent30-x64.exe -7.2.6001.788-ia64=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.2.6001.788/WindowsUpdateAgent30-ia64.exe -7.6.7600.243-x86=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.4.7600.243/WindowsUpdateAgent30-x86.exe -7.6.7600.256-x86=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.6.7600.320/WindowsUpdateAgent-7.6-x86.exe -7.6.7600.256-x64=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.6.7600.320/WindowsUpdateAgent-7.6-x64.exe -7.6.7600.256-ia64=http://download.windowsupdate.com/windowsupdate/redist/standalone/7.6.7600.320/WindowsUpdateAgent-7.6-ia64.exe +7.2.6001.788-x86=7.2.6001.788/WindowsUpdateAgent30-x86.exe +7.2.6001.788-x64=7.2.6001.788/WindowsUpdateAgent30-x64.exe +7.2.6001.788-ia64=7.2.6001.788/WindowsUpdateAgent30-ia64.exe +7.6.7600.243-x86=7.4.7600.243/WindowsUpdateAgent30-x86.exe +7.6.7600.256-x86=7.6.7600.320/WindowsUpdateAgent-7.6-x86.exe +7.6.7600.256-x64=7.6.7600.320/WindowsUpdateAgent-7.6-x64.exe +7.6.7600.256-ia64=7.6.7600.320/WindowsUpdateAgent-7.6-ia64.exe ; Win2k 5.0.0=7.2.6001.788 5.0.1=7.2.6001.788 @@ -236,115 +243,146 @@ JPN-ia64=http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool 5.2.1=7.2.6001.788 5.2.2=7.6.7600.256 ; Vista/Server 08 +6.0.0=7.6.7600.256 +6.0.1=7.6.7600.256 6.0.2=7.6.7600.256 ; Vista/Server 08 [VistaSP1] -x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windows6.0-kb936330-x86_b8a3fa8f819269e37d8acde799e7a9aea3dd4529.exe -x64=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/windows6.0-kb936330-x64_12eed6cf0a842ce2a609c622b843afc289a8f4b9.exe +Prefix=http://download.windowsupdate.com/msdownload/update/software/svpk/2008/04/ +x86=windows6.0-kb936330-x86_b8a3fa8f819269e37d8acde799e7a9aea3dd4529.exe +x64=windows6.0-kb936330-x64_12eed6cf0a842ce2a609c622b843afc289a8f4b9.exe ; No ia64 release for Vista SP1 [VistaSP2] -x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2009/06/windows6.0-kb948465-x86_55f17352b4398ecb4f0cc20e3737631420ca1609.exe -x64=http://download.windowsupdate.com/msdownload/update/software/svpk/2009/06/windows6.0-kb948465-x64_2eedca0bfa5ae8d1b0acf2117ddc4f15ac5183c9.exe -ia64=http://download.windowsupdate.com/msdownload/update/software/svpk/2009/06/windows6.0-kb948465-ia64_1a6cd9ade213bcc056cba3b810e86f0c09c16b51.exe +Prefix=http://download.windowsupdate.com/msdownload/update/software/svpk/2009/06/ +x86=windows6.0-kb948465-x86_55f17352b4398ecb4f0cc20e3737631420ca1609.exe +x64=windows6.0-kb948465-x64_2eedca0bfa5ae8d1b0acf2117ddc4f15ac5183c9.exe +ia64=windows6.0-kb948465-ia64_1a6cd9ade213bcc056cba3b810e86f0c09c16b51.exe [KB3205638] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/11/windows6.0-kb3205638-x86_e2211e9a6523061972decd158980301fc4c32a47.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/11/windows6.0-kb3205638-x64_a52aaa009ee56ca941e21a6009c00bc4c88cbb7c.msu -ia64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/11/windows6.0-kb3205638-ia64_d6bd55663080885c712c3afb9021c7336d0be83a.msu +Prefix=http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/11/ +x86=windows6.0-kb3205638-x86_e2211e9a6523061972decd158980301fc4c32a47.msu +x64=windows6.0-kb3205638-x64_a52aaa009ee56ca941e21a6009c00bc4c88cbb7c.msu +ia64=windows6.0-kb3205638-ia64_d6bd55663080885c712c3afb9021c7336d0be83a.msu [KB4012583] -x86=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/02/windows6.0-kb4012583-x86_1887cb5393b62cbd2dbb6a6ff6b136e809a2fbd0.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/02/windows6.0-kb4012583-x64_f63c9a85aa877d86c886e432560fdcfad53b752d.msu -ia64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/02/windows6.0-kb4012583-ia64_ab1ab96d3a3d7fbd1bf5d1cee53bf0be958c6329.msu +Prefix=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/02/ +x86=windows6.0-kb4012583-x86_1887cb5393b62cbd2dbb6a6ff6b136e809a2fbd0.msu +x64=windows6.0-kb4012583-x64_f63c9a85aa877d86c886e432560fdcfad53b752d.msu +ia64=windows6.0-kb4012583-ia64_ab1ab96d3a3d7fbd1bf5d1cee53bf0be958c6329.msu [KB4015195] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2017/03/windows6.0-kb4015195-x86_eb045e0144266b20b615f29fa581c4001ebb7852.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2017/03/windows6.0-kb4015195-x64_2e310724d86b6a43c5ae8ec659685dd6cfb28ba4.msu -ia64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2017/03/windows6.0-kb4015195-ia64_0ae8f7c2ab5cf24123f6e279469674d823d20129.msu +Prefix=http://download.windowsupdate.com/d/msdownload/update/software/secu/2017/03/ +x86=windows6.0-kb4015195-x86_eb045e0144266b20b615f29fa581c4001ebb7852.msu +x64=windows6.0-kb4015195-x64_2e310724d86b6a43c5ae8ec659685dd6cfb28ba4.msu +ia64=windows6.0-kb4015195-ia64_0ae8f7c2ab5cf24123f6e279469674d823d20129.msu [KB4015380] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-x86_3f3548db24cf61d6f47d2365c298d739e6cb069a.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-x64_959aedbe0403d160be89f4dac057e2a0cd0c6d40.msu -ia64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-ia64_2a825e5f1aca191bb5f627b494838660180da2d6.msu +Prefix=http://download.windowsupdate.com/ +x86=d/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-x86_3f3548db24cf61d6f47d2365c298d739e6cb069a.msu +x64=c/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-x64_959aedbe0403d160be89f4dac057e2a0cd0c6d40.msu +ia64=c/msdownload/update/software/secu/2017/03/windows6.0-kb4015380-ia64_2a825e5f1aca191bb5f627b494838660180da2d6.msu [KB4493730] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2019/04/windows6.0-kb4493730-x86_ab4368f19db796680ff445a7769886c4cdc009a0.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2019/04/windows6.0-kb4493730-x64_5cb91f4e9000383f061b80f88feffdf228c2443c.msu -ia64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2019/04/windows6.0-kb4493730-ia64_024e5a390f7eace6d2e9dcaa91f09976e4d147db.msu +Prefix=http://download.windowsupdate.com/d/msdownload/update/software/secu/2019/04/ +x86=windows6.0-kb4493730-x86_ab4368f19db796680ff445a7769886c4cdc009a0.msu +x64=windows6.0-kb4493730-x64_5cb91f4e9000383f061b80f88feffdf228c2443c.msu +ia64=windows6.0-kb4493730-ia64_024e5a390f7eace6d2e9dcaa91f09976e4d147db.msu ; IE9 for Vista [KB971512] -x86=http://download.windowsupdate.com/msdownload/update/software/updt/2009/10/windows6.0-kb971512-x86_370c3e41e1c161ddce29676e9273e4b8bb7ba3eb.msu -x64=http://download.windowsupdate.com/msdownload/update/software/updt/2009/10/windows6.0-kb971512-x64_0b329b985437c6c572529e5fd0042b9d54aeaa0c.msu +Prefix=http://download.windowsupdate.com/msdownload/update/software/updt/2009/10/ +x86=windows6.0-kb971512-x86_370c3e41e1c161ddce29676e9273e4b8bb7ba3eb.msu +x64=windows6.0-kb971512-x64_0b329b985437c6c572529e5fd0042b9d54aeaa0c.msu [KB2117917] -x86=http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.0-kb2117917-x86_370435d9efa6643c44d6506666b1960d56cf673a.msu -x64=http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.0-kb2117917-x64_655a21758801e9648702791d7bf30f81b58884b3.msu +Prefix=http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/ +x86=windows6.0-kb2117917-x86_370435d9efa6643c44d6506666b1960d56cf673a.msu +x64=windows6.0-kb2117917-x64_655a21758801e9648702791d7bf30f81b58884b3.msu [IE9] -x86=http://download.windowsupdate.com/msdownload/update/software/uprl/2011/05/wu-ie9-windowsvista-x86_90e3e90e964c2769a008cbf924eefdc42413dd52.exe -x64=http://download.windowsupdate.com/msdownload/update/software/uprl/2011/03/wu-ie9-windowsvista-x64_f599c02e7e1ea8a4e1029f0e49418a8be8416367.exe +Prefix=http://download.windowsupdate.com/msdownload/update/software/uprl/2011/ +x86=05/wu-ie9-windowsvista-x86_90e3e90e964c2769a008cbf924eefdc42413dd52.exe +x64=03/wu-ie9-windowsvista-x64_f599c02e7e1ea8a4e1029f0e49418a8be8416367.exe ; 7/Server 08 R2 [Win7SP1] -x86=http://download.windowsupdate.com/msdownload/update/software/svpk/2011/02/windows6.1-kb976932-x86_c3516bc5c9e69fee6d9ac4f981f5b95977a8a2fa.exe -x64=http://download.windowsupdate.com/msdownload/update/software/svpk/2011/02/windows6.1-kb976932-x64_74865ef2562006e51d7f9333b4a8d45b7a749dab.exe - -[KB3102810] -x86=http://web.archive.org/web/20240309135134id_/http://download.microsoft.com/download/A/0/9/A09BC0FD-747C-4B97-8371-1A7F5AC417E9/Windows6.1-KB3102810-x86.msu -x64=http://web.archive.org/web/20240309135154id_/https://download.microsoft.com/download/F/A/A/FAABD5C2-4600-45F8-96F1-B25B137E3C87/Windows6.1-KB3102810-x64.msu +Prefix=http://download.windowsupdate.com/msdownload/update/software/svpk/2011/02/ +x86=windows6.1-kb976932-x86_c3516bc5c9e69fee6d9ac4f981f5b95977a8a2fa.exe +x64=windows6.1-kb976932-x64_74865ef2562006e51d7f9333b4a8d45b7a749dab.exe [KB3138612] -x86=http://download.windowsupdate.com/d/msdownload/update/software/updt/2016/02/windows6.1-kb3138612-x86_6e90531daffc13bc4e92ecea890e501e807c621f.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/updt/2016/02/windows6.1-kb3138612-x64_f7b1de8ea7cf8faf57b0138c4068d2e899e2b266.msu -ia64=http://download.windowsupdate.com/d/msdownload/update/software/updt/2016/02/windows6.1-kb3138612-ia64_4edd5410fb137382d77f468a14118fa6d1c03655.msu +Prefix=http://download.windowsupdate.com/d/msdownload/update/software/updt/2016/02/ +x86=windows6.1-kb3138612-x86_6e90531daffc13bc4e92ecea890e501e807c621f.msu +x64=windows6.1-kb3138612-x64_f7b1de8ea7cf8faf57b0138c4068d2e899e2b266.msu +ia64=windows6.1-kb3138612-ia64_4edd5410fb137382d77f468a14118fa6d1c03655.msu [KB4474419] -x86=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/09/windows6.1-kb4474419-v3-x86_0f687d50402790f340087c576886501b3223bec6.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/09/windows6.1-kb4474419-v3-x64_b5614c6cea5cb4e198717789633dca16308ef79c.msu -ia64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/09/windows6.1-kb4474419-v3-ia64_1436a990f64876332857baaafa7aeb9eadcb4fa4.msu +Prefix=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/09/ +x86=windows6.1-kb4474419-v3-x86_0f687d50402790f340087c576886501b3223bec6.msu +x64=windows6.1-kb4474419-v3-x64_b5614c6cea5cb4e198717789633dca16308ef79c.msu +ia64=windows6.1-kb4474419-v3-ia64_1436a990f64876332857baaafa7aeb9eadcb4fa4.msu [KB4490628] -x86=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-x86_3cdb3df55b9cd7ef7fcb24fc4e237ea287ad0992.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-x64_d3de52d6987f7c8bdc2c015dca69eac96047c76e.msu -ia64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-ia64_4736acd98e0a4e02f29fcdef63feacc5ac7b702b.msu +Prefix=http://download.windowsupdate.com/ +x86=c/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-x86_3cdb3df55b9cd7ef7fcb24fc4e237ea287ad0992.msu +x64=c/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-x64_d3de52d6987f7c8bdc2c015dca69eac96047c76e.msu +ia64=d/msdownload/update/software/secu/2019/03/windows6.1-kb4490628-ia64_4736acd98e0a4e02f29fcdef63feacc5ac7b702b.msu ; Windows Home Server 2011 [KB2757011] -x64=http://download.windowsupdate.com/msdownload/update/software/uprl/2012/12/windows6.1-kb2757011-x64_4140355ab0b06df89668ec51432a820dff9af356.msu +Prefix=http://download.windowsupdate.com/msdownload/update/software/uprl/2012/12/ +x64=windows6.1-kb2757011-x64_4140355ab0b06df89668ec51432a820dff9af356.msu ; 8/Server 2012 [KB4598297] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2021/01/windows8-rt-kb4598297-x86_a517ea587c91af5f803b0973d40166c3e076fe5c.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2021/01/windows8-rt-kb4598297-x64_60f5c45d1216ee6ff1ab88ca03b037ac519ad0da.msu +Prefix=http://download.windowsupdate.com/d/msdownload/update/software/secu/2021/01/ +x86=windows8-rt-kb4598297-x86_a517ea587c91af5f803b0973d40166c3e076fe5c.msu +x64=windows8-rt-kb4598297-x64_60f5c45d1216ee6ff1ab88ca03b037ac519ad0da.msu ; 8.1/Server 2012 R2 [KB3021910] -x86=http://download.windowsupdate.com/c/msdownload/update/software/updt/2015/04/windows8.1-kb3021910-x86_7e70173bec00c3d4fe3b0b8cba17b095b4ed2d20.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/updt/2015/04/windows8.1-kb3021910-x64_e291c0c339586e79c36ebfc0211678df91656c3d.msu +Prefix=http://download.windowsupdate.com/ +x86=c/msdownload/update/software/updt/2015/04/windows8.1-kb3021910-x86_7e70173bec00c3d4fe3b0b8cba17b095b4ed2d20.msu +x64=c/msdownload/update/software/updt/2015/04/windows8.1-kb3021910-x64_e291c0c339586e79c36ebfc0211678df91656c3d.msu +arm=d/msdownload/update/software/updt/2015/03/windows8.1-kb3021910-arm_72a8286480463b9328f742c7247d7c155a716cd0.msu [ClearCompressionFlag] -x86=http://download.windowsupdate.com/c/msdownload/update/software/secu/2014/04/clearcompressionflag_220edca17ae47089fc4da060915e0df568eac4ff.exe -x64=http://download.windowsupdate.com/d/msdownload/update/software/secu/2014/04/clearcompressionflag_3104315db9d84f6a2a56b9621e89ea66a8c27604.exe +Prefix=http://download.windowsupdate.com/ +x86=c/msdownload/update/software/secu/2014/04/clearcompressionflag_220edca17ae47089fc4da060915e0df568eac4ff.exe +x64=d/msdownload/update/software/secu/2014/04/clearcompressionflag_3104315db9d84f6a2a56b9621e89ea66a8c27604.exe +arm=c/msdownload/update/software/secu/2014/04/clearcompressionflag_70c52df15023ad1fa579149f0435e6a2b078fc94.exe [KB2919355] -x86=http://download.windowsupdate.com/c/msdownload/update/software/crup/2014/02/windows8.1-kb2919355-x86_de9df31e42fe034c9a763328326e5852c2b4963d.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/crup/2014/02/windows8.1-kb2919355-x64_e6f4da4d33564419065a7370865faacf9b40ff72.msu +Prefix=http://download.windowsupdate.com/ +x86=c/msdownload/update/software/crup/2014/02/windows8.1-kb2919355-x86_de9df31e42fe034c9a763328326e5852c2b4963d.msu +x64=d/msdownload/update/software/crup/2014/02/windows8.1-kb2919355-x64_e6f4da4d33564419065a7370865faacf9b40ff72.msu +arm=c/msdownload/update/software/crup/2014/02/windows8.1-kb2919355-arm_a6119d3e5ddd1a233a09dd79d91067de7b826f85.msu [KB2932046] -x86=http://download.windowsupdate.com/c/msdownload/update/software/crup/2014/02/windows8.1-kb2932046-x86_bfd8ca4c683ccec26355afc1f2e677f3809cb3d6.msu -x64=http://download.windowsupdate.com/d/msdownload/update/software/crup/2014/02/windows8.1-kb2932046-x64_6aee5fda6e2a6729d1fbae6eac08693acd70d985.msu +Prefix=http://download.windowsupdate.com/ +x86=c/msdownload/update/software/crup/2014/02/windows8.1-kb2932046-x86_bfd8ca4c683ccec26355afc1f2e677f3809cb3d6.msu +x64=d/msdownload/update/software/crup/2014/02/windows8.1-kb2932046-x64_6aee5fda6e2a6729d1fbae6eac08693acd70d985.msu +arm=c/msdownload/update/software/crup/2014/02/windows8.1-kb2932046-arm_fe6acf558880d127aef1a759a8c2539afc67b5fb.msu [KB2959977] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2014/04/windows8.1-kb2959977-x86_5ccf761a356bb143b68887f99883d8c24946d2c2.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2014/04/windows8.1-kb2959977-x64_574ba2d60baa13645b764f55069b74b2de866975.msu +Prefix=http://download.windowsupdate.com/ +x86=d/msdownload/update/software/secu/2014/04/windows8.1-kb2959977-x86_5ccf761a356bb143b68887f99883d8c24946d2c2.msu +x64=c/msdownload/update/software/secu/2014/04/windows8.1-kb2959977-x64_574ba2d60baa13645b764f55069b74b2de866975.msu +arm=c/msdownload/update/software/secu/2014/04/windows8.1-kb2959977-arm_d37dfe20cdc496b4ed4338913d225fc1a9a91d36.msu [KB2937592] -x86=http://download.windowsupdate.com/d/msdownload/update/software/crup/2014/02/windows8.1-kb2937592-x86_96a3416d480bd2b54803df26b8e76cd1d0008d43.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/crup/2014/02/windows8.1-kb2937592-x64_4abc0a39c9e500c0fbe9c41282169c92315cafc2.msu +Prefix=http://download.windowsupdate.com/ +x86=d/msdownload/update/software/crup/2014/02/windows8.1-kb2937592-x86_96a3416d480bd2b54803df26b8e76cd1d0008d43.msu +x64=c/msdownload/update/software/crup/2014/02/windows8.1-kb2937592-x64_4abc0a39c9e500c0fbe9c41282169c92315cafc2.msu +arm=c/msdownload/update/software/crup/2014/02/windows8.1-kb2937592-arm_860c83a0cccc0519111f57a679ae9f9d071315e5.msu [KB2934018] -x86=http://download.windowsupdate.com/d/msdownload/update/software/secu/2014/04/windows8.1-kb2934018-x86_8fb05387836b77abbf1755185ae743c9da417e9a.msu -x64=http://download.windowsupdate.com/c/msdownload/update/software/secu/2014/04/windows8.1-kb2934018-x64_234a5fc4955f81541f5bfc0d447e4fc4934efc38.msu +Prefix=http://download.windowsupdate.com/ +x86=d/msdownload/update/software/secu/2014/04/windows8.1-kb2934018-x86_8fb05387836b77abbf1755185ae743c9da417e9a.msu +x64=c/msdownload/update/software/secu/2014/04/windows8.1-kb2934018-x64_234a5fc4955f81541f5bfc0d447e4fc4934efc38.msu +arm=c/msdownload/update/software/secu/2014/04/windows8.1-kb2934018-arm_28c62f5a4129ba24ab75936517c5066435702ae8.msu + +[KB3097667] +arm=http://download.windowsupdate.com/d/msdownload/update/software/updt/2015/09/windows8.1-kb3033055-arm_1b0aeee420c6ad850de7cfac0c485d4bd7965f71.msu diff --git a/setup/RunOnce.nsh b/setup/RunOnce.nsh index 647ee03..85b1900 100644 --- a/setup/RunOnce.nsh +++ b/setup/RunOnce.nsh @@ -2,165 +2,262 @@ !define IsPostInstall `"" HasFlag "/postinstall"` !define NoRestart `"" HasFlag "/norestart"` -!macro -PromptReboot +!macro PromptReboot + !insertmacro InhibitSleep 0 SetErrorLevel ${ERROR_SUCCESS_REBOOT_REQUIRED} ${If} ${NoRestart} ; Prompt for reboot ${IfNot} ${Silent} - System::Call '${RestartDialog}($HWNDPARENT, \ - "Windows will be restarted to complete installation of prerequisite components. Setup will resume after the restart.", \ - ${EWX_REBOOT})' + ${AndIfNot} ${IsPassive} + System::Call '${RestartDialog}($HWNDPARENT, "", ${EWX_REBOOT})' ${EndIf} + Quit ${Else} ; Reboot immediately - Reboot + System::Call '${GetUserName}(.r0, ${NSIS_MAX_STRLEN}) .r1' + ${If} ${IsRunOnce} + ${AndIf} $0 == "SYSTEM" + ; Running in setup mode. Winlogon will reboot for us. + SetErrorLevel ${ERROR_SUCCESS} + Quit + ${Else} + ; Regular reboot. + Reboot + ${EndIf} ${EndIf} !macroend -!macro -RegisterRunOnce flags - WriteRegStr HKLM "${REGPATH_RUNONCE}" "Legacy Update" '"$RunOnceDir\LegacyUpdateSetup.exe" ${flags}' -!macroend - -Function RegisterRunOnce - !insertmacro -RegisterRunOnce "/runonce" -FunctionEnd - -Function un.RegisterRunOnce - ; Unused, just needs to exist to make the compiler happy -FunctionEnd - -Function RegisterRunOncePostInstall - !insertmacro -RegisterRunOnce "/postinstall" -FunctionEnd - -!macro -WriteRegStrWithBackup root key name value - ; Backup the key if it exists +!macro RunOnceOverwriteReg type root subkey name value ClearErrors - ReadRegStr $0 ${root} "${key}" "${name}" + ReadReg${type} $0 ${root} "${subkey}" "${name}" ${IfNot} ${Errors} - WriteRegStr ${root} "${key}" "LegacyUpdate_${name}" $0 + WriteReg${type} ${root} "${subkey}" "${name}_LegacyUpdateTemp" $0 ${EndIf} - - WriteRegStr ${root} "${key}" "${name}" "${value}" + WriteReg${type} ${root} "${subkey}" "${name}" `${value}` !macroend -!macro -RestoreRegStr root key name - ; Restore the key if it exists +!macro RunOnceRestoreReg type root subkey name fallback ClearErrors - ReadRegStr $0 ${root} "${key}" "LegacyUpdate_${name}" + ReadReg${type} $0 ${root} "${subkey}" "${name}_LegacyUpdateTemp" ${If} ${Errors} - DeleteRegValue ${root} "${key}" "${name}" +!if "${fallback}" == "-" + DeleteRegValue ${root} "${subkey}" "${name}" +!else + WriteReg${type} ${root} "${subkey}" "${name}" `${fallback}` +!endif ${Else} - WriteRegStr ${root} "${key}" "${name}" $0 - DeleteRegValue ${root} "${key}" "LegacyUpdate_${name}" + WriteReg${type} ${root} "${subkey}" "${name}" $0 + DeleteRegValue ${root} "${subkey}" "${name}_LegacyUpdateTemp" ${EndIf} !macroend -!macro -RebootIfRequired un +Function CleanUpRunOnce + ; Restore setup keys + ; Be careful here. Doing this wrong can cause SYSTEM_LICENSE_VIOLATION bootloops! + !insertmacro RunOnceRestoreReg Str HKLM "${REGPATH_SETUP}" "CmdLine" "" + !insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_SETUP}" "SetupType" ${SETUP_TYPE_NORMAL} + DeleteRegValue HKLM "${REGPATH_SETUP}" "SetupShutdownRequired" + + ${If} ${Abort} + Call CleanUpRunOnceFinal + ${EndIf} +FunctionEnd + +Function CleanUpRunOnceFinal + ; Enable keys we disabled if needed + ${If} ${IsWinXP2002} + !insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_SECURITYCENTER}" "FirstRunDisabled" "-" + ${EndIf} + + ${If} ${AtLeastWin8} + !insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_POLICIES_SYSTEM}" "EnableFirstLogonAnimation" "-" + ${EndIf} + + ; Delete runonce stuff + RMDir /r /REBOOTOK "${RUNONCEDIR}" + + ; Delete IE6 temp files + RMDir /r /REBOOTOK "$WINDIR\Windows Update Setup Files" +FunctionEnd + +Function CopyLauncher + ${If} ${IsNativeAMD64} + File /ONAME=LegacyUpdate.exe "..\launcher\obj\LegacyUpdate64.exe" + ${Else} + File /ONAME=LegacyUpdate.exe "..\launcher\obj\LegacyUpdate32.exe" + ${EndIf} +FunctionEnd + +Var /GLOBAL RunOnce.UseFallback + +Function PrepareRunOnce ${If} ${RebootFlag} ${IfNot} ${IsRunOnce} - ${AndIfNot} ${NoRestart} - !insertmacro DetailPrint "Preparing to restart..." - - ; Get the localised name of the Administrators group from its SID - System::Call '*(&i1 0, &i4 0, &i1 5) i .r0' - ; S-1-5-32-544 - System::Call '${AllocateAndInitializeSid}(r0, 2, ${SECURITY_BUILTIN_DOMAIN_RID}, ${DOMAIN_ALIAS_RID_ADMINS}, 0, 0, 0, 0, 0, 0, .r1)' - System::Free $0 - System::Call '${LookupAccountSid}(0, r1, .r0, ${NSIS_MAX_STRLEN}, .r2, ${NSIS_MAX_STRLEN}, 0)' - System::Call '${FreeSid}(r1)' - - ; Create the admin user - ExecShellWait "" "$WINDIR\system32\net.exe" "user /add ${RUNONCE_USERNAME} ${RUNONCE_PASSWORD}" SW_HIDE - ExecShellWait "" "$WINDIR\system32\net.exe" 'localgroup /add "$0" ${RUNONCE_USERNAME}' SW_HIDE - - !insertmacro -WriteRegStrWithBackup HKLM "${REGPATH_WINLOGON}" "AutoAdminLogon" "1" - !insertmacro -WriteRegStrWithBackup HKLM "${REGPATH_WINLOGON}" "DefaultDomainName" "." - !insertmacro -WriteRegStrWithBackup HKLM "${REGPATH_WINLOGON}" "DefaultUserName" "${RUNONCE_USERNAME}" - !insertmacro -WriteRegStrWithBackup HKLM "${REGPATH_WINLOGON}" "DefaultPassword" "${RUNONCE_PASSWORD}" - ; Copy to runonce path to ensure installer is accessible by the temp user - CreateDirectory "$RunOnceDir" - CopyFiles /SILENT "$EXEPATH" "$RunOnceDir\LegacyUpdateSetup.exe" + CreateDirectory "${RUNONCEDIR}" + SetOutPath "${RUNONCEDIR}" + CopyFiles /SILENT "$EXEPATH" "${RUNONCEDIR}\LegacyUpdateSetup.exe" + Call CopyLauncher ; Remove mark of the web to prevent "Open File - Security Warning" dialog - System::Call '${DeleteFile}("$RunOnceDir\LegacyUpdateSetup.exe:Zone.Identifier")' + Delete "${RUNONCEDIR}\LegacyUpdateSetup.exe:Zone.Identifier" ${EndIf} - Call ${un}RegisterRunOnce - !insertmacro -PromptReboot - Quit + ${If} $RunOnce.UseFallback == 1 + WriteRegStr HKLM "${REGPATH_RUNONCE}" "LegacyUpdateRunOnce" '"${RUNONCEDIR}\LegacyUpdateSetup.exe" /runonce' + ${Else} + ; Somewhat documented in KB939857: + ; https://web.archive.org/web/20090723061647/http://support.microsoft.com/kb/939857 + ; See also Wine winternl.h + !insertmacro RunOnceOverwriteReg Str HKLM "${REGPATH_SETUP}" "CmdLine" '"${RUNONCEDIR}\LegacyUpdate.exe" /runonce' + !insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_SETUP}" "SetupType" ${SETUP_TYPE_NOREBOOT} + WriteRegDword HKLM "${REGPATH_SETUP}" "SetupShutdownRequired" ${SETUP_SHUTDOWN_REBOOT} + ${EndIf} + + ; Temporarily disable Security Center first run if needed + ${If} ${IsWinXP2002} + ${AndIfNot} ${AtLeastServicePack} 2 + ${VerbosePrint} "Disabling Security Center first run" + !insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_SECURITYCENTER}" "FirstRunDisabled" 1 + ${EndIf} + + ; Temporarily disable logon animation if needed + ${If} ${AtLeastWin8} + ${VerbosePrint} "Disabling first logon animation" + !insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_POLICIES_SYSTEM}" "EnableFirstLogonAnimation" 0 + ${EndIf} ${EndIf} -!macroend +FunctionEnd Function RebootIfRequired ${MementoSectionSave} - !insertmacro -RebootIfRequired "" -FunctionEnd + ${If} ${RebootFlag} + ; Give the user a moment to understand we're rebooting + ${DetailPrint} "$(StatusRestarting)" + Sleep 2000 -Function un.RebootIfRequired - !insertmacro -RebootIfRequired "un." + ; Now reboot + Call PrepareRunOnce + !insertmacro PromptReboot + ${Else} + ; Restore setup keys + Call CleanUpRunOnce + ${EndIf} FunctionEnd Function OnRunOnceLogon - ; Trick winlogon into thinking the shell has started, so it doesn't appear to be stuck at - ; "Welcome" (XP) or "Preparing your desktop..." (Vista+) - ; https://social.msdn.microsoft.com/Forums/WINDOWS/en-US/ca253e22-1ef8-4582-8710-9cd9c89b15c3 - ${If} ${AtLeastWinVista} - StrCpy $0 "ShellDesktopSwitchEvent" - ${Else} - StrCpy $0 "msgina: ShellReadyEvent" - ${EndIf} + ; To be safe in case we crash, immediately restore setup keys. We'll set them again if needed. + Call CleanUpRunOnce - System::Call '${OpenEvent}(${EVENT_MODIFY_STATE}, 0, "$0") .r0' - ${If} $0 != 0 - System::Call '${SetEvent}(r0)' - System::Call '${CloseHandle}(r0)' - ${EndIf} - - ; Handle Safe Mode case. RunOnce can still be processed in Safe Mode in some edge cases. If that - ; happens, just silently register runonce again and quit. - ${If} ${IsSafeMode} - Call RegisterRunOnce - Quit - ${EndIf} - - ; Allow the themes component to be registered if necessary. This sets the theme to Aero Basic - ; rather than Classic in Vista/7. + ; If we're in the middle of installing a service pack, the system will reboot without notice. Be prepared for that + ; to happen. ClearErrors - ReadRegStr $0 HKLM "${REGPATH_COMPONENT_THEMES}" "StubPath" + EnumRegKey $1 HKLM "${REGPATH_CBS_REBOOTINPROGRESS}" 0 ${IfNot} ${Errors} - ExecShellWait "" "$WINDIR\system32\cmd.exe" "/c $0" SW_HIDE + ; System will reboot without notice. Be prepared for that to happen. + ${VerbosePrint} "CBS reboot is pending" + Call PrepareRunOnce ${EndIf} FunctionEnd -Function CleanUpRunOnce - ; Restore autologon keys - !insertmacro -RestoreRegStr HKLM "${REGPATH_WINLOGON}" "AutoAdminLogon" - !insertmacro -RestoreRegStr HKLM "${REGPATH_WINLOGON}" "DefaultDomainName" - !insertmacro -RestoreRegStr HKLM "${REGPATH_WINLOGON}" "DefaultUserName" - !insertmacro -RestoreRegStr HKLM "${REGPATH_WINLOGON}" "DefaultPassword" +!macro SetMarquee state + Push $0 + FindWindow $0 "#32770" "" $HWNDPARENT + FindWindow $0 "msctls_progress32" "" $0 +!if ${state} == 1 + ${NSD_AddStyle} $0 ${PBS_MARQUEE} + SendMessage $0 ${PBM_SETMARQUEE} 1 100 +!else + ${NSD_RemoveStyle} $0 ${PBS_MARQUEE} +!endif + Pop $0 +!macroend - ; Delete the temp user - ExecShellWait "" "$WINDIR\system32\net.exe" "user /delete ${RUNONCE_USERNAME}" SW_HIDE +Function PollCbsInstall + ${IfNot} ${AtLeastWinVista} + Return + ${EndIf} + ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState" + ${If} $0 == ${CBS_EXECUTE_STATE_NONE} + ${OrIf} $0 == ${CBS_EXECUTE_STATE_NONE2} + Return + ${EndIf} + + ${VerbosePrint} "Packages are still installing [$0]" + ${DetailPrint} "$(StatusCbsInstalling)" + + ; Set marquee progress bar + !insertmacro SetMarquee 1 + + ${While} 1 == 1 + ; Are we in a RebootInProgress phase? + ClearErrors + EnumRegKey $1 HKLM "${REGPATH_CBS_REBOOTINPROGRESS}" 0 + ${IfNot} ${Errors} + ; Spin forever. TrustedInstaller will reboot on its own. + ${While} 1 == 1 + Sleep 10000 + ${EndWhile} + ${EndIf} + + ; Poll ExecuteState, waiting for TrustedInstaller to be done. + ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState" + ${If} $0 == ${CBS_EXECUTE_STATE_NONE} + ${OrIf} $0 == ${CBS_EXECUTE_STATE_NONE2} + ${Break} + ${EndIf} + + Sleep 1000 + ${EndWhile} + + ; Revert progress bar + !insertmacro SetMarquee 0 +FunctionEnd + +Function RebootIfCbsRebootPending + ${IfNot} ${AtLeastWinVista} + Return + ${EndIf} + + StrCpy $1 0 + + ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState" + ${If} $0 != ${CBS_EXECUTE_STATE_NONE} + ${AndIf} $0 != ${CBS_EXECUTE_STATE_NONE2} + StrCpy $1 1 + ${EndIf} + + ClearErrors + EnumRegKey $0 HKLM "${REGPATH_CBS_REBOOTPENDING}" 0 + ${IfNot} ${Errors} + StrCpy $1 1 + ${EndIf} + + EnumRegKey $0 HKLM "${REGPATH_CBS_PACKAGESPENDING}" 0 + ${IfNot} ${Errors} + StrCpy $1 1 + ${EndIf} + + ${If} $1 == 1 + ${VerbosePrint} "Restarting to install previously pending packages" + SetRebootFlag true + Call RebootIfRequired + ${EndIf} +FunctionEnd + +Function OnRunOnceDone ${If} ${IsRunOnce} - ; Clean up temporary setup exe if we created it (likely on next reboot) - ${If} ${FileExists} "$RunOnceDir" - RMDir /r /REBOOTOK "$RunOnceDir" - ${EndIf} + ${AndIfNot} ${Abort} + ; Set up postinstall runonce + ${VerbosePrint} "Preparing postinstall" + WriteRegStr HKLM "${REGPATH_RUNONCE}" "LegacyUpdatePostInstall" '"${RUNONCEDIR}\LegacyUpdateSetup.exe" /postinstall' - ; Be really really sure this is the right user before we nuke their profile and log out System::Call '${GetUserName}(.r0, ${NSIS_MAX_STRLEN}) .r1' - ${If} $0 == "${RUNONCE_USERNAME}" - ; Register postinstall runonce for the next admin user logon, and log out of the temporary user - ${IfNot} ${Abort} - Call RegisterRunOncePostInstall - ${EndIf} - - RMDir /r /REBOOTOK "$PROFILE" - System::Call "${ExitWindowsEx}(${EWX_FORCE}, 0) .r0" + ${If} $0 == "SYSTEM" + ; Configure winlogon to proceed to the logon dialog + Call CleanUpRunOnce ${EndIf} ${EndIf} FunctionEnd diff --git a/setup/UpdateRoots.nsh b/setup/UpdateRoots.nsh index 22e9e95..ca81a07 100644 --- a/setup/UpdateRoots.nsh +++ b/setup/UpdateRoots.nsh @@ -1,4 +1,8 @@ -!macro -SetSecureProtocolsBitmask +!macro -SetSecureProtocolsBitmask root path key + ReadRegDword $0 ${root} "${path}" "${key}" + ${VerbosePrint} "${root}\${path}" + ${VerbosePrint} "Before: $0" + ; If the value isn't yet set, ReadRegDword will return 0. This means TLSv1.1 and v1.2 will be the ; only enabled protocols. This is intentional behavior, because SSLv2 and SSLv3 are not secure, ; and TLSv1.0 is deprecated. The user can manually enable them in Internet Settings if needed. @@ -10,6 +14,9 @@ ${EndIf} IntOp $0 $0 | ${WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1} IntOp $0 $0 | ${WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2} + + ${VerbosePrint} "After: $0" + WriteRegDword ${root} "${path}" "${key}" $0 !macroend Function _ConfigureCrypto @@ -24,22 +31,12 @@ Function _ConfigureCrypto WriteRegDword HKLM "${REGPATH_SCHANNEL_PROTOCOLS}\TLS 1.2\Server" "DisabledByDefault" 0 ; Enable IE TLSv1.1 and v1.2 - ReadRegDword $0 HKLM "${REGPATH_INETSETTINGS}" "SecureProtocols" - !insertmacro -SetSecureProtocolsBitmask - WriteRegDword HKLM "${REGPATH_INETSETTINGS}" "SecureProtocols" $0 - - ReadRegDword $0 HKCU "${REGPATH_INETSETTINGS}" "SecureProtocols" - !insertmacro -SetSecureProtocolsBitmask - WriteRegDword HKCU "${REGPATH_INETSETTINGS}" "SecureProtocols" $0 + !insertmacro -SetSecureProtocolsBitmask HKLM "${REGPATH_INETSETTINGS}" "SecureProtocols" + !insertmacro -SetSecureProtocolsBitmask HKCU "${REGPATH_INETSETTINGS}" "SecureProtocols" ; Enable WinHTTP TLSv1.1 and v1.2 - ReadRegDword $0 HKLM "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" - !insertmacro -SetSecureProtocolsBitmask - WriteRegDword HKLM "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" $0 - - ReadRegDword $0 HKCU "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" - !insertmacro -SetSecureProtocolsBitmask - WriteRegDword HKCU "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" $0 + !insertmacro -SetSecureProtocolsBitmask HKLM "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" + !insertmacro -SetSecureProtocolsBitmask HKCU "${REGPATH_INETSETTINGS}\WinHttp" "DefaultSecureProtocols" ; Enable .NET inheriting SChannel protocol config ; .NET 3 uses the same registry keys as .NET 2. @@ -48,10 +45,12 @@ Function _ConfigureCrypto FunctionEnd Function ConfigureCrypto + ${VerbosePrint} "Configuring crypto (native)" Call _ConfigureCrypto ; Repeat in the WOW64 registry if needed ${If} ${RunningX64} + ${VerbosePrint} "Configuring crypto (WOW64)" SetRegView 32 Call _ConfigureCrypto SetRegView 64 @@ -59,24 +58,42 @@ Function ConfigureCrypto FunctionEnd !macro _DownloadSST name - !insertmacro Download "Certificate Trust List" "${TRUSTEDR}/${name}.sst" "${name}.sst" 0 + !insertmacro Download "$(CTL) (${name})" "${TRUSTEDR}/${name}.sst" "${name}.sst" 0 !macroend Function DownloadRoots - !insertmacro DetailPrint "Downloading Certificate Trust List..." - !insertmacro _DownloadSST "authroots" - !insertmacro _DownloadSST "delroots" - !insertmacro _DownloadSST "roots" - !insertmacro _DownloadSST "updroots" - !insertmacro _DownloadSST "disallowedcert" + ${DetailPrint} "$(Downloading)$(CTL)..." + !insertmacro _DownloadSST authroots + !insertmacro _DownloadSST delroots + !insertmacro _DownloadSST roots + !insertmacro _DownloadSST updroots + !insertmacro _DownloadSST disallowedcert FunctionEnd +!macro _InstallRoots state store file + LegacyUpdateNSIS::UpdateRoots ${state} ${store} "${file}" + Pop $0 + ${If} $0 != 0 + LegacyUpdateNSIS::MessageForHresult $0 + Pop $1 + StrCpy $2 "$(CTL) (${file})" + MessageBox MB_USERICON "$(MsgBoxInstallFailed)" /SD IDOK + SetErrorLevel $0 + Abort + ${EndIf} +!macroend + Function UpdateRoots - File "updroots.exe" - !insertmacro DetailPrint "Installing Certificate Trust List..." - !insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" authroots.sst' 0 - !insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" updroots.sst' 0 - !insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -l roots.sst' 0 - !insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -d delroots.sst' 0 - !insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -l -u disallowedcert.sst' 0 + ${DetailPrint} "$(Installing)$(CTL)..." + !insertmacro _InstallRoots /update AuthRoot authroots.sst + !insertmacro _InstallRoots /update AuthRoot updroots.sst + !insertmacro _InstallRoots /update Root roots.sst + !insertmacro _InstallRoots /delete AuthRoot delroots.sst + !insertmacro _InstallRoots /update Disallowed disallowedcert.sst + + WriteRegStr HKLM "${REGPATH_COMPONENTS}\${ROOTSUPDATE_GUID}" "" "RootsUpdate" + WriteRegDword HKLM "${REGPATH_COMPONENTS}\${ROOTSUPDATE_GUID}" "IsInstalled" 1 + WriteRegStr HKLM "${REGPATH_COMPONENTS}\${ROOTSUPDATE_GUID}" "Version" "1337,0,2195,0" + WriteRegStr HKLM "${REGPATH_COMPONENTS}\${ROOTSUPDATE_GUID}" "Locale" "*" + WriteRegStr HKLM "${REGPATH_COMPONENTS}\${ROOTSUPDATE_GUID}" "ComponentID" "Windows Roots Update" FunctionEnd diff --git a/setup/Win32.nsh b/setup/Win32.nsh index 0369fb6..d6940b6 100644 --- a/setup/Win32.nsh +++ b/setup/Win32.nsh @@ -1,12 +1,10 @@ ; advapi32 -!define SECURITY_BUILTIN_DOMAIN_RID 0x00000020 -!define DOMAIN_ALIAS_RID_ADMINS 0x00000220 - -!define AllocateAndInitializeSid 'advapi32::AllocateAndInitializeSid(i, i, i, i, i, i, i, i, i, i, *i) i' -!define LookupAccountSid 'advapi32::LookupAccountSid(i, i, t, *i, t, *i, *i) i' -!define FreeSid 'advapi32::FreeSid(i)' !define GetUserName 'advapi32::GetUserName(t, *i) i' +; cbscore +!define CBS_EXECUTE_STATE_NONE -1 +!define CBS_EXECUTE_STATE_NONE2 0xffffffff ; Probably an underflow of -1? + ; kernel32 !define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10 @@ -14,36 +12,25 @@ !define ES_SYSTEM_REQUIRED 0x00000001 !define GetVersionEx 'kernel32::GetVersionEx(pr) i' -!define GetLogicalProcessorInformationEx 'kernel32::GetLogicalProcessorInformationEx(i, *i, *i) i' +!define IsProcessorFeaturePresent 'kernel32::IsProcessorFeaturePresent(i) i' !define SetThreadExecutionState 'kernel32::SetThreadExecutionState(i) i' !define OpenEvent 'kernel32::OpenEvent(i, i, t) i' !define SetEvent 'kernel32::SetEvent(i) i' !define CloseHandle 'kernel32::CloseHandle(i) i' !define DeleteFile 'kernel32::DeleteFile(t) i' -; netapi32 -!define NetApiBufferFree 'netapi32::NetApiBufferFree(i) i' -!define NetUserGetInfo 'netapi32::NetUserGetInfo(t, t, i, *i) i' -!define NetUserAdd 'netapi32::NetUserAdd(t, i, t, i, *i) i' -!define NetLocalGroupAddMembers 'netapi32::NetLocalGroupAddMembers(t, t, i, *i, i) i' - -; ole32 -!define CoCreateInstance 'ole32::CoCreateInstance(g, p, i, g, *p) i' -!define CoTaskMemFree 'ole32::CoTaskMemFree(p)' - -; oleaut32 -!define SysAllocString 'oleaut32::SysAllocString(t) p' -!define SysFreeString 'oleaut32::SysFreeString(p)' +; ntdll +!define RtlGetNtVersionNumbers 'ntdll::RtlGetNtVersionNumbers(*i, *i, *i)' ; shell32 -!define IsUserAnAdmin 'shell32::IsUserAnAdmin() i' !define RestartDialog 'shell32::RestartDialog(p, t, i) i' ; user32 !define EWX_REBOOT 0x02 -!define EWX_FORCE 0x04 -!define ExitWindowsEx 'user32::ExitWindowsEx(i, i) i' +!define PBS_SMOOTH 0x02 +!define PBS_MARQUEE 0x08 + !define GetSystemMetrics 'user32::GetSystemMetrics(i) i' ; winhttp @@ -62,6 +49,11 @@ !define SECURITY_FLAG_STRENGTH_STRONG 0x20000000 +; winlogon +!define SETUP_TYPE_NORMAL 0 +!define SETUP_TYPE_NOREBOOT 2 +!define SETUP_SHUTDOWN_REBOOT 1 + ; wuapi !define WU_S_ALREADY_INSTALLED 2359302 ; 0x00240006 !define WU_E_NOT_APPLICABLE -2145124329 ; 0x80240017 diff --git a/setup/WinVer.nsh b/setup/WinVer.nsh index 6282f8f..2497521 100644 --- a/setup/WinVer.nsh +++ b/setup/WinVer.nsh @@ -16,6 +16,7 @@ !define WINVER_7 0x0601 ; 6.1.7600 !define WINVER_8 0x0602 ; 6.2.9200 !define WINVER_8.1 0x0603 ; 6.3.9600 +!define WINVER_10TP 0x0604 ; 6.4.9841-9883 !define WINVER_10 0x0A00 ; 10.0.10240 !define WINVER_SERVER_2000 ${WINVER_2000} @@ -27,6 +28,18 @@ !define WINVER_SERVER_2012R2 ${WINVER_8.1} !define WINVER_SERVER_2016 ${WINVER_10} +!define WINVER_BUILD_2000 2195 +!define WINVER_BUILD_XP2002 2600 +!define WINVER_BUILD_XP2003 3790 +!define WINVER_BUILD_VISTA 6000 +!define WINVER_BUILD_VISTA_SP1 6001 +!define WINVER_BUILD_VISTA_SP2 6002 +!define WINVER_BUILD_VISTA_ESU 6003 +!define WINVER_BUILD_7 7600 +!define WINVER_BUILD_7_SP1 7601 +!define WINVER_BUILD_8 9200 +!define WINVER_BUILD_8.1 9600 +!define WINVER_BUILD_10 10240 !define WINVER_BUILD_11 22000 !define /ifndef VER_NT_WORKSTATION 1 @@ -58,7 +71,6 @@ Var /GLOBAL __WINVERBUILD Var /GLOBAL __WINVERSP Var /GLOBAL __WINVERPROD - Var /GLOBAL __WINVERSUITE !endif StrCmp $__WINVEROS "" _winver_noveryet @@ -69,7 +81,19 @@ GetWinVer $__WINVERBUILD Build GetWinVer $__WINVERSP ServicePack GetWinVer $__WINVERPROD Product +!macroend +!macro __WinVer_InitEx + !ifndef __WINVER_VARS_DECLARED_EX + !define __WINVER_VARS_DECLARED_EX + + Var /GLOBAL __WINVERSUITE + !endif + + StrCmp $__WINVERSUITE "" _winver_noveryet_ex + Return + + _winver_noveryet_ex: Push $0 Push $1 System::Alloc ${OSVERSIONINFOEXW_SIZE} @@ -107,7 +131,7 @@ !macro __WinVer_TestSuite _a num _t _f !insertmacro _LOGICLIB_TEMP - ${CallArtificialFunction} __WinVer_Init + ${CallArtificialFunction} __WinVer_InitEx IntOp $_LOGICLIB_TEMP $__WINVERSUITE & ${num} !insertmacro _= $_LOGICLIB_TEMP ${num} `${_t}` `${_f}` !macroend @@ -127,6 +151,7 @@ !define IsHomeEdition `"" _WinVer_TestSuite ${VER_SUITE_PERSONAL}` !define IsEmbedded `"" _WinVer_TestSuite ${VER_SUITE_EMBEDDEDNT}` +!define IsDatacenter `"" _WinVer_TestSuite ${VER_SUITE_DATACENTER}` !define IsHomeServer `"" _WinVer_TestSuite ${VER_SUITE_WH_SERVER}` !define IsSafeMode `!= _WinVer_TestSystemMetric ${SM_CLEANBOOT}` diff --git a/setup/ie6setupstub.nsi b/setup/ie6setupstub.nsi deleted file mode 100644 index e793287..0000000 --- a/setup/ie6setupstub.nsi +++ /dev/null @@ -1,89 +0,0 @@ -; Stub file used to replace the ie6setup_w2k.exe file that was previously hosted by Legacy Update. -; This was a full copy of IE6 SP1, but only for English installations of Windows 2000. -; This is expected to ONLY be run by Legacy Update 1.5 and earlier. It should not be used directly. - -!define MUI_UI "modern_aerowizard.exe" -!define MUI_UI_HEADERIMAGE "modern_aerowizard.exe" - -!define MUI_CUSTOMFUNCTION_GUIINIT OnShow - -!include Constants.nsh - -Name "${NAME}" -Caption "${NAME} - Internet Explorer 6 Downloader" -BrandingText "${NAME} ${VERSION} - ${DOMAIN}" -OutFile "ie6setupstub-${VERSION}.exe" - -Unicode True -RequestExecutionLevel Admin -AutoCloseWindow true - -VIAddVersionKey /LANG=1033 "ProductName" "${NAME} - Internet Explorer 6 Downloader" -VIAddVersionKey /LANG=1033 "ProductVersion" "${LONGVERSION}" -VIAddVersionKey /LANG=1033 "CompanyName" "Hashbang Productions" -VIAddVersionKey /LANG=1033 "LegalCopyright" "© Hashbang Productions. All rights reserved." -VIAddVersionKey /LANG=1033 "FileDescription" "${NAME} - Internet Explorer 6 Downloader" -VIAddVersionKey /LANG=1033 "FileVersion" "${LONGVERSION}" -VIProductVersion ${LONGVERSION} -VIFileVersion ${LONGVERSION} - -!define MUI_ICON "..\icon.ico" - -!define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "setupbanner.bmp" - -!include FileFunc.nsh -!include LogicLib.nsh -!include MUI2.nsh -!include Win\WinNT.nsh -!include WinCore.nsh -!include WinVer.nsh -!include WordFunc.nsh -!include x64.nsh - -!include Common.nsh -!include AeroWizard.nsh -!include Download2KXP.nsh - -!insertmacro GetParameters -!insertmacro GetOptions - -!define MUI_PAGE_HEADER_TEXT "Performing Actions" -!define MUI_PAGE_CUSTOMFUNCTION_SHOW OnShow - -!insertmacro MUI_PAGE_INSTFILES - -!insertmacro MUI_LANGUAGE "English" - -Function OnShow - Call AeroWizardOnShow -FunctionEnd - -Section "Internet Explorer 6.0 Service Pack 1" IE6SP1 - SectionIn Ro - Call DownloadIE6 - Call InstallIE6 -SectionEnd - -Function .onInit - SetShellVarContext All - !insertmacro EnsureAdminRights - SetDetailsPrint listonly - - ${IfNot} ${IsWin2000} - MessageBox MB_USERICON "This tool is intended only for use on Windows 2000." /SD IDOK - Quit - ${EndIf} - - Call NeedsIE6 - Pop $0 - ${If} $0 == 0 - MessageBox MB_USERICON "Internet Explorer 6 Service Pack 1 is already installed." /SD IDOK - Quit - ${EndIf} - - SetOutPath $PLUGINSDIR - File Patches.ini - - SetErrorLevel ${ERROR_SUCCESS_REBOOT_REQUIRED} -FunctionEnd diff --git a/setup/modern_aerowizard.exe b/setup/modern_aerowizard.exe index f29ef9f..6407f88 100644 Binary files a/setup/modern_aerowizard.exe and b/setup/modern_aerowizard.exe differ diff --git a/setup/setup.nsi b/setup/setup.nsi index ca0d292..71c760f 100644 --- a/setup/setup.nsi +++ b/setup/setup.nsi @@ -3,9 +3,9 @@ Name "${NAME}" Caption "${NAME}" BrandingText "${NAME} ${VERSION} - ${DOMAIN}" -OutFile "WUIsBack-latest.exe" -InstallDir "$PROGRAMFILES\${NAME}" -InstallDirRegKey HKLM "${REGPATH_LEGACYUPDATE_SETUP}" "InstallDir" +OutFile "LegacyUpdate-${VERSION}.exe" +InstallDir "$PROGRAMFILES64\Legacy Update" +InstallDirRegKey HKLM "${REGPATH_LEGACYUPDATE_SETUP}" "InstallLocation" Unicode true RequestExecutionLevel admin @@ -17,17 +17,30 @@ SetCompressor /SOLID lzma VIAddVersionKey /LANG=1033 "ProductName" "${NAME}" VIAddVersionKey /LANG=1033 "ProductVersion" "${LONGVERSION}" -VIAddVersionKey /LANG=1033 "CompanyName" "Hashbang Productions and Vichingo455" -VIAddVersionKey /LANG=1033 "LegalCopyright" "${U+00A9} Hashbang Productions and Vichingo455. All rights reserved." +VIAddVersionKey /LANG=1033 "CompanyName" "Hashbang Productions" +VIAddVersionKey /LANG=1033 "LegalCopyright" "${U+00A9} Hashbang Productions. All rights reserved." VIAddVersionKey /LANG=1033 "FileDescription" "${NAME}" VIAddVersionKey /LANG=1033 "FileVersion" "${LONGVERSION}" VIProductVersion ${LONGVERSION} VIFileVersion ${LONGVERSION} +ReserveFile "${NSIS_TARGET}\System.dll" +ReserveFile "${NSIS_TARGET}\NSxfer.dll" +ReserveFile "${NSIS_TARGET}\LegacyUpdateNSIS.dll" +ReserveFile "banner-wordmark-classic.bmp" +ReserveFile "Patches.ini" +ReserveFile "..\${VSBUILD32}\LegacyUpdate.dll" +ReserveFile "..\x64\${VSBUILD64}\LegacyUpdate.dll" +ReserveFile "..\launcher\obj\LegacyUpdate32.exe" +ReserveFile "..\launcher\obj\LegacyUpdate64.exe" + +Var /GLOBAL UninstallInstalled + +!define RUNONCEDIR "$COMMONPROGRAMDATA\Legacy Update" + !define MUI_UI "modern_aerowizard.exe" !define MUI_UI_HEADERIMAGE "modern_aerowizard.exe" -!define MUI_CUSTOMFUNCTION_GUIINIT OnShow !define MUI_CUSTOMFUNCTION_UNGUIINIT un.OnShow !define MUI_CUSTOMFUNCTION_ABORT CleanUp @@ -35,22 +48,20 @@ VIFileVersion ${LONGVERSION} !define MUI_UNICON "..\LegacyUpdate\icon.ico" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "setupbanner.bmp" -!define MUI_HEADERIMAGE_UNBITMAP "setupbanner.bmp" +!define MUI_HEADERIMAGE_BITMAP "banner-wordmark-classic.bmp" +!define MUI_HEADERIMAGE_UNBITMAP "banner-wordmark-classic.bmp" !define MUI_TEXT_ABORT_TITLE "Installation Failed" !define MEMENTO_REGISTRY_ROOT HKLM !define MEMENTO_REGISTRY_KEY "${REGPATH_LEGACYUPDATE_SETUP}" -Var /GLOBAL InstallDir -Var /GLOBAL RunOnceDir - !include FileFunc.nsh !include Integration.nsh !include LogicLib.nsh !include Memento.nsh !include MUI2.nsh +!include nsDialogs.nsh !include Sections.nsh !include Win\COM.nsh !include Win\WinError.nsh @@ -63,20 +74,19 @@ Var /GLOBAL RunOnceDir !include Win32.nsh !include Common.nsh +!include RunOnce.nsh !include AeroWizard.nsh !include Download2KXP.nsh -!include DownloadVista7.nsh -!include Download8.nsh +!include DownloadVista78.nsh !include DownloadWUA.nsh -!include RunOnce.nsh !include UpdateRoots.nsh -!include 7zip.nsh +; !include ActiveXPage.nsh !insertmacro GetParameters !insertmacro GetOptions -!define MUI_PAGE_HEADER_TEXT "Welcome to WUIsBack" -!define MUI_COMPONENTSPAGE_TEXT_TOP "Select what you would like WUIsBack to do. An internet connection is required to download additional components from Microsoft. Your computer will restart automatically if needed. Close all other programs before continuing." +!define MUI_PAGE_HEADER_TEXT "Welcome to Legacy Update - Vichingo455's Mod" +!define MUI_COMPONENTSPAGE_TEXT_TOP "Select what you would like Legacy Update to do. An internet connection is required to download additional components from Microsoft. Your computer will restart automatically if needed. Close all other programs before continuing." !define MUI_PAGE_CUSTOMFUNCTION_PRE ComponentsPageCheck !define MUI_PAGE_CUSTOMFUNCTION_SHOW OnShow !define MUI_PAGE_FUNCTION_GUIINIT OnShow @@ -84,13 +94,15 @@ Var /GLOBAL RunOnceDir !insertmacro MUI_PAGE_COMPONENTS +; Page custom ActiveXPage + !define MUI_PAGE_HEADER_TEXT "Performing Actions" !define MUI_PAGE_CUSTOMFUNCTION_SHOW OnShow !insertmacro MUI_PAGE_INSTFILES -!define MUI_PAGE_HEADER_TEXT "Uninstall WUIsBack" -!define MUI_UNCONFIRMPAGE_TEXT_TOP "WUIsBack will be uninstalled. Your Windows Update configuration will be reset to directly use Microsoft servers." +!define MUI_PAGE_HEADER_TEXT "Uninstall Legacy Update - Vichingo455's Mod" +!define MUI_UNCONFIRMPAGE_TEXT_TOP "Legacy Update - Vichingo455's Mod will be uninstalled. Your Windows Update configuration will be reset to directly use Microsoft servers." !define MUI_PAGE_CUSTOMFUNCTION_SHOW un.OnShow !insertmacro MUI_UNPAGE_CONFIRM @@ -100,13 +112,15 @@ Var /GLOBAL RunOnceDir !insertmacro MUI_UNPAGE_INSTFILES -!insertmacro MUI_LANGUAGE "English" +!include Strings.nsh + +; Uncomment lines below to enable code signing when compiling under Windows +; !uninstfinalize 'sign.cmd "certPath" certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0 +; !finalize 'sign.cmd "certPath" certPassword "Legacy Update - Vichingo455 Mod" "%1"' = 0 !macro RestartWUAUService - !insertmacro DetailPrint "Restarting Windows Update service..." - SetDetailsPrint none - ExecShellWait "" "$WINDIR\system32\net.exe" "stop wuauserv" SW_HIDE - SetDetailsPrint listonly + ${DetailPrint} "$(StatusRestartingWUAU)" + LegacyUpdateNSIS::Exec '"$WINDIR\system32\net.exe" stop wuauserv' !macroend Function OnShow @@ -117,59 +131,91 @@ Function un.OnShow Call un.AeroWizardOnShow FunctionEnd -Section -BeforeInstall - !insertmacro InhibitSleep 1 -SectionEnd +Function MakeUninstallEntry + ${IfNot} $UninstallInstalled == 1 + StrCpy $UninstallInstalled 1 + SetOutPath $INSTDIR + WriteUninstaller "$INSTDIR\Uninstall.exe" + + ; Add uninstall entry + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayName" "${NAME}" + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayIcon" '"$INSTDIR\Uninstall.exe",-103' + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "Publisher" "${NAME}" + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "URLInfoAbout" "${WEBSITE}" + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "QuietUninstallString" '"$INSTDIR\Uninstall.exe" /S' + WriteRegDword HKLM "${REGPATH_UNINSTSUBKEY}" "NoModify" 1 + WriteRegDword HKLM "${REGPATH_UNINSTSUBKEY}" "NoRepair" 1 + ${MakeARPInstallDate} $0 + WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "InstallDate" $0 + ${EndIf} +FunctionEnd + +Section -BeforeInstall PREREQS_START + !insertmacro InhibitSleep 1 -Section -PreDownload ${IfNot} ${IsRunOnce} ${AndIfNot} ${IsPostInstall} + ; Download files Call PreDownload + + ; If a reboot is pending, do it now + Call RebootIfCbsRebootPending + +!if ${DEBUG} == 1 + ${If} ${TestRunOnce} + SetRebootFlag true + Call RebootIfRequired + ${EndIf} +!endif + ${Else} + ; Wait for packages to install if needed + Call PollCbsInstall ${EndIf} SectionEnd -Section - PREREQS_START -SectionEnd - ; Win2k prerequisities -Section "Windows 2000 Service Pack 4" W2KSP4 - SectionIn Ro - Call InstallW2KSP4 - Call InstallKB835732 - Call RebootIfRequired -SectionEnd - -Section "Internet Explorer 6.0 Service Pack 1" IE6SP1 +Section "$(IE) 6.0 $(SP) 1" IE6SP1 SectionIn Ro Call InstallIE6 Call RebootIfRequired SectionEnd -Section "7-Zip File Manager" 7ZIP - Call Install7Zip +Section "Windows 2000 $(SP) 4" W2KSP4 + SectionIn Ro + Call InstallW2KSP4 + Call InstallW2KUR1 + Call FixW2KUR1 + Call RebootIfRequired SectionEnd ; XP 2002 prerequisities -${MementoSection} "Windows XP Service Pack 3" XPSP3 - Call InstallXPSP2 +${MementoSection} "Windows XP $(SP) 3" XPSP3 + Call InstallXPSP1a Call RebootIfRequired Call InstallXPSP3 Call RebootIfRequired ${MementoSectionEnd} -${MementoSection} "Windows XP Embedded Service Pack 3" XPESP3 +${MementoSection} "Windows XP $(EMB) $(SP) 3" XPESP3 Call InstallXPESP3 Call RebootIfRequired ${MementoSectionEnd} +${MementoUnselectedSection} "$(SectionWES09)" WES09 + WriteRegDword HKLM "${REGPATH_POSREADY}" "Installed" 1 +${MementoSectionEnd} + ; XP 2003 prerequisities -${MementoSection} "Windows XP/Server 2003 Service Pack 2" 2003SP2 +${MementoSection} "Windows XP/$(SRV) 2003 $(SP) 2" 2003SP2 Call Install2003SP2 Call RebootIfRequired ${MementoSectionEnd} ; Vista prerequisities -Section "Windows Vista Service Pack 2" VISTASP2 +Section "Windows Vista $(SP) 2" VISTASP2 SectionIn Ro Call InstallVistaSP1 Call RebootIfRequired @@ -177,7 +223,7 @@ Section "Windows Vista Service Pack 2" VISTASP2 Call RebootIfRequired SectionEnd -Section "Windows Servicing Stack update" VISTASSU +Section "$(SectionSSU)" VISTASSU SectionIn Ro Call InstallKB3205638 Call InstallKB4012583 @@ -187,7 +233,7 @@ Section "Windows Servicing Stack update" VISTASSU Call RebootIfRequired SectionEnd -${MementoSection} "Internet Explorer 9" VISTAIE9 +${MementoSection} "$(IE) 9" VISTAIE9 Call InstallKB971512 Call InstallKB2117917 Call RebootIfRequired @@ -196,41 +242,36 @@ ${MementoSection} "Internet Explorer 9" VISTAIE9 ${MementoSectionEnd} ; 7 prerequisities -Section "Windows 7 Service Pack 1" WIN7SP1 +Section "Windows 7 $(SP) 1" WIN7SP1 SectionIn Ro Call InstallWin7SP1 Call RebootIfRequired SectionEnd -Section "Windows Servicing Stack update" WIN7SSU +Section "$(SectionSSU)" WIN7SSU SectionIn Ro - Call InstallKB3102810 Call InstallKB3138612 Call InstallKB4474419 Call InstallKB4490628 Call RebootIfRequired SectionEnd -; Windows Home Server 2011 (Server 2008 R2) prerequisites -Section "Windows Home Server Update Rollup 4" WHS2011U4 +; Windows Home Server 2011 is based on Server 2008 R2, but has its own separate "rollup" updates +Section "$(SectionWHS2011U4)" WHS2011U4 SectionIn Ro Call InstallKB2757011 Call RebootIfRequired SectionEnd ; 8 prerequisities -Section "Windows Servicing Stack update" WIN8SSU +Section "$(SectionSSU)" WIN8SSU SectionIn Ro Call InstallKB4598297 Call RebootIfRequired SectionEnd -Section "Windows 8.1" WIN81UPGRADE - ; No-op; we'll launch the support site in post-install. -SectionEnd - ; 8.1 prerequisities -Section "Windows 8.1 Update 1" WIN81UPDATE1 +Section "Windows 8.1 $(Update) 1" WIN81U1 SectionIn Ro Call InstallKB3021910 Call InstallClearCompressionFlag @@ -242,23 +283,19 @@ Section "Windows 8.1 Update 1" WIN81UPDATE1 Call RebootIfRequired SectionEnd -Section "Windows Servicing Stack update" WIN81SSU +Section "$(SectionSSU)" WIN81SSU SectionIn Ro Call InstallKB3021910 Call RebootIfRequired SectionEnd ; Shared prerequisites -Section "Windows Update Agent update" WUA +Section "$(SectionWUA)" WUA SectionIn Ro Call InstallWUA SectionEnd -${MementoUnselectedSection} "Enable Windows Embedded 2009 updates" WES09 - WriteRegDword HKLM "${REGPATH_POSREADY}" "Installed" 1 -${MementoSectionEnd} - -${MementoSection} "Update root certificates store" ROOTCERTS +${MementoSection} "$(SectionRootCerts)" ROOTCERTS Call ConfigureCrypto ${IfNot} ${IsPostInstall} @@ -266,19 +303,19 @@ ${MementoSection} "Update root certificates store" ROOTCERTS ${EndIf} ${MementoSectionEnd} -${MementoSection} "Enable Microsoft Update" WIN7MU +${MementoSection} "$(SectionEnableMU)" WIN7MU LegacyUpdateNSIS::EnableMicrosoftUpdate Pop $0 ${If} $0 != 0 LegacyUpdateNSIS::MessageForHresult $0 - Pop $0 - MessageBox MB_USERICON "Failed to enable Microsoft Update.$\r$\n$\r$\n$0" /SD IDOK - ${Else} - !insertmacro RestartWUAUService + Pop $1 + ${DetailPrint} "$1 ($0)" + MessageBox MB_USERICON "$(MsgBoxMUFailed)" /SD IDOK ${EndIf} + !insertmacro RestartWUAUService ${MementoSectionEnd} -${MementoSection} "Activate Windows" ACTIVATE +${MementoSection} "$(SectionActivate)" ACTIVATE ; No-op; we'll launch the activation wizard in post-install. ${MementoSectionEnd} @@ -286,67 +323,97 @@ Section - PREREQS_END SectionEnd ; Main installation -${MementoSection} "WUIsBack" LEGACYUPDATE - SetOutPath $InstallDir - WriteUninstaller "$OUTDIR\Uninstall.exe" +${MementoSection} "$(^Name)" LEGACYUPDATE + ; WUSERVER section + Call MakeUninstallEntry + ; Check if Schannel is going to work with modern TLS + ${If} ${AtLeastWinVista} + ${DetailPrint} "$(StatusCheckingSSL)" + !insertmacro DownloadRequest "${WSUS_SERVER_HTTPS}/ClientWebService/ping.bin" NONE \ + `/TIMEOUTCONNECT 0 /TIMEOUTRECONNECT 0` + Pop $0 + Call DownloadWaitSilent + Pop $0 + Pop $0 + ${VerbosePrint} "Ping result: $0" + ${Else} + StrCpy $0 "" + ${EndIf} - ; Add uninstall entry - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayName" "${NAME}" - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayIcon" '"$OUTDIR\LegacyUpdate.dll",-201' - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "DisplayVersion" "${VERSION}" - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "Publisher" "${NAME}" - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "URLInfoAbout" "${WEBSITE}" - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "UninstallString" '"$OUTDIR\Uninstall.exe"' - WriteRegStr HKLM "${REGPATH_UNINSTSUBKEY}" "QuietUninstallString" '"$OUTDIR\Uninstall.exe" /S' - WriteRegDword HKLM "${REGPATH_UNINSTSUBKEY}" "NoModify" 1 - WriteRegDword HKLM "${REGPATH_UNINSTSUBKEY}" "NoRepair" 1 + ${If} $0 == "OK" + ; HTTPS will work + WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUServer" "${WSUS_SERVER_HTTPS}" + WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" "${WSUS_SERVER_HTTPS}" + WriteRegStr HKLM "${REGPATH_WU}" "URL" "${UPDATE_URL_HTTPS}" + ${Else} + ; Probably not supported; use HTTP + WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUServer" "${WSUS_SERVER}" + WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" "${WSUS_SERVER}" + WriteRegStr HKLM "${REGPATH_WU}" "URL" "${UPDATE_URL}" + ${EndIf} + + WriteRegDword HKLM "${REGPATH_WUAUPOLICY}" "UseWUServer" 1 + + ; Restart service + !insertmacro RestartWUAUService + + ; ACTIVEX section + SetOutPath $INSTDIR + ; Call MakeUninstallEntry ; Add Control Panel entry ; Category 5: XP Performance and Maintenance, Vista System and Maintenance, 7+ System and Security ; Category 10: XP SP2 Security Center, Vista Security, 7+ System and Security - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "" "${NAME}" - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "LocalizedString" '${NAME}' - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "InfoTip" 'Check for software and driver updates via ${NAME}' - WriteRegStr HKCR "${REGPATH_CPLCLSID}\DefaultIcon" "" '"$OUTDIR\LegacyUpdate.dll",-201' - WriteRegStr HKCR "${REGPATH_CPLCLSID}\Shell\Open\Command" "" 'rundll32.exe "$OUTDIR\LegacyUpdate.dll",LaunchUpdateSite' - WriteRegDword HKCR "${REGPATH_CPLCLSID}\ShellFolder" "Attributes" 0 - WriteRegDword HKCR "${REGPATH_CPLCLSID}" "{305CA226-D286-468e-B848-2B2E8E697B74} 2" 5 - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "System.ApplicationName" "${CPL_APPNAME}" - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "System.ControlPanelCategory" "5,10" - WriteRegStr HKCR "${REGPATH_CPLCLSID}" "System.Software.TasksFileUrl" "$OUTDIR\LegacyUpdate.dll,-202" + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "" "${NAME}" + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "LocalizedString" '@"$OUTDIR\LegacyUpdate.exe",-2' + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "InfoTip" '@"$OUTDIR\LegacyUpdate.exe",-4' + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}\DefaultIcon" "" '"$OUTDIR\LegacyUpdate.exe",-100' + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}\Shell\Open\Command" "" '"$OUTDIR\LegacyUpdate.exe"' + WriteRegDword HKCR "${REGPATH_HKCR_CPLCLSID}\ShellFolder" "Attributes" 0 + WriteRegDword HKCR "${REGPATH_HKCR_CPLCLSID}" "{305CA226-D286-468e-B848-2B2E8E697B74} 2" 5 + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "System.ApplicationName" "${CPL_APPNAME}" + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "System.ControlPanelCategory" "5,10" + WriteRegStr HKCR "${REGPATH_HKCR_CPLCLSID}" "System.Software.TasksFileUrl" '"$OUTDIR\LegacyUpdate.exe",-202' + WriteRegStr HKLM "${REGPATH_CPLNAMESPACE}" "" "${NAME}" - ; Install DLL, with detection for it being in use by IE + ; Install DLLs + ${VerbosePrint} "Closing IE windows" + LegacyUpdateNSIS::CloseIEWindows + ; NOTE: Here we specifically check for amd64, because the DLL is amd64. ; We still install to native Program Files on IA64, but with x86 binaries. - SetOverwrite try - !insertmacro TryFile "..\Release\LegacyUpdate.dll" "$OUTDIR\LegacyUpdate.dll" + File "..\${VSBUILD32}\LegacyUpdate.dll" ${If} ${IsNativeAMD64} - ${If} ${FileExists} "$OUTDIR\LegacyUpdate32.dll" - !insertmacro TryDelete "$OUTDIR\LegacyUpdate32.dll" + ${If} ${FileExists} "LegacyUpdate32.dll" + Delete "LegacyUpdate32.dll" ${EndIf} - !insertmacro TryRename "$OUTDIR\LegacyUpdate.dll" "$OUTDIR\LegacyUpdate32.dll" - !insertmacro TryFile "..\x64\Release\LegacyUpdate.dll" "$OUTDIR\LegacyUpdate.dll" + Rename "LegacyUpdate.dll" "LegacyUpdate32.dll" + File "..\x64\${VSBUILD64}\LegacyUpdate.dll" ${EndIf} - SetOverwrite on + Call CopyLauncher - ; Register DLL - ${If} ${IsNativeAMD64} - !insertmacro RegisterDLL "" x64 "$OUTDIR\LegacyUpdate.dll" - !insertmacro RegisterDLL "" x86 "$OUTDIR\LegacyUpdate32.dll" - ${Else} - !insertmacro RegisterDLL "" x86 "$OUTDIR\LegacyUpdate.dll" + ; Register DLLs + ExecWait '"$OUTDIR\LegacyUpdate.exe" /regserver $HWNDPARENT' $0 + ${If} $0 != 0 + Abort ${EndIf} ; Create shortcut + ${If} ${IsWin2000} + ; Doesn't seem to support @ syntax with an exe? + StrCpy $0 "Check for software updates via Legacy Update." + ${Else} + StrCpy $0 "Check for software updates via Legacy Update." + ${EndIf} + CreateShortcut "$COMMONSTARTMENU\${NAME}.lnk" \ - "$SYSDIR\rundll32.exe" '"$OUTDIR\LegacyUpdate.dll",LaunchUpdateSite' \ - "$OUTDIR\LegacyUpdate.dll" 0 \ + '"$OUTDIR\LegacyUpdate.exe"' '' \ + "$OUTDIR\LegacyUpdate.exe" 0 \ SW_SHOWNORMAL "" \ - '@"$OUTDIR\LegacyUpdate.dll",-4' + "$0" ; Hide WU shortcuts - ; TODO: How can we consistently find the shortcuts for non-English installs? ${If} ${AtMostWinXP2003} ${If} ${FileExists} "$COMMONSTARTMENU\Windows Update.lnk" CreateDirectory "$OUTDIR\Backup" @@ -360,11 +427,29 @@ ${MementoSection} "WUIsBack" LEGACYUPDATE ${EndIf} ; Add to trusted sites + WriteRegDword HKLM "${REGPATH_ZONEDOMAINS}\${DOMAIN}" "http" 2 + WriteRegDword HKLM "${REGPATH_ZONEDOMAINS}\${DOMAIN}" "https" 2 + WriteRegDword HKLM "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" "http" 2 + WriteRegDword HKLM "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" "https" 2 + WriteRegDword HKCU "${REGPATH_ZONEDOMAINS}\${DOMAIN}" "http" 2 WriteRegDword HKCU "${REGPATH_ZONEDOMAINS}\${DOMAIN}" "https" 2 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" + + ${If} ${RunningX64} + SetRegView 32 + 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" + SetRegView 64 + ${EndIf} + ; Delete LegacyUpdate.dll in System32 from 1.0 installer ${If} ${FileExists} $WINDIR\System32\LegacyUpdate.dll Delete $WINDIR\System32\LegacyUpdate.dll @@ -382,39 +467,9 @@ ${MementoSection} "WUIsBack" LEGACYUPDATE Rename "$PROGRAMFILES32\Legacy Update\Backup" "$PROGRAMFILES64\Legacy Update\Backup" RMDir /r "$PROGRAMFILES32\Legacy Update" ${EndIf} - - ; Set WSUS server - ; Check if Schannel is going to work with modern TLS - ${If} ${AtMostWin8.1} - !insertmacro DetailPrint "Checking SSL connectivity..." - !insertmacro DownloadRequest "${WSUS_SERVER_HTTPS}/ClientWebService/ping.bin" NONE \ - `/TIMEOUTCONNECT 0 /TIMEOUTRECONNECT 0` - Pop $0 - Call DownloadWaitSilent - Pop $0 - Pop $0 - - ${If} $0 == "OK" - ; HTTPS will work - !insertmacro DetailPrint "SSL: Detected working HTTPS!" - WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUServer" "${WSUS_SERVER_HTTPS}" - WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" "${WSUS_SERVER_HTTPS}" - WriteRegStr HKLM "${REGPATH_WU}" "URL" "${UPDATE_URL_HTTPS}" - ${Else} - ; Probably not supported; use HTTP - !insertmacro DetailPrint "SSL: HTTPS is probably not supported. Using HTTP." - WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUServer" "${WSUS_SERVER}" - WriteRegStr HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" "${WSUS_SERVER}" - WriteRegStr HKLM "${REGPATH_WU}" "URL" "${UPDATE_URL}" - ${EndIf} - WriteRegDword HKLM "${REGPATH_WUAUPOLICY}" "UseWUServer" 1 - ${EndIf} - - ; Restart service - !insertmacro RestartWUAUService ${MementoSectionEnd} -${MementoSection} "Allow OS Upgrade" ALLOWOSUPGRADE +${MementoUnselectedSection} "$(SectionAllowOSUpgrade)" ALLOWOSUPGRADE WriteRegDword HKLM "${REGPATH_WUPOLICY}" "AllowOSUpgrade" 1 WriteRegDword HKLM "${REGPATH_WUPOLICY}" "DisableOSUpgrade" 0 WriteRegDword HKLM "${REGPATH_WUPOLICY}\OSUpgrade" "AllowOSUpgrade" 1 @@ -426,16 +481,44 @@ ${MementoSectionEnd} ${MementoSectionDone} -Section -Uninstall - SetOutPath $InstallDir +; Uninstaller +Section "-un.Legacy Update Server" un.WUSERVER + ; Clear WSUS server + ${If} ${AtMostWinVista} + ReadRegStr $0 HKLM "${REGPATH_WUPOLICY}" "WUServer" + ${VerbosePrint} "WUServer: $0" + ${If} $0 == "${WSUS_SERVER}" + ${OrIf} $0 == "${WSUS_SERVER_HTTPS}" + DeleteRegValue HKLM "${REGPATH_WUPOLICY}" "WUServer" + DeleteRegValue HKLM "${REGPATH_WUAUPOLICY}" "UseWUServer" + ${EndIf} + + ReadRegStr $0 HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" + ${VerbosePrint} "WUStatusServer: $0" + ${If} $0 == "${WSUS_SERVER}" + ${OrIf} $0 == "${WSUS_SERVER_HTTPS}" + DeleteRegValue HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" + DeleteRegValue HKLM "${REGPATH_WUAUPOLICY}" "UseWUServer" + ${EndIf} + + ReadRegStr $0 HKLM "${REGPATH_WU}" "URL" + ${VerbosePrint} "URL: $0" + ${If} $0 == "${UPDATE_URL}" + ${OrIf} $0 == "${UPDATE_URL_HTTPS}" + DeleteRegValue HKLM "${REGPATH_WU}" "URL" + ${EndIf} + ${EndIf} +SectionEnd + +Section "-un.Legacy Update website" un.ACTIVEX + SetOutPath $INSTDIR ; Delete shortcut - ${UnpinShortcut} "$COMMONSTARTMENU\${NAME}.lnk" Delete "$COMMONSTARTMENU\${NAME}.lnk" ; Delete Control Panel entry DeleteRegKey HKLM "${REGPATH_CPLNAMESPACE}" - DeleteRegKey HKCR "${REGPATH_CPLCLSID}" + DeleteRegKey HKCR "${REGPATH_HKCR_CPLCLSID}" ; Restore shortcuts ${If} ${FileExists} "$OUTDIR\Backup\Windows Update.lnk" @@ -446,80 +529,84 @@ Section -Uninstall Rename "$OUTDIR\Backup\Microsoft Update.lnk" "$COMMONSTARTMENU\Microsoft Update.lnk" ${EndIf} - ; Unregister DLLS - ${If} ${IsNativeAMD64} - !insertmacro RegisterDLL Un x64 "$OUTDIR\LegacyUpdate.dll" - !insertmacro RegisterDLL Un x86 "$OUTDIR\LegacyUpdate32.dll" - ${Else} - !insertmacro RegisterDLL Un x86 "$OUTDIR\LegacyUpdate.dll" + ; Unregister DLLs + ExecWait '"$OUTDIR\LegacyUpdate.exe" /unregserver $HWNDPARENT' $0 + ${If} $0 != 0 + Abort ${EndIf} - ; Delete DLLs - SetOverwrite try - !insertmacro TryDelete "$OUTDIR\LegacyUpdate.dll" - !insertmacro TryDelete "$OUTDIR\LegacyUpdate32.dll" - SetOverwrite on - - ; Clear WSUS server - ${If} ${AtMostWinVista} - DeleteRegValue HKLM "${REGPATH_WUPOLICY}" "WUServer" - DeleteRegValue HKLM "${REGPATH_WUPOLICY}" "WUStatusServer" - DeleteRegValue HKLM "${REGPATH_WUAUPOLICY}" "UseWUStatusServer" - DeleteRegValue HKLM "${REGPATH_WU}" "URL" - ${EndIf} + ; Delete files + Delete "$OUTDIR\LegacyUpdate.exe" + Delete "$OUTDIR\LegacyUpdate.dll" + Delete "$OUTDIR\LegacyUpdate32.dll" ; Remove from trusted sites + DeleteRegKey HKLM "${REGPATH_ZONEDOMAINS}\${DOMAIN}" DeleteRegKey HKCU "${REGPATH_ZONEDOMAINS}\${DOMAIN}" + DeleteRegKey HKLM "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" DeleteRegKey HKCU "${REGPATH_ZONEESCDOMAINS}\${DOMAIN}" + ; Remove IE elevation policy + DeleteRegKey HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" + + ${If} ${RunningX64} + SetRegView 32 + DeleteRegKey HKLM "${REGPATH_ELEVATIONPOLICY}\${ELEVATIONPOLICY_GUID}" + SetRegView 64 + ${EndIf} + ; Restart service !insertmacro RestartWUAUService +SectionEnd + +Section -Uninstall + SetOutPath $INSTDIR ; Delete folders RMDir /r "$OUTDIR" - RMDir /r /REBOOTOK "$RunOnceDir" + RMDir /r /REBOOTOK "${RUNONCEDIR}" ; Delete uninstall entry DeleteRegKey HKLM "${REGPATH_UNINSTSUBKEY}" SectionEnd -!define DESCRIPTION_REBOOTS "Your computer will restart automatically to complete installation." -!define DESCRIPTION_SUPEULA "By installing, you are agreeing to the Supplemental End User License Agreement for this update." -!define DESCRIPTION_MSLT "By installing, you are agreeing to the Microsoft Software License Terms for this update." +!macro DESCRIPTION_STRING section + !insertmacro MUI_DESCRIPTION_TEXT ${${section}} "$(Section${section}Desc)" +!macroend !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${W2KSP4} "Updates Windows 2000 to Service Pack 4, as required to install the Windows Update Agent.$\r$\n${DESCRIPTION_REBOOTS} ${DESCRIPTION_SUPEULA}" - !insertmacro MUI_DESCRIPTION_TEXT ${IE6SP1} "Updates Internet Explorer to 6.0 SP1, as required for Legacy Update.$\r$\n${DESCRIPTION_REBOOTS} ${DESCRIPTION_SUPEULA}" - !insertmacro MUI_DESCRIPTION_TEXT ${XPSP3} "Updates Windows XP to Service Pack 3. Required if you would like to activate Windows online. ${DESCRIPTION_REBOOTS} ${DESCRIPTION_SUPEULA}" - !insertmacro MUI_DESCRIPTION_TEXT ${XPESP3} "Updates Windows XP Embedded to Service Pack 3. Required if you would like to activate Windows online. ${DESCRIPTION_REBOOTS} ${DESCRIPTION_SUPEULA}" - !insertmacro MUI_DESCRIPTION_TEXT ${WES09} "Configures Windows to appear as Windows Embedded POSReady 2009 to Windows Update, enabling access to Windows XP security updates released between 2014 and 2019. Please note that Microsoft officially advises against doing this." - !insertmacro MUI_DESCRIPTION_TEXT ${2003SP2} "Updates Windows XP x64 Edition or Windows Server 2003 to Service Pack 2. Required if you would like to activate Windows online. ${DESCRIPTION_REBOOTS} ${DESCRIPTION_SUPEULA}" - !insertmacro MUI_DESCRIPTION_TEXT ${VISTASP2} "Updates Windows Vista or Windows Server 2008 to Service Pack 2, as required to install the Windows Update Agent. ${DESCRIPTION_REBOOTS} ${DESCRIPTION_MSLT}" - !insertmacro MUI_DESCRIPTION_TEXT ${VISTASSU} "Updates Windows Vista or Windows Server 2008 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${VISTAIE9} "Updates Internet Explorer to 9.0.$\r$\n${DESCRIPTION_REBOOTS} ${DESCRIPTION_MSLT}" - !insertmacro MUI_DESCRIPTION_TEXT ${WIN7SP1} "Updates Windows 7 or Windows Server 2008 R2 to Service Pack 1, as required to install the Windows Update Agent. ${DESCRIPTION_REBOOTS} ${DESCRIPTION_MSLT}" - !insertmacro MUI_DESCRIPTION_TEXT ${WIN7SSU} "Updates Windows 7 or Windows Server 2008 R2 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${WIN8SSU} "Updates Windows 8 or Windows Server 2012 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${WIN81UPGRADE} "Windows 8 can be updated to Windows 8.1. This process involves a manual download. After Legacy Update setup completes, a Microsoft website will be opened with more information." - !insertmacro MUI_DESCRIPTION_TEXT ${WIN81UPDATE1} "Updates Windows 8.1 to Update 1, as required to resolve issues with the Windows Update Agent. Also required to upgrade to Windows 10.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${WIN81SSU} "Updates Windows 8.1 or Windows Server 2012 R2 with additional updates required to resolve issues with the Windows Update Agent.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${WHS2011U4} "Updates Windows Home Server 2011 to Update Rollup 4 to resolve issues with the Windows Update Agent. Also fixes data corruption problems.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${WUA} "Updates the Windows Update Agent to the latest version, as required for Legacy Update." - !insertmacro MUI_DESCRIPTION_TEXT ${ROOTCERTS} "Updates the root certificate store to the latest from Microsoft, and enables additional modern security features. Root certificates are used to verify the security of encrypted (https) connections. This fixes connection issues with some websites." - !insertmacro MUI_DESCRIPTION_TEXT ${WIN7MU} "Configures Windows to install updates for Microsoft Office and other Microsoft software." - !insertmacro MUI_DESCRIPTION_TEXT ${ACTIVATE} "Your copy of Windows is not activated. If you update the root certificates store, Windows Product Activation can be completed over the internet. Legacy Update can start the activation wizard after installation so you can activate your copy of Windows." - !insertmacro MUI_DESCRIPTION_TEXT ${ALLOWOSUPGRADE} "Forces Windows Update to deliver the Windows 10/11 upgrade.$\r$\n${DESCRIPTION_REBOOTS}" - !insertmacro MUI_DESCRIPTION_TEXT ${7ZIP} "Installs 7-Zip on Windows 2000 to open zip files.$\r$\n${DESCRIPTION_SUPEULA}" + !insertmacro DESCRIPTION_STRING W2KSP4 + !insertmacro DESCRIPTION_STRING IE6SP1 + !insertmacro DESCRIPTION_STRING XPSP3 + !insertmacro DESCRIPTION_STRING XPESP3 + !insertmacro DESCRIPTION_STRING WES09 + !insertmacro DESCRIPTION_STRING 2003SP2 + !insertmacro DESCRIPTION_STRING VISTASP2 + !insertmacro DESCRIPTION_STRING VISTASSU + !insertmacro DESCRIPTION_STRING VISTAIE9 + !insertmacro DESCRIPTION_STRING WIN7SP1 + !insertmacro DESCRIPTION_STRING WIN7SSU + !insertmacro DESCRIPTION_STRING WIN8SSU + !insertmacro DESCRIPTION_STRING WIN81U1 + !insertmacro DESCRIPTION_STRING WIN81SSU + !insertmacro DESCRIPTION_STRING WHS2011U4 + !insertmacro DESCRIPTION_STRING WUA + !insertmacro DESCRIPTION_STRING ROOTCERTS + !insertmacro DESCRIPTION_STRING WIN7MU + !insertmacro DESCRIPTION_STRING ACTIVATE + ; !insertmacro DESCRIPTION_STRING LEGACYUPDATE + ; !insertmacro DESCRIPTION_STRING WUSERVER + !insertmacro DESCRIPTION_STRING ALLOWOSUPGRADE !insertmacro MUI_FUNCTION_DESCRIPTION_END Function OnMouseOverSection ${If} $0 == ${LEGACYUPDATE} ${If} ${AtMostWinXP2003} - StrCpy $0 "Installs WUIsBack, enabling access to the full Windows Update interface via the legacyupdate.net website. Windows Update will be configured to use the WUIsBack WSUS server." + StrCpy $0 "$(SectionActiveX2KXPDesc)" ${ElseIf} ${AtMostWin8.1} - StrCpy $0 "Installs WUIsBack, enabling access to the full Windows Update interface via the legacyupdate.net website, and Windows Update Control Panel. Windows Update will be configured to use the WUIsBack WSUS server." + StrCpy $0 "$(SectionActiveXVista78Desc)" ${Else} - StrCpy $0 "Installs WUIsBack, enabling access to the full Windows Update interface via the legacyupdate.net website, and Windows Update Settings page. Windows Update will be configured to use the WUIsBack WSUS server." + StrCpy $0 "$(SectionActiveXWin10Desc)" ${EndIf} SendMessage $mui.ComponentsPage.DescriptionText ${WM_SETTEXT} 0 "STR:" EnableWindow $mui.ComponentsPage.DescriptionText 1 @@ -527,96 +614,120 @@ Function OnMouseOverSection ${EndIf} FunctionEnd -!macro Init - SetShellVarContext All - ${If} ${RunningX64} - SetRegView 64 - StrCpy $InstallDir "$PROGRAMFILES64\${NAME}" - ${Else} - StrCpy $InstallDir "$PROGRAMFILES32\${NAME}" - ${EndIf} - StrCpy $RunOnceDir "$COMMONPROGRAMDATA\Legacy Update" - !insertmacro EnsureAdminRights - SetDetailsPrint listonly -!macroend - Function .onInit ${If} ${IsHelp} - MessageBox MB_USERICON \ - "Usage: setup.exe [/S] [/norestart]$\r$\n\ - $\r$\n\ - /S$\tExecutes WUIsBack setup silently.$\r$\n\ - /norestart$\tDisables automatic restart during installation.$\r$\n\ - $\r$\n\ - If no flags are passed, WUIsBack will launch its full user interface.$\r$\n\ - For more information on these flags, visit legacyupdate.net." + MessageBox MB_USERICON "$(MsgBoxUsage)" Quit ${EndIf} - !insertmacro Init + SetShellVarContext all + ${If} ${IsVerbose} + SetDetailsPrint both + ${Else} + SetDetailsPrint listonly + ${EndIf} + ${If} "$PROGRAMFILES64" != "$PROGRAMFILES32" + SetRegView 64 + ${EndIf} + !insertmacro EnsureAdminRights ${If} ${IsRunOnce} ${OrIf} ${IsPostInstall} Call OnRunOnceLogon + ${ElseIfNot} ${AtLeastWin10} + GetWinVer $0 Build + ReadRegDword $1 HKLM "${REGPATH_CONTROL_WINDOWS}" "CSDVersion" + IntOp $1 $1 & 0xFF + ${If} $1 != 0 + ${VerbosePrint} "Unexpected service pack: $1" + StrCpy $1 1 + ${EndIf} + + ${If} $0 != ${WINVER_BUILD_2000} + ${AndIf} $0 != ${WINVER_BUILD_XP2002} + ${AndIf} $0 != ${WINVER_BUILD_XP2003} + ${AndIf} $0 != ${WINVER_BUILD_VISTA} + ${AndIf} $0 != ${WINVER_BUILD_VISTA_SP1} + ${AndIf} $0 != ${WINVER_BUILD_VISTA_SP2} + ${AndIf} $0 != ${WINVER_BUILD_VISTA_ESU} + ${AndIf} $0 != ${WINVER_BUILD_7} + ${AndIf} $0 != ${WINVER_BUILD_7_SP1} + ${AndIf} $0 != ${WINVER_BUILD_8} + ${AndIf} $0 != ${WINVER_BUILD_8.1} + ${VerbosePrint} "Unexpected build: $0" + StrCpy $1 1 + ${EndIf} + + ${If} $1 == 1 + MessageBox MB_USERICON|MB_OKCANCEL "$(MsgBoxBetaOS)" /SD IDOK \ + IDOK +2 + Quit + ${EndIf} + ${EndIf} + + ; Check for compatibility mode (GetVersionEx() and RtlGetNtVersionNumbers() disagreeing) + GetWinVer $0 Major + GetWinVer $1 Minor + GetWinVer $2 Build + System::Call '${RtlGetNtVersionNumbers}(.r3, .r4, .r5)' + IntOp $5 $5 & 0xFFFF + + ; Detect NNN4NT5 + ReadEnvStr $6 "_COMPAT_VER_NNN" + ${If} $6 != "" + StrCpy $3 "?" + ${EndIf} + + ; Windows 2000 lacks RtlGetNtVersionNumbers(), but there is no compatibility mode anyway. + ${If} "$3.$4.$5" != "0.0.0" + ${AndIf} "$0.$1.$2" != "$3.$4.$5" + ${VerbosePrint} "Compatibility mode detected. Fake: $0.$1.$2, Actual: $3.$4.$5" + MessageBox MB_USERICON "$(MsgBoxCompatMode)" /SD IDOK + SetErrorLevel 1 + Quit ${EndIf} SetOutPath $PLUGINSDIR File Patches.ini - SetOutPath $RunOnceDir + SetOutPath "${RUNONCEDIR}" ${MementoSectionRestore} ${If} ${IsWin2000} - !insertmacro RemoveSection ${ALLOWOSUPGRADE} ; Determine whether Win2k prereqs need to be installed - Call NeedsW2KSP4 - Call NeedsKB835732 - Pop $0 - Pop $1 - ${If} $0 == 0 - ${AndIf} $1 == 0 + ${IfNot} ${NeedsPatch} W2KSP4 + ${AndIfNot} ${NeedsPatch} W2KUR1 !insertmacro RemoveSection ${W2KSP4} ${EndIf} - ; Check if system needs Internet Explorer 6 - Call NeedsIE6 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} IE6 !insertmacro RemoveSection ${IE6SP1} ${EndIf} - ; Check if 7-Zip is installed - ${If} ${FileExists} "$PROGRAMFILES\7-Zip\7zFM.exe" - !insertmacro RemoveSection ${7ZIP} + ; Handle 2000 Datacenter Server + ${If} ${IsDatacenter} + !insertmacro UnselectSection ${LEGACYUPDATE} ${EndIf} ${Else} !insertmacro RemoveSection ${W2KSP4} !insertmacro RemoveSection ${IE6SP1} - !insertmacro RemoveSection ${7ZIP} ${EndIf} ${If} ${IsWinXP2002} - !insertmacro RemoveSection ${ALLOWOSUPGRADE} ${If} ${IsEmbedded} ; Determine whether XP Embedded prereqs need to be installed ; Windows XP Embedded (version 2001), including FLP and WEPOS, has a different service pack !insertmacro RemoveSection ${XPSP3} - Call NeedsXPESP3 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} XPESP3 !insertmacro RemoveSection ${XPESP3} ${EndIf} - ${EndIf} - - ${IfNot} ${IsEmbedded} + ${Else} ; Determine whether XP prereqs need to be installed !insertmacro RemoveSection ${XPESP3} - Call NeedsXPSP3 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} XPSP3 !insertmacro RemoveSection ${XPSP3} ${EndIf} ${EndIf} @@ -632,11 +743,8 @@ Function .onInit ${EndIf} ${If} ${IsWinXP2003} - !insertmacro RemoveSection ${ALLOWOSUPGRADE} ; Determine whether 2003 prereqs need to be installed - Call Needs2003SP2 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} 2003SP2 !insertmacro RemoveSection ${2003SP2} ${EndIf} ${Else} @@ -644,23 +752,16 @@ Function .onInit ${EndIf} ${If} ${IsWinVista} - !insertmacro RemoveSection ${ALLOWOSUPGRADE} ; Determine whether Vista prereqs need to be installed - Call NeedsVistaSP2 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} VistaSP2 !insertmacro RemoveSection ${VISTASP2} ${EndIf} - Call NeedsVistaPostSP2 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} VistaPostSP2 !insertmacro RemoveSection ${VISTASSU} ${EndIf} - Call NeedsIE9 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} IE9 !insertmacro RemoveSection ${VISTAIE9} ${EndIf} ${Else} @@ -671,25 +772,16 @@ Function .onInit ${If} ${IsWin7} ; Determine whether 7 prereqs need to be installed - Call NeedsWin7SP1 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} Win7SP1 !insertmacro RemoveSection ${WIN7SP1} ${EndIf} - ${If} ${IsHomeServer} - Call NeedsKB2757011 - Pop $0 - ${If} $0 == 0 - !insertmacro RemoveSection ${WHS2011U4} - ${EndIf} - ${Else} + ${IfNot} ${IsHomeServer} + ${OrIfNot} ${NeedsPatch} KB2757011 !insertmacro RemoveSection ${WHS2011U4} ${EndIf} - Call NeedsWin7SHA2 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} Win7PostSP1 !insertmacro RemoveSection ${WIN7SSU} ${EndIf} @@ -707,35 +799,24 @@ Function .onInit ${If} ${IsWin8} ; Determine whether 8 prereqs need to be installed - ${IfNot} ${IsWin8} - !insertmacro RemoveSection ${WIN81UPGRADE} - ${EndIf} - - Call NeedsKB4598297 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} KB4598297 !insertmacro RemoveSection ${WIN8SSU} ${EndIf} ${Else} - !insertmacro RemoveSection ${WIN81UPGRADE} !insertmacro RemoveSection ${WIN8SSU} ${EndIf} ${If} ${IsWin8.1} ; Determine whether 8.1 prereqs need to be installed - Call NeedsWin81Update1 - Pop $0 - ${If} $0 == 0 - !insertmacro RemoveSection ${WIN81UPDATE1} + ${IfNot} ${NeedsPatch} Win81Update1 + !insertmacro RemoveSection ${WIN81U1} ${EndIf} - Call NeedsKB3021910 - Pop $0 - ${If} $0 == 0 + ${IfNot} ${NeedsPatch} KB3021910 !insertmacro RemoveSection ${WIN81SSU} ${EndIf} ${Else} - !insertmacro RemoveSection ${WIN81UPDATE1} + !insertmacro RemoveSection ${WIN81U1} !insertmacro RemoveSection ${WIN81SSU} ${EndIf} @@ -744,33 +825,42 @@ Function .onInit !insertmacro RemoveSection ${WUA} ${EndIf} - ${If} ${IsWinXP2002} - ${OrIf} ${IsWinXP2003} + ${If} ${AtLeastWinXP2002} + ${AndIf} ${AtMostWin8.1} ; Check if the OS needs activation - LegacyUpdateNSIS::IsProcessRunning "wpabaln.exe" + LegacyUpdateNSIS::IsActivated Pop $0 - ${If} $0 == 0 + ${If} $0 == 1 !insertmacro RemoveSection ${ACTIVATE} ${EndIf} ${Else} !insertmacro RemoveSection ${ACTIVATE} ${EndIf} + ; ${IfNot} ${AtMostWinVista} + ; !insertmacro RemoveSection ${LEGACYUPDATE} + ; ${EndIf} + ; Try not to be too intrusive on Windows 10 and newer, which are (for now) fine ${If} ${AtLeastWin10} + !insertmacro RemoveSection ${ROOTCERTS} + ${EndIf} + + ${IfNot} ${AtLeastWin7} !insertmacro RemoveSection ${ALLOWOSUPGRADE} ${EndIf} FunctionEnd Function ComponentsPageCheck - ; Skip the page if we're being launched via RunOnce + ; Skip the page if we're being launched with /runonce, /postinstall, or /passive ${If} ${IsRunOnce} ${OrIf} ${IsPostInstall} + ${OrIf} ${IsPassive} Abort ${EndIf} ; Skip if installer was invoked by IE, and all prerequisites are installed - ${If} ${IsActiveXInstall} + ${If} ${IsActiveX} ${AndIf} ${SectionIsSelected} ${LEGACYUPDATE} StrCpy $1 0 ${For} $0 ${PREREQS_START} ${PREREQS_END} @@ -794,14 +884,14 @@ Function PreDownload ; Win2k ${If} ${IsWin2000} Call DownloadW2KSP4 - Call DownloadKB835732 + Call DownloadW2KUR1 Call DownloadIE6 ${EndIf} ; XP 2002 ${If} ${IsWinXP2002} ${AndIf} ${SectionIsSelected} ${XPSP3} - Call DownloadXPSP2 + Call DownloadXPSP1a Call DownloadXPSP3 ${EndIf} @@ -840,7 +930,7 @@ Function PreDownload ${Else} Call DownloadWin7SP1 ${EndIf} - Call DownloadKB3102810 + Call DownloadKB3138612 Call DownloadKB4474419 Call DownloadKB4490628 @@ -866,17 +956,19 @@ Function PreDownload ; General Call DownloadWUA - ${If} ${SectionIsSelected} ${ROOTCERTS} + ${If} ${AtMostWin8.1} + ${AndIf} ${SectionIsSelected} ${ROOTCERTS} Call DownloadRoots ${EndIf} FunctionEnd Function PostInstall ; Handle first run flag if needed - ${If} ${FileExists} "$InstallDir\LegacyUpdate.dll" + ${If} ${FileExists} "$INSTDIR\LegacyUpdate.exe" + ClearErrors ReadRegDword $0 HKLM "${REGPATH_LEGACYUPDATE_SETUP}" "ActiveXInstalled" ${If} ${Errors} - StrCpy $0 "firstrun" + StrCpy $0 "/firstrun" ${Else} StrCpy $0 "" ${EndIf} @@ -885,32 +977,39 @@ Function PostInstall ${IfNot} ${Silent} ${AndIfNot} ${IsRunOnce} - ${IfNot} ${IsActiveXInstall} - ${AndIf} ${SectionIsSelected} ${LEGACYUPDATE} - Exec '$SYSDIR\rundll32.exe "$InstallDir\LegacyUpdate.dll",LaunchUpdateSite $0' + ${If} ${FileExists} "$INSTDIR\LegacyUpdate.exe" + Exec '"$INSTDIR\LegacyUpdate.exe" /launch $0' + ${ElseIf} ${AtLeastWin10} + ExecShell "" "ms-settings:windowsupdate" ${ElseIf} ${AtLeastWinVista} - Exec '$SYSDIR\wuauclt.exe /ShowWUAutoScan' + Exec '"$WINDIR\system32\wuauclt.exe" /ShowWUAutoScan' ${EndIf} - ; Launch XP activation wizard if requested by the user + ; Launch activation wizard if requested by the user ${If} ${SectionIsSelected} ${ACTIVATE} - ExecShell "" "$WINDIR\system32\oobe\msoobe.exe" "/a" - ${EndIf} - - ; Launch Windows 8.1 upgrade site if requested by the user - ${If} ${SectionIsSelected} ${WIN81UPGRADE} - ExecShell "" "${WIN81UPGRADE_URL}" + ${DisableX64FSRedirection} + ${If} ${AtLeastWinVista} + Exec '"$WINDIR\system32\slui.exe"' + ${Else} + Exec '"$WINDIR\system32\oobe\msoobe.exe" /a' + ${EndIf} + ${EnableX64FSRedirection} ${EndIf} ${EndIf} FunctionEnd Function CleanUp + ; Called only after all tasks have completed Call CleanUpRunOnce !insertmacro InhibitSleep 0 + ${If} ${IsRunOnce} + Call OnRunOnceDone + ${EndIf} + ${If} ${IsPostInstall} ${OrIfNot} ${RebootFlag} - RMDir /r /REBOOTOK "$RunOnceDir" + Call CleanUpRunOnceFinal ${EndIf} FunctionEnd @@ -926,28 +1025,55 @@ Function .onInstSuccess FunctionEnd Function .onInstFailed + ${MementoSectionSave} Call CleanUp FunctionEnd Function .onSelChange ${If} ${SectionIsSelected} ${WES09} - ; Check for SSE2. - System::Call 'kernel32::IsProcessorFeaturePresent(i ${PF_XMMI64_INSTRUCTIONS_AVAILABLE}) i .r0' + ; Check for SSE2 + System::Call '${IsProcessorFeaturePresent}(${PF_XMMI64_INSTRUCTIONS_AVAILABLE}) .r0' ${If} $0 == 0 - MessageBox MB_USERICON "Your processor does not support the Streaming SIMD Extensions 2 (SSE2) instruction set, which is required to install Windows Embedded 2009 updates released after May 2018. Processors that initially implemented SSE2 instructions include the Intel Pentium 4, Pentium M, and AMD Athlon 64.$\r$\n$\r$\nTo protect your Windows installation from becoming corrupted by incompatible updates, this option will be disabled." /SD IDOK + MessageBox MB_USERICON "$(MsgBoxWES09NotSSE2)" /SD IDOK !insertmacro UnselectSection ${WES09} ${EndIf} + ${ElseIf} ${SectionIsSelected} ${ACTIVATE} + ; Make sure the service pack prerequisite is selected + ${If} ${IsWinXP2002} + ${AndIfNot} ${AtLeastServicePack} 3 + ${AndIfNot} ${SectionIsSelected} ${XPSP3} + MessageBox MB_USERICON "$(MsgBoxActivateXP2002NotSP3)" /SD IDOK + !insertmacro SelectSection ${XPSP3} + ${ElseIf} ${IsWinXP2003} + ${AndIfNot} ${AtLeastServicePack} 2 + ${AndIfNot} ${SectionIsSelected} ${2003SP2} + MessageBox MB_USERICON "$(MsgBoxActivateXP2003NotSP2)" /SD IDOK + !insertmacro SelectSection ${2003SP2} + ${EndIf} + ${ElseIf} ${SectionIsSelected} ${LEGACYUPDATE} + ; Handle 2000 Datacenter Server + ${If} ${IsWin2000} + ${AndIf} ${IsDatacenter} + MessageBox MB_USERICON "$(MsgBoxWUA2000Datacenter)" /SD IDOK + !insertmacro UnselectSection ${LEGACYUPDATE} + ${EndIf} ${EndIf} FunctionEnd Function un.onInit - !insertmacro Init + SetShellVarContext all + ${If} ${IsVerbose} + SetDetailsPrint both + ${Else} + SetDetailsPrint listonly + ${EndIf} + + ; Hack to avoid bundling System.dll in uninstaller + ${If} "$PROGRAMFILES64" != "$PROGRAMFILES32" + SetRegView 64 + ${EndIf} FunctionEnd Function un.onUninstSuccess - !insertmacro DetailPrint "Done" - Call un.RebootIfRequired - ${IfNot} ${RebootFlag} - Quit - ${EndIf} + Quit FunctionEnd diff --git a/setup/setupbanner.bmp b/setup/setupbanner.bmp deleted file mode 100644 index fff839c..0000000 Binary files a/setup/setupbanner.bmp and /dev/null differ diff --git a/setup/updroots.exe b/setup/updroots.exe deleted file mode 100644 index bf3b0a0..0000000 Binary files a/setup/updroots.exe and /dev/null differ diff --git a/setup/x86-unicode/LegacyUpdateNSIS.dll b/setup/x86-unicode/LegacyUpdateNSIS.dll index 845d0e3..a32e446 100644 Binary files a/setup/x86-unicode/LegacyUpdateNSIS.dll and b/setup/x86-unicode/LegacyUpdateNSIS.dll differ diff --git a/setup/x86-unicode/System.dll b/setup/x86-unicode/System.dll index 7e7adf8..a8baf30 100644 Binary files a/setup/x86-unicode/System.dll and b/setup/x86-unicode/System.dll differ diff --git a/shared/HResult.c b/shared/HResult.c index 6a1bd0f..3993d73 100644 --- a/shared/HResult.c +++ b/shared/HResult.c @@ -1,19 +1,55 @@ +#include "stdafx.h" #include -#include "WUErrors.h" +#include "HResult.h" +#include "LegacyUpdate.h" +#include "VersionInfo.h" + +static BOOL g_loadedHModule; +static HMODULE g_messagesHModule; EXTERN_C LPWSTR GetMessageForHresult(HRESULT hr) { - LPWSTR message; - for (int i = 0; WUErrorMessages[i].hr != 0; i++) { - if (WUErrorMessages[i].hr == hr) { - message = (LPWSTR)LocalAlloc(LPTR, 4096 * sizeof(WCHAR)); - lstrcpy(message, WUErrorMessages[i].message); - return message; + LPWSTR message = NULL; + + if (HRESULT_FACILITY(hr) == FACILITY_WINDOWSUPDATE) { + if (!g_loadedHModule) { + g_loadedHModule = TRUE; + + // Load messages table from main dll + LPWSTR installPath; + if (GetInstallPath(&installPath)) { + WCHAR path[MAX_PATH]; + wsprintf(path, L"%ls\\LegacyUpdate.dll", installPath); + g_messagesHModule = LoadLibrary(path); + LocalFree(installPath); + } + + if (!g_messagesHModule) { + // Try the current module + g_messagesHModule = (HMODULE)&__ImageBase; + } } + + FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, g_messagesHModule, hr, LANG_NEUTRAL, (LPWSTR)&message, 0, NULL); } - if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&message, 0, NULL) == 0) { - message = (LPWSTR)LocalAlloc(LPTR, 1024 * sizeof(WCHAR)); - wsprintf(message, L"Error 0x%08x", hr); + if (message == NULL && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, LANG_NEUTRAL, (LPWSTR)&message, 0, NULL)) { + message = (LPWSTR)LocalAlloc(LPTR, 17 * sizeof(WCHAR)); + wsprintf(message, L"Error 0x%08X", hr); + return message; + } + + // Truncate trailing \r\n if any + int len = lstrlen(message); + if (len >= 2 && message[len - 2] == '\r' && message[len - 1] == '\n') { + message[len - 2] = 0; + } + + // Remove title part in braces + if (len > 1 && message[0] == '{') { + LPWSTR closeBrace = wcsstr(message, L"}\r\n"); + if (closeBrace) { + message = closeBrace + 3; + } } return message; diff --git a/shared/VersionInfo.cpp b/shared/VersionInfo.cpp deleted file mode 100644 index 73fa4ab..0000000 --- a/shared/VersionInfo.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "stdafx.h" -#include "VersionInfo.h" - -static BOOL _loadedVersionInfo = FALSE; -static OSVERSIONINFOEX _versionInfo; - -OSVERSIONINFOEX *GetVersionInfo() { - if (!_loadedVersionInfo) { - _loadedVersionInfo = true; - ZeroMemory(&_versionInfo, sizeof(OSVERSIONINFOEX)); - _versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((LPOSVERSIONINFO)&_versionInfo); - } - return &_versionInfo; -} - -BOOL IsOSVersionOrLater(DWORD major, DWORD minor) { - OSVERSIONINFOEX *versionInfo = GetVersionInfo(); - return versionInfo->dwMajorVersion > major || (versionInfo->dwMajorVersion == major && versionInfo->dwMinorVersion >= minor); -} - -BOOL IsOSVersionOrEarlier(DWORD major, DWORD minor) { - OSVERSIONINFOEX *versionInfo = GetVersionInfo(); - return versionInfo->dwMajorVersion < major || (versionInfo->dwMajorVersion == major && versionInfo->dwMinorVersion <= minor); -} diff --git a/shared/VersionInfo.h b/shared/VersionInfo.h index a7bdd72..a06ef44 100644 --- a/shared/VersionInfo.h +++ b/shared/VersionInfo.h @@ -1,6 +1,118 @@ #pragma once -#include -OSVERSIONINFOEX *GetVersionInfo(); -BOOL IsOSVersionOrLater(DWORD major, DWORD minor); -BOOL IsOSVersionOrEarlier(DWORD major, DWORD minor); +#include +#include "stdafx.h" + +// Windows 11 Copper (22H2). "WIN10" typo is from the original sdkddkvers.h +#ifndef NTDDI_WIN10_CU +#define NTDDI_WIN10_CU 0x0A00000D +#endif + +#define BUILD_WIN10_1507 10240 +#define BUILD_WIN10_1511 10586 +#define BUILD_WIN10_1607 14393 +#define BUILD_WIN10_1703 15063 +#define BUILD_WIN10_1709 16299 +#define BUILD_WIN10_1803 17134 +#define BUILD_WIN10_1809 17763 +#define BUILD_WIN10_1903 18362 +#define BUILD_WIN10_1909 18363 +#define BUILD_WIN10_2004 19041 +#define BUILD_WIN10_20H2 19042 +#define BUILD_WIN10_21H1 19043 +#define BUILD_WIN10_21H2 19044 +#define BUILD_WIN10_22H2 19045 +#define BUILD_WIN11_21H1 22000 +#define BUILD_WIN11_22H2 22621 +#define BUILD_WIN11_23H2 22631 +#define BUILD_WIN11_24H2 26100 + +// Undocumented IsOS() flags +#define OS_STARTER 38 // Starter Edition +#define OS_STORAGESERVER 40 // Windows Storage Server 2003 +#define OS_COMPUTECLUSTER 41 // Windows Compute Cluster 2003 +#define OS_SERVERR2 42 // Windows Server 2003 R2 (in combination with edition) +#define OS_EMBPOS 43 // Windows Embedded for Point of Service +#define OS_HOMESERVER 43 // Windows Home Server (2007) +#define OS_WINFLP 44 // Windows Fundamentals for Legacy PCs +#define OS_EMBSTD2009 45 // Windows Embedded Standard 2009 +#define OS_EMBPOS2009 46 // Windows Embedded POSReady 2009 + +EXTERN_C IMAGE_DOS_HEADER __ImageBase; + +static BOOL _loadedVersionInfo = FALSE; +static OSVERSIONINFOEX _versionInfo; + +static OSVERSIONINFOEX *GetVersionInfo() { + if (!_loadedVersionInfo) { + _loadedVersionInfo = TRUE; + ZeroMemory(&_versionInfo, sizeof(OSVERSIONINFOEX)); + _versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + GetVersionEx((LPOSVERSIONINFO)&_versionInfo); + } + return &_versionInfo; +} + +static ALWAYS_INLINE WORD GetWinVer() { + return __builtin_bswap16(LOWORD(GetVersion())); +} + +#define _IS_OS_MACRO(name, ver) \ + static ALWAYS_INLINE BOOL IsWin ## name() { \ + return GetWinVer() == ver; \ + } \ + static ALWAYS_INLINE BOOL AtLeastWin ## name() { \ + return GetWinVer() >= ver; \ + } \ + static ALWAYS_INLINE BOOL AtMostWin ## name() { \ + return GetWinVer() <= ver; \ + } + +_IS_OS_MACRO(NT4, 0x0400) +_IS_OS_MACRO(2000, 0x0500) +_IS_OS_MACRO(XP2002, 0x0501) +_IS_OS_MACRO(XP2003, 0x0502) +_IS_OS_MACRO(Vista, 0x0600) +_IS_OS_MACRO(7, 0x0601) +_IS_OS_MACRO(8, 0x0602) +_IS_OS_MACRO(8_1, 0x0603) +_IS_OS_MACRO(10, 0x0A00) +#undef _IS_OS_MACRO + +#define _IS_BUILD_MACRO(ver) \ + static ALWAYS_INLINE BOOL IsWin ## ver() { \ + return GetVersionInfo()->dwBuildNumber == BUILD_WIN ## ver; \ + } \ + static ALWAYS_INLINE BOOL AtLeastWin ## ver() { \ + return GetVersionInfo()->dwBuildNumber >= BUILD_WIN ## ver; \ + } \ + static ALWAYS_INLINE BOOL AtMostWin ## ver() { \ + return GetVersionInfo()->dwBuildNumber <= BUILD_WIN ## ver; \ + } + +_IS_BUILD_MACRO(10_1507) +_IS_BUILD_MACRO(10_1511) +_IS_BUILD_MACRO(10_1607) +_IS_BUILD_MACRO(10_1703) +_IS_BUILD_MACRO(10_1709) +_IS_BUILD_MACRO(10_1803) +_IS_BUILD_MACRO(10_1809) +_IS_BUILD_MACRO(10_1903) +_IS_BUILD_MACRO(10_1909) +_IS_BUILD_MACRO(10_2004) +_IS_BUILD_MACRO(10_20H2) +_IS_BUILD_MACRO(10_21H1) +_IS_BUILD_MACRO(10_21H2) +_IS_BUILD_MACRO(10_22H2) +_IS_BUILD_MACRO(11_21H1) +_IS_BUILD_MACRO(11_22H2) +_IS_BUILD_MACRO(11_23H2) +_IS_BUILD_MACRO(11_24H2) +#undef _IS_BUILD_MACRO + +EXTERN_C HRESULT GetOwnVersion(LPWSTR *version); + +static ALWAYS_INLINE void GetOwnFileName(LPWSTR *filename) { + *filename = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR)); + GetModuleFileName((HMODULE)&__ImageBase, *filename, MAX_PATH); +} diff --git a/shared/WMI.cpp b/shared/WMI.cpp deleted file mode 100644 index 6ef9b5d..0000000 --- a/shared/WMI.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "stdafx.h" -#include "WMI.h" -#include -#include - -#pragma comment(lib, "wbemuuid.lib") - -HRESULT QueryWMIProperty(BSTR query, BSTR property, VARIANT *value) { - CComPtr locator; - HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void **)&locator); - if (!SUCCEEDED(hr)) { - return hr; - } - - CComPtr services; - hr = locator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, NULL, 0, NULL, NULL, &services); - if (!SUCCEEDED(hr)) { - return hr; - } - - hr = CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); - if (!SUCCEEDED(hr)) { - return hr; - } - - CComPtr enumerator; - hr = services->ExecQuery(L"WQL", query, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator); - if (!SUCCEEDED(hr)) { - return hr; - } - - CComPtr object; - ULONG uReturn = 0; - hr = enumerator->Next(WBEM_INFINITE, 1, &object, &uReturn); - if (!SUCCEEDED(hr)) { - return hr; - } - - hr = object->Get(property, 0, value, NULL, NULL); - if (!SUCCEEDED(hr)) { - return hr; - } - - return S_OK; -} diff --git a/shared/WMI.h b/shared/WMI.h index b2507d3..f35df50 100644 --- a/shared/WMI.h +++ b/shared/WMI.h @@ -1,6 +1,6 @@ #pragma once -#include -#include -#include -HRESULT QueryWMIProperty(BSTR query, BSTR property, VARIANT *value); +#include +#include + +EXTERN_C HRESULT QueryWMIProperty(LPWSTR query, LPWSTR property, LPVARIANT value); diff --git a/shared/WUErrors.c b/shared/WUErrors.c deleted file mode 100644 index 8307365..0000000 --- a/shared/WUErrors.c +++ /dev/null @@ -1,266 +0,0 @@ -#include "stdafx.h" -#include "WUErrors.h" -#include - -// TODO: There needs to be a better way to do this other than hardcoding all these English strings... -HResultMessage WUErrorMessages[] = { - { WU_S_SERVICE_STOP, L"Windows Update Agent was stopped successfully." }, - { WU_S_SELFUPDATE, L"Windows Update Agent updated itself." }, - { WU_S_UPDATE_ERROR, L"Operation completed successfully but there were errors applying the updates.." }, - { WU_S_MARKED_FOR_DISCONNECT, L"A callback was marked to be disconnected later because the request to disconnect the operation came while a callback was executing." }, - { WU_S_REBOOT_REQUIRED, L"The system must be restarted to complete installation of the update." }, - { WU_S_ALREADY_INSTALLED, L"The update to be installed is already installed on the system." }, - { WU_S_ALREADY_UNINSTALLED, L"The update to be removed is not installed on the system." }, - { WU_S_ALREADY_DOWNLOADED, L"The update to be downloaded has already been downloaded." }, - { WU_E_NO_SERVICE, L"Windows Update Agent was unable to provide the service." }, - { WU_E_MAX_CAPACITY_REACHED, L"The maximum capacity of the service was exceeded." }, - { WU_E_UNKNOWN_ID, L"An ID cannot be found." }, - { WU_E_NOT_INITIALIZED, L"The object could not be initialized." }, - { WU_E_RANGEOVERLAP, L"The update handler requested a byte range overlapping a previously requested range." }, - { WU_E_TOOMANYRANGES, L"The requested number of byte ranges exceeds the maximum number (2^31 - 1)." }, - { WU_E_INVALIDINDEX, L"The index to a collection was invalid." }, - { WU_E_ITEMNOTFOUND, L"The key for the item queried could not be found." }, - { WU_E_OPERATIONINPROGRESS, L"Another conflicting operation was in progress. Some operations such as installation cannot be performed twice simultaneously." }, - { WU_E_COULDNOTCANCEL, L"Cancellation of the operation was not allowed." }, - { WU_E_CALL_CANCELLED, L"Operation was cancelled." }, - { WU_E_NOOP, L"No operation was required." }, - { WU_E_XML_MISSINGDATA, L"Windows Update Agent could not find required information in the update's XML data." }, - { WU_E_XML_INVALID, L"Windows Update Agent found invalid information in the update's XML data." }, - { WU_E_CYCLE_DETECTED, L"Circular update relationships were detected in the metadata." }, - { WU_E_TOO_DEEP_RELATION, L"Update relationships too deep to evaluate were evaluated." }, - { WU_E_INVALID_RELATIONSHIP, L"An invalid update relationship was detected." }, - { WU_E_REG_VALUE_INVALID, L"An invalid registry value was read." }, - { WU_E_DUPLICATE_ITEM, L"Operation tried to add a duplicate item to a list." }, - { WU_E_INSTALL_NOT_ALLOWED, L"Operation tried to install while another installation was in progress or the system was pending a mandatory restart." }, - { WU_E_NOT_APPLICABLE, L"Operation was not performed because there are no applicable updates." }, - { WU_E_NO_USERTOKEN, L"Operation failed because a required user token is missing." }, - { WU_E_EXCLUSIVE_INSTALL_CONFLICT, L"An exclusive update cannot be installed with other updates at the same time." }, - { WU_E_POLICY_NOT_SET, L"A policy value was not set." }, - { WU_E_SELFUPDATE_IN_PROGRESS, L"The operation could not be performed because the Windows Update Agent is self-updating." }, - { WU_E_INVALID_UPDATE, L"An update contains invalid metadata." }, - { WU_E_SERVICE_STOP, L"Operation did not complete because the service or system was being shut down." }, - { WU_E_NO_CONNECTION, L"Operation did not complete because the network connection was unavailable." }, - { WU_E_NO_INTERACTIVE_USER, L"Operation did not complete because there is no logged-on interactive user." }, - { WU_E_TIME_OUT, L"Operation did not complete because it timed out." }, - { WU_E_ALL_UPDATES_FAILED, L"Operation failed for all the updates." }, - { WU_E_EULAS_DECLINED, L"The license terms for all updates were declined." }, - { WU_E_NO_UPDATE, L"There are no updates." }, - { WU_E_USER_ACCESS_DISABLED, L"Group Policy settings prevented access to Windows Update." }, - { WU_E_INVALID_UPDATE_TYPE, L"The type of update is invalid." }, - { WU_E_URL_TOO_LONG, L"The URL exceeded the maximum length." }, - { WU_E_UNINSTALL_NOT_ALLOWED, L"The update could not be uninstalled because the request did not originate from a WSUS server." }, - { WU_E_INVALID_PRODUCT_LICENSE, L"Search may have missed some updates before there is an unlicensed application on the system." }, - { WU_E_MISSING_HANDLER, L"A component required to detect applicable updates was missing." }, - { WU_E_LEGACYSERVER, L"An operation did not complete because it requires a newer version of server." }, - { WU_E_BIN_SOURCE_ABSENT, L"A delta-compressed update could not be installed because it required the source." }, - { WU_E_SOURCE_ABSENT, L"A full-file update could not be installed because it required the source." }, - { WU_E_WU_DISABLED, L"Access to an unmanaged server is not allowed." }, - { WU_E_CALL_CANCELLED_BY_POLICY, L"Operation did not complete because the DisableWindowsUpdateAccess policy was set." }, - { WU_E_INVALID_PROXY_SERVER, L"The format of the proxy list was invalid." }, - { WU_E_INVALID_FILE, L"The file is in the wrong format." }, - { WU_E_INVALID_CRITERIA, L"The search criteria string was invalid." }, - { WU_E_EULA_UNAVAILABLE, L"License terms could not be downloaded." }, - { WU_E_DOWNLOAD_FAILED, L"Update failed to download." }, - { WU_E_UPDATE_NOT_PROCESSED, L"The update was not processed." }, - { WU_E_INVALID_OPERATION, L"The object's current state did not allow the operation." }, - { WU_E_NOT_SUPPORTED, L"The functionality for the operation is not supported." }, - { WU_E_WINHTTP_INVALID_FILE, L"The downloaded file has an unexpected content type." }, - { WU_E_TOO_MANY_RESYNC, L"Agent is asked by server to resync too many times." }, - { WU_E_NO_SERVER_CORE_SUPPORT, L"WUA API method does not run on Server Core installation." }, - { WU_E_SYSPREP_IN_PROGRESS, L"Service is not available while sysprep is running." }, - { WU_E_UNKNOWN_SERVICE, L"The update service is no longer registered with AU." }, - { WU_E_UNEXPECTED, L"An operation failed due to reasons not covered by another error code." }, - { WU_E_MSI_WRONG_VERSION, L"Search may have missed some updates because the Windows Installer is less than version 3.1." }, - { WU_E_MSI_NOT_CONFIGURED, L"Search may have missed some updates because the Windows Installer is not configured." }, - { WU_E_MSP_DISABLED, L"Search may have missed some updates because policy has disabled Windows Installer patching." }, - { WU_E_MSI_WRONG_APP_CONTEXT, L"An update could not be applied because the application is installed per-user." }, - { WU_E_MSP_UNEXPECTED, L"Search may have missed some updates because there was a failure of the Windows Installer." }, - { WU_E_UH_REMOTEUNAVAILABLE, L"A request for a remote update handler could not be completed because no remote process is available." }, - { WU_E_UH_LOCALONLY, L"A request for a remote update handler could not be completed because the handler is local only." }, - { WU_E_UH_UNKNOWNHANDLER, L"A request for an update handler could not be completed because the handler could not be recognized." }, - { WU_E_UH_REMOTEALREADYACTIVE, L"A remote update handler could not be created because one already exists." }, - { WU_E_UH_DOESNOTSUPPORTACTION, L"A request for the handler to install (uninstall) an update could not be completed because the update does not support install (uninstall)." }, - { WU_E_UH_WRONGHANDLER, L"An operation did not complete because the wrong handler was specified." }, - { WU_E_UH_INVALIDMETADATA, L"A handler operation could not be completed because the update contains invalid metadata." }, - { WU_E_UH_INSTALLERHUNG, L"An operation could not be completed because the installer exceeded the time limit." }, - { WU_E_UH_OPERATIONCANCELLED, L"An operation being done by the update handler was cancelled." }, - { WU_E_UH_BADHANDLERXML, L"An operation could not be completed because the handler-specific metadata is invalid." }, - { WU_E_UH_CANREQUIREINPUT, L"A request to the handler to install an update could not be completed because the update requires user input." }, - { WU_E_UH_INSTALLERFAILURE, L"The installer failed to install (uninstall) one or more updates." }, - { WU_E_UH_FALLBACKTOSELFCONTAINED, L"The update handler should download self-contained content rather than delta-compressed content for the update." }, - { WU_E_UH_NEEDANOTHERDOWNLOAD, L"The update handler did not install the update because it needs to be downloaded again." }, - { WU_E_UH_NOTIFYFAILURE, L"The update handler failed to send notification of the status of the install (uninstall) operation." }, - { WU_E_UH_INCONSISTENT_FILE_NAMES, L"The file names contained in the update metadata and in the update package are inconsistent." }, - { WU_E_UH_FALLBACKERROR, L"The update handler failed to fall back to the self-contained content." }, - { WU_E_UH_TOOMANYDOWNLOADREQUESTS, L"The update handler has exceeded the maximum number of download requests." }, - { WU_E_UH_UNEXPECTEDCBSRESPONSE, L"The update handler has received an unexpected response from CBS." }, - { WU_E_UH_BADCBSPACKAGEID, L"The update metadata contains an invalid CBS package identifier." }, - { WU_E_UH_POSTREBOOTSTILLPENDING, L"The post-reboot operation for the update is still in progress." }, - { WU_E_UH_POSTREBOOTRESULTUNKNOWN, L"The result of the post-reboot operation for the update could not be determined." }, - { WU_E_UH_POSTREBOOTUNEXPECTEDSTATE, L"The state of the update after its post-reboot operation has completed is unexpected." }, - { WU_E_UH_NEW_SERVICING_STACK_REQUIRED, L"The operating system servicing stack must be updated before this update is downloaded or installed." }, - { WU_E_UH_UNEXPECTED, L"An update handler error not covered by another WU_E_UH_* code." }, - { WU_E_INSTALLATION_RESULTS_UNKNOWN_VERSION, L"The results of download and installation could not be read from the registry due to an unrecognized data format version." }, - { WU_E_INSTALLATION_RESULTS_INVALID_DATA, L"The results of download and installation could not be read from the registry due to an invalid data format." }, - { WU_E_INSTALLATION_RESULTS_NOT_FOUND, L"The results of download and installation are not available; the operation may have failed to start." }, - { WU_E_TRAYICON_FAILURE, L"A failure occurred when trying to create an icon in the taskbar notification area." }, - { WU_E_NON_UI_MODE, L"Unable to show UI when in non-UI mode; WU client UI modules may not be installed." }, - { WU_E_WUCLTUI_UNSUPPORTED_VERSION, L"Unsupported version of WU client UI exported functions." }, - { WU_E_AUCLIENT_UNEXPECTED, L"There was a user interface error not covered by another WU_E_AUCLIENT_* error code." }, - { WU_E_PT_SOAPCLIENT_BASE, L"WU_E_PT_SOAPCLIENT_* error codes map to the SOAPCLIENT_ERROR enum of the ATL Server Library." }, - { WU_E_PT_SOAPCLIENT_INITIALIZE, L"SOAPCLIENT_INITIALIZE_ERROR - initialization of the SOAP client failed, possibly because of an MSXML installation failure." }, - { WU_E_PT_SOAPCLIENT_OUTOFMEMORY, L"SOAPCLIENT_OUTOFMEMORY - SOAP client failed because it ran out of memory." }, - { WU_E_PT_SOAPCLIENT_GENERATE, L"SOAPCLIENT_GENERATE_ERROR - SOAP client failed to generate the request." }, - { WU_E_PT_SOAPCLIENT_CONNECT, L"SOAPCLIENT_CONNECT_ERROR - SOAP client failed to connect to the server." }, - { WU_E_PT_SOAPCLIENT_SEND, L"SOAPCLIENT_SEND_ERROR - SOAP client failed to send a message for reasons of WU_E_WINHTTP_* error codes." }, - { WU_E_PT_SOAPCLIENT_SERVER, L"SOAPCLIENT_SERVER_ERROR - SOAP client failed because there was a server error." }, - { WU_E_PT_SOAPCLIENT_SOAPFAULT, L"SOAPCLIENT_SOAPFAULT - SOAP client failed because there was a SOAP fault for reasons of WU_E_PT_SOAP_* error codes." }, - { WU_E_PT_SOAPCLIENT_PARSEFAULT, L"SOAPCLIENT_PARSEFAULT_ERROR - SOAP client failed to parse a SOAP fault." }, - { WU_E_PT_SOAPCLIENT_READ, L"SOAPCLIENT_READ_ERROR - SOAP client failed while reading the response from the server." }, - { WU_E_PT_SOAPCLIENT_PARSE, L"SOAPCLIENT_PARSE_ERROR - SOAP client failed to parse the response from the server." }, - { WU_E_PT_SOAP_VERSION, L"SOAP_E_VERSION_MISMATCH - SOAP client found an unrecognizable namespace for the SOAP envelope." }, - { WU_E_PT_SOAP_MUST_UNDERSTAND, L"SOAP_E_MUST_UNDERSTAND - SOAP client was unable to understand a header." }, - { WU_E_PT_SOAP_CLIENT, L"SOAP_E_CLIENT - SOAP client found the message was malformed; fix before resending." }, - { WU_E_PT_SOAP_SERVER, L"SOAP_E_SERVER - The SOAP message could not be processed due to a server error; resend later." }, - { WU_E_PT_WMI_ERROR, L"There was an unspecified Windows Management Instrumentation (WMI) error." }, - { WU_E_PT_EXCEEDED_MAX_SERVER_TRIPS, L"The number of round trips to the server exceeded the maximum limit." }, - { WU_E_PT_SUS_SERVER_NOT_SET, L"WUServer policy value is missing in the registry." }, - { WU_E_PT_DOUBLE_INITIALIZATION, L"Initialization failed because the object was already initialized." }, - { WU_E_PT_INVALID_COMPUTER_NAME, L"The computer name could not be determined." }, - { WU_E_PT_REFRESH_CACHE_REQUIRED, L"The reply from the server indicates that the server was changed or the cookie was invalid; refresh the state of the internal cache and retry." }, - { WU_E_PT_HTTP_STATUS_BAD_REQUEST, L"HTTP 400 - the server could not process the request due to invalid syntax." }, - { WU_E_PT_HTTP_STATUS_DENIED, L"HTTP 401 - the requested resource requires user authentication." }, - { WU_E_PT_HTTP_STATUS_FORBIDDEN, L"HTTP 403 - server understood the request, but declined to fulfill it." }, - { WU_E_PT_HTTP_STATUS_NOT_FOUND, L"HTTP 404 - the server cannot find the requested URI (Uniform Resource Identifier)." }, - { WU_E_PT_HTTP_STATUS_BAD_METHOD, L"HTTP 405 - the HTTP method is not allowed." }, - { WU_E_PT_HTTP_STATUS_PROXY_AUTH_REQ, L"HTTP 407 - proxy authentication is required." }, - { WU_E_PT_HTTP_STATUS_REQUEST_TIMEOUT, L"HTTP 408 - the server timed out waiting for the request." }, - { WU_E_PT_HTTP_STATUS_CONFLICT, L"HTTP 409 - the request was not completed due to a conflict with the current state of the resource." }, - { WU_E_PT_HTTP_STATUS_GONE, L"HTTP 410 - requested resource is no longer available at the server." }, - { WU_E_PT_HTTP_STATUS_SERVER_ERROR, L"HTTP 500 - an error internal to the server prevented fulfilling the request." }, - { WU_E_PT_HTTP_STATUS_NOT_SUPPORTED, L"HTTP 501 - server does not support the functionality required to fulfill the request." }, - { WU_E_PT_HTTP_STATUS_BAD_GATEWAY, L"HTTP 502 - the server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request." }, - { WU_E_PT_HTTP_STATUS_SERVICE_UNAVAIL, L"HTTP 503 - the service is temporarily overloaded." }, - { WU_E_PT_HTTP_STATUS_GATEWAY_TIMEOUT, L"HTTP 504 - the request was timed out waiting for a gateway." }, - { WU_E_PT_HTTP_STATUS_VERSION_NOT_SUP, L"HTTP 505 - the server does not support the HTTP protocol version used for the request." }, - { WU_E_PT_FILE_LOCATIONS_CHANGED, L"Operation failed due to a changed file location; refresh internal state and resend." }, - { WU_E_PT_REGISTRATION_NOT_SUPPORTED, L"Operation failed because Windows Update Agent does not support registration with a non-WSUS server." }, - { WU_E_PT_NO_AUTH_PLUGINS_REQUESTED, L"The server returned an empty authentication information list." }, - { WU_E_PT_NO_AUTH_COOKIES_CREATED, L"Windows Update Agent was unable to create any valid authentication cookies." }, - { WU_E_PT_INVALID_CONFIG_PROP, L"A configuration property value was wrong." }, - { WU_E_PT_CONFIG_PROP_MISSING, L"A configuration property value was missing." }, - { WU_E_PT_HTTP_STATUS_NOT_MAPPED, L"The HTTP request could not be completed and the reason did not correspond to any of the WU_E_PT_HTTP_* error codes." }, - { WU_E_PT_WINHTTP_NAME_NOT_RESOLVED, L"ERROR_WINHTTP_NAME_NOT_RESOLVED - the proxy server or target server name cannot be resolved." }, - { WU_E_PT_ECP_SUCCEEDED_WITH_ERRORS, L"External cab file processing completed with some errors. (Confirm that download.windowsupdate.com and www.download.windowsupdate.com aren't being blocked by a firewall.)" }, - { WU_E_PT_ECP_INIT_FAILED, L"The external cab processor initialization did not complete." }, - { WU_E_PT_ECP_INVALID_FILE_FORMAT, L"The format of a metadata file was invalid." }, - { WU_E_PT_ECP_INVALID_METADATA, L"External cab processor found invalid metadata." }, - { WU_E_PT_ECP_FAILURE_TO_EXTRACT_DIGEST, L"The file digest could not be extracted from an external cab file." }, - { WU_E_PT_ECP_FAILURE_TO_DECOMPRESS_CAB_FILE, L"An external cab file could not be decompressed." }, - { WU_E_PT_ECP_FILE_LOCATION_ERROR, L"External cab processor was unable to get file locations." }, - { WU_E_PT_UNEXPECTED, L"A communication error not covered by another WU_E_PT_* error code" }, - { WU_E_REDIRECTOR_LOAD_XML, L"The redirector XML document could not be loaded into the DOM class." }, - { WU_E_REDIRECTOR_S_FALSE, L"The redirector XML document is missing some required information." }, - { WU_E_REDIRECTOR_ID_SMALLER, L"The redirector ID in the downloaded redirector cab is less than in the cached cab." }, - { WU_E_PT_SAME_REDIR_ID, L"Windows Update Agent failed to download a redirector cabinet file with a new redirector ID value from the server during the recovery." }, - { WU_E_PT_NO_MANAGED_RECOVER, L"A redirector recovery action did not complete because the server is managed." }, - { WU_E_REDIRECTOR_UNEXPECTED, L"The redirector failed for reasons not covered by another WU_E_REDIRECTOR_* error code." }, - { WU_E_DM_URLNOTAVAILABLE, L"A download manager operation could not be completed because the requested file does not have a URL." }, - { WU_E_DM_INCORRECTFILEHASH, L"A download manager operation could not be completed because the file digest was not recognized." }, - { WU_E_DM_UNKNOWNALGORITHM, L"A download manager operation could not be completed because the file metadata requested an unrecognized hash algorithm." }, - { WU_E_DM_NEEDDOWNLOADREQUEST, L"An operation could not be completed because a download request is required from the download handler." }, - { WU_E_DM_NONETWORK, L"A download manager operation could not be completed because the network connection was unavailable." }, - { WU_E_DM_WRONGBITSVERSION, L"A download manager operation could not be completed because the version of Background Intelligent Transfer Service (BITS) is incompatible." }, - { WU_E_DM_NOTDOWNLOADED, L"The update has not been downloaded." }, - { WU_E_DM_FAILTOCONNECTTOBITS, L"A download manager operation failed because the download manager was unable to connect the Background Intelligent Transfer Service (BITS)." }, - { WU_E_DM_BITSTRANSFERERROR, L"A download manager operation failed because there was an unspecified Background Intelligent Transfer Service (BITS) transfer error." }, - { WU_E_DM_DOWNLOADLOCATIONCHANGED, L"A download must be restarted because the location of the source of the download has changed." }, - { WU_E_DM_CONTENTCHANGED, L"A download must be restarted because the update content changed in a new revision." }, - { WU_E_DM_UNEXPECTED, L"There was a download manager error not covered by another WU_E_DM_* error code." }, - { WU_E_OL_INVALID_SCANFILE, L"An operation could not be completed because the scan package was invalid." }, - { WU_E_OL_NEWCLIENT_REQUIRED, L"An operation could not be completed because the scan package requires a greater version of the Windows Update Agent." }, - { WU_E_OL_UNEXPECTED, L"Search using the scan package failed." }, - { WU_E_REPORTER_EVENTCACHECORRUPT, L"The event cache file was defective." }, - { WU_E_REPORTER_EVENTNAMESPACEPARSEFAILED, L"The XML in the event namespace descriptor could not be parsed." }, - { WU_E_INVALID_EVENT, L"The XML in the event namespace descriptor could not be parsed." }, - { WU_E_SERVER_BUSY, L"The server rejected an event because the server was too busy." }, - { WU_E_REPORTER_UNEXPECTED, L"There was a reporter error not covered by another error code." }, - { WU_E_DS_SHUTDOWN, L"An operation failed because Windows Update Agent is shutting down." }, - { WU_E_DS_INUSE, L"An operation failed because the data store was in use." }, - { WU_E_DS_INVALID, L"The current and expected states of the data store do not match." }, - { WU_E_DS_TABLEMISSING, L"The data store is missing a table." }, - { WU_E_DS_TABLEINCORRECT, L"The data store contains a table with unexpected columns." }, - { WU_E_DS_INVALIDTABLENAME, L"A table could not be opened because the table is not in the data store." }, - { WU_E_DS_BADVERSION, L"The current and expected versions of the data store do not match." }, - { WU_E_DS_NODATA, L"The information requested is not in the data store." }, - { WU_E_DS_MISSINGDATA, L"The data store is missing required information or has a NULL in a table column that requires a non-null value." }, - { WU_E_DS_MISSINGREF, L"The data store is missing required information or has a reference to missing license terms, file, localized property or linked row." }, - { WU_E_DS_UNKNOWNHANDLER, L"The update was not processed because its update handler could not be recognized." }, - { WU_E_DS_CANTDELETE, L"The update was not deleted because it is still referenced by one or more services." }, - { WU_E_DS_LOCKTIMEOUTEXPIRED, L"The data store section could not be locked within the allotted time." }, - { WU_E_DS_NOCATEGORIES, L"The category was not added because it contains no parent categories and is not a top-level category itself." }, - { WU_E_DS_ROWEXISTS, L"The row was not added because an existing row has the same primary key." }, - { WU_E_DS_STOREFILELOCKED, L"The data store could not be initialized because it was locked by another process." }, - { WU_E_DS_CANNOTREGISTER, L"The data store is not allowed to be registered with COM in the current process." }, - { WU_E_DS_UNABLETOSTART, L"Could not create a data store object in another process." }, - { WU_E_DS_DUPLICATEUPDATEID, L"The server sent the same update to the client with two different revision IDs." }, - { WU_E_DS_UNKNOWNSERVICE, L"An operation did not complete because the service is not in the data store." }, - { WU_E_DS_SERVICEEXPIRED, L"An operation did not complete because the registration of the service has expired." }, - { WU_E_DS_DECLINENOTALLOWED, L"A request to hide an update was declined because it is a mandatory update or because it was deployed with a deadline." }, - { WU_E_DS_TABLESESSIONMISMATCH, L"A table was not closed because it is not associated with the session." }, - { WU_E_DS_SESSIONLOCKMISMATCH, L"A table was not closed because it is not associated with the session." }, - { WU_E_DS_NEEDWINDOWSSERVICE, L"A request to remove the Windows Update service or to unregister it with Automatic Updates was declined because it is a built-in service and/or Automatic Updates cannot fall back to another service." }, - { WU_E_DS_INVALIDOPERATION, L"A request was declined because the operation is not allowed." }, - { WU_E_DS_SCHEMAMISMATCH, L"The schema of the current data store and the schema of a table in a backup XML document do not match." }, - { WU_E_DS_RESETREQUIRED, L"The data store requires a session reset; release the session and retry with a new session." }, - { WU_E_DS_IMPERSONATED, L"A data store operation did not complete because it was requested with an impersonated identity." }, - { WU_E_DS_UNEXPECTED, L"A data store error not covered by another WU_E_DS_* code." }, - { WU_E_INVENTORY_PARSEFAILED, L"Parsing of the rule file failed." }, - { WU_E_INVENTORY_GET_INVENTORY_TYPE_FAILED, L"Failed to get the requested inventory type from the server." }, - { WU_E_INVENTORY_RESULT_UPLOAD_FAILED, L"Failed to upload inventory result to the server." }, - { WU_E_INVENTORY_UNEXPECTED, L"There was an inventory error not covered by another error code." }, - { WU_E_INVENTORY_WMI_ERROR, L"A WMI error occurred when enumerating the instances for a particular class." }, - { WU_E_AU_NOSERVICE, L"Automatic Updates was unable to service incoming requests." }, - { WU_E_AU_NONLEGACYSERVER, L"The old version of the Automatic Updates client has stopped because the WSUS server has been upgraded." }, - { WU_E_AU_LEGACYCLIENTDISABLED, L"The old version of the Automatic Updates client was disabled." }, - { WU_E_AU_PAUSED, L"Automatic Updates was unable to process incoming requests because it was paused." }, - { WU_E_AU_NO_REGISTERED_SERVICE, L"No unmanaged service is registered with AU." }, - { WU_E_AU_UNEXPECTED, L"An Automatic Updates error not covered by another WU_E_AU * code." }, - { WU_E_DRV_PRUNED, L"A driver was skipped." }, - { WU_E_DRV_NOPROP_OR_LEGACY, L"A property for the driver could not be found. It may not conform with required specifications." }, - { WU_E_DRV_REG_MISMATCH, L"The registry type read for the driver does not match the expected type." }, - { WU_E_DRV_NO_METADATA, L"The driver update is missing metadata." }, - { WU_E_DRV_MISSING_ATTRIBUTE, L"The driver update is missing a required attribute." }, - { WU_E_DRV_SYNC_FAILED, L"Driver synchronization failed." }, - { WU_E_DRV_NO_PRINTER_CONTENT, L"Information required for the synchronization of applicable printers is missing." }, - { WU_E_DRV_UNEXPECTED, L"A driver error not covered by another WU_E_DRV_* code." }, - { WU_E_SETUP_INVALID_INFDATA, L"Windows Update Agent could not be updated because an INF file contains invalid information." }, - { WU_E_SETUP_INVALID_IDENTDATA, L"Windows Update Agent could not be updated because the wuident.cab file contains invalid information." }, - { WU_E_SETUP_ALREADY_INITIALIZED, L"Windows Update Agent could not be updated because of an internal error that caused setup initialization to be performed twice." }, - { WU_E_SETUP_NOT_INITIALIZED, L"Windows Update Agent could not be updated because setup initialization never completed successfully." }, - { WU_E_SETUP_SOURCE_VERSION_MISMATCH, L"Windows Update Agent could not be updated because the versions specified in the INF do not match the actual source file versions." }, - { WU_E_SETUP_TARGET_VERSION_GREATER, L"Windows Update Agent could not be updated because a WUA file on the target system is newer than the corresponding source file." }, - { WU_E_SETUP_REGISTRATION_FAILED, L"Windows Update Agent could not be updated because regsvr32.exe returned an error." }, - { WU_E_SELFUPDATE_SKIP_ON_FAILURE, L"An update to the Windows Update Agent was skipped because previous attempts to update have failed." }, - { WU_E_SETUP_SKIP_UPDATE, L"An update to the Windows Update Agent was skipped due to a directive in the wuident.cab file." }, - { WU_E_SETUP_UNSUPPORTED_CONFIGURATION, L"Windows Update Agent could not be updated because the current system configuration is not supported." }, - { WU_E_SETUP_BLOCKED_CONFIGURATION, L"Windows Update Agent could not be updated because the system is configured to block the update." }, - { WU_E_SETUP_REBOOT_TO_FIX, L"Windows Update Agent could not be updated because a restart of the system is required." }, - { WU_E_SETUP_ALREADYRUNNING, L"Windows Update Agent setup is already running." }, - { WU_E_SETUP_REBOOTREQUIRED, L"Windows Update Agent setup package requires a reboot to complete installation." }, - { WU_E_SETUP_HANDLER_EXEC_FAILURE, L"Windows Update Agent could not be updated because the setup handler failed during execution." }, - { WU_E_SETUP_INVALID_REGISTRY_DATA, L"Windows Update Agent could not be updated because the registry contains invalid information." }, - { WU_E_SELFUPDATE_REQUIRED, L"Windows Update Agent must be updated before search can continue." }, - { WU_E_SELFUPDATE_REQUIRED_ADMIN, L"Windows Update Agent must be updated before search can continue. An administrator is required to perform the operation." }, - { WU_E_SETUP_WRONG_SERVER_VERSION, L"Windows Update Agent could not be updated because the server does not contain update information for this version." }, - { WU_E_SETUP_UNEXPECTED, L"Windows Update Agent could not be updated because of an error not covered by another WU_E_SETUP_* error code." }, - { WU_E_EE_UNKNOWN_EXPRESSION, L"An expression evaluator operation could not be completed because an expression was unrecognized." }, - { WU_E_EE_INVALID_EXPRESSION, L"An expression evaluator operation could not be completed because an expression was invalid." }, - { WU_E_EE_MISSING_METADATA, L"An expression evaluator operation could not be completed because an expression contains an incorrect number of metadata nodes." }, - { WU_E_EE_INVALID_VERSION, L"An expression evaluator operation could not be completed because the version of the serialized expression data is invalid." }, - { WU_E_EE_NOT_INITIALIZED, L"The expression evaluator could not be initialized." }, - { WU_E_EE_INVALID_ATTRIBUTEDATA, L"An expression evaluator operation could not be completed because there was an invalid attribute." }, - { WU_E_EE_CLUSTER_ERROR, L"An expression evaluator operation could not be completed because the cluster state of the computer could not be determined." }, - { WU_E_EE_UNEXPECTED, L"There was an expression evaluator error not covered by another WU_E_EE_* error code." }, - NULL -}; diff --git a/shared/WUErrors.h b/shared/WUErrors.h deleted file mode 100644 index e077cc6..0000000 --- a/shared/WUErrors.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include - -struct HResultMessage { - HRESULT hr; - const LPWSTR message; -}; - -EXTERN_C HResultMessage WUErrorMessages[]; diff --git a/shared/stdafx.h b/shared/stdafx.h index e69de29..5742feb 100644 --- a/shared/stdafx.h +++ b/shared/stdafx.h @@ -0,0 +1,6 @@ +#if defined(_MSC_VER) + #define ALWAYS_INLINE __forceinline + #define __builtin_bswap16 _byteswap_ushort +#else + #define ALWAYS_INLINE inline __attribute__((__always_inline__)) +#endif