X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fxml.c;h=19cf5f327a0f8698d5534a9db4d1698bce5f85c7;hp=4b1d708da1bd03e01d8c0358f2ef09dbcfdbf0e4;hb=2784a74a03a6fe989e8d09ced028959ed1f2a2fd;hpb=650997e4865a090b6856c7ca34b02f42994e8e29 diff --git a/src/xml.c b/src/xml.c index 4b1d708d..19cf5f32 100644 --- a/src/xml.c +++ b/src/xml.c @@ -78,7 +78,7 @@ struct image_info { tchar *display_name; tchar *display_description; tchar *flags; - struct wim_lookup_table *lookup_table; /* Temporary field only */ + struct wim_lookup_table *lookup_table; /* temporary field */ }; struct xml_string_spec { @@ -1033,7 +1033,6 @@ static int calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) { struct image_info *info = arg; - struct wim_lookup_table *lookup_table = info->lookup_table; const struct wim_inode *inode = dentry->d_inode; struct wim_lookup_table_entry *lte; @@ -1090,7 +1089,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) { for (unsigned i = 0; i < inode->i_num_ads; i++) { if (inode->i_ads_entries[i].stream_name_nbytes) { - lte = inode_stream_lte(inode, i + 1, lookup_table); + lte = inode_stream_lte(inode, i + 1, info->lookup_table); if (lte) { info->hard_link_bytes += inode->i_nlink * wim_resource_size(lte); @@ -1123,7 +1122,7 @@ xml_update_image_info(WIMStruct *w, int image) image_info->hard_link_bytes = 0; image_info->lookup_table = w->lookup_table; - for_dentry_in_tree(w->image_metadata[image - 1].root_dentry, + for_dentry_in_tree(w->image_metadata[image - 1]->root_dentry, calculate_dentry_statistics, image_info); image_info->last_modification_time = get_wim_timestamp(); @@ -1212,7 +1211,7 @@ print_image_info(const struct wim_info *wim_info, int image) wim_timestamp_to_str(image_info->creation_time, buf, sizeof(buf)); tprintf(T("Creation Time: %"TS"\n"), buf); - wim_timestamp_to_str(image_info->creation_time, buf, sizeof(buf)); + wim_timestamp_to_str(image_info->last_modification_time, buf, sizeof(buf)); tprintf(T("Last Modification Time: %"TS"\n"), buf); if (image_info->windows_info_exists) print_windows_info(&image_info->windows_info); @@ -1239,8 +1238,9 @@ libxml_global_cleanup() * Reads the XML data from a WIM file. */ int -read_xml_data(FILE *fp, const struct resource_entry *res_entry, - utf16lechar **xml_data_ret, struct wim_info **info_ret) +read_xml_data(int in_fd, + const struct resource_entry *res_entry, + struct wim_info **info_ret) { utf16lechar *xml_data; xmlDoc *doc; @@ -1268,10 +1268,13 @@ read_xml_data(FILE *fp, const struct resource_entry *res_entry, goto out; } - ret = read_uncompressed_resource(fp, res_entry->offset, - res_entry->size, xml_data); - if (ret != 0) + if (full_pread(in_fd, xml_data, + res_entry->size, res_entry->offset) != res_entry->size) + { + ERROR_WITH_ERRNO("Error reading XML data"); + ret = WIMLIB_ERR_READ; goto out_free_xml_data; + } /* Null-terminate just in case */ ((u8*)xml_data)[res_entry->size] = 0; @@ -1303,13 +1306,7 @@ read_xml_data(FILE *fp, const struct resource_entry *res_entry, ret = WIMLIB_ERR_XML; goto out_free_doc; } - ret = xml_read_wim_info(root, info_ret); - if (ret != 0) - goto out_free_doc; - - *xml_data_ret = xml_data; - xml_data = NULL; out_free_doc: DEBUG("Freeing XML tree."); xmlFreeDoc(doc); @@ -1333,7 +1330,7 @@ out: * the offset of the XML data. */ int -write_xml_data(const struct wim_info *wim_info, int image, FILE *out, +write_xml_data(const struct wim_info *wim_info, int image, int out_fd, u64 total_bytes, struct resource_entry *out_res_entry) { xmlCharEncodingHandler *encoding_handler; @@ -1347,7 +1344,7 @@ write_xml_data(const struct wim_info *wim_info, int image, FILE *out, (wim_info != NULL && image >= 1 && image <= wim_info->num_images)); - start_offset = ftello(out); + start_offset = filedes_offset(out_fd); if (start_offset == -1) return WIMLIB_ERR_WRITE; @@ -1356,7 +1353,8 @@ write_xml_data(const struct wim_info *wim_info, int image, FILE *out, /* 2 bytes endianness marker for UTF-16LE. This is _required_ for WIM * XML data. */ - if ((putc(0xff, out)) == EOF || (putc(0xfe, out) == EOF)) { + static u8 bom[2] = {0xff, 0xfe}; + if (full_write(out_fd, bom, 2) != 2) { ERROR_WITH_ERRNO("Error writing XML data"); return WIMLIB_ERR_WRITE; } @@ -1382,7 +1380,7 @@ write_xml_data(const struct wim_info *wim_info, int image, FILE *out, goto out; } - out_buffer = xmlOutputBufferCreateFile(out, encoding_handler); + out_buffer = xmlOutputBufferCreateFd(out_fd, encoding_handler); if (!out_buffer) { ERROR("Failed to allocate xmlOutputBuffer"); ret = WIMLIB_ERR_NOMEM; @@ -1432,12 +1430,7 @@ write_xml_data(const struct wim_info *wim_info, int image, FILE *out, DEBUG("Ended XML document"); - /* Call xmlFreeTextWriter() before ftello() because the former will - * flush the file stream. */ - xmlFreeTextWriter(writer); - writer = NULL; - - end_offset = ftello(out); + end_offset = filedes_offset(out_fd); if (end_offset == -1) { ret = WIMLIB_ERR_WRITE; } else { @@ -1495,16 +1488,38 @@ wimlib_image_name_in_use(const WIMStruct *w, const tchar *name) WIMLIBAPI int wimlib_extract_xml_data(WIMStruct *w, FILE *fp) { - size_t bytes_written; + size_t size; + void *buf; + int ret; - if (!w->xml_data) - return WIMLIB_ERR_INVALID_PARAM; - bytes_written = fwrite(w->xml_data, 1, w->hdr.xml_res_entry.size, fp); - if (bytes_written != w->hdr.xml_res_entry.size) { + size = w->hdr.xml_res_entry.size; + if (sizeof(size_t) < sizeof(u64)) + if (size != w->hdr.xml_res_entry.size) + return WIMLIB_ERR_INVALID_PARAM; + + buf = MALLOC(size); + if (!buf) + return WIMLIB_ERR_NOMEM; + + if (full_pread(w->in_fd, + buf, + w->hdr.xml_res_entry.size, + w->hdr.xml_res_entry.offset) != w->hdr.xml_res_entry.size) + { + ERROR_WITH_ERRNO("Error reading XML data"); + ret = WIMLIB_ERR_READ; + goto out_free_buf; + } + + if (fwrite(buf, 1, size, fp) != size) { ERROR_WITH_ERRNO("Failed to extract XML data"); - return WIMLIB_ERR_WRITE; + ret = WIMLIB_ERR_WRITE; + } else { + ret = 0; } - return 0; +out_free_buf: + FREE(buf); + return ret; } /* Sets the name of an image in the WIM. */