Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions main/desktop/win32/source/setup/setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,13 @@
#define ERROR_OS_TO_OLD -5
#define ERROR_RUNTIME_FAILED -6

// Lowest Windows this office can run on. Not an arbitrary policy: the VC v14
// redistributable that supplies the runtime the binaries need installs only on
// Windows 10/11 and Server 2016 and later, so the floor comes with the toolset.
#define REQUIRED_WINDOWS_MAJOR 10
// Lowest Windows this office can run on: Windows 7 SP1 (6.1 SP1), matching the
// WINVER/_WIN32_WINNT 0x0601 the office is compiled for and the MSI launch
// condition. The bundled VC v14 redistributable must still install there --
// current releases do not; see external/vcredist/README.
#define REQUIRED_WINDOWS_MAJOR 6
#define REQUIRED_WINDOWS_MINOR 1
#define REQUIRED_WINDOWS_SP 1

#define PARAM_SETUP_USED TEXT( " SETUP_USED=1 " )
#define PARAM_PACKAGE TEXT( "/I " )
Expand Down Expand Up @@ -1861,9 +1864,9 @@ boolean SetupApp::IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName )
// as an MSI LaunchCondition, and lives here instead.
//
// RtlGetVersion is not subject to that shim.
static bool GetRealWindowsVersion( DWORD *pMajor, DWORD *pBuild )
static bool GetRealWindowsVersion( OSVERSIONINFOEXW *pInfo )
{
typedef LONG ( WINAPI *pfnRtlGetVersion_t )( OSVERSIONINFOW * );
typedef LONG ( WINAPI *pfnRtlGetVersion_t )( OSVERSIONINFOEXW * );

HMODULE hNtdll = ::GetModuleHandle( TEXT( "ntdll.dll" ) );
if ( hNtdll == NULL )
Expand All @@ -1874,25 +1877,18 @@ static bool GetRealWindowsVersion( DWORD *pMajor, DWORD *pBuild )
if ( pRtlGetVersion == NULL )
return false;

OSVERSIONINFOW aInfo;
ZeroMemory( &aInfo, sizeof( aInfo ) );
aInfo.dwOSVersionInfoSize = sizeof( aInfo );
ZeroMemory( pInfo, sizeof( *pInfo ) );
pInfo->dwOSVersionInfoSize = sizeof( *pInfo );

if ( pRtlGetVersion( &aInfo ) != 0 )
return false;

*pMajor = aInfo.dwMajorVersion;
*pBuild = aInfo.dwBuildNumber;
return true;
return pRtlGetVersion( pInfo ) == 0;
}

