[vlc-commits] [Git][videolan/vlc][master] 4 commits: contrib: mingw64: allow CreateHardLinkW/GetVolumePathNameW in UWP

Steve Lhomme (@robUx4) gitlab at videolan.org
Wed May 31 07:46:42 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
4347aac5 by Steve Lhomme at 2023-05-31T06:52:24+00:00
contrib: mingw64: allow CreateHardLinkW/GetVolumePathNameW in UWP

- - - - -
d853db29 by Steve Lhomme at 2023-05-31T06:52:24+00:00
contrib: libarchive: allow CreateHardLinkW in UWP

- - - - -
c340f0b0 by Steve Lhomme at 2023-05-31T06:52:24+00:00
contrib: libarchive: download tarball from GitHub

The hash is unchanged (good).

- - - - -
3b0db17c by Steve Lhomme at 2023-05-31T06:52:24+00:00
contrib: libarchive: cleanup UWP patches with patches sent upstream

None rely on WINSTORECOMPAT anymore.

- - - - -


14 changed files:

- + contrib/src/libarchive/0001-Use-CreateHardLinkW-and-CreateSymbolicLinkW-directly.patch
- + contrib/src/libarchive/0002-Disable-CreateSymbolicLinkW-use-in-UWP-builds.patch
- + contrib/src/libarchive/0003-fix-the-CreateHardLinkW-signature-to-match-the-real-.patch
- + contrib/src/libarchive/0004-Don-t-call-GetOEMCP-in-Universal-Windows-Platform-bu.patch
- + contrib/src/libarchive/0005-tests-use-CreateFileA-for-char-filenames.patch
- + contrib/src/libarchive/0006-Use-CreateFile2-instead-of-CreateFileW-on-Win8-build.patch
- + contrib/src/libarchive/0007-Disable-CreateFileA-calls-in-UWP-builds.patch
- + contrib/src/libarchive/0008-Disable-program-call-with-stdin-stdout-usage-on-UWP-.patch
- + contrib/src/libarchive/0009-Use-Windows-bcrypt-when-enabled-and-building-for-Vis.patch
- contrib/src/libarchive/rules.mak
- − contrib/src/libarchive/winrt.patch
- + contrib/src/mingw64/0001-headers-enable-CreateHardLinkW-in-Win10-UWP-builds.patch
- + contrib/src/mingw64/0001-headers-enable-GetVolumePathNameW-in-Win10-UWP-build.patch
- contrib/src/mingw64/rules.mak


Changes:

