]> wimlib.net Git - wimlib/blobdiff - src/add_image.c
Windows native build
[wimlib] / src / add_image.c
index 5b51f493ea78e597375259ee7345be6222ae98ea..a57541f99711d94b474df35e69400269cbaf45e2 100644 (file)
 #      include "timestamp.h"
 #endif
 
+#ifdef __WIN32__
+#include <shlwapi.h>
+#endif
+
 #include "wimlib_internal.h"
 #include "dentry.h"
 #include "lookup_table.h"
 #include "xml.h"
 #include <ctype.h>
 #include <errno.h>
+
+#ifndef __WIN32__
 #include <fnmatch.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -162,7 +170,7 @@ static int win32_get_security_descriptor(struct wim_dentry *dentry,
                DWORD len = lenNeeded;
                char buf[len];
                if (GetFileSecurityW(path_utf16, requestedInformation,
-                                    buf, len, &lenNeeded))
+                                    (PSECURITY_DESCRIPTOR)buf, len, &lenNeeded))
                {
                        int security_id = sd_set_add_sd(sd_set, buf, len);
                        if (security_id < 0)
@@ -536,6 +544,7 @@ out_find_close:
        FindClose(hFind);
        return ret;
 }
+
 #endif
 
 /*
@@ -674,11 +683,15 @@ static int build_dentry_tree(struct wim_dentry **root_ret,
        inode->i_last_write_time = unix_timestamp_to_wim(root_stbuf.st_mtime);
        inode->i_last_access_time = unix_timestamp_to_wim(root_stbuf.st_atime);
 #endif
-       if (sizeof(ino_t) >= 8)
-               inode->i_ino = (u64)root_stbuf.st_ino;
-       else
-               inode->i_ino = (u64)root_stbuf.st_ino |
-                                  ((u64)root_stbuf.st_dev << ((sizeof(ino_t) * 8) & 63));
+       /* Leave the inode number at 0 for directories. */
+       if (!S_ISDIR(root_stbuf.st_mode)) {
+               if (sizeof(ino_t) >= 8)
+                       inode->i_ino = (u64)root_stbuf.st_ino;
+               else
+                       inode->i_ino = (u64)root_stbuf.st_ino |
+                                          ((u64)root_stbuf.st_dev <<
+                                               ((sizeof(ino_t) * 8) & 63));
+       }
        inode->i_resolved = 1;
        if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) {
                ret = inode_set_unix_data(inode, root_stbuf.st_uid,
@@ -847,7 +860,7 @@ static int build_dentry_tree(struct wim_dentry **root_ret,
        ret = utf8_to_utf16(root_disk_path, strlen(root_disk_path),
                            (char**)&path_utf16, &path_utf16_nchars);
        if (ret)
-               goto out;
+               goto out_destroy_sd_set;
        path_utf16_nchars /= sizeof(wchar_t);
 
        HANDLE hFile = win32_open_file_readonly(path_utf16);
@@ -856,7 +869,7 @@ static int build_dentry_tree(struct wim_dentry **root_ret,
                ERROR("Win32 API: Failed to open \"%s\"", root_disk_path);
                win32_error(err);
                ret = WIMLIB_ERR_OPEN;
-               goto out_destroy_sd_set;
+               goto out_free_path_utf16;
        }
 
        BY_HANDLE_FILE_INFORMATION file_info;
@@ -939,11 +952,11 @@ static int build_dentry_tree(struct wim_dentry **root_ret,
        }
 out_close_handle:
        CloseHandle(hFile);
+out_free_path_utf16:
+       FREE(path_utf16);
 out_destroy_sd_set:
        if (extra_arg == NULL)
                destroy_sd_set(sd_set);
-out_free_path_utf16:
-       FREE(path_utf16);
 #endif
        /* The below lines of code are common to both UNIX and Win32 builds.  It
         * simply returns the captured directory tree if the capture was
@@ -1133,6 +1146,19 @@ static int capture_config_set_prefix(struct capture_config *config,
        return 0;
 }
 
+static bool path_matches_pattern(const char *path, const char *pattern)
+{
+#ifdef __WIN32__
+       return PathMatchSpecA(path, pattern);
+#else
+       return fnmatch(pattern, path, FNM_PATHNAME
+                       #ifdef FNM_CASEFOLD
+                                       | FNM_CASEFOLD
+                       #endif
+               ) == 0;
+#endif
+}
+
 static bool match_pattern(const char *path, const char *path_basename,
                          const struct pattern_list *list)
 {
@@ -1150,12 +1176,8 @@ static bool match_pattern(const char *path, const char *path_basename,
                                /* A file name pattern */
                                string = path_basename;
                }
-               if (fnmatch(pat, string, FNM_PATHNAME
-                       #ifdef FNM_CASEFOLD
-                                       | FNM_CASEFOLD
-                       #endif
-                       ) == 0)
-               {
+
+               if (path_matches_pattern(string, pat)) {
                        DEBUG("`%s' matches the pattern \"%s\"",
                              string, pat);
                        return true;
@@ -1323,9 +1345,8 @@ new_filler_directory(const char *name)
        DEBUG("Creating filler directory \"%s\"", name);
        dentry = new_dentry_with_inode(name);
        if (dentry) {
-               /* Set the inode number to 0 for now.  The final inode number
+               /* Leave the inode number as 0 for now.  The final inode number
                 * will be assigned later by assign_inode_numbers(). */
-               dentry->d_inode->i_ino = 0;
                dentry->d_inode->i_resolved = 1;
                dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
        }
@@ -1339,6 +1360,9 @@ static int do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
 {
        struct rb_root *rb_root;
 
+       DEBUG("Doing overlay %s => %s",
+             branch->file_name_utf8, target->file_name_utf8);
+
        if (!dentry_is_directory(target)) {
                ERROR("Cannot overlay directory `%s' over non-directory",
                      branch->file_name_utf8);
@@ -1360,6 +1384,7 @@ static int do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
                        return WIMLIB_ERR_INVALID_OVERLAY;
                }
        }
+       free_dentry(branch);
        return 0;
 
 }
@@ -1382,6 +1407,9 @@ static int attach_branch(struct wim_dentry **root_p,
        char *slash;
        struct wim_dentry *dentry, *parent, *target;
 
+       DEBUG("Attaching branch \"%s\" => \"%s\"",
+             branch->file_name_utf8, target_path);
+
        if (*target_path == '\0') {
                /* Target: root directory */
                if (*root_p) {
@@ -1544,6 +1572,11 @@ WIMLIBAPI int wimlib_add_image_multisource(WIMStruct *w,
        } else {
                size_t i;
 
+#if defined(__CYGWIN__) || defined(__WIN32__)
+               win32_acquire_privilege(SE_BACKUP_NAME);
+               win32_acquire_privilege(SE_SECURITY_NAME);
+               win32_acquire_privilege(SE_TAKE_OWNERSHIP_NAME);
+#endif
                root_dentry = NULL;
                i = 0;
                do {
@@ -1622,7 +1655,7 @@ WIMLIBAPI int wimlib_add_image_multisource(WIMStruct *w,
        if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_BOOT)
                wimlib_set_boot_idx(w, w->hdr.image_count);
        ret = 0;
-       goto out;
+       goto out_destroy_capture_config;
 out_destroy_imd:
        destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1],
                               w->lookup_table);
@@ -1637,6 +1670,11 @@ out_free_security_data:
 out_destroy_capture_config:
        destroy_capture_config(&config);
 out:
+#if defined(__CYGWIN__) || defined(__WIN32__)
+       win32_release_privilege(SE_BACKUP_NAME);
+       win32_release_privilege(SE_SECURITY_NAME);
+       win32_release_privilege(SE_TAKE_OWNERSHIP_NAME);
+#endif
        return ret;
 }