X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Flookup_table.c;h=393c0d68afaf74d90fe69bc9990a763f8c22b045;hp=43f9ca09148867b04ef4234d4b7b003645f3cd6c;hb=9fb3aaca115429b0af2a623bf20bfceef74f047f;hpb=1530b6dab02a9e1e5faf81529ab502aee68d8cd2 diff --git a/src/lookup_table.c b/src/lookup_table.c index 43f9ca09..393c0d68 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -1,12 +1,12 @@ /* * lookup_table.c * - * Lookup table, implemented as a hash table, that maps dentries to file - * resources. + * Lookup table, implemented as a hash table, that maps SHA1 message digests to + * data streams. */ /* - * Copyright (C) 2012 Eric Biggers + * Copyright (C) 2012, 2013 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -84,6 +84,18 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old) memcpy(new, old, sizeof(*old)); new->extracted_file = NULL; switch (new->resource_location) { +#ifdef __WIN32__ + case RESOURCE_WIN32: + { + size_t nbytes = utf16le_strlen(old->win32_file_on_disk); + new->win32_file_on_disk = MALLOC(nbytes + 2); + if (!new->win32_file_on_disk) + goto out_free; + memcpy(new->win32_file_on_disk, old->win32_file_on_disk, + nbytes + 2); + } + break; +#endif case RESOURCE_IN_STAGING_FILE: case RESOURCE_IN_FILE_ON_DISK: BUILD_BUG_ON((void*)&old->file_on_disk != @@ -107,18 +119,18 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old) if (!loc) goto out_free; memcpy(loc, old->ntfs_loc, sizeof(*loc)); - loc->path_utf8 = NULL; - loc->stream_name_utf16 = NULL; + loc->path = NULL; + loc->stream_name = NULL; new->ntfs_loc = loc; - loc->path_utf8 = STRDUP(old->ntfs_loc->path_utf8); - if (!loc->path_utf8) + loc->path = STRDUP(old->ntfs_loc->path); + if (!loc->path) goto out_free; - loc->stream_name_utf16 = MALLOC(loc->stream_name_utf16_num_chars * 2); - if (!loc->stream_name_utf16) + loc->stream_name = MALLOC((loc->stream_name_nchars + 1) * 2); + if (!loc->stream_name) goto out_free; - memcpy(loc->stream_name_utf16, - old->ntfs_loc->stream_name_utf16, - loc->stream_name_utf16_num_chars * 2); + memcpy(loc->stream_name, + old->ntfs_loc->stream_name, + (loc->stream_name_nchars + 1) * 2); } break; #endif @@ -138,6 +150,9 @@ void free_lookup_table_entry(struct wim_lookup_table_entry *lte) case RESOURCE_IN_STAGING_FILE: case RESOURCE_IN_ATTACHED_BUFFER: case RESOURCE_IN_FILE_ON_DISK: +#ifdef __WIN32__ + case RESOURCE_WIN32: +#endif BUILD_BUG_ON((void*)<e->file_on_disk != (void*)<e->staging_file_name); BUILD_BUG_ON((void*)<e->file_on_disk != @@ -147,8 +162,8 @@ void free_lookup_table_entry(struct wim_lookup_table_entry *lte) #ifdef WITH_NTFS_3G case RESOURCE_IN_NTFS_VOLUME: if (lte->ntfs_loc) { - FREE(lte->ntfs_loc->path_utf8); - FREE(lte->ntfs_loc->stream_name_utf16); + FREE(lte->ntfs_loc->path); + FREE(lte->ntfs_loc->stream_name); FREE(lte->ntfs_loc); } break; @@ -186,7 +201,7 @@ void free_lookup_table(struct wim_lookup_table *table) * Inserts an entry into the lookup table. * * @table: A pointer to the lookup table. - * @entry: A pointer to the entry to insert. + * @lte: A pointer to the entry to insert. */ void lookup_table_insert(struct wim_lookup_table *table, struct wim_lookup_table_entry *lte) @@ -344,12 +359,14 @@ int read_lookup_table(WIMStruct *w) && !((duplicate_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) && cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)) { + #ifdef ENABLE_ERROR_MESSAGES ERROR("The WIM lookup table contains two entries with the " "same SHA1 message digest!"); ERROR("The first entry is:"); - print_lookup_table_entry(duplicate_entry); + print_lookup_table_entry(duplicate_entry, stderr); ERROR("The second entry is:"); - print_lookup_table_entry(cur_entry); + print_lookup_table_entry(cur_entry, stderr); + #endif ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; goto out_free_cur_entry; } @@ -358,18 +375,22 @@ int read_lookup_table(WIMStruct *w) && (cur_entry->resource_entry.size != cur_entry->resource_entry.original_size)) { + #ifdef ENABLE_ERROR_MESSAGES ERROR("Found uncompressed resource with original size " "not the same as compressed size"); ERROR("The lookup table entry for the resource is as follows:"); - print_lookup_table_entry(cur_entry); + print_lookup_table_entry(cur_entry, stderr); + #endif ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; goto out_free_cur_entry; } if ((cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) && cur_entry->refcnt != 1) { + #ifdef ENABLE_ERROR_MESSAGES ERROR("Found metadata resource with refcnt != 1:"); - print_lookup_table_entry(cur_entry); + print_lookup_table_entry(cur_entry, stderr); + #endif ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; goto out_free_cur_entry; } @@ -403,9 +424,11 @@ int write_lookup_table_entry(struct wim_lookup_table_entry *lte, void *__out) if (lte->out_refcnt == 0) return 0; - if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA) - DEBUG("Writing metadata entry at %lu (orig size = %zu)", + if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA) { + DEBUG("Writing metadata entry at %"PRIu64" " + "(orig size = %"PRIu64")", ftello(out), lte->output_resource_entry.original_size); + } p = put_resource_entry(buf, <e->output_resource_entry); p = put_u16(p, lte->part_number); @@ -467,57 +490,58 @@ int lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *ignore) return 0; } -void print_lookup_table_entry(const struct wim_lookup_table_entry *lte) +void print_lookup_table_entry(const struct wim_lookup_table_entry *lte, + FILE *out) { if (!lte) { - putchar('\n'); + putc('\n', out); return; } - printf("Offset = %"PRIu64" bytes\n", + fprintf(out, "Offset = %"PRIu64" bytes\n", lte->resource_entry.offset); - printf("Size = %"PRIu64" bytes\n", + fprintf(out, "Size = %"PRIu64" bytes\n", (u64)lte->resource_entry.size); - printf("Original size = %"PRIu64" bytes\n", + fprintf(out, "Original size = %"PRIu64" bytes\n", lte->resource_entry.original_size); - printf("Part Number = %hu\n", lte->part_number); - printf("Reference Count = %u\n", lte->refcnt); - printf("Hash = 0x"); + fprintf(out, "Part Number = %hu\n", lte->part_number); + fprintf(out, "Reference Count = %u\n", lte->refcnt); + fprintf(out, "Hash = 0x"); print_hash(lte->hash); - putchar('\n'); - printf("Flags = "); + putc('\n', out); + fprintf(out, "Flags = "); u8 flags = lte->resource_entry.flags; if (flags & WIM_RESHDR_FLAG_COMPRESSED) - fputs("WIM_RESHDR_FLAG_COMPRESSED, ", stdout); + fputs("WIM_RESHDR_FLAG_COMPRESSED, ", out); if (flags & WIM_RESHDR_FLAG_FREE) - fputs("WIM_RESHDR_FLAG_FREE, ", stdout); + fputs("WIM_RESHDR_FLAG_FREE, ", out); if (flags & WIM_RESHDR_FLAG_METADATA) - fputs("WIM_RESHDR_FLAG_METADATA, ", stdout); + fputs("WIM_RESHDR_FLAG_METADATA, ", out); if (flags & WIM_RESHDR_FLAG_SPANNED) - fputs("WIM_RESHDR_FLAG_SPANNED, ", stdout); - putchar('\n'); + fputs("WIM_RESHDR_FLAG_SPANNED, ", out); + putc('\n', out); switch (lte->resource_location) { case RESOURCE_IN_WIM: if (lte->wim->filename) { - printf("WIM file = `%s'\n", + fprintf(out, "WIM file = `%s'\n", lte->wim->filename); } break; case RESOURCE_IN_FILE_ON_DISK: - printf("File on Disk = `%s'\n", lte->file_on_disk); + fprintf(out, "File on Disk = `%s'\n", lte->file_on_disk); break; case RESOURCE_IN_STAGING_FILE: - printf("Staging File = `%s'\n", lte->staging_file_name); + fprintf(out, "Staging File = `%s'\n", lte->staging_file_name); break; default: break; } - putchar('\n'); + putc('\n', out); } static int do_print_lookup_table_entry(struct wim_lookup_table_entry *lte, - void *ignore) + void *fp) { - print_lookup_table_entry(lte); + print_lookup_table_entry(lte, (FILE*)fp); return 0; } @@ -528,7 +552,7 @@ WIMLIBAPI void wimlib_print_lookup_table(WIMStruct *w) { for_lookup_table_entry(w->lookup_table, do_print_lookup_table_entry, - NULL); + stdout); } /* Given a SHA1 message digest, return the corresponding entry in the WIM's @@ -557,23 +581,25 @@ __lookup_resource(const struct wim_lookup_table *table, const u8 hash[]) * * This is only for pre-resolved inodes. */ -int lookup_resource(WIMStruct *w, const char *path, - int lookup_flags, - struct wim_dentry **dentry_ret, - struct wim_lookup_table_entry **lte_ret, - u16 *stream_idx_ret) +int +lookup_resource(WIMStruct *w, + const mbchar *path, + int lookup_flags, + struct wim_dentry **dentry_ret, + struct wim_lookup_table_entry **lte_ret, + u16 *stream_idx_ret) { struct wim_dentry *dentry; struct wim_lookup_table_entry *lte; u16 stream_idx; - const char *stream_name = NULL; + const mbchar *stream_name = NULL; struct wim_inode *inode; - char *p = NULL; + mbchar *p = NULL; if (lookup_flags & LOOKUP_FLAG_ADS_OK) { stream_name = path_stream_name(path); if (stream_name) { - p = (char*)stream_name - 1; + p = (mbchar*)stream_name - 1; *p = '\0'; } } @@ -582,7 +608,7 @@ int lookup_resource(WIMStruct *w, const char *path, if (p) *p = ':'; if (!dentry) - return -ENOENT; + return -errno; inode = dentry->d_inode; @@ -593,7 +619,7 @@ int lookup_resource(WIMStruct *w, const char *path, return -EISDIR; if (stream_name) { - struct ads_entry *ads_entry; + struct wim_ads_entry *ads_entry; u16 ads_idx; ads_entry = inode_get_ads_entry(inode, stream_name, &ads_idx); @@ -640,7 +666,7 @@ void inode_resolve_ltes(struct wim_inode *inode, struct wim_lookup_table *table) /* Resolve the alternate data streams */ for (u16 i = 0; i < inode->i_num_ads; i++) { - struct ads_entry *cur_entry = &inode->i_ads_entries[i]; + struct wim_ads_entry *cur_entry = &inode->i_ads_entries[i]; lte = __lookup_resource(table, cur_entry->hash); cur_entry->lte = lte; }