NTFS capture updates
authorEric Biggers <ebiggers3@gmail.com>
Mon, 27 Aug 2012 22:30:07 +0000 (17:30 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 27 Aug 2012 22:30:07 +0000 (17:30 -0500)
programs/imagex.c
src/dentry.c
src/lookup_table.h
src/modify.c
src/ntfs-capture.c
src/resource.c
src/util.c
src/wim.c
src/wimlib_internal.h

index d41964a22ba384b9bd514b3c7209c8eae8546df9..fe7f3be9866de20ee66888a4c6ab3e89f59bad0f 100644 (file)
@@ -80,26 +80,26 @@ static const char *path_basename(const char *path)
 
 static const char *usage_strings[] = {
 [APPEND] = 
-"    imagex append (DIRECTORY | NTFS_VOLUME) WIMFILE [\"IMAGE_NAME\"]\n"
-"                  [\"DESCRIPTION\"] [--boot] [--check] [--flags EDITIONID]\n"
+"    imagex append (DIRECTORY | NTFS_VOLUME) WIMFILE [IMAGE_NAME]\n"
+"                  [DESCRIPTION] [--boot] [--check] [--flags EDITION_ID]\n"
 "                  [--verbose] [--dereference] [--config=FILE]\n",
 [APPLY] = 
 "    imagex apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all]\n"
 "                 (DIRECTORY | NTFS_VOLUME) [--check] [--hardlink]\n"
 "                 [--symlink] [--verbose]\n",
 [CAPTURE] = 
-"    imagex capture (DIRECTORY | NTFS_VOLUME) WIMFILE [\"IMAGE_NAME\"]\n"
-"                   [\"DESCRIPTION\"] [--boot] [--check] [--compress=TYPE]\n"
-"                   [--flags \"EditionID\"] [--verbose] [--dereference]\n"
+"    imagex capture (DIRECTORY | NTFS_VOLUME) WIMFILE [IMAGE_NAME]\n"
+"                   [DESCRIPTION] [--boot] [--check] [--compress=TYPE]\n"
+"                   [--flags EDITION_ID] [--verbose] [--dereference]\n"
 "                   [--config=FILE]\n",
 [DELETE] = 
 "    imagex delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check]\n",
 [DIR] = 
-"    imagex dir WIMFILE (IMAGE_NUM | IMAGE_NAME | \"all\")\n",
+"    imagex dir WIMFILE (IMAGE_NUM | IMAGE_NAME | all)\n",
 [EXPORT] = 
 "    imagex export SRC_WIMFILE (SRC_IMAGE_NUM | SRC_IMAGE_NAME | all ) \n"
-"                  DEST_WIMFILE [\"DEST_IMAGE_NAME\"]\n"
-"                  [\"DEST_IMAGE_DESCRIPTION\"] [--boot] [--check]\n"
+"                  DEST_WIMFILE [DEST_IMAGE_NAME]\n"
+"                  [DEST_IMAGE_DESCRIPTION] [--boot] [--check]\n"
 "                  [--compress=TYPE]\n",
 [INFO] = 
 "    imagex info WIMFILE [IMAGE_NUM | IMAGE_NAME] [NEW_NAME]\n"
index 3f258b76d9151e8e1e6101d155a900c6fb78e05c..a0d0febde3e9894c5e11b7d66e396ec1c82b7392 100644 (file)
@@ -1143,7 +1143,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
                p = put_zeroes(p, 4);
        } else {
                u64 hard_link;
-               p = put_u32(p, dentry->reparse_tag);
+               p = put_u32(p, 0);
                if (dentry->link_group_list.next == &dentry->link_group_list)
                        hard_link = 0;
                else
index 6a07aaa97d51db024ebdb8f00a80ae2df841bd36..c211fe142c45291de89973e4d658f5466c305b6f 100644 (file)
@@ -26,6 +26,7 @@ struct lookup_table {
 
 struct wimlib_fd;
 
+#ifdef WITH_NTFS_3G
 typedef struct _ntfs_attr ntfs_attr;
 typedef struct _ntfs_volume ntfs_volume;
 struct ntfs_location {
@@ -35,6 +36,7 @@ struct ntfs_location {
        ntfs_volume **ntfs_vol_p;
        bool is_reparse_point;
 };
+#endif
 
 /* 
  * An entry in the lookup table in the WIM file. 
@@ -95,12 +97,16 @@ struct lookup_table_entry {
                char *file_on_disk;
                char *staging_file_name;
                u8 *attached_buffer;
+       #ifdef WITH_NTFS_3G
                struct ntfs_location *ntfs_loc;
+       #endif
        };
        union {
                struct lookup_table_entry *next_lte_in_swm;
                FILE *file_on_disk_fp;
+       #ifdef WITH_NTFS_3G
                ntfs_attr *attr;
+       #endif
        };
 #ifdef WITH_FUSE
        /* File descriptors table for this data stream */
index 3b321c37204cd230e5f15cc7eed4ad51fd20768f..141f2dd8aac45cb0de271803cb2a6d71a4258f8e 100644 (file)
@@ -518,7 +518,7 @@ static const char *default_config =
 "\\$ntfs.log\n"
 "\\hiberfil.sys\n"
 "\\pagefile.sys\n"
-"\"\\System Volume Information\"\n"
+"\\System Volume Information\n"
 "\\RECYCLER\n"
 "\\Windows\\CSC\n"
 "\n"
index 5d8ebcf8c27e5473292ff925c09aa42f5dc41780..751ce50f759e9f3e70b23666df451a02b236cdec 100644 (file)
@@ -297,6 +297,9 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni,
                        lte->resource_location = RESOURCE_IN_NTFS_VOLUME;
                        lte->resource_entry.original_size = actx->attr->data_size;
                        lte->resource_entry.size = actx->attr->data_size;
+                       DEBUG("Add resource for `%s' (size = %zu)",
+                               dentry->file_name_utf8,
+                               lte->resource_entry.original_size);
                        copy_hash(lte->hash, attr_hash);
                        lookup_table_insert(lookup_table, lte);
                }
@@ -369,10 +372,13 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
        struct readdir_ctx *ctx;
        size_t utf8_name_len;
        char *utf8_name;
-       struct dentry *child;
+       struct dentry *child = NULL;
        int ret;
        size_t path_len;
 
+       if (name_type == FILE_NAME_DOS)
+               return 0;
+
        ret = -1;
 
        utf8_name = utf16_to_utf8((const u8*)name, name_len * 2,
@@ -405,11 +411,12 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
        ret = __build_dentry_tree_ntfs(&child, ni, ctx->path, path_len,
                                       ctx->lookup_table, ctx->sd_set,
                                       ctx->config, ctx->ntfs_vol_p);
-       DEBUG("Linking dentry `%s' with parent `%s'",
-             child->file_name_utf8, ctx->parent->file_name_utf8);
 
-       link_dentry(child, ctx->parent);
-       DEBUG("Return %d", ret);
+       if (child) {
+               DEBUG("Linking dentry `%s' with parent `%s'",
+                     child->file_name_utf8, ctx->parent->file_name_utf8);
+               link_dentry(child, ctx->parent);
+       }
 out_close_ni:
        ntfs_inode_close(ni);
 out_free_utf8_name:
@@ -478,8 +485,10 @@ static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni,
                        .ntfs_vol_p   = ntfs_vol_p,
                };
                ret = ntfs_readdir(ni, &pos, &ctx, wim_ntfs_capture_filldir);
-               if (ret != 0)
+               if (ret != 0) {
+                       ERROR_WITH_ERRNO("ntfs_readdir()");
                        ret = WIMLIB_ERR_NTFS_3G;
+               }
        } else {
                DEBUG("Normal file `%s'", path);
                /* Normal file */
@@ -490,7 +499,6 @@ static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni,
        if (ret != 0)
                return ret;
 
-       DEBUG("Getting security information from `%s'", path);
        ret = ntfs_inode_get_security(ni,
                                      OWNER_SECURITY_INFORMATION |
                                      GROUP_SECURITY_INFORMATION |
@@ -568,10 +576,15 @@ static int build_dentry_tree_ntfs(struct dentry **root_p,
        ntfs_inode_close(root_ni);
 
 out:
-       if (ntfs_umount(vol, FALSE) != 0) {
-               ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'", device);
-               if (ret == 0)
-                       ret = WIMLIB_ERR_NTFS_3G;
+       if (ret) {
+               if (ntfs_umount(vol, FALSE) != 0) {
+                       ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'",
+                                        device);
+                       if (ret == 0)
+                               ret = WIMLIB_ERR_NTFS_3G;
+               }
+       } else {
+               *ntfs_vol_p = vol;
        }
        return ret;
 }
index d81421c558661cb1e2bef93a753e2a6fd9c8ee7a..73cea71c2de7b264671e5c4629650176d6478814 100644 (file)
 #include <errno.h>
 #include <alloca.h>
 
+#ifdef WITH_NTFS_3G
+#include <ntfs-3g/attrib.h>
+#include <ntfs-3g/inode.h>
+#include <ntfs-3g/dir.h>
+#endif
 
 /* 
  * Reads all or part of a compressed resource into an in-memory buffer.
@@ -475,6 +480,22 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
                memcpy(buf, lte->attached_buffer + offset, size);
                return 0;
                break;
+#ifdef WITH_NTFS_3G
+       case RESOURCE_IN_NTFS_VOLUME:
+               if (lte->attr) {
+                       if (ntfs_attr_pread(lte->attr, offset, size, buf) == size) {
+                               return 0;
+                       } else {
+                               ERROR_WITH_ERRNO("Error reading NTFS attribute "
+                                                "at `%s'",
+                                                lte->ntfs_loc->path_utf8);
+                               return WIMLIB_ERR_NTFS_3G;
+                       }
+               } else {
+                       wimlib_assert(0);
+               }
+               break;
+#endif
        default:
                assert(0);
        }
@@ -718,6 +739,9 @@ static int write_wim_resource(struct lookup_table_entry *lte,
        struct chunk_table *chunk_tab = NULL;
        bool raw;
        off_t file_offset;
+#ifdef WITH_NTFS_3G
+       ntfs_inode *ni;
+#endif
 
        /* Original size of the resource */
        original_size = wim_resource_size(lte);
@@ -773,6 +797,28 @@ static int write_wim_resource(struct lookup_table_entry *lte,
                        goto out;
                }
        }
+#ifdef WITH_NTFS_3G
+       else if (lte->resource_location == RESOURCE_IN_NTFS_VOLUME
+                  && !lte->attr)
+       {
+               struct ntfs_location *loc = lte->ntfs_loc;
+               wimlib_assert(loc);
+               ni = ntfs_pathname_to_inode(*loc->ntfs_vol_p, NULL, loc->path_utf8);
+               if (!ni) {
+                       ERROR_WITH_ERRNO("Failed to open inode `%s' in NTFS "
+                                        "volume", loc->path_utf8);
+               }
+               lte->attr = ntfs_attr_open(ni,
+                                          loc->is_reparse_point ? AT_REPARSE_POINT : AT_DATA,
+                                          (ntfschar*)loc->stream_name_utf16,
+                                          loc->stream_name_utf16_num_chars);
+               if (!lte->attr) {
+                       ntfs_inode_close(ni);
+                       ERROR_WITH_ERRNO("Failed to open attribute of `%s' in "
+                                        "NTFS volume", loc->path_utf8);
+               }
+       }
+#endif
 
        /* If we aren't doing a raw copy, we will compute the SHA1 message
         * digest of the resource as we read it, and verify it's the same as the
@@ -875,6 +921,13 @@ out_fclose:
                fclose(lte->file_on_disk_fp);
                lte->file_on_disk_fp = NULL;
        }
+#ifdef WITH_NTFS_3G
+       else if (lte->resource_location == RESOURCE_IN_NTFS_VOLUME
+                && lte->attr) {
+               ntfs_attr_close(lte->attr);
+               ntfs_inode_close(ni);
+       }
+#endif
 out:
        FREE(chunk_tab);
        return ret;
index fdb0c850dc7be34e99d5a432372180e54dfece39..8f4e0c0be53756db28ef2974d43de4b1f08b8b3e 100644 (file)
@@ -429,8 +429,13 @@ const char *path_basename(const char *path)
        p--;
 
        /* Trailing slashes. */
-       while ((p != path - 1) && *p == '/')
+       while (1) {
+               if (p == path - 1)
+                       return "";
+               if (*p != '/')
+                       break;
                p--;
+       }
 
        while ((p != path - 1) && *p != '/')
                p--;
index 933cfd73032f20f927c06aced94709eb3ec83e93..0b37899d36576a2f821264178748f5ef3dbb1eff 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
 #include "xml.h"
 #include <stdlib.h>
 
+#ifdef WITH_NTFS_3G
+#include <ntfs-3g/volume.h>
+#endif
+
 static int print_metadata(WIMStruct *w)
 {
        print_security_data(wim_security_data(w));
@@ -550,6 +554,12 @@ WIMLIBAPI void wimlib_free(WIMStruct *w)
                        destroy_image_metadata(&w->image_metadata[i], NULL);
                FREE(w->image_metadata);
        }
+#ifdef WITH_NTFS_3G
+       if (w->ntfs_vol) {
+               DEBUG("Unmounting NTFS volume");
+               ntfs_umount(w->ntfs_vol, FALSE);
+       }
+#endif
        FREE(w);
 }
 
index 008db34b3509390618df6ff721beb92d3929a30b..be4c60911648be2daee13604a5b90053698e4a49 100644 (file)
@@ -266,8 +266,10 @@ typedef struct WIMStruct {
                int add_flags;
                int write_flags;
                bool write_metadata;
-               ntfs_volume *ntfs_vol;
        };
+#ifdef WITH_NTFS_3G
+       ntfs_volume *ntfs_vol;
+#endif
 
        /* The currently selected image, indexed starting at 1.  If not 0,
         * subtract 1 from this to get the index of the current image in the