X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmodify.c;h=744ab2d7cdb42b908a80e3a944e095272e5eff8b;hb=36011d478b941ecaffbbbe98ec82f83916908add;hp=6b1239da3c2b738f17e62b0456bca69db7ba0b97;hpb=815ad485b8ce48db48a3137d73e511f6c9af868c;p=wimlib diff --git a/src/modify.c b/src/modify.c index 6b1239da..744ab2d7 100644 --- a/src/modify.c +++ b/src/modify.c @@ -42,15 +42,19 @@ * the WIM. */ #define WIMLIB_ADD_IMAGE_FLAG_ROOT 0x80000000 -static void destroy_image_metadata(struct image_metadata *imd, - struct lookup_table *lt) +void destroy_image_metadata(struct image_metadata *imd,struct lookup_table *lt) { - free_dentry_tree(imd->root_dentry, lt, true); + if (lt) + free_dentry_tree(imd->root_dentry, lt, true); + else + free_dentry_tree(imd->root_dentry, NULL, false); free_security_data(imd->security_data); + free_link_group_table(imd->lgt); /* Get rid of the lookup table entry for this image's metadata resource * */ - lookup_table_remove(lt, imd->metadata_lte); + if (lt) + lookup_table_remove(lt, imd->metadata_lte); } /* @@ -59,9 +63,7 @@ static void destroy_image_metadata(struct image_metadata *imd, * * @root: A dentry that has already been created for the root of the dentry * tree. - * @source_path: The path to the root of the tree on disk. - * @root_stat: A pointer to a `struct stat' that contains the metadata for the - * root of the tree on disk. + * @root_disk_path: The path to the root of the tree on disk. * @lookup_table: The lookup table for the WIM file. For each file added to the * dentry tree being built, an entry is added to the lookup table, * unless an identical file is already in the lookup table. These @@ -77,7 +79,7 @@ static int build_dentry_tree(struct dentry *root, const char *root_disk_path, struct lookup_table* lookup_table, int add_flags) { - DEBUG("`%s'", root_disk_path); + DEBUG("%s", root_disk_path); struct stat root_stbuf; int ret; int (*stat_fn)(const char *restrict, struct stat *restrict); @@ -129,10 +131,8 @@ static int build_dentry_tree(struct dentry *root, const char *root_disk_path, continue; strcpy(name + len + 1, p->d_name); child = new_dentry(p->d_name); - if (!child) { - ERROR("No memory to allocate new dentry"); + if (!child) return WIMLIB_ERR_NOMEM; - } ret = build_dentry_tree(child, name, lookup_table, add_flags); link_dentry(child, root); @@ -153,56 +153,20 @@ static int build_dentry_tree(struct dentry *root, const char *root_disk_path, } deref_name_buf[ret] = '\0'; DEBUG("Read symlink `%s'", deref_name_buf); - void *symlink_buf = make_symlink_reparse_data_buf(deref_name_buf, - &symlink_buf_len); - if (!symlink_buf) - return WIMLIB_ERR_NOMEM; - DEBUG("Made symlink reparse data buf (len = %zu, name len = %zu)", - symlink_buf_len, ret); - - u8 symlink_buf_hash[WIM_HASH_SIZE]; - sha1_buffer(symlink_buf, symlink_buf_len, symlink_buf_hash); - - ret = dentry_set_symlink_buf(root, symlink_buf_hash); - - if (ret != 0) { - FREE(symlink_buf); - return ret; - } - DEBUG("Created symlink buf"); - - struct lookup_table_entry *lte; - struct lookup_table_entry *existing_lte; - - existing_lte = lookup_resource(lookup_table, symlink_buf_hash); - if (existing_lte) { - existing_lte->refcnt++; - } else { - DEBUG("Creating new lookup table entry"); - lte = new_lookup_table_entry(); - if (!lte) { - FREE(symlink_buf); - return WIMLIB_ERR_NOMEM; - } - lte->symlink_buf = symlink_buf; - lte->resource_entry.original_size = symlink_buf_len; - lte->resource_entry.size = symlink_buf_len; - lte->is_symlink = true; - memcpy(lte->hash, symlink_buf_hash, WIM_HASH_SIZE); - lookup_table_insert(lookup_table, lte); - } + ret = dentry_set_symlink(root, deref_name_buf, lookup_table); } else { + /* Regular file */ struct lookup_table_entry *lte; - /* For each non-directory, we must check to see if the file is - * in the lookup table already; if it is, we increment its - * refcnt; otherwise, we create a new lookup table entry and - * insert it. */ + /* For each regular file, we must check to see if the file is in + * the lookup table already; if it is, we increment its refcnt; + * otherwise, we create a new lookup table entry and insert it. + * */ ret = sha1sum(root_disk_path, root->hash); if (ret != 0) return ret; - lte = lookup_resource(lookup_table, root->hash); + lte = __lookup_resource(lookup_table, root->hash); if (lte) { lte->refcnt++; } else { @@ -251,11 +215,13 @@ static int add_lookup_table_entry_to_dest_wim(struct dentry *dentry, void *arg) if (dentry_is_directory(dentry)) return 0; - src_table_entry = wim_lookup_resource(src_wim, dentry); + /* XXX ADS */ + src_table_entry = __lookup_resource(src_wim->lookup_table, dentry->hash); if (!src_table_entry) return 0; - dest_table_entry = wim_lookup_resource(dest_wim, dentry); + /* XXX ADS */ + dest_table_entry = __lookup_resource(dest_wim->lookup_table, dentry->hash); if (dest_table_entry) { dest_table_entry->refcnt++; } else { @@ -291,6 +257,7 @@ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry) struct image_metadata *imd; struct image_metadata *new_imd; struct wim_security_data *sd; + struct link_group_table *lgt; DEBUG("Reallocating image metadata array for image_count = %u", w->hdr.image_count + 1); @@ -313,22 +280,30 @@ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry) sd->refcnt = 1; sd->total_length = 8; + lgt = new_link_group_table(9001); + if (!lgt) + goto out_free_security_data; + metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; randomize_byte_array(metadata_lte->hash, WIM_HASH_SIZE); lookup_table_insert(w->lookup_table, metadata_lte); - w->hdr.image_count++; + new_imd = &imd[w->hdr.image_count]; - new_imd = &imd[w->hdr.image_count - 1]; - new_imd->metadata_lte = metadata_lte; - new_imd->modified = true; new_imd->root_dentry = root_dentry; + new_imd->metadata_lte = metadata_lte; new_imd->security_data = sd; + new_imd->lgt = lgt; + new_imd->modified = true; + FREE(w->image_metadata); w->image_metadata = imd; + w->hdr.image_count++; /* Change the current image to the new one. */ return wimlib_select_image(w, w->hdr.image_count); +out_free_security_data: + FREE(sd); out_free_metadata_lte: FREE(metadata_lte); out_free_imd: @@ -516,7 +491,6 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, const char *flags_element, int flags) { struct dentry *root_dentry; - struct stat root_stat; struct image_metadata *imd; int ret; @@ -567,6 +541,14 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, if (ret != 0) goto out_free_dentry_tree; + DEBUG("Inserting dentries into hard link group table"); + ret = for_dentry_in_tree(root_dentry, link_group_table_insert, + w->image_metadata[w->hdr.image_count - 1].lgt); + if (ret != 0) + goto out_destroy_imd; + DEBUG("Assigning hard link groups"); + assign_link_groups(w->image_metadata[w->hdr.image_count - 1].lgt); + if (flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) wimlib_set_boot_idx(w, w->hdr.image_count); @@ -578,6 +560,7 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, out_destroy_imd: destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1], w->lookup_table); + w->hdr.image_count--; return ret; out_free_dentry_tree: free_dentry_tree(root_dentry, w->lookup_table, true);