Use GetFileAttributesExA/W instead of opening file.
diff --git a/lib/zip_source_file_win32.c b/lib/zip_source_file_win32.c
index 4a46e96..8e59357 100644
--- a/lib/zip_source_file_win32.c
+++ b/lib/zip_source_file_win32.c
@@ -35,7 +35,7 @@
static bool _zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
-static int _zip_filetime_to_time_t(FILETIME ft, time_t *t);
+static bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h);
static zip_source_file_operations_t ops_win32_read = {
_zip_win32_op_close,
@@ -183,7 +183,7 @@
}
-bool
+static bool
_zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h) {
FILETIME mtimeft;
time_t mtime;
@@ -218,7 +218,7 @@
}
-static int
+bool
_zip_filetime_to_time_t(FILETIME ft, time_t *t) {
/*
Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
diff --git a/lib/zip_source_file_win32.h b/lib/zip_source_file_win32.h
index 0097afd..78c77ad 100644
--- a/lib/zip_source_file_win32.h
+++ b/lib/zip_source_file_win32.h
@@ -52,6 +52,7 @@
HANDLE (*create_file)(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
BOOL (*delete_file)(const char *name);
DWORD (*get_file_attributes)(const char *name);
+ BOOL (*get_file_attributes_ex)(const char *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
void (*make_tempname)(char *buf, size_t len, const char *name, int i);
BOOL (*move_file)(const char *from, const char *to, DWORD flags);
BOOL (*set_file_attributes)(const char *name, DWORD attributes);
@@ -68,7 +69,7 @@
zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
zip_int64_t _zip_win32_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
-bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h);
+bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
int _zip_win32_error_to_errno(DWORD win32err);
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
diff --git a/lib/zip_source_file_win32_ansi.c b/lib/zip_source_file_win32_ansi.c
index 0909519..0d2568c 100644
--- a/lib/zip_source_file_win32_ansi.c
+++ b/lib/zip_source_file_win32_ansi.c
@@ -41,6 +41,7 @@
CreateFileA,
DeleteFileA,
GetFileAttributesA,
+ GetFileAttributesExA,
ansi_make_tempname,
MoveFileExA,
SetFileAttributesA,
diff --git a/lib/zip_source_file_win32_utf16.c b/lib/zip_source_file_win32_utf16.c
index 8263ac9..97b7a8e 100644
--- a/lib/zip_source_file_win32_utf16.c
+++ b/lib/zip_source_file_win32_utf16.c
@@ -37,6 +37,7 @@
static HANDLE utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
static BOOL utf16_delete_file(const char *name);
static DWORD utf16_get_file_attributes(const char *name);
+static BOOL utf16_get_file_attributes(const char *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
static void utf16_make_tempname(char *buf, size_t len, const char *name, int i);
static BOOL utf16_move_file(const char *from, const char *to, DWORD flags);
static BOOL utf16_set_file_attributes(const char *name, DWORD attributes);
@@ -47,6 +48,7 @@
utf16_create_file,
utf16_delete_file,
utf16_get_file_attributes,
+ utf16_get_file_attributes_ex,
utf16_make_tempname,
utf16_move_file,
utf16_set_file_attributes,
@@ -94,7 +96,7 @@
return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams);
#else
- wprintf(L"CreateFileW(\"%s\", %x, %x, %x, %p, %x)\n", (const wchar_t *)name, access, share_mode, creation_disposition, security_attributes, file_attributes);
+ // wprintf(L"CreateFileW(\"%s\", %x, %x, %x, %p, %x)\n", (const wchar_t *)name, access, share_mode, creation_disposition, security_attributes, file_attributes);
return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);
#endif
}
@@ -112,6 +114,13 @@
}
+static BOOL
+utf16_get_file_attributes(const char *name, GET_FILEEX_INFO_LEVELS info_level, void *information) {
+ return GetFeilAttributesExW((const wchar_t *)name, info_level, information);
+}
+
+
+
static void
utf16_make_tempname(char *buf, size_t len, const char *name, int i) {
_snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i);
diff --git a/lib/zip_source_file_win32_write.c b/lib/zip_source_file_win32_write.c
index dfcf1ad..300c84c 100644
--- a/lib/zip_source_file_win32_write.c
+++ b/lib/zip_source_file_win32_write.c
@@ -193,19 +193,25 @@
static bool
_zip_win32_write_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
- HANDLE h = win32_write_open(ctx, ctx->fname, false, NULL);
- bool ok;
+ zip_source_file_win32_write_operations_t *write_ops = (zip_source_file_win32_write_operations_t *)ctx->ops_userdata;
- if (h == INVALID_HANDLE_VALUE) {
- printf("open in stat failed\n");
+ WIN32_FILE_ATTRIBUTE_DATA file_attributes;
+
+ if (!write_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return false;
}
-
- ok = _zip_stat_win32(ctx, st, h);
- // CloseHandle(h);
+ st->exists = true;
+ st->regular_file = true; /* TODO: Is this always right? How to determine without a HANDLE? */
+ if (!_zip_filetime_to_time_t(file_attributes->ftLastWriteTime, &st->mtime)) {
+ printf("filetime_to_time_t failed\n");
+ zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
+ return false;
+ }
+ st->size = ((zip_uint64_t)file_attributes->nFileSizeHigh << 32) | file_attributes->nFileSizeLow;
- return ok;
+ return true;
}