Use exists flag instead of error return for detecting non-existing files.
diff --git a/lib/zip_source_file_common.c b/lib/zip_source_file_common.c
index 602e609..977d390 100644
--- a/lib/zip_source_file_common.c
+++ b/lib/zip_source_file_common.c
@@ -134,14 +134,25 @@
     ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
 
     zip_source_file_stat_init(&sb);
-    stat_valid = ops->stat(ctx, &sb);
-
-    if (ctx->fname && !stat_valid && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) {
-	ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+    if (!ops->stat(ctx, &sb)) {
+        _zip_error_copy(error, &ctx->error);
+        free(ctx->fname);
+        free(ctx);
+        return NULL;
     }
 
-    if (!stat_valid) {
-	zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno);
+    if (!sb.exists) {
+        if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) {
+            ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+            /* zip_open_from_source checks for this to detect non-existing files */
+            zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
+        }
+        else {
+            zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
+            free(ctx->fname);
+            free(ctx);
+            return NULL;
+        }
     }
     else {
 	if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
diff --git a/lib/zip_source_file_stdio.c b/lib/zip_source_file_stdio.c
index 6fda8ec..4a22f78 100644
--- a/lib/zip_source_file_stdio.c
+++ b/lib/zip_source_file_stdio.c
@@ -142,6 +142,10 @@
     }
 
     if (ret < 0) {
+        if (errno == ENOENT) {
+            st->exists = false;
+            return true;
+        }
 	zip_error_set(&ctx->error, ZIP_ER_READ, errno);
 	return false;
     }
diff --git a/lib/zip_source_file_win32_write.c b/lib/zip_source_file_win32_write.c
index 2f4ead1..13e8d1f 100644
--- a/lib/zip_source_file_win32_write.c
+++ b/lib/zip_source_file_win32_write.c
@@ -198,8 +198,13 @@
     WIN32_FILE_ATTRIBUTE_DATA file_attributes;
 
     if (!write_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) {
-        printf("get_file_attributes_ex failed: %d\n", (int)GetLastError());
-        zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+        DWORD error = GetLastError();
+        if (error == ERROR_FILE_NOT_FOUND) {
+            st->exists = false;
+            return true;
+        }
+        printf("get_file_attributes_ex failed: %u / %d\n", error, _zip_win32_error_to_errno(error));
+        zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(error));
         return false;
     }
     
@@ -214,7 +219,6 @@
 
     /* TODO: fill in ctx->attributes */
 
-    printf("stat succeded: size: %llu\n", st->size);
     return true;
 }