]> wimlib.net Git - wimlib/blobdiff - src/extract_image.c
Win32 fixes
[wimlib] / src / extract_image.c
index 6735602f495d489a545598bddd85a3efe6060265..25f4d917450ece86f753d1c3d20828e359f0f985 100644 (file)
@@ -2,11 +2,6 @@
  * extract_image.c
  *
  * Support for extracting WIM files.
- *
- * This code does NOT contain any filesystem-specific features.  In particular,
- * security information (i.e. file permissions) and alternate data streams are
- * ignored, except possibly to read an alternate data stream that contains
- * symbolic link data.
  */
 
 /*
 #include "config.h"
 
 #if defined(__CYGWIN__) || defined(__WIN32__)
-#include <windows.h>
-#ifdef ERROR
-#undef ERROR
-#endif
-#include <wchar.h>
+#      include <windows.h>
+#      ifdef ERROR
+#              undef ERROR
+#      endif
+#      include <wchar.h>
+#else
+#      include <dirent.h>
+#      ifdef HAVE_UTIME_H
+#              include <utime.h>
+#      endif
+#      include "timestamp.h"
+#      include <sys/time.h>
 #endif
 
-#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
 
 #include <unistd.h>
 
 #include "dentry.h"
 #include "lookup_table.h"
-#include "timestamp.h"
 #include "wimlib_internal.h"
 #include "xml.h"
 
@@ -64,8 +59,6 @@
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
-#else
-#include <stdlib.h>
 #endif
 
 #if defined(__CYGWIN__) || defined(__WIN32__)
@@ -227,7 +220,7 @@ static int win32_extract_stream(const struct wim_inode *inode,
 
        DEBUG("Opening \"%ls\"", stream_path);
        h = CreateFileW(stream_path,
-                       GENERIC_WRITE | WRITE_OWNER | WRITE_DAC,
+                       GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY,
                        0,
                        NULL,
                        creationDisposition,
@@ -289,7 +282,7 @@ out:
  * Returns 0 on success; nonzero on failure.
  */
 static int win32_extract_streams(struct wim_inode *inode,
-                                const wchar_t *path)
+                                const wchar_t *path, u64 *completed_bytes_p)
 {
        struct wim_lookup_table_entry *unnamed_lte;
        int ret;
@@ -298,6 +291,8 @@ static int win32_extract_streams(struct wim_inode *inode,
        ret = win32_extract_stream(inode, path, NULL, unnamed_lte);
        if (ret)
                goto out;
+       if (unnamed_lte)
+               *completed_bytes_p += wim_resource_size(unnamed_lte);
        for (u16 i = 0; i < inode->i_num_ads; i++) {
                const struct wim_ads_entry *ads_entry = &inode->i_ads_entries[i];
                if (ads_entry->stream_name_len != 0) {
@@ -314,6 +309,8 @@ static int win32_extract_streams(struct wim_inode *inode,
                                                   ads_entry->lte);
                        if (ret)
                                break;
+                       if (ads_entry->lte)
+                               *completed_bytes_p += wim_resource_size(ads_entry->lte);
                }
        }
 out:
@@ -350,7 +347,7 @@ static int win32_set_security_data(const struct wim_inode *inode,
        return 0;
 }
 
-#else
+#else /* __CYGWIN__ || __WIN32__ */
 static int extract_regular_file_linked(struct wim_dentry *dentry,
                                       const char *output_path,
                                       struct apply_args *args,
@@ -619,7 +616,7 @@ static int extract_symlink(struct wim_dentry *dentry,
        return 0;
 }
 
-#endif /* !__CYGWIN__ && !__WIN32__ */
+#endif /* !(__CYGWIN__ || __WIN32__) */
 
 static int extract_directory(struct wim_dentry *dentry,
                             const char *output_path, bool is_root)
@@ -714,7 +711,8 @@ static int apply_dentry_normal(struct wim_dentry *dentry, void *arg)
        } else {
                /* Create the file, directory, or reparse point, and extract the
                 * data streams. */
-               ret = win32_extract_streams(inode, (const wchar_t*)utf16_path);
+               ret = win32_extract_streams(inode, (const wchar_t*)utf16_path,
+                                           &args->progress.extract.completed_bytes);
                if (ret)
                        goto out_free_utf16_path;
 
@@ -785,8 +783,11 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
                return ret;
 
        DEBUG("Opening \"%ls\" to set timestamps", utf16_path);
-       h = CreateFileW(utf16_path, GENERIC_WRITE, FILE_SHARE_READ,
-                       NULL, OPEN_EXISTING,
+       h = CreateFileW((const wchar_t*)utf16_path,
+                       GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY,
+                       FILE_SHARE_READ,
+                       NULL,
+                       OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
                        NULL);
 
@@ -814,11 +815,13 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
                err = GetLastError();
                goto fail;
        }
-       return 0;
+       goto out;
 fail:
-       ERROR("Can't set timestamps on \"%s\"", output_path);
+       /* Only warn if setting timestamps failed. */
+       WARNING("Can't set timestamps on \"%s\"", output_path);
        win32_error(err);
-       return WIMLIB_ERR_WRITE;
+out:
+       return 0;
 #else
        /* UNIX */