=====================================
contrib/src/libarchive/0001-Use-CreateHardLinkW-and-CreateSymbolicLinkW-directly.patch
=====================================
@@ -0,0 +1,81 @@
+From 5e0a673c7b4a48238f9afea754872447f1d55830 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 25 May 2023 09:53:49 +0200
+Subject: [PATCH 1/9] Use CreateHardLinkW and CreateSymbolicLinkW directly on
+ Vista+ builds
+
+No need to load the kernel library manually. It's always available. It's not
+possible to load it in Universal Windows Platform (UWP) builds anyway.
+
+No need to load the kernel library manually. It's always available. It's not
+possible to load it in Universal Windows Platform (UWP) builds anyway.
+---
+ libarchive/archive_write_disk_windows.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
+index 7bed5bd2..8a8c6d00 100644
+--- a/libarchive/archive_write_disk_windows.c
++++ b/libarchive/archive_write_disk_windows.c
+@@ -559,6 +559,7 @@ la_mktemp(struct archive_write_disk *a)
+ 	return (fd);
+ }
+ 
++#if _WIN32_WINNT < _WIN32_WINNT_VISTA
+ static void *
+ la_GetFunctionKernel32(const char *name)
+ {
+@@ -574,18 +575,24 @@ la_GetFunctionKernel32(const char *name)
+ 	}
+ 	return (void *)GetProcAddress(lib, name);
+ }
++#endif
+ 
+ static int
+ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
+ {
+ 	static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
+-	static int set;
+ 	BOOL ret;
+ 
++#if _WIN32_WINNT < _WIN32_WINNT_XP
++	static int set;
++/* CreateHardLinkW is available since XP and always loaded */
+ 	if (!set) {
+ 		set = 1;
+ 		f = la_GetFunctionKernel32("CreateHardLinkW");
+ 	}
++#else
++	f = CreateHardLinkW;
++#endif
+ 	if (!f) {
+ 		errno = ENOTSUP;
+ 		return (0);
+@@ -624,7 +631,6 @@ static int
+ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
+     int linktype) {
+ 	static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
+-	static int set;
+ 	wchar_t *ttarget, *p;
+ 	size_t len;
+ 	DWORD attrs = 0;
+@@ -632,10 +638,16 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
+ 	DWORD newflags = 0;
+ 	BOOL ret = 0;
+ 
++#if _WIN32_WINNT < _WIN32_WINNT_VISTA
++/* CreateSymbolicLinkW is available since Vista and always loaded */
++	static int set;
+ 	if (!set) {
+ 		set = 1;
+ 		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
+ 	}
++#else
++	f = CreateSymbolicLinkW;
++#endif
+ 	if (!f)
+ 		return (0);
+ 
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0002-Disable-CreateSymbolicLinkW-use-in-UWP-builds.patch
=====================================
@@ -0,0 +1,30 @@
+From 8f390c3eb57ddbf4b1aa9aecd1da35151a0d8636 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 25 May 2023 09:38:30 +0200
+Subject: [PATCH 2/9] Disable CreateSymbolicLinkW use in UWP builds
+
+The call is forbidden:
+https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw#requirements
+---
+ libarchive/archive_write_disk_windows.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
+index 8a8c6d00..b42010d4 100644
+--- a/libarchive/archive_write_disk_windows.c
++++ b/libarchive/archive_write_disk_windows.c
+@@ -646,7 +646,11 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
+ 		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
+ 	}
+ #else
++# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ 	f = CreateSymbolicLinkW;
++# else
++	f = NULL;
++# endif
+ #endif
+ 	if (!f)
+ 		return (0);
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0003-fix-the-CreateHardLinkW-signature-to-match-the-real-.patch
=====================================
@@ -0,0 +1,27 @@
+From 57abf55bba172dfb4301674a75c1f663a70741d0 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 25 May 2023 10:16:08 +0200
+Subject: [PATCH 3/9] fix the CreateHardLinkW signature to match the real
+ function
+
+The `ret` variable was already using BOOL instead of BOOLEAN.
+---
+ libarchive/archive_write_disk_windows.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
+index b42010d4..839bc295 100644
+--- a/libarchive/archive_write_disk_windows.c
++++ b/libarchive/archive_write_disk_windows.c
+@@ -580,7 +580,7 @@ la_GetFunctionKernel32(const char *name)
+ static int
+ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
+ {
+-	static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
++	static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
+ 	BOOL ret;
+ 
+ #if _WIN32_WINNT < _WIN32_WINNT_XP
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0004-Don-t-call-GetOEMCP-in-Universal-Windows-Platform-bu.patch
=====================================
@@ -0,0 +1,36 @@
+From 4d018f8cd3104fb34e0f4c6c5bebbdd47351643d Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Wed, 24 May 2023 15:23:14 +0200
+Subject: [PATCH 4/9] Don't call GetOEMCP() in Universal Windows Platform
+ builds
+
+It's not available [1] [2]. However we can use the intermediate CP_OEMCP
+value. It can be used to compare charsets in create_sconv_object().
+It won't work with comparing charsets in archive_string_default_conversion_for_read()
+and archive_string_default_conversion_for_write(). current_codepage being
+an actual CodePage value.
+
+[1] https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-localization-l1-2-0dll
+[2] https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getoemcp#requirements
+---
+ libarchive/archive_string.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
+index 69458e1a..accf5263 100644
+--- a/libarchive/archive_string.c
++++ b/libarchive/archive_string.c
+@@ -1324,6 +1324,10 @@ free_sconv_object(struct archive_string_conv *sc)
+ }
+ 
+ #if defined(_WIN32) && !defined(__CYGWIN__)
++# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
++#  define GetOEMCP() CP_OEMCP
++# endif
++
+ static unsigned
+ my_atoi(const char *p)
+ {
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0005-tests-use-CreateFileA-for-char-filenames.patch
=====================================
@@ -0,0 +1,35 @@
+From 442c857f5d34a2230058f12c46e92e53940b1444 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Wed, 24 May 2023 15:00:04 +0200
+Subject: [PATCH 5/9] tests: use CreateFileA for char* filenames
+
+In case the code is compiled with the UNICODE define.
+---
+ test_utils/test_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/test_utils/test_main.c b/test_utils/test_main.c
+index 3250423a..e4b884ee 100644
+--- a/test_utils/test_main.c
++++ b/test_utils/test_main.c
+@@ -327,7 +327,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
+ 	int r;
+ 
+ 	memset(bhfi, 0, sizeof(*bhfi));
+-	h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
++	h = CreateFileA(path, FILE_READ_ATTRIBUTES, 0, NULL,
+ 		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ 	if (h == INVALID_HANDLE_VALUE)
+ 		return (0);
+@@ -1432,7 +1432,7 @@ assertion_file_time(const char *file, int line,
+ 	/* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
+ 	 * a directory file. If not, CreateFile() will fail when
+ 	 * the pathname is a directory. */
+-	h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
++	h = CreateFileA(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
+ 	    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ 	if (h == INVALID_HANDLE_VALUE) {
+ 		failure_start(file, line, "Can't access %s\n", pathname);
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0006-Use-CreateFile2-instead-of-CreateFileW-on-Win8-build.patch
=====================================
@@ -0,0 +1,410 @@
+From e6da44580b3b700b1e194c7b1a465d28aa7ea6f3 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 26 May 2023 09:57:40 +0200
+Subject: [PATCH 6/9] Use CreateFile2 instead of CreateFileW on Win8+ builds
+
+CreateFileW is not allowed in Universal Windows Platform (UWP) builds but
+CreateFile2 is available. We could just enable this code for UWP but
+it's probably to use it going forward so the code is properly tested on
+both sides.
+---
+ cpio/cpio_windows.c                     | 15 +++++
+ libarchive/archive_read_disk_windows.c  | 83 ++++++++++++++++++++++---
+ libarchive/archive_util.c               | 15 +++++
+ libarchive/archive_windows.c            | 15 +++++
+ libarchive/archive_write_disk_windows.c | 51 +++++++++++++++
+ 5 files changed, 172 insertions(+), 7 deletions(-)
+
+diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c
+index 63f6df03..15cccaf9 100644
+--- a/cpio/cpio_windows.c
++++ b/cpio/cpio_windows.c
+@@ -156,6 +156,9 @@ cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ {
+ 	wchar_t *wpath;
+ 	HANDLE handle;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+@@ -167,9 +170,21 @@ cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 	wpath = permissive_name(path);
+ 	if (wpath == NULL)
+ 		return (handle);
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
++	createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
++	createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F0000;
++	createExParams.lpSecurityAttributes = lpSecurityAttributes;
++	createExParams.hTemplateFile = hTemplateFile;
++	handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
++	    dwCreationDisposition, &createExParams);
++#else
+ 	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ 	    hTemplateFile);
++#endif
+ 	free(wpath);
+ 	return (handle);
+ }
+diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c
+index ea32e2aa..21356ee6 100644
+--- a/libarchive/archive_read_disk_windows.c
++++ b/libarchive/archive_read_disk_windows.c
+@@ -418,8 +418,19 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
+ 	    FILE_FLAG_OPEN_REPARSE_POINT;
+ 	int ret;
+ 
+-	h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
+-	    NULL);
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileFlags = flag;
++	h = CreateFile2(path, 0,
++	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
++	    OPEN_EXISTING, &createExParams);
++#else
++	h = CreateFileW(path, 0,
++	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
++	    OPEN_EXISTING, flag, NULL);
++#endif
+ 	if (h == INVALID_HANDLE_VALUE) {
+ 		la_dosmaperr(GetLastError());
+ 		return (-1);
+@@ -1066,14 +1077,27 @@ next_entry(struct archive_read_disk *a, struct tree *t,
+ 	if (archive_entry_filetype(entry) == AE_IFREG &&
+ 	    archive_entry_size(entry) > 0) {
+ 		DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
++#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 		if (t->async_io)
+ 			flags |= FILE_FLAG_OVERLAPPED;
+ 		if (t->direct_io)
+ 			flags |= FILE_FLAG_NO_BUFFERING;
+ 		else
+ 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
++#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		ZeroMemory(&createExParams, sizeof(createExParams));
++		createExParams.dwSize = sizeof(createExParams);
++		createExParams.dwFileFlags = flags;
++		t->entry_fh = CreateFile2(tree_current_access_path(t),
++		    GENERIC_READ,
++		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
++		    OPEN_EXISTING, &createExParams);
++#else
+ 		t->entry_fh = CreateFileW(tree_current_access_path(t),
+ 		    GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
++#endif
+ 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
+ 			la_dosmaperr(GetLastError());
+ 			archive_set_error(&a->archive, errno,
+@@ -1544,6 +1568,9 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
+ {
+ 	HANDLE handle;
+ 	int r = 0;
++#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 	if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
+ 		return (0);
+@@ -1557,8 +1584,16 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
+ 	if ((t->flags & needsRestoreTimes) == 0)
+ 		return (r);
+ 
++#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
++	handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
++		    0, OPEN_EXISTING, &createExParams);
++#else
+ 	handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
+ 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
++#endif
+ 	if (handle == INVALID_HANDLE_VALUE) {
+ 		errno = EINVAL;
+ 		return (-1);
+@@ -2043,11 +2078,23 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
+ 	HANDLE h;
+ 	int r;
+ 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+-	
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
++
+ 	if (sim_lstat && tree_current_is_physical_link(t))
+ 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileFlags = flag;
++	h = CreateFile2(tree_current_access_path(t), 0,
++	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
++	    OPEN_EXISTING, &createExParams);
++#else
+ 	h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
+ 	    OPEN_EXISTING, flag, NULL);
++#endif
+ 	if (h == INVALID_HANDLE_VALUE) {
+ 		la_dosmaperr(GetLastError());
+ 		t->tree_errno = errno;
+@@ -2253,7 +2300,10 @@ archive_read_disk_entry_from_file(struct archive *_a,
+ 		} else {
+ 			WIN32_FIND_DATAW findData;
+ 			DWORD flag, desiredAccess;
+-	
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
++
+ 			h = FindFirstFileW(path, &findData);
+ 			if (h == INVALID_HANDLE_VALUE) {
+ 				la_dosmaperr(GetLastError());
+@@ -2275,8 +2325,17 @@ archive_read_disk_entry_from_file(struct archive *_a,
+ 			} else
+ 				desiredAccess = GENERIC_READ;
+ 
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++			ZeroMemory(&createExParams, sizeof(createExParams));
++			createExParams.dwSize = sizeof(createExParams);
++			createExParams.dwFileFlags = flag;
++			h = CreateFile2(path, desiredAccess,
++			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
++			    OPEN_EXISTING, &createExParams);
++#else
+ 			h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
+ 			    OPEN_EXISTING, flag, NULL);
++#endif
+ 			if (h == INVALID_HANDLE_VALUE) {
+ 				la_dosmaperr(GetLastError());
+ 				archive_set_error(&a->archive, errno,
+@@ -2337,8 +2396,18 @@ archive_read_disk_entry_from_file(struct archive *_a,
+ 		if (fd >= 0) {
+ 			h = (HANDLE)_get_osfhandle(fd);
+ 		} else {
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++			ZeroMemory(&createExParams, sizeof(createExParams));
++			createExParams.dwSize = sizeof(createExParams);
++			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
++			h = CreateFile2(path, GENERIC_READ,
++			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
++			    OPEN_EXISTING, &createExParams);
++#else
+ 			h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
++#endif
+ 			if (h == INVALID_HANDLE_VALUE) {
+ 				la_dosmaperr(GetLastError());
+ 				archive_set_error(&a->archive, errno,
+diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c
+index b1582edb..17123b94 100644
+--- a/libarchive/archive_util.c
++++ b/libarchive/archive_util.c
+@@ -323,6 +323,9 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 	for (;;) {
+ 		wchar_t *p;
+ 		HANDLE h;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 		/* Generate a random file name through CryptGenRandom(). */
+ 		p = xp;
+@@ -347,6 +350,17 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 			/* mkstemp */
+ 			attr = FILE_ATTRIBUTE_NORMAL;
+ 		}
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		ZeroMemory(&createExParams, sizeof(createExParams));
++		createExParams.dwSize = sizeof(createExParams);
++		createExParams.dwFileAttributes = attr & 0xFFFF;
++		createExParams.dwFileFlags = attr & 0xFFF00000;
++		h = CreateFile2(ws,
++		    GENERIC_READ | GENERIC_WRITE | DELETE,
++		    0,/* Not share */
++			CREATE_NEW,
++			&createExParams);
++#else
+ 		h = CreateFileW(ws,
+ 		    GENERIC_READ | GENERIC_WRITE | DELETE,
+ 		    0,/* Not share */
+@@ -354,6 +368,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 		    CREATE_NEW,/* Create a new file only */
+ 		    attr,
+ 		    NULL);
++#endif
+ 		if (h == INVALID_HANDLE_VALUE) {
+ 			/* The same file already exists. retry with
+ 			 * a new filename. */
+diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
+index 624e2700..53d4b558 100644
+--- a/libarchive/archive_windows.c
++++ b/libarchive/archive_windows.c
+@@ -234,6 +234,9 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ {
+ 	wchar_t *wpath;
+ 	HANDLE handle;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+@@ -245,9 +248,21 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 	wpath = __la_win_permissive_name(path);
+ 	if (wpath == NULL)
+ 		return (handle);
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
++	createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
++	createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
++	createExParams.lpSecurityAttributes = lpSecurityAttributes;
++	createExParams.hTemplateFile = hTemplateFile;
++	handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
++	    dwCreationDisposition, &createExParams);
++#else /* !WINAPI_PARTITION_DESKTOP */
+ 	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ 	    hTemplateFile);
++#endif /* !WINAPI_PARTITION_DESKTOP */
+ 	free(wpath);
+ 	return (handle);
+ }
+diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
+index 0d838c14..7521fbe1 100644
+--- a/libarchive/archive_write_disk_windows.c
++++ b/libarchive/archive_write_disk_windows.c
+@@ -266,6 +266,9 @@ file_information(struct archive_write_disk *a, wchar_t *path,
+ 	int r;
+ 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+ 	WIN32_FIND_DATAW	findData;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 	if (sim_lstat || mode != NULL) {
+ 		h = FindFirstFileW(path, &findData);
+@@ -290,14 +293,27 @@ file_information(struct archive_write_disk *a, wchar_t *path,
+ 		(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
+ 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+ 
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++	ZeroMemory(&createExParams, sizeof(createExParams));
++	createExParams.dwSize = sizeof(createExParams);
++	createExParams.dwFileFlags = flag;
++	h = CreateFile2(a->name, 0, 0,
++		OPEN_EXISTING, &createExParams);
++#else
+ 	h = CreateFileW(a->name, 0, 0, NULL,
+ 	    OPEN_EXISTING, flag, NULL);
++#endif
+ 	if (h == INVALID_HANDLE_VALUE &&
+ 	    GetLastError() == ERROR_INVALID_NAME) {
+ 		wchar_t *full;
+ 		full = __la_win_permissive_name_w(path);
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		h = CreateFile2(full, 0, 0,
++			OPEN_EXISTING, &createExParams);
++#else
+ 		h = CreateFileW(full, 0, 0, NULL,
+ 		    OPEN_EXISTING, flag, NULL);
++#endif
+ 		free(full);
+ 	}
+ 	if (h == INVALID_HANDLE_VALUE) {
+@@ -1671,6 +1687,9 @@ create_filesystem_object(struct archive_write_disk *a)
+ 	mode_t final_mode, mode;
+ 	int r;
+ 	DWORD attrs = 0;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 	/* We identify hard/symlinks according to the link names. */
+ 	/* Since link(2) and symlink(2) don't handle modes, we're done here. */
+@@ -1734,8 +1753,16 @@ create_filesystem_object(struct archive_write_disk *a)
+ 			a->todo = 0;
+ 			a->deferred = 0;
+ 		} else if (r == 0 && a->filesize > 0) {
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++			ZeroMemory(&createExParams, sizeof(createExParams));
++			createExParams.dwSize = sizeof(createExParams);
++			createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
++			a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
++			    TRUNCATE_EXISTING, &createExParams);
++#else
+ 			a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
+ 			    TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
++#endif
+ 			if (a->fh == INVALID_HANDLE_VALUE) {
+ 				la_dosmaperr(GetLastError());
+ 				r = errno;
+@@ -1798,14 +1825,27 @@ create_filesystem_object(struct archive_write_disk *a)
+ 		a->tmpname = NULL;
+ 		fullname = a->name;
+ 		/* O_WRONLY | O_CREAT | O_EXCL */
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		ZeroMemory(&createExParams, sizeof(createExParams));
++		createExParams.dwSize = sizeof(createExParams);
++		createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
++		a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
++		    CREATE_NEW, &createExParams);
++#else
+ 		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ 		    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
++#endif
+ 		if (a->fh == INVALID_HANDLE_VALUE &&
+ 		    GetLastError() == ERROR_INVALID_NAME &&
+ 		    fullname == a->name) {
+ 			fullname = __la_win_permissive_name_w(a->name);
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++			a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
++			    CREATE_NEW, &createExParams);
++#else
+ 			a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ 			    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
++#endif
+ 		}
+ 		if (a->fh == INVALID_HANDLE_VALUE) {
+ 			if (GetLastError() == ERROR_ACCESS_DENIED) {
+@@ -2561,14 +2601,25 @@ set_times(struct archive_write_disk *a,
+ 		hw = NULL;
+ 	} else {
+ 		wchar_t *ws;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++#endif
+ 
+ 		if (S_ISLNK(mode))
+ 			return (ARCHIVE_OK);
+ 		ws = __la_win_permissive_name_w(name);
+ 		if (ws == NULL)
+ 			goto settimes_failed;
++# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
++		ZeroMemory(&createExParams, sizeof(createExParams));
++		createExParams.dwSize = sizeof(createExParams);
++		createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
++		hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
++		    OPEN_EXISTING, &createExParams);
++#else
+ 		hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
+ 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
++#endif
+ 		free(ws);
+ 		if (hw == INVALID_HANDLE_VALUE)
+ 			goto settimes_failed;
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0007-Disable-CreateFileA-calls-in-UWP-builds.patch
=====================================
@@ -0,0 +1,99 @@
+From 282cf8ce619eaf62addf65ee7825c8f2d8ebf4e3 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 26 May 2023 09:58:48 +0200
+Subject: [PATCH 7/9] Disable CreateFileA calls in UWP builds
+
+Only CreateFile2 and CreateFileFromAppW are allowed.
+---
+ cpio/cpio_windows.c          |  4 +++-
+ libarchive/archive_windows.c | 20 +++++++++++++++++---
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c
+index 15cccaf9..2809ca82 100644
+--- a/cpio/cpio_windows.c
++++ b/cpio/cpio_windows.c
+@@ -160,6 +160,7 @@ cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+ #endif
+ 
++#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+ 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ 	    hTemplateFile);
+@@ -167,9 +168,10 @@ cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 		return (handle);
+ 	if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ 		return (handle);
++#endif
+ 	wpath = permissive_name(path);
+ 	if (wpath == NULL)
+-		return (handle);
++		return INVALID_HANDLE_VALUE;
+ # if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+ 	ZeroMemory(&createExParams, sizeof(createExParams));
+ 	createExParams.dwSize = sizeof(createExParams);
+diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
+index 53d4b558..ebc5eefb 100644
+--- a/libarchive/archive_windows.c
++++ b/libarchive/archive_windows.c
+@@ -238,6 +238,7 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+ #endif
+ 
++#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+ 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ 	    hTemplateFile);
+@@ -245,9 +246,10 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ 		return (handle);
+ 	if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ 		return (handle);
++#endif
+ 	wpath = __la_win_permissive_name(path);
+ 	if (wpath == NULL)
+-		return (handle);
++		return INVALID_HANDLE_VALUE;
+ # if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+ 	ZeroMemory(&createExParams, sizeof(createExParams));
+ 	createExParams.dwSize = sizeof(createExParams);
+@@ -320,7 +322,10 @@ __la_open(const char *path, int flags, ...)
+ 		 * "Permission denied" error.
+ 		 */
+ 		attr = GetFileAttributesA(path);
+-		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
++#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
++		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
++#endif
++		{
+ 			ws = __la_win_permissive_name(path);
+ 			if (ws == NULL) {
+ 				errno = EINVAL;
+@@ -335,7 +340,7 @@ __la_open(const char *path, int flags, ...)
+ 		}
+ 		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+ 			HANDLE handle;
+-
++#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+ 			if (ws != NULL)
+ 				handle = CreateFileW(ws, 0, 0, NULL,
+ 				    OPEN_EXISTING,
+@@ -348,6 +353,15 @@ __la_open(const char *path, int flags, ...)
+ 				    FILE_FLAG_BACKUP_SEMANTICS |
+ 				    FILE_ATTRIBUTE_READONLY,
+ 					NULL);
++#else /* !WINAPI_PARTITION_DESKTOP */
++			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
++			ZeroMemory(&createExParams, sizeof(createExParams));
++			createExParams.dwSize = sizeof(createExParams);
++			createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
++			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
++			handle = CreateFile2(ws, 0, 0,
++				OPEN_EXISTING, &createExParams);
++#endif /* !WINAPI_PARTITION_DESKTOP */
+ 			free(ws);
+ 			if (handle == INVALID_HANDLE_VALUE) {
+ 				la_dosmaperr(GetLastError());
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0008-Disable-program-call-with-stdin-stdout-usage-on-UWP-.patch
=====================================
@@ -0,0 +1,47 @@
+From 243b00a950c396850859822ceaf0056e4b8cf0bc Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Wed, 24 May 2023 15:14:33 +0200
+Subject: [PATCH 8/9] Disable program call with stdin/stdout usage on UWP
+ builds
+
+Some calls are not allowed:
+* WaitForInputIdle [1]
+* SetHandleInformation [2]
+* STARTF_XXX flags for CreateProcess are not allowed
+
+[1] https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-waitforinputidle#requirements
+[2] https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation#requirements
+---
+ libarchive/filter_fork_windows.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/libarchive/filter_fork_windows.c b/libarchive/filter_fork_windows.c
+index 6b0ed7df..e977c396 100644
+--- a/libarchive/filter_fork_windows.c
++++ b/libarchive/filter_fork_windows.c
+@@ -31,6 +31,7 @@
+ 
+ #include "filter_fork.h"
+ 
++#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ /* There are some editions of Windows ("nano server," for example) that
+  * do not host user32.dll. If we want to keep running on those editions,
+  * we need to delay-load WaitForInputIdle. */
+@@ -224,6 +225,14 @@ fail:
+ 	__archive_cmdline_free(acmd);
+ 	return ARCHIVE_FAILED;
+ }
++#else /* !WINAPI_PARTITION_DESKTOP */
++int
++__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
++{
++	(void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
++	return ARCHIVE_FAILED;
++}
++#endif /* !WINAPI_PARTITION_DESKTOP */
+ 
+ void
+ __archive_check_child(int in, int out)
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/0009-Use-Windows-bcrypt-when-enabled-and-building-for-Vis.patch
=====================================
@@ -0,0 +1,349 @@
+From 9817dab89dc01ea42e48e0fa38e721c63cc0bd5c Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 26 May 2023 11:58:48 +0200
+Subject: [PATCH 9/9] Use Windows bcrypt when enabled and building for Vista+
+
+The wincrypt API is deprecated and is not allowed in UWP builds.
+We can use the more modern bcrypt API which has equivalent calls.
+---
+ libarchive/archive_digest.c         | 60 +++++++++++++++++++++++++++++
+ libarchive/archive_digest_private.h | 10 +++++
+ libarchive/archive_random.c         | 28 +++++++++++++-
+ libarchive/archive_util.c           | 42 ++++++++++++++++++--
+ 4 files changed, 135 insertions(+), 5 deletions(-)
+
+diff --git a/libarchive/archive_digest.c b/libarchive/archive_digest.c
+index a7bd5f02..cd9b3f9d 100644
+--- a/libarchive/archive_digest.c
++++ b/libarchive/archive_digest.c
+@@ -36,6 +36,11 @@
+ #error Cannot use both OpenSSL and libmd.
+ #endif
+ 
++/* Common in other bcrypt implementations, but missing from VS2008. */
++#ifndef BCRYPT_SUCCESS
++#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
++#endif
++
+ /*
+  * Message digest functions for Windows platform.
+  */
+@@ -48,6 +53,26 @@
+ /*
+  * Initialize a Message digest.
+  */
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++static int
++win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
++{
++	NTSTATUS status;
++	ctx->valid = 0;
++
++	status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
++	if (!BCRYPT_SUCCESS(status))
++		return (ARCHIVE_FAILED);
++	status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
++	if (!BCRYPT_SUCCESS(status)) {
++		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
++		return (ARCHIVE_FAILED);
++	}
++
++	ctx->valid = 1;
++	return (ARCHIVE_OK);
++}
++#else
+ static int
+ win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+ {
+@@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+ 	ctx->valid = 1;
+ 	return (ARCHIVE_OK);
+ }
++#endif
+ 
+ /*
+  * Update a Message digest.
+@@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
+ 	if (!ctx->valid)
+ 		return (ARCHIVE_FAILED);
+ 
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	BCryptHashData(ctx->hHash,
++		      (PUCHAR)(uintptr_t)buf,
++		      len, 0);
++#else
+ 	CryptHashData(ctx->hash,
+ 		      (unsigned char *)(uintptr_t)buf,
+ 		      (DWORD)len, 0);
++#endif
+ 	return (ARCHIVE_OK);
+ }
+ 
+ static int
+ win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
+ {
++#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
+ 	DWORD siglen = (DWORD)bufsize;
++#endif
+ 
+ 	if (!ctx->valid)
+ 		return (ARCHIVE_FAILED);
+ 
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
++	BCryptDestroyHash(ctx->hHash);
++	BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
++#else
+ 	CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
+ 	CryptDestroyHash(ctx->hash);
+ 	CryptReleaseContext(ctx->cryptProv, 0);
++#endif
+ 	ctx->valid = 0;
+ 	return (ARCHIVE_OK);
+ }
+@@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
+ static int
+ __archive_md5init(archive_md5_ctx *ctx)
+ {
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++  return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
++#else
+   return (win_crypto_init(ctx, CALG_MD5));
++#endif
+ }
+ 
+ static int
+@@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
+ static int
+ __archive_sha1init(archive_sha1_ctx *ctx)
+ {
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++  return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
++#else
+   return (win_crypto_init(ctx, CALG_SHA1));
++#endif
+ }
+ 
+ static int
+@@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
+ static int
+ __archive_sha256init(archive_sha256_ctx *ctx)
+ {
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++  return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
++#else
+   return (win_crypto_init(ctx, CALG_SHA_256));
++#endif
+ }
+ 
+ static int
+@@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
+ static int
+ __archive_sha384init(archive_sha384_ctx *ctx)
+ {
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++  return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
++#else
+   return (win_crypto_init(ctx, CALG_SHA_384));
++#endif
+ }
+ 
+ static int
+@@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
+ static int
+ __archive_sha512init(archive_sha512_ctx *ctx)
+ {
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++  return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
++#else
+   return (win_crypto_init(ctx, CALG_SHA_512));
++#endif
+ }
+ 
+ static int
+diff --git a/libarchive/archive_digest_private.h b/libarchive/archive_digest_private.h
+index 9b3bd662..339b4edc 100644
+--- a/libarchive/archive_digest_private.h
++++ b/libarchive/archive_digest_private.h
+@@ -164,6 +164,15 @@
+   defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+   defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+   defined(ARCHIVE_CRYPTO_SHA512_WIN)
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++/* don't use bcrypt when XP needs to be supported */
++#include <bcrypt.h>
++typedef struct {
++  int   valid;
++  BCRYPT_ALG_HANDLE  hAlg;
++  BCRYPT_HASH_HANDLE hHash;
++} Digest_CTX;
++#else
+ #include <windows.h>
+ #include <wincrypt.h>
+ typedef struct {
+@@ -172,6 +181,7 @@ typedef struct {
+   HCRYPTHASH  hash;
+ } Digest_CTX;
+ #endif
++#endif
+ 
+ /* typedefs */
+ #if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+diff --git a/libarchive/archive_random.c b/libarchive/archive_random.c
+index 9d1aa493..57d57e10 100644
+--- a/libarchive/archive_random.c
++++ b/libarchive/archive_random.c
+@@ -58,9 +58,20 @@ static void arc4random_buf(void *, size_t);
+ #include "archive.h"
+ #include "archive_random_private.h"
+ 
+-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
++#if defined(_WIN32) && !defined(__CYGWIN__)
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++/* don't use bcrypt when XP needs to be supported */
++#include <bcrypt.h>
++
++/* Common in other bcrypt implementations, but missing from VS2008. */
++#ifndef BCRYPT_SUCCESS
++#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
++#endif
++
++#elif defined(HAVE_WINCRYPT_H)
+ #include <wincrypt.h>
+ #endif
++#endif
+ 
+ #ifndef O_CLOEXEC
+ #define O_CLOEXEC	0
+@@ -75,6 +86,20 @@ int
+ archive_random(void *buf, size_t nbytes)
+ {
+ #if defined(_WIN32) && !defined(__CYGWIN__)
++# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	NTSTATUS status;
++	BCRYPT_ALG_HANDLE hAlg;
++
++	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
++	if (!BCRYPT_SUCCESS(status))
++		return ARCHIVE_FAILED;
++	status = BCryptGenRandom(hAlg, buf, nbytes, 0);
++	BCryptCloseAlgorithmProvider(hAlg, 0);
++	if (!BCRYPT_SUCCESS(status))
++		return ARCHIVE_FAILED;
++
++	return ARCHIVE_OK;
++# else
+ 	HCRYPTPROV hProv;
+ 	BOOL success;
+ 
+@@ -92,6 +117,7 @@ archive_random(void *buf, size_t nbytes)
+ 	}
+ 	/* TODO: Does this case really happen? */
+ 	return ARCHIVE_FAILED;
++# endif
+ #else
+ 	arc4random_buf(buf, nbytes);
+ 	return ARCHIVE_OK;
+diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c
+index 17123b94..40603c48 100644
+--- a/libarchive/archive_util.c
++++ b/libarchive/archive_util.c
+@@ -42,9 +42,20 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
+ #ifdef HAVE_STRING_H
+ #include <string.h>
+ #endif
+-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
++#if defined(_WIN32) && !defined(__CYGWIN__)
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++/* don't use bcrypt when XP needs to be supported */
++#include <bcrypt.h>
++
++/* Common in other bcrypt implementations, but missing from VS2008. */
++#ifndef BCRYPT_SUCCESS
++#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
++#endif
++
++#elif defined(HAVE_WINCRYPT_H)
+ #include <wincrypt.h>
+ #endif
++#endif
+ #ifdef HAVE_ZLIB_H
+ #include <zlib.h>
+ #endif
+@@ -233,14 +244,16 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 		L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
+ 		L'u', L'v', L'w', L'x', L'y', L'z'
+ 	};
+-	HCRYPTPROV hProv;
+ 	struct archive_wstring temp_name;
+ 	wchar_t *ws;
+ 	DWORD attr;
+ 	wchar_t *xp, *ep;
+ 	int fd;
+-
+-	hProv = (HCRYPTPROV)NULL;
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	BCRYPT_ALG_HANDLE hAlg = NULL;
++#else
++	HCRYPTPROV hProv = (HCRYPTPROV)NULL;
++#endif
+ 	fd = -1;
+ 	ws = NULL;
+ 
+@@ -314,11 +327,19 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 			abort();
+ 	}
+ 
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
++		NULL, 0))) {
++		la_dosmaperr(GetLastError());
++		goto exit_tmpfile;
++	}
++#else
+ 	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ 		CRYPT_VERIFYCONTEXT)) {
+ 		la_dosmaperr(GetLastError());
+ 		goto exit_tmpfile;
+ 	}
++#endif
+ 
+ 	for (;;) {
+ 		wchar_t *p;
+@@ -329,11 +350,19 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 
+ 		/* Generate a random file name through CryptGenRandom(). */
+ 		p = xp;
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++		if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
++		    (DWORD)(ep - p)*sizeof(wchar_t), 0))) {
++			la_dosmaperr(GetLastError());
++			goto exit_tmpfile;
++		}
++#else
+ 		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
+ 		    (BYTE*)p)) {
+ 			la_dosmaperr(GetLastError());
+ 			goto exit_tmpfile;
+ 		}
++#endif
+ 		for (; p < ep; p++)
+ 			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
+ 
+@@ -387,8 +416,13 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
+ 			break;/* success! */
+ 	}
+ exit_tmpfile:
++#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
++	if (hAlg != NULL)
++		BCryptCloseAlgorithmProvider(hAlg, 0);
++#else
+ 	if (hProv != (HCRYPTPROV)NULL)
+ 		CryptReleaseContext(hProv, 0);
++#endif
+ 	free(ws);
+ 	if (template == temp_name.s)
+ 		archive_wstring_free(&temp_name);
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/libarchive/rules.mak
=====================================
@@ -1,6 +1,6 @@
 # LIBARCHIVE
 LIBARCHIVE_VERSION := 3.6.1
-LIBARCHIVE_URL := http://www.libarchive.org/downloads/libarchive-$(LIBARCHIVE_VERSION).tar.gz
+LIBARCHIVE_URL := $(GITHUB)/libarchive/libarchive/releases/download/v$(LIBARCHIVE_VERSION)/libarchive-$(LIBARCHIVE_VERSION).tar.gz
 
 PKGS += libarchive
 ifeq ($(call need_pkg,"libarchive >= 3.2.0"),)
@@ -8,14 +8,19 @@ PKGS_FOUND += libarchive
 endif
 
 DEPS_libarchive = zlib $(DEPS_zlib)
+ifdef HAVE_WINSTORE
+# libarchive uses CreateHardLinkW
+DEPS_libarchive += alloweduwp $(DEPS_alloweduwp)
+endif
 
 LIBARCHIVE_CONF := \
 		--disable-bsdcpio --disable-bsdtar --disable-bsdcat \
-		--without-nettle --without-cng \
+		--without-nettle \
 		--without-xml2 --without-lzma --without-iconv --without-expat
 
 ifdef HAVE_WIN32
-LIBARCHIVE_CONF += --without-openssl
+# CNG enables bcrypt on Windows and useless otherwise, it's OK we build for Win7+
+LIBARCHIVE_CONF += --without-openssl --with-cng
 endif
 
 $(TARBALLS)/libarchive-$(LIBARCHIVE_VERSION).tar.gz:
@@ -28,9 +33,15 @@ libarchive: libarchive-$(LIBARCHIVE_VERSION).tar.gz .sum-libarchive
 ifdef HAVE_ANDROID
 	$(APPLY) $(SRC)/libarchive/android.patch
 endif
-ifdef HAVE_WINSTORE
-	$(APPLY) $(SRC)/libarchive/winrt.patch
-endif
+	$(APPLY) $(SRC)/libarchive/0001-Use-CreateHardLinkW-and-CreateSymbolicLinkW-directly.patch
+	$(APPLY) $(SRC)/libarchive/0002-Disable-CreateSymbolicLinkW-use-in-UWP-builds.patch
+	$(APPLY) $(SRC)/libarchive/0003-fix-the-CreateHardLinkW-signature-to-match-the-real-.patch
+	$(APPLY) $(SRC)/libarchive/0004-Don-t-call-GetOEMCP-in-Universal-Windows-Platform-bu.patch
+	$(APPLY) $(SRC)/libarchive/0005-tests-use-CreateFileA-for-char-filenames.patch
+	$(APPLY) $(SRC)/libarchive/0006-Use-CreateFile2-instead-of-CreateFileW-on-Win8-build.patch
+	$(APPLY) $(SRC)/libarchive/0007-Disable-CreateFileA-calls-in-UWP-builds.patch
+	$(APPLY) $(SRC)/libarchive/0008-Disable-program-call-with-stdin-stdout-usage-on-UWP-.patch
+	$(APPLY) $(SRC)/libarchive/0009-Use-Windows-bcrypt-when-enabled-and-building-for-Vis.patch
 	$(call pkg_static,"build/pkgconfig/libarchive.pc.in")
 	$(MOVE)
 


=====================================
contrib/src/libarchive/winrt.patch deleted
=====================================
@@ -1,948 +0,0 @@
-From 2594486c32fd71ca63d0eea10b7266034f703eb0 Mon Sep 17 00:00:00 2001
-From: Steve Lhomme <robux4 at ycbcr.xyz>
-Date: Fri, 27 Mar 2020 16:25:36 +0100
-Subject: [PATCH] WIP fix compilation for Universal Windows
-
----
- libarchive/archive_digest.c                   | 50 +++++++++++-
- libarchive/archive_digest_private.h           |  9 +++
- libarchive/archive_random.c                   |  7 ++
- libarchive/archive_read_disk_windows.c        | 80 +++++++++++++++++++
- .../archive_read_support_filter_bzip2.c       |  4 +
- .../archive_read_support_filter_grzip.c       |  4 +
- .../archive_read_support_filter_lrzip.c       |  4 +
- libarchive/archive_read_support_filter_lz4.c  |  4 +
- libarchive/archive_read_support_filter_lzop.c |  4 +
- .../archive_read_support_filter_program.c     | 12 ++-
- libarchive/archive_read_support_filter_xz.c   | 12 +++
- libarchive/archive_read_support_filter_zstd.c |  4 +
- .../archive_read_support_format_mtree.c       | 10 +++
- libarchive/archive_string.c                   |  2 +-
- libarchive/archive_util.c                     |  9 ++-
- libarchive/archive_windows.c                  | 31 ++++++-
- libarchive/archive_windows.h                  |  4 +
- libarchive/archive_write_disk_windows.c       | 78 ++++++++++++++++++
- libarchive/filter_fork_windows.c              |  8 ++
- 19 files changed, 327 insertions(+), 9 deletions(-)
-
-diff --git a/libarchive/archive_digest.c b/libarchive/archive_digest.c
-index a7bd5f02..02dd27ee 100644
---- a/libarchive/archive_digest.c
-+++ b/libarchive/archive_digest.c
-@@ -48,6 +48,19 @@
- /*
-  * Initialize a Message digest.
-  */
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+static int
-+win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
-+{
-+	ctx->valid = 0;
-+
-+	BCryptOpenAlgorithmProvider(&ctx->algo_handle, algo, NULL, 0);
-+	BCryptCreateHash(ctx->algo_handle, &ctx->hash, NULL, 0, NULL, 0, 0);
-+
-+	ctx->valid = 1;
-+	return (ARCHIVE_OK);
-+}
-+#else
- static int
- win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
- {
-@@ -70,6 +83,7 @@ win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
- 	ctx->valid = 1;
- 	return (ARCHIVE_OK);
- }
-+#endif
- 
- /*
-  * Update a Message digest.
-@@ -81,23 +95,35 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
- 	if (!ctx->valid)
- 		return (ARCHIVE_FAILED);
- 
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+	BCryptHashData(ctx->hash,
-+		      (PUCHAR) buf,
-+		      len, 0);
-+#else
- 	CryptHashData(ctx->hash,
- 		      (unsigned char *)(uintptr_t)buf,
- 		      (DWORD)len, 0);
-+#endif
- 	return (ARCHIVE_OK);
- }
- 
- static int
- win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
- {
--	DWORD siglen = (DWORD)bufsize;
--
- 	if (!ctx->valid)
- 		return (ARCHIVE_FAILED);
- 
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+	BCryptFinishHash(ctx->hash, buf, (ULONG)bufsize, 0);
-+	BCryptDestroyHash(ctx->hash);
-+	BCryptCloseAlgorithmProvider(ctx->algo_handle, 0);
-+#else
-+	DWORD siglen = (DWORD)bufsize;
-+
- 	CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- 	CryptDestroyHash(ctx->hash);
- 	CryptReleaseContext(ctx->cryptProv, 0);
-+#endif
- 	ctx->valid = 0;
- 	return (ARCHIVE_OK);
- }
-@@ -276,7 +302,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
- static int
- __archive_md5init(archive_md5_ctx *ctx)
- {
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
-+#else
-   return (win_crypto_init(ctx, CALG_MD5));
-+#endif
- }
- 
- static int
-@@ -659,7 +689,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
- static int
- __archive_sha1init(archive_sha1_ctx *ctx)
- {
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
-+#else
-   return (win_crypto_init(ctx, CALG_SHA1));
-+#endif
- }
- 
- static int
-@@ -919,7 +953,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
- static int
- __archive_sha256init(archive_sha256_ctx *ctx)
- {
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
-+#else
-   return (win_crypto_init(ctx, CALG_SHA_256));
-+#endif
- }
- 
- static int
-@@ -1155,7 +1193,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
- static int
- __archive_sha384init(archive_sha384_ctx *ctx)
- {
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
-+#else
-   return (win_crypto_init(ctx, CALG_SHA_384));
-+#endif
- }
- 
- static int
-@@ -1415,7 +1457,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
- static int
- __archive_sha512init(archive_sha512_ctx *ctx)
- {
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
-+#else
-   return (win_crypto_init(ctx, CALG_SHA_512));
-+#endif
- }
- 
- static int
-diff --git a/libarchive/archive_digest_private.h b/libarchive/archive_digest_private.h
-index 9b3bd662..8082059c 100644
---- a/libarchive/archive_digest_private.h
-+++ b/libarchive/archive_digest_private.h
-@@ -165,11 +165,20 @@
-   defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
-   defined(ARCHIVE_CRYPTO_SHA512_WIN)
- #include <windows.h>
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+#include <bcrypt.h>
-+#else
- #include <wincrypt.h>
-+#endif
- typedef struct {
-   int   valid;
-+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+  BCRYPT_ALG_HANDLE  algo_handle;
-+  BCRYPT_HASH_HANDLE hash;
-+#else
-   HCRYPTPROV  cryptProv;
-   HCRYPTHASH  hash;
-+#endif
- } Digest_CTX;
- #endif
- 
-diff --git a/libarchive/archive_random.c b/libarchive/archive_random.c
-index 9d1aa493..e63ffbfa 100644
---- a/libarchive/archive_random.c
-+++ b/libarchive/archive_random.c
-@@ -75,6 +75,12 @@ int
- archive_random(void *buf, size_t nbytes)
- {
- #if defined(_WIN32) && !defined(__CYGWIN__)
-+# if _WIN32_WINNT >= _WIN32_WINNT_VISTA
-+	BCRYPT_ALG_HANDLE algo_handle;
-+	BCryptOpenAlgorithmProvider(&algo_handle, BCRYPT_RNG_ALGORITHM, NULL, 0);
-+	BCryptGenRandom(algo_handle, buf, nbytes, 0);
-+	BCryptCloseAlgorithmProvider(algo_handle, 0);
-+# else
- 	HCRYPTPROV hProv;
- 	BOOL success;
- 
-@@ -92,6 +98,7 @@ archive_random(void *buf, size_t nbytes)
- 	}
- 	/* TODO: Does this case really happen? */
- 	return ARCHIVE_FAILED;
-+# endif
- #else
- 	arc4random_buf(buf, nbytes);
- 	return ARCHIVE_OK;
-diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c
-index ea32e2aa..7dd2e8a8 100644
---- a/libarchive/archive_read_disk_windows.c
-+++ b/libarchive/archive_read_disk_windows.c
-@@ -418,8 +418,19 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
- 	    FILE_FLAG_OPEN_REPARSE_POINT;
- 	int ret;
- 
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+	createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+	createExParams.dwFileAttributes = 0;
-+	createExParams.dwFileFlags = flag;
-+	createExParams.dwSecurityQosFlags = 0;
-+	createExParams.lpSecurityAttributes = NULL;
-+	createExParams.hTemplateFile = NULL;
-+	h = CreateFile2(path, 0, FILE_SHARE_READ, OPEN_EXISTING, &createExParams);
-+#else
- 	h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
- 	    NULL);
-+#endif
- 	if (h == INVALID_HANDLE_VALUE) {
- 		la_dosmaperr(GetLastError());
- 		return (-1);
-@@ -707,7 +718,11 @@ start_next_async_read(struct archive_read_disk *a, struct tree *t)
- 	if (olp->buff == NULL) {
- 		void *p;
- 		size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE);
-+#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- 		p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
-+#else /* !WINAPI_PARTITION_DESKTOP */
-+		p = VirtualAllocFromApp(NULL, s, MEM_COMMIT, PAGE_READWRITE);
-+#endif /* !WINAPI_PARTITION_DESKTOP */
- 		if (p == NULL) {
- 			archive_set_error(&a->archive, ENOMEM,
- 			    "Couldn't allocate memory");
-@@ -1072,8 +1087,20 @@ next_entry(struct archive_read_disk *a, struct tree *t,
- 			flags |= FILE_FLAG_NO_BUFFERING;
- 		else
- 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
-+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+		createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+		createExParams.dwFileAttributes = 0;
-+		createExParams.dwFileFlags = flags;
-+		createExParams.dwSecurityQosFlags = 0;
-+		createExParams.lpSecurityAttributes = NULL;
-+		createExParams.hTemplateFile = NULL;
-+		t->entry_fh = CreateFile2(tree_current_access_path(t),
-+			GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &createExParams);
-+#else
- 		t->entry_fh = CreateFileW(tree_current_access_path(t),
- 		    GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
-+#endif
- 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
- 			la_dosmaperr(GetLastError());
- 			archive_set_error(&a->archive, errno,
-@@ -1506,7 +1533,12 @@ setup_current_filesystem(struct archive_read_disk *a)
- 
- 	t->current_filesystem->synthetic = -1;/* Not supported */
- 	path = safe_path_for_statfs(t);
-+#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- 	if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
-+#else /* !WINAPI_PARTITION_DESKTOP */
-+	DWORD MaximumComponentLength, FileSystemFlags;
-+	if (!GetVolumeInformationW(path, vol, sizeof(vol)/sizeof(vol[0]), NULL, &MaximumComponentLength, &FileSystemFlags, NULL, 0)) {
-+#endif
- 		free(path);
- 		t->current_filesystem->remote = -1;
- 		t->current_filesystem->bytesPerSector = 0;
-@@ -1557,8 +1589,20 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
- 	if ((t->flags & needsRestoreTimes) == 0)
- 		return (r);
- 
-+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+	createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+	createExParams.dwFileAttributes = FILE_SHARE_READ;
-+	createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
-+	createExParams.dwSecurityQosFlags = 0;
-+	createExParams.lpSecurityAttributes = NULL;
-+	createExParams.hTemplateFile = NULL;
-+	handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
-+		    0, OPEN_EXISTING, &createExParams);
-+#else
- 	handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
- 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-+#endif
- 	if (handle == INVALID_HANDLE_VALUE) {
- 		errno = EINVAL;
- 		return (-1);
-@@ -2046,8 +2090,20 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
- 	
- 	if (sim_lstat && tree_current_is_physical_link(t))
- 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+	createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+	createExParams.dwFileAttributes = 0;
-+	createExParams.dwFileFlags = flag;
-+	createExParams.dwSecurityQosFlags = 0;
-+	createExParams.lpSecurityAttributes = NULL;
-+	createExParams.hTemplateFile = NULL;
-+	h = CreateFile2(tree_current_access_path(t), 0, FILE_SHARE_READ,
-+	    OPEN_EXISTING, &createExParams);
-+#else
- 	h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
- 	    OPEN_EXISTING, flag, NULL);
-+#endif
- 	if (h == INVALID_HANDLE_VALUE) {
- 		la_dosmaperr(GetLastError());
- 		t->tree_errno = errno;
-@@ -2275,8 +2331,20 @@ archive_read_disk_entry_from_file(struct archive *_a,
- 			} else
- 				desiredAccess = GENERIC_READ;
- 
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+			createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+			createExParams.dwFileAttributes = 0;
-+			createExParams.dwFileFlags = flag;
-+			createExParams.dwSecurityQosFlags = 0;
-+			createExParams.lpSecurityAttributes = NULL;
-+			createExParams.hTemplateFile = NULL;
-+			h = CreateFile2(path, desiredAccess, FILE_SHARE_READ,
-+			    OPEN_EXISTING, &createExParams);
-+#else
- 			h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
- 			    OPEN_EXISTING, flag, NULL);
-+#endif
- 			if (h == INVALID_HANDLE_VALUE) {
- 				la_dosmaperr(GetLastError());
- 				archive_set_error(&a->archive, errno,
-@@ -2337,8 +2405,20 @@ archive_read_disk_entry_from_file(struct archive *_a,
- 		if (fd >= 0) {
- 			h = (HANDLE)_get_osfhandle(fd);
- 		} else {
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+			createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+			createExParams.dwFileAttributes = 0;
-+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
-+			createExParams.dwSecurityQosFlags = 0;
-+			createExParams.lpSecurityAttributes = NULL;
-+			createExParams.hTemplateFile = NULL;
-+			h = CreateFile2(path, GENERIC_READ, FILE_SHARE_READ,
-+			    OPEN_EXISTING, &createExParams);
-+#else
- 			h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
- 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-+#endif
- 			if (h == INVALID_HANDLE_VALUE) {
- 				la_dosmaperr(GetLastError());
- 				archive_set_error(&a->archive, errno,
-diff --git a/libarchive/archive_read_support_filter_bzip2.c b/libarchive/archive_read_support_filter_bzip2.c
-index 793d605c..57a84eba 100644
---- a/libarchive/archive_read_support_filter_bzip2.c
-+++ b/libarchive/archive_read_support_filter_bzip2.c
-@@ -159,6 +159,7 @@ bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_fi
- static int
- bzip2_reader_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "bzip2 -d");
-@@ -168,6 +169,9 @@ bzip2_reader_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_BZIP2;
- 	self->name = "bzip2";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- 
-diff --git a/libarchive/archive_read_support_filter_grzip.c b/libarchive/archive_read_support_filter_grzip.c
-index d4d1737c..7660b392 100644
---- a/libarchive/archive_read_support_filter_grzip.c
-+++ b/libarchive/archive_read_support_filter_grzip.c
-@@ -100,6 +100,7 @@ grzip_bidder_bid(struct archive_read_filter_bidder *self,
- static int
- grzip_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "grzip -d");
-@@ -109,4 +110,7 @@ grzip_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_GRZIP;
- 	self->name = "grzip";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
-diff --git a/libarchive/archive_read_support_filter_lrzip.c b/libarchive/archive_read_support_filter_lrzip.c
-index a2389894..562e37e0 100644
---- a/libarchive/archive_read_support_filter_lrzip.c
-+++ b/libarchive/archive_read_support_filter_lrzip.c
-@@ -110,6 +110,7 @@ lrzip_bidder_bid(struct archive_read_filter_bidder *self,
- static int
- lrzip_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "lrzip -d -q");
-@@ -119,4 +120,7 @@ lrzip_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_LRZIP;
- 	self->name = "lrzip";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
-diff --git a/libarchive/archive_read_support_filter_lz4.c b/libarchive/archive_read_support_filter_lz4.c
-index ae0b0800..3f7fc14e 100644
---- a/libarchive/archive_read_support_filter_lz4.c
-+++ b/libarchive/archive_read_support_filter_lz4.c
-@@ -194,6 +194,7 @@ lz4_reader_bid(struct archive_read_filter_bidder *self,
- static int
- lz4_reader_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "lz4 -d -q");
-@@ -203,6 +204,9 @@ lz4_reader_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_LZ4;
- 	self->name = "lz4";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- 
-diff --git a/libarchive/archive_read_support_filter_lzop.c b/libarchive/archive_read_support_filter_lzop.c
-index afd2d4d0..7dd80c0b 100644
---- a/libarchive/archive_read_support_filter_lzop.c
-+++ b/libarchive/archive_read_support_filter_lzop.c
-@@ -158,6 +158,7 @@ lzop_bidder_bid(struct archive_read_filter_bidder *self,
- static int
- lzop_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "lzop -d");
-@@ -167,6 +168,9 @@ lzop_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_LZOP;
- 	self->name = "lzop";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- #else
- 
-diff --git a/libarchive/archive_read_support_filter_program.c b/libarchive/archive_read_support_filter_program.c
-index 885b2c20..4015cea2 100644
---- a/libarchive/archive_read_support_filter_program.c
-+++ b/libarchive/archive_read_support_filter_program.c
-@@ -82,6 +82,8 @@ archive_read_support_filter_program(struct archive *a, const char *cmd)
- 	return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
- }
- 
-+ #if !defined(_WIN32) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-+
- /*
-  * The bidder object stores the command and the signature to watch for.
-  * The 'inhibit' entry here is used to ensure that unchecked filters never
-@@ -105,7 +107,7 @@ static void	program_bidder_free(struct archive_read_filter_bidder *);
-  */
- struct program_filter {
- 	struct archive_string description;
--#if defined(_WIN32) && !defined(__CYGWIN__)
-+#if defined(_WIN32) && !defined(__CYGWIN__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	HANDLE		 child;
- #else
- 	pid_t		 child;
-@@ -243,7 +245,7 @@ child_stop(struct archive_read_filter *self, struct program_filter *state)
- 			state->waitpid_return
- 			    = waitpid(state->child, &state->exit_status, 0);
- 		} while (state->waitpid_return == -1 && errno == EINTR);
--#if defined(_WIN32) && !defined(__CYGWIN__)
-+#if defined(_WIN32) && !defined(__CYGWIN__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 		CloseHandle(state->child);
- #endif
- 		state->child = 0;
-@@ -298,7 +300,7 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
- 	struct program_filter *state = self->data;
- 	ssize_t ret, requested, avail;
- 	const char *p;
--#if defined(_WIN32) && !defined(__CYGWIN__)
-+#if defined(_WIN32) && !defined(__CYGWIN__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	HANDLE handle = (HANDLE)_get_osfhandle(state->child_stdout);
- #endif
- 
-@@ -306,7 +308,7 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
- 
- 	for (;;) {
- 		do {
--#if defined(_WIN32) && !defined(__CYGWIN__)
-+#if defined(_WIN32) && !defined(__CYGWIN__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 			/* Avoid infinity wait.
- 			 * Note: If there is no data in the pipe, ReadFile()
- 			 * called in read() never returns and so we won't
-@@ -494,3 +496,5 @@ program_filter_close(struct archive_read_filter *self)
- 
- 	return (e);
- }
-+
-+#endif // !_WIN32 || WINAPI_PARTITION_DESKTOP
-diff --git a/libarchive/archive_read_support_filter_xz.c b/libarchive/archive_read_support_filter_xz.c
-index 32ae0be9..a521548f 100644
---- a/libarchive/archive_read_support_filter_xz.c
-+++ b/libarchive/archive_read_support_filter_xz.c
-@@ -749,6 +749,7 @@ xz_filter_close(struct archive_read_filter *self)
- static int
- lzma_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "lzma -d -qq");
-@@ -758,11 +759,15 @@ lzma_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_LZMA;
- 	self->name = "lzma";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- static int
- xz_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "xz -d -qq");
-@@ -772,11 +777,15 @@ xz_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_XZ;
- 	self->name = "xz";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- static int
- lzip_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "lzip -d -q");
-@@ -786,6 +795,9 @@ lzip_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_LZIP;
- 	self->name = "lzip";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- #endif /* HAVE_LZMA_H */
-diff --git a/libarchive/archive_read_support_filter_zstd.c b/libarchive/archive_read_support_filter_zstd.c
-index 39f25f1b..15bec661 100644
---- a/libarchive/archive_read_support_filter_zstd.c
-+++ b/libarchive/archive_read_support_filter_zstd.c
-@@ -144,6 +144,7 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
- static int
- zstd_bidder_init(struct archive_read_filter *self)
- {
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- 	int r;
- 
- 	r = __archive_read_program(self, "zstd -d -qq");
-@@ -153,6 +154,9 @@ zstd_bidder_init(struct archive_read_filter *self)
- 	self->code = ARCHIVE_FILTER_ZSTD;
- 	self->name = "zstd";
- 	return (r);
-+#else
-+    return ARCHIVE_FATAL;
-+#endif
- }
- 
- #else
-diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
-index 4a281632..e398625a 100644
---- a/libarchive/archive_read_support_format_mtree.c
-+++ b/libarchive/archive_read_support_format_mtree.c
-@@ -58,6 +58,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
- #include "archive_string.h"
- #include "archive_pack_dev.h"
- 
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-+
- #ifndef O_BINARY
- #define	O_BINARY 0
- #endif
-@@ -2138,3 +2140,11 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
- 		find_off = u - mtree->line.s;
- 	}
- }
-+
-+#else
-+int
-+archive_read_support_format_mtree(struct archive *_a)
-+{
-+    return ARCHIVE_OK;
-+}
-+#endif
-diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
-index d7f2c46b..60daeafe 100644
---- a/libarchive/archive_string.c
-+++ b/libarchive/archive_string.c
-@@ -1323,7 +1323,7 @@ free_sconv_object(struct archive_string_conv *sc)
- 	free(sc);
- }
- 
--#if defined(_WIN32) && !defined(__CYGWIN__)
-+#if defined(_WIN32) && !defined(__CYGWIN__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- static unsigned
- my_atoi(const char *p)
- {
-diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c
-index b1582edb..2efff38a 100644
---- a/libarchive/archive_util.c
-+++ b/libarchive/archive_util.c
-@@ -209,7 +209,7 @@ __archive_errx(int retvalue, const char *msg)
-  * Create a temporary file
-  */
- #if defined(_WIN32) && !defined(__CYGWIN__)
--
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- /*
-  * Do not use Windows tmpfile() function.
-  * It will make a temporary file under the root directory
-@@ -379,6 +379,13 @@ exit_tmpfile:
- 		archive_wstring_free(&temp_name);
- 	return (fd);
- }
-+#else
-+int
-+__archive_mktempx(const char *tmpdir, wchar_t *template)
-+{
-+    return -1;
-+}
-+#endif
- 
- int
- __archive_mktemp(const char *tmpdir)
-diff --git a/libarchive/archive_windows.c b/libarchive/archive_windows.c
-index 624e2700..ede0269a 100644
---- a/libarchive/archive_windows.c
-+++ b/libarchive/archive_windows.c
-@@ -235,6 +235,7 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
- 	wchar_t *wpath;
- 	HANDLE handle;
- 
-+#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
- 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- 	    hTemplateFile);
-@@ -249,6 +250,20 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
- 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- 	    hTemplateFile);
- 	free(wpath);
-+#else /* !WINAPI_PARTITION_DESKTOP */
-+	wpath = __la_win_permissive_name(path);
-+	if (wpath == NULL)
-+		return INVALID_HANDLE_VALUE;
-+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+	createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+	createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
-+	createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
-+	createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
-+	createExParams.lpSecurityAttributes = lpSecurityAttributes;
-+	createExParams.hTemplateFile = hTemplateFile;
-+	handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode, dwCreationDisposition, &createExParams);
-+	free(wpath);
-+#endif /* !WINAPI_PARTITION_DESKTOP */
- 	return (handle);
- }
- 
-@@ -320,7 +335,7 @@ __la_open(const char *path, int flags, ...)
- 		}
- 		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
- 			HANDLE handle;
--
-+#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
- 			if (ws != NULL)
- 				handle = CreateFileW(ws, 0, 0, NULL,
- 				    OPEN_EXISTING,
-@@ -333,6 +348,20 @@ __la_open(const char *path, int flags, ...)
- 				    FILE_FLAG_BACKUP_SEMANTICS |
- 				    FILE_ATTRIBUTE_READONLY,
- 					NULL);
-+#else /* !WINAPI_PARTITION_DESKTOP */
-+			if (ws != NULL) {
-+				CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+				createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+				createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
-+				createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
-+				createExParams.dwSecurityQosFlags = 0;
-+				createExParams.lpSecurityAttributes = NULL;
-+				createExParams.hTemplateFile = NULL;
-+				handle = CreateFile2(ws, 0, 0, OPEN_EXISTING, &createExParams);
-+			}
-+			else
-+				handle = INVALID_HANDLE_VALUE;
-+#endif /* !WINAPI_PARTITION_DESKTOP */
- 			free(ws);
- 			if (handle == INVALID_HANDLE_VALUE) {
- 				la_dosmaperr(GetLastError());
-diff --git a/libarchive/archive_windows.h b/libarchive/archive_windows.h
-index 47b7cb8e..4aad8199 100644
---- a/libarchive/archive_windows.h
-+++ b/libarchive/archive_windows.h
-@@ -106,9 +106,11 @@
- #define	lseek		__la_lseek
- #define __LA_LSEEK_NEEDED
- #endif
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- #define	lstat		__la_stat
- #define	open		__la_open
- #define	read		__la_read
-+#endif
- #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
- #define setmode		_setmode
- #endif
-@@ -276,8 +278,10 @@ extern int	 __la_stat(const char *path, struct stat *st);
- extern pid_t	 __la_waitpid(HANDLE child, int *status, int option);
- extern ssize_t	 __la_write(int fd, const void *buf, size_t nbytes);
- 
-+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- #define _stat64i32(path, st)	__la_stat(path, st)
- #define _stat64(path, st)	__la_stat(path, st)
-+#endif
- /* for status returned by la_waitpid */
- #define WIFEXITED(sts)		((sts & 0x100) == 0)
- #define WEXITSTATUS(sts)	(sts & 0x0FF)
-diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c
-index 1b12a299..f90861b0 100644
---- a/libarchive/archive_write_disk_windows.c
-+++ b/libarchive/archive_write_disk_windows.c
-@@ -290,14 +290,31 @@ file_information(struct archive_write_disk *a, wchar_t *path,
- 		(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
- 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
- 
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+	createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+	createExParams.dwFileAttributes = 0;
-+	createExParams.dwFileFlags = flag;
-+	createExParams.dwSecurityQosFlags = 0;
-+	createExParams.lpSecurityAttributes = NULL;
-+	createExParams.hTemplateFile = NULL;
-+	h = CreateFile2(a->name, 0, 0,
-+		OPEN_EXISTING, &createExParams);
-+#else
- 	h = CreateFileW(a->name, 0, 0, NULL,
- 	    OPEN_EXISTING, flag, NULL);
-+#endif
- 	if (h == INVALID_HANDLE_VALUE &&
- 	    GetLastError() == ERROR_INVALID_NAME) {
- 		wchar_t *full;
- 		full = __la_win_permissive_name_w(path);
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+		h = CreateFile2(full, 0, 0,
-+			OPEN_EXISTING, &createExParams);
-+#else
- 		h = CreateFileW(full, 0, 0, NULL,
- 		    OPEN_EXISTING, flag, NULL);
-+#endif
- 		free(full);
- 	}
- 	if (h == INVALID_HANDLE_VALUE) {
-@@ -559,6 +576,7 @@ la_mktemp(struct archive_write_disk *a)
- 	return (fd);
- }
- 
-+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
- static void *
- la_GetFunctionKernel32(const char *name)
- {
-@@ -574,6 +592,7 @@ la_GetFunctionKernel32(const char *name)
- 	}
- 	return (void *)GetProcAddress(lib, name);
- }
-+#endif
- 
- static int
- la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
-@@ -582,10 +601,19 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
- 	static int set;
- 	BOOL ret;
- 
-+#if _WIN32_WINNT < _WIN32_WINNT_XP
-+/* CreateHardLinkW is available since XP and always loaded */
- 	if (!set) {
- 		set = 1;
- 		f = la_GetFunctionKernel32("CreateHardLinkW");
- 	}
-+#else
-+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-+	f = CreateHardLinkW;
-+# else
-+	f = NULL;
-+# endif
-+#endif
- 	if (!f) {
- 		errno = ENOTSUP;
- 		return (0);
-@@ -632,10 +660,19 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
- 	DWORD newflags = 0;
- 	BOOL ret = 0;
- 
-+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
-+/* CreateSymbolicLinkW is available since Vista and always loaded */
- 	if (!set) {
- 		set = 1;
- 		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
- 	}
-+#else
-+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-+	f = CreateSymbolicLinkW;
-+# else
-+	f = NULL;
-+# endif
-+#endif
- 	if (!f)
- 		return (0);
- 
-@@ -1718,8 +1755,20 @@ create_filesystem_object(struct archive_write_disk *a)
- 			a->todo = 0;
- 			a->deferred = 0;
- 		} else if (r == 0 && a->filesize > 0) {
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+			createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-+			createExParams.dwFileFlags = 0;
-+			createExParams.dwSecurityQosFlags = 0;
-+			createExParams.lpSecurityAttributes = NULL;
-+			createExParams.hTemplateFile = NULL;
-+			a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
-+			    TRUNCATE_EXISTING, &createExParams);
-+#else
- 			a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
- 			    TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-+#endif
- 			if (a->fh == INVALID_HANDLE_VALUE) {
- 				la_dosmaperr(GetLastError());
- 				r = errno;
-@@ -1782,14 +1831,31 @@ create_filesystem_object(struct archive_write_disk *a)
- 		a->tmpname = NULL;
- 		fullname = a->name;
- 		/* O_WRONLY | O_CREAT | O_EXCL */
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+		createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+		createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-+		createExParams.dwFileFlags = 0;
-+		createExParams.dwSecurityQosFlags = 0;
-+		createExParams.lpSecurityAttributes = NULL;
-+		createExParams.hTemplateFile = NULL;
-+		a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
-+		    CREATE_NEW, &createExParams);
-+#else
- 		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
- 		    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
-+#endif
- 		if (a->fh == INVALID_HANDLE_VALUE &&
- 		    GetLastError() == ERROR_INVALID_NAME &&
- 		    fullname == a->name) {
- 			fullname = __la_win_permissive_name_w(a->name);
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+			a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
-+			    CREATE_NEW, &createExParams);
-+#else
- 			a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
- 			    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
-+#endif
- 		}
- 		if (a->fh == INVALID_HANDLE_VALUE) {
- 			if (GetLastError() == ERROR_ACCESS_DENIED) {
-@@ -2551,8 +2617,20 @@ set_times(struct archive_write_disk *a,
- 		ws = __la_win_permissive_name_w(name);
- 		if (ws == NULL)
- 			goto settimes_failed;
-+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
-+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
-+		createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-+		createExParams.dwFileAttributes = 0;
-+		createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
-+		createExParams.dwSecurityQosFlags = 0;
-+		createExParams.lpSecurityAttributes = NULL;
-+		createExParams.hTemplateFile = NULL;
-+		hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
-+		    OPEN_EXISTING, &createExParams);
-+#else
- 		hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
- 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-+#endif
- 		free(ws);
- 		if (hw == INVALID_HANDLE_VALUE)
- 			goto settimes_failed;
-diff --git a/libarchive/filter_fork_windows.c b/libarchive/filter_fork_windows.c
-index 0b963975..fc9c0f55 100644
---- a/libarchive/filter_fork_windows.c
-+++ b/libarchive/filter_fork_windows.c
-@@ -31,6 +31,13 @@
- 
- #include "filter_fork.h"
- 
-+#if !WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
-+int
-+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
-+{
-+	return ARCHIVE_FAILED;
-+}
-+#else /* WINAPI_PARTITION_DESKTOP */
- /* There are some editions of Windows ("nano server," for example) that
-  * do not host user32.dll. If we want to keep running on those editions,
-  * we need to delay-load WaitForInputIdle. */
-@@ -224,6 +231,7 @@ fail:
- 	__archive_cmdline_free(acmd);
- 	return ARCHIVE_FAILED;
- }
-+#endif /* WINAPI_PARTITION_DESKTOP */
- 
- void
- __archive_check_child(int in, int out)
--- 
-2.37.3.windows.1
-


=====================================
contrib/src/mingw64/0001-headers-enable-CreateHardLinkW-in-Win10-UWP-builds.patch
=====================================
@@ -0,0 +1,36 @@
+From dd4f835601548529980550ddb0a66a7c8881ce9b Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Thu, 25 May 2023 09:44:35 +0200
+Subject: [PATCH] headers: enable CreateHardLinkW in Win10 UWP builds
+
+The documentation doesn't say it's allowed, but the WIndows SDK allow it and
+the Windows App Certification as well.
+
+The official page for allowed API's also doesn't say it's allowed [1]
+but the DLL that contains it is there.
+
+[1] https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-file-l2-1-0dll
+---
+ mingw-w64-headers/include/winbase.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/mingw-w64-headers/include/winbase.h b/mingw-w64-headers/include/winbase.h
+index 82c8b7cc3..94f5df309 100644
+--- a/mingw-w64-headers/include/winbase.h
++++ b/mingw-w64-headers/include/winbase.h
+@@ -2464,9 +2464,11 @@ typedef enum FILE_FLUSH_MODE {
+   WINBASEAPI WINBOOL WINAPI ReplaceFileA (LPCSTR lpReplacedFileName, LPCSTR lpReplacementFileName, LPCSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved);
+   WINBASEAPI WINBOOL WINAPI ReplaceFileW (LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileName, LPCWSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved);
+ #endif
++#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) || _WIN32_WINNT >= _WIN32_WINNT_WIN10
++  WINBASEAPI WINBOOL WINAPI CreateHardLinkW (LPCWSTR lpFileName, LPCWSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
++#endif
+ #if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+   WINBASEAPI WINBOOL WINAPI CreateHardLinkA (LPCSTR lpFileName, LPCSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+-  WINBASEAPI WINBOOL WINAPI CreateHardLinkW (LPCWSTR lpFileName, LPCWSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ 
+ #define ReplaceFile __MINGW_NAME_AW(ReplaceFile)
+ #define CreateHardLink __MINGW_NAME_AW(CreateHardLink)
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/mingw64/0001-headers-enable-GetVolumePathNameW-in-Win10-UWP-build.patch
=====================================
@@ -0,0 +1,39 @@
+From de5009b7952c6c74511facef02c3d21855b4ee0e Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Sat, 27 May 2023 11:52:25 +0200
+Subject: [PATCH] headers: enable GetVolumePathNameW in Win10 UWP builds
+
+The documentation doesn't say it's allowed, but the WIndows SDK allow it and
+the Windows App Certification as well.
+
+The official page for allowed API's also doesn't say it's allowed [1]
+but the DLL that contains it is there.
+
+[1] https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-file-l2-1-0dll
+---
+ mingw-w64-headers/include/fileapi.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mingw-w64-headers/include/fileapi.h b/mingw-w64-headers/include/fileapi.h
+index 8ea09f6c9..e9e0c647f 100644
+--- a/mingw-w64-headers/include/fileapi.h
++++ b/mingw-w64-headers/include/fileapi.h
+@@ -81,6 +81,7 @@ WINBASEAPI DWORD WINAPI SetFilePointer (HANDLE hFile, LONG lDistanceToMove, PLON
+   WINBASEAPI DWORD WINAPI GetFullPathNameA (LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, LPSTR *lpFilePart);
+   WINBASEAPI DWORD WINAPI GetFullPathNameW (LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart);
+   WINBASEAPI DWORD WINAPI GetLogicalDrives (VOID);
++  WINBASEAPI WINBOOL WINAPI GetVolumePathNameW (LPCWSTR lpszFileName, LPWSTR lpszVolumePathName, DWORD cchBufferLength);
+ #define FindFirstFile __MINGW_NAME_AW(FindFirstFile)
+ #define GetDiskFreeSpace __MINGW_NAME_AW(GetDiskFreeSpace)
+ #define GetDriveType __MINGW_NAME_AW(GetDriveType)
+@@ -89,7 +90,6 @@ WINBASEAPI DWORD WINAPI SetFilePointer (HANDLE hFile, LONG lDistanceToMove, PLON
+ #if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+   WINBASEAPI DWORD WINAPI GetLogicalDriveStringsW (DWORD nBufferLength, LPWSTR lpBuffer);
+   WINBASEAPI DWORD WINAPI GetShortPathNameW (LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer);
+-  WINBASEAPI WINBOOL WINAPI GetVolumePathNameW (LPCWSTR lpszFileName, LPWSTR lpszVolumePathName, DWORD cchBufferLength);
+   WINBASEAPI DWORD WINAPI QueryDosDeviceW (LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax);
+   WINBASEAPI WINBOOL WINAPI ReadFileScatter (HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[], DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped);
+   WINBASEAPI WINBOOL WINAPI SetFileValidData (HANDLE hFile, LONGLONG ValidDataLength);
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/mingw64/rules.mak
=====================================
@@ -58,6 +58,8 @@ mingw64: mingw-w64-v$(MINGW64_VERSION).tar.bz2 .sum-mingw64
 	$(UNPACK)
 	$(APPLY) $(SRC)/mingw64/0001-headers-enable-GetFileInformationByHandle-in-Win10-U.patch
 	$(APPLY) $(SRC)/mingw64/0001-headers-enable-VirtualAlloc-Ex-in-Win10-UWP-builds.patch
+	$(APPLY) $(SRC)/mingw64/0001-headers-enable-CreateHardLinkW-in-Win10-UWP-builds.patch
+	$(APPLY) $(SRC)/mingw64/0001-headers-enable-GetVolumePathNameW-in-Win10-UWP-build.patch
 	$(MOVE)
 
 .mingw64: mingw64
@@ -132,5 +134,6 @@ MINGW_HEADERS_D3D9 := d3d9.h d3d9caps.h
 	install -d "$(PREFIX)/include"
 	install $</mingw-w64-headers/include/fileapi.h "$(PREFIX)/include"
 	install $</mingw-w64-headers/include/memoryapi.h "$(PREFIX)/include"
+	install $</mingw-w64-headers/include/winbase.h "$(PREFIX)/include"
 	touch $@
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3bfe42813a946271710ad07e9a3b0426a98049fe...3b0db17ce675e7580fbe9d696a3592f2b3c3bd4f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3bfe42813a946271710ad07e9a3b0426a98049fe...3b0db17ce675e7580fbe9d696a3592f2b3c3bd4f
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list