Skip to content

Win7 floor trunk - #518

Open
leginee wants to merge 10 commits into
trunkfrom
win7-floor-trunk
Open

leginee wants to merge 10 commits into
trunkfrom
win7-floor-trunk

Conversation

@leginee

@leginee leginee commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

No description provided.

leginee and others added 10 commits November 4, 2026 22:54
Trunk builds only with a VS2015-or-newer toolset -- Python 3.11 needs one --
and that toolset's runtime does not install on anything older than Windows 7
SP1.  The dmake and gbuild platform settings still declared Windows 2000
(WINVER/_WIN32_WINNT/_WIN32_IE 0x0500), and gbuild declared no _WIN32_WINNT
at all.  Declare the floor the result actually has, with the values the
Bazel build has compiled and run at: WINVER/_WIN32_WINNT 0x0601 and the
_WIN32_IE 0x0800 the Windows SDK derives from them.

Unchanged on purpose: the GUI subsystem version pin in wntmsc14.mk
(5.02/5.01 -- 6.00 switches Windows to the brokered drag-and-drop path our
drop targets fail), and the modules that state their own value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream Python 3.9+ targets Windows 8: PC/pyconfig.h sets Py_WINVER 0x0602
and pythoncore links pathcch.lib, whose API set (api-ms-win-core-path-l1-1-0)
does not exist on Windows 7 -- python311.dll would not even load there.
PCbuild compiles with its own settings, so the solenv floor does not reach it.

The patch is the Windows 7 support the Bazel build has compiled and run with
(ext_libraries/modules/python/3.11.15/overlay on bazel-migration):

  PC/pyconfig.h            Py_WINVER 0x0601, Py_NTDDI NTDDI_WIN7
  PC/pathcch.h             shadows the SDK header (PC/ is ahead on the path)
  PC/pathcch_win7.c        PathCchSkipRoot/FindExtension/CombineEx: the real
                           ones from KernelBase.dll where exported (Windows 8+),
                           documented-behaviour fallbacks on Windows 7
  PC/aoo_win7_compat.h     the two Windows 8 LCMAP_* constants _winapi.c uses
                           only to reject them, force-included everywhere
  pythoncore.vcxproj       compiles pathcch_win7.c, links shlwapi.lib instead
                           of pathcch.lib

_freeze_module keeps pathcch.lib: it only runs on the build machine.  The
patch is applied for the Windows build only.  Verified to apply with
tg_ext.mk's own `patch --binary -p2' against the pristine tarball and to
reproduce the intended tree byte for byte.

On Windows 7 SP1 Python's dynload needs KB2533623 (LOAD_LIBRARY_SEARCH_*),
the same class of prerequisite as the UCRT update the VS2015+ runtime needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The office is now built for Windows 7 SP1 (WINVER/_WIN32_WINNT 0x0601, the
VS2015+ runtime, Python 3.11), but the MSI would still install on Vista or
Windows 7 RTM and leave an office that cannot start.  Add a launch condition
so the installer stops with a clear message instead:

  (VersionNT > 601) or (VersionNT = 601 and ServicePackLevel >= 1) or Installed

The "or Installed" keeps repair and removal of an existing installation
working.  Office MSI only: the language pack, SDK and URE packages install
next to an office and carry only the privilege check.  The new string
OOO_LAUNCH_3 is en-US until translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Record the floor raise (solenv WINVER/_WIN32_WINNT 0x0601), why Python is
where the floor is actually decided (python-3.11.15-win7.patch), the
installer's launch condition, what was deliberately left alone (the GUI
subsystem pin, per-module values), and the Windows 7 SP1 install-time
prerequisites (KB2999226, KB2533623, a Windows 7-capable VC++ runtime).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f74c7b0 set _WIN32_IE=0x0800 next to _WIN32_WINNT=0x0601.  That is the
value the Windows SDK derives at 0x0601, but a fixed value is not the same
thing as a derived one: sal/systools/win32/uwinapi's CopyFileEx{A,W}.cpp
define _WIN32_WINNT 0x0400 themselves, and sdkddkver.h rejects an NT4
_WIN32_WINNT next to an IE above 6.0 SP1:

  sdkddkver.h(296): fatal error C1189: _WIN32_WINNT settings conflicts
  with _WIN32_IE setting

Leave _WIN32_IE unset, as the Bazel build does, so each translation unit
gets the value matching its own _WIN32_WINNT.  Everything at the floor still
compiles at 0x0800.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
At the Windows 7 floor (_WIN32_WINNT 0x0601) psapi.h defaults to
PSAPI_VERSION 2 and maps GetModuleFileNameExA/W to the K32 names, so the
uwinapi thunks were defined as K32GetModuleFileNameExA/W while uwinapi.dxp
exports the classic names: LNK2001 + LNK1120.  Pin version 1 for this
module only; callers elsewhere keep the default and bind to kernel32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Commit 805d7ec raised BUILD from 9900 to 99000. get_fileversion() in
solenv/bin/modules/installer/windows/file.pm splices that value into the
third field of every file's version, so each File.Version row became
10.0.99000.0. Windows Installer stores each version field in 16 bits and
rejects anything above 65535, so the whole database is judged invalid and
every install aborts at InstallValidate with

    Internal Error 2725 -- Invalid database tables

That hit every package the tree produces -- office, SDK and language pack,
x86 and x64 alike -- and the message names neither a table nor the value
responsible.

Lower BUILD to 9900, and derive RSCREVISION from RSCVERSION, LAST_MINOR and
BUILD so the build id is written in exactly one place instead of twice.
Reject an out-of-range build id in get_fileversion() as well: a package that
no Windows machine can install should fail while it is being built, not
after it ships.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit ca673c293cf2eb5f1c8f982dc62180981fbaa8b0)
lngconvex substitutes each %PLACEHOLDER% in an .rc template from the
string table of the language being written.  A string that has an en-US
entry but no translation yet -- every string added since the last
translation round -- was left as the raw placeholder in all other
language sections.

setup.exe shows this: on a non-English system a failed runtime install
reported "%RUNTIME_FAILED%" instead of the message, and %OS_TO_OLD% and
%USER_CANCELED% had the same problem.  Fall back to the en-US text.

The fallback looks the en-US table up with find() so that it cannot
create an empty table, which would add an extra language section to the
output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The office is now built for Windows 7 SP1 (WINVER/_WIN32_WINNT 0x0601)
and the MSI launch condition stops below Windows 7 SP1, but setup.exe
still refused to run on anything older than Windows 10.  Check for 6.1
SP1 instead, and say so in the message.

The version still comes from RtlGetVersion, because GetVersionEx reports
6.3 on Windows 10 and 11 without a supportedOS manifest entry.  The
service pack level needs OSVERSIONINFOEXW.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the Windows 7 SP1 floor, the bundled VC v14 redistributable must
install on Windows 7 SP1.  The current v14 releases do not, so the
"latest" permalinks are wrong for this build.  The 14.29 redistributable
that ships with the VS2019 build tools still supports Windows 7 SP1 and
matches the toolset.

Also document how a wrong file shows up: setup.exe runs the package with
the v14 switches "/install /quiet /norestart".  The Visual C++ 2008
package does not understand them and fails, and setup.exe stops with
"The Microsoft Visual C++ runtime could not be installed".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant