X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=programs%2Fimagex.c;h=34eefedf36fa45f8d14f1bebe01499227d109de4;hp=5d7aa233236443b34d9526d7bcce689b3eb4e43e;hb=03c0995c472eb5b9084e998cf91065b131ddedfb;hpb=ce7a3173855e654bf1aa52f1b7d7e676667192cd diff --git a/programs/imagex.c b/programs/imagex.c index 5d7aa233..34eefedf 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -125,7 +125,7 @@ IMAGEX_PROGNAME" delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check] [--soft ), [DIR] = T( -IMAGEX_PROGNAME" dir WIMFILE (IMAGE_NUM | IMAGE_NAME | all)\n" +IMAGEX_PROGNAME" dir WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--path=PATH]\n" ), [EXPORT] = T( @@ -221,6 +221,7 @@ enum { IMAGEX_METADATA_OPTION, IMAGEX_NORPFIX_OPTION, IMAGEX_NO_ACLS_OPTION, + IMAGEX_PATH_OPTION, IMAGEX_REBUILD_OPTION, IMAGEX_RECOMPRESS_OPTION, IMAGEX_RECURSIVE_OPTION, @@ -279,6 +280,11 @@ static const struct option delete_options[] = { {NULL, 0, NULL, 0}, }; +static const struct option dir_options[] = { + {T("path"), required_argument, NULL, IMAGEX_PATH_OPTION}, + {NULL, 0, NULL, 0}, +}; + static const struct option export_options[] = { {T("boot"), no_argument, NULL, IMAGEX_BOOT_OPTION}, {T("check"), no_argument, NULL, IMAGEX_CHECK_OPTION}, @@ -980,18 +986,6 @@ stdin_get_text_contents(size_t *num_tchars_ret) return translate_text_to_tstr(contents, num_bytes, num_tchars_ret); } -/* Return 0 if a path names a file to which the current user has write access; - * -1 otherwise (and print an error message). */ -static int -file_writable(const tchar *path) -{ - int ret; - ret = taccess(path, W_OK); - if (ret != 0) - imagex_error_with_errno(T("Can't modify \"%"TS"\""), path); - return ret; -} - #define TO_PERCENT(numerator, denominator) \ (((denominator) == 0) ? 0 : ((numerator) * 100 / (denominator))) @@ -1656,7 +1650,7 @@ static int imagex_capture_or_append(int argc, tchar **argv) { int c; - int open_flags = 0; + int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS; int add_image_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE; int write_flags = 0; int compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS; @@ -1889,8 +1883,6 @@ imagex_capture_or_append(int argc, tchar **argv) ret = wimlib_write(w, wimfile, WIMLIB_ALL_IMAGES, write_flags, num_threads, imagex_progress_func); } - if (ret == WIMLIB_ERR_REOPEN) - ret = 0; if (ret != 0) imagex_error(T("Failed to write the WIM file \"%"TS"\""), wimfile); @@ -1919,7 +1911,7 @@ static int imagex_delete(int argc, tchar **argv) { int c; - int open_flags = 0; + int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS; int write_flags = 0; const tchar *wimfile; const tchar *image_num_or_name; @@ -1955,10 +1947,6 @@ imagex_delete(int argc, tchar **argv) wimfile = argv[0]; image_num_or_name = argv[1]; - ret = file_writable(wimfile); - if (ret != 0) - return ret; - ret = wimlib_open_wim(wimfile, open_flags, &w, imagex_progress_func); if (ret != 0) @@ -1977,8 +1965,6 @@ imagex_delete(int argc, tchar **argv) } ret = wimlib_overwrite(w, write_flags, 0, imagex_progress_func); - if (ret == WIMLIB_ERR_REOPEN) - ret = 0; if (ret != 0) { imagex_error(T("Failed to write the file \"%"TS"\" with image " "deleted"), wimfile); @@ -1988,56 +1974,80 @@ out: return ret; } +static int +print_full_path(const struct wimlib_wim_dentry *wdentry, void *_ignore) +{ + int ret = tprintf(T("%"TS"\n"), wdentry->full_path); + return (ret >= 0) ? 0 : -1; +} + /* Print the files contained in an image(s) in a WIM file. */ static int imagex_dir(int argc, tchar **argv) { const tchar *wimfile; - WIMStruct *w; + WIMStruct *wim = NULL; int image; int ret; - int num_images; + const tchar *path = T(""); + int c; - if (argc < 2) { + for_opt(c, dir_options) { + switch (c) { + case IMAGEX_PATH_OPTION: + path = optarg; + break; + default: + goto out_usage; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { imagex_error(T("Must specify a WIM file")); - usage(DIR); - return -1; + goto out_usage; } - if (argc > 3) { + if (argc > 2) { imagex_error(T("Too many arguments")); - usage(DIR); - return -1; + goto out_usage; } - wimfile = argv[1]; - ret = wimlib_open_wim(wimfile, WIMLIB_OPEN_FLAG_SPLIT_OK, &w, + wimfile = argv[0]; + ret = wimlib_open_wim(wimfile, WIMLIB_OPEN_FLAG_SPLIT_OK, &wim, imagex_progress_func); - if (ret != 0) - return ret; + if (ret) + goto out; - if (argc == 3) { - image = wimlib_resolve_image(w, argv[2]); - ret = verify_image_exists(image, argv[2], wimfile); - if (ret != 0) - goto out; + if (argc == 2) { + image = wimlib_resolve_image(wim, argv[1]); + ret = verify_image_exists(image, argv[1], wimfile); + if (ret) + goto out_wimlib_free; } else { /* Image was not specified. If the WIM only contains one image, * choose that one; otherwise, print an error. */ - num_images = wimlib_get_num_images(w); + int num_images = wimlib_get_num_images(wim); if (num_images != 1) { imagex_error(T("\"%"TS"\" contains %d images; Please " "select one."), wimfile, num_images); - usage(DIR); - ret = -1; - goto out; + wimlib_free(wim); + goto out_usage; } image = 1; } - ret = wimlib_print_files(w, image); + ret = wimlib_iterate_dir_tree(wim, image, path, + WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE, + print_full_path, NULL); +out_wimlib_free: + wimlib_free(wim); out: - wimlib_free(w); return ret; +out_usage: + usage(DIR); + ret = -1; + goto out; } /* Exports one, or all, images from a WIM file to a new WIM file or an existing @@ -2130,12 +2140,8 @@ imagex_export(int argc, tchar **argv) ret = -1; goto out; } - ret = wimlib_open_wim(dest_wimfile, open_flags, &dest_w, - imagex_progress_func); - if (ret != 0) - goto out; - - ret = file_writable(dest_wimfile); + ret = wimlib_open_wim(dest_wimfile, open_flags | WIMLIB_OPEN_FLAG_WRITE_ACCESS, + &dest_w, imagex_progress_func); if (ret != 0) goto out; @@ -2194,8 +2200,6 @@ imagex_export(int argc, tchar **argv) ret = wimlib_overwrite(dest_w, write_flags, num_threads, imagex_progress_func); out: - if (ret == WIMLIB_ERR_REOPEN) - ret = 0; wimlib_free(src_w); wimlib_free(dest_w); if (additional_swms) { @@ -2395,6 +2399,38 @@ out_usage: goto out; } +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, WIMStruct *wim) +{ + struct wimlib_wim_info info; + + wimlib_get_wim_info((WIMStruct*)wim, &info); + + tputs(T("WIM Information:")); + tputs(T("----------------")); + tprintf(T("Path: %"TS"\n"), wimfile); + tfputs(T("GUID: 0x"), stdout); + print_byte_field(info.guid, WIMLIB_GUID_LEN); + tputchar(T('\n')); + tprintf(T("Image Count: %d\n"), info.image_count); + tprintf(T("Compression: %"TS"\n"), + wimlib_get_compression_type_string(info.compression_type)); + 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")); + tputchar(T('\n')); +} + /* 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 @@ -2538,7 +2574,7 @@ imagex_info(int argc, tchar **argv) } if (image == WIMLIB_ALL_IMAGES && short_header) - wimlib_print_wim_information(w); + print_wim_information(wimfile, w); if (header) wimlib_print_header(w); @@ -2591,11 +2627,7 @@ imagex_info(int argc, tchar **argv) } else { /* Modification operations */ - if (total_parts != 1) { - imagex_error(T("Modifying a split WIM is not supported.")); - ret = -1; - goto out; - } + if (image == WIMLIB_ALL_IMAGES) image = 1; @@ -2614,7 +2646,9 @@ imagex_info(int argc, tchar **argv) } else { tprintf(T("Marking image %d as bootable.\n"), image); - wimlib_set_boot_idx(w, image); + ret = wimlib_set_boot_idx(w, image); + if (ret) + goto out; } } if (new_name) { @@ -2653,21 +2687,12 @@ imagex_info(int argc, tchar **argv) if (boot || new_name || new_desc || (check && !wimlib_has_integrity_table(w))) { - int write_flags; - - ret = file_writable(wimfile); - if (ret != 0) - goto out; + int write_flags = 0; if (check) - write_flags = WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; - else - write_flags = 0; - + write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; ret = wimlib_overwrite(w, write_flags, 1, imagex_progress_func); - if (ret == WIMLIB_ERR_REOPEN) - ret = 0; } else { tprintf(T("The file \"%"TS"\" was not modified because nothing " "needed to be done.\n"), wimfile); @@ -2736,8 +2761,10 @@ imagex_mount_rw_or_ro(int argc, tchar **argv) unsigned num_additional_swms = 0; const tchar *staging_dir = NULL; - if (!tstrcmp(argv[0], T("mountrw"))) + if (!tstrcmp(argv[0], T("mountrw"))) { mount_flags |= WIMLIB_MOUNT_FLAG_READWRITE; + open_flags |= WIMLIB_OPEN_FLAG_WRITE_ACCESS; + } for_opt(c, mount_options) { switch (c) { @@ -2816,12 +2843,6 @@ imagex_mount_rw_or_ro(int argc, tchar **argv) goto out; } - if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) { - ret = file_writable(wimfile); - if (ret != 0) - goto out; - } - ret = wimlib_mount_image(w, image, dir, mount_flags, additional_swms, num_additional_swms, staging_dir); if (ret != 0) { @@ -2849,7 +2870,7 @@ static int imagex_optimize(int argc, tchar **argv) { int c; - int open_flags = 0; + int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS; int write_flags = WIMLIB_WRITE_FLAG_REBUILD; int ret; WIMStruct *w; @@ -2887,10 +2908,6 @@ imagex_optimize(int argc, tchar **argv) wimfile = argv[0]; - ret = file_writable(wimfile); - if (ret) - return ret; - ret = wimlib_open_wim(wimfile, open_flags, &w, imagex_progress_func); if (ret) @@ -3024,7 +3041,7 @@ imagex_update(int argc, tchar **argv) int image; WIMStruct *wim; int ret; - int open_flags = 0; + int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS; int write_flags = 0; int update_flags = WIMLIB_UPDATE_FLAG_SEND_PROGRESS; int default_add_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE; @@ -3115,10 +3132,6 @@ imagex_update(int argc, tchar **argv) goto out_usage; wimfile = argv[0]; - ret = file_writable(wimfile); - if (ret) - goto out; - ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func); if (ret) goto out; @@ -3188,11 +3201,13 @@ imagex_update(int argc, tchar **argv) } /* Set default flags and capture config on the update commands */ + bool have_add_command = false; for (size_t i = 0; i < num_cmds; i++) { switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: cmds[i].add.add_flags |= default_add_flags; cmds[i].add.config = config; + have_add_command = true; break; case WIMLIB_UPDATE_OP_DELETE: cmds[i].delete.delete_flags |= default_delete_flags; @@ -3203,7 +3218,8 @@ imagex_update(int argc, tchar **argv) } #ifdef __WIN32__ - win32_acquire_capture_privileges(); + if (have_add_command) + win32_acquire_capture_privileges(); #endif /* Execute the update commands */ @@ -3217,7 +3233,8 @@ imagex_update(int argc, tchar **argv) imagex_progress_func); out_release_privs: #ifdef __WIN32__ - win32_release_capture_privileges(); + if (have_add_command) + win32_release_capture_privileges(); #endif free(cmds); out_free_cmd_file_contents: