X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fxml.c;h=7ff9c615cda47af72b6366d18ce2e10fe5e39dbb;hp=5258aaf4cfacb7275e1d8203195668b09680c20d;hb=e3dc3c76cf0896eb98f455f2538999d23f95b61a;hpb=db52422f8a9e87e7d160b68b3271d26c41f0687e diff --git a/src/xml.c b/src/xml.c index 5258aaf4..7ff9c615 100644 --- a/src/xml.c +++ b/src/xml.c @@ -36,6 +36,7 @@ #include "wimlib/resource.h" #include "wimlib/timestamp.h" #include "wimlib/xml.h" +#include "wimlib/write.h" #include #include @@ -61,6 +62,7 @@ struct windows_info { tchar *product_name; tchar *edition_id; tchar *installation_type; + tchar *pkeyconfigversion; tchar *hal; tchar *product_type; tchar *product_suite; @@ -87,6 +89,7 @@ struct image_info { tchar *display_name; tchar *display_description; tchar *flags; + bool wimboot; struct wim_lookup_table *lookup_table; /* temporary field */ }; @@ -165,6 +168,18 @@ wim_info_get_num_images(const struct wim_info *info) return 0; } +void +wim_info_set_wimboot(struct wim_info *info, int image, bool value) +{ + info->images[image - 1].wimboot = value; +} + +bool +wim_info_get_wimboot(const struct wim_info *info, int image) +{ + return info->images[image - 1].wimboot; +} + /* Architecture constants are from w64 mingw winnt.h */ #define PROCESSOR_ARCHITECTURE_INTEL 0 #define PROCESSOR_ARCHITECTURE_MIPS 1 @@ -257,6 +272,9 @@ node_get_string(const xmlNode *string_node, tchar **tstr_ret) tchar *tstr = NULL; int ret; + if (*tstr_ret) + return 0; + for_node_child(string_node, child) { if (node_is_text(child) && child->content) { ret = utf8_to_tstr_simple(child->content, &tstr); @@ -313,6 +331,7 @@ destroy_windows_info(struct windows_info *windows_info) FREE(windows_info->hal); FREE(windows_info->product_type); FREE(windows_info->product_suite); + FREE(windows_info->pkeyconfigversion); for (size_t i = 0; i < windows_info->num_languages; i++) FREE(windows_info->languages[i]); FREE(windows_info->languages); @@ -448,7 +467,19 @@ xml_read_windows_info(const xmlNode *windows_node, ret = node_get_string(child, &windows_info->system_root); } else if (node_name_is(child, "HAL")) { ret = node_get_string(child, &windows_info->hal); + } else if (node_name_is(child, "SERVICINGDATA")) { + xmlNode *grandchild; + + for_node_child(child, grandchild) { + if (node_is_element(grandchild) && + node_name_is(grandchild, "PKEYCONFIGVERSION")) + { + ret = node_get_string(grandchild, + &windows_info->pkeyconfigversion); + } + } } + if (ret != 0) return ret; } @@ -502,6 +533,10 @@ xml_read_image_info(xmlNode *image_node, struct image_info *image_info) ret = node_get_string(child, &image_info->display_name); } else if (node_name_is(child, "DISPLAYDESCRIPTION")) { ret = node_get_string(child, &image_info->display_description); + } else if (node_name_is(child, "WIMBOOT")) { + if (node_get_u64(child) == 1) { + image_info->wimboot = true; + } } if (ret != 0) return ret; @@ -565,6 +600,16 @@ xml_read_wim_info(const xmlNode *wim_node, struct wim_info **wim_info_ret) i++; } else if (node_name_is(child, "TOTALBYTES")) { wim_info->total_bytes = node_get_u64(child); + } else if (node_name_is(child, "ESD")) { + xmlNode *esdchild; + for_node_child(child, esdchild) { + if (node_is_element(esdchild) && + node_name_is(esdchild, "ENCRYPTED")) + { + ret = WIMLIB_ERR_WIM_IS_ENCRYPTED; + goto err; + } + } } } @@ -689,7 +734,7 @@ xml_write_strings_from_specs(xmlTextWriter *writer, for (size_t i = 0; i < num_specs; i++) { int rc = xml_write_string(writer, specs[i].name, *(const tchar * const *) - (struct_with_strings + specs[i].offset)); + (struct_with_strings + specs[i].offset)); if (rc) return rc; } @@ -804,6 +849,21 @@ xml_write_windows_info(xmlTextWriter *writer, return rc; } + if (windows_info->pkeyconfigversion) { + rc = xmlTextWriterStartElement(writer, "SERVICINGDATA"); + if (rc < 0) + return rc; + + rc = xml_write_string(writer, "PKEYCONFIGVERSION", + windows_info->pkeyconfigversion); + if (rc) + return rc; + + rc = xmlTextWriterEndElement(writer); + if (rc < 0) + return rc; + } + if (windows_info->windows_version_exists) { rc = xml_write_windows_version(writer, &windows_info->windows_version); if (rc) @@ -901,6 +961,12 @@ xml_write_image_info(xmlTextWriter *writer, const struct image_info *image_info) if (rc) return rc; + if (image_info->wimboot) { + rc = xmlTextWriterWriteFormatElement(writer, "WIMBOOT", "%d", 1); + if (rc < 0) + return rc; + } + rc = xmlTextWriterEndElement(writer); /* */ if (rc < 0) return rc; @@ -938,6 +1004,12 @@ clone_windows_info(const struct windows_info *old, struct windows_info *new) if (ret) return ret; + if (old->pkeyconfigversion) { + new->pkeyconfigversion = TSTRDUP(old->pkeyconfigversion); + if (new->pkeyconfigversion == NULL) + return WIMLIB_ERR_NOMEM; + } + if (old->languages) { new->languages = CALLOC(old->num_languages, sizeof(new->languages[0])); if (!new->languages) @@ -1091,7 +1163,6 @@ xml_get_max_image_name_len(const WIMStruct *wim) return max_len; } -#ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR void xml_set_memory_allocator(void *(*malloc_func)(size_t), void (*free_func)(void *), @@ -1099,7 +1170,6 @@ xml_set_memory_allocator(void *(*malloc_func)(size_t), { xmlMemSetup(free_func, malloc_func, realloc_func, STRDUP); } -#endif static int calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) @@ -1153,9 +1223,9 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) */ lte = inode_unnamed_lte(inode, info->lookup_table); if (lte) { - info->total_bytes += wim_resource_size(lte); + info->total_bytes += lte->size; if (!dentry_is_first_in_inode(dentry)) - info->hard_link_bytes += wim_resource_size(lte); + info->hard_link_bytes += lte->size; } if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) { @@ -1164,7 +1234,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) lte = inode_stream_lte(inode, i + 1, info->lookup_table); if (lte) { info->hard_link_bytes += inode->i_nlink * - wim_resource_size(lte); + lte->size; } } } @@ -1289,6 +1359,8 @@ print_image_info(const struct wim_info *wim_info, int image) print_windows_info(&image_info->windows_info); if (image_info->flags) tprintf(T("Flags: %"TS"\n"), image_info->flags); + tprintf(T("WIMBoot compatible: %"TS"\n"), + image_info->wimboot ? T("yes") : T("no")); tputchar('\n'); } @@ -1311,23 +1383,18 @@ int read_wim_xml_data(WIMStruct *wim) { void *buf; + size_t bufsize; u8 *xml_data; xmlDoc *doc; xmlNode *root; int ret; - const struct resource_entry *res_entry; - - res_entry = &wim->hdr.xml_res_entry; - - DEBUG("Reading XML data: %"PRIu64" bytes at offset %"PRIu64"", - (u64)res_entry->size, res_entry->offset); - ret = res_entry_to_data(res_entry, wim, &buf); + ret = wimlib_get_xml_data(wim, &buf, &bufsize); if (ret) goto out; xml_data = buf; - doc = xmlReadMemory((const char *)xml_data, res_entry->original_size, + doc = xmlReadMemory((const char *)xml_data, bufsize, NULL, "UTF-16LE", 0); if (!doc) { ERROR("Failed to parse XML data"); @@ -1500,7 +1567,7 @@ out_write_error: /* Writes the XML data to a WIM file. */ int write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes, - struct resource_entry *out_res_entry, + struct wim_reshdr *out_reshdr, int write_resource_flags) { int ret; @@ -1508,7 +1575,7 @@ write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes, size_t xml_len; DEBUG("Writing WIM XML data (image=%d, offset=%"PRIu64")", - image, total_bytes, wim->out_fd.offset); + image, wim->out_fd.offset); ret = prepare_wim_xml_data(wim, image, total_bytes, &xml_data, &xml_len); @@ -1522,12 +1589,12 @@ write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes, WIM_RESHDR_FLAG_METADATA, &wim->out_fd, WIMLIB_COMPRESSION_TYPE_NONE, - out_res_entry, + 0, + out_reshdr, NULL, - write_resource_flags, - &wim->lzx_context); + write_resource_flags); FREE(xml_data); - DEBUG("ret=%d"); + DEBUG("ret=%d", ret); return ret; } @@ -1564,30 +1631,39 @@ wimlib_image_name_in_use(const WIMStruct *wim, const tchar *name) /* API function documented in wimlib.h */ WIMLIBAPI int -wimlib_extract_xml_data(WIMStruct *wim, FILE *fp) +wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret) { - size_t size; - void *buf; - int ret; + const struct wim_reshdr *xml_reshdr; - if (!wim->filename) + if (wim->filename == NULL && filedes_is_seekable(&wim->in_fd)) return WIMLIB_ERR_INVALID_PARAM; - ret = res_entry_to_data(&wim->hdr.xml_res_entry, wim, &buf); + if (buf_ret == NULL || bufsize_ret == NULL) + return WIMLIB_ERR_INVALID_PARAM; + + xml_reshdr = &wim->hdr.xml_data_reshdr; + + DEBUG("Reading XML data."); + *bufsize_ret = xml_reshdr->uncompressed_size; + return wim_reshdr_to_data(xml_reshdr, wim, buf_ret); +} + +WIMLIBAPI int +wimlib_extract_xml_data(WIMStruct *wim, FILE *fp) +{ + int ret; + void *buf; + size_t bufsize; + + ret = wimlib_get_xml_data(wim, &buf, &bufsize); if (ret) - goto out; + return ret; - size = wim->hdr.xml_res_entry.original_size; - if (fwrite(buf, 1, size, fp) != size) { + if (fwrite(buf, 1, bufsize, fp) != bufsize) { ERROR_WITH_ERRNO("Failed to extract XML data"); ret = WIMLIB_ERR_WRITE; - goto out_free_buf; } - - ret = 0; -out_free_buf: FREE(buf); -out: return ret; }