diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp index 2f21caa4cc..b0bac73e8a 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp @@ -120,17 +120,32 @@ bool CBoot::Install_WiiWAD(const char* _pFilename) fwrite(Content.m_Header, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE, 1, pTMDFile); char APPFileName[1024]; - sprintf(APPFileName, "%s%08x.app", ContentPath, Content.m_ContentID); - - FILE* pAPPFile = fopen(APPFileName, "wb"); - if (pAPPFile == NULL) + if (Content.m_Type & 0x8000) //shared { - PanicAlert("WAD installation failed: error creating %s", APPFileName); - return false; + sprintf(APPFileName, "%s", + DiscIO::CSharedContent::AccessInstance().AddSharedContent(Content.m_SHA1Hash).c_str()); + } + else + { + sprintf(APPFileName, "%s%08x.app", ContentPath, Content.m_ContentID); + } + + if (!File::Exists(APPFileName)) + { + FILE* pAPPFile = fopen(APPFileName, "wb"); + if (pAPPFile == NULL) + { + PanicAlert("WAD installation failed: error creating %s", APPFileName); + return false; + } + + fwrite(Content.m_pData, Content.m_Size, 1, pAPPFile); + fclose(pAPPFile); + } + else + { + INFO_LOG(DISCIO, "Content %s already exists.", APPFileName); } - - fwrite(Content.m_pData, Content.m_Size, 1, pAPPFile); - fclose(pAPPFile); } fclose(pTMDFile); @@ -160,6 +175,11 @@ bool CBoot::Install_WiiWAD(const char* _pFilename) fwrite(Wad.GetTicket(), Wad.GetTicketSize(), 1, pTicketFile); fclose(pTicketFile); + + if (!DiscIO::cUIDsys::AccessInstance().AddTitle(TitleID)) + { + INFO_LOG(DISCIO, "Title %08x%08x, already exists in uid.sys", TitleID_HI, TitleID_LO); + } return true; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp index ffc94207e5..445dbd202a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -92,14 +92,16 @@ bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) m_TitleID = ((u64)0x00010000 << 32) | 0xF00DBEEF; } + // TODO: when dev/fs IOCTLV_GETUSAGE is correct (wii doesnt report fs as corrupt) uncomment this line + // title ids are all listed in sys/uid.sys - lpfaint99 + //DiscIO::cUIDsys::AccessInstance().GetTitleIDs(m_TitleIDs); - // scan for the title ids listed in TMDs within /title/ m_TitleIDs.push_back(0x0000000100000002ULL); //m_TitleIDs.push_back(0x0001000248414741ULL); //m_TitleIDs.push_back(0x0001000248414341ULL); //m_TitleIDs.push_back(0x0001000248414241ULL); //m_TitleIDs.push_back(0x0001000248414141ULL); - + // scan for the title ids listed in TMDs within /title/ //FindValidTitleIDs(); INFO_LOG(WII_IPC_ES, "Set default title to %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID); diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index b58f17df2b..03f3ec54f2 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -29,51 +29,31 @@ namespace DiscIO { - -class CSharedContent -{ -public: - - static CSharedContent& AccessInstance() { return m_Instance; } - - std::string GetFilenameFromSHA1(u8* _pHash); - -private: - - - CSharedContent(); - - virtual ~CSharedContent(); - - struct SElement - { - u8 FileName[8]; - u8 SHA1Hash[20]; - }; - - std::vector m_Elements; - static CSharedContent m_Instance; -}; - CSharedContent CSharedContent::m_Instance; +cUIDsys cUIDsys::m_Instance; CSharedContent::CSharedContent() { - char szFilename[1024]; - sprintf(szFilename, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX)); - if (File::Exists(szFilename)) + sprintf(contentMap, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX)); + lastID = 0; + if (File::Exists(contentMap)) { - FILE* pFile = fopen(szFilename, "rb"); + FILE* pFile = fopen(contentMap, "rb"); while(!feof(pFile)) { SElement Element; if (fread(&Element, sizeof(SElement), 1, pFile) == 1) { m_Elements.push_back(Element); + lastID++; } } fclose(pFile); } + else + { + File::CreateFullPath(contentMap); + } } CSharedContent::~CSharedContent() @@ -95,6 +75,29 @@ std::string CSharedContent::GetFilenameFromSHA1(u8* _pHash) return "unk"; } +std::string CSharedContent::AddSharedContent(u8* _pHash) +{ + std::string szFilename = GetFilenameFromSHA1(_pHash); + if (strcasecmp(szFilename.c_str(), "unk") == 0) + { + char tempFilename[1024], c_ID[9]; + SElement Element; + sprintf(c_ID, "%08x", lastID); + memcpy(Element.FileName, c_ID, 8); + memcpy(Element.SHA1Hash, _pHash, 20); + m_Elements.push_back(Element); + FILE* pFile = fopen(contentMap, "ab"); + if (pFile) + { + fwrite(&Element, sizeof(SElement), 1, pFile); + fclose(pFile); + } + sprintf(tempFilename, "%sshared1/%s.app", File::GetUserPath(D_WIIUSER_IDX), c_ID); + szFilename = tempFilename; + lastID++; + } + return szFilename; +} // this classes must be created by the CNANDContentManager @@ -371,5 +374,100 @@ const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string& return *m_Map[_rName]; } +cUIDsys::cUIDsys() +{ + sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX)); + lastUID = 0x00001000; + if (File::Exists(uidSys)) + { + FILE* pFile = fopen(uidSys, "rb"); + while(!feof(pFile)) + { + SElement Element; + if (fread(&Element, sizeof(SElement), 1, pFile) == 1) + { + if (CheckValidTitle(Common::swap64(Element.titleID))) + { + m_Elements.push_back(Element); + lastUID++; + } + } + } + fclose(pFile); + } + else + { + File::CreateFullPath(uidSys); + } +} + +cUIDsys::~cUIDsys() +{} + +u32 cUIDsys::GetUIDFromTitle(u64 _Title) +{ + for (size_t i=0; i& _TitleIDs) +{ + for (size_t i = 0; i < m_Elements.size(); i++) + { + _TitleIDs.push_back(Common::swap64(m_Elements[i].titleID)); + } +} + +bool cUIDsys::CheckValidTitle(u64 _TitleID) +{ + char TitlePath[1024]; + sprintf(TitlePath, "%stitle/%08x/%08x/content/title.tmd", File::GetUserPath(D_WIIUSER_IDX), + (u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF)); + + if (File::Exists(TitlePath)) + { + FILE* pTMDFile = fopen(TitlePath, "rb"); + if(pTMDFile) + { + u64 TitleID = 0xDEADBEEFDEADBEEFULL; + fseek(pTMDFile, 0x18C, SEEK_SET); + fread(&TitleID, 8, 1, pTMDFile); + fclose(pTMDFile); + if (_TitleID == Common::swap64(TitleID)) + return true; + } + } + return false; +} + } // namespace end diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index 0f3b802edd..57e1fb0183 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -94,7 +94,66 @@ private: }; +class CSharedContent +{ +public: + + static CSharedContent& AccessInstance() { return m_Instance; } + + std::string GetFilenameFromSHA1(u8* _pHash); + std::string AddSharedContent(u8* _pHash); + +private: + + + CSharedContent(); + + virtual ~CSharedContent(); + +#pragma pack(push,1) + struct SElement + { + u8 FileName[8]; + u8 SHA1Hash[20]; + }; +#pragma pack(pop) + + u32 lastID; + char contentMap[1024]; + std::vector m_Elements; + static CSharedContent m_Instance; +}; + +class cUIDsys +{ +public: + + static cUIDsys& AccessInstance() { return m_Instance; } + + u32 GetUIDFromTitle(u64 _Title); + bool AddTitle(u64 _Title); + bool CheckValidTitle(u64 _TitleID); + void GetTitleIDs(std::vector& _TitleIDs); +private: + + + cUIDsys(); + + virtual ~cUIDsys(); + +#pragma pack(push,1) + struct SElement + { + u8 titleID[8]; + u8 UID[4]; + }; +#pragma pack(pop) + u32 lastUID; + char uidSys[1024]; + std::vector m_Elements; + static cUIDsys m_Instance; +}; + } #endif - diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index 29a14ada4e..1f9dd4d5ca 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -281,6 +281,7 @@ EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard) EVT_MENU(IDM_IMPORTSAVE, CFrame::OnImportSave) EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow) EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc) +EVT_MENU(IDM_INSTALL_WII_MENU, CFrame::OnLoadWiiMenu) EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu) EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen) diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index a61e0dbbb3..f6cd332f31 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -192,6 +192,10 @@ void CFrame::CreateMenu() { toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu")); } + else + { + toolsMenu->Append(IDM_INSTALL_WII_MENU, _T("Install Wii Menu")); + } toolsMenu->AppendSeparator(); toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE1, GetMenuLabel(HK_WIIMOTE1_CONNECT)); toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE2, GetMenuLabel(HK_WIIMOTE2_CONNECT)); @@ -1035,9 +1039,33 @@ void CFrame::OnShow_CheatsWindow(wxCommandEvent& WXUNUSED (event)) CheatsWindow = new wxCheatsWindow(this, wxDefaultPosition, wxSize(600, 390)); } -void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event)) +void CFrame::OnLoadWiiMenu(wxCommandEvent& event) { - BootGame(std::string (File::GetUserPath(D_WIIMENU_IDX))); + if (event.GetId() == IDM_LOAD_WII_MENU) + { + BootGame(std::string (File::GetUserPath(D_WIIMENU_IDX))); + } + else + { + + wxString path = wxFileSelector( + _T("Select the System Menu wad extracted from the update partition of a disc"), + wxEmptyString, wxEmptyString, wxEmptyString, + wxString::Format + ( + _T("System Menu wad|RVL-WiiSystemmenu-v*.wad"), + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST, + this); + + if (CBoot::Install_WiiWAD(path.mb_str())) + {;// TODO: Fix so that menu item changes approprately so a restart is not required + // GetMenuBar()->FindItem(IDM_INSTALL_WII_MENU)->SetId(IDM_LOAD_WII_MENU); + // GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->SetItemLabel(_T("Load Wii Menu")); + } + } } void CFrame::OnConnectWiimote(wxCommandEvent& event) diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h index 0c7588a363..4ec49b29a1 100644 --- a/Source/Core/DolphinWX/Src/Globals.h +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -95,6 +95,7 @@ enum IDM_CHANGEDISC, IDM_PROPERTIES, IDM_LOAD_WII_MENU, + IDM_INSTALL_WII_MENU, IDM_LUA, IDM_CONNECT_WIIMOTE1, IDM_CONNECT_WIIMOTE2,