Preserve DACL when creating tempfile on Win32.
diff --git a/lib/zip_source_win32a.c b/lib/zip_source_win32a.c
index 03534a0..bb3ebaa 100644
--- a/lib/zip_source_win32a.c
+++ b/lib/zip_source_win32a.c
@@ -40,7 +40,7 @@
 
 static void * _win32_strdup_a(const void *str);
 static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value);
+static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
 static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
 static int _win32_remove_a(const void *fname);
 
@@ -89,7 +89,7 @@
 
 
 static HANDLE
-_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value)
+_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
 {
     int len;
 
@@ -104,7 +104,7 @@
 	return INVALID_HANDLE_VALUE;
     }
 
-    return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+    return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
 }
 
 
diff --git a/lib/zip_source_win32file.c b/lib/zip_source_win32file.c
index ee8319e..b392ab8 100644
--- a/lib/zip_source_win32file.c
+++ b/lib/zip_source_win32file.c
@@ -417,20 +417,52 @@
     int i;
     HANDLE th = INVALID_HANDLE_VALUE;
     void *temp = NULL;
+    SECURITY_INFORMATION si;
+    SECURITY_ATTRIBUTES sa;
+    PSECURITY_DESCRIPTOR psd = NULL;
+    PSECURITY_ATTRIBUTES psa = NULL;
+    DWORD len;
+    BOOL success;
+
+    /*
+    Read the DACL from the original file, so we can copy it to the temp file.
+    If there is no original file, or if we can't read the DACL, we'll use the
+    default security descriptor.
+    */
+    if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
+	si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
+	len = 0;
+	success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len);
+	if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+	    if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) {
+		zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+		return -1;
+	    }
+	    success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len);
+	}
+	if (success) {
+	    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+	    sa.bInheritHandle = FALSE;
+	    sa.lpSecurityDescriptor = psd;
+	    psa = &sa;
+	}
+    }
 
     zip_uint32_t value = GetTickCount();
     for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
-	th = ctx->ops->op_create_temp(ctx, &temp, value + i);
+	th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
 	if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
 	    break;
     }
 
     if (th == INVALID_HANDLE_VALUE) {
 	free(temp);
+	free(psd);
 	zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
 	return -1;
     }
 
+    free(psd);
     ctx->hout = th;
     ctx->tmpname = temp;
 
diff --git a/lib/zip_source_win32w.c b/lib/zip_source_win32w.c
index e58d2a3..d18b432 100644
--- a/lib/zip_source_win32w.c
+++ b/lib/zip_source_win32w.c
@@ -40,7 +40,7 @@
 
 static void * _win32_strdup_w(const void *str);
 static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx);
-static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value);
+static HANDLE _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
 static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx);
 static int _win32_remove_w(const void *fname);
 
@@ -89,7 +89,7 @@
 
 
 static HANDLE
-_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value)
+_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
 {
     int len;
 
@@ -104,7 +104,7 @@
 	return INVALID_HANDLE_VALUE;
     }
 
-    return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+    return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
 }
 
 
diff --git a/lib/zipwin32.h b/lib/zipwin32.h
index 3adfdc3..7416bd2 100644
--- a/lib/zipwin32.h
+++ b/lib/zipwin32.h
@@ -68,7 +68,7 @@
 struct _zip_source_win32_file_ops {
     void *(*op_strdup)(const void *);
     void *(*op_open)(_zip_source_win32_read_file_t *);
-    void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t);
+    void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t, PSECURITY_ATTRIBUTES);
     int (*op_rename_temp)(_zip_source_win32_read_file_t *);
     int (*op_remove)(const void *);
 };