SIGN IN SIGN UP

Protocol Buffers - Google's data interchange format

0 0 35 C++

Fix AddDefaultProtoPaths failing when protoc is accessed via symlink … (#26169)

Fixes #25529

## Problem

On Windows, when `protoc.exe` is added to PATH via a symbolic link (e.g.,
WinGet places a symlink in its `Links` directory), `AddDefaultProtoPaths`
fails to locate bundled well-known type `.proto` files like
`google/protobuf/timestamp.proto`. This causes compilation errors:

google/protobuf/timestamp.proto: File not found.

The root cause is that `GetProtocAbsolutePath` uses `GetModuleFileNameA`,
which does not resolve symbolic links. It returns the symlink path instead
of the real executable path, so `AddDefaultProtoPaths` searches for
well-known types relative to the wrong directory.

On other platforms this already works correctly:
- macOS: uses `realpath` (resolves symlinks)
- Linux: uses `readlink("/proc/self/exe")` (resolves symlinks)
- FreeBSD: uses `sysctl` with `KERN_PROC_PATHNAME` (resolves symlinks)

## Fix

After `GetModuleFileNameA` succeeds, resolve the path through
`GetFinalPathNameByHandleA` to follow symbolic links to the real
executable location. The `\\?\` prefix returned by this API is stripped
to produce a normal path.

The fix is defensive — if the handle cannot be opened or the path cannot
be resolved, the original `GetModuleFileNameA` result is preserved
(no change in behavior for the non-symlink case).

Closes #26169

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/26169 from rootvector2:win32-resolve-symlink-in-GetProtocAbsolutePath 6307f504bef0692107732c7366d2ec6ab0345620
PiperOrigin-RevId: 919703245
D
Dexter.k committed
3981478ddaac28d963532e4d41f1609796d14fc4
Parent: 3a48173
Committed by Copybara-Service <copybara-worker@google.com> on 5/22/2026, 4:00:34 PM