Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Merge pull request #11072 from SketchMaster2001/wiiconnect24
Add initial WiiConnect24 support
- Loading branch information
Showing
12 changed files
with
863 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| // Copyright 2022 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #include "Core/IOS/Network/KD/NWC24DL.h" | ||
|
|
||
| #include "Common/BitUtils.h" | ||
| #include "Common/CommonPaths.h" | ||
| #include "Common/CommonTypes.h" | ||
| #include "Common/Logging/Log.h" | ||
| #include "Common/Swap.h" | ||
| #include "Core/IOS/FS/FileSystem.h" | ||
| #include "Core/IOS/Uids.h" | ||
|
|
||
| namespace IOS::HLE::NWC24 | ||
| { | ||
| constexpr const char DL_LIST_PATH[] = "/" WII_WC24CONF_DIR "/nwc24dl.bin"; | ||
|
|
||
| NWC24Dl::NWC24Dl(std::shared_ptr<FS::FileSystem> fs) : m_fs{std::move(fs)} | ||
| { | ||
| ReadDlList(); | ||
| } | ||
|
|
||
| void NWC24Dl::ReadDlList() | ||
| { | ||
| const auto file = m_fs->OpenFile(PID_KD, PID_KD, DL_LIST_PATH, FS::Mode::Read); | ||
| if (!file || !file->Read(&m_data, 1)) | ||
| return; | ||
|
|
||
| const s32 file_error = CheckNwc24DlList(); | ||
| if (file_error) | ||
| ERROR_LOG_FMT(IOS_WC24, "There is an error in the DL list for WC24: {}", file_error); | ||
| } | ||
|
|
||
| s32 NWC24Dl::CheckNwc24DlList() const | ||
| { | ||
| // 'WcDl' magic | ||
| if (Magic() != DL_LIST_MAGIC) | ||
| { | ||
| ERROR_LOG_FMT(IOS_WC24, "DL list magic mismatch"); | ||
| return -1; | ||
| } | ||
|
|
||
| if (Version() != 1) | ||
| { | ||
| ERROR_LOG_FMT(IOS_WC24, "DL list version mismatch"); | ||
| return -1; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| void NWC24Dl::WriteDlList() const | ||
| { | ||
| constexpr FS::Modes public_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite}; | ||
| m_fs->CreateFullPath(PID_KD, PID_KD, DL_LIST_PATH, 0, public_modes); | ||
| const auto file = m_fs->CreateAndOpenFile(PID_KD, PID_KD, DL_LIST_PATH, public_modes); | ||
|
|
||
| if (!file || !file->Write(&m_data, 1)) | ||
| ERROR_LOG_FMT(IOS_WC24, "Failed to open or write WC24 DL list file"); | ||
| } | ||
|
|
||
| bool NWC24Dl::DoesEntryExist(u16 entry_index) | ||
| { | ||
| return m_data.entries[entry_index].low_title_id != 0; | ||
| } | ||
|
|
||
| std::string NWC24Dl::GetDownloadURL(u16 entry_index, std::optional<u8> subtask_id) const | ||
| { | ||
| std::string url(m_data.entries[entry_index].dl_url); | ||
|
|
||
| // Determine if we need to append the subtask to the URL. | ||
| if (subtask_id && | ||
| Common::ExtractBit(Common::swap32(m_data.entries[entry_index].subtask_bitmask), 1)) | ||
| { | ||
| url.append(fmt::format(".{:02d}", *subtask_id)); | ||
| } | ||
|
|
||
| return url; | ||
| } | ||
|
|
||
| std::string NWC24Dl::GetVFFContentName(u16 entry_index, std::optional<u8> subtask_id) const | ||
| { | ||
| std::string content(m_data.entries[entry_index].filename); | ||
|
|
||
| // Determine if we need to append the subtask to the name. | ||
| if (subtask_id && | ||
| Common::ExtractBit(Common::swap32(m_data.entries[entry_index].subtask_bitmask), 0)) | ||
| { | ||
| content.append(fmt::format(".{:02d}", *subtask_id)); | ||
| } | ||
|
|
||
| return content; | ||
| } | ||
|
|
||
| std::string NWC24Dl::GetVFFPath(u16 entry_index) const | ||
| { | ||
| const u32 lower_title_id = Common::swap32(m_data.entries[entry_index].low_title_id); | ||
| const u32 high_title_id = Common::swap32(m_data.entries[entry_index].high_title_id); | ||
|
|
||
| return fmt::format("/title/{0:08x}/{1:08x}/data/wc24dl.vff", lower_title_id, high_title_id); | ||
| } | ||
|
|
||
| WC24PubkMod NWC24Dl::GetWC24PubkMod(u16 entry_index) const | ||
| { | ||
| WC24PubkMod pubkMod; | ||
| const u32 lower_title_id = Common::swap32(m_data.entries[entry_index].low_title_id); | ||
| const u32 high_title_id = Common::swap32(m_data.entries[entry_index].high_title_id); | ||
|
|
||
| const std::string path = | ||
| fmt::format("/title/{0:08x}/{1:08x}/data/wc24pubk.mod", lower_title_id, high_title_id); | ||
|
|
||
| const auto file = m_fs->OpenFile(PID_KD, PID_KD, path, IOS::HLE::FS::Mode::Read); | ||
| file->Read(&pubkMod, 1); | ||
|
|
||
| return pubkMod; | ||
| } | ||
|
|
||
| bool NWC24Dl::IsEncrypted(u16 entry_index) const | ||
| { | ||
| return !!Common::ExtractBit(Common::swap32(m_data.entries[entry_index].flags), 3); | ||
| } | ||
|
|
||
| u32 NWC24Dl::Magic() const | ||
| { | ||
| return Common::swap32(m_data.header.magic); | ||
| } | ||
|
|
||
| void NWC24Dl::SetMagic(u32 magic) | ||
| { | ||
| m_data.header.magic = Common::swap32(magic); | ||
| } | ||
|
|
||
| u32 NWC24Dl::Version() const | ||
| { | ||
| return Common::swap32(m_data.header.version); | ||
| } | ||
|
|
||
| void NWC24Dl::SetVersion(u32 version) | ||
| { | ||
| m_data.header.version = Common::swap32(version); | ||
| } | ||
|
|
||
| } // namespace IOS::HLE::NWC24 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| // Copyright 2022 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <memory> | ||
| #include <optional> | ||
| #include <string> | ||
| #include "Common/CommonTypes.h" | ||
| #include "Core/IOS/Network/KD/WC24File.h" | ||
|
|
||
| namespace IOS::HLE | ||
| { | ||
| namespace FS | ||
| { | ||
| class FileSystem; | ||
| } | ||
| namespace NWC24 | ||
| { | ||
| class NWC24Dl final | ||
| { | ||
| public: | ||
| explicit NWC24Dl(std::shared_ptr<FS::FileSystem> fs); | ||
|
|
||
| void ReadDlList(); | ||
| void WriteDlList() const; | ||
|
|
||
| s32 CheckNwc24DlList() const; | ||
|
|
||
| bool DoesEntryExist(u16 entry_index); | ||
| bool IsEncrypted(u16 entry_index) const; | ||
| std::string GetVFFContentName(u16 entry_index, std::optional<u8> subtask_id) const; | ||
| std::string GetDownloadURL(u16 entry_index, std::optional<u8> subtask_id) const; | ||
| std::string GetVFFPath(u16 entry_index) const; | ||
| WC24PubkMod GetWC24PubkMod(u16 entry_index) const; | ||
|
|
||
| u32 Magic() const; | ||
| void SetMagic(u32 magic); | ||
|
|
||
| u32 Version() const; | ||
| void SetVersion(u32 version); | ||
|
|
||
| static constexpr u32 MAX_ENTRIES = 120; | ||
|
|
||
| private: | ||
| static constexpr u32 DL_LIST_MAGIC = 0x5763446C; // WcDl | ||
| static constexpr u32 MAX_SUBENTRIES = 32; | ||
|
|
||
| enum EntryType : u8 | ||
| { | ||
| UNK = 1, | ||
| MAIL, | ||
| CHANNEL_CONTENT, | ||
| UNUSED = 0xff | ||
| }; | ||
|
|
||
| #pragma pack(push, 1) | ||
| // The following format is partially based off of https://wiibrew.org/wiki//dev/net/kd/request. | ||
| struct DLListHeader final | ||
| { | ||
| u32 magic; // 'WcDl' 0x5763446c | ||
| u32 version; // must be 1 | ||
| u32 unk1; | ||
| u32 unk2; | ||
| u16 max_subentries; // Asserted to be less than max_entries | ||
| u16 reserved_mailnum; | ||
| u16 max_entries; | ||
| u8 reserved[106]; | ||
| }; | ||
|
|
||
| struct DLListRecord final | ||
| { | ||
| u32 low_title_id; | ||
| u32 next_dl_timestamp; | ||
| u32 last_modified_timestamp; | ||
| u8 flags; | ||
| u8 padding[3]; | ||
| }; | ||
|
|
||
| struct DLListEntry final | ||
| { | ||
| u16 index; | ||
| EntryType type; | ||
| u8 record_flags; | ||
| u32 flags; | ||
| u32 high_title_id; | ||
| u32 low_title_id; | ||
| u32 unknown1; | ||
| u16 group_id; | ||
| u16 padding1; | ||
| u16 remaining_downloads; | ||
| u16 error_count; | ||
| u16 dl_frequency; | ||
| u16 dl_frequency_when_err; | ||
| s32 error_code; | ||
| u8 subtask_id; | ||
| u8 subtask_type; | ||
| u8 subtask_flags; | ||
| u8 padding2; | ||
| u32 subtask_bitmask; | ||
| s32 unknown2; | ||
| u32 dl_timestamp; // Last DL time | ||
| u32 subtask_timestamps[32]; | ||
| char dl_url[236]; | ||
| char filename[64]; | ||
| u8 unk6[29]; | ||
| u8 should_use_rootca; | ||
| u16 unknown3; | ||
| }; | ||
|
|
||
| struct DLList final | ||
| { | ||
| DLListHeader header; | ||
| DLListRecord records[MAX_ENTRIES]; | ||
| DLListEntry entries[MAX_ENTRIES]; | ||
| }; | ||
| #pragma pack(pop) | ||
|
|
||
| std::shared_ptr<FS::FileSystem> m_fs; | ||
| DLList m_data; | ||
| }; | ||
| } // namespace NWC24 | ||
| } // namespace IOS::HLE |
Oops, something went wrong.