diff options
Diffstat (limited to 'Source/Core/DiscIO')
30 files changed, 409 insertions, 624 deletions
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj index 6dd24ddd44..722aae2040 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj +++ b/Source/Core/DiscIO/DiscIO.vcxproj @@ -44,7 +44,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>MultiByte</CharacterSet> + <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> @@ -54,7 +54,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <UseDebugLibraries>false</UseDebugLibraries> <ConfigurationType>StaticLibrary</ConfigurationType> - <CharacterSet>MultiByte</CharacterSet> + <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index 6451c73670..d38c7e9ea4 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -22,180 +22,8 @@ #include "VolumeCreator.h" #include "FileUtil.h" -// HyperIris: dunno if this suitable, may be need move. -#ifdef _WIN32 -#include <Windows.h> -#else -#include <sys/param.h> -#include <iconv.h> -#include <errno.h> -#endif - -#ifndef ICONV_CONST -#if defined __FreeBSD__ || __NetBSD__ -#define ICONV_CONST const -#else -#define ICONV_CONST -#endif -#endif - namespace DiscIO { -void IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src) -{ - static bool bValidChars[256]; - static bool bInitialized = false; - - if (!bInitialized) - { - for (int i = 0; i < 0x20; i++) - { - bValidChars[i] = false; - } - - // generate valid chars - for (int i = 0x20; i < 256; i++) - { - bValidChars[i] = true; - } - - bValidChars[0x0a] = true; - //bValidChars[0xa9] = true; - //bValidChars[0xe9] = true; - - bInitialized = true; - } - - char destBuffer[2048] = {0}; - char* dest = destBuffer; - const char* src = _src; - - // copy the string and check for "unknown" characters - while (*src != 0x00) - { - u8 c = *src; - - if (c == 0x0a){c = 0x20;} - - if (bValidChars[c] == false) - { - src++; - continue; - } - - *dest = c; - dest++; - src++; - } - - // finalize the string - *dest = 0x00; - - _rDestination = destBuffer; -} - -bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16* _src, int length ) -{ - bool returnCode = false; -#ifdef WIN32 - if (_src) - { - u16* buffer = new u16[length]; - if (buffer) - { - memcpy(buffer, _src, sizeof(u16)*length); - for (int i = 0; i < length; i++) - { - buffer[i] = swap16(buffer[i]); - } - - u32 ansiNameSize = WideCharToMultiByte(932, 0, - (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer), - NULL, NULL, NULL, NULL); - if (ansiNameSize > 0) - { - char* pAnsiStrBuffer = new char[ansiNameSize + 1]; - if (pAnsiStrBuffer) - { - memset(pAnsiStrBuffer, 0, (ansiNameSize + 1) * sizeof(char)); - if (WideCharToMultiByte(932, 0, - (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer), - pAnsiStrBuffer, ansiNameSize, NULL, NULL)) - { - _rDestination = pAnsiStrBuffer; - returnCode = true; - } - delete[] pAnsiStrBuffer; - } - } - delete[] buffer; - } - } -#else - if (_src) - { - iconv_t conv_desc = iconv_open("UTF-8", "CP932"); - if (conv_desc == (iconv_t) -1) - { - // Initialization failure. - if (errno == EINVAL) - { - ERROR_LOG(DISCIO, "Conversion from CP932 to UTF-8 is not supported."); - } - else - { - ERROR_LOG(DISCIO, "Iconv initialization failure: %s\n", strerror (errno)); - } - return false; - } - - char* src_buffer = new char[length]; - for (int i = 0; i < length; i++) - src_buffer[i] = swap16(_src[i]); - - size_t inbytes = sizeof(char) * length; - size_t outbytes = 2 * inbytes; - char* utf8_buffer = new char[outbytes + 1]; - memset(utf8_buffer, 0, (outbytes + 1) * sizeof(char)); - - // Save the buffer locations because iconv increments them - char* utf8_buffer_start = utf8_buffer; - char* src_buffer_start = src_buffer; - - size_t iconv_size = iconv(conv_desc, - (ICONV_CONST char**)&src_buffer, &inbytes, - &utf8_buffer, &outbytes); - - // Handle failures - if (iconv_size == (size_t) -1) - { - ERROR_LOG(DISCIO, "iconv failed."); - switch (errno) { - case EILSEQ: - ERROR_LOG(DISCIO, "Invalid multibyte sequence."); - break; - case EINVAL: - ERROR_LOG(DISCIO, "Incomplete multibyte sequence."); - break; - case E2BIG: - ERROR_LOG(DISCIO, "Insufficient space allocated for output buffer."); - break; - default: - ERROR_LOG(DISCIO, "Error: %s.", strerror(errno)); - } - } - else - { - _rDestination = utf8_buffer_start; - returnCode = true; - } - delete[] utf8_buffer_start; - delete[] src_buffer_start; - iconv_close(conv_desc); - } -#endif - return returnCode; -} IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume) { @@ -203,9 +31,9 @@ IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVo { return new CBannerLoaderWii(pVolume); } - if (_rFileSystem.IsValid()) + if (_rFileSystem.IsValid()) { - return new CBannerLoaderGC(_rFileSystem); + return new CBannerLoaderGC(_rFileSystem, pVolume); } return NULL; diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h index 1fe48dd364..b30ee17a46 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.h +++ b/Source/Core/DiscIO/Src/BannerLoader.h @@ -18,6 +18,9 @@ #ifndef _BANNER_LOADER_H_ #define _BANNER_LOADER_H_ +#include <vector> +#include <string> + #include "Filesystem.h" namespace DiscIO @@ -38,24 +41,9 @@ class IBannerLoader virtual bool GetBanner(u32* _pBannerImage) = 0; - virtual bool GetName(std::string* _rName) = 0; - virtual bool GetName(std::vector<std::wstring>& _rNames) {return false;}; - virtual bool GetCompany(std::string& _rCompany) = 0; - - virtual bool GetDescription(std::string* _rDescription) = 0; - virtual bool GetDescription(std::wstring& _rDescription) {return false;}; - - - protected: - - void CopyToStringAndCheck(std::string& _rDestination, const char* _src); - - bool CopyBeUnicodeToString(std::string& _rDestination, const u16* _src, int length); - private: - u16 swap16(u16 data) - { - return ((data & 0xff00) >> 8) | ((data & 0xff) << 8); - } + virtual std::vector<std::string> GetNames() = 0; + virtual std::string GetCompany() = 0; + virtual std::vector<std::string> GetDescriptions() = 0; }; IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume); diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp index bf9f634ff8..d8ae259b16 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp @@ -23,13 +23,14 @@ namespace DiscIO { -CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem) - : m_pBannerFile(NULL), - m_IsValid(false) +CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume) + : m_pBannerFile(NULL) + , m_IsValid(false) + , m_country(volume->GetCountry()) { // load the opening.bnr size_t FileSize = (size_t) _rFileSystem.GetFileSize("opening.bnr"); - if (FileSize == sizeof(DVDBanner) || FileSize == sizeof(DVDBanner2)) + if (FileSize == BNR1_SIZE || FileSize == BNR2_SIZE) { m_pBannerFile = new u8[FileSize]; if (m_pBannerFile) @@ -62,7 +63,6 @@ bool CBannerLoaderGC::IsValid() return m_IsValid; } - bool CBannerLoaderGC::GetBanner(u32* _pBannerImage) { if (!IsValid()) @@ -70,132 +70,111 @@ bool CBannerLoaderGC::GetBanner(u32* _pBannerImage) return false; } - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; + auto const pBanner = (DVDBanner*)m_pBannerFile; decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT); return true; } -bool CBannerLoaderGC::GetName(std::string _rName[]) +std::vector<std::string> CBannerLoaderGC::GetNames() { - bool returnCode = false; + std::vector<std::string> names; if (!IsValid()) { - return false; + return names; } + u32 name_count = 0; + // find Banner type switch (m_BNRType) { case CBannerLoaderGC::BANNER_BNR1: - { - DVDBanner* pBanner = (DVDBanner*)m_pBannerFile; - char tempBuffer[65] = {0}; - if (pBanner->comment.longTitle[0]) - { - memcpy(tempBuffer, pBanner->comment.longTitle, 64); - } - else - { - memcpy(tempBuffer, pBanner->comment.shortTitle, 32); - } - for (int i = 0; i < 6; i++) - { - CopyToStringAndCheck(_rName[i], tempBuffer); - } - returnCode = true; - } + name_count = 1; break; + case CBannerLoaderGC::BANNER_BNR2: - { - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; + name_count = 6; + break; - for (int i = 0; i < 6; i++) - { - char tempBuffer[65] = {0}; - if (pBanner->comment[i].longTitle[0]) - { - memcpy(tempBuffer, pBanner->comment[i].longTitle, 64); - } - else - { - memcpy(tempBuffer, pBanner->comment[i].shortTitle, 32); - } - CopyToStringAndCheck(_rName[i], tempBuffer); - } + default: + break; + } - returnCode = true; + auto const banner = reinterpret_cast<const DVDBanner*>(m_pBannerFile); + + for (u32 i = 0; i != name_count; ++i) + { + auto& comment = banner->comment[i]; + if (comment.longTitle[0]) + { + auto& data = comment.longTitle; + names.push_back(GetDecodedString(data)); + } + else + { + auto& data = comment.shortTitle; + names.push_back(GetDecodedString(data)); } - break; - default: - break; } - return returnCode; + return names; } -bool CBannerLoaderGC::GetCompany(std::string& _rCompany) +std::string CBannerLoaderGC::GetCompany() { - _rCompany = "N/A"; + std::string company; - if (!IsValid()) + if (IsValid()) { - return(false); + auto const pBanner = (DVDBanner*)m_pBannerFile; + auto& data = pBanner->comment[0].shortMaker; + company = GetDecodedString(data); } - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; - - CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker); - - return true; + return company; } -bool CBannerLoaderGC::GetDescription(std::string* _rDescription) +std::vector<std::string> CBannerLoaderGC::GetDescriptions() { - bool returnCode = false; + std::vector<std::string> descriptions; if (!IsValid()) { - return false; + return descriptions; } + u32 desc_count = 0; + // find Banner type switch (m_BNRType) { case CBannerLoaderGC::BANNER_BNR1: - { - DVDBanner* pBanner = (DVDBanner*)m_pBannerFile; - char tempBuffer[129] = {0}; - memcpy(tempBuffer, pBanner->comment.comment, 128); - for (int i = 0; i < 6; i++) - { - CopyToStringAndCheck(_rDescription[i], tempBuffer); - } - returnCode = true; - } + desc_count = 1; break; - case CBannerLoaderGC::BANNER_BNR2: - { - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; - for (int i = 0; i< 6; i++) - { - char tempBuffer[129] = {0}; - memcpy(tempBuffer, pBanner->comment[i].comment, 128); - CopyToStringAndCheck(_rDescription[i], tempBuffer); - } - returnCode = true; - } + case CBannerLoaderGC::BANNER_BNR2: + desc_count = 6; break; + default: break; } - return returnCode; + + auto banner = reinterpret_cast<const DVDBanner*>(m_pBannerFile); + + for (u32 i = 0; i != desc_count; ++i) + { + auto& data = banner->comment[i].comment; + descriptions.push_back(GetDecodedString(data)); + } + + return descriptions; } @@ -223,13 +202,17 @@ CBannerLoaderGC::BANNER_TYPE CBannerLoaderGC::getBannerType() CBannerLoaderGC::BANNER_TYPE type = CBannerLoaderGC::BANNER_UNKNOWN; switch (bannerSignature) { + // "BNR1" case 0x31524e42: type = CBannerLoaderGC::BANNER_BNR1; break; + + // "BNR2" case 0x32524e42: type = CBannerLoaderGC::BANNER_BNR2; break; } return type; } + } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h index 0527c721c1..8b14a45d43 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.h +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h @@ -19,6 +19,8 @@ #define _BANNER_LOADER_GC_H_ #include "BannerLoader.h" +#include "VolumeGC.h" +#include "StringUtil.h" namespace DiscIO { @@ -26,15 +28,16 @@ class CBannerLoaderGC : public IBannerLoader { public: - CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem); + CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume); virtual ~CBannerLoaderGC(); virtual bool IsValid(); virtual bool GetBanner(u32* _pBannerImage); - virtual bool GetName(std::string* _rName); - virtual bool GetCompany(std::string& _rCompany); - virtual bool GetDescription(std::string* _rDescription); + + virtual std::vector<std::string> GetNames(); + virtual std::string GetCompany(); + virtual std::vector<std::string> GetDescriptions(); private: enum @@ -60,23 +63,26 @@ class CBannerLoaderGC char comment[128]; // Game description shown in IPL game start screen in two lines. }; - // "opening.bnr" file format for JP/US console + // "opening.bnr" file format for EU console struct DVDBanner { - u32 id; // 'BNR1' + u32 id; // 'BNR2' u32 padding[7]; u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image - DVDBannerComment comment; + DVDBannerComment comment[6]; // Comments in six languages (only 1 for BNR1 type) }; - // "opening.bnr" file format for EU console - struct DVDBanner2 + static const u32 BNR1_SIZE = sizeof(DVDBanner) - sizeof(DVDBannerComment) * 5; + static const u32 BNR2_SIZE = sizeof(DVDBanner); + + template <u32 N> + std::string GetDecodedString(const char (&data)[N]) { - u32 id; // 'BNR2' - u32 padding[7]; - u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image - DVDBannerComment comment[6]; // Comments in six languages - }; + auto const string_decoder = CVolumeGC::GetStringDecoder(m_country); + + // strnlen to trim NULLs + return string_decoder(std::string(data, strnlen(data, sizeof(data)))); + } u8* m_pBannerFile; bool m_IsValid; @@ -84,6 +90,8 @@ class CBannerLoaderGC void decode5A3image(u32* dst, u16* src, int width, int height); BANNER_TYPE getBannerType(); + + DiscIO::IVolume::ECountry const m_country; }; } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp index b23dc4d91a..f606ed8876 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include <stdio.h> +#include <algorithm> #include "Common.h" #include "ColorUtil.h" @@ -144,73 +145,48 @@ bool CBannerLoaderWii::GetBanner(u32* _pBannerImage) return true; } -bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& s) -{ - bool ret = false; - - if (IsValid()) - { - // find Banner type - SWiiBanner *pBanner = (SWiiBanner*)m_pBannerFile; - - // Ensure the string is null-terminating, since the banner format - // doesn't require it - u16 *src = new u16[COMMENT_SIZE + 1]; - memcpy(src, &pBanner->m_Comment[index], COMMENT_SIZE * sizeof(u16)); - src[COMMENT_SIZE] = 0; - - ret = CopyBeUnicodeToString(s, src, COMMENT_SIZE + 1); - - delete [] src; - } - - return ret; -} - -bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::wstring& s) +bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result) { if (IsValid()) { - // find Banner type - SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile; - - std::wstring description; - for (int i = 0; i < COMMENT_SIZE; ++i) - description.push_back(Common::swap16(pBanner->m_Comment[index][i])); - - s = description; + auto const banner = reinterpret_cast<const SWiiBanner*>(m_pBannerFile); + auto const src_ptr = banner->m_Comment[index]; + + // Trim at first NULL + auto const length = std::find(src_ptr, src_ptr + COMMENT_SIZE, 0x0) - src_ptr; + + std::wstring src; + src.resize(length); + std::transform(src_ptr, src_ptr + src.size(), src.begin(), (u16(&)(u16))Common::swap16); + result = UTF16ToUTF8(src); + return true; } + return false; } -bool CBannerLoaderWii::GetName(std::string* _rName) +std::vector<std::string> CBannerLoaderWii::GetNames() { - return GetStringFromComments(NAME_IDX, *_rName); -} + std::vector<std::string> ret(1); + + if (!GetStringFromComments(NAME_IDX, ret[0])) + ret.clear(); -bool CBannerLoaderWii::GetName(std::vector<std::wstring>& _rNames) -{ - std::wstring temp; - bool ret = GetStringFromComments(NAME_IDX, temp); - _rNames.push_back(temp); return ret; } -bool CBannerLoaderWii::GetCompany(std::string& _rCompany) -{ - _rCompany = "N/A"; - return true; -} - -bool CBannerLoaderWii::GetDescription(std::string* _rDescription) +std::string CBannerLoaderWii::GetCompany() { - return GetStringFromComments(DESC_IDX, *_rDescription); + return ""; } -bool CBannerLoaderWii::GetDescription(std::wstring& _rDescription) +std::vector<std::string> CBannerLoaderWii::GetDescriptions() { - return GetStringFromComments(DESC_IDX, _rDescription); + std::vector<std::string> result(1); + if (!GetStringFromComments(DESC_IDX, result[0])) + result.clear(); + return result; } void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height) diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h index 83733cf5ed..036eeeacbd 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.h +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h @@ -35,15 +35,9 @@ class CBannerLoaderWii virtual bool GetBanner(u32* _pBannerImage); - virtual bool GetName(std::string* _rName); - - bool GetName(std::vector<std::wstring>& _rNames); - - virtual bool GetCompany(std::string& _rCompany); - - virtual bool GetDescription(std::string* _rDescription); - - bool GetDescription(std::wstring& _rDescription); + virtual std::vector<std::string> GetNames(); + virtual std::string GetCompany(); + virtual std::vector<std::string> GetDescriptions(); private: @@ -81,7 +75,6 @@ class CBannerLoaderWii void decode5A3image(u32* dst, u16* src, int width, int height); bool GetStringFromComments(const CommentIndex index, std::string& s); - bool GetStringFromComments(const CommentIndex index, std::wstring& s); }; } // namespace diff --git a/Source/Core/DiscIO/Src/CISOBlob.cpp b/Source/Core/DiscIO/Src/CISOBlob.cpp index b3a2e31b2b..8d267c15fb 100644 --- a/Source/Core/DiscIO/Src/CISOBlob.cpp +++ b/Source/Core/DiscIO/Src/CISOBlob.cpp @@ -15,24 +15,30 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include <algorithm> +#include <cmath> + #include "Blob.h" #include "CISOBlob.h" namespace DiscIO { +static const char CISO_MAGIC[] = "CISO"; + CISOFileReader::CISOFileReader(std::FILE* file) : m_file(file) { m_size = m_file.GetSize(); - - memset(&header, 0, sizeof(header)); + + CISOHeader header; m_file.ReadArray(&header, 1); + + m_block_size = header.block_size; - CISO_Map_t count = 0; - int idx; - for (idx = 0; idx < CISO_MAP_SIZE; idx++) - ciso_map[idx] = (header.map[idx] == 1) ? count++ : CISO_UNUSED_BLOCK; + MapType count = 0; + for (u32 idx = 0; idx < CISO_MAP_SIZE; idx++) + m_ciso_map[idx] = (1 == header.map[idx]) ? count++ : UNUSED_BLOCK_ID; } CISOFileReader* CISOFileReader::Create(const char* filename) @@ -46,34 +52,45 @@ CISOFileReader* CISOFileReader::Create(const char* filename) return NULL; } +u64 CISOFileReader::GetDataSize() const +{ + return GetRawSize(); +} + +u64 CISOFileReader::GetRawSize() const +{ + return m_size; +} + bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr) { - u64 bytesRead = 0; - while (bytesRead < nbytes) + while (nbytes != 0) { - u32 block = (u32)(offset / header.block_size); - u32 data_offset = offset % header.block_size; - u32 bytes_to_read = (u32)min((u64)(header.block_size - data_offset), nbytes); - if ((block >= CISO_MAP_SIZE) || (ciso_map[block] == CISO_UNUSED_BLOCK)) + auto const block = offset / m_block_size; + auto const data_offset = offset % m_block_size; + + auto const bytes_to_read = std::min(m_block_size - data_offset, nbytes); + if (block < CISO_MAP_SIZE && UNUSED_BLOCK_ID != m_ciso_map[block]) { - memset(out_ptr, 0, bytes_to_read); + // calcualte the base address + auto const file_off = CISO_HEADER_SIZE + m_ciso_map[block] * m_block_size + data_offset; + + if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadArray(out_ptr, bytes_to_read))) + return false; + out_ptr += bytes_to_read; offset += bytes_to_read; - bytesRead += bytes_to_read; + nbytes -= bytes_to_read; } else { - // calcualte the base address - u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset; - - if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadBytes(out_ptr, bytes_to_read))) - return false; - + std::fill_n(out_ptr, bytes_to_read, 0); out_ptr += bytes_to_read; offset += bytes_to_read; - bytesRead += bytes_to_read; + nbytes -= bytes_to_read; } } + return true; } @@ -81,8 +98,9 @@ bool IsCISOBlob(const char* filename) { File::IOFile f(filename, "rb"); - CISO_Head_t header; - return (f.ReadArray(&header, 1) && (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0)); + CISOHeader header; + return (f.ReadArray(&header, 1) && + std::equal(header.magic, header.magic + sizeof(header.magic), CISO_MAGIC)); } } // namespace diff --git a/Source/Core/DiscIO/Src/CISOBlob.h b/Source/Core/DiscIO/Src/CISOBlob.h index e87e616a21..9b490f0638 100644 --- a/Source/Core/DiscIO/Src/CISOBlob.h +++ b/Source/Core/DiscIO/Src/CISOBlob.h @@ -21,43 +21,45 @@ #include "Blob.h" #include "FileUtil.h" -#define CISO_MAGIC "CISO" -#define CISO_HEAD_SIZE (0x8000) -#define CISO_MAP_SIZE (CISO_HEAD_SIZE - 8) - namespace DiscIO { bool IsCISOBlob(const char* filename); -// Blocks that won't compress to less than 97% of the original size are stored as-is. -struct CISO_Head_t +static const u32 CISO_HEADER_SIZE = 0x8000; +static const u32 CISO_MAP_SIZE = CISO_HEADER_SIZE - sizeof(u32) - sizeof(char) * 4; + +struct CISOHeader { - u8 magic[4]; // "CISO" - u32 block_size; // stored as litte endian (not network byte order) - u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid + // "CISO" + char magic[4]; + + // little endian + u32 block_size; + + // 0=unused, 1=used, others=invalid + u8 map[CISO_MAP_SIZE]; }; -typedef u16 CISO_Map_t; - -const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0; - class CISOFileReader : public IBlobReader { - File::IOFile m_file; - CISOFileReader(std::FILE* file); - s64 m_size; - public: static CISOFileReader* Create(const char* filename); - u64 GetDataSize() const { return m_size; } - u64 GetRawSize() const { return m_size; } + u64 GetDataSize() const; + u64 GetRawSize() const; bool Read(u64 offset, u64 nbytes, u8* out_ptr); private: - CISO_Head_t header; - CISO_Map_t ciso_map[CISO_MAP_SIZE]; + CISOFileReader(std::FILE* file); + + typedef u16 MapType; + static const MapType UNUSED_BLOCK_ID = -1; + + File::IOFile m_file; + u64 m_size; + u32 m_block_size; + MapType m_ciso_map[CISO_MAP_SIZE]; }; } // namespace diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp index c4b1aa1385..2bc4a93ede 100644 --- a/Source/Core/DiscIO/Src/CompressedBlob.cpp +++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp @@ -301,7 +301,10 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca File::IOFile f(outfile, "wb"); if (!f) + { + delete reader; return false; + } const CompressedBlobHeader &header = reader->GetHeader(); u8* buffer = new u8[header.block_size]; diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp index e69f8ff34c..2638f3fac4 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.cpp +++ b/Source/Core/DiscIO/Src/DriveBlob.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "DriveBlob.h" +#include "StringUtil.h" namespace DiscIO { @@ -23,12 +24,9 @@ namespace DiscIO DriveReader::DriveReader(const char *drive) { #ifdef _WIN32 - char path[MAX_PATH]; - strncpy(path, drive, 3); - path[2] = 0; - sprintf(path, "\\\\.\\%s", drive); SectorReader::SetSectorSize(2048); - hDisc = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + auto const path = UTF8ToTStr(std::string("\\\\.\\") + drive); + hDisc = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); if (hDisc != INVALID_HANDLE_VALUE) { diff --git a/Source/Core/DiscIO/Src/FileHandlerARC.cpp b/Source/Core/DiscIO/Src/FileHandlerARC.cpp index a9e4beee5d..63a4876718 100644 --- a/Source/Core/DiscIO/Src/FileHandlerARC.cpp +++ b/Source/Core/DiscIO/Src/FileHandlerARC.cpp @@ -27,19 +27,19 @@ namespace DiscIO { CARCFile::CARCFile(const std::string& _rFilename) - : m_pBuffer(NULL) - , m_Initialized(false) + : m_pBuffer(NULL) + , m_Initialized(false) { - DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str()); - if (pReader != NULL) - { - u64 FileSize = pReader->GetDataSize(); - m_pBuffer = new u8[(u32)FileSize]; - pReader->Read(0, FileSize, m_pBuffer); - delete pReader; - - m_Initialized = ParseBuffer(); - } + DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str()); + if (pReader != NULL) + { + u64 FileSize = pReader->GetDataSize(); + m_pBuffer = new u8[(u32)FileSize]; + pReader->Read(0, FileSize, m_pBuffer); + delete pReader; + + m_Initialized = ParseBuffer(); + } } CARCFile::CARCFile(const std::string& _rFilename, u32 offset) diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index 47651e2f23..93b569e043 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -20,6 +20,7 @@ #include <string> #include <vector> +#include <algorithm> #include "FileSystemGCWii.h" #include "StringUtil.h" @@ -27,10 +28,10 @@ namespace DiscIO { CFileSystemGCWii::CFileSystemGCWii(const IVolume *_rVolume) - : IFileSystem(_rVolume), - m_Initialized(false), - m_Valid(false), - m_OffsetShift(0) + : IFileSystem(_rVolume) + , m_Initialized(false) + , m_Valid(false) + , m_OffsetShift(0) { m_Valid = DetectFileSystem(); } @@ -213,9 +214,16 @@ u32 CFileSystemGCWii::Read32(u64 _Offset) const return Common::swap32(Temp); } -void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const +std::string CFileSystemGCWii::GetStringFromOffset(u64 _Offset) const { - m_rVolume->Read(_Offset, 255, (u8*)Filename); + std::string data; + data.resize(255); + m_rVolume->Read(_Offset, data.size(), (u8*)&data[0]); + data.erase(std::find(data.begin(), data.end(), 0x00), data.end()); + + // TODO: Should we really always use SHIFT-JIS? + // It makes some filenames in Pikmin (NTSC-U) sane, but is it correct? + return SHIFTJISToUTF8(data); } size_t CFileSystemGCWii::GetFileList(std::vector<const SFileInfo *> &_rFilenames) @@ -311,18 +319,16 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _ { SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex]; u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF); - char filename[512]; - memset(filename, 0, sizeof(filename)); - GetStringFromOffset(uOffset, filename); + std::string filename = GetStringFromOffset(uOffset); // check next index if (rFileInfo->IsDirectory()) { // this is a directory, build up the new szDirectory if (_szDirectory != NULL) - CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename.c_str()); else - CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename.c_str()); CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset); } @@ -330,9 +336,9 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _ { // this is a filename if (_szDirectory != NULL) - CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename.c_str()); else - CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename.c_str()); CurrentIndex++; } diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.h b/Source/Core/DiscIO/Src/FileSystemGCWii.h index 0e7d836d75..9054ade272 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.h +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.h @@ -28,7 +28,7 @@ namespace DiscIO class CFileSystemGCWii : public IFileSystem { public: - CFileSystemGCWii(const IVolume *_rVolume); + CFileSystemGCWii(const IVolume* _rVolume); virtual ~CFileSystemGCWii(); virtual bool IsValid() const { return m_Valid; } virtual u64 GetFileSize(const char* _rFullPath); @@ -44,11 +44,11 @@ public: private: bool m_Initialized; bool m_Valid; - u32 m_OffsetShift; // WII offsets are all shifted + std::vector <SFileInfo> m_FileInfoVector; u32 Read32(u64 _Offset) const; - void GetStringFromOffset(u64 _Offset, char* Filename) const; + std::string GetStringFromOffset(u64 _Offset) const; const SFileInfo* FindFileInfo(const char* _rFullPath); bool DetectFileSystem(); void InitFileSystem(); diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index 3c00d66be5..110efd6fa9 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -273,7 +273,7 @@ bool CNANDContentLoader::Initialize(const std::string& _rName) continue; } - rContent.m_pData = NULL; + rContent.m_pData = NULL; char szFilename[1024]; if (rContent.m_Type & 0x8000) // shared app diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index 63135df693..f95ae6586c 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -32,14 +32,14 @@ namespace DiscIO bool Add_Ticket(u64 TitleID, const u8 *p_tik, u32 tikSize); struct SNANDContent { - u32 m_ContentID; - u16 m_Index; - u16 m_Type; - u32 m_Size; - u8 m_SHA1Hash[20]; - u8 m_Header[36]; //all of the above - - u8* m_pData; + u32 m_ContentID; + u16 m_Index; + u16 m_Type; + u32 m_Size; + u8 m_SHA1Hash[20]; + u8 m_Header[36]; //all of the above + + u8* m_pData; }; // pure virtual interface so just the NANDContentManager can create these files only @@ -47,34 +47,34 @@ class INANDContentLoader { public: - INANDContentLoader() {} + INANDContentLoader() {} - virtual ~INANDContentLoader() {} + virtual ~INANDContentLoader() {} - virtual bool IsValid() const = 0; + virtual bool IsValid() const = 0; virtual void RemoveTitle() const = 0; - virtual u64 GetTitleID() const = 0; - virtual u16 GetIosVersion() const = 0; - virtual u32 GetBootIndex() const = 0; - virtual size_t GetContentSize() const = 0; - virtual const SNANDContent* GetContentByIndex(int _Index) const = 0; + virtual u64 GetTitleID() const = 0; + virtual u16 GetIosVersion() const = 0; + virtual u32 GetBootIndex() const = 0; + virtual size_t GetContentSize() const = 0; + virtual const SNANDContent* GetContentByIndex(int _Index) const = 0; virtual const u8* GetTMDView() const = 0; virtual const u8* GetTMDHeader() const = 0; virtual u32 GetTIKSize() const = 0; virtual const u8* GetTIK() const = 0; - virtual const std::vector<SNANDContent>& GetContent() const = 0; - virtual u16 GetTitleVersion() const = 0; - virtual u16 GetNumEntries() const = 0; - virtual DiscIO::IVolume::ECountry GetCountry() const = 0; + virtual const std::vector<SNANDContent>& GetContent() const = 0; + virtual u16 GetTitleVersion() const = 0; + virtual u16 GetNumEntries() const = 0; + virtual DiscIO::IVolume::ECountry GetCountry() const = 0; virtual u8 GetCountryChar() const = 0; - enum - { - TMD_VIEW_SIZE = 0x58, - TMD_HEADER_SIZE = 0x1e4, + enum + { + TMD_VIEW_SIZE = 0x58, + TMD_HEADER_SIZE = 0x1e4, CONTENT_HEADER_SIZE = 0x24, TICKET_SIZE = 0x2A4 - }; + }; }; @@ -83,22 +83,22 @@ class CNANDContentManager { public: - static CNANDContentManager& Access() { return m_Instance; } + static CNANDContentManager& Access() { return m_Instance; } u64 Install_WiiWAD(std::string &fileName); - const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false); + const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false); const INANDContentLoader& GetNANDLoader(u64 _titleId, bool forceReload = false); bool RemoveTitle(u64 _titleID); private: - CNANDContentManager() {}; + CNANDContentManager() {}; - ~CNANDContentManager(); + ~CNANDContentManager(); - static CNANDContentManager m_Instance; + static CNANDContentManager m_Instance; - typedef std::map<std::string, INANDContentLoader*> CNANDContentMap; - CNANDContentMap m_Map; + typedef std::map<std::string, INANDContentLoader*> CNANDContentMap; + CNANDContentMap m_Map; }; diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h index 557c71c31f..c19aaf93a8 100644 --- a/Source/Core/DiscIO/Src/Volume.h +++ b/Source/Core/DiscIO/Src/Volume.h @@ -22,6 +22,7 @@ #include <vector> #include "Common.h" +#include "StringUtil.h" namespace DiscIO { @@ -37,8 +38,9 @@ public: virtual void GetTMD(u8*, u32 *_sz) const { *_sz=0; } virtual std::string GetUniqueID() const = 0; virtual std::string GetMakerID() const = 0; - virtual std::string GetName() const = 0; - virtual bool GetWName(std::vector<std::wstring>& _rwNames) const { return false; } + // TODO: eliminate? + virtual std::string GetName() const; + virtual std::vector<std::string> GetNames() const = 0; virtual u32 GetFSTSize() const = 0; virtual std::string GetApploaderDate() const = 0; virtual bool SupportsIntegrityCheck() const { return false; } diff --git a/Source/Core/DiscIO/Src/VolumeCommon.cpp b/Source/Core/DiscIO/Src/VolumeCommon.cpp index 415af2725a..4ab433680d 100644 --- a/Source/Core/DiscIO/Src/VolumeCommon.cpp +++ b/Source/Core/DiscIO/Src/VolumeCommon.cpp @@ -111,5 +111,13 @@ u8 GetSysMenuRegion(u16 _TitleVersion) } } -}; +std::string IVolume::GetName() const +{ + auto names = GetNames(); + if (names.empty()) + return ""; + else + return names[0]; +} +} diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index dc76e2e641..be7cdeb565 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -207,11 +207,10 @@ std::string CVolumeDirectory::GetMakerID() const return "VOID"; } -std::string CVolumeDirectory::GetName() const +std::vector<std::string> CVolumeDirectory::GetNames() const { _dbg_assert_(DVDINTERFACE, m_diskHeader); - std::string name = (char*)(m_diskHeader + 0x20); - return name; + return std::vector<std::string>(1, (char*)(m_diskHeader + 0x20)); } void CVolumeDirectory::SetName(std::string _Name) diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h index 0547be3b8a..4e28d6460f 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.h +++ b/Source/Core/DiscIO/Src/VolumeDirectory.h @@ -50,7 +50,7 @@ public: std::string GetMakerID() const; - std::string GetName() const; + std::vector<std::string> GetNames() const; void SetName(std::string); u32 GetFSTSize() const; @@ -59,7 +59,7 @@ public: ECountry GetCountry() const; - u64 GetSize() const; + u64 GetSize() const; void BuildFST(); diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index 09e2c5eaa9..6210172790 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -91,16 +91,17 @@ std::string CVolumeGC::GetMakerID() const return makerID; } -std::string CVolumeGC::GetName() const +std::vector<std::string> CVolumeGC::GetNames() const { - if (m_pReader == NULL) - return ""; + std::vector<std::string> names; + + auto const string_decoder = GetStringDecoder(GetCountry()); - char name[128]; - if (!Read(0x20, 0x60, (u8*)&name)) - return ""; + char name[0x60 + 1] = {}; + if (m_pReader != NULL && Read(0x20, 0x60, (u8*)name)) + names.push_back(string_decoder(name)); - return name; + return names; } u32 CVolumeGC::GetFSTSize() const @@ -144,4 +145,10 @@ bool CVolumeGC::IsDiscTwo() const return discTwo; } +auto CVolumeGC::GetStringDecoder(ECountry country) -> StringDecoder +{ + return (COUNTRY_JAPAN == country || COUNTRY_TAIWAN == country) ? + SHIFTJISToUTF8 : CP1252ToUTF8; +} + } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h index 4221df9493..d7729ee04c 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.h +++ b/Source/Core/DiscIO/Src/VolumeGC.h @@ -34,12 +34,16 @@ public: bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; + std::vector<std::string> GetNames() const; u32 GetFSTSize() const; std::string GetApploaderDate() const; ECountry GetCountry() const; u64 GetSize() const; bool IsDiscTwo() const; + + typedef std::string(*StringDecoder)(const std::string&); + + static StringDecoder GetStringDecoder(ECountry country); private: IBlobReader* m_pReader; diff --git a/Source/Core/DiscIO/Src/VolumeWad.cpp b/Source/Core/DiscIO/Src/VolumeWad.cpp index 2f9f0ef961..a10e5bdb42 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.cpp +++ b/Source/Core/DiscIO/Src/VolumeWad.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include <algorithm> #include <math.h> #include "VolumeWad.h" @@ -107,78 +108,42 @@ bool CVolumeWAD::GetTitleID(u8* _pBuffer) const return true; } -bool CVolumeWAD::GetWName(std::vector<std::wstring>& _rwNames) const +std::vector<std::string> CVolumeWAD::GetNames() const { - u32 footer_size; + std::vector<std::string> names; + u32 footer_size; if (!Read(0x1C, 4, (u8*)&footer_size)) { - return false; + return names; } + + footer_size = Common::swap32(footer_size); + //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean - - // Offset to the english title - for (int i = 0; i < 10; i++) + for (int i = 0; i != 10; ++i) { - u16 temp[42]; - std::wstring out_temp; + static const u32 string_length = 42; + static const u32 bytes_length = string_length * sizeof(u16); + + u16 temp[string_length]; - if (!Read(0x9C + (i*84) + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 - || !temp[0]) + if (footer_size < 0xF1 || !Read(0x9C + (i * bytes_length) + OpeningBnrOffset, bytes_length, (u8*)&temp)) { - _rwNames.push_back(L""); - continue; + names.push_back(""); } - for (int j = 0; j < 42; ++j) + else { - u16 t = Common::swap16(temp[j]); - if (t == 0 && j > 0) - { - if (out_temp.at(out_temp.size()-1) != ' ') - out_temp.push_back(' '); - } - else - out_temp.push_back(t); - } - - _rwNames.push_back(out_temp); - } - return true; -} - -std::string CVolumeWAD::GetName() const -{ - u32 footer_size; - - if (!Read(0x1C, 4, (u8*)&footer_size)) - return ""; - - - //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean - - // Offset to the english title - char temp[84]; - if (!Read(0xF1 + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 || - !Common::swap16(temp[0])) - return ""; - - // Remove the null bytes due to 16bit char length - std::string out_temp; - for (unsigned int i = 0; i < sizeof(temp); i+=2) - { - // Replace null chars with a single space per null section - if (temp[i] == '\0' && i > 0) - { - if (out_temp.at(out_temp.size()-1) != ' ') - out_temp.push_back(' '); + std::wstring out_temp; + out_temp.resize(string_length); + std::transform(temp, temp + out_temp.size(), out_temp.begin(), (u16(&)(u16))Common::swap16); + out_temp.erase(std::find(out_temp.begin(), out_temp.end(), 0x00), out_temp.end()); + + names.push_back(UTF16ToUTF8(out_temp)); } - else - out_temp.push_back(temp[i]); } - // Make it a null terminated string - out_temp.replace(out_temp.end()-1, out_temp.end(), 1, '\0'); - return out_temp; + return names; } u64 CVolumeWAD::GetSize() const diff --git a/Source/Core/DiscIO/Src/VolumeWad.h b/Source/Core/DiscIO/Src/VolumeWad.h index 956844acd1..afc16766a2 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.h +++ b/Source/Core/DiscIO/Src/VolumeWad.h @@ -38,8 +38,7 @@ public: bool GetTitleID(u8* _pBuffer) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; - bool GetWName(std::vector<std::wstring>& _rwNames) const; + std::vector<std::string> GetNames() const; u32 GetFSTSize() const { return 0; } std::string GetApploaderDate() const { return "0"; } ECountry GetCountry() const; diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp index ca010b5ae4..32aa92bd08 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "VolumeWiiCrypted.h" +#include "VolumeGC.h" #include "StringUtil.h" #include "Crypto/sha1.h" @@ -168,21 +169,17 @@ std::string CVolumeWiiCrypted::GetMakerID() const return makerID; } -std::string CVolumeWiiCrypted::GetName() const +std::vector<std::string> CVolumeWiiCrypted::GetNames() const { - if (m_pReader == NULL) - { - return std::string(); - } - - char name[0xFF]; + std::vector<std::string> names; + + auto const string_decoder = CVolumeGC::GetStringDecoder(GetCountry()); - if (!Read(0x20, 0x60, (u8*)&name)) - { - return std::string(); - } + char name[0xFF] = {}; + if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name)) + names.push_back(string_decoder(name)); - return name; + return names; } u32 CVolumeWiiCrypted::GetFSTSize() const diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h index 5010e46bbd..56c2a8a363 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h @@ -37,7 +37,7 @@ public: void GetTMD(u8* _pBuffer, u32* _sz) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; + std::vector<std::string> GetNames() const; u32 GetFSTSize() const; std::string GetApploaderDate() const; ECountry GetCountry() const; diff --git a/Source/Core/DiscIO/Src/WbfsBlob.cpp b/Source/Core/DiscIO/Src/WbfsBlob.cpp index 1b7696cc58..0fd89243e3 100644 --- a/Source/Core/DiscIO/Src/WbfsBlob.cpp +++ b/Source/Core/DiscIO/Src/WbfsBlob.cpp @@ -75,47 +75,47 @@ bool WbfsFileReader::OpenFiles(const char* filename) delete new_entry; return 0 != m_total_files; } - + new_entry->base_address = m_size; new_entry->size = new_entry->file.GetSize(); m_size += new_entry->size; m_total_files ++; - m_files.push_back(new_entry); + m_files.push_back(new_entry); } } bool WbfsFileReader::ReadHeader() { m_files[0]->file.Seek(4, SEEK_SET); - + // Read hd size info m_files[0]->file.ReadBytes(&hd_sector_count, 4); hd_sector_count = Common::swap32(hd_sector_count); - + m_files[0]->file.ReadBytes(&hd_sector_shift, 1); hd_sector_size = 1 << hd_sector_shift; - + if(m_size != hd_sector_count * hd_sector_size) { //printf("File size doesn't match expected size\n"); return false; } - + // Read wbfs cluster info m_files[0]->file.ReadBytes(&wbfs_sector_shift, 1); wbfs_sector_size = 1 << wbfs_sector_shift; wbfs_sector_count = m_size / wbfs_sector_size; - + if(wbfs_sector_size < wii_sector_size) { //Setting this too low would case a very large memory allocation return false; } - + m_blocks_per_disc = (wii_sector_count * wii_sector_size) / wbfs_sector_size; m_disc_info_size = align(wii_disc_header_size + m_blocks_per_disc * 2, hd_sector_size); - + // Read disc table m_files[0]->file.Seek(2, SEEK_CUR); m_files[0]->file.ReadBytes(disc_table, 500); @@ -125,7 +125,7 @@ bool WbfsFileReader::ReadHeader() //printf("Game must be in 'slot 0'\n"); return false; } - + return true; } @@ -143,7 +143,7 @@ bool WbfsFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr) nbytes -= read_size; offset += read_size; } - + return true; } @@ -172,16 +172,16 @@ File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available) } } } - + PanicAlert("Read beyond end of disc"); m_files[0]->file.Seek(0, SEEK_SET); return m_files[0]->file; } WbfsFileReader* WbfsFileReader::Create(const char* filename) -{ +{ WbfsFileReader* reader = new WbfsFileReader(filename); - + if(reader->IsGood()) { return reader; diff --git a/Source/Core/DiscIO/Src/WbfsBlob.h b/Source/Core/DiscIO/Src/WbfsBlob.h index 300f658ddc..acae008fc2 100644 --- a/Source/Core/DiscIO/Src/WbfsBlob.h +++ b/Source/Core/DiscIO/Src/WbfsBlob.h @@ -63,7 +63,7 @@ class WbfsFileReader : public IBlobReader u16* m_wlba_table; u64 m_blocks_per_disc; - + bool m_good; public: diff --git a/Source/Core/DiscIO/Src/WiiWad.cpp b/Source/Core/DiscIO/Src/WiiWad.cpp index 24e091f9f4..d718436905 100644 --- a/Source/Core/DiscIO/Src/WiiWad.cpp +++ b/Source/Core/DiscIO/Src/WiiWad.cpp @@ -45,10 +45,11 @@ private: WiiWAD::WiiWAD(const std::string& _rName) { - DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str()); - if (pReader == NULL || File::IsDirectory(_rName)) + DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str()); + if (pReader == NULL || File::IsDirectory(_rName)) { m_Valid = false; + if(pReader) delete pReader; return; } @@ -70,87 +71,87 @@ WiiWAD::~WiiWAD() u8* WiiWAD::CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset) { - if (_Size > 0) - { - u8* pTmpBuffer = new u8[_Size]; - _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry"); + if (_Size > 0) + { + u8* pTmpBuffer = new u8[_Size]; + _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry"); - if (!_rReader.Read(_Offset, _Size, pTmpBuffer)) - { + if (!_rReader.Read(_Offset, _Size, pTmpBuffer)) + { ERROR_LOG(DISCIO, "WiiWAD: Could not read from file"); - PanicAlertT("WiiWAD: Could not read from file"); - } - return pTmpBuffer; - } + PanicAlertT("WiiWAD: Could not read from file"); + } + return pTmpBuffer; + } return NULL; } bool WiiWAD::ParseWAD(DiscIO::IBlobReader& _rReader) { - CBlobBigEndianReader ReaderBig(_rReader); + CBlobBigEndianReader ReaderBig(_rReader); - // get header size + // get header size u32 HeaderSize = ReaderBig.Read32(0); - if (HeaderSize != 0x20) - { - _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20"); - return false; - } - - // get header - u8 Header[0x20]; - _rReader.Read(0, HeaderSize, Header); + if (HeaderSize != 0x20) + { + _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20"); + return false; + } + + // get header + u8 Header[0x20]; + _rReader.Read(0, HeaderSize, Header); u32 HeaderType = ReaderBig.Read32(0x4); - if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType)) - return false; - - m_CertificateChainSize = ReaderBig.Read32(0x8); - u32 Reserved = ReaderBig.Read32(0xC); - m_TicketSize = ReaderBig.Read32(0x10); - m_TMDSize = ReaderBig.Read32(0x14); - m_DataAppSize = ReaderBig.Read32(0x18); - m_FooterSize = ReaderBig.Read32(0x1C); + if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType)) + return false; + + m_CertificateChainSize = ReaderBig.Read32(0x8); + u32 Reserved = ReaderBig.Read32(0xC); + m_TicketSize = ReaderBig.Read32(0x10); + m_TMDSize = ReaderBig.Read32(0x14); + m_DataAppSize = ReaderBig.Read32(0x18); + m_FooterSize = ReaderBig.Read32(0x1C); #if MAX_LOGLEVEL >= DEBUG_LEVEL _dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00"); #else (void)Reserved; #endif - u32 Offset = 0x40; - m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40); - m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40); - m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40); - m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40); - m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40); + u32 Offset = 0x40; + m_pCertificateChain = CreateWADEntry(_rReader, m_CertificateChainSize, Offset); Offset += ROUND_UP(m_CertificateChainSize, 0x40); + m_pTicket = CreateWADEntry(_rReader, m_TicketSize, Offset); Offset += ROUND_UP(m_TicketSize, 0x40); + m_pTMD = CreateWADEntry(_rReader, m_TMDSize, Offset); Offset += ROUND_UP(m_TMDSize, 0x40); + m_pDataApp = CreateWADEntry(_rReader, m_DataAppSize, Offset); Offset += ROUND_UP(m_DataAppSize, 0x40); + m_pFooter = CreateWADEntry(_rReader, m_FooterSize, Offset); Offset += ROUND_UP(m_FooterSize, 0x40); return true; } bool WiiWAD::IsWiiWAD(const std::string& _rName) { - DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str()); - if (pReader == NULL) - return false; - - CBlobBigEndianReader Reader(*pReader); - bool Result = false; - - // check for wii wad - if (Reader.Read32(0x00) == 0x20) - { - u32 WADTYpe = Reader.Read32(0x04); - switch(WADTYpe) - { - case 0x49730000: - case 0x69620000: - Result = true; - } - } - - delete pReader; - - return Result; + DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str()); + if (pReader == NULL) + return false; + + CBlobBigEndianReader Reader(*pReader); + bool Result = false; + + // check for wii wad + if (Reader.Read32(0x00) == 0x20) + { + u32 WADTYpe = Reader.Read32(0x04); + switch(WADTYpe) + { + case 0x49730000: + case 0x69620000: + Result = true; + } + } + + delete pReader; + + return Result; } diff --git a/Source/Core/DiscIO/Src/WiiWad.h b/Source/Core/DiscIO/Src/WiiWad.h index 3c219b6627..3b0bad1ed9 100644 --- a/Source/Core/DiscIO/Src/WiiWad.h +++ b/Source/Core/DiscIO/Src/WiiWad.h @@ -33,7 +33,7 @@ class WiiWAD { public: - WiiWAD(const std::string& _rName); + WiiWAD(const std::string& _rName); ~WiiWAD(); @@ -50,7 +50,7 @@ public: u8* GetDataApp() const { return m_pDataApp; } u8* GetFooter() const { return m_pFooter; } - static bool IsWiiWAD(const std::string& _rName); + static bool IsWiiWAD(const std::string& _rName); private: |
