diff options
-rw-r--r-- | .gitlab-ci.yml | 8 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | meson.build | 8 | ||||
-rw-r--r-- | meson_options.txt | 4 | ||||
-rw-r--r-- | src/win32/filesystem_win32.c | 61 | ||||
-rw-r--r-- | src/zix_config.h | 35 |
6 files changed, 94 insertions, 25 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7fd5f8b..94f8795 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -95,6 +95,8 @@ mingw32: - ninja -C build test - meson configure -Dbuildtype=release build - ninja -C build test + - meson configure -Dwin_ver=vista build + - ninja -C build test - meson configure -Dwin_ver=winxp build - ninja -C build test - meson configure -Dwin_ver=nt4 build @@ -112,6 +114,8 @@ mingw64: - ninja -C build test - meson configure -Dbuildtype=release build - ninja -C build test + - meson configure -Dwin_ver=vista build + - ninja -C build test - meson configure -Dwin_ver=winxp build - ninja -C build test - meson configure -Dwin_wchar=disabled build @@ -156,12 +160,16 @@ win: - ninja -C build test - meson configure -Dbuildtype=release build - ninja -C build test + - meson configure -Dwin_ver=vista build + - ninja -C build test - meson configure -Dwin_ver=winxp build - ninja -C build test - meson configure -Dwin_ver=nt4 build - ninja -C build test - meson configure -Dwin_wchar=disabled build - ninja -C build test + - meson configure -Dwin_wchar=enabled -Dwin_ver=win8 -Dc_args="/DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP" -Dc_link_args="/APPCONTAINER" build + - ninja -C build test # Documentation @@ -10,9 +10,10 @@ zix (0.5.1) unstable; urgency=medium * Fix nullability annotations for zix_canonical_path() and friends * Fix ring unit test when mlock() is unavailable * Improve documentation + * Support building for UWP * Support building for Windows with or without UNICODE - -- David Robillard <d@drobilla.net> Wed, 11 Dec 2024 05:21:56 +0000 + -- David Robillard <d@drobilla.net> Wed, 11 Dec 2024 05:22:31 +0000 zix (0.4.2) stable; urgency=medium diff --git a/meson.build b/meson.build index 9e14d02..d4b9fcd 100644 --- a/meson.build +++ b/meson.build @@ -170,6 +170,7 @@ elif host_machine.system() == 'windows' 'nt4': '0x0400', 'winxp': '0x0501', 'vista': '0x0600', + 'win8': '0x0602', } system_c_args += [ '-DWIN32_LEAN_AND_MEAN', @@ -252,6 +253,11 @@ else } windows_checks = { + 'CreateFile2': template.format( + 'windows.h', + 'CREATEFILE2_EXTENDED_PARAMETERS p = {0};\n' + + 'return CreateFile2(NULL, FILE_READ_ATTRIBUTES, 0U, OPEN_EXISTING, &p);', + ), 'CreateHardLink': template.format( 'windows.h', 'return CreateHardLink(TEXT("l"), TEXT("t"), NULL);', @@ -297,7 +303,7 @@ int main(void) { sem_t s; struct timespec t; return sem_timedwait(&s, &t); }''', foreach name, check_code : checks is_mingw = host_machine.system() == 'windows' and cc.get_id() == 'gcc' - if is_mingw and name in ['CreateSymbolicLink'] + if is_mingw and name in ['CreateFile2', 'CreateSymbolicLink'] message('Ignoring MinGW stub @0@'.format(name)) continue endif diff --git a/meson_options.txt b/meson_options.txt index a5fed47..9b5a599 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -34,8 +34,8 @@ option('tests_cpp', type: 'feature', yield: true, option('title', type: 'string', value: 'Zix', description: 'Project title') -option('win_ver', type: 'combo', value: 'vista', - choices: ['nt4', 'winxp', 'vista'], +option('win_ver', type: 'combo', value: 'win8', + choices: ['nt4', 'winxp', 'vista', 'win8'], description: 'Latest Windows API version to use') option('win_wchar', type: 'feature', yield: true, diff --git a/src/win32/filesystem_win32.c b/src/win32/filesystem_win32.c index c88b1ff..196818b 100644 --- a/src/win32/filesystem_win32.c +++ b/src/win32/filesystem_win32.c @@ -248,6 +248,49 @@ zix_file_unlock(FILE* const file, const ZixFileLockMode mode) UnlockFileEx(handle, 0, UINT32_MAX, UINT32_MAX, &overlapped)); } +#if USE_GETFINALPATHNAMEBYHANDLE && USE_CREATEFILE2 + +static HANDLE +open_attribute_handle(const char* const path) +{ + wchar_t* const wpath = zix_utf8_to_wchar(NULL, path); + + CREATEFILE2_EXTENDED_PARAMETERS params = { + sizeof(CREATEFILE2_EXTENDED_PARAMETERS), + 0U, + FILE_FLAG_BACKUP_SEMANTICS, + 0U, + NULL, + NULL}; + + const HANDLE handle = + CreateFile2(wpath, FILE_READ_ATTRIBUTES, 0U, OPEN_EXISTING, ¶ms); + + zix_free(NULL, wpath); + return handle; +} + +#elif USE_GETFINALPATHNAMEBYHANDLE + +static HANDLE +open_attribute_handle(const char* const path) +{ + ArgPathChar* const wpath = arg_path_new(NULL, path); + + const HANDLE handle = CreateFile(wpath, + FILE_READ_ATTRIBUTES, + 0U, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + arg_path_free(NULL, wpath); + return handle; +} + +#endif + char* zix_canonical_path(ZixAllocator* const allocator, const char* const path) { @@ -255,20 +298,10 @@ zix_canonical_path(ZixAllocator* const allocator, const char* const path) return NULL; } - ArgPathChar* const wpath = arg_path_new(allocator, path); - #if USE_GETFINALPATHNAMEBYHANDLE // Vista+ - const HANDLE h = - CreateFile(wpath, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - TCHAR* final = NULL; + const HANDLE h = open_attribute_handle(path); + TCHAR* final = NULL; if (h != INVALID_HANDLE_VALUE) { const DWORD flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS; const DWORD length = GetFinalPathNameByHandle(h, NULL, 0U, flags); @@ -281,12 +314,12 @@ zix_canonical_path(ZixAllocator* const allocator, const char* const path) } CloseHandle(h); - arg_path_free(allocator, wpath); return path_result(allocator, final); #else // Fall back to "full path iff it exists" for older Windows - TCHAR* full = NULL; + ArgPathChar* const wpath = arg_path_new(allocator, path); + TCHAR* full = NULL; if (GetFileAttributes(wpath) != INVALID_FILE_ATTRIBUTES) { const DWORD length = GetFullPathName(wpath, 0U, NULL, NULL); if (length) { diff --git a/src/zix_config.h b/src/zix_config.h index 6bbc92b..abcd11e 100644 --- a/src/zix_config.h +++ b/src/zix_config.h @@ -55,6 +55,13 @@ # define ZIX_POSIX_VERSION 0 # endif +// Define ZIX_WINAPI_UWP to 1 (if this is a sandboxed UWP app) or 0 +# if defined(WINAPI_FAMILY) && WINAPI_FAMILY < 10 +# define ZIX_WINAPI_UWP 1 +# else +# define ZIX_WINAPI_UWP 0 +# endif + // POSIX.1-2001: clock_gettime() # ifndef HAVE_CLOCK_GETTIME # if ZIX_POSIX_VERSION >= 200112L @@ -78,16 +85,24 @@ # endif # endif -// Windows XP: CreateHardLink() +// Windows 8 (Desktop, UWP): CreateFile2() +# ifndef HAVE_CREATEFILE2 +# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 && !defined(__MINGW32__) +# define HAVE_CREATEFILE2 1 +# endif +# endif + +// Windows XP (Desktop): CreateHardLink() # ifndef HAVE_CREATEHARDLINK -# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501 +# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501 && !ZIX_WINAPI_UWP # define HAVE_CREATEHARDLINK 1 # endif # endif -// Windows Vista: CreateSymbolicLink() +// Windows Vista (Desktop): CreateSymbolicLink() # ifndef HAVE_CREATESYMBOLICLINK -# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && !defined(__MINGW32__) +# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && \ + !defined(__MINGW32__) && !ZIX_WINAPI_UWP # define HAVE_CREATESYMBOLICLINK 1 # endif # endif @@ -106,7 +121,7 @@ # endif # endif -// Windows Vista: GetFinalPathNameByHandle() +// Windows Vista (Desktop, UWP): GetFinalPathNameByHandle() # ifndef HAVE_GETFINALPATHNAMEBYHANDLE # if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 # define HAVE_GETFINALPATHNAMEBYHANDLE 1 @@ -162,9 +177,9 @@ # endif # endif -// Windows XP: VirtualLock +// Windows XP (Desktop): VirtualLock # ifndef HAVE_VIRTUALLOCK -# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501 +# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501 && !ZIX_WINAPI_UWP # define HAVE_VIRTUALLOCK 1 # endif # endif @@ -197,6 +212,12 @@ # define USE_COPY_FILE_RANGE 0 #endif +#if defined(HAVE_CREATEFILE2) && HAVE_CREATEFILE2 +# define USE_CREATEFILE2 1 +#else +# define USE_CREATEFILE2 0 +#endif + #if defined(HAVE_CREATEHARDLINK) && HAVE_CREATEHARDLINK # define USE_CREATEHARDLINK 1 #else |