//--------------------------------------------------------------------------
boolean SetupApp::CheckOSVersion()
{
DWORD nMajor = 0;
DWORD nBuild = 0;
OSVERSIONINFOEXW aInfo;

if ( !GetRealWindowsVersion( &nMajor, &nBuild ) )
if ( !GetRealWindowsVersion( &aInfo ) )
{
// Could not determine the version. Let the install proceed rather than
// refuse on a machine we simply failed to identify -- if the OS really is too
Expand All @@ -1903,15 +1899,24 @@ boolean SetupApp::CheckOSVersion()

TCHAR sBuf[ 128 ];

StringCchPrintf( sBuf, 128, TEXT( " Windows major version %u, build %u\r\n" ),
nMajor, nBuild );
StringCchPrintf( sBuf, 128, TEXT( " Windows version %u.%u build %u, service pack %u\r\n" ),
aInfo.dwMajorVersion, aInfo.dwMinorVersion, aInfo.dwBuildNumber,
(DWORD)aInfo.wServicePackMajor );
Log( sBuf );

if ( nMajor < REQUIRED_WINDOWS_MAJOR )
const DWORD nHave = ( aInfo.dwMajorVersion << 16 ) | ( aInfo.dwMinorVersion << 8 )
| aInfo.wServicePackMajor;
const DWORD nNeed = ( REQUIRED_WINDOWS_MAJOR << 16 ) | ( REQUIRED_WINDOWS_MINOR << 8 )
| REQUIRED_WINDOWS_SP;

if ( nHave < nNeed )
{
StringCchPrintf( sBuf, 128,
TEXT( "ERROR: Windows %u is older than the required Windows %u.\r\n" ),
nMajor, (DWORD)REQUIRED_WINDOWS_MAJOR );
TEXT( "ERROR: Windows %u.%u SP%u is older than the required Windows %u.%u SP%u.\r\n" ),
aInfo.dwMajorVersion, aInfo.dwMinorVersion,
(DWORD)aInfo.wServicePackMajor,
(DWORD)REQUIRED_WINDOWS_MAJOR, (DWORD)REQUIRED_WINDOWS_MINOR,
(DWORD)REQUIRED_WINDOWS_SP );
Log( sBuf );
SetError( ERROR_OS_TO_OLD );
return false;
Expand Down
2 changes: 1 addition & 1 deletion main/desktop/win32/source/setup/setup.ulf
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ en-US = "This package requires at least the version '%s' of the Windows Installe
en-US = "This package requires the Windows Installer. \nYou need at least Windows Installer '%s' on your system!"

[%OS_TO_OLD%]
en-US = "This version of %PRODUCTNAME% requires Windows 10 or later. \nIt cannot be installed on this version of Windows."
en-US = "This version of %PRODUCTNAME% requires Windows 7 Service Pack 1 or later. \nIt cannot be installed on this version of Windows."

[%RUNTIME_FAILED%]
en-US = "The Microsoft Visual C++ runtime could not be installed. \n%PRODUCTNAME% cannot run without it, so the installation has been stopped."
Expand Down
37 changes: 25 additions & 12 deletions main/external/vcredist/README
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ desktop/win32/source/setup/setup.cpp all refer to the vcredist_* spelling.

Which ones
----------
The Visual C++ v14 Redistributable (Visual Studio 2015-2022), latest version:
The Visual C++ v14 Redistributable that ships with the Visual Studio 2019
build tools used to compile the office (14.29.x, VS2019 16.11). It is
already on the build machine:

x86 https://aka.ms/vc14/vc_redist.x86.exe
x64 https://aka.ms/vc14/vc_redist.x64.exe
<VS2019>/VC/Redist/MSVC/14.29.30133/vc_redist.x86.exe
<VS2019>/VC/Redist/MSVC/14.29.30133/vc_redist.x64.exe

These are permalinks that always resolve to the current v14 release.
Do NOT take the "latest" permalinks (https://aka.ms/vc14/vc_redist.x64.exe):
the current v14 releases no longer install on Windows 7 SP1, which is this
build's floor -- see below.

The rule is that the redistributable must be the same version as, or newer
than, the MSVC build tools used to compile the office. A v14 redistributable
Expand All @@ -34,11 +38,20 @@ runtime.

Supported Windows versions
--------------------------
The current v14 redistributable supports Windows 10 and 11, and Windows Server
2016 / 2019 / 2022 / 2025 -- it does not install on anything older. That is
what sets the minimum Windows version for a build made with a modern toolset;
it is not an independent choice.

If an older floor is ever needed, an older v14 servicing release has to be
pinned here explicitly, and its own supported-OS list checked -- the v14 line
has raised its floor over time.
The office is built for Windows 7 SP1 (WINVER/_WIN32_WINNT 0x0601), and both
setup.exe and the MSI launch condition enforce that floor. The bundled
redistributable must therefore install on Windows 7 SP1 too.

The current v14 redistributable supports only Windows 10 and 11 and Windows
Server 2016 and later -- it does not install on anything older. The VS2019
16.11 redistributable (14.29.x) still supports Windows 7 SP1, and because it
matches the toolset it also satisfies "same version or newer". If the
toolset is ever raised, the redistributable has to move with it, and the new
release's supported-OS list has to be checked against the floor -- the v14
line has raised its floor over time.

Check what is in this directory before building: the file version of
vcredist_x64.exe must start with 14., not 9.0. setup.exe runs it with the v14
switches "/install /quiet /norestart"; the 2008 package does not understand
them, fails, and setup.exe stops with "The Microsoft Visual C++ runtime could
not be installed".
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@
en-US = "The Installation Wizard cannot be run properly because you are logged in as a user without sufficient administrator rights for this system."
[OOO_LAUNCH_2]
en-US = "Please use the file setup.exe to start the installation."
[OOO_LAUNCH_3]
en-US = "[ProductName] requires Windows 7 Service Pack 1 or later."
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ Condition Description
s255 l255
WINDOWSENCODINGTEMPLATE LaunchCondition Condition
Privileged OOO_LAUNCH_1
(VersionNT < 600) or (SETUP_USED=1) or Installed OOO_LAUNCH_2
(VersionNT < 600) or (SETUP_USED=1) or Installed OOO_LAUNCH_2
(VersionNT > 601) or (VersionNT = 601 and ServicePackLevel >= 1) or Installed OOO_LAUNCH_3
11 changes: 11 additions & 0 deletions main/python/makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ PATCH_FILES=\
# through the compiler include/lib search paths instead of the old hard-coded
# source edit; see python_CFLAGS/python_LDFLAGS in the UNX branch below.

# Windows 7 SP1, the office's floor, where upstream Python 3.9+ wants
# Windows 8: PC/pyconfig.h's Py_WINVER/Py_NTDDI lowered to Windows 7, and
# pythoncore no longer imports pathcch.lib (its API set does not exist on
# Windows 7, so python311.dll would not even load there) -- PC/pathcch_win7.c
# calls the real PathCch* functions where KernelBase exports them and falls
# back to their documented behaviour on Windows 7. _freeze_module keeps
# pathcch.lib: it only runs on the build machine.
.IF "$(GUI)"=="WNT"
PATCH_FILES += python-$(PYVERSION)-win7.patch
.ENDIF

# Windows build deferred — Python 3 requires modern MSVC (VS2008/msvs9 not supported).
# The msvs9 patch files below are retained for reference but are NOT applied until
# the Windows toolchain is modernised. See python3 migration notes.
Expand Down
Loading
Loading