Release v2.1.0
[v2.1.0] – 2026-05-23
Added
-
Long path support (paths > MAX_PATH / 260 characters), to the extent
Windows and Office permit it. The host process now declares
<longPathAware>true</longPathAware>in its manifest, and
GetModuleFileNameW/GetEnvironmentVariableW(L"APPDATA", …)
callers no longer rely on fixed-size MAX_PATH buffers, so the
plugin can be installed under a long path.Long paths require both
<longPathAware>true</longPathAware>in
the manifest (we ship this) and the system-wide
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1
registry switch (Windows default is0; user/admin must enable it).
With both in place, Win32 / Shell file APIs accept paths longer than
MAX_PATH and we pass the raw path to every preview entry point —
IInitializeWithFile::Initialize,SHCreateStreamOnFileEx,
SHCreateItemFromParsingName, and Office'sDocuments.Open/
Workbooks.Open/Presentations.Open. All of them rejected the
\\?\long-path prefix in testing (Shell APIs withE_INVALIDARG,
Office handlers withE_NOTIMPL), so the prefix is only used for
Win32 file APIs that genuinely benefit from it — currently just
GetFileAttributesExWin the fallback panel — via a new
EnsureLongPathPrefix()helper.Hard limits inside Office that the raw long path could not get
past — Word's preview handler returnedE_NOTIMPLand Excel /
PowerPoint refused both Open() and their preview handlers on paths
above MAX_PATH-1 — are bypassed transparently by creating a
per-LOAD directory junction (NTFS reparse point with
IO_REPARSE_TAG_MOUNT_POINT) in%TEMP%pointing at the file's
parent folder, and passing every consumer a short alias path
(%TEMP%\TCOV_<pid>_<tick>\<filename>) inside that junction. The
kernel transparently follows the junction to the real file, so the
consumer never sees a long path at all. This works regardless of
theLongPathsEnabledregistry switch, requires no privileges
(junctions, unlike symbolic links, are unprivileged) and applies
uniformly to Word / Excel / PowerPoint in both quick and full mode.Junction lifecycle:
- Creation: on the LOAD that exceeds the threshold (
MAX_PATH-9). - Removal on the next LOAD: deferred until AFTER the loader has
closed the previous consumer's document (an earlier draft removed
the junction at the top ofLoadFileWithModeSta, which routinely
failed because Word keeps a directory-change-notification handle on
the parent folder of an open document and that handle survives
untilDocuments.Close). - Removal on
WM_HOST_CLOSE: after the finalUnloadXxxFullSta. - Retry queue: a junction whose
RemoveDirectoryWfails (Office
handle still pending, antivirus scan in flight, …) is parked on a
stale list and re-attempted on every subsequent cleanup opportunity. - Startup sweep: every host process scans
%TEMP%\TCOV_*on
launch and removes junctions whose owning PID is no longer alive.
This is the safety net for orphans left by host crashes or by TC
killing the host during shutdown.
MSG remains the exception: it never needs the junction because
mssvp.dllis initialised throughIInitializeWithItem(Shell-item-
based, immune to path length). - Creation: on the LOAD that exceeds the threshold (