From 9aa037173e39edcc1dba7c29ff45457f9e0d92c3 Mon Sep 17 00:00:00 2001 From: Kei Takahashi Date: Tue, 13 Aug 2024 15:51:44 -0400 Subject: [PATCH 1/3] treat deduped file as regular file --- lib/zip_source_file_win32.h | 1 + lib/zip_source_file_win32_ansi.c | 10 +++++++++- lib/zip_source_file_win32_named.c | 14 ++++++++++++-- lib/zip_source_file_win32_utf16.c | 12 +++++++++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/zip_source_file_win32.h b/lib/zip_source_file_win32.h index 86ef2651c..55e11a4aa 100644 --- a/lib/zip_source_file_win32.h +++ b/lib/zip_source_file_win32.h @@ -59,6 +59,7 @@ struct zip_win32_file_operations { BOOL(__stdcall *move_file)(const void *from, const void *to, DWORD flags); BOOL(__stdcall *set_file_attributes)(const void *name, DWORD attributes); char *(*string_duplicate)(const char *string); + HANDLE(__stdcall *find_first_file)(const void *name, void *data); }; typedef struct zip_win32_file_operations zip_win32_file_operations_t; diff --git a/lib/zip_source_file_win32_ansi.c b/lib/zip_source_file_win32_ansi.c index b9a744fdf..4467b2e94 100644 --- a/lib/zip_source_file_win32_ansi.c +++ b/lib/zip_source_file_win32_ansi.c @@ -41,6 +41,7 @@ static BOOL __stdcall ansi_get_file_attributes_ex(const void *name, GET_FILEEX_I static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); static BOOL __stdcall ansi_move_file(const void *from, const void *to, DWORD flags); static BOOL __stdcall ansi_set_file_attributes(const void *name, DWORD attributes); +static BOOL __stdcall ansi_find_first_file(const void *name, void* data); /* clang-format off */ DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN @@ -54,7 +55,8 @@ zip_win32_file_operations_t ops_ansi = { ansi_make_tempname, ansi_move_file, ansi_set_file_attributes, - strdup + strdup, + ansi_find_first_file, }; DONT_WARN_INCOMPATIBLE_FN_PTR_END @@ -126,3 +128,9 @@ ansi_set_file_attributes(const void *name, DWORD attributes) { return SetFileAttributesA((const char *)name, attributes); } + +static BOOL __stdcall +ansi_find_first_file(const void *name, void *data) +{ + return FindFirstFileA((const char *)name, data); +} diff --git a/lib/zip_source_file_win32_named.c b/lib/zip_source_file_win32_named.c index a406d32f0..bb3082651 100644 --- a/lib/zip_source_file_win32_named.c +++ b/lib/zip_source_file_win32_named.c @@ -221,8 +221,18 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t st->regular_file = false; if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) { - if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) == 0) { - st->regular_file = true; + if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) { + if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + printf("REPARSE_POINT!!!!\n"); + WIN32_FIND_DATA find_data; + if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) { + st->regular_file = find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP; + } + } + else { + printf("Not REPARSE_POINT ...\n"); + st->regular_file = true; + } } } diff --git a/lib/zip_source_file_win32_utf16.c b/lib/zip_source_file_win32_utf16.c index e37d65c10..15e2390f8 100644 --- a/lib/zip_source_file_win32_utf16.c +++ b/lib/zip_source_file_win32_utf16.c @@ -42,6 +42,7 @@ static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uin static BOOL __stdcall utf16_move_file(const void *from, const void *to, DWORD flags); static BOOL __stdcall utf16_set_file_attributes(const void *name, DWORD attributes); static char *utf16_strdup(const char *string); +static BOOL __stdcall utf16_find_first_file(const void *name, void* data); /* clang-format off */ @@ -56,7 +57,8 @@ zip_win32_file_operations_t ops_utf16 = { utf16_make_tempname, utf16_move_file, utf16_set_file_attributes, - utf16_strdup + utf16_strdup, + utf16_find_first_file }; DONT_WARN_INCOMPATIBLE_FN_PTR_END @@ -145,3 +147,11 @@ static char * utf16_strdup(const char *string) { return (char *)_wcsdup((const wchar_t *)string); } + + +static BOOL __stdcall +utf16_find_first_file(const void *name, void* data) +{ + return FileFirstFileW((const wchar_t *)name, data); +} + From 0a65934ddaa463780d232482d7b104395bc52e69 Mon Sep 17 00:00:00 2001 From: Kei Takahashi Date: Wed, 14 Aug 2024 08:42:03 -0400 Subject: [PATCH 2/3] some cleanup --- lib/zip_source_file_win32_named.c | 4 +--- lib/zip_source_file_win32_utf16.c | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/zip_source_file_win32_named.c b/lib/zip_source_file_win32_named.c index bb3082651..39e4a6d7f 100644 --- a/lib/zip_source_file_win32_named.c +++ b/lib/zip_source_file_win32_named.c @@ -223,14 +223,12 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) { if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) { if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - printf("REPARSE_POINT!!!!\n"); WIN32_FIND_DATA find_data; if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) { - st->regular_file = find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP; + st->regular_file = (find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP); } } else { - printf("Not REPARSE_POINT ...\n"); st->regular_file = true; } } diff --git a/lib/zip_source_file_win32_utf16.c b/lib/zip_source_file_win32_utf16.c index 15e2390f8..6a45f5e4a 100644 --- a/lib/zip_source_file_win32_utf16.c +++ b/lib/zip_source_file_win32_utf16.c @@ -150,8 +150,7 @@ utf16_strdup(const char *string) { static BOOL __stdcall -utf16_find_first_file(const void *name, void* data) +utf16_find_first_file(const void *name, void* data) { return FileFirstFileW((const wchar_t *)name, data); } - From 22751dbd80b04ae87c9fac295da598a98d5eeb8c Mon Sep 17 00:00:00 2001 From: Kei Takahashi Date: Thu, 15 Aug 2024 16:33:41 -0400 Subject: [PATCH 3/3] fix error --- lib/zip_source_file_win32_ansi.c | 4 ++-- lib/zip_source_file_win32_utf16.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/zip_source_file_win32_ansi.c b/lib/zip_source_file_win32_ansi.c index 4467b2e94..ad86eace4 100644 --- a/lib/zip_source_file_win32_ansi.c +++ b/lib/zip_source_file_win32_ansi.c @@ -41,7 +41,7 @@ static BOOL __stdcall ansi_get_file_attributes_ex(const void *name, GET_FILEEX_I static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i); static BOOL __stdcall ansi_move_file(const void *from, const void *to, DWORD flags); static BOOL __stdcall ansi_set_file_attributes(const void *name, DWORD attributes); -static BOOL __stdcall ansi_find_first_file(const void *name, void* data); +static HANDLE __stdcall ansi_find_first_file(const void *name, void* data); /* clang-format off */ DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN @@ -129,7 +129,7 @@ ansi_set_file_attributes(const void *name, DWORD attributes) return SetFileAttributesA((const char *)name, attributes); } -static BOOL __stdcall +static HANDLE __stdcall ansi_find_first_file(const void *name, void *data) { return FindFirstFileA((const char *)name, data); diff --git a/lib/zip_source_file_win32_utf16.c b/lib/zip_source_file_win32_utf16.c index 6a45f5e4a..64907f818 100644 --- a/lib/zip_source_file_win32_utf16.c +++ b/lib/zip_source_file_win32_utf16.c @@ -42,7 +42,7 @@ static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uin static BOOL __stdcall utf16_move_file(const void *from, const void *to, DWORD flags); static BOOL __stdcall utf16_set_file_attributes(const void *name, DWORD attributes); static char *utf16_strdup(const char *string); -static BOOL __stdcall utf16_find_first_file(const void *name, void* data); +static HANDLE __stdcall utf16_find_first_file(const void *name, void* data); /* clang-format off */ @@ -149,8 +149,8 @@ utf16_strdup(const char *string) { } -static BOOL __stdcall +static HANDLE __stdcall utf16_find_first_file(const void *name, void* data) { - return FileFirstFileW((const wchar_t *)name, data); + return FindFirstFileW((const wchar_t *)name, data); }