From: Eric Biggers Date: Thu, 16 Jan 2014 00:52:10 +0000 (-0600) Subject: Remove some printing code from library X-Git-Tag: v1.6.1~30 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=2850f8933244f6c63f608eec612ad804e01072e1;ds=sidebyside Remove some printing code from library Remove print_lookup_table_entry(), print_dentry(), and print_security_data() from the library. Turn wimlib_print_metadata() into a stub and replace it with code in `wimlib-imagex dir' that uses wimlib_iterate_dir_tree(). Also, on Windows use ConvertSecurityDescriptorToStringSecurityDescriptorW() to print security descriptors in string format. --- diff --git a/NEWS b/NEWS index f1e10d97..469425b7 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,10 @@ Version 1.6.1: changing the compression type from None to LZX with no chunk size explicitly specified, for example). + 'wiminfo' no longer accepts the '--metadata' option. Use the new + '--detailed' option to 'wimdir' instead. (This is primarily for + debugging.) + Version 1.6.0: Support for extracting and updating the new version 3584 WIMs has been added. These WIMs typically pack many streams ("files") together into a diff --git a/doc/imagex-dir.1.in b/doc/imagex-dir.1.in index d7937b51..e0f49c46 100644 --- a/doc/imagex-dir.1.in +++ b/doc/imagex-dir.1.in @@ -19,13 +19,15 @@ to show what images a WIM file contains. \fB--path\fR=\fIPATH\fR List the files recursively from the \fIPATH\fR directory instead of from the root directory. +.TP +\fB--detailed\fR +List detailed information about each file. .SH NOTES \fB@IMAGEX_PROGNAME@ dir\fR supports split WIMs, but it will only work on the first part of the split WIM. .PP -The DOS names of files are not displayed. -.PP -Alternate (named) data streams are not displayed. +DOS names and alternate (named) data streams are not listed unless the +\fB--detailed\fR mode is used. .SH EXAMPLES List all files in the first image of 'boot.wim': .RS diff --git a/doc/imagex-info.1.in b/doc/imagex-info.1.in index 22bae39a..0bcbc4d0 100644 --- a/doc/imagex-info.1.in +++ b/doc/imagex-info.1.in @@ -55,14 +55,9 @@ Shows detailed information from the WIM header. \fB--lookup-table\fR Prints all the entries in the stream lookup table of the WIM. .TP -\fB--metadata\fR -Prints the metadata, including the security data and the directory entry tree -but not the XML data, for the specified image. If no image is specified, the -metadata for all images is printed. This only works on standalone WIMs or on -the first part of a split WIM. -.TP \fB--xml\fR Prints the raw XML data from the WIM. Note: the XML data will be encoded using UTF-16LE, and it will begin with a byte-order mark. .SH SEE ALSO .BR @IMAGEX_PROGNAME@ (1) +.BR @IMAGEX_PROGNAME@-dir (1) diff --git a/include/wimlib.h b/include/wimlib.h index de10307c..28f5e9ef 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -3146,15 +3146,6 @@ wimlib_print_available_images(const WIMStruct *wim, int image); extern void wimlib_print_header(const WIMStruct *wim) _wimlib_deprecated; -/** - * @ingroup G_wim_information - * - * Deprecated in favor of wimlib_iterate_dir_tree(), which provides the - * information in a way that can be accessed programatically. - */ -extern int -wimlib_print_metadata(WIMStruct *wim, int image) _wimlib_deprecated; - /** * @ingroup G_nonstandalone_wims * @@ -4344,10 +4335,19 @@ wimlib_xpress_decompress(const void *cdata, unsigned clen, void *udata, unsigned ulen) _wimlib_deprecated; + /** * @} */ +/** @ingroup G_wim_information + * + * Deprecated and will return ::WIMLIB_ERR_UNSUPPORTED. Use + * wimlib_iterate_dir_tree() instead. */ +extern int +wimlib_print_metadata(WIMStruct *wim, int image) + _wimlib_deprecated; + #ifdef __cplusplus } diff --git a/include/wimlib/dentry.h b/include/wimlib/dentry.h index 0466fb5a..ce09dd81 100644 --- a/include/wimlib/dentry.h +++ b/include/wimlib/dentry.h @@ -219,12 +219,6 @@ wim_pathname_to_stream(WIMStruct *wim, u16 *stream_idx_ret); #endif -extern int -print_dentry(struct wim_dentry *dentry, void *lookup_table); - -extern int -print_dentry_full_path(struct wim_dentry *entry, void *ignore); - extern int calculate_dentry_full_path(struct wim_dentry *dentry); diff --git a/include/wimlib/lookup_table.h b/include/wimlib/lookup_table.h index 82138e35..d4a46c7f 100644 --- a/include/wimlib/lookup_table.h +++ b/include/wimlib/lookup_table.h @@ -261,9 +261,6 @@ extern struct wim_lookup_table_entry * clone_lookup_table_entry(const struct wim_lookup_table_entry *lte) _malloc_attribute; -extern void -print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out); - extern void lte_decrement_refcnt(struct wim_lookup_table_entry *lte, struct wim_lookup_table *table); diff --git a/programs/imagex-win32.c b/programs/imagex-win32.c index 083c1453..0d87bab3 100644 --- a/programs/imagex-win32.c +++ b/programs/imagex-win32.c @@ -83,3 +83,41 @@ void set_fd_to_binary_mode(int fd) { _setmode(fd, _O_BINARY); } + +#include + +static wchar_t * +get_security_descriptor_string(PSECURITY_DESCRIPTOR desc) +{ + wchar_t *str = NULL; + /* 53 characters!!! */ + ConvertSecurityDescriptorToStringSecurityDescriptorW( + desc, + SDDL_REVISION_1, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION, + &str, + NULL); + return str; +} + +void +win32_print_security_descriptor(const uint8_t *sd, size_t size) +{ + wchar_t *str; + const wchar_t *printstr; + + /* 'size' is ignored here due to the crappy Windows APIs. Oh well, this + * is just for debugging anyway. */ + str = get_security_descriptor_string((PSECURITY_DESCRIPTOR)sd); + if (str) + printstr = str; + else + printstr = L"(invalid)"; + + wprintf(L"Security Descriptor = %ls\n", printstr); + + LocalFree(str); +} diff --git a/programs/imagex-win32.h b/programs/imagex-win32.h index bf1d2a7f..e49bd1c1 100644 --- a/programs/imagex-win32.h +++ b/programs/imagex-win32.h @@ -3,6 +3,7 @@ #include #include +#include #include extern wchar_t * @@ -11,6 +12,9 @@ win32_mbs_to_wcs(const char *mbs, size_t mbs_nbytes, size_t *num_wchars_ret); extern wchar_t * win32_wbasename(wchar_t *path); +extern void +win32_print_security_descriptor(const uint8_t *sd, size_t size); + extern void set_fd_to_binary_mode(int fd); diff --git a/programs/imagex.c b/programs/imagex.c index 5dd52322..f795ded7 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -51,6 +51,7 @@ # define tbasename win32_wbasename # define OS_PREFERRED_PATH_SEPARATOR L'\\' # define OS_PREFERRED_PATH_SEPARATOR_STRING L"\\" +# define print_security_descriptor win32_print_security_descriptor #else /* __WIN32__ */ # include # include @@ -58,6 +59,7 @@ # define tbasename basename # define OS_PREFERRED_PATH_SEPARATOR '/' # define OS_PREFERRED_PATH_SEPARATOR_STRING "/" +# define print_security_descriptor default_print_security_descriptor static inline void set_fd_to_binary_mode(int fd) { } @@ -130,6 +132,7 @@ enum { IMAGEX_DELTA_FROM_OPTION, IMAGEX_DEREFERENCE_OPTION, IMAGEX_DEST_DIR_OPTION, + IMAGEX_DETAILED_OPTION, IMAGEX_EXTRACT_XML_OPTION, IMAGEX_FLAGS_OPTION, IMAGEX_FORCE_OPTION, @@ -227,7 +230,8 @@ static const struct option delete_options[] = { }; static const struct option dir_options[] = { - {T("path"), required_argument, NULL, IMAGEX_PATH_OPTION}, + {T("path"), required_argument, NULL, IMAGEX_PATH_OPTION}, + {T("detailed"), no_argument, NULL, IMAGEX_DETAILED_OPTION}, {NULL, 0, NULL, 0}, }; @@ -2366,11 +2370,205 @@ out_usage: goto out; } +struct print_dentry_options { + bool detailed; +}; + +static void +print_dentry_full_path(const struct wimlib_dir_entry *dentry) +{ + tprintf(T("%"TS"\n"), dentry->full_path); +} + +static const struct { + uint32_t flag; + const tchar *name; +} file_attr_flags[] = { + {WIMLIB_FILE_ATTRIBUTE_READONLY, T("READONLY")}, + {WIMLIB_FILE_ATTRIBUTE_HIDDEN, T("HIDDEN")}, + {WIMLIB_FILE_ATTRIBUTE_SYSTEM, T("SYSTEM")}, + {WIMLIB_FILE_ATTRIBUTE_DIRECTORY, T("DIRECTORY")}, + {WIMLIB_FILE_ATTRIBUTE_ARCHIVE, T("ARCHIVE")}, + {WIMLIB_FILE_ATTRIBUTE_DEVICE, T("DEVICE")}, + {WIMLIB_FILE_ATTRIBUTE_NORMAL, T("NORMAL")}, + {WIMLIB_FILE_ATTRIBUTE_TEMPORARY, T("TEMPORARY")}, + {WIMLIB_FILE_ATTRIBUTE_SPARSE_FILE, T("SPARSE_FILE")}, + {WIMLIB_FILE_ATTRIBUTE_REPARSE_POINT, T("REPARSE_POINT")}, + {WIMLIB_FILE_ATTRIBUTE_COMPRESSED, T("COMPRESSED")}, + {WIMLIB_FILE_ATTRIBUTE_OFFLINE, T("OFFLINE")}, + {WIMLIB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, T("NOT_CONTENT_INDEXED")}, + {WIMLIB_FILE_ATTRIBUTE_ENCRYPTED, T("ENCRYPTED")}, + {WIMLIB_FILE_ATTRIBUTE_VIRTUAL, T("VIRTUAL")}, +}; + +#define TIMESTR_MAX 100 + +static void +timespec_to_string(const struct timespec *spec, tchar *buf) +{ + time_t t = spec->tv_sec; + struct tm tm; + gmtime_r(&t, &tm); + tstrftime(buf, TIMESTR_MAX, T("%a %b %d %H:%M:%S %Y UTC"), &tm); + buf[TIMESTR_MAX - 1] = '\0'; +} + +static void +print_time(const tchar *type, const struct timespec *spec) +{ + tchar timestr[TIMESTR_MAX]; + + timespec_to_string(spec, timestr); + + tprintf(T("%-20"TS"= %"TS"\n"), type, timestr); +} + +static void print_byte_field(const uint8_t field[], size_t len) +{ + while (len--) + tprintf(T("%02hhx"), *field++); +} + +static void +print_wim_information(const tchar *wimfile, const struct wimlib_wim_info *info) +{ + tputs(T("WIM Information:")); + tputs(T("----------------")); + tprintf(T("Path: %"TS"\n"), wimfile); + tprintf(T("GUID: 0x")); + print_byte_field(info->guid, sizeof(info->guid)); + tputchar(T('\n')); + tprintf(T("Version: %u\n"), info->wim_version); + tprintf(T("Image Count: %d\n"), info->image_count); + tprintf(T("Compression: %"TS"\n"), + wimlib_get_compression_type_string(info->compression_type)); + tprintf(T("Chunk Size: %"PRIu32" bytes\n"), + info->chunk_size); + tprintf(T("Part Number: %d/%d\n"), info->part_number, info->total_parts); + tprintf(T("Boot Index: %d\n"), info->boot_index); + tprintf(T("Size: %"PRIu64" bytes\n"), info->total_bytes); + tprintf(T("Integrity Info: %"TS"\n"), + info->has_integrity_table ? T("yes") : T("no")); + tprintf(T("Relative path junction: %"TS"\n"), + info->has_rpfix ? T("yes") : T("no")); + tprintf(T("Pipable: %"TS"\n"), + info->pipable ? T("yes") : T("no")); + tputchar(T('\n')); +} + +static int +print_resource(const struct wimlib_resource_entry *resource, + void *_ignore) +{ + tprintf(T("Hash = 0x")); + print_byte_field(resource->sha1_hash, sizeof(resource->sha1_hash)); + tputchar(T('\n')); + + if (!resource->is_missing) { + tprintf(T("Uncompressed size = %"PRIu64" bytes\n"), + resource->uncompressed_size); + if (resource->packed) { + tprintf(T("Raw compressed size = %"PRIu64" bytes\n"), + resource->raw_resource_compressed_size); + + tprintf(T("Raw offset in WIM = %"PRIu64" bytes\n"), + resource->raw_resource_offset_in_wim); + + tprintf(T("Offset in raw = %"PRIu64" bytes\n"), + resource->offset); + } else { + tprintf(T("Compressed size = %"PRIu64" bytes\n"), + resource->compressed_size); + + tprintf(T("Offset in WIM = %"PRIu64" bytes\n"), + resource->offset); + } + + tprintf(T("Part Number = %u\n"), resource->part_number); + tprintf(T("Reference Count = %u\n"), resource->reference_count); + + tprintf(T("Flags = ")); + if (resource->is_compressed) + tprintf(T("WIM_RESHDR_FLAG_COMPRESSED ")); + if (resource->is_metadata) + tprintf(T("WIM_RESHDR_FLAG_METADATA ")); + if (resource->is_free) + tprintf(T("WIM_RESHDR_FLAG_FREE ")); + if (resource->is_spanned) + tprintf(T("WIM_RESHDR_FLAG_SPANNED ")); + if (resource->packed) + tprintf(T("WIM_RESHDR_FLAG_PACKED_STREAMS ")); + tputchar(T('\n')); + } + tputchar(T('\n')); + return 0; +} + +static void +print_lookup_table(WIMStruct *wim) +{ + wimlib_iterate_lookup_table(wim, 0, print_resource, NULL); +} + +static void +default_print_security_descriptor(const uint8_t *sd, size_t size) +{ + tprintf(T("Security Descriptor = ")); + print_byte_field(sd, size); + tputchar(T('\n')); +} + +static void +print_dentry_detailed(const struct wimlib_dir_entry *dentry) +{ + + tprintf(T( +"----------------------------------------------------------------------------\n")); + tprintf(T("Full Path = \"%"TS"\"\n"), dentry->full_path); + if (dentry->dos_name) + tprintf(T("Short Name = \"%"TS"\"\n"), dentry->dos_name); + tprintf(T("Attributes = 0x%08x\n"), dentry->attributes); + for (size_t i = 0; i < ARRAY_LEN(file_attr_flags); i++) + if (file_attr_flags[i].flag & dentry->attributes) + tprintf(T(" FILE_ATTRIBUTE_%"TS" is set\n"), + file_attr_flags[i].name); + + if (dentry->security_descriptor) { + print_security_descriptor(dentry->security_descriptor, + dentry->security_descriptor_size); + } + + print_time(T("Creation Time"), &dentry->creation_time); + print_time(T("Last Write Time"), &dentry->last_write_time); + print_time(T("Last Access Time"), &dentry->last_access_time); + + + if (dentry->attributes & WIMLIB_FILE_ATTRIBUTE_REPARSE_POINT) + tprintf(T("Reparse Tag = 0x%"PRIx32"\n"), dentry->reparse_tag); + + tprintf(T("Link Group ID = 0x%016"PRIx64"\n"), dentry->hard_link_group_id); + tprintf(T("Link Count = %"PRIu32"\n"), dentry->num_links); + + for (uint32_t i = 0; i <= dentry->num_named_streams; i++) { + if (dentry->streams[i].stream_name) { + tprintf(T("\tData stream \"%"TS"\":\n"), + dentry->streams[i].stream_name); + } else { + tprintf(T("\tUnnamed data stream:\n")); + } + print_resource(&dentry->streams[i].resource, NULL); + } +} + static int -print_full_path(const struct wimlib_dir_entry *wdentry, void *_ignore) +print_dentry(const struct wimlib_dir_entry *dentry, void *_options) { - int ret = tprintf(T("%"TS"\n"), wdentry->full_path); - return (ret >= 0) ? 0 : -1; + const struct print_dentry_options *options = _options; + if (!options->detailed) + print_dentry_full_path(dentry); + else + print_dentry_detailed(dentry); + return 0; } /* Print the files contained in an image(s) in a WIM file. */ @@ -2383,12 +2581,18 @@ imagex_dir(int argc, tchar **argv, int cmd) int ret; const tchar *path = T(""); int c; + struct print_dentry_options options = { + .detailed = false, + }; for_opt(c, dir_options) { switch (c) { case IMAGEX_PATH_OPTION: path = optarg; break; + case IMAGEX_DETAILED_OPTION: + options.detailed = true; + break; default: goto out_usage; } @@ -2434,7 +2638,7 @@ imagex_dir(int argc, tchar **argv, int cmd) ret = wimlib_iterate_dir_tree(wim, image, path, WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE, - print_full_path, NULL); + print_dentry, &options); out_wimlib_free: wimlib_free(wim); out: @@ -2902,91 +3106,6 @@ out_err: goto out_free_refglobs; } -static void print_byte_field(const uint8_t field[], size_t len) -{ - while (len--) - tprintf(T("%02hhx"), *field++); -} - -static void -print_wim_information(const tchar *wimfile, const struct wimlib_wim_info *info) -{ - tputs(T("WIM Information:")); - tputs(T("----------------")); - tprintf(T("Path: %"TS"\n"), wimfile); - tprintf(T("GUID: 0x")); - print_byte_field(info->guid, sizeof(info->guid)); - tputchar(T('\n')); - tprintf(T("Version: %u\n"), info->wim_version); - tprintf(T("Image Count: %d\n"), info->image_count); - tprintf(T("Compression: %"TS"\n"), - wimlib_get_compression_type_string(info->compression_type)); - tprintf(T("Chunk Size: %"PRIu32" bytes\n"), - info->chunk_size); - tprintf(T("Part Number: %d/%d\n"), info->part_number, info->total_parts); - tprintf(T("Boot Index: %d\n"), info->boot_index); - tprintf(T("Size: %"PRIu64" bytes\n"), info->total_bytes); - tprintf(T("Integrity Info: %"TS"\n"), - info->has_integrity_table ? T("yes") : T("no")); - tprintf(T("Relative path junction: %"TS"\n"), - info->has_rpfix ? T("yes") : T("no")); - tprintf(T("Pipable: %"TS"\n"), - info->pipable ? T("yes") : T("no")); - tputchar(T('\n')); -} - -static int -print_resource(const struct wimlib_resource_entry *resource, - void *_ignore) -{ - tprintf(T("Uncompressed size = %"PRIu64" bytes\n"), - resource->uncompressed_size); - if (resource->packed) { - tprintf(T("Raw compressed size = %"PRIu64" bytes\n"), - resource->raw_resource_compressed_size); - - tprintf(T("Raw offset in WIM = %"PRIu64" bytes\n"), - resource->raw_resource_offset_in_wim); - - tprintf(T("Offset in raw = %"PRIu64" bytes\n"), - resource->offset); - } else { - tprintf(T("Compressed size = %"PRIu64" bytes\n"), - resource->compressed_size); - - tprintf(T("Offset in WIM = %"PRIu64" bytes\n"), - resource->offset); - } - - tprintf(T("Part Number = %u\n"), resource->part_number); - tprintf(T("Reference Count = %u\n"), resource->reference_count); - - tprintf(T("Hash = 0x")); - print_byte_field(resource->sha1_hash, sizeof(resource->sha1_hash)); - tputchar(T('\n')); - - tprintf(T("Flags = ")); - if (resource->is_compressed) - tprintf(T("WIM_RESHDR_FLAG_COMPRESSED ")); - if (resource->is_metadata) - tprintf(T("WIM_RESHDR_FLAG_METADATA ")); - if (resource->is_free) - tprintf(T("WIM_RESHDR_FLAG_FREE ")); - if (resource->is_spanned) - tprintf(T("WIM_RESHDR_FLAG_SPANNED ")); - if (resource->packed) - tprintf(T("WIM_RESHDR_FLAG_PACKED_STREAMS ")); - tputchar(T('\n')); - tputchar(T('\n')); - return 0; -} - -static void -print_lookup_table(WIMStruct *wim) -{ - wimlib_iterate_lookup_table(wim, 0, print_resource, NULL); -} - /* Prints information about a WIM file; also can mark an image as bootable, * change the name of an image, or change the description of an image. */ static int @@ -2999,7 +3118,6 @@ imagex_info(int argc, tchar **argv, int cmd) bool header = false; bool lookup_table = false; bool xml = false; - bool metadata = false; bool short_header = true; const tchar *xml_out_file = NULL; const tchar *wimfile; @@ -3040,9 +3158,9 @@ imagex_info(int argc, tchar **argv, int cmd) short_header = false; break; case IMAGEX_METADATA_OPTION: - metadata = true; - short_header = false; - break; + imagex_error(T("The --metadata option has been removed. " + "Use 'wimdir --detail' instead.")); + goto out_err; default: goto out_usage; } @@ -3163,11 +3281,6 @@ imagex_info(int argc, tchar **argv, int cmd) if (short_header) wimlib_print_available_images(wim, image); - if (metadata) { - ret = wimlib_print_metadata(wim, image); - if (ret) - goto out_wimlib_free; - } ret = 0; } else { @@ -3944,7 +4057,7 @@ T( ), [CMD_DIR] = T( -" %"TS" WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--path=PATH]\n" +" %"TS" WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--path=PATH] [--detailed]\n" ), [CMD_EXPORT] = T( diff --git a/src/dentry.c b/src/dentry.c index 0a898ff7..19e4199f 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -931,120 +931,6 @@ out: } #endif /* WITH_FUSE */ -/* Prints the full path of a dentry. */ -int -print_dentry_full_path(struct wim_dentry *dentry, void *_ignore) -{ - int ret = calculate_dentry_full_path(dentry); - if (ret) - return ret; - tprintf(T("%"TS"\n"), dentry->_full_path); - return 0; -} - -/* We want to be able to show the names of the file attribute flags that are - * set. */ -struct file_attr_flag { - u32 flag; - const tchar *name; -}; -struct file_attr_flag file_attr_flags[] = { - {FILE_ATTRIBUTE_READONLY, T("READONLY")}, - {FILE_ATTRIBUTE_HIDDEN, T("HIDDEN")}, - {FILE_ATTRIBUTE_SYSTEM, T("SYSTEM")}, - {FILE_ATTRIBUTE_DIRECTORY, T("DIRECTORY")}, - {FILE_ATTRIBUTE_ARCHIVE, T("ARCHIVE")}, - {FILE_ATTRIBUTE_DEVICE, T("DEVICE")}, - {FILE_ATTRIBUTE_NORMAL, T("NORMAL")}, - {FILE_ATTRIBUTE_TEMPORARY, T("TEMPORARY")}, - {FILE_ATTRIBUTE_SPARSE_FILE, T("SPARSE_FILE")}, - {FILE_ATTRIBUTE_REPARSE_POINT, T("REPARSE_POINT")}, - {FILE_ATTRIBUTE_COMPRESSED, T("COMPRESSED")}, - {FILE_ATTRIBUTE_OFFLINE, T("OFFLINE")}, - {FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,T("NOT_CONTENT_INDEXED")}, - {FILE_ATTRIBUTE_ENCRYPTED, T("ENCRYPTED")}, - {FILE_ATTRIBUTE_VIRTUAL, T("VIRTUAL")}, -}; - -/* Prints a directory entry. @lookup_table is a pointer to the lookup table, if - * available. If the dentry is unresolved and the lookup table is NULL, the - * lookup table entries will not be printed. Otherwise, they will be. */ -int -print_dentry(struct wim_dentry *dentry, void *lookup_table) -{ - const u8 *hash; - struct wim_lookup_table_entry *lte; - const struct wim_inode *inode = dentry->d_inode; - tchar buf[50]; - - tprintf(T("[DENTRY]\n")); - tprintf(T("Length = %"PRIu64"\n"), dentry->length); - tprintf(T("Attributes = 0x%x\n"), inode->i_attributes); - for (size_t i = 0; i < ARRAY_LEN(file_attr_flags); i++) - if (file_attr_flags[i].flag & inode->i_attributes) - tprintf(T(" FILE_ATTRIBUTE_%"TS" is set\n"), - file_attr_flags[i].name); - tprintf(T("Security ID = %d\n"), inode->i_security_id); - tprintf(T("Subdir offset = %"PRIu64"\n"), dentry->subdir_offset); - - wim_timestamp_to_str(inode->i_creation_time, buf, sizeof(buf)); - tprintf(T("Creation Time = %"TS"\n"), buf); - - wim_timestamp_to_str(inode->i_last_access_time, buf, sizeof(buf)); - tprintf(T("Last Access Time = %"TS"\n"), buf); - - wim_timestamp_to_str(inode->i_last_write_time, buf, sizeof(buf)); - tprintf(T("Last Write Time = %"TS"\n"), buf); - - if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) { - tprintf(T("Reparse Tag = 0x%"PRIx32"\n"), inode->i_reparse_tag); - tprintf(T("Reparse Point Flags = 0x%"PRIx16"\n"), - inode->i_not_rpfixed); - tprintf(T("Reparse Point Unknown 2 = 0x%"PRIx32"\n"), - inode->i_rp_unknown_2); - } - tprintf(T("Reparse Point Unknown 1 = 0x%"PRIx32"\n"), - inode->i_rp_unknown_1); - tprintf(T("Hard Link Group = 0x%"PRIx64"\n"), inode->i_ino); - tprintf(T("Hard Link Group Size = %"PRIu32"\n"), inode->i_nlink); - tprintf(T("Number of Alternate Data Streams = %hu\n"), inode->i_num_ads); - if (dentry_has_long_name(dentry)) - wimlib_printf(T("Filename = \"%"WS"\"\n"), dentry->file_name); - if (dentry_has_short_name(dentry)) - wimlib_printf(T("Short Name \"%"WS"\"\n"), dentry->short_name); - if (dentry->_full_path) - tprintf(T("Full Path = \"%"TS"\"\n"), dentry->_full_path); - - lte = inode_stream_lte(dentry->d_inode, 0, lookup_table); - if (lte) { - print_lookup_table_entry(lte, stdout); - } else { - hash = inode_stream_hash(inode, 0); - if (hash) { - tprintf(T("Hash = 0x")); - print_hash(hash, stdout); - tputchar(T('\n')); - tputchar(T('\n')); - } - } - for (u16 i = 0; i < inode->i_num_ads; i++) { - tprintf(T("[Alternate Stream Entry %u]\n"), i); - wimlib_printf(T("Name = \"%"WS"\"\n"), - inode->i_ads_entries[i].stream_name); - tprintf(T("Name Length (UTF16 bytes) = %hu\n"), - inode->i_ads_entries[i].stream_name_nbytes); - hash = inode_stream_hash(inode, i + 1); - if (hash) { - tprintf(T("Hash = 0x")); - print_hash(hash, stdout); - tputchar(T('\n')); - } - print_lookup_table_entry(inode_stream_lte(inode, i + 1, lookup_table), - stdout); - } - return 0; -} - /* Initializations done on every `struct wim_dentry'. */ static void dentry_common_init(struct wim_dentry *dentry) diff --git a/src/lookup_table.c b/src/lookup_table.c index f24bf053..c76823d1 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -827,10 +827,7 @@ read_wim_lookup_table(WIMStruct *wim) } if (cur_entry->refcnt != 1) { - if (wimlib_print_errors) { - ERROR("Found metadata resource with refcnt != 1:"); - print_lookup_table_entry(cur_entry, stderr); - } + ERROR("Found metadata resource with refcnt != 1"); ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; goto err; } @@ -870,14 +867,8 @@ read_wim_lookup_table(WIMStruct *wim) * resource. */ duplicate_entry = lookup_stream(table, cur_entry->hash); if (duplicate_entry) { - if (wimlib_print_errors) { - WARNING("The WIM lookup table contains two entries with the " - "same SHA1 message digest!"); - WARNING("The first entry is:"); - print_lookup_table_entry(duplicate_entry, stderr); - WARNING("The second entry is:"); - print_lookup_table_entry(cur_entry, stderr); - } + WARNING("The WIM lookup table contains two entries " + "with the same SHA1 message digest!"); free_lookup_table_entry(cur_entry); continue; } @@ -1140,87 +1131,6 @@ hash_unhashed_stream(struct wim_lookup_table_entry *lte, return 0; } -void -print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out) -{ - if (lte == NULL) { - tputc(T('\n'), out); - return; - } - - - tprintf(T("Uncompressed size = %"PRIu64" bytes\n"), - lte->size); - if (lte->flags & WIM_RESHDR_FLAG_PACKED_STREAMS) { - tprintf(T("Offset = %"PRIu64" bytes\n"), - lte->offset_in_res); - - tprintf(T("Raw uncompressed size = %"PRIu64" bytes\n"), - lte->rspec->uncompressed_size); - - tprintf(T("Raw compressed size = %"PRIu64" bytes\n"), - lte->rspec->size_in_wim); - - tprintf(T("Raw offset = %"PRIu64" bytes\n"), - lte->rspec->offset_in_wim); - } else if (lte->resource_location == RESOURCE_IN_WIM) { - tprintf(T("Compressed size = %"PRIu64" bytes\n"), - lte->rspec->size_in_wim); - - tprintf(T("Offset = %"PRIu64" bytes\n"), - lte->rspec->offset_in_wim); - } - - tfprintf(out, T("Reference Count = %u\n"), lte->refcnt); - - if (lte->unhashed) { - tfprintf(out, T("(Unhashed: inode %p, stream_id = %u)\n"), - lte->back_inode, lte->back_stream_id); - } else { - tfprintf(out, T("Hash = 0x")); - print_hash(lte->hash, out); - tputc(T('\n'), out); - } - - tfprintf(out, T("Flags = ")); - u8 flags = lte->flags; - if (flags & WIM_RESHDR_FLAG_COMPRESSED) - tfputs(T("WIM_RESHDR_FLAG_COMPRESSED, "), out); - if (flags & WIM_RESHDR_FLAG_FREE) - tfputs(T("WIM_RESHDR_FLAG_FREE, "), out); - if (flags & WIM_RESHDR_FLAG_METADATA) - tfputs(T("WIM_RESHDR_FLAG_METADATA, "), out); - if (flags & WIM_RESHDR_FLAG_SPANNED) - tfputs(T("WIM_RESHDR_FLAG_SPANNED, "), out); - if (flags & WIM_RESHDR_FLAG_PACKED_STREAMS) - tfputs(T("WIM_RESHDR_FLAG_PACKED_STREAMS, "), out); - tputc(T('\n'), out); - switch (lte->resource_location) { - case RESOURCE_IN_WIM: - if (lte->rspec->wim->filename) { - tfprintf(out, T("WIM file = `%"TS"'\n"), - lte->rspec->wim->filename); - } - break; -#ifdef __WIN32__ - case RESOURCE_WIN32_ENCRYPTED: -#endif - case RESOURCE_IN_FILE_ON_DISK: - tfprintf(out, T("File on Disk = `%"TS"'\n"), - lte->file_on_disk); - break; -#ifdef WITH_FUSE - case RESOURCE_IN_STAGING_FILE: - tfprintf(out, T("Staging File = `%"TS"'\n"), - lte->staging_file_name); - break; -#endif - default: - break; - } - tputc(T('\n'), out); -} - void lte_to_wimlib_resource_entry(const struct wim_lookup_table_entry *lte, struct wimlib_resource_entry *wentry) diff --git a/src/resource.c b/src/resource.c index c7312df8..bbf929a3 100644 --- a/src/resource.c +++ b/src/resource.c @@ -991,6 +991,13 @@ hasher_consume_chunk(const void *chunk, size_t size, void *_ctx) return (*ctx->cbs.consume_chunk)(chunk, size, ctx->cbs.consume_chunk_ctx); } +static void +get_sha1_string(const u8 md[SHA1_HASH_SIZE], tchar *str) +{ + for (size_t i = 0; i < SHA1_HASH_SIZE; i++) + str += tsprintf(str, T("%02x"), md[i]); +} + /* Callback for finishing reading a stream while calculating its SHA1 message * digest. */ static int @@ -1023,9 +1030,14 @@ hasher_end_stream(struct wim_lookup_table_entry *lte, int status, void *_ctx) * that it is the same as the calculated value. */ if (!hashes_equal(hash, lte->hash)) { if (wimlib_print_errors) { - ERROR("Invalid SHA1 message digest " - "on the following WIM stream:"); - print_lookup_table_entry(lte, stderr); + tchar expected_hashstr[SHA1_HASH_SIZE * 2 + 1]; + tchar actual_hashstr[SHA1_HASH_SIZE * 2 + 1]; + get_sha1_string(lte->hash, expected_hashstr); + get_sha1_string(hash, actual_hashstr); + ERROR("The stream is corrupted!\n" + " (Expected SHA1=%s,\n" + " got SHA1=%s)", + expected_hashstr, actual_hashstr); } ret = WIMLIB_ERR_INVALID_RESOURCE_HASH; errno = EINVAL; diff --git a/src/security.c b/src/security.c index d5fbcbb7..cac61917 100644 --- a/src/security.c +++ b/src/security.c @@ -31,7 +31,6 @@ #include "wimlib/endianness.h" #include "wimlib/error.h" #include "wimlib/security.h" -#include "wimlib/security_descriptor.h" #include "wimlib/sha1.h" #include "wimlib/util.h" @@ -215,116 +214,6 @@ write_wim_security_data(const struct wim_security_data * restrict sd, return p; } -static void -print_acl(const wimlib_ACL *acl, const tchar *type, size_t max_size) -{ - const u8 *p; - - if (max_size < sizeof(wimlib_ACL)) - return; - - u8 revision = acl->revision; - u16 acl_size = le16_to_cpu(acl->acl_size); - u16 ace_count = le16_to_cpu(acl->ace_count); - - tprintf(T(" [%"TS" ACL]\n"), type); - tprintf(T(" Revision = %u\n"), revision); - tprintf(T(" ACL Size = %u\n"), acl_size); - tprintf(T(" ACE Count = %u\n"), ace_count); - - p = (const u8*)acl + sizeof(wimlib_ACL); - for (u16 i = 0; i < ace_count; i++) { - if (max_size < p + sizeof(wimlib_ACCESS_ALLOWED_ACE) - (const u8*)acl) - break; - const wimlib_ACCESS_ALLOWED_ACE *aaa = (const wimlib_ACCESS_ALLOWED_ACE*)p; - tprintf(T(" [ACE]\n")); - tprintf(T(" ACE type = %d\n"), aaa->hdr.type); - tprintf(T(" ACE flags = 0x%x\n"), aaa->hdr.flags); - tprintf(T(" ACE size = %u\n"), le16_to_cpu(aaa->hdr.size)); - tprintf(T(" ACE mask = %x\n"), le32_to_cpu(aaa->mask)); - tprintf(T(" SID start = %u\n"), le32_to_cpu(aaa->sid_start)); - p += le16_to_cpu(aaa->hdr.size); - } - tputchar(T('\n')); -} - -static void -print_sid(const wimlib_SID *sid, const tchar *type, size_t max_size) -{ - if (max_size < sizeof(wimlib_SID)) - return; - - tprintf(T(" [%"TS" SID]\n"), type); - tprintf(T(" Revision = %u\n"), sid->revision); - tprintf(T(" Subauthority count = %u\n"), sid->sub_authority_count); - tprintf(T(" Identifier authority = ")); - print_byte_field(sid->identifier_authority, - sizeof(sid->identifier_authority), stdout); - tputchar(T('\n')); - if (max_size < sizeof(wimlib_SID) + (size_t)sid->sub_authority_count * sizeof(u32)) - return; - for (u8 i = 0; i < sid->sub_authority_count; i++) { - tprintf(T(" Subauthority %u = %u\n"), - i, le32_to_cpu(sid->sub_authority[i])); - } - tputchar(T('\n')); -} - -static void -print_security_descriptor(const wimlib_SECURITY_DESCRIPTOR_RELATIVE *descr, - size_t size) -{ - u8 revision = descr->revision; - u16 control = le16_to_cpu(descr->control); - u32 owner_offset = le32_to_cpu(descr->owner_offset); - u32 group_offset = le32_to_cpu(descr->group_offset); - u32 dacl_offset = le32_to_cpu(descr->dacl_offset); - u32 sacl_offset = le32_to_cpu(descr->sacl_offset); - - tprintf(T("Revision = %u\n"), revision); - tprintf(T("Security Descriptor Control = %#x\n"), control); - tprintf(T("Owner offset = %u\n"), owner_offset); - tprintf(T("Group offset = %u\n"), group_offset); - tprintf(T("Discretionary ACL offset = %u\n"), dacl_offset); - tprintf(T("System ACL offset = %u\n"), sacl_offset); - - if (owner_offset != 0 && owner_offset <= size) - print_sid((const wimlib_SID*)((const u8*)descr + owner_offset), - T("Owner"), size - owner_offset); - - if (group_offset != 0 && group_offset <= size) - print_sid((const wimlib_SID*)((const u8*)descr + group_offset), - T("Group"), size - group_offset); - - if (dacl_offset != 0 && dacl_offset <= size) - print_acl((const wimlib_ACL*)((const u8*)descr + dacl_offset), - T("Discretionary"), size - dacl_offset); - - if (sacl_offset != 0 && sacl_offset <= size) - print_acl((const wimlib_ACL*)((const u8*)descr + sacl_offset), - T("System"), size - sacl_offset); -} - -/* - * Prints the security data for a WIM file. - */ -void -print_wim_security_data(const struct wim_security_data *sd) -{ - tputs(T("[SECURITY DATA]")); - tprintf(T("Length = %"PRIu32" bytes\n"), sd->total_length); - tprintf(T("Number of Entries = %"PRIu32"\n"), sd->num_entries); - - for (u32 i = 0; i < sd->num_entries; i++) { - tprintf(T("[SECURITY_DESCRIPTOR_RELATIVE %"PRIu32", length = %"PRIu64"]\n"), - i, sd->sizes[i]); - print_security_descriptor((const wimlib_SECURITY_DESCRIPTOR_RELATIVE*)sd->descriptors[i], - sd->sizes[i]); - tputchar(T('\n')); - } - tputchar(T('\n')); -} - void free_wim_security_data(struct wim_security_data *sd) { diff --git a/src/wim.c b/src/wim.c index 42f0892e..d885b797 100644 --- a/src/wim.c +++ b/src/wim.c @@ -55,15 +55,6 @@ #include #include -static int -image_print_metadata(WIMStruct *wim) -{ - DEBUG("Printing metadata for image %d", wim->current_image); - print_wim_security_data(wim_security_data(wim)); - return for_dentry_in_tree(wim_root_dentry(wim), print_dentry, - wim->lookup_table); -} - static int wim_default_pack_compression_type(void) { @@ -276,11 +267,6 @@ select_wim_image(WIMStruct *wim, int image) if (imd->root_dentry || imd->modified) { ret = 0; } else { - #ifdef ENABLE_DEBUG - DEBUG("Reading metadata resource specified by the following " - "lookup table entry:"); - print_lookup_table_entry(imd->metadata_lte, stderr); - #endif ret = read_metadata_resource(wim, imd); if (ret) wim->current_image = WIMLIB_NO_IMAGE; @@ -364,12 +350,11 @@ wimlib_print_available_images(const WIMStruct *wim, int image) print_image_info(wim->wim_info, i); } - -/* API function documented in wimlib.h */ +/* TODO: Deprecated; remove this. */ WIMLIBAPI int wimlib_print_metadata(WIMStruct *wim, int image) { - return for_image(wim, image, image_print_metadata); + return WIMLIB_ERR_UNSUPPORTED; } /* API function documented in wimlib.h */ diff --git a/tests/test-imagex b/tests/test-imagex index 4ae0540c..4694d3dc 100755 --- a/tests/test-imagex +++ b/tests/test-imagex @@ -132,7 +132,7 @@ if ! imagex info --extract-xml=dir.xml dir.wim; then error "Failed to extract WIM XML data" fi echo "Testing printing WIM metadata" -if ! imagex info --metadata dir.wim > /dev/null; then +if ! imagex dir --detailed dir.wim > /dev/null; then error "Failed to print WIM metadata" fi rm -rf dir.wim tmp dir.xml