IMAGEX_COMPRESS_OPTION,
IMAGEX_CONFIG_OPTION,
IMAGEX_DEBUG_OPTION,
+ IMAGEX_DELTA_FROM_OPTION,
IMAGEX_DEREFERENCE_OPTION,
IMAGEX_DEST_DIR_OPTION,
IMAGEX_EXTRACT_XML_OPTION,
{T("rpfix"), no_argument, NULL, IMAGEX_RPFIX_OPTION},
{T("norpfix"), no_argument, NULL, IMAGEX_NORPFIX_OPTION},
{T("include-invalid-names"), no_argument, NULL, IMAGEX_INCLUDE_INVALID_NAMES_OPTION},
+
+ /* --resume is undocumented for now as it needs improvement. */
{T("resume"), no_argument, NULL, IMAGEX_RESUME_OPTION},
{NULL, 0, NULL, 0},
};
{T("norpfix"), no_argument, NULL, IMAGEX_NORPFIX_OPTION},
{T("pipable"), no_argument, NULL, IMAGEX_PIPABLE_OPTION},
{T("not-pipable"), no_argument, NULL, IMAGEX_NOT_PIPABLE_OPTION},
+ {T("delta-from"), required_argument, NULL, IMAGEX_DELTA_FROM_OPTION},
{NULL, 0, NULL, 0},
};
return (off_t)-1;
}
-tchar pat_ntfs_log[] = T("/$ntfs.log");
-tchar pat_hiberfil_sys[] = T("/hiberfil.sys");
-tchar pat_pagefile_sys[] = T("/pagefile.sys");
-tchar pat_system_volume_information[] = T("/System Volume Information");
-tchar pat_recycler[] = T("/RECYCLER");
-tchar pat_windows_csc[] = T("/Windows/CSC");
-
-tchar *default_pats[] = {
- pat_ntfs_log,
- pat_hiberfil_sys,
- pat_pagefile_sys,
- pat_system_volume_information,
- pat_recycler,
- pat_windows_csc,
-};
-
-static struct wimlib_capture_config default_capture_config = {
- .exclusion_pats = {
- .num_pats = sizeof(default_pats) / sizeof(default_pats[0]),
- .pats = default_pats,
- },
-};
-
enum {
PARSE_STRING_SUCCESS = 0,
PARSE_STRING_FAILURE = 1,
switch (op) {
case WIMLIB_UPDATE_OP_ADD:
if (!tstrcmp(option, T("--verbose")))
- cmd->add.add_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE;
+ cmd->add.add_flags |= WIMLIB_ADD_FLAG_VERBOSE;
else if (!tstrcmp(option, T("--unix-data")))
- cmd->add.add_flags |= WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA;
+ cmd->add.add_flags |= WIMLIB_ADD_FLAG_UNIX_DATA;
else if (!tstrcmp(option, T("--no-acls")) || !tstrcmp(option, T("--noacls")))
- cmd->add.add_flags |= WIMLIB_ADD_IMAGE_FLAG_NO_ACLS;
+ cmd->add.add_flags |= WIMLIB_ADD_FLAG_NO_ACLS;
else if (!tstrcmp(option, T("--strict-acls")))
- cmd->add.add_flags |= WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS;
+ cmd->add.add_flags |= WIMLIB_ADD_FLAG_STRICT_ACLS;
else if (!tstrcmp(option, T("--dereference")))
- cmd->add.add_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE;
+ cmd->add.add_flags |= WIMLIB_ADD_FLAG_DEREFERENCE;
else
recognized = false;
break;
{
int c;
int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS;
- int add_image_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE;
+ int add_image_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE |
+ WIMLIB_ADD_IMAGE_FLAG_WINCONFIG;
int write_flags = 0;
int compression_type = WIMLIB_COMPRESSION_TYPE_LZX;
const tchar *wimfile;
const tchar *name;
const tchar *desc;
const tchar *flags_element = NULL;
+ const tchar *template_image_name_or_num = NULL;
+ int template_image;
WIMStruct *wim;
int ret;
unsigned num_threads = 0;
break;
case IMAGEX_CONFIG_OPTION:
config_file = optarg;
+ add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_WINCONFIG;
break;
case IMAGEX_COMPRESS_OPTION:
compression_type = get_compression_type(optarg);
case IMAGEX_NOT_PIPABLE_OPTION:
write_flags |= WIMLIB_WRITE_FLAG_NOT_PIPABLE;
break;
+ case IMAGEX_DELTA_FROM_OPTION:
+ if (cmd == CMD_CAPTURE) {
+ imagex_error(T("--delta-from=IMAGE is only "
+ "valid for append."));
+ goto out_usage;
+ }
+ template_image_name_or_num = optarg;
+ break;
default:
goto out_usage;
}
wimfile = argv[1];
if (!tstrcmp(wimfile, T("-"))) {
+ /* Writing captured WIM to standard output. */
#if 0
if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) {
imagex_error("Can't write a non-pipable WIM to "
wim_fd = STDOUT_FILENO;
wimfile = NULL;
imagex_info_file = stderr;
+ set_fd_to_binary_mode(wim_fd);
}
if (argc >= 3) {
if (ret)
goto out_free_config;
} else {
- config = &default_capture_config;
+ config = NULL;
}
if (cmd == CMD_APPEND)
tsprintf(name_end, T(" (%lu)"), conflict_idx);
}
}
+
+ if (template_image_name_or_num) {
+ template_image = wimlib_resolve_image(wim, template_image_name_or_num);
+ if (template_image_name_or_num[0] == T('-')) {
+ tchar *tmp;
+ unsigned long n;
+ struct wimlib_wim_info info;
+
+ wimlib_get_wim_info(wim, &info);
+ n = tstrtoul(template_image_name_or_num + 1, &tmp, 10);
+ if (n >= 1 && n <= info.image_count &&
+ *tmp == T('\0') &&
+ tmp != template_image_name_or_num + 1)
+ {
+ template_image = info.image_count - (n - 1);
+ }
+ }
+ ret = verify_image_exists_and_is_single(template_image,
+ template_image_name_or_num,
+ wimfile);
+ if (ret)
+ goto out_wimlib_free;
+ }
+
ret = wimlib_add_image_multisource(wim,
capture_sources,
num_sources,
if (ret)
goto out_wimlib_free;
- if (desc || flags_element) {
- /* User provided <DESCRIPTION> or <FLAGS> element. Get the
- * index of the image we just added, then use it to call the
- * appropriate functions. */
+ if (desc || flags_element || template_image_name_or_num) {
+ /* User provided <DESCRIPTION> or <FLAGS> element, or an image
+ * on which the added one is to be based has been specified with
+ * --delta-from=IMAGE. Get the index of the image we just
+ * added, then use it to call the appropriate functions. */
struct wimlib_wim_info info;
wimlib_get_wim_info(wim, &info);
if (ret)
goto out_wimlib_free;
}
+
+ if (template_image_name_or_num) {
+ ret = wimlib_reference_template_image(wim,
+ info.image_count,
+ template_image,
+ 0, NULL);
+ if (ret)
+ goto out_wimlib_free;
+ }
}
/* Write the new WIM or overwrite the existing WIM with the new image
out_wimlib_free:
wimlib_free(wim);
out_free_config:
- if (config != &default_capture_config) {
+ if (config) {
free(config->exclusion_pats.pats);
free(config->exclusion_exception_pats.pats);
free(config_str);
dest_wimfile = NULL;
dest_wim_fd = STDOUT_FILENO;
imagex_info_file = stderr;
+ set_fd_to_binary_mode(dest_wim_fd);
}
errno = ENOENT;
if (dest_wimfile != NULL && tstat(dest_wimfile, &stbuf) == 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;
+ int default_add_flags = WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE |
+ WIMLIB_ADD_FLAG_WINCONFIG;
int default_delete_flags = 0;
unsigned num_threads = 0;
int c;
/* Global add option */
case IMAGEX_CONFIG_OPTION:
+ default_add_flags &= ~WIMLIB_ADD_FLAG_WINCONFIG;
config_file = optarg;
break;
/* Default add options */
case IMAGEX_VERBOSE_OPTION:
- default_add_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE;
+ default_add_flags |= WIMLIB_ADD_FLAG_VERBOSE;
break;
case IMAGEX_DEREFERENCE_OPTION:
- default_add_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE;
+ default_add_flags |= WIMLIB_ADD_FLAG_DEREFERENCE;
break;
case IMAGEX_UNIX_DATA_OPTION:
- default_add_flags |= WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA;
+ default_add_flags |= WIMLIB_ADD_FLAG_UNIX_DATA;
break;
case IMAGEX_NO_ACLS_OPTION:
- default_add_flags |= WIMLIB_ADD_IMAGE_FLAG_NO_ACLS;
+ default_add_flags |= WIMLIB_ADD_FLAG_NO_ACLS;
break;
case IMAGEX_STRICT_ACLS_OPTION:
- default_add_flags |= WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS;
+ default_add_flags |= WIMLIB_ADD_FLAG_STRICT_ACLS;
break;
default:
goto out_usage;
if (ret)
goto out_free_config;
} else {
- config = &default_capture_config;
+ config = NULL;
}
/* Read update commands from standard input, or the command string if
out_free_cmd_file_contents:
free(cmd_file_contents);
out_free_config:
- if (config != &default_capture_config) {
+ if (config) {
free(config->exclusion_pats.pats);
free(config->exclusion_exception_pats.pats);
free(config_str);
" [--dereference] [--config=FILE] [--threads=NUM_THREADS]\n"
" [--rebuild] [--unix-data] [--source-list] [--no-acls]\n"
" [--strict-acls] [--rpfix] [--norpfix] [--pipable]\n"
-" [--not-pipable]\n"
+" [--not-pipable] [--delta-from=IMAGE]\n"
),
[CMD_APPLY] =
T(
" (DIRECTORY | NTFS_VOLUME) [--check] [--hardlink]\n"
" [--symlink] [--verbose] [--ref=\"GLOB\"] [--unix-data]\n"
" [--no-acls] [--strict-acls] [--rpfix] [--norpfix]\n"
-" [--include-invalid-names] [--resume]\n"
+" [--include-invalid-names]\n"
),
[CMD_CAPTURE] =
T(
" [--nocheck] [--compress=TYPE] [--flags EDITION_ID]\n"
" [--verbose] [--dereference] [--config=FILE]\n"
" [--threads=NUM_THREADS] [--unix-data] [--source-list]\n"
-" [--no-acls] [--strict-acls] [--rpfix] [--norpfix]\n"
-" [--pipable] [--not-pipable]\n"
+" [--no-acls] [--strict-acls] [--norpfix] [--pipable]\n"
),
[CMD_DELETE] =
T(
};
static const tchar *invocation_name;
-static bool using_cmd_from_invocation_name = false;
+static int invocation_cmd = CMD_NONE;
static const tchar *get_cmd_string(int cmd, bool nospace)
{
-
- if (using_cmd_from_invocation_name || cmd == CMD_NONE) {
- return invocation_name;
+ static tchar buf[50];
+ if (cmd == CMD_NONE) {
+ tsprintf(buf, T("%"TS), T(IMAGEX_PROGNAME));
+ } else if (invocation_cmd != CMD_NONE) {
+ tsprintf(buf, T("wim%"TS), imagex_commands[cmd].name);
} else {
const tchar *format;
- static tchar buf[50];
if (nospace)
format = T("%"TS"-%"TS"");
else
format = T("%"TS" %"TS"");
tsprintf(buf, format, invocation_name, imagex_commands[cmd].name);
- return buf;
}
+ return buf;
}
static void
if (!tstrcmp(invocation_name + 3,
imagex_commands[i].name))
{
- using_cmd_from_invocation_name = true;
+ invocation_cmd = i;
cmd = i;
break;
}