8 * Copyright (C) 2012, 2013, 2014 Eric Biggers
10 * This file is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU Lesser General Public License as published by the Free
12 * Software Foundation; either version 3 of the License, or (at your option) any
15 * This file is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this file; if not, see https://www.gnu.org/licenses/.
28 #include "wimlib/blob_table.h"
29 #include "wimlib/dentry.h"
30 #include "wimlib/error.h"
31 #include "wimlib/metadata.h"
32 #include "wimlib/progress.h"
33 #include "wimlib/security.h"
36 append_blob_to_list(struct blob_descriptor *blob, void *_list)
38 list_add(&blob->extraction_list, (struct list_head *)_list);
42 struct verify_blob_list_ctx {
43 wimlib_progress_func_t progfunc;
45 union wimlib_progress_info *progress;
50 verify_continue_blob(const struct blob_descriptor *blob, u64 offset,
51 const void *chunk, size_t size, void *_ctx)
53 struct verify_blob_list_ctx *ctx = _ctx;
54 union wimlib_progress_info *progress = ctx->progress;
56 if (offset + size == blob->size)
57 progress->verify_streams.completed_streams++;
59 progress->verify_streams.completed_bytes += size;
61 if (progress->verify_streams.completed_bytes >= ctx->next_progress) {
63 int ret = call_progress(ctx->progfunc,
64 WIMLIB_PROGRESS_MSG_VERIFY_STREAMS,
65 progress, ctx->progctx);
69 set_next_progress(progress->verify_streams.completed_bytes,
70 progress->verify_streams.total_bytes,
77 verify_file_data_present(struct wim_image_metadata *imd,
78 struct blob_table *blob_table)
80 struct wim_inode *inode;
83 image_for_each_inode(inode, imd) {
84 ret = inode_resolve_streams(inode, blob_table, false);
91 /* API function documented in wimlib.h */
93 wimlib_verify_wim(WIMStruct *wim, int verify_flags)
97 union wimlib_progress_info progress;
98 struct verify_blob_list_ctx ctx;
99 struct blob_descriptor *blob;
100 struct read_blob_callbacks cbs = {
101 .continue_blob = verify_continue_blob,
105 /* Check parameters */
108 return WIMLIB_ERR_INVALID_PARAM;
111 return WIMLIB_ERR_INVALID_PARAM;
113 /* Verify the images */
115 if (wim_has_metadata(wim)) {
117 memset(&progress, 0, sizeof(progress));
118 progress.verify_image.wimfile = wim->filename;
119 progress.verify_image.total_images = wim->hdr.image_count;
121 for (int i = 1; i <= wim->hdr.image_count; i++) {
123 progress.verify_image.current_image = i;
125 ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_BEGIN_VERIFY_IMAGE,
126 &progress, wim->progctx);
130 ret = select_wim_image(wim, i);
134 ret = verify_file_data_present(wim_get_current_image_metadata(wim),
139 ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_END_VERIFY_IMAGE,
140 &progress, wim->progctx);
145 WARNING("\"%"TS"\" does not contain image metadata. Skipping image verification.",
149 /* Verify the blobs: SHA-1 message digests must match */
151 for_blob_in_table(wim->blob_table, append_blob_to_list, &blob_list);
153 memset(&progress, 0, sizeof(progress));
155 progress.verify_streams.wimfile = wim->filename;
156 list_for_each_entry(blob, &blob_list, extraction_list) {
157 progress.verify_streams.total_streams++;
158 progress.verify_streams.total_bytes += blob->size;
161 ctx.progfunc = wim->progfunc;
162 ctx.progctx = wim->progctx;
163 ctx.progress = &progress;
164 ctx.next_progress = 0;
166 ret = call_progress(ctx.progfunc, WIMLIB_PROGRESS_MSG_VERIFY_STREAMS,
167 ctx.progress, ctx.progctx);
171 return read_blob_list(&blob_list,
172 offsetof(struct blob_descriptor, extraction_list),
173 &cbs, VERIFY_BLOB_HASHES);