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"
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
struct wimlib_fd;
+#ifdef WITH_NTFS_3G
typedef struct _ntfs_attr ntfs_attr;
typedef struct _ntfs_volume ntfs_volume;
struct ntfs_location {
ntfs_volume **ntfs_vol_p;
bool is_reparse_point;
};
+#endif
/*
* An entry in the lookup table in the WIM file.
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 */
"\\$ntfs.log\n"
"\\hiberfil.sys\n"
"\\pagefile.sys\n"
-"\"\\System Volume Information\"\n"
+"\\System Volume Information\n"
"\\RECYCLER\n"
"\\Windows\\CSC\n"
"\n"
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);
}
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,
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:
.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 */
if (ret != 0)
return ret;
- DEBUG("Getting security information from `%s'", path);
ret = ntfs_inode_get_security(ni,
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
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;
}
#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.
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);
}
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);
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
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;
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--;
#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));
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);
}
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