X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fntfs-capture.c;h=eadedac725a5efc33872a76855ddb5904852b4b0;hp=43caec0e9668634d63b74c62c0c98c5c1146c0ec;hb=8396da8b23c2c66cf7f8752f2c487cdc6c40516e;hpb=d9d4b6b3e0462d3419bb8a9964b5da38a72da02f diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 43caec0e..eadedac7 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -121,7 +121,7 @@ static int lookup_sd(const u8 hash[SHA1_HASH_SIZE], struct sd_node *root) * the security ID for it. If a new security descriptor cannot be allocated, * return -1. */ -static int sd_set_add_sd(struct sd_set *sd_set, const u8 *descriptor, +static int sd_set_add_sd(struct sd_set *sd_set, const char descriptor[], size_t size) { u8 hash[SHA1_HASH_SIZE]; @@ -132,7 +132,7 @@ static int sd_set_add_sd(struct sd_set *sd_set, const u8 *descriptor, u8 *descr_copy; struct wim_security_data *sd; - sha1_buffer(descriptor, size, hash); + sha1_buffer((const u8*)descriptor, size, hash); security_id = lookup_sd(hash, sd_set->root); if (security_id >= 0) return security_id; @@ -166,6 +166,7 @@ static int sd_set_add_sd(struct sd_set *sd_set, const u8 *descriptor, sd->descriptors[sd->num_entries] = descr_copy; sd->sizes[sd->num_entries] = size; sd->num_entries++; + DEBUG("There are now %d security descriptors", sd->num_entries); sd->total_length += size + sizeof(sd->sizes[0]); if (sd_set->root) @@ -242,7 +243,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, ntfs_attr_search_ctx *actx; u8 attr_hash[SHA1_HASH_SIZE]; - struct ntfs_location *ntfs_loc; + struct ntfs_location *ntfs_loc = NULL; struct lookup_table_entry *lte; int ret = 0; @@ -251,7 +252,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, /* Get context to search the streams of the NTFS file. */ actx = ntfs_attr_get_search_ctx(ni, NULL); if (!actx) { - ERROR_WITH_ERRNO("Cannot get attribute search " + ERROR_WITH_ERRNO("Cannot get NTFS attribute search " "context"); return WIMLIB_ERR_NTFS_3G; } @@ -275,8 +276,6 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, if (lte) { lte->refcnt++; } else { - struct ntfs_location *ntfs_loc; - ntfs_loc = CALLOC(1, sizeof(*ntfs_loc)); if (!ntfs_loc) goto out_put_actx; @@ -317,9 +316,10 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, dentry->lte = lte; } else { struct ads_entry *new_ads_entry; - stream_name_utf8 = utf16_to_utf8((const u8*)attr_record_name(actx->attr), + size_t stream_name_utf8_len; + stream_name_utf8 = utf16_to_utf8((const char*)attr_record_name(actx->attr), actx->attr->name_length, - &stream_name_utf16_len); + &stream_name_utf8_len); if (!stream_name_utf8) goto out_free_lte; new_ads_entry = dentry_add_ads(dentry, stream_name_utf8); @@ -360,13 +360,13 @@ struct readdir_ctx { ntfs_volume **ntfs_vol_p; }; -static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni, - char path[], size_t path_len, - struct lookup_table *lookup_table, - struct sd_set *sd_set, - const struct capture_config *config, - ntfs_volume **ntfs_vol_p); - +static int +build_dentry_tree_ntfs_recursive(struct dentry **root_p, ntfs_inode *ni, + char path[], size_t path_len, + struct lookup_table *lookup_table, + struct sd_set *sd_set, + const struct capture_config *config, + ntfs_volume **ntfs_vol_p); static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, const int name_len, const int name_type, @@ -385,7 +385,7 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, ret = -1; - utf8_name = utf16_to_utf8((const u8*)name, name_len * 2, + utf8_name = utf16_to_utf8((const char*)name, name_len * 2, &utf8_name_len); if (!utf8_name) goto out; @@ -412,16 +412,15 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, ctx->path[path_len++] = '/'; memcpy(ctx->path + path_len, utf8_name, utf8_name_len + 1); path_len += utf8_name_len; - ret = __build_dentry_tree_ntfs(&child, ni, ctx->path, path_len, - ctx->lookup_table, ctx->sd_set, - ctx->config, ctx->ntfs_vol_p); + ret = build_dentry_tree_ntfs_recursive(&child, ni, ctx->path, path_len, + ctx->lookup_table, ctx->sd_set, + ctx->config, ctx->ntfs_vol_p); 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: FREE(utf8_name); @@ -433,16 +432,18 @@ out: * At the same time, update the WIM lookup table with lookup table entries for * the NTFS streams, and build an array of security descriptors. */ -static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni, - char path[], size_t path_len, - struct lookup_table *lookup_table, - struct sd_set *sd_set, - const struct capture_config *config, - ntfs_volume **ntfs_vol_p) +static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, + ntfs_inode *ni, + char path[], + size_t path_len, + struct lookup_table *lookup_table, + struct sd_set *sd_set, + const struct capture_config *config, + ntfs_volume **ntfs_vol_p) { u32 attributes; int mrec_flags; - u32 sd_size; + u32 sd_size = 0; int ret = 0; struct dentry *root; @@ -463,10 +464,9 @@ static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni, root->creation_time = le64_to_cpu(ni->creation_time); root->last_write_time = le64_to_cpu(ni->last_data_change_time); root->last_access_time = le64_to_cpu(ni->last_access_time); - root->security_id = le32_to_cpu(ni->security_id); root->attributes = le32_to_cpu(attributes); - root->hard_link = ni->mft_no; - root->resolved = true; + root->link_group_id = ni->mft_no; + root->resolved = true; if (attributes & FILE_ATTR_REPARSE_POINT) { DEBUG("Reparse point `%s'", path); @@ -510,7 +510,7 @@ static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, NULL, 0, &sd_size); - u8 sd[sd_size]; + char sd[sd_size]; ret = ntfs_inode_get_security(ni, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | @@ -525,6 +525,10 @@ static int __build_dentry_tree_ntfs(struct dentry **root_p, ntfs_inode *ni, if (ret > 0) { /*print_security_descriptor(sd, sd_size);*/ root->security_id = sd_set_add_sd(sd_set, sd, sd_size); + if (root->security_id == -1) { + ERROR("Out of memory"); + return WIMLIB_ERR_NOMEM; + } DEBUG("Added security ID = %u for `%s'", root->security_id, path); } else { @@ -547,9 +551,10 @@ static int build_dentry_tree_ntfs(struct dentry **root_p, ntfs_volume *vol; ntfs_inode *root_ni; int ret = 0; - struct sd_set sd_set; - sd_set.sd = sd; - sd_set.root = NULL; + struct sd_set sd_set = { + .sd = sd, + .root = NULL, + }; ntfs_volume **ntfs_vol_p = extra_arg; DEBUG("Mounting NTFS volume `%s' read-only", device); @@ -561,6 +566,9 @@ static int build_dentry_tree_ntfs(struct dentry **root_p, return WIMLIB_ERR_NTFS_3G; } + /* We don't want to capture the special NTFS files such as $Bitmap. Not + * to be confused with "hidden" or "system" files which are real files + * that we do need to capture. */ NVolClearShowSysFiles(vol); DEBUG("Opening root NTFS dentry"); @@ -571,12 +579,22 @@ static int build_dentry_tree_ntfs(struct dentry **root_p, ret = WIMLIB_ERR_NTFS_3G; goto out; } - char path[4096]; + + /* Currently we assume that all the UTF-8 paths fit into this length and + * there is no check for overflow. */ + char *path = MALLOC(32768); + if (!path) { + ERROR("Could not allocate memory for NTFS pathname"); + goto out_cleanup; + } + path[0] = '/'; path[1] = '\0'; - ret = __build_dentry_tree_ntfs(root_p, root_ni, path, 1, - lookup_table, &sd_set, config, - ntfs_vol_p); + ret = build_dentry_tree_ntfs_recursive(root_p, root_ni, path, 1, + lookup_table, &sd_set, + config, ntfs_vol_p); +out_cleanup: + FREE(path); ntfs_inode_close(root_ni); destroy_sd_set(&sd_set); @@ -589,6 +607,8 @@ out: ret = WIMLIB_ERR_NTFS_3G; } } else { + /* We need to leave the NTFS volume mounted so that we can read + * the NTFS files again when we are actually writing the WIM */ *ntfs_vol_p = vol; } return ret; @@ -615,11 +635,9 @@ WIMLIBAPI int wimlib_add_image_from_ntfs_volume(WIMStruct *w, WIMLIBAPI int wimlib_add_image_from_ntfs_volume(WIMStruct *w, const char *device, const char *name, - const char *description, - const char *flags_element, - int flags, const char *config_str, - size_t config_len) + size_t config_len, + int flags) { ERROR("wimlib was compiled without support for NTFS-3g, so"); ERROR("we cannot capture a WIM image directly from a NTFS volume");