]> wimlib.net Git - wimlib/blobdiff - src/extract_image.c
Fix UNIX build; rename functions; comments
[wimlib] / src / extract_image.c
index c0d951cb6279d49739e547efc317c35533a48dde..6279c4901c75402be3f7f96856fd32cd4be75ca1 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"
 
 #include <dirent.h>
+
+#ifdef __WIN32__
+#  include "win32.h"
+#else
+#  ifdef HAVE_UTIME_H
+#    include <utime.h>
+#  endif
+#  include "timestamp.h"
+#  include <sys/time.h>
+#endif
+
 #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"
 
 #ifdef WITH_NTFS_3G
-#include <ntfs-3g/volume.h>
+#  include <ntfs-3g/volume.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
 #endif
 
+#ifndef __WIN32__
 static int extract_regular_file_linked(struct wim_dentry *dentry,
                                       const char *output_path,
                                       struct apply_args *args,
@@ -322,6 +327,8 @@ static int extract_symlink(struct wim_dentry *dentry,
        return 0;
 }
 
+#endif /* !__WIN32__ */
+
 static int extract_directory(struct wim_dentry *dentry,
                             const char *output_path, bool is_root)
 {
@@ -351,6 +358,8 @@ static int extract_directory(struct wim_dentry *dentry,
                return WIMLIB_ERR_MKDIR;
        }
 dir_exists:
+       ret = 0;
+#ifndef __WIN32__
        if (dentry) {
                struct wimlib_unix_data unix_data;
                ret = inode_get_unix_data(dentry->d_inode, &unix_data, NULL);
@@ -360,24 +369,18 @@ dir_exists:
                        ret = 0;
                else
                        ret = dir_apply_unix_data(output_path, &unix_data);
-       } else {
-               ret = 0;
        }
+#endif
        return ret;
 }
 
-/* Extracts a file, directory, or symbolic link from the WIM archive. */
-static int apply_dentry_normal(struct wim_dentry *dentry, void *arg)
+#ifndef __WIN32__
+static int unix_do_apply_dentry(const char *output_path,
+                               size_t output_path_len,
+                               struct wim_dentry *dentry,
+                               struct apply_args *args)
 {
-       struct apply_args *args = arg;
-       struct wim_inode *inode = dentry->d_inode;
-       size_t len;
-
-       len = strlen(args->target);
-       char output_path[len + dentry->full_path_utf8_len + 1];
-       memcpy(output_path, args->target, len);
-       memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len);
-       output_path[len + dentry->full_path_utf8_len] = '\0';
+       const struct wim_inode *inode = dentry->d_inode;
 
        if (inode_is_symlink(inode))
                return extract_symlink(dentry, args, output_path);
@@ -389,18 +392,13 @@ static int apply_dentry_normal(struct wim_dentry *dentry, void *arg)
                return extract_regular_file(dentry, args, output_path);
 }
 
-/* Apply timestamps to an extracted file or directory */
-static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
+static int unix_do_apply_dentry_timestamps(const char *output_path,
+                                          size_t output_path_len,
+                                          const struct wim_dentry *dentry,
+                                          struct apply_args *args)
 {
-       struct apply_args *args = arg;
-       size_t len = strlen(args->target);
-       char output_path[len + dentry->full_path_utf8_len + 1];
-       const struct wim_inode *inode = dentry->d_inode;
        int ret;
-
-       memcpy(output_path, args->target, len);
-       memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len);
-       output_path[len + dentry->full_path_utf8_len] = '\0';
+       const struct wim_inode *inode = dentry->d_inode;
 
        /* Convert the WIM timestamps, which are accurate to 100 nanoseconds,
         * into struct timeval's. */
@@ -431,6 +429,57 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
        }
        return 0;
 }
+#endif /* !__WIN32__ */
+
+/* Extracts a file, directory, or symbolic link from the WIM archive. */
+static int apply_dentry_normal(struct wim_dentry *dentry, void *arg)
+{
+       struct apply_args *args = arg;
+       struct wim_inode *inode = dentry->d_inode;
+       size_t len;
+       char *output_path;
+
+       len = strlen(args->target);
+       if (dentry_is_root(dentry)) {
+               output_path = (char*)args->target;
+       } else {
+               output_path = alloca(len + dentry->full_path_utf8_len + 1);
+               memcpy(output_path, args->target, len);
+               memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len);
+               output_path[len + dentry->full_path_utf8_len] = '\0';
+               len += dentry->full_path_utf8_len;
+       }
+#ifdef __WIN32__
+       return win32_do_apply_dentry(output_path, len, dentry, args);
+#else
+       return unix_do_apply_dentry(output_path, len, dentry, args);
+#endif
+}
+
+
+/* Apply timestamps to an extracted file or directory */
+static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
+{
+       struct apply_args *args = arg;
+       size_t len;
+       char *output_path;
+
+       len = strlen(args->target);
+       if (dentry_is_root(dentry)) {
+               output_path = (char*)args->target;
+       } else {
+               output_path = alloca(len + dentry->full_path_utf8_len + 1);
+               memcpy(output_path, args->target, len);
+               memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len);
+               output_path[len + dentry->full_path_utf8_len] = '\0';
+               len += dentry->full_path_utf8_len;
+       }
+#ifdef __WIN32__
+       return win32_do_apply_dentry_timestamps(output_path, len, dentry, args);
+#else
+       return unix_do_apply_dentry_timestamps(output_path, len, dentry, args);
+#endif
+}
 
 /* Extract a dentry if it hasn't already been extracted, and either the dentry
  * has no streams or WIMLIB_EXTRACT_FLAG_NO_STREAMS is not specified. */
@@ -849,6 +898,17 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
                        == (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK))
                return WIMLIB_ERR_INVALID_PARAM;
 
+#ifdef __WIN32__
+       if (extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) {
+               ERROR("Extracting UNIX data is not supported on Windows");
+               return WIMLIB_ERR_INVALID_PARAM;
+       }
+       if (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) {
+               ERROR("Linked extraction modes are not supported on Windows");
+               return WIMLIB_ERR_INVALID_PARAM;
+       }
+#endif
+
        if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
 #ifdef WITH_NTFS_3G
                if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK))) {
@@ -885,6 +945,9 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
                w->lookup_table = joined_tab;
        }
 
+#ifdef __WIN32__
+       win32_acquire_restore_privileges();
+#endif
        if (image == WIMLIB_ALL_IMAGES) {
                extract_flags |= WIMLIB_EXTRACT_FLAG_MULTI_IMAGE;
                ret = extract_all_images(w, target, extract_flags,
@@ -894,6 +957,9 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
                ret = extract_single_image(w, image, target, extract_flags,
                                           progress_func);
        }
+#ifdef __WIN32__
+       win32_release_restore_privileges();
+#endif
 
        if (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
                             WIMLIB_EXTRACT_FLAG_HARDLINK))