From: Eric Biggers Date: Sat, 21 Jul 2018 19:34:19 +0000 (-0700) Subject: wimappend: add --create option to create WIM file if needed X-Git-Tag: v1.13.0~6 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=8c8340effb447f9058f8227550ac368a4b442d23 wimappend: add --create option to create WIM file if needed --- diff --git a/NEWS b/NEWS index 5d7b94af..b75e3804 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ Version 1.13.0-BETA: example, listing "/dir/file" in [ExclusionException] now works even if "/dir" is matched by [ExclusionList]. + Added a '--create' option to 'wimappend' which makes it create the WIM + file (like 'wimcapture') if it doesn't exist yet. + Added an '--include-integrity' option to various wimlib-imagex commands. '--include-integrity' is like '--check', but it will just include an integrity table in the output WIM(s), while skipping verification of any diff --git a/doc/man1/wimcapture.1 b/doc/man1/wimcapture.1 index 9426c813..40ef2476 100644 --- a/doc/man1/wimcapture.1 +++ b/doc/man1/wimcapture.1 @@ -10,7 +10,8 @@ The \fBwimcapture\fR (equivalently: \fBwimlib-imagex capture\fR) and \fBwimappend\fR (equivalently: \fBwimlib-imagex append\fR) commands create ("capture") a new Windows Imaging (WIM) image. \fBwimcapture\fR creates a new WIM archive \fIWIMFILE\fR to contain the new image, while \fBwimappend\fR adds -the image to the existing WIM archive \fIWIMFILE\fR. +the image to the existing WIM archive \fIWIMFILE\fR (or with \fB--create\fR, +creating it if needed). .PP \fISOURCE\fR specifies the location of the files from which to create the WIM image. If \fISOURCE\fR is a directory or a symbolic link pointing to a @@ -588,6 +589,10 @@ running into problems with locked files. For the VSS snapshot to be successfully created, \fBwimlib-imagex\fR must be run as an Administrator, and it cannot be run in WoW64 mode (i.e. if Windows is 64-bit, then \fBwimlib-imagex\fR must be 64-bit as well). +.TP +\fB--create\fR +With \fBwimappend\fR, if the WIM file doesn't exist yet, then create it (like +\fBwimcapture\fR). .SH NOTES \fBwimappend\fR does not support appending an image to a split WIM. .PP diff --git a/programs/imagex.c b/programs/imagex.c index ea0815a6..a274f78b 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -171,6 +171,7 @@ enum { IMAGEX_COMPACT_OPTION, IMAGEX_COMPRESS_OPTION, IMAGEX_CONFIG_OPTION, + IMAGEX_CREATE_OPTION, IMAGEX_DEBUG_OPTION, IMAGEX_DELTA_FROM_OPTION, IMAGEX_DEREFERENCE_OPTION, @@ -274,6 +275,7 @@ static const struct option capture_or_append_options[] = { {T("wimboot"), no_argument, NULL, IMAGEX_WIMBOOT_OPTION}, {T("unsafe-compact"), no_argument, NULL, IMAGEX_UNSAFE_COMPACT_OPTION}, {T("snapshot"), no_argument, NULL, IMAGEX_SNAPSHOT_OPTION}, + {T("create"), no_argument, NULL, IMAGEX_CREATE_OPTION}, {NULL, 0, NULL, 0}, }; @@ -1853,14 +1855,18 @@ out_usage: goto out_free_refglobs; } -/* Create a WIM image from a directory tree, NTFS volume, or multiple files or - * directory trees. 'wimlib-imagex capture': create a new WIM file containing - * the desired image. 'wimlib-imagex append': add a new image to an existing - * WIM file. */ +/* + * Create a WIM image from a directory tree, NTFS volume, or multiple files or + * directory trees. 'wimcapture': create a new WIM file containing the desired + * image. 'wimappend': add a new image to an existing WIM file; or, with + * '--create' behave like 'wimcapture' if the WIM file doesn't exist. + */ static int imagex_capture_or_append(int argc, tchar **argv, int cmd) { int c; + bool create = false; + bool appending = (cmd == CMD_APPEND); int open_flags = 0; int add_flags = WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE | WIMLIB_ADD_FLAG_WINCONFIG | @@ -2025,16 +2031,18 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) add_flags |= WIMLIB_ADD_FLAG_WIMBOOT; break; case IMAGEX_UNSAFE_COMPACT_OPTION: - if (cmd != CMD_APPEND) { - imagex_error(T("'--unsafe-compact' is only " - "valid for append!")); - goto out_err; - } write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT; break; case IMAGEX_SNAPSHOT_OPTION: add_flags |= WIMLIB_ADD_FLAG_SNAPSHOT; break; + case IMAGEX_CREATE_OPTION: + if (cmd == CMD_CAPTURE) { + imagex_error(T("'--create' is only valid for 'wimappend', not 'wimcapture'")); + goto out_err; + } + create = true; + break; default: goto out_usage; } @@ -2069,6 +2077,8 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) if (!tstrcmp(wimfile, T("-"))) { /* Writing captured WIM to standard output. */ + if (create) + appending = false; #if 0 if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) { imagex_error("Can't write a non-pipable WIM to " @@ -2080,7 +2090,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) #else write_flags |= WIMLIB_WRITE_FLAG_PIPABLE; #endif - if (cmd == CMD_APPEND) { + if (appending) { imagex_error(T("Using standard output for append does " "not make sense.")); goto out_err; @@ -2089,6 +2099,16 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) wimfile = NULL; imagex_output_to_stderr(); set_fd_to_binary_mode(wim_fd); + } else { + struct stat stbuf; + + if (create && tstat(wimfile, &stbuf) != 0 && errno == ENOENT) + appending = false; + } + + if ((write_flags & WIMLIB_WRITE_FLAG_UNSAFE_COMPACT) && !appending) { + imagex_error(T("'--unsafe-compact' is only valid for append!")); + goto out_err; } /* If template image was specified using --update-of=IMAGE rather @@ -2098,7 +2118,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) /* Capturing delta WIM based on single WIM: default to * base WIM. */ template_wimfile = base_wimfiles.strings[0]; - } else if (cmd == CMD_APPEND) { + } else if (appending) { /* Appending to WIM: default to WIM being appended to. */ template_wimfile = wimfile; @@ -2176,7 +2196,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) } /* Open the existing WIM, or create a new one. */ - if (cmd == CMD_APPEND) { + if (appending) { ret = wimlib_open_wim_with_progress(wimfile, open_flags | WIMLIB_OPEN_FLAG_WRITE_ACCESS, &wim, @@ -2200,7 +2220,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) int ctype = compression_type; - if (cmd == CMD_APPEND) { + if (appending) { struct wimlib_wim_info info; wimlib_get_wim_info(wim, &info); ctype = info.compression_type; @@ -2249,7 +2269,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) /* If the user did not specify an image name, and the basename of the * source already exists as an image name in the WIM file, append a * suffix to make it unique. */ - if (cmd == CMD_APPEND && name_defaulted) { + if (appending && name_defaulted) { unsigned long conflict_idx; tchar *name_end = tstrchr(name, T('\0')); for (conflict_idx = 1; @@ -2301,7 +2321,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) * open the WIM if needed and parse the image index. */ if (template_image_name_or_num) { - if (cmd == CMD_APPEND && !tstrcmp(template_wimfile, wimfile)) { + if (appending && !tstrcmp(template_wimfile, wimfile)) { template_wim = wim; } else { for (size_t i = 0; i < base_wimfiles.num_strings; i++) { @@ -2386,7 +2406,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) /* Write the new WIM or overwrite the existing WIM with the new image * appended. */ - if (cmd == CMD_APPEND) { + if (appending) { ret = wimlib_overwrite(wim, write_flags, num_threads); } else if (wimfile) { ret = wimlib_write(wim, wimfile, WIMLIB_ALL_IMAGES, @@ -4426,7 +4446,7 @@ T( " [--threads=NUM_THREADS] [--no-acls] [--strict-acls]\n" " [--rpfix] [--norpfix] [--update-of=[WIMFILE:]IMAGE]\n" " [--delta-from=WIMFILE] [--wimboot] [--unix-data]\n" -" [--dereference] [--snapshot]\n" +" [--dereference] [--snapshot] [--create]\n" ), [CMD_APPLY] = T( diff --git a/tests/test-imagex b/tests/test-imagex index d36bf82f..9c92715b 100755 --- a/tests/test-imagex +++ b/tests/test-imagex @@ -65,6 +65,21 @@ for comp_type in None LZX XPRESS; do rm -rf dir.wim tmp done +# Test wimappend --create +rm -f dir.wim +if wimappend dir dir.wim; then + error "wimappend to nonexisting file unexpectedly succeeded" +fi +if ! wimappend dir dir.wim --create; then + error "wimappend --create to nonexisting file failed" +fi +if ! wimappend dir dir.wim --create; then + error "wimappend --create to existing file failed" +fi +if ! test "`wiminfo dir.wim | grep 'Image Count' | awk '{print $3}'`" = 2; then + error "Incorrect WIM image count after wimappend --create" +fi + # Capturing and modifying name, description, and bootable flag echo "Testing capture of WIM with default name and description"