1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/file.h"
24 #include "common/md5.h"
25 #include "common/translation.h"
26 
27 #include "gui/error.h"
28 
29 #include "engines/grim/md5check.h"
30 #include "engines/grim/grim.h"
31 
32 namespace Grim {
33 
34 // Grim retail
35 
36 const char *gfupd101[] = {
37 	"bc57c4db2ab814f3bb115ec5702b62f4"
38 };
39 const char *year4mus[] = {
40 	"939e041887c1b14f99ad951ac8e3cb25" //english unpatched
41 };
42 const char *year3mus[] = {
43 	"df556a8fc151f6f48bb68a8cef855e7d" //english unpatched
44 };
45 const char *year2mus[] = {
46 	"775376fccf0415258be6b33e7e6e4985" //english unpatched
47 };
48 const char *year1mus[] = {
49 	"c555c95b0f7557617da364091589d6ea" //english unpatched
50 };
51 const char *year0mus[] = {
52 	"fea10f11abe3ac32d53e4798f80d5ba0" //english unpatched
53 };
54 const char *vox0004[] = {
55 	"ae53a36f77eb0d42a28653b28c345439", //english unpatched
56 	"57915d4dd3aa5aa44817477b7bd41ce6", //italian unpatched
57 	"bae246c5335c1d139b97a48277ee8841", //german unpatched
58 	"a49dce6e1bb83ad40b47e03903aaff1b", //french unpatched
59 	"3577a8b6cf013bc5b9c9133e29d1f4f0", //spanish unpatched
60 	"2be5b0cc13a83f59945d31080b0949bb"  //brasilian-portuguese
61 };
62 const char *vox0003[] = {
63 	"7c88ad7c949a516793b584299f33ed23", //english unpatched
64 	"f900cb063fbd0ef2a0516e9a00291d13", //italian unpatched
65 	"5bda9a36181c1fea368491b842c11efe", //german unpatched
66 	"c4aa2c45b24f351e8fce40a141084fb0", //french unpatched
67 	"1d4e94e3d3fd803a02c9993412359082", //spanish unpatched
68 	"e107073a05f588df0c057b594c28b50e"  //brasilian-portuguese
69 };
70 const char *vox0002[] = {
71 	"70419878e32377d9d2906fbcb2cb59b5", //english unpatched
72 	"616e4147c39268b650ce112bf79ea3a1", //italian unpatched
73 	"5ea9fde04f3315a51fe1fe9c5bdb9d0d", //german unpatched
74 	"24bbf1f6d3d63ae07ad2dd06bd7dad8c", //french unpatched
75 	"c4484dadd4a33066290e1847523d7d64", //spanish unpatched
76 	"0748f44ee1e67b6d7555a644a1fa43ce"  //brasilian-portuguese
77 };
78 const char *vox0001[] = {
79 	"40beb2e0a6572dc89fddb21f282bc237", //english pre-patched
80 	"6a32f8079d2d98d1c10ec8364765fd4b", //english unpatched
81 	"a0455d5d883ed46f0bda5030e4b5654c", //italian unpatched
82 	"e13eb421b9490cbaeef66f0cf6156764", //german unpatched
83 	"e940d5a4a4f2229f0a6674bf45464457", //french unpatched
84 	"77cdd6f02bc3f7085bff17c454066de3", //spanish unpatched
85 	"31f261f87cc4854055c1ca1afddf677e"  //brasilian-portuguese
86 };
87 const char *vox0000[] = {
88 	"c7900f32d48d7e265629bd355a21c795", //english pre-patched
89 	"67627f2d9314f9c0ae55dd2099fc052f", //english unpatched
90 	"c9e1a755f280b3ebff58578c4e5f1e52", //italian unpatched
91 	"e884221099ba62dacf04a35be8428419", //german unpatched
92 	"dbe35af39eec29db21a4c6e1c228cc9d", //french unpatched
93 	"076bf048de229ad8cefcb3d7c0bfd134", //spanish unpatched
94 	"d48832ea234015e74590654ada02e163"  //brasilian-portuguese
95 };
96 const char *movie04[] = {
97 	"605d6f2cc4d21fbe702d8e637b5bcfa1", //english unpatched
98 	"7c8d7e0f4beaca3910658290e8b14cf8", //italian unpatched
99 	"f1b8c1de4f82099ab080f9cbe2b02da6", //german unpatched
100 	"7e2a4578010cdf5407bb24dcfb6705e4", //french unpatched
101 	"2daf2ec272a7be49cbfde053482f182c", //spanish unpatched
102 	"d9bfe59690a5de0500d18e29cdaa293f"  //brasilian-portuguese
103 };
104 const char *movie03[] = {
105 	"113a768e7206016df72f9d2f5c1851b7", //english unpatched
106 	"0fdb7dda9ebc049eac386d29bface366", //italian unpatched
107 	"d2aae2e27616f78016a71818e528acda", //german unpatched
108 	"c2ba7adbf09b7a4f69c180f1c74297ee", //french unpatched
109 	"fb87d5a9e3a81d3ffd521dee4432c4da", //spanish unpatched
110 	"5280486c3aee4fb1f9dcbc289f5f58b9"  //brasilian-portuguese
111 };
112 const char *movie02[] = {
113 	"24a8704a331a03097d195f3597fe21e1", //english unpatched
114 	"129dad4e40987e91c5549c819d0dad1d", //italian unpatched
115 	"a4d5c108a167afb0674e26790edf65e6", //german unpatched
116 	"90fce3e6e1f91455d92b072f773f0a67", //french unpatched
117 	"f5879c544f4c1f1f2e2d2e92c026c245", //spanish unpatched
118 	"000185c50bbf09bcd7421667d46a9e5c"  //brasilian-portuguese
119 };
120 const char *movie01[] = {
121 	"548a19a0a4d4ccb8660966d646210820", //english unpatched
122 	"9fd30d0289f9b4d5c09e821a0a478db5", //italian unpatched
123 	"500bc51ce211d528f6c7170f479c9525", //german unpatched
124 	"16674e1496e4fb3f0f5f173f12e30617", //french unpatched
125 	"ede9fb7d035a5d4af496f23f811707a2", //spanish unpatched
126 	"a88876b3347106d49b733c178f0d606a"  //brasilian-portuguese
127 };
128 const char *movie00[] = {
129 	"0c6b8e4fa74024c4afdf7758f8d8b1a0" //english unpatched
130 };
131 const char *data004[] = {
132 	"2cdb79d3606965a9a0a3378507488dd7" //english unpatched
133 };
134 const char *data003[] = {
135 	"76dcfc2c21f3412415674c65611fb76d", //english unpatched
136 	"7f76c20f1d77db287473ffef10b8b309" //german unpatched
137 };
138 const char *data002[] = {
139 	"d236403c0d860961963db0134380001f" //english unpatched
140 };
141 const char *data001[] = {
142 	"84cf3072586fe2840ae16774adb6f5cb" //english unpatched
143 };
144 const char *data000[] = {
145 	"2069b8bf113119910df8219e787e7e94", //english pre-patched
146 	"08e2505a6a7fd90d3920131b1297c60f" //english unpatched
147 };
148 const char *credits[] = {
149 	"6dcecad8f01657184f8576aab8fb3f00", //english unpatched
150 	"1827307248d55c07642342c9213a4723", //italian unpatched
151 	"2e6319c2ec5772ced5dc9f8b41eb5de7", //german unpatched
152 	"cd71ca4e600198277f22e944988f7516", //french unpatched
153 	"836a2081d5e57ed6ef5eaade7f770b0e", //spanish unpatched
154 	"368baa2f319a72278035095e4f4a4466"  //brasilian-portuguese
155 };
156 const char *local[] = {
157 	"6142624ce13ea3c9079aa80918010c4a", //italian unpatched
158 	"27c961c16f9eaf0260781883150e5611", //german unpatched
159 	"c9dd41f66883959de27f80bbe457f30d", //french unpatched
160 	"d22648d6787c2f8f0a789ee3ed0c08f7", //spanish unpatched
161 	"04d76cbbd5e603f35318bebb64f69378"  //brasilian-portuguese
162 };
163 
164 
165 // Grim demo
166 
167 const char *gfdemo01[] = {
168 	"25d831d57a93eb3ab8edbb07b7b63943"
169 };
170 const char *gdemo001[] = {
171 	"aa44d6c01a1b03d4607901933635d385"
172 };
173 const char *gfdemo01ger[] = {
174 	"fd728f040557118b7ca436f8205029e5"
175 };
176 const char *gfdemo01fra[] = {
177 	"fd728f040557118b7ca436f8205029e5" // Same as german
178 };
179 const char *gfdemo01ita[] = {
180 	"fd728f040557118b7ca436f8205029e5" // Same as german
181 };
182 const char *gfdemo01spa[] = {
183 	"fd728f040557118b7ca436f8205029e5" // Same as german
184 };
185 const char *grimdemo[] = {
186 	"3ba28e7e36a49b5fd01ba98e3c772fe8"
187 };
188 const char *sound001[] = {
189 	"c91a7d405d15fb198a9cb31f89637026"
190 };
191 const char *voice001[] = {
192 	"f24a45079394fee296a0f7fad07c7fad"
193 };
194 const char *voice001ger[] = {
195 	"d1d68735ae10148ecccb6b5000a4db96"
196 };
197 const char *voice001fra[] = {
198 	"43f56fca727e117b724051c740202c26"
199 };
200 const char *voice001ita[] = {
201 	"412bd831ec42d226fa173e0f55cb47cd"
202 };
203 const char *voice001spa[] = {
204 	"00cb825deca33b96719bc157a5427c40"
205 };
206 
207 // EMI retail PC version
208 
209 const char *emi_artAll[] = {
210 	"8c7db9dab564854f2c4bab0571104780", // english patched
211 	"7c1da307c5c3eb1ba65b7c1a2e6b5bce", // german patched
212 	"f2ec4854639cd25792dd3e88fb08a1e6", // spanish patched
213 	"e0fbba846efca842553bb1a726a25dcf", // french patched
214 	"b9838ab13a672a42b1fbc8893b94ca26", // italian patched
215 	"52111c719bcccacd4b4b8548007edd9c" 	// Russian version
216 };
217 const char *emi_artJam[] = {
218 	"e5ff286dbf7b23d1ad41dd8defe48291", // english patched
219 	"f0bcfa22f77d12e25920148d405a9615", // german patched
220 	"86ceeb03620d316f2dba86f68e40bebb", // spanish patched
221 	"6b9c6c88a0cd95f92f60db823fca4baa", // french patched
222 	"70a6fe11cc2de45f7b0650c8ea749156", // italian patched
223 	"10cb2cf22497d0007263116db68692a6", // Mac version
224 };
225 const char *emi_artLuc[] = {
226 	"1fcaef5755e6f6c3c30c89536022bd72", // english patched
227 	"0f6bcf8997ddd3cbdf161132103f769d", // german patched
228 	"cc956c2b6e99329bb970c9c18ed63b80", // spanish patched
229 	"1d388d0c12f99ba9af540f1b8b98e34b", // french patched
230 	"24216ef38709dc0be3771755bd274b79", // italian patched
231 };
232 const char *emi_artMel[] = {
233 	"66144e92a0742fdc9cc6c4f892c53e84", // english patched
234 	"ed1d2548374339775110bf5826db9f6d", // german patched
235 	"9b49161e7bb4db1dd3cb66d33940c22f", // spanish patched
236 	"33f3dc6eaf6ec50a9dbad3858dc00876", // french patched
237 	"640559d6854c3aa5b63bfad1a9afd60e", // italian patched
238 };
239 const char *emi_artMon[] = {
240 	"3510567bda8a4e8c5aee4c3b3bb1f98e", // english patched
241 	"5ff8b38e44fe1d3aeeb277f35f932d7b", // german patched
242 	"1d69547c39a9a85bfb1bf50c503f479d", // spanish patched
243 	"408a55615fef4282b9996aa0df8373e3", // french patched
244 	"a27c1a33652473d7caf26c069520a765", // italian patched
245 };
246 const char *emi_lip[] = {
247 	"57eceeae6b82028243ede6c97c334c57", // english patched
248 	"0ad24338f33f8ed9b4ab21e43f99aff0", // german patched
249 	"c0e9f1197338440b005431d2b365d287", // spanish patched
250 	"53973abc64a8ecaf963ba7e2dc6f7b42", // french patched
251 	"9b64f65a9473d11e34055137c4d978d1", // italian patched
252 };
253 const char *emi_local[] = {
254 	"c3b694d941c05264e8c37dc2be75ca1c", // english patched
255 	"6bd6582e9ab602c1f86c8593563cc9e5"	// Russian version
256 };
257 const char *emi_patch[] = {
258 	"067100a100b3ca9283b796480aa39b52", // english patched
259 };
260 const char *emi_update[] = {
261 	"7c7dbd2349d49e382a2dea40bed448e0", // english
262 	"dc1376baf7c8be28854a6fa620ad2278", // german
263 	"12c5db7d07d198d1506ab8b141dd594d", // spanish
264 	"cc5ff3bb8f78a0eb4b8e0feb9cdd2e87", // french
265 	"943ad57c2873b5eb9928e6b04a5b48d4", // italian
266 	"6d2516abcdce4266ad3ae873040258ab", // portuguese
267 };
268 const char *emi_sfx[] = {
269 	"a5d2ded26255518b82030466c2368168", // english patched
270 };
271 const char *emi_voiceAll[] = {
272 	"18d3996c7de4d460b4cd4ee5897a90ae", // english patched
273 	"e65a13f2906899ab6eca2cce3c4cb514", // german patched
274 	"073ecbe5f23d17536dce591174bac593", // spanish patched
275 	"86126ac852312452ee79558a5e76d7fd", // french patched
276 	"9b6b4748e872712c267d65778a3ed2da", // italian patched
277 };
278 const char *emi_voiceJam[] = {
279 	"2318a4680a89b93f1f71b09e66c65c86", // english patched
280 	"3df7d4964fe33f22be67920b21d65710", // german patched
281 	"173b1b949a84746d51d51ccbf7e9856e", // spanish patched
282 	"89947e7e6064356ebfde10b644f3d612", // french patched
283 	"a50b0d5d7f3aecd8629bd5e8c0647bcc", // italian patched
284 };
285 const char *emi_voiceLuc[] = {
286 	"d5e4842e421bdb891e6cbf88741e9119", // english patched
287 	"60d96bb92042729037b37c0056f93267", // german patched
288 	"2e0279b8753129f6ce167cc0823a4865", // spanish patched
289 	"ab9fe90e177cd03af1e34059117cc995", // french patched
290 	"c6ed446d4448de214dbdcbb6cbcca41b", // italian patched
291 };
292 const char *emi_voiceMel[] = {
293 	"b8b19fc4a9438f51a99f7cf3cad9c419", // english patched
294 	"0511a19405b763e2dd9ab5b0637757ee", // german patched
295 	"15154f16af25c55d7b797174032abe8a", // spanish patched
296 	"3e678cef88037ebd6c52988744401c03", // french patched
297 	"d1af7a4f0a2bed25c43d3fd197b6df3b", // italian patched
298 };
299 const char *emi_voiceMon[] = {
300 	"9327a6bea951b28bac31bdb52007dc41", // english patched
301 	"e3046478916f0000a657f9ebf498e120", // german patched
302 	"eda144022632cafc45c3174abc774468", // spanish patched
303 	"ef130c43a84c9d88a3e95abc51839292", // french patched
304 	"bc4d8ab5231f620c46117205578a2642", // italian patched
305 };
306 
307 // EMI retail PS2 version
308 
309 const char *emiPS2_artAll[] = {
310 	"7bed6dd54ea6509b708e93017c14df8d", // english
311 };
312 const char *emiPS2_artJam[] = {
313 	"199c713bbfc22ae941502ffd60ea794d", // english
314 };
315 const char *emiPS2_artLuc[] = {
316 	"7add9758294c2118621e900940e66838", // english
317 };
318 const char *emiPS2_artMel[] = {
319 	"514f1a684022831c178a18d13a16b6ad", // english PAL?
320 	"c4f51395440049942fae39bf6155e82c", // english NTSC
321 };
322 const char *emiPS2_artMon[] = {
323 	"db945bd9d5fa990447bbabf6a1e00e5b", // english
324 };
325 const char *emiPS2_lip[] = {
326 	"57eceeae6b82028243ede6c97c334c57", // english
327 };
328 const char *emiPS2_local[] = {
329 	"da26ad3a739f2fa341988901ce8dfa49", // english
330 };
331 /*
332 const char *emiPS2_music1[] = {
333 	"a44753d9aaed016e6c7b398b55c97d3d", // english
334 };
335 const char *emiPS2_music2[] = {
336 	"204cb3d451e4bf71ae5432ab33ca3a49", // english
337 };
338 */
339 const char *emiPS2_sfx[] = {
340 	"877e90e1329182caaf27d2ce4d3c9c42", // english
341 };
342 const char *emiPS2_voiceAll[] = {
343 	"194a1e545a348df0fe488012bc703338", // english
344 };
345 const char *emiPS2_voiceJam[] = {
346 	"686b45178a4b2fdb5bee2097739feea9", // english
347 };
348 const char *emiPS2_voiceLuc[] = {
349 	"c5e8e0ce9986385b6c1f31b68768be47", // english
350 };
351 const char *emiPS2_voiceMel[] = {
352 	"54663fc82520f1f02d7f3d9b29894540", // english
353 };
354 const char *emiPS2_voiceMon[] = {
355 	"b4a938b9c116e9370e992c8edfb00c35", // english
356 };
357 
358 // EMI demo
359 
360 const char *emid_i9n[] = {
361 	"d913504ec3a2fe52ee02a20a154a2b17", // english patched
362 	"1cd0547b7cb26082274624b146dab3f1", // french
363 	"0e011c72372acc4baeac259b46ae30f4", // german
364 	"25523ee7687096382cbd3f3b6d30b84c", // spanish
365 };
366 const char *emid_lip[] = {
367 	"0a145aa7acc1a68a738c7a6f27d23283", // english patched
368 };
369 const char *emid_MagDemo[] = {
370 	"0a7f0e72d3fab641f0d7b0efbaa15cdc", // english patched
371 };
372 const char *emid_tile[] = {
373 	"23fdff61743c5621963ca04e8ca43000", // english patched
374 };
375 const char *emid_voice[] = {
376 	"7f9867d48b5e0af5cb3fbd8d79741f5d", // english patched
377 };
378 
379 // EMI Macintosh
380 const char *emi_installer[] = {
381 	"93a639e3221405862dc46e9706216c00", // German (EFMI Installer)
382 	"a42f8aa079a6d23c285fceba191e67a4", // English (Monkey Island 4 Installer)
383 };
384 
385 bool MD5Check::_initted = false;
386 Common::Array<MD5Check::MD5Sum> *MD5Check::_files = nullptr;
387 int MD5Check::_iterator = -1;
388 
init()389 void MD5Check::init() {
390 	if (_initted) {
391 		return;
392 	}
393 	_initted = true;
394 	_files = new Common::Array<MD5Sum>();
395 
396 	#define MD5SUM(filename, sums) _files->push_back(MD5Sum(filename, sums, sizeof(sums) / sizeof(const char *)));
397 
398 	if (g_grim->getGameType() == GType_GRIM) {
399 		if (g_grim->getGameFlags() & ADGF_DEMO) {
400 			bool isDemoWithVideo = false;
401 			if (g_grim->getGameLanguage() == Common::DE_DEU) {
402 				MD5SUM("gfdemo01.lab", gfdemo01ger)
403 				MD5SUM("voice001.lab", voice001ger)
404 			} else if (g_grim->getGameLanguage() == Common::FR_FRA) {
405 				MD5SUM("gfdemo01.lab", gfdemo01fra)
406 				MD5SUM("voice001.lab", voice001fra)
407 			} else if (g_grim->getGameLanguage() == Common::IT_ITA) {
408 				MD5SUM("gfdemo01.lab", gfdemo01ita)
409 				MD5SUM("voice001.lab", voice001ita)
410 			} else if (g_grim->getGameLanguage() == Common::ES_ESP) {
411 				MD5SUM("gfdemo01.lab", gfdemo01spa)
412 				MD5SUM("voice001.lab", voice001spa)
413 			} else {
414 				// Check which version we have
415 				Common::File test;
416 				if (!test.open("gfdemo01.lab")) {
417 					isDemoWithVideo = true;
418 					MD5SUM("gdemo001.lab", gdemo001);
419 				} else {
420 					MD5SUM("gfdemo01.lab", gfdemo01)
421 					MD5SUM("voice001.lab", voice001)
422 				}
423 			}
424 			if (!isDemoWithVideo) {
425 				MD5SUM("sound001.lab", sound001)
426 			}
427 			MD5SUM("grimdemo.mus", grimdemo)
428 		} else {
429 			MD5SUM("gfupd101.exe", gfupd101)
430 			MD5SUM("year4mus.lab", year4mus)
431 			MD5SUM("year3mus.lab", year3mus)
432 			MD5SUM("year2mus.lab", year2mus)
433 			MD5SUM("year1mus.lab", year1mus)
434 			MD5SUM("year0mus.lab", year0mus)
435 			MD5SUM("vox0004.lab", vox0004)
436 			MD5SUM("vox0003.lab", vox0003)
437 			MD5SUM("vox0002.lab", vox0002)
438 			MD5SUM("vox0001.lab", vox0001)
439 			MD5SUM("vox0000.lab", vox0000)
440 			MD5SUM("movie04.lab", movie04)
441 			MD5SUM("movie03.lab", movie03)
442 			MD5SUM("movie02.lab", movie02)
443 			MD5SUM("movie01.lab", movie01)
444 			MD5SUM("movie00.lab", movie00)
445 			MD5SUM("data004.lab", data004)
446 			MD5SUM("data003.lab", data003)
447 			MD5SUM("data002.lab", data002)
448 			MD5SUM("data001.lab", data001)
449 			MD5SUM("data000.lab", data000)
450 			MD5SUM("credits.lab", credits)
451 			if (g_grim->getGameLanguage() != Common::EN_ANY) {
452 				MD5SUM("local.lab", local)
453 			}
454 		}
455 	} else {
456 		if (g_grim->getGameFlags() & ADGF_DEMO) {
457 			MD5SUM("i9n.lab", emid_i9n)
458 			MD5SUM("lip.lab", emid_lip)
459 			MD5SUM("MagDemo.lab", emid_MagDemo)
460 			MD5SUM("tile.lab", emid_tile)
461 			MD5SUM("voice.lab", emid_voice)
462 		} else if (g_grim->getGamePlatform() == Common::kPlatformPS2) {
463 			MD5SUM("artAll.m4b", emiPS2_artAll)
464 			MD5SUM("artJam.m4b", emiPS2_artJam)
465 			MD5SUM("artLuc.m4b", emiPS2_artLuc)
466 			MD5SUM("artMel.m4b", emiPS2_artMel)
467 			MD5SUM("artMon.m4b", emiPS2_artMon)
468 			MD5SUM("lip.m4b", emiPS2_lip)
469 			MD5SUM("local.m4b", emiPS2_local)
470 			MD5SUM("sfx.m4b", emiPS2_sfx)
471 			MD5SUM("voiceAll.m4b", emiPS2_voiceAll)
472 			MD5SUM("voiceJam.m4b", emiPS2_voiceJam)
473 			MD5SUM("voiceLuc.m4b", emiPS2_voiceLuc)
474 			MD5SUM("voiceMel.m4b", emiPS2_voiceMel)
475 			MD5SUM("voiceMon.m4b", emiPS2_voiceMon)
476 		} else {
477 			if (g_grim->getGamePlatform() == Common::kPlatformMacintosh) {
478 				if (g_grim->getGameLanguage() == Common::DE_DEU) {
479 					// Known to be the correct filename for german
480 					MD5SUM("EFMI Installer", emi_installer)
481 				} else {
482 					// Known to be the correct filename for english
483 					MD5SUM("Monkey Island 4 Installer", emi_installer)
484 				}
485 			}
486 			MD5SUM("artAll.m4b", emi_artAll)
487 			MD5SUM("artJam.m4b", emi_artJam)
488 			MD5SUM("artLuc.m4b", emi_artLuc)
489 			MD5SUM("artMel.m4b", emi_artMel)
490 			MD5SUM("artMon.m4b", emi_artMon)
491 			MD5SUM("lip.m4b", emi_lip)
492 			MD5SUM("local.m4b", emi_local)
493 			MD5SUM("sfx.m4b", emi_sfx)
494 			MD5SUM("voiceAll.m4b", emi_voiceAll)
495 			MD5SUM("voiceJam.m4b", emi_voiceJam)
496 			MD5SUM("voiceLuc.m4b", emi_voiceLuc)
497 			MD5SUM("voiceMel.m4b", emi_voiceMel)
498 			MD5SUM("voiceMon.m4b", emi_voiceMon)
499 
500 			const char *updateFilename = g_grim->getUpdateFilename();
501 			if (updateFilename)
502 				MD5SUM(updateFilename, emi_update)
503 		}
504 	}
505 
506 	#undef MD5SUM
507 }
508 
clear()509 void MD5Check::clear() {
510 	delete _files;
511 	_files = nullptr;
512 	_initted = false;
513 }
514 
checkMD5(const MD5Sum & sums,const char * md5)515 bool MD5Check::checkMD5(const MD5Sum &sums, const char *md5) {
516 	for (int i = 0; i < sums.numSums; ++i) {
517 		if (strcmp(sums.sums[i], md5) == 0) {
518 			return true;
519 		}
520 	}
521 	return false;
522 }
523 
checkFiles()524 bool MD5Check::checkFiles() {
525 	startCheckFiles();
526 	bool ok = true;
527 	while (_iterator != -1) {
528 		ok = advanceCheck() && ok;
529 	}
530 
531 	return ok;
532 }
533 
startCheckFiles()534 void MD5Check::startCheckFiles() {
535 	init();
536 	_iterator = 0;
537 }
538 
advanceCheck(int * pos,int * total)539 bool MD5Check::advanceCheck(int *pos, int *total) {
540 	if (_iterator < 0) {
541 		return false;
542 	}
543 
544 	const MD5Sum &sum = (*_files)[_iterator++];
545 	if (pos) {
546 		*pos = _iterator;
547 	}
548 	if (total) {
549 		*total = _files->size();
550 	}
551 	if ((uint32)_iterator == _files->size()) {
552 		_iterator = -1;
553 	}
554 
555 	Common::File file;
556 	if (file.open(sum.filename)) {
557 		Common::String md5 = Common::computeStreamMD5AsString(file);
558 		if (!checkMD5(sum, md5.c_str())) {
559 			warning("'%s' may be corrupted. MD5: '%s'", sum.filename, md5.c_str());
560 			GUI::displayErrorDialog(Common::U32String::format(_("The game data file %s may be corrupted.\nIf you are sure it is "
561 									"not please provide the ScummVM team the following code, along with the file name, the language and a "
562 									"description of your game version (i.e. dvd-box or jewelcase):\n%s"), sum.filename, md5.c_str()));
563 			return false;
564 		}
565 	} else {
566 		warning("Could not open %s for checking", sum.filename);
567 		GUI::displayErrorDialog(Common::U32String::format(_("Could not open the file %s for checking.\nIt may be missing or "
568 								"you may not have the rights to open it.\nGo to https://wiki.scummvm.org/index.php/Datafiles to see a list "
569 								"of the needed files."), sum.filename));
570 		return false;
571 	}
572 
573 	return true;
574 }
575 
576 }
577