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 http://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;
52 verify_begin_blob(struct blob_descriptor *blob, void *_ctx)
54 struct verify_blob_list_ctx *ctx = _ctx;
56 ctx->cur_blob_offset = 0;
57 ctx->cur_blob_size = blob->size;
62 verify_consume_chunk(const void *chunk, size_t size, void *_ctx)
64 struct verify_blob_list_ctx *ctx = _ctx;
65 union wimlib_progress_info *progress = ctx->progress;
67 ctx->cur_blob_offset += size;
68 if (ctx->cur_blob_offset == ctx->cur_blob_size)
69 progress->verify_streams.completed_streams++;
71 progress->verify_streams.completed_bytes += size;
73 if (progress->verify_streams.completed_bytes >= ctx->next_progress) {
75 int ret = call_progress(ctx->progfunc,
76 WIMLIB_PROGRESS_MSG_VERIFY_STREAMS,
77 progress, ctx->progctx);
81 set_next_progress(progress->verify_streams.completed_bytes,
82 progress->verify_streams.total_bytes,
89 verify_file_data_present(struct wim_image_metadata *imd,
90 struct blob_table *blob_table)
92 struct wim_inode *inode;
95 image_for_each_inode(inode, imd) {
96 ret = inode_resolve_streams(inode, blob_table, false);
103 /* API function documented in wimlib.h */
105 wimlib_verify_wim(WIMStruct *wim, int verify_flags)
108 LIST_HEAD(blob_list);
109 union wimlib_progress_info progress;
110 struct verify_blob_list_ctx ctx;
111 struct blob_descriptor *blob;
112 struct read_blob_callbacks cbs = {
113 .begin_blob = verify_begin_blob,
114 .consume_chunk = verify_consume_chunk,
118 /* Check parameters */
121 return WIMLIB_ERR_INVALID_PARAM;
124 return WIMLIB_ERR_INVALID_PARAM;
126 /* Verify the images */
128 if (wim_has_metadata(wim)) {
130 memset(&progress, 0, sizeof(progress));
131 progress.verify_image.wimfile = wim->filename;
132 progress.verify_image.total_images = wim->hdr.image_count;
134 for (int i = 1; i <= wim->hdr.image_count; i++) {
136 progress.verify_image.current_image = i;
138 ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_BEGIN_VERIFY_IMAGE,
139 &progress, wim->progctx);
143 ret = select_wim_image(wim, i);
147 ret = verify_file_data_present(wim_get_current_image_metadata(wim),
152 ret = call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_END_VERIFY_IMAGE,
153 &progress, wim->progctx);
158 WARNING("\"%"TS"\" does not contain image metadata. Skipping image verification.",
162 /* Verify the blobs: SHA-1 message digests must match */
164 for_blob_in_table(wim->blob_table, append_blob_to_list, &blob_list);
166 memset(&progress, 0, sizeof(progress));
168 progress.verify_streams.wimfile = wim->filename;
169 list_for_each_entry(blob, &blob_list, extraction_list) {
170 progress.verify_streams.total_streams++;
171 progress.verify_streams.total_bytes += blob->size;
174 ctx.progfunc = wim->progfunc;
175 ctx.progctx = wim->progctx;
176 ctx.progress = &progress;
177 ctx.next_progress = 0;
179 ret = call_progress(ctx.progfunc, WIMLIB_PROGRESS_MSG_VERIFY_STREAMS,
180 ctx.progress, ctx.progctx);
184 return read_blob_list(&blob_list,
185 offsetof(struct blob_descriptor, extraction_list),
186 &cbs, VERIFY_BLOB_HASHES);