| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2009 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2014-08-31 09:34:58 -04:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  | #include "Common/Align.h"
 | 
					
						
							| 
									
										
										
										
											2015-09-26 16:39:47 -04:00
										 |  |  | #include "Common/Assert.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/FileUtil.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:29:54 -04:00
										 |  |  | #include "Common/Logging/Log.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include "DiscIO/Blob.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "DiscIO/WiiWad.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace DiscIO | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-25 17:24:44 -04:00
										 |  |  | namespace | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-25 17:24:44 -04:00
										 |  |  | std::vector<u8> CreateWADEntry(IBlobReader& reader, u32 size, u64 offset) | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (size == 0) | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2015-12-19 13:46:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   std::vector<u8> buffer(size); | 
					
						
							| 
									
										
										
										
											2015-12-19 13:46:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!reader.Read(offset, size, buffer.data())) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ERROR_LOG(DISCIO, "WiiWAD: Could not read from file"); | 
					
						
							|  |  |  |     PanicAlertT("WiiWAD: Could not read from file"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-19 13:46:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return buffer; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-25 17:24:44 -04:00
										 |  |  | bool IsWiiWAD(const CBlobBigEndianReader& reader) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   u32 header_size = 0; | 
					
						
							|  |  |  |   u32 header_type = 0; | 
					
						
							|  |  |  |   reader.ReadSwapped(0x0, &header_size); | 
					
						
							|  |  |  |   reader.ReadSwapped(0x4, &header_type); | 
					
						
							|  |  |  |   return header_size == 0x20 && (header_type == 0x49730000 || header_type == 0x69620000); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | }  // Anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WiiWAD::WiiWAD(const std::string& name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   std::unique_ptr<IBlobReader> reader(CreateBlobReader(name)); | 
					
						
							|  |  |  |   if (reader == nullptr || File::IsDirectory(name)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_valid = false; | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_valid = ParseWAD(*reader); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WiiWAD::~WiiWAD() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 13:46:01 -05:00
										 |  |  | bool WiiWAD::ParseWAD(IBlobReader& reader) | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   CBlobBigEndianReader big_endian_reader(reader); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!IsWiiWAD(big_endian_reader)) | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   u32 certificate_chain_size; | 
					
						
							|  |  |  |   u32 reserved; | 
					
						
							|  |  |  |   u32 ticket_size; | 
					
						
							|  |  |  |   u32 tmd_size; | 
					
						
							|  |  |  |   u32 data_app_size; | 
					
						
							|  |  |  |   u32 footer_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!big_endian_reader.ReadSwapped(0x08, &certificate_chain_size) || | 
					
						
							|  |  |  |       !big_endian_reader.ReadSwapped(0x0C, &reserved) || | 
					
						
							|  |  |  |       !big_endian_reader.ReadSwapped(0x10, &ticket_size) || | 
					
						
							|  |  |  |       !big_endian_reader.ReadSwapped(0x14, &tmd_size) || | 
					
						
							|  |  |  |       !big_endian_reader.ReadSwapped(0x18, &data_app_size) || | 
					
						
							|  |  |  |       !big_endian_reader.ReadSwapped(0x1C, &footer_size)) | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG) | 
					
						
							|  |  |  |     _dbg_assert_msg_(BOOT, reserved == 0x00, "WiiWAD: Reserved must be 0x00"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   u32 offset = 0x40; | 
					
						
							|  |  |  |   m_certificate_chain = CreateWADEntry(reader, certificate_chain_size, offset); | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   offset += Common::AlignUp(certificate_chain_size, 0x40); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_ticket = CreateWADEntry(reader, ticket_size, offset); | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   offset += Common::AlignUp(ticket_size, 0x40); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_tmd = CreateWADEntry(reader, tmd_size, offset); | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   offset += Common::AlignUp(tmd_size, 0x40); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_data_app = CreateWADEntry(reader, data_app_size, offset); | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   offset += Common::AlignUp(data_app_size, 0x40); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_footer = CreateWADEntry(reader, footer_size, offset); | 
					
						
							| 
									
										
										
										
											2016-11-27 11:56:22 +01:00
										 |  |  |   offset += Common::AlignUp(footer_size, 0x40); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2009-07-06 02:10:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-25 17:24:44 -04:00
										 |  |  | }  // namespace DiscIO
 |