From: Eric Biggers Date: Mon, 27 Aug 2012 22:30:07 +0000 (-0500) Subject: NTFS capture updates X-Git-Tag: v1.0.0~65 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=1dde5fb0d809f2f5e032e4d5241d1cb15ff3eb65 NTFS capture updates --- diff --git a/programs/imagex.c b/programs/imagex.c index d41964a2..fe7f3be9 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -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" diff --git a/src/dentry.c b/src/dentry.c index 3f258b76..a0d0febd 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -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 diff --git a/src/lookup_table.h b/src/lookup_table.h index 6a07aaa9..c211fe14 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -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 */ diff --git a/src/modify.c b/src/modify.c index 3b321c37..141f2dd8 100644 --- a/src/modify.c +++ b/src/modify.c @@ -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" diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 5d8ebcf8..751ce50f 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -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; } diff --git a/src/resource.c b/src/resource.c index d81421c5..73cea71c 100644 --- a/src/resource.c +++ b/src/resource.c @@ -36,6 +36,11 @@ #include #include +#ifdef WITH_NTFS_3G +#include +#include +#include +#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; diff --git a/src/util.c b/src/util.c index fdb0c850..8f4e0c0b 100644 --- a/src/util.c +++ b/src/util.c @@ -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--; diff --git a/src/wim.c b/src/wim.c index 933cfd73..0b37899d 100644 --- a/src/wim.c +++ b/src/wim.c @@ -30,6 +30,10 @@ #include "xml.h" #include +#ifdef WITH_NTFS_3G +#include +#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); } diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 008db34b..be4c6091 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -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