| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | #include <cstddef>
 | 
					
						
							|  |  |  | #include <cstring>
 | 
					
						
							|  |  |  | #include <map>
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/CommonPaths.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include "Common/FileUtil.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/MathUtil.h"
 | 
					
						
							|  |  |  | #include "DiscIO/FileBlob.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-27 20:13:31 +01:00
										 |  |  | #include "DiscIO/FileMonitor.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include "DiscIO/Volume.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "DiscIO/VolumeDirectory.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace DiscIO | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-14 05:27:29 +00:00
										 |  |  | CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, | 
					
						
							|  |  |  | 								   const std::string& _rApploader, const std::string& _rDOL) | 
					
						
							| 
									
										
										
										
											2010-01-29 19:45:01 +00:00
										 |  |  | 	: m_totalNameSize(0) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	, m_dataStartAddress(-1) | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	, m_diskHeader(DISKHEADERINFO_ADDRESS) | 
					
						
							|  |  |  | 	, m_diskHeaderInfo(new SDiskHeaderInfo()) | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	, m_fst_address(0) | 
					
						
							|  |  |  | 	, m_dol_address(0) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	m_rootDirectory = ExtractDirectoryName(_rDirectory); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// create the default disk header
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	SetUniqueID("AGBJ01"); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	SetName("Default name"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_bIsWii) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		SetDiskTypeWii(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		SetDiskTypeGC(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	// Don't load the dol if we've no apploader...
 | 
					
						
							|  |  |  | 	if (SetApploader(_rApploader)) | 
					
						
							|  |  |  | 		SetDOL(_rDOL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	BuildFST(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CVolumeDirectory::~CVolumeDirectory() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::string directoryName = ExtractDirectoryName(_rDirectory); | 
					
						
							| 
									
										
										
										
											2011-03-01 03:06:14 +00:00
										 |  |  | 	return File::IsDirectory(directoryName); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-28 10:35:48 +01:00
										 |  |  | bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt) const | 
					
						
							| 
									
										
										
										
											2009-02-22 13:59:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-17 13:21:02 +01:00
										 |  |  | 	if (!decrypt && (_Offset + _Length >= 0x400) && m_is_wii) | 
					
						
							| 
									
										
										
										
											2014-12-28 10:35:48 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// Fully supporting this would require re-encrypting every file that's read.
 | 
					
						
							|  |  |  | 		// Only supporting the areas that IOS allows software to read could be more feasible.
 | 
					
						
							|  |  |  | 		// Currently, only the header (up to 0x400) is supported, though we're cheating a bit
 | 
					
						
							|  |  |  | 		// with it by reading the header inside the current partition instead. Supporting the
 | 
					
						
							|  |  |  | 		// header is enough for booting games, but not for running things like the Disc Channel.
 | 
					
						
							| 
									
										
										
										
											2014-12-27 13:49:25 +01:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2014-12-28 10:35:48 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 13:21:02 +01:00
										 |  |  | 	if (decrypt && !m_is_wii) | 
					
						
							| 
									
										
										
										
											2014-12-28 10:35:48 +01:00
										 |  |  | 		PanicAlertT("Tried to decrypt data from a non-Wii volume"); | 
					
						
							| 
									
										
										
										
											2009-02-22 13:59:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	// header
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_Offset < DISKHEADERINFO_ADDRESS) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		WriteToBuffer(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, m_diskHeader.data(), _Offset, _Length, _pBuffer); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	// header info
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_Offset >= DISKHEADERINFO_ADDRESS && _Offset < APPLOADER_ADDRESS) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		WriteToBuffer(DISKHEADERINFO_ADDRESS, sizeof(m_diskHeaderInfo), (u8*)m_diskHeaderInfo.get(), _Offset, _Length, _pBuffer); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// apploader
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	if (_Offset >= APPLOADER_ADDRESS && _Offset < APPLOADER_ADDRESS + m_apploader.size()) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		WriteToBuffer(APPLOADER_ADDRESS, m_apploader.size(), m_apploader.data(), _Offset, _Length, _pBuffer); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// dol
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	if (_Offset >= m_dol_address && _Offset < m_dol_address + m_DOL.size()) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		WriteToBuffer(m_dol_address, m_DOL.size(), m_DOL.data(), _Offset, _Length, _pBuffer); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// fst
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	if (_Offset >= m_fst_address && _Offset < m_dataStartAddress) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		WriteToBuffer(m_fst_address, m_FSTData.size(), m_FSTData.data(), _Offset, _Length, _pBuffer); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (m_virtualDisk.empty()) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Determine which file the offset refers to
 | 
					
						
							|  |  |  | 	std::map<u64, std::string>::const_iterator fileIter = m_virtualDisk.lower_bound(_Offset); | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (fileIter->first > _Offset && fileIter != m_virtualDisk.begin()) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		--fileIter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// zero fill to start of file data
 | 
					
						
							|  |  |  | 	PadToAddress(fileIter->first, _Offset, _Length, _pBuffer); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	while (fileIter != m_virtualDisk.end() && _Length > 0) | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		_dbg_assert_(DVDINTERFACE, fileIter->first <= _Offset); | 
					
						
							|  |  |  | 		u64 fileOffset = _Offset - fileIter->first; | 
					
						
							| 
									
										
										
										
											2014-12-27 20:13:31 +01:00
										 |  |  | 		const std::string fileName = fileIter->second; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-27 20:13:31 +01:00
										 |  |  | 		std::unique_ptr<PlainFileReader> reader(PlainFileReader::Create(fileName)); | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (reader == nullptr) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		u64 fileSize = reader->GetDataSize(); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-27 20:13:31 +01:00
										 |  |  | 		FileMon::CheckFile(fileName, fileSize); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (fileOffset < fileSize) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			u64 fileBytes = fileSize - fileOffset; | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 			if (_Length < fileBytes) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 				fileBytes = _Length; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 			if (!reader->Read(fileOffset, fileBytes, _pBuffer)) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-28 17:24:02 -05:00
										 |  |  | 			_Length  -= fileBytes; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 			_pBuffer += fileBytes; | 
					
						
							| 
									
										
										
										
											2015-02-28 17:24:02 -05:00
										 |  |  | 			_Offset  += fileBytes; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		++fileIter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (fileIter != m_virtualDisk.end()) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			_dbg_assert_(DVDINTERFACE, fileIter->first >= _Offset); | 
					
						
							|  |  |  | 			PadToAddress(fileIter->first, _Offset, _Length, _pBuffer); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string CVolumeDirectory::GetUniqueID() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-09 18:57:45 -04:00
										 |  |  | 	static const size_t ID_LENGTH = 6; | 
					
						
							|  |  |  | 	return std::string(m_diskHeader.begin(), m_diskHeader.begin() + ID_LENGTH); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 13:52:36 -04:00
										 |  |  | void CVolumeDirectory::SetUniqueID(const std::string& id) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-09 19:01:20 -04:00
										 |  |  | 	size_t length = id.length(); | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (length > 6) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		length = 6; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-09 19:01:20 -04:00
										 |  |  | 	memcpy(m_diskHeader.data(), id.c_str(), length); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | IVolume::ECountry CVolumeDirectory::GetCountry() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-23 20:43:29 -05:00
										 |  |  | 	u8 country_code = m_diskHeader[3]; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 20:43:29 -05:00
										 |  |  | 	return CountrySwitch(country_code); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string CVolumeDirectory::GetMakerID() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "VOID"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 11:19:30 +02:00
										 |  |  | std::string CVolumeDirectory::GetInternalName() const | 
					
						
							| 
									
										
										
										
											2015-04-10 22:10:49 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	char name[0x60]; | 
					
						
							|  |  |  | 	if (Read(0x20, 0x60, (u8*)name, false)) | 
					
						
							|  |  |  | 		return DecodeString(name); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return ""; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 17:44:53 +02:00
										 |  |  | std::map<IVolume::ELanguage, std::string> CVolumeDirectory::GetNames() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-04-09 17:44:53 +02:00
										 |  |  | 	std::map<IVolume::ELanguage, std::string> names; | 
					
						
							| 
									
										
										
										
											2015-05-11 11:19:30 +02:00
										 |  |  | 	std::string name = GetInternalName(); | 
					
						
							| 
									
										
										
										
											2015-04-10 22:10:49 +02:00
										 |  |  | 	if (!name.empty()) | 
					
						
							|  |  |  | 		names[IVolume::ELanguage::LANGUAGE_UNKNOWN] = name; | 
					
						
							| 
									
										
										
										
											2015-04-09 17:44:53 +02:00
										 |  |  | 	return names; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 13:52:36 -04:00
										 |  |  | void CVolumeDirectory::SetName(const std::string& name) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-09-09 19:01:20 -04:00
										 |  |  | 	size_t length = name.length(); | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (length > MAX_NAME_LENGTH) | 
					
						
							|  |  |  | 	    length = MAX_NAME_LENGTH; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-09 19:01:20 -04:00
										 |  |  | 	memcpy(&m_diskHeader[0x20], name.c_str(), length); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_diskHeader[length + 0x20] = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 CVolumeDirectory::GetFSTSize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string CVolumeDirectory::GetApploaderDate() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return "VOID"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 13:21:02 +01:00
										 |  |  | bool CVolumeDirectory::IsWiiDisc() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return m_is_wii; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | u64 CVolumeDirectory::GetSize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-09 12:58:56 -05:00
										 |  |  | u64 CVolumeDirectory::GetRawSize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return GetSize(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | std::string CVolumeDirectory::ExtractDirectoryName(const std::string& _rDirectory) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::string directoryName = _rDirectory; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-03 22:34:51 +00:00
										 |  |  | 	size_t lastSep = directoryName.find_last_of(DIR_SEP_CHR); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (lastSep != directoryName.size() - 1) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// TODO: This assumes that file names will always have a dot in them
 | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 		//       and directory names never will; both assumptions are often
 | 
					
						
							|  |  |  | 		//       right but in general wrong.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		size_t extensionStart = directoryName.find_last_of('.'); | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (extensionStart != std::string::npos && extensionStart > lastSep) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			directoryName.resize(lastSep); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		directoryName.resize(lastSep); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return directoryName; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::SetDiskTypeWii() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_diskHeader[0x18] = 0x5d; | 
					
						
							|  |  |  | 	m_diskHeader[0x19] = 0x1c; | 
					
						
							|  |  |  | 	m_diskHeader[0x1a] = 0x9e; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	m_diskHeader[0x1b] = 0xa3; | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	memset(&m_diskHeader[0x1c], 0, 4); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 13:21:02 +01:00
										 |  |  | 	m_is_wii = true; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_addressShift = 2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::SetDiskTypeGC() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	memset(&m_diskHeader[0x18], 0, 4); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_diskHeader[0x1c] = 0xc2; | 
					
						
							|  |  |  | 	m_diskHeader[0x1d] = 0x33; | 
					
						
							|  |  |  | 	m_diskHeader[0x1e] = 0x9f; | 
					
						
							|  |  |  | 	m_diskHeader[0x1f] = 0x3d; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-17 13:21:02 +01:00
										 |  |  | 	m_is_wii = false; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_addressShift = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | bool CVolumeDirectory::SetApploader(const std::string& _rApploader) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!_rApploader.empty()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		std::string data; | 
					
						
							| 
									
										
										
										
											2014-09-09 19:01:20 -04:00
										 |  |  | 		if (!File::ReadFileToString(_rApploader, data)) | 
					
						
							| 
									
										
										
										
											2009-12-14 05:27:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-01-13 02:05:58 +00:00
										 |  |  | 			PanicAlertT("Apploader unable to load from file"); | 
					
						
							| 
									
										
										
										
											2009-12-14 05:27:29 +00:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		size_t apploaderSize = 0x20 + Common::swap32(*(u32*)&data.data()[0x14]) + Common::swap32(*(u32*)&data.data()[0x18]); | 
					
						
							|  |  |  | 		if (apploaderSize != data.size()) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-01-13 02:05:58 +00:00
										 |  |  | 			PanicAlertT("Apploader is the wrong size...is it really an apploader?"); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		m_apploader.resize(apploaderSize); | 
					
						
							|  |  |  | 		std::copy(data.begin(), data.end(), m_apploader.begin()); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// 32byte aligned (plus 0x20 padding)
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		m_dol_address = ROUND_UP(APPLOADER_ADDRESS + m_apploader.size() + 0x20, 0x20ull); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		m_apploader.resize(0x20); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 		// Make sure BS2 HLE doesn't try to run the apploader
 | 
					
						
							|  |  |  | 		*(u32*)&m_apploader[0x10] = (u32)-1; | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | void CVolumeDirectory::SetDOL(const std::string& rDOL) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	if (!rDOL.empty()) | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		std::string data; | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 		File::ReadFileToString(rDOL, data); | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 		m_DOL.resize(data.size()); | 
					
						
							|  |  |  | 		std::copy(data.begin(), data.end(), m_DOL.begin()); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		Write32((u32)(m_dol_address >> m_addressShift), 0x0420, &m_diskHeader); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// 32byte aligned (plus 0x20 padding)
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		m_fst_address = ROUND_UP(m_dol_address + m_DOL.size() + 0x20, 0x20ull); | 
					
						
							| 
									
										
										
										
											2009-12-10 09:16:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | void CVolumeDirectory::BuildFST() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	m_FSTData.clear(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	File::FSTEntry rootEntry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// read data from physical disk to rootEntry
 | 
					
						
							|  |  |  | 	u32 totalEntries = AddDirectoryEntries(m_rootDirectory, rootEntry) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 	m_fstNameOffset = totalEntries * ENTRY_SIZE; // offset in FST nameTable
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	m_FSTData.resize(m_fstNameOffset + m_totalNameSize); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-23 00:38:58 -07:00
										 |  |  | 	// if FST hasn't been assigned (ie no apploader/dol setup), set to default
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	if (m_fst_address == 0) | 
					
						
							|  |  |  | 		m_fst_address = APPLOADER_ADDRESS + 0x2000; | 
					
						
							| 
									
										
										
										
											2012-04-23 00:38:58 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	// 4 byte aligned start of data on disk
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_dataStartAddress = ROUND_UP(m_fst_address + m_FSTData.size(), 0x8000ull); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	u64 curDataAddress = m_dataStartAddress; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 	u32 fstOffset = 0;  // Offset within FST data
 | 
					
						
							|  |  |  | 	u32 nameOffset = 0; // Offset within name table
 | 
					
						
							|  |  |  | 	u32 rootOffset = 0; // Offset of root of FST
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// write root entry
 | 
					
						
							|  |  |  | 	WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	for (auto& entry : rootEntry.children) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 		WriteEntry(entry, fstOffset, nameOffset, curDataAddress, rootOffset); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// overflow check
 | 
					
						
							| 
									
										
										
										
											2009-01-11 22:25:57 +00:00
										 |  |  | 	_dbg_assert_(DVDINTERFACE, nameOffset == m_totalNameSize); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// write FST size and location
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	Write32((u32)(m_fst_address >> m_addressShift), 0x0424, &m_diskHeader); | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	Write32((u32)(m_FSTData.size() >> m_addressShift), 0x0428, &m_diskHeader); | 
					
						
							|  |  |  | 	Write32((u32)(m_FSTData.size() >> m_addressShift), 0x042c, &m_diskHeader); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | void CVolumeDirectory::WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, const u8* _Src, | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 									 u64& _Address, u64& _Length, u8*& _pBuffer) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_Length == 0) | 
					
						
							| 
									
										
										
										
											2009-01-11 22:25:57 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	_dbg_assert_(DVDINTERFACE, _Address >= _SrcStartAddress); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u64 srcOffset = _Address - _SrcStartAddress; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (srcOffset < _SrcLength) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		u64 srcBytes = _SrcLength - srcOffset; | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		if (_Length < srcBytes) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 			srcBytes = _Length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(_pBuffer, _Src + srcOffset, (size_t)srcBytes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_Length -= srcBytes; | 
					
						
							|  |  |  | 		_pBuffer += srcBytes; | 
					
						
							|  |  |  | 		_Address += srcBytes; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_StartAddress <= _Address) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u64 padBytes = _StartAddress - _Address; | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (padBytes > _Length) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		padBytes = _Length; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (_Length > 0) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		memset(_pBuffer, 0, (size_t)padBytes); | 
					
						
							|  |  |  | 		_Length -= padBytes; | 
					
						
							|  |  |  | 		_pBuffer += padBytes; | 
					
						
							|  |  |  | 		_Address += padBytes; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | void CVolumeDirectory::Write32(u32 data, u32 offset, std::vector<u8>* const buffer) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	(*buffer)[offset++] = (data >> 24); | 
					
						
							|  |  |  | 	(*buffer)[offset++] = (data >> 16) & 0xff; | 
					
						
							|  |  |  | 	(*buffer)[offset++] = (data >> 8) & 0xff; | 
					
						
							|  |  |  | 	(*buffer)[offset] = (data) & 0xff; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_FSTData[entryOffset++] = type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_FSTData[entryOffset++] = (nameOffset >> 16) & 0xff; | 
					
						
							|  |  |  | 	m_FSTData[entryOffset++] = (nameOffset >> 8) & 0xff; | 
					
						
							|  |  |  | 	m_FSTData[entryOffset++] = (nameOffset) & 0xff; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	Write32((u32)(dataOffset >> m_addressShift), entryOffset, &m_FSTData); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	entryOffset += 4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	Write32((u32)length, entryOffset, &m_FSTData); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	entryOffset += 4; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-25 23:40:05 -04:00
										 |  |  | 	strncpy((char*)&m_FSTData[nameOffset + m_fstNameOffset], name.c_str(), name.length() + 1); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 00:45:46 +00:00
										 |  |  | 	nameOffset += (u32)(name.length() + 1); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum) | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 	if (entry.isDirectory) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		u32 myOffset = fstOffset; | 
					
						
							| 
									
										
										
										
											2013-04-16 23:14:36 -04:00
										 |  |  | 		u32 myEntryNum = myOffset / ENTRY_SIZE; | 
					
						
							| 
									
										
										
										
											2009-02-28 01:26:56 +00:00
										 |  |  | 		WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum, (u32)(myEntryNum + entry.size + 1)); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		WriteEntryName(nameOffset, entry.virtualName); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 00:30:55 +13:00
										 |  |  | 		for (const auto& child : entry.children) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:09:01 -04:00
										 |  |  | 			WriteEntry(child, fstOffset, nameOffset, dataOffset, myEntryNum); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// put entry in FST
 | 
					
						
							| 
									
										
										
										
											2009-02-28 01:26:56 +00:00
										 |  |  | 		WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, (u32)entry.size); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		WriteEntryName(nameOffset, entry.virtualName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// write entry to virtual disk
 | 
					
						
							|  |  |  | 		_dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end()); | 
					
						
							|  |  |  | 		m_virtualDisk.insert(make_pair(dataOffset, entry.physicalName)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// 4 byte aligned
 | 
					
						
							| 
									
										
										
										
											2012-04-23 00:38:58 -07:00
										 |  |  | 		dataOffset = ROUND_UP(dataOffset + entry.size, 0x8000ull); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static u32 ComputeNameSize(const File::FSTEntry& parentEntry) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 nameSize = 0; | 
					
						
							|  |  |  | 	const std::vector<File::FSTEntry>& children = parentEntry.children; | 
					
						
							| 
									
										
										
										
											2013-10-18 03:32:56 -04:00
										 |  |  | 	for (auto it = children.cbegin(); it != children.cend(); ++it) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		const File::FSTEntry& entry = *it; | 
					
						
							|  |  |  | 		if (entry.isDirectory) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			nameSize += ComputeNameSize(entry); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-01-24 00:45:46 +00:00
										 |  |  | 		nameSize += (u32)entry.virtualName.length() + 1; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nameSize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 CVolumeDirectory::AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-01 03:06:14 +00:00
										 |  |  | 	u32 foundEntries = ScanDirectoryTree(_Directory, parentEntry); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_totalNameSize += ComputeNameSize(parentEntry); | 
					
						
							|  |  |  | 	return foundEntries; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace
 |