]> wimlib.net Git - wimlib/blobdiff - src/resource.c
NTFS capture updates
[wimlib] / src / resource.c
index 2dde8d55578435c39b64151746a6c1e1dbe88abd..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.
@@ -447,16 +452,11 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
                                                        ctype, size, offset, buf);
                break;
        case RESOURCE_IN_STAGING_FILE:
-               /* The WIM FUSE implementation needs to handle multiple open
-                * file descriptors per lookup table entry so it does not
-                * currently work with this function. */
-               wimlib_assert(lte->staging_file_name);
-               wimlib_assert(0);
-               break;
        case RESOURCE_IN_FILE_ON_DISK:
                /* The resource is in some file on the external filesystem and
                 * needs to be read uncompressed */
                wimlib_assert(lte->file_on_disk);
+               wimlib_assert(&lte->file_on_disk == &lte->staging_file_name);
                /* Use existing file pointer if available; otherwise open one
                 * temporarily */
                if (lte->file_on_disk_fp) {
@@ -480,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);
        }
@@ -723,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);
@@ -778,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
@@ -880,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;
@@ -1185,11 +1233,9 @@ int write_metadata_resource(WIMStruct *w)
 
        root = wim_root_dentry(w);
 
-       struct wim_security_data *sd = wim_security_data(w);
-       if (sd)
-               subdir_offset = sd->total_length + root->length + 8;
-       else
-               subdir_offset = 8 + root->length + 8;
+       const struct wim_security_data *sd = wim_security_data(w);
+       wimlib_assert(sd);
+       subdir_offset = sd->total_length + root->length + 8;
        calculate_subdir_offsets(root, &subdir_offset);
        metadata_original_size = subdir_offset + random_tail_len;
        buf = MALLOC(metadata_original_size);
@@ -1216,7 +1262,7 @@ int write_metadata_resource(WIMStruct *w)
        lookup_table_unlink(w->lookup_table, lte);
        lookup_table_insert(w->lookup_table, lte);
        wimlib_assert(lte->out_refcnt == 0);
-       lte->out_refcnt++;
+       lte->out_refcnt = 1;
        lte->output_resource_entry.flags |= WIM_RESHDR_FLAG_METADATA;
 out:
        FREE(buf);