Merge pull request #3162 from soda0289/add-windows-long-path-manifest

tar: mark bsdtar as long-path aware on Windows

tar -C/--directory option calls SetCurrentDirectoryW(), which is limited to MAX_PATH (260) characters unless the process opts in to longpath support via an application manifest and enables a registry setting or sets an option in developer settings.
This commit is contained in:
Dustin L. Howett authored and GitHub committed 2026-06-23 23:33:12 -05:00
commit c0e779b73c
5 files changed
+64

No files matched your search

+13
View File
@@ -74,6 +74,8 @@ distcheck-hook:
#
# Extra rules for cleanup
#
CLEANFILES=
DISTCLEANFILES= \
libarchive/test/list.h \
tar/test/list.h \
@@ -1228,10 +1230,21 @@ bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV)
bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS)
bsdtar_LDFLAGS= $(bsdtar_ldstatic) $(DEAD_CODE_REMOVAL)
if INC_WINDOWS_FILES
# Embed an application manifest marking bsdtar as long-path aware.
tar/bsdtar_rc.$(OBJEXT): $(top_srcdir)/tar/bsdtar.rc $(top_srcdir)/tar/bsdtar.exe.manifest
$(AM_V_GEN)$(WINDRES) -I $(top_srcdir)/tar -i $(top_srcdir)/tar/bsdtar.rc -o $@
bsdtar_LDADD += tar/bsdtar_rc.$(OBJEXT)
bsdtar_DEPENDENCIES += tar/bsdtar_rc.$(OBJEXT)
CLEANFILES += tar/bsdtar_rc.$(OBJEXT)
endif
bsdtar_EXTRA_DIST= \
tar/bsdtar.1 \
tar/bsdtar_windows.h \
tar/bsdtar_windows.c \
tar/bsdtar.rc \
tar/bsdtar.exe.manifest \
tar/CMakeLists.txt \
tar/config_freebsd.h
+3
View File
@@ -101,6 +101,9 @@ esac
AM_CONDITIONAL([INC_WINDOWS_FILES], [test $inc_windows_files = yes])
AM_CONDITIONAL([INC_CYGWIN_FILES], [test $inc_cygwin_files = yes])
dnl On native Windows (MinGW), embedding the manifest needs windres
AS_IF([test $inc_windows_files = yes], [AC_CHECK_TOOL([WINDRES], [windres])])
dnl Defines that are required for specific platforms (e.g. -D_POSIX_SOURCE, etc)
PLATFORMCPPFLAGS=
case "$host_os" in
+13
View File
@@ -30,6 +30,15 @@ IF(ENABLE_TAR)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND bsdtar_SOURCES bsdtar_windows.c)
LIST(APPEND bsdtar_SOURCES bsdtar_windows.h)
IF(NOT MSVC)
# The GNU toolchains (MinGW/Clang) do not generate an application
# manifest, so we embed one through a resource script.
ENABLE_LANGUAGE(RC)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
LIST(APPEND bsdtar_SOURCES bsdtar.rc)
SET_SOURCE_FILES_PROPERTIES(bsdtar.rc PROPERTIES
OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bsdtar.exe.manifest)
ENDIF(NOT MSVC)
ENDIF(WIN32 AND NOT CYGWIN)
# bsdtar documentation
@@ -44,6 +53,10 @@ IF(ENABLE_TAR)
SET_TARGET_PROPERTIES(bsdtar PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
ENDIF(ENABLE_TAR_SHARED)
IF(WIN32 AND NOT CYGWIN AND MSVC)
# MSVC merges .manifest sources into the linker's default manifest
TARGET_SOURCES(bsdtar PRIVATE bsdtar.exe.manifest)
ENDIF(WIN32 AND NOT CYGWIN AND MSVC)
# Installation rules
IF(ENABLE_INSTALL)
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>
+20
View File
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Embed an application manifest that marks bsdtar as long-path aware.
*
* bsdtar implements -C/--directory on Windows with SetCurrentDirectoryW(),
* whose argument is limited to MAX_PATH (260) characters unless the process
* opts in to long paths via a "longPathAware" manifest. A system-wide
* LongPathsEnabled registry value is not sufficient on its own; the executable
* must also carry this manifest. Without it, extracting into deeply nested
* destination directories fails with "could not chdir to ...".
*
* See:
* https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation
*/
#define RT_MANIFEST 24
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "bsdtar.exe.manifest"