From 458c953b7e788fd831f7eb4645f1585581f79b11 Mon Sep 17 00:00:00 2001 From: mrdude2478 Date: Tue, 5 Sep 2023 02:02:42 +0100 Subject: [PATCH] Delete source directory --- source/HDInstall.cpp | 168 ------ source/data/buffered_placeholder_writer.cpp | 212 ------- source/data/byte_buffer.cpp | 55 -- source/data/byte_stream.cpp | 41 -- source/install/http_nsp.cpp | 154 ----- source/install/http_xci.cpp | 162 ------ source/install/install.cpp | 192 ------- source/install/install_nsp.cpp | 182 ------ source/install/install_xci.cpp | 181 ------ source/install/nsp.cpp | 143 ----- source/install/sdmc_nsp.cpp | 75 --- source/install/sdmc_xci.cpp | 75 --- source/install/simple_filesystem.cpp | 89 --- source/install/usb_nsp.cpp | 193 ------- source/install/usb_xci.cpp | 192 ------- source/install/xci.cpp | 174 ------ source/main.cpp | 34 -- source/netInstall.cpp | 429 -------------- source/nx/content_meta.cpp | 131 ----- source/nx/fs.cpp | 156 ----- source/nx/ipc/es.c | 145 ----- source/nx/ipc/ns_ext.c | 197 ------- source/nx/ipc/service_guard.h | 74 --- source/nx/nca_writer.cpp | 479 ---------------- source/nx/ncm.cpp | 76 --- source/nx/usbhdd.cpp | 190 ------- source/sdInstall.cpp | 169 ------ source/sigInstall.cpp | 73 --- source/ui/HDInstPage.cpp | 202 ------- source/ui/MainApplication.cpp | 28 - source/ui/instPage.cpp | 78 --- source/ui/mainPage.cpp | 319 ----------- source/ui/netInstPage.cpp | 272 --------- source/ui/optionsPage.cpp | 340 ----------- source/ui/sdInstPage.cpp | 225 -------- source/ui/usbInstPage.cpp | 180 ------ source/usbInstall.cpp | 195 ------- source/util/config.cpp | 83 --- source/util/crypto.cpp | 90 --- source/util/curl.cpp | 102 ---- source/util/debug.c | 53 -- source/util/file_util.cpp | 53 -- source/util/lang.cpp | 79 --- source/util/network_util.cpp | 267 --------- source/util/title_util.cpp | 134 ----- source/util/unzip.cpp | 161 ------ source/util/usb_comms_tinleaf.c | 595 -------------------- source/util/usb_util.cpp | 105 ---- source/util/util.cpp | 317 ----------- 49 files changed, 8319 deletions(-) delete mode 100644 source/HDInstall.cpp delete mode 100644 source/data/buffered_placeholder_writer.cpp delete mode 100644 source/data/byte_buffer.cpp delete mode 100644 source/data/byte_stream.cpp delete mode 100644 source/install/http_nsp.cpp delete mode 100644 source/install/http_xci.cpp delete mode 100644 source/install/install.cpp delete mode 100644 source/install/install_nsp.cpp delete mode 100644 source/install/install_xci.cpp delete mode 100644 source/install/nsp.cpp delete mode 100644 source/install/sdmc_nsp.cpp delete mode 100644 source/install/sdmc_xci.cpp delete mode 100644 source/install/simple_filesystem.cpp delete mode 100644 source/install/usb_nsp.cpp delete mode 100644 source/install/usb_xci.cpp delete mode 100644 source/install/xci.cpp delete mode 100644 source/main.cpp delete mode 100644 source/netInstall.cpp delete mode 100644 source/nx/content_meta.cpp delete mode 100644 source/nx/fs.cpp delete mode 100644 source/nx/ipc/es.c delete mode 100644 source/nx/ipc/ns_ext.c delete mode 100644 source/nx/ipc/service_guard.h delete mode 100644 source/nx/nca_writer.cpp delete mode 100644 source/nx/ncm.cpp delete mode 100644 source/nx/usbhdd.cpp delete mode 100644 source/sdInstall.cpp delete mode 100644 source/sigInstall.cpp delete mode 100644 source/ui/HDInstPage.cpp delete mode 100644 source/ui/MainApplication.cpp delete mode 100644 source/ui/instPage.cpp delete mode 100644 source/ui/mainPage.cpp delete mode 100644 source/ui/netInstPage.cpp delete mode 100644 source/ui/optionsPage.cpp delete mode 100644 source/ui/sdInstPage.cpp delete mode 100644 source/ui/usbInstPage.cpp delete mode 100644 source/usbInstall.cpp delete mode 100644 source/util/config.cpp delete mode 100644 source/util/crypto.cpp delete mode 100644 source/util/curl.cpp delete mode 100644 source/util/debug.c delete mode 100644 source/util/file_util.cpp delete mode 100644 source/util/lang.cpp delete mode 100644 source/util/network_util.cpp delete mode 100644 source/util/title_util.cpp delete mode 100644 source/util/unzip.cpp delete mode 100644 source/util/usb_comms_tinleaf.c delete mode 100644 source/util/usb_util.cpp delete mode 100644 source/util/util.cpp diff --git a/source/HDInstall.cpp b/source/HDInstall.cpp deleted file mode 100644 index 82b651b..0000000 --- a/source/HDInstall.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "HDInstall.hpp" -#include "install/install_nsp.hpp" -#include "install/install_xci.hpp" -#include "install/sdmc_xci.hpp" -#include "install/sdmc_nsp.hpp" -#include "nx/fs.hpp" -#include "util/file_util.hpp" -#include "util/title_util.hpp" -#include "util/error.hpp" -#include "util/config.hpp" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "ui/MainApplication.hpp" -#include "ui/instPage.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace nspInstStuff_B { - - void installNspFromFile(std::vector ourTitleList, int whereToInstall) - { - inst::util::initInstallServices(); - inst::ui::instPage::loadInstallScreen(); - bool nspInstalled = true; - NcmStorageId m_destStorageId = NcmStorageId_SdCard; - - if (whereToInstall) m_destStorageId = NcmStorageId_BuiltInUser; - unsigned int titleItr; - - std::vector previousClockValues; - if (inst::config::overClock) { - previousClockValues.push_back(inst::util::setClockSpeed(0, 1785000000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(1, 76800000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(2, 1600000000)[0]); - } - - try - { - for (titleItr = 0; titleItr < ourTitleList.size(); titleItr++) { - inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 40, true) + "inst.hd.source_string"_lang); - std::unique_ptr installTask; - - if (ourTitleList[titleItr].extension() == ".xci" || ourTitleList[titleItr].extension() == ".xcz") { - auto sdmcXCI = std::make_shared(ourTitleList[titleItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, sdmcXCI); - } else { - auto sdmcNSP = std::make_shared(ourTitleList[titleItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, sdmcNSP); - } - - LOG_DEBUG("%s\n", "Preparing installation"); - inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang); - inst::ui::instPage::setInstBarPerc(0); - installTask->Prepare(); - installTask->Begin(); - } - } - catch (std::exception& e) - { - LOG_DEBUG("Failed to install"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true)); - inst::ui::instPage::setInstBarPerc(0); - std::string audioPath = ""; - if (std::filesystem::exists(inst::config::appDir + "/sounds/OHNO.WAV")) { - audioPath = (inst::config::appDir + "/sounds/OHNO.WAV"); - } - else { - audioPath = "romfs:/audio/bark.wav"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true) + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true); - audioThread.join(); - nspInstalled = false; - } - - if (previousClockValues.size() > 0) { - inst::util::setClockSpeed(0, previousClockValues[0]); - inst::util::setClockSpeed(1, previousClockValues[1]); - inst::util::setClockSpeed(2, previousClockValues[2]); - } - - if(nspInstalled) { - inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang); - inst::ui::instPage::setInstBarPerc(100); - std::string audioPath = ""; - - if (inst::config::useSound) { - if (std::filesystem::exists(inst::config::appDir + "/sounds/YIPPEE.WAV")) { - audioPath = (inst::config::appDir + "/sounds/YIPPEE.WAV"); - } - else { - audioPath = "romfs:/audio/ameizing.mp3"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - - if (ourTitleList.size() > 1) { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.hd.delete_info_multi"_lang, "inst.hd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) { - for (long unsigned int i = 0; i < ourTitleList.size(); i++) { - if (std::filesystem::exists(ourTitleList[i])) std::filesystem::remove(ourTitleList[i]); - } - } - } else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } else { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + "inst.hd.delete_info"_lang, "inst.hd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]); - } else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - - audioThread.join(); - } - - else{ - if (ourTitleList.size() > 1) { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.hd.delete_info_multi"_lang, "inst.hd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) { - for (long unsigned int i = 0; i < ourTitleList.size(); i++) { - if (std::filesystem::exists(ourTitleList[i])) std::filesystem::remove(ourTitleList[i]); - } - } - } else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } else { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + "inst.hd.delete_info"_lang, "inst.hd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]); - } else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - } - } - - LOG_DEBUG("Done"); - inst::ui::instPage::loadMainMenu(); - inst::util::deinitInstallServices(); - return; - } -} \ No newline at end of file diff --git a/source/data/buffered_placeholder_writer.cpp b/source/data/buffered_placeholder_writer.cpp deleted file mode 100644 index 5e6d071..0000000 --- a/source/data/buffered_placeholder_writer.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "data/buffered_placeholder_writer.hpp" - -#include -#include -#include -#include -#include "util/error.hpp" -#include "util/debug.h" - -namespace tin::data -{ - int NUM_BUFFER_SEGMENTS; - - BufferedPlaceholderWriter::BufferedPlaceholderWriter(std::shared_ptr& contentStorage, NcmContentId ncaId, size_t totalDataSize) : - m_totalDataSize(totalDataSize), m_contentStorage(contentStorage), m_ncaId(ncaId), m_writer(ncaId, contentStorage) - { - // Though currently the number of segments is fixed, we want them allocated on the heap, not the stack - m_bufferSegments = std::make_unique(NUM_BUFFER_SEGMENTS); - - if (m_bufferSegments == nullptr) - THROW_FORMAT("Failed to allocated buffer segments!\n"); - - m_currentFreeSegmentPtr = &m_bufferSegments[m_currentFreeSegment]; - m_currentSegmentToWritePtr = &m_bufferSegments[m_currentSegmentToWrite]; - } - - void BufferedPlaceholderWriter::AppendData(void* source, size_t length) - { - if (m_sizeBuffered + length > m_totalDataSize) - THROW_FORMAT("Cannot append data as it would exceed the expected total.\n"); - - size_t dataSizeRemaining = length; - u64 sourceOffset = 0; - - while (dataSizeRemaining > 0) - { - size_t bufferSegmentSizeRemaining = BUFFER_SEGMENT_DATA_SIZE - m_currentFreeSegmentPtr->writeOffset; - - if (m_currentFreeSegmentPtr->isFinalized) - THROW_FORMAT("Current buffer segment is already finalized!\n"); - - if (dataSizeRemaining < bufferSegmentSizeRemaining) - { - memcpy(m_currentFreeSegmentPtr->data + m_currentFreeSegmentPtr->writeOffset, (u8*)source + sourceOffset, dataSizeRemaining); - sourceOffset += dataSizeRemaining; - m_currentFreeSegmentPtr->writeOffset += dataSizeRemaining; - dataSizeRemaining = 0; - } - else - { - memcpy(m_currentFreeSegmentPtr->data + m_currentFreeSegmentPtr->writeOffset, (u8*)source + sourceOffset, bufferSegmentSizeRemaining); - dataSizeRemaining -= bufferSegmentSizeRemaining; - sourceOffset += bufferSegmentSizeRemaining; - m_currentFreeSegmentPtr->writeOffset += bufferSegmentSizeRemaining; - m_currentFreeSegmentPtr->isFinalized = true; - - m_currentFreeSegment = (m_currentFreeSegment + 1) % NUM_BUFFER_SEGMENTS; - m_currentFreeSegmentPtr = &m_bufferSegments[m_currentFreeSegment]; - } - } - - m_sizeBuffered += length; - - if (m_sizeBuffered == m_totalDataSize) - { - m_currentFreeSegmentPtr->isFinalized = true; - } - } - - bool BufferedPlaceholderWriter::CanAppendData(size_t length) - { - if (m_sizeBuffered + length > m_totalDataSize) - return false; - - if (!this->IsSizeAvailable(length)) - return false; - - return true; - } - - void BufferedPlaceholderWriter::WriteSegmentToPlaceholder() - { - if (m_sizeWrittenToPlaceholder >= m_totalDataSize) - THROW_FORMAT("Cannot write segment as end of data has already been reached!\n"); - - if (!m_currentSegmentToWritePtr->isFinalized) - THROW_FORMAT("Cannot write segment as it hasn't been finalized!\n"); - - // NOTE: The final segment will have leftover data from previous writes, however - // this will be accounted for by this size - size_t sizeToWriteToPlaceholder = std::min(m_totalDataSize - m_sizeWrittenToPlaceholder, BUFFER_SEGMENT_DATA_SIZE); - m_writer.write(m_currentSegmentToWritePtr->data, sizeToWriteToPlaceholder); - - m_currentSegmentToWritePtr->isFinalized = false; - m_currentSegmentToWritePtr->writeOffset = 0; - m_currentSegmentToWrite = (m_currentSegmentToWrite + 1) % NUM_BUFFER_SEGMENTS; - m_currentSegmentToWritePtr = &m_bufferSegments[m_currentSegmentToWrite]; - m_sizeWrittenToPlaceholder += sizeToWriteToPlaceholder; - } - - bool BufferedPlaceholderWriter::CanWriteSegmentToPlaceholder() - { - if (m_sizeWrittenToPlaceholder >= m_totalDataSize) - return false; - - if (!m_currentSegmentToWritePtr->isFinalized) - return false; - - return true; - } - - u32 BufferedPlaceholderWriter::CalcNumSegmentsRequired(size_t size) - { - if (m_currentFreeSegmentPtr->isFinalized) - return INT_MAX; - - size_t bufferSegmentSizeRemaining = BUFFER_SEGMENT_DATA_SIZE - m_currentFreeSegmentPtr->writeOffset; - - if (size <= bufferSegmentSizeRemaining) return 1; - else - { - double numSegmentsReq = 1 + (double)(size - bufferSegmentSizeRemaining) / (double)BUFFER_SEGMENT_DATA_SIZE; - return ceil(numSegmentsReq); - } - } - - bool BufferedPlaceholderWriter::IsSizeAvailable(size_t size) - { - u32 numSegmentsRequired = this->CalcNumSegmentsRequired(size); - - if ((int)numSegmentsRequired > NUM_BUFFER_SEGMENTS) - return false; - - for (unsigned int i = 0; i < numSegmentsRequired; i++) - { - unsigned int segmentIndex = m_currentFreeSegment + i; - BufferSegment* bufferSegment = &m_bufferSegments[segmentIndex % NUM_BUFFER_SEGMENTS]; - - if (bufferSegment->isFinalized) - return false; - - if (i != 0 && bufferSegment->writeOffset != 0) - THROW_FORMAT("Unexpected non-zero write offset at segment %u (%lu)\n", segmentIndex, bufferSegment->writeOffset); - } - - return true; - } - - bool BufferedPlaceholderWriter::IsBufferDataComplete() - { - if (m_sizeBuffered > m_totalDataSize) - THROW_FORMAT("Size buffered cannot exceed total data size!\n"); - - return m_sizeBuffered == m_totalDataSize; - } - - bool BufferedPlaceholderWriter::IsPlaceholderComplete() - { - if (m_sizeWrittenToPlaceholder > m_totalDataSize) - THROW_FORMAT("Size written to placeholder cannot exceed total data size!\n"); - - return m_sizeWrittenToPlaceholder == m_totalDataSize; - } - - size_t BufferedPlaceholderWriter::GetTotalDataSize() - { - return m_totalDataSize; - } - - size_t BufferedPlaceholderWriter::GetSizeBuffered() - { - return m_sizeBuffered; - } - - size_t BufferedPlaceholderWriter::GetSizeWrittenToPlaceholder() - { - return m_sizeWrittenToPlaceholder; - } - - void BufferedPlaceholderWriter::DebugPrintBuffers() - { - LOG_DEBUG("BufferedPlaceholderWriter Buffers: \n"); - - for (int i = 0; i < NUM_BUFFER_SEGMENTS; i++) - { - LOG_DEBUG("Buffer %u:\n", i); - printBytes(m_bufferSegments[i].data, BUFFER_SEGMENT_DATA_SIZE, true); - } - } -} \ No newline at end of file diff --git a/source/data/byte_buffer.cpp b/source/data/byte_buffer.cpp deleted file mode 100644 index 033da8f..0000000 --- a/source/data/byte_buffer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "data/byte_buffer.hpp" - -#include "util/error.hpp" -#include "util/debug.h" - -namespace tin::data -{ - ByteBuffer::ByteBuffer(size_t reserveSize) - { - m_buffer.resize(reserveSize); - } - - size_t ByteBuffer::GetSize() - { - return m_buffer.size(); - } - - u8* ByteBuffer::GetData() - { - return m_buffer.data(); - } - - void ByteBuffer::Resize(size_t size) - { - m_buffer.resize(size, 0); - } - - void ByteBuffer::DebugPrintContents() - { - LOG_DEBUG("Buffer Size: 0x%lx\n", this->GetSize()); - printBytes(this->GetData(), this->GetSize(), true); - } -} \ No newline at end of file diff --git a/source/data/byte_stream.cpp b/source/data/byte_stream.cpp deleted file mode 100644 index fb76391..0000000 --- a/source/data/byte_stream.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "data/byte_stream.hpp" - -namespace tin::data -{ - BufferedByteStream::BufferedByteStream(ByteBuffer buffer) : - m_byteBuffer(buffer) - { - - } - - void BufferedByteStream::ReadBytes(void* dest, size_t length) - { - if (m_offset + length > m_byteBuffer.GetSize()) - return; - - memcpy(dest, m_byteBuffer.GetData() + m_offset, length); - m_offset += length; - } -} \ No newline at end of file diff --git a/source/install/http_nsp.cpp b/source/install/http_nsp.cpp deleted file mode 100644 index 95480b6..0000000 --- a/source/install/http_nsp.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/http_nsp.hpp" - -#include -#include -#include "data/buffered_placeholder_writer.hpp" -#include "util/title_util.hpp" -#include "util/error.hpp" -#include "util/debug.h" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "ui/instPage.hpp" - -namespace tin::install::nsp -{ - bool stopThreadsHttpNsp; - - HTTPNSP::HTTPNSP(std::string url) : - m_download(url) - { - - } - - struct StreamFuncArgs - { - tin::network::HTTPDownload* download; - tin::data::BufferedPlaceholderWriter* bufferedPlaceholderWriter; - u64 pfs0Offset; - u64 ncaSize; - }; - - int CurlStreamFunc(void* in) - { - StreamFuncArgs* args = reinterpret_cast(in); - - auto streamFunc = [&](u8* streamBuf, size_t streamBufSize) -> size_t - { - while (true) - { - if (args->bufferedPlaceholderWriter->CanAppendData(streamBufSize)) - break; - } - - args->bufferedPlaceholderWriter->AppendData(streamBuf, streamBufSize); - return streamBufSize; - }; - - if (args->download->StreamDataRange(args->pfs0Offset, args->ncaSize, streamFunc) == 1) stopThreadsHttpNsp = true; - return 0; - } - - int PlaceholderWriteFunc(void* in) - { - StreamFuncArgs* args = reinterpret_cast(in); - - while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete() && !stopThreadsHttpNsp) - { - if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder()) - args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder(); - } - - return 0; - } - - void HTTPNSP::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId placeholderId) - { - const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - tin::data::BufferedPlaceholderWriter bufferedPlaceholderWriter(contentStorage, placeholderId, ncaSize); - StreamFuncArgs args; - args.download = &m_download; - args.bufferedPlaceholderWriter = &bufferedPlaceholderWriter; - args.pfs0Offset = this->GetDataOffset() + fileEntry->dataOffset; - args.ncaSize = ncaSize; - thrd_t curlThread; - thrd_t writeThread; - - stopThreadsHttpNsp = false; - thrd_create(&curlThread, CurlStreamFunc, &args); - thrd_create(&writeThread, PlaceholderWriteFunc, &args); - - u64 freq = armGetSystemTickFreq(); - u64 startTime = armGetSystemTick(); - size_t startSizeBuffered = 0; - double speed = 0.0; - - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsBufferDataComplete() && !stopThreadsHttpNsp) - { - u64 newTime = armGetSystemTick(); - - if (newTime - startTime >= freq * 0.5) - { - size_t newSizeBuffered = bufferedPlaceholderWriter.GetSizeBuffered(); - double mbBuffered = (newSizeBuffered / 1000000.0) - (startSizeBuffered / 1000000.0); - double duration = ((double)(newTime - startTime) / (double)freq); - speed = mbBuffered / duration; - - startTime = newTime; - startSizeBuffered = newSizeBuffered; - - int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - - inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s"); - inst::ui::instPage::setInstBarPerc((double)downloadProgress); - } - } - inst::ui::instPage::setInstBarPerc(100); - - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsHttpNsp) - { - int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - - inst::ui::instPage::setInstBarPerc((double)installProgress); - } - inst::ui::instPage::setInstBarPerc(100); - - thrd_join(curlThread, NULL); - thrd_join(writeThread, NULL); - if (stopThreadsHttpNsp) THROW_FORMAT(("inst.net.transfer_interput"_lang).c_str()); - } - - void HTTPNSP::BufferData(void* buf, off_t offset, size_t size) - { - m_download.BufferDataRange(buf, offset, size, nullptr); - } -} \ No newline at end of file diff --git a/source/install/http_xci.cpp b/source/install/http_xci.cpp deleted file mode 100644 index 499416f..0000000 --- a/source/install/http_xci.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/http_xci.hpp" - -#include -#include "data/buffered_placeholder_writer.hpp" -#include "util/error.hpp" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "ui/instPage.hpp" - -namespace tin::install::xci -{ - bool stopThreadsHttpXci; - - HTTPXCI::HTTPXCI(std::string url) : - m_download(url) - { - - } - - struct StreamFuncArgs - { - tin::network::HTTPDownload* download; - tin::data::BufferedPlaceholderWriter* bufferedPlaceholderWriter; - u64 pfs0Offset; - u64 ncaSize; - }; - - int CurlStreamFunc(void* in) - { - StreamFuncArgs* args = reinterpret_cast(in); - - auto streamFunc = [&](u8* streamBuf, size_t streamBufSize) -> size_t - { - while (true) - { - if (args->bufferedPlaceholderWriter->CanAppendData(streamBufSize)) - break; - } - - args->bufferedPlaceholderWriter->AppendData(streamBuf, streamBufSize); - return streamBufSize; - }; - - if (args->download->StreamDataRange(args->pfs0Offset, args->ncaSize, streamFunc) == 1) stopThreadsHttpXci = true; - return 0; - } - - int PlaceholderWriteFunc(void* in) - { - StreamFuncArgs* args = reinterpret_cast(in); - - while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete() && !stopThreadsHttpXci) - { - if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder()) - args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder(); - } - - return 0; - } - - void HTTPXCI::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId ncaId) - { - const HFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(ncaId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - tin::data::BufferedPlaceholderWriter bufferedPlaceholderWriter(contentStorage, ncaId, ncaSize); - StreamFuncArgs args; - args.download = &m_download; - args.bufferedPlaceholderWriter = &bufferedPlaceholderWriter; - args.pfs0Offset = this->GetDataOffset() + fileEntry->dataOffset; - args.ncaSize = ncaSize; - thrd_t curlThread; - thrd_t writeThread; - - stopThreadsHttpXci = false; - thrd_create(&curlThread, CurlStreamFunc, &args); - thrd_create(&writeThread, PlaceholderWriteFunc, &args); - - u64 freq = armGetSystemTickFreq(); - u64 startTime = armGetSystemTick(); - size_t startSizeBuffered = 0; - double speed = 0.0; - - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsBufferDataComplete() && !stopThreadsHttpXci) - { - u64 newTime = armGetSystemTick(); - - if (newTime - startTime >= freq * 0.5) - { - size_t newSizeBuffered = bufferedPlaceholderWriter.GetSizeBuffered(); - double mbBuffered = (newSizeBuffered / 1000000.0) - (startSizeBuffered / 1000000.0); - double duration = ((double)(newTime - startTime) / (double)freq); - speed = mbBuffered / duration; - - startTime = newTime; - startSizeBuffered = newSizeBuffered; - int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000; - LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed); - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s"); - inst::ui::instPage::setInstBarPerc((double)downloadProgress); - } - } - inst::ui::instPage::setInstBarPerc(100); - - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsHttpXci) - { - int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000; - LOG_DEBUG("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%"); - #endif - inst::ui::instPage::setInstBarPerc((double)installProgress); - } - inst::ui::instPage::setInstBarPerc(100); - - thrd_join(curlThread, NULL); - thrd_join(writeThread, NULL); - if (stopThreadsHttpXci) THROW_FORMAT(("inst.net.transfer_interput"_lang).c_str()); - } - - void HTTPXCI::BufferData(void* buf, off_t offset, size_t size) - { - m_download.BufferDataRange(buf, offset, size, nullptr); - } -} \ No newline at end of file diff --git a/source/install/install.cpp b/source/install/install.cpp deleted file mode 100644 index 4fca448..0000000 --- a/source/install/install.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/install.hpp" - -#include -#include -#include -#include "util/error.hpp" - -#include "nx/ncm.hpp" -#include "util/title_util.hpp" - - -// TODO: Check NCA files are present -// TODO: Check tik/cert is present -namespace tin::install -{ - Install::Install(NcmStorageId destStorageId, bool ignoreReqFirmVersion) : - m_destStorageId(destStorageId), m_ignoreReqFirmVersion(ignoreReqFirmVersion), m_contentMeta() - { - appletSetMediaPlaybackState(true); - } - - Install::~Install() - { - appletSetMediaPlaybackState(false); - } - - // TODO: Implement RAII on NcmContentMetaDatabase - void Install::InstallContentMetaRecords(tin::data::ByteBuffer& installContentMetaBuf, int i) - { - NcmContentMetaDatabase contentMetaDatabase; - NcmContentMetaKey contentMetaKey = m_contentMeta[i].GetContentMetaKey(); - - try - { - ASSERT_OK(ncmOpenContentMetaDatabase(&contentMetaDatabase, m_destStorageId), "Failed to open content meta database"); - ASSERT_OK(ncmContentMetaDatabaseSet(&contentMetaDatabase, &contentMetaKey, (NcmContentMetaHeader*)installContentMetaBuf.GetData(), installContentMetaBuf.GetSize()), "Failed to set content records"); - ASSERT_OK(ncmContentMetaDatabaseCommit(&contentMetaDatabase), "Failed to commit content records"); - } - catch (std::runtime_error& e) - { - serviceClose(&contentMetaDatabase.s); - THROW_FORMAT(e.what()); - } - - serviceClose(&contentMetaDatabase.s); - } - - void Install::InstallApplicationRecord(int i) - { - Result rc = 0; - std::vector storageRecords; - u64 baseTitleId = tin::util::GetBaseTitleId(this->GetTitleId(i), this->GetContentMetaType(i)); - s32 contentMetaCount = 0; - - LOG_DEBUG("Base title Id: 0x%lx", baseTitleId); - - // TODO: Make custom error with result code field - // 0x410: The record doesn't already exist - if (R_FAILED(rc = nsCountApplicationContentMeta(baseTitleId, &contentMetaCount)) && rc != 0x410) - { - THROW_FORMAT("Failed to count application content meta"); - } - rc = 0; - - LOG_DEBUG("Content meta count: %u\n", contentMetaCount); - - // Obtain any existing app record content meta and append it to our vector - if (contentMetaCount > 0) - { - storageRecords.resize(contentMetaCount); - size_t contentStorageBufSize = contentMetaCount * sizeof(ContentStorageRecord); - auto contentStorageBuf = std::make_unique(contentMetaCount); - u32 entriesRead; - - ASSERT_OK(nsListApplicationRecordContentMeta(0, baseTitleId, contentStorageBuf.get(), contentStorageBufSize, &entriesRead), "Failed to list application record content meta"); - - if ((s32)entriesRead != contentMetaCount) - { - THROW_FORMAT("Mismatch between entries read and content meta count"); - } - - memcpy(storageRecords.data(), contentStorageBuf.get(), contentStorageBufSize); - } - - // Add our new content meta - ContentStorageRecord storageRecord; - storageRecord.metaRecord = m_contentMeta[i].GetContentMetaKey(); - storageRecord.storageId = m_destStorageId; - storageRecords.push_back(storageRecord); - - // Replace the existing application records with our own - try - { - nsDeleteApplicationRecord(baseTitleId); - } - catch (...) {} - - LOG_DEBUG("Pushing application record...\n"); - ASSERT_OK(nsPushApplicationRecord(baseTitleId, 0x3, storageRecords.data(), storageRecords.size() * sizeof(ContentStorageRecord)), "Failed to push application record"); - } - - // Validate and obtain all data needed for install - void Install::Prepare() - { - tin::data::ByteBuffer cnmtBuf; - - std::vector> tupelList = this->ReadCNMT(); - - for (size_t i = 0; i < tupelList.size(); i++) { - std::tuple cnmtTuple = tupelList[i]; - - m_contentMeta.push_back(std::get<0>(cnmtTuple)); - NcmContentInfo cnmtContentRecord = std::get<1>(cnmtTuple); - - nx::ncm::ContentStorage contentStorage(m_destStorageId); - - if (!contentStorage.Has(cnmtContentRecord.content_id)) - { - LOG_DEBUG("Installing CNMT NCA...\n"); - this->InstallNCA(cnmtContentRecord.content_id); - } - else - { - LOG_DEBUG("CNMT NCA already installed. Proceeding...\n"); - } - - // Parse data and create install content meta - if (m_ignoreReqFirmVersion) - LOG_DEBUG("WARNING: Required system firmware version is being IGNORED!\n"); - - tin::data::ByteBuffer installContentMetaBuf; - m_contentMeta[i].GetInstallContentMeta(installContentMetaBuf, cnmtContentRecord, m_ignoreReqFirmVersion); - - this->InstallContentMetaRecords(installContentMetaBuf, i); - this->InstallApplicationRecord(i); - } - } - - void Install::Begin() - { - LOG_DEBUG("Installing ticket and cert...\n"); - try - { - this->InstallTicketCert(); - } - catch (std::runtime_error& e) - { - LOG_DEBUG("WARNING: Ticket installation failed! This may not be an issue, depending on your use case.\nProceed with caution!\n"); - } - - for (nx::ncm::ContentMeta contentMeta: m_contentMeta) { - LOG_DEBUG("Installing NCAs...\n"); - for (auto& record : contentMeta.GetContentInfos()) - { - LOG_DEBUG("Installing from %s\n", tin::util::GetNcaIdString(record.content_id).c_str()); - this->InstallNCA(record.content_id); - } - } - } - - u64 Install::GetTitleId(int i) - { - return m_contentMeta[i].GetContentMetaKey().id; - } - - NcmContentMetaType Install::GetContentMetaType(int i) - { - return static_cast(m_contentMeta[i].GetContentMetaKey().type); - } -} diff --git a/source/install/install_nsp.cpp b/source/install/install_nsp.cpp deleted file mode 100644 index 630b882..0000000 --- a/source/install/install_nsp.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/install_nsp.hpp" - -#include -#include - -#include "install/nca.hpp" -#include "nx/fs.hpp" -#include "nx/ncm.hpp" -#include "util/config.hpp" -#include "util/crypto.hpp" -#include "util/file_util.hpp" -#include "util/title_util.hpp" -#include "util/debug.h" -#include "util/error.hpp" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "ui/MainApplication.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace tin::install::nsp -{ - NSPInstall::NSPInstall(NcmStorageId destStorageId, bool ignoreReqFirmVersion, const std::shared_ptr& remoteNSP) : - Install(destStorageId, ignoreReqFirmVersion), m_NSP(remoteNSP) - { - m_NSP->RetrieveHeader(); - } - - std::vector> NSPInstall::ReadCNMT() - { - std::vector> CNMTList; - - for (const PFS0FileEntry* fileEntry : m_NSP->GetFileEntriesByExtension("cnmt.nca")) { - std::string cnmtNcaName(m_NSP->GetFileEntryName(fileEntry)); - NcmContentId cnmtContentId = tin::util::GetNcaIdFromString(cnmtNcaName); - size_t cnmtNcaSize = fileEntry->fileSize; - - nx::ncm::ContentStorage contentStorage(m_destStorageId); - - LOG_DEBUG("CNMT Name: %s\n", cnmtNcaName.c_str()); - - // We install the cnmt nca early to read from it later - this->InstallNCA(cnmtContentId); - std::string cnmtNCAFullPath = contentStorage.GetPath(cnmtContentId); - - NcmContentInfo cnmtContentInfo; - cnmtContentInfo.content_id = cnmtContentId; - *(u64*)&cnmtContentInfo.size = cnmtNcaSize & 0xFFFFFFFFFFFF; - cnmtContentInfo.content_type = NcmContentType_Meta; - - CNMTList.push_back( { tin::util::GetContentMetaFromNCA(cnmtNCAFullPath), cnmtContentInfo } ); - } - - return CNMTList; - } - - void NSPInstall::InstallNCA(const NcmContentId& ncaId) - { - const PFS0FileEntry* fileEntry = m_NSP->GetFileEntryByNcaId(ncaId); - std::string ncaFileName = m_NSP->GetFileEntryName(fileEntry); - - #ifdef NXLINK_DEBUG - size_t ncaSize = fileEntry->fileSize; - LOG_DEBUG("Installing %s to storage Id %u\n", ncaFileName.c_str(), m_destStorageId); - #endif - - std::shared_ptr contentStorage(new nx::ncm::ContentStorage(m_destStorageId)); - - // Attempt to delete any leftover placeholders - try { - contentStorage->DeletePlaceholder(*(NcmPlaceHolderId*)&ncaId); - } - catch (...) {} - // Attempt to delete leftover ncas - try { - contentStorage->Delete(ncaId); - } - catch (...) {} - - LOG_DEBUG("Size: 0x%lx\n", ncaSize); - - if (inst::config::validateNCAs && !m_declinedValidation) - { - tin::install::NcaHeader* header = new NcaHeader; - m_NSP->BufferData(header, m_NSP->GetDataOffset() + fileEntry->dataOffset, sizeof(tin::install::NcaHeader)); - - Crypto::AesXtr crypto(Crypto::Keys().headerKey, false); - crypto.decrypt(header, header, sizeof(tin::install::NcaHeader), 0, 0x200); - - if (header->magic != MAGIC_NCA3) - THROW_FORMAT("Invalid NCA magic"); - - if (!Crypto::rsa2048PssVerify(&header->magic, 0x200, header->fixed_key_sig, Crypto::NCAHeaderSignature)) - { - std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav"); - int rc = inst::ui::mainApp->CreateShowDialog("inst.nca_verify.title"_lang, "inst.nca_verify.desc"_lang, {"common.cancel"_lang, "inst.nca_verify.opt1"_lang}, false); - audioThread.join(); - if (rc != 1) - THROW_FORMAT(("inst.nca_verify.error"_lang + tin::util::GetNcaIdString(ncaId)).c_str()); - m_declinedValidation = true; - } - delete header; - } - - m_NSP->StreamToPlaceholder(contentStorage, ncaId); - - LOG_DEBUG("Registering placeholder...\n"); - - try - { - contentStorage->Register(*(NcmPlaceHolderId*)&ncaId, ncaId); - } - catch (...) - { - LOG_DEBUG(("Failed to register " + ncaFileName + ". It may already exist.\n").c_str()); - } - - try - { - contentStorage->DeletePlaceholder(*(NcmPlaceHolderId*)&ncaId); - } - catch (...) {} - } - - void NSPInstall::InstallTicketCert() - { - // Read the tik files and put it into a buffer - std::vector tikFileEntries = m_NSP->GetFileEntriesByExtension("tik"); - std::vector certFileEntries = m_NSP->GetFileEntriesByExtension("cert"); - - for (size_t i = 0; i < tikFileEntries.size(); i++) - { - if (tikFileEntries[i] == nullptr) { - LOG_DEBUG("Remote tik file is missing.\n"); - THROW_FORMAT("Remote tik file is not present!"); - } - - u64 tikSize = tikFileEntries[i]->fileSize; - auto tikBuf = std::make_unique(tikSize); - LOG_DEBUG("> Reading tik\n"); - m_NSP->BufferData(tikBuf.get(), m_NSP->GetDataOffset() + tikFileEntries[i]->dataOffset, tikSize); - - if (certFileEntries[i] == nullptr) - { - LOG_DEBUG("Remote cert file is missing.\n"); - THROW_FORMAT("Remote cert file is not present!"); - } - - u64 certSize = certFileEntries[i]->fileSize; - auto certBuf = std::make_unique(certSize); - LOG_DEBUG("> Reading cert\n"); - m_NSP->BufferData(certBuf.get(), m_NSP->GetDataOffset() + certFileEntries[i]->dataOffset, certSize); - - // Finally, let's actually import the ticket - ASSERT_OK(esImportTicket(tikBuf.get(), tikSize, certBuf.get(), certSize), "Failed to import ticket"); - } - } -} \ No newline at end of file diff --git a/source/install/install_xci.cpp b/source/install/install_xci.cpp deleted file mode 100644 index 2ce6469..0000000 --- a/source/install/install_xci.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include - -#include "install/install_xci.hpp" -#include "util/file_util.hpp" -#include "util/title_util.hpp" -#include "util/debug.h" -#include "util/error.hpp" -#include "util/config.hpp" -#include "util/crypto.hpp" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "install/nca.hpp" -#include "ui/MainApplication.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace tin::install::xci -{ - XCIInstallTask::XCIInstallTask(NcmStorageId destStorageId, bool ignoreReqFirmVersion, const std::shared_ptr& xci) : - Install(destStorageId, ignoreReqFirmVersion), m_xci(xci) - { - m_xci->RetrieveHeader(); - } - - std::vector> XCIInstallTask::ReadCNMT() - { - std::vector> CNMTList; - - for (const HFS0FileEntry* fileEntry : m_xci->GetFileEntriesByExtension("cnmt.nca")) { - std::string cnmtNcaName(m_xci->GetFileEntryName(fileEntry)); - NcmContentId cnmtContentId = tin::util::GetNcaIdFromString(cnmtNcaName); - size_t cnmtNcaSize = fileEntry->fileSize; - - nx::ncm::ContentStorage contentStorage(m_destStorageId); - - LOG_DEBUG("CNMT Name: %s\n", cnmtNcaName.c_str()); - - // We install the cnmt nca early to read from it later - this->InstallNCA(cnmtContentId); - std::string cnmtNCAFullPath = contentStorage.GetPath(cnmtContentId); - - NcmContentInfo cnmtContentInfo; - cnmtContentInfo.content_id = cnmtContentId; - *(u64*)&cnmtContentInfo.size = cnmtNcaSize & 0xFFFFFFFFFFFF; - cnmtContentInfo.content_type = NcmContentType_Meta; - - CNMTList.push_back( { tin::util::GetContentMetaFromNCA(cnmtNCAFullPath), cnmtContentInfo } ); - } - - return CNMTList; - } - - void XCIInstallTask::InstallNCA(const NcmContentId& ncaId) - { - const HFS0FileEntry* fileEntry = m_xci->GetFileEntryByNcaId(ncaId); - std::string ncaFileName = m_xci->GetFileEntryName(fileEntry); - - #ifdef NXLINK_DEBUG - size_t ncaSize = fileEntry->fileSize; - LOG_DEBUG("Installing %s to storage Id %u\n", ncaFileName.c_str(), m_destStorageId); - #endif - - std::shared_ptr contentStorage(new nx::ncm::ContentStorage(m_destStorageId)); - - // Attempt to delete any leftover placeholders - try { - contentStorage->DeletePlaceholder(*(NcmPlaceHolderId*)&ncaId); - } - catch (...) {} - // Attempt to delete leftover ncas - try { - contentStorage->Delete(ncaId); - } - catch (...) {} - - LOG_DEBUG("Size: 0x%lx\n", ncaSize); - - if (inst::config::validateNCAs && !m_declinedValidation) - { - tin::install::NcaHeader* header = new NcaHeader; - m_xci->BufferData(header, m_xci->GetDataOffset() + fileEntry->dataOffset, sizeof(tin::install::NcaHeader)); - - Crypto::AesXtr crypto(Crypto::Keys().headerKey, false); - crypto.decrypt(header, header, sizeof(tin::install::NcaHeader), 0, 0x200); - - if (header->magic != MAGIC_NCA3) - THROW_FORMAT("Invalid NCA magic"); - - if (!Crypto::rsa2048PssVerify(&header->magic, 0x200, header->fixed_key_sig, Crypto::NCAHeaderSignature)) - { - std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav"); - int rc = inst::ui::mainApp->CreateShowDialog("inst.nca_verify.title"_lang, "inst.nca_verify.desc"_lang, {"common.cancel"_lang, "inst.nca_verify.opt1"_lang}, false); - audioThread.join(); - if (rc != 1) - THROW_FORMAT(("inst.nca_verify.error"_lang + tin::util::GetNcaIdString(ncaId)).c_str()); - m_declinedValidation = true; - } - delete header; - } - - m_xci->StreamToPlaceholder(contentStorage, ncaId); - - // Clean up the line for whatever comes next - LOG_DEBUG(" \r"); - LOG_DEBUG("Registering placeholder...\n"); - - try - { - contentStorage->Register(*(NcmPlaceHolderId*)&ncaId, ncaId); - } - catch (...) - { - LOG_DEBUG(("Failed to register " + ncaFileName + ". It may already exist.\n").c_str()); - } - - try - { - contentStorage->DeletePlaceholder(*(NcmPlaceHolderId*)&ncaId); - } - catch (...) {} - } - - void XCIInstallTask::InstallTicketCert() - { - // Read the tik files and put it into a buffer - std::vector tikFileEntries = m_xci->GetFileEntriesByExtension("tik"); - std::vector certFileEntries = m_xci->GetFileEntriesByExtension("cert"); - - for (size_t i = 0; i < tikFileEntries.size(); i++) - { - if (tikFileEntries[i] == nullptr) - { - LOG_DEBUG("Remote tik file is missing.\n"); - THROW_FORMAT("Remote tik file is not present!"); - } - - u64 tikSize = tikFileEntries[i]->fileSize; - auto tikBuf = std::make_unique(tikSize); - LOG_DEBUG("> Reading tik\n"); - m_xci->BufferData(tikBuf.get(), m_xci->GetDataOffset() + tikFileEntries[i]->dataOffset, tikSize); - - if (certFileEntries[i] == nullptr) - { - LOG_DEBUG("Remote cert file is missing.\n"); - THROW_FORMAT("Remote cert file is not present!"); - } - - u64 certSize = certFileEntries[i]->fileSize; - auto certBuf = std::make_unique(certSize); - LOG_DEBUG("> Reading cert\n"); - m_xci->BufferData(certBuf.get(), m_xci->GetDataOffset() + certFileEntries[i]->dataOffset, certSize); - - // Finally, let's actually import the ticket - ASSERT_OK(esImportTicket(tikBuf.get(), tikSize, certBuf.get(), certSize), "Failed to import ticket"); - } - } -} \ No newline at end of file diff --git a/source/install/nsp.cpp b/source/install/nsp.cpp deleted file mode 100644 index c2f4de0..0000000 --- a/source/install/nsp.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/nsp.hpp" - -#include -#include "data/buffered_placeholder_writer.hpp" -#include "util/title_util.hpp" -#include "util/error.hpp" -#include "util/debug.h" - -namespace tin::install::nsp -{ - NSP::NSP() {} - - // TODO: Do verification: PFS0 magic, sizes not zero - void NSP::RetrieveHeader() - { - LOG_DEBUG("Retrieving remote NSP header...\n"); - - // Retrieve the base header - m_headerBytes.resize(sizeof(PFS0BaseHeader), 0); - this->BufferData(m_headerBytes.data(), 0x0, sizeof(PFS0BaseHeader)); - - LOG_DEBUG("Base header: \n"); - printBytes(m_headerBytes.data(), sizeof(PFS0BaseHeader), true); - - // Retrieve the full header - size_t remainingHeaderSize = this->GetBaseHeader()->numFiles * sizeof(PFS0FileEntry) + this->GetBaseHeader()->stringTableSize; - m_headerBytes.resize(sizeof(PFS0BaseHeader) + remainingHeaderSize, 0); - this->BufferData(m_headerBytes.data() + sizeof(PFS0BaseHeader), sizeof(PFS0BaseHeader), remainingHeaderSize); - - LOG_DEBUG("Full header: \n"); - printBytes(m_headerBytes.data(), m_headerBytes.size(), true); - } - - const PFS0FileEntry* NSP::GetFileEntry(unsigned int index) - { - if (index >= this->GetBaseHeader()->numFiles) - THROW_FORMAT("File entry index is out of bounds\n") - - size_t fileEntryOffset = sizeof(PFS0BaseHeader) + index * sizeof(PFS0FileEntry); - - if (m_headerBytes.size() < fileEntryOffset + sizeof(PFS0FileEntry)) - THROW_FORMAT("Header bytes is too small to get file entry!"); - - return reinterpret_cast(m_headerBytes.data() + fileEntryOffset); - } - - std::vector NSP::GetFileEntriesByExtension(std::string extension) - { - std::vector entryList; - - for (unsigned int i = 0; i < this->GetBaseHeader()->numFiles; i++) - { - const PFS0FileEntry* fileEntry = this->GetFileEntry(i); - std::string name(this->GetFileEntryName(fileEntry)); - auto foundExtension = name.substr(name.find(".") + 1); - - if (foundExtension == extension) - entryList.push_back(fileEntry); - } - - return entryList; - } - - const PFS0FileEntry* NSP::GetFileEntryByName(std::string name) - { - for (unsigned int i = 0; i < this->GetBaseHeader()->numFiles; i++) - { - const PFS0FileEntry* fileEntry = this->GetFileEntry(i); - std::string foundName(this->GetFileEntryName(fileEntry)); - - if (foundName == name) - return fileEntry; - } - - return nullptr; - } - - const PFS0FileEntry* NSP::GetFileEntryByNcaId(const NcmContentId& ncaId) - { - const PFS0FileEntry* fileEntry = nullptr; - std::string ncaIdStr = tin::util::GetNcaIdString(ncaId); - - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".nca")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".cnmt.nca")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".ncz")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".cnmt.ncz")) == nullptr) - { - return nullptr; - } - } - } - } - - return fileEntry; - } - - const char* NSP::GetFileEntryName(const PFS0FileEntry* fileEntry) - { - u64 stringTableStart = sizeof(PFS0BaseHeader) + this->GetBaseHeader()->numFiles * sizeof(PFS0FileEntry); - return reinterpret_cast(m_headerBytes.data() + stringTableStart + fileEntry->stringTableOffset); - } - - const PFS0BaseHeader* NSP::GetBaseHeader() - { - if (m_headerBytes.empty()) - THROW_FORMAT("Cannot retrieve header as header bytes are empty. Have you retrieved it yet?\n"); - - return reinterpret_cast(m_headerBytes.data()); - } - - u64 NSP::GetDataOffset() - { - if (m_headerBytes.empty()) - THROW_FORMAT("Cannot get data offset as header is empty. Have you retrieved it yet?\n"); - - return m_headerBytes.size(); - } -} \ No newline at end of file diff --git a/source/install/sdmc_nsp.cpp b/source/install/sdmc_nsp.cpp deleted file mode 100644 index e8d7b66..0000000 --- a/source/install/sdmc_nsp.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "install/sdmc_nsp.hpp" -#include "error.hpp" -#include "debug.h" -#include "nx/nca_writer.h" -#include "ui/instPage.hpp" -#include "util/lang.hpp" - -namespace tin::install::nsp -{ - SDMCNSP::SDMCNSP(std::string path) - { - m_nspFile = fopen((path).c_str(), "rb"); - if (!m_nspFile) - THROW_FORMAT("can't open file at %s\n", path.c_str()); - } - - SDMCNSP::~SDMCNSP() - { - fclose(m_nspFile); - } - - void SDMCNSP::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId ncaId) - { - const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(ncaId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - NcaWriter writer(ncaId, contentStorage); - - float progress; - - u64 fileStart = GetDataOffset() + fileEntry->dataOffset; - u64 fileOff = 0; - size_t readSize = 0x400000; // 4MB buff - auto readBuffer = std::make_unique(readSize); - - try - { - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (fileOff < ncaSize) - { - progress = (float) fileOff / (float) ncaSize; - - if (fileOff % (0x400000 * 3) == 0) { - LOG_DEBUG("> Progress: %lu/%lu MB (%d%s)\r", (fileOff / 1000000), (ncaSize / 1000000), (int)(progress * 100.0), "%"); - inst::ui::instPage::setInstBarPerc((double)(progress * 100.0)); - } - - if (fileOff + readSize >= ncaSize) readSize = ncaSize - fileOff; - - this->BufferData(readBuffer.get(), fileOff + fileStart, readSize); - writer.write(readBuffer.get(), readSize); - - fileOff += readSize; - } - inst::ui::instPage::setInstBarPerc(100); - } - catch (std::exception& e) - { - LOG_DEBUG("something went wrong: %s\n", e.what()); - } - - writer.close(); - } - - void SDMCNSP::BufferData(void* buf, off_t offset, size_t size) - { - fseeko(m_nspFile, offset, SEEK_SET); - //fseek(m_nspFile, offset, SEEK_SET); - fread(buf, 1, size, m_nspFile); - } -} diff --git a/source/install/sdmc_xci.cpp b/source/install/sdmc_xci.cpp deleted file mode 100644 index ae7e530..0000000 --- a/source/install/sdmc_xci.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "install/sdmc_xci.hpp" -#include "error.hpp" -#include "debug.h" -#include "nx/nca_writer.h" -#include "ui/instPage.hpp" -#include "util/lang.hpp" - -namespace tin::install::xci -{ - SDMCXCI::SDMCXCI(std::string path) - { - m_xciFile = fopen((path).c_str(), "rb"); - if (!m_xciFile) - THROW_FORMAT("can't open file at %s\n", path.c_str()); - } - - SDMCXCI::~SDMCXCI() - { - fclose(m_xciFile); - } - - void SDMCXCI::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId ncaId) - { - const HFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(ncaId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - NcaWriter writer(ncaId, contentStorage); - - float progress; - - u64 fileStart = GetDataOffset() + fileEntry->dataOffset; - u64 fileOff = 0; - size_t readSize = 0x400000; // 4MB buff - auto readBuffer = std::make_unique(readSize); - - try - { - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (fileOff < ncaSize) - { - progress = (float) fileOff / (float) ncaSize; - - if (fileOff % (0x400000 * 3) == 0) { - LOG_DEBUG("> Progress: %lu/%lu MB (%d%s)\r", (fileOff / 1000000), (ncaSize / 1000000), (int)(progress * 100.0), "%"); - inst::ui::instPage::setInstBarPerc((double)(progress * 100.0)); - } - - if (fileOff + readSize >= ncaSize) readSize = ncaSize - fileOff; - - this->BufferData(readBuffer.get(), fileOff + fileStart, readSize); - writer.write(readBuffer.get(), readSize); - - fileOff += readSize; - } - inst::ui::instPage::setInstBarPerc(100); - } - catch (std::exception& e) - { - LOG_DEBUG("something went wrong: %s\n", e.what()); - } - - writer.close(); - } - - void SDMCXCI::BufferData(void* buf, off_t offset, size_t size) - { - fseeko(m_xciFile, offset, SEEK_SET); - //fseek(m_xciFile, offset, SEEK_SET); - fread(buf, 1, size, m_xciFile); - } -} \ No newline at end of file diff --git a/source/install/simple_filesystem.cpp b/source/install/simple_filesystem.cpp deleted file mode 100644 index dce06df..0000000 --- a/source/install/simple_filesystem.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/simple_filesystem.hpp" - -#include -#include -#include "nx/fs.hpp" -#include "util/error.hpp" - -namespace tin::install::nsp -{ - SimpleFileSystem::SimpleFileSystem(nx::fs::IFileSystem& fileSystem, std::string rootPath, std::string absoluteRootPath) : - m_fileSystem(&fileSystem) , m_rootPath(rootPath), m_absoluteRootPath(absoluteRootPath) - {} - - SimpleFileSystem::~SimpleFileSystem() {} - - nx::fs::IFile SimpleFileSystem::OpenFile(std::string path) - { - return m_fileSystem->OpenFile(m_rootPath + path); - } - - bool SimpleFileSystem::HasFile(std::string path) - { - try - { - LOG_DEBUG(("Attempting to find file at " + m_rootPath + path + "\n").c_str()); - m_fileSystem->OpenFile(m_rootPath + path); - return true; - } - catch (std::exception& e) {} - return false; - } - - std::string SimpleFileSystem::GetFileNameFromExtension(std::string path, std::string extension) - { - nx::fs::IDirectory dir = m_fileSystem->OpenDirectory(m_rootPath + path, FsDirOpenMode_ReadFiles | FsDirOpenMode_ReadDirs); - - u64 entryCount = dir.GetEntryCount(); - auto dirEntries = std::make_unique(entryCount); - - dir.Read(0, dirEntries.get(), entryCount); - - for (unsigned int i = 0; i < entryCount; i++) - { - FsDirectoryEntry dirEntry = dirEntries[i]; - std::string dirEntryName = dirEntry.name; - - if (dirEntry.type == FsDirEntryType_Dir) - { - auto subdirPath = path + dirEntryName + "/"; - auto subdirFound = this->GetFileNameFromExtension(subdirPath, extension); - - if (subdirFound != "") - return subdirFound; - continue; - } - else if (dirEntry.type == FsDirEntryType_File) - { - auto foundExtension = dirEntryName.substr(dirEntryName.find(".") + 1); - - if (foundExtension == extension) - return dirEntryName; - } - } - - return ""; - } -} \ No newline at end of file diff --git a/source/install/usb_nsp.cpp b/source/install/usb_nsp.cpp deleted file mode 100644 index 384b358..0000000 --- a/source/install/usb_nsp.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/usb_nsp.hpp" - -#include -#include -#include -#include -#include "data/byte_buffer.hpp" -#include "data/buffered_placeholder_writer.hpp" -#include "util/usb_util.hpp" -#include "util/error.hpp" -#include "util/debug.h" -#include "util/util.hpp" -#include "util/usb_comms_tinleaf.h" -#include "util/lang.hpp" -#include "ui/instPage.hpp" - - -namespace tin::install::nsp -{ - bool stopThreadsUsbNsp; - std::string errorMessageUsbNsp; - - USBNSP::USBNSP(std::string nspName) : - m_nspName(nspName) - { - - } - - struct USBFuncArgs - { - std::string nspName; - tin::data::BufferedPlaceholderWriter* bufferedPlaceholderWriter; - u64 pfs0Offset; - u64 ncaSize; - }; - - int USBThreadFunc(void* in) - { - USBFuncArgs* args = reinterpret_cast(in); - tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(args->nspName, args->pfs0Offset, args->ncaSize); - - u8* buf = (u8*)memalign(0x1000, 0x800000); - u64 sizeRemaining = header.dataSize; - size_t tmpSizeRead = 0; - - try - { - while (sizeRemaining && !stopThreadsUsbNsp) - { - tmpSizeRead = tinleaf_usbCommsRead(buf, std::min(sizeRemaining, (u64)0x800000), 5000000000); - if (tmpSizeRead == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str()); - sizeRemaining -= tmpSizeRead; - - while (true) - { - if (args->bufferedPlaceholderWriter->CanAppendData(tmpSizeRead)) - break; - } - - args->bufferedPlaceholderWriter->AppendData(buf, tmpSizeRead); - } - } - catch (std::exception& e) - { - stopThreadsUsbNsp = true; - errorMessageUsbNsp = e.what(); - } - - free(buf); - - return 0; - } - - int USBPlaceholderWriteFunc(void* in) - { - USBFuncArgs* args = reinterpret_cast(in); - - while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete() && !stopThreadsUsbNsp) - { - if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder()) - args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder(); - } - - return 0; - } - - void USBNSP::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId placeholderId) - { - const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - tin::data::BufferedPlaceholderWriter bufferedPlaceholderWriter(contentStorage, placeholderId, ncaSize); - USBFuncArgs args; - args.nspName = m_nspName; - args.bufferedPlaceholderWriter = &bufferedPlaceholderWriter; - args.pfs0Offset = this->GetDataOffset() + fileEntry->dataOffset; - args.ncaSize = ncaSize; - thrd_t usbThread; - thrd_t writeThread; - - stopThreadsUsbNsp = false; - thrd_create(&usbThread, USBThreadFunc, &args); - thrd_create(&writeThread, USBPlaceholderWriteFunc, &args); - - u64 freq = armGetSystemTickFreq(); - u64 startTime = armGetSystemTick(); - size_t startSizeBuffered = 0; - double speed = 0.0; - - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsBufferDataComplete() && !stopThreadsUsbNsp) - { - u64 newTime = armGetSystemTick(); - - if (newTime - startTime >= freq) - { - size_t newSizeBuffered = bufferedPlaceholderWriter.GetSizeBuffered(); - double mbBuffered = (newSizeBuffered / 1000000.0) - (startSizeBuffered / 1000000.0); - double duration = ((double)(newTime - startTime) / (double)freq); - speed = mbBuffered / duration; - - startTime = newTime; - startSizeBuffered = newSizeBuffered; - int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000; - LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed); - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s"); - inst::ui::instPage::setInstBarPerc((double)downloadProgress); - } - } - inst::ui::instPage::setInstBarPerc(100); - - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsUsbNsp) - { - int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000; - LOG_DEBUG("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%"); - #endif - inst::ui::instPage::setInstBarPerc((double)installProgress); - } - inst::ui::instPage::setInstBarPerc(100); - - thrd_join(usbThread, NULL); - thrd_join(writeThread, NULL); - if (stopThreadsUsbNsp) throw std::runtime_error(errorMessageUsbNsp.c_str()); - } - - void USBNSP::BufferData(void* buf, off_t offset, size_t size) - { - LOG_DEBUG("buffering 0x%lx-0x%lx\n", offset, offset + size); - tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_nspName, offset, size); - u8* tempBuffer = (u8*)memalign(0x1000, header.dataSize); - if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str()); - memcpy(buf, tempBuffer, header.dataSize); - free(tempBuffer); - } -} \ No newline at end of file diff --git a/source/install/usb_xci.cpp b/source/install/usb_xci.cpp deleted file mode 100644 index c1e0767..0000000 --- a/source/install/usb_xci.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/usb_xci.hpp" - -#include -#include -#include -#include -#include "data/byte_buffer.hpp" -#include "data/buffered_placeholder_writer.hpp" -#include "util/usb_util.hpp" -#include "util/error.hpp" -#include "util/debug.h" -#include "util/util.hpp" -#include "util/usb_comms_tinleaf.h" -#include "util/lang.hpp" -#include "ui/instPage.hpp" - -namespace tin::install::xci -{ - bool stopThreadsUsbXci; - std::string errorMessageUsbXci; - - USBXCI::USBXCI(std::string xciName) : - m_xciName(xciName) - { - - } - - struct USBFuncArgs - { - std::string xciName; - tin::data::BufferedPlaceholderWriter* bufferedPlaceholderWriter; - u64 hfs0Offset; - u64 ncaSize; - }; - - int USBThreadFunc(void* in) - { - USBFuncArgs* args = reinterpret_cast(in); - tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(args->xciName, args->hfs0Offset, args->ncaSize); - - u8* buf = (u8*)memalign(0x1000, 0x800000); - u64 sizeRemaining = header.dataSize; - size_t tmpSizeRead = 0; - - try - { - while (sizeRemaining && !stopThreadsUsbXci) - { - tmpSizeRead = tinleaf_usbCommsRead(buf, std::min(sizeRemaining, (u64)0x800000), 5000000000); - if (tmpSizeRead == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str()); - sizeRemaining -= tmpSizeRead; - - while (true) - { - if (args->bufferedPlaceholderWriter->CanAppendData(tmpSizeRead)) - break; - } - - args->bufferedPlaceholderWriter->AppendData(buf, tmpSizeRead); - } - } - catch (std::exception& e) - { - stopThreadsUsbXci = true; - errorMessageUsbXci = e.what(); - } - - free(buf); - - return 0; - } - - int USBPlaceholderWriteFunc(void* in) - { - USBFuncArgs* args = reinterpret_cast(in); - - while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete() && !stopThreadsUsbXci) - { - if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder()) - args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder(); - } - - return 0; - } - - void USBXCI::StreamToPlaceholder(std::shared_ptr& contentStorage, NcmContentId placeholderId) - { - const HFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId); - std::string ncaFileName = this->GetFileEntryName(fileEntry); - - LOG_DEBUG("Retrieving %s\n", ncaFileName.c_str()); - size_t ncaSize = fileEntry->fileSize; - - tin::data::BufferedPlaceholderWriter bufferedPlaceholderWriter(contentStorage, placeholderId, ncaSize); - USBFuncArgs args; - args.xciName = m_xciName; - args.bufferedPlaceholderWriter = &bufferedPlaceholderWriter; - args.hfs0Offset = this->GetDataOffset() + fileEntry->dataOffset; - args.ncaSize = ncaSize; - thrd_t usbThread; - thrd_t writeThread; - - stopThreadsUsbXci = false; - thrd_create(&usbThread, USBThreadFunc, &args); - thrd_create(&writeThread, USBPlaceholderWriteFunc, &args); - - u64 freq = armGetSystemTickFreq(); - u64 startTime = armGetSystemTick(); - size_t startSizeBuffered = 0; - double speed = 0.0; - - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsBufferDataComplete() && !stopThreadsUsbXci) - { - u64 newTime = armGetSystemTick(); - - if (newTime - startTime >= freq) - { - size_t newSizeBuffered = bufferedPlaceholderWriter.GetSizeBuffered(); - double mbBuffered = (newSizeBuffered / 1000000.0) - (startSizeBuffered / 1000000.0); - double duration = ((double)(newTime - startTime) / (double)freq); - speed = mbBuffered / duration; - - startTime = newTime; - startSizeBuffered = newSizeBuffered; - int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000; - LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed); - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s"); - inst::ui::instPage::setInstBarPerc((double)downloadProgress); - } - } - inst::ui::instPage::setInstBarPerc(100); - - #ifdef NXLINK_DEBUG - u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000; - #endif - - inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "..."); - inst::ui::instPage::setInstBarPerc(0); - while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsUsbXci) - { - int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0); - #ifdef NXLINK_DEBUG - u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000; - LOG_DEBUG("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%"); - #endif - inst::ui::instPage::setInstBarPerc((double)installProgress); - } - inst::ui::instPage::setInstBarPerc(100); - - thrd_join(usbThread, NULL); - thrd_join(writeThread, NULL); - if (stopThreadsUsbXci) throw std::runtime_error(errorMessageUsbXci.c_str()); - } - - void USBXCI::BufferData(void* buf, off_t offset, size_t size) - { - LOG_DEBUG("buffering 0x%lx-0x%lx\n", offset, offset + size); - tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_xciName, offset, size); - u8* tempBuffer = (u8*)memalign(0x1000, header.dataSize); - if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str()); - memcpy(buf, tempBuffer, header.dataSize); - free(tempBuffer); - } -} \ No newline at end of file diff --git a/source/install/xci.cpp b/source/install/xci.cpp deleted file mode 100644 index e95f8f6..0000000 --- a/source/install/xci.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "install/xci.hpp" -#include "util/title_util.hpp" -#include "error.hpp" -#include "debug.h" - -namespace tin::install::xci -{ - XCI::XCI() - { - } - - void XCI::RetrieveHeader() - { - LOG_DEBUG("Retrieving HFS0 header...\n"); - - // Retrieve hfs0 offset - u64 hfs0Offset = 0xf000; - - // Retrieve main hfs0 header - std::vector m_headerBytes; - m_headerBytes.resize(sizeof(HFS0BaseHeader), 0); - this->BufferData(m_headerBytes.data(), hfs0Offset, sizeof(HFS0BaseHeader)); - - LOG_DEBUG("Base header: \n"); - printBytes(m_headerBytes.data(), sizeof(HFS0BaseHeader), true); - - // Retrieve full header - HFS0BaseHeader *header = reinterpret_cast(m_headerBytes.data()); - if (header->magic != MAGIC_HFS0) - THROW_FORMAT("hfs0 magic doesn't match at 0x%lx\n", hfs0Offset); - - size_t remainingHeaderSize = header->numFiles * sizeof(HFS0FileEntry) + header->stringTableSize; - m_headerBytes.resize(sizeof(HFS0BaseHeader) + remainingHeaderSize, 0); - this->BufferData(m_headerBytes.data() + sizeof(HFS0BaseHeader), hfs0Offset + sizeof(HFS0BaseHeader), remainingHeaderSize); - - LOG_DEBUG("Base header: \n"); - printBytes(m_headerBytes.data(), sizeof(HFS0BaseHeader) + remainingHeaderSize, true); - - // Find Secure partition - header = reinterpret_cast(m_headerBytes.data()); - for (unsigned int i = 0; i < header->numFiles; i++) - { - const HFS0FileEntry *entry = hfs0GetFileEntry(header, i); - std::string entryName(hfs0GetFileName(header, entry)); - - if (entryName != "secure") - continue; - - m_secureHeaderOffset = hfs0Offset + remainingHeaderSize + 0x10 + entry->dataOffset; - m_secureHeaderBytes.resize(sizeof(HFS0BaseHeader), 0); - this->BufferData(m_secureHeaderBytes.data(), m_secureHeaderOffset, sizeof(HFS0BaseHeader)); - - LOG_DEBUG("Secure header: \n"); - printBytes(m_secureHeaderBytes.data(), sizeof(HFS0BaseHeader), true); - - if (this->GetSecureHeader()->magic != MAGIC_HFS0) - THROW_FORMAT("hfs0 magic doesn't match at 0x%lx\n", m_secureHeaderOffset); - - // Retrieve full header - remainingHeaderSize = this->GetSecureHeader()->numFiles * sizeof(HFS0FileEntry) + this->GetSecureHeader()->stringTableSize; - m_secureHeaderBytes.resize(sizeof(HFS0BaseHeader) + remainingHeaderSize, 0); - this->BufferData(m_secureHeaderBytes.data() + sizeof(HFS0BaseHeader), m_secureHeaderOffset + sizeof(HFS0BaseHeader), remainingHeaderSize); - - LOG_DEBUG("Base header: \n"); - printBytes(m_secureHeaderBytes.data(), sizeof(HFS0BaseHeader) + remainingHeaderSize, true); - return; - } - THROW_FORMAT("couldn't optain secure hfs0 header\n"); - } - - const HFS0BaseHeader* XCI::GetSecureHeader() - { - if (m_secureHeaderBytes.empty()) - THROW_FORMAT("Cannot retrieve header as header bytes are empty. Have you retrieved it yet?\n"); - - return reinterpret_cast(m_secureHeaderBytes.data()); - } - - u64 XCI::GetDataOffset() - { - if (m_secureHeaderBytes.empty()) - THROW_FORMAT("Cannot get data offset as header is empty. Have you retrieved it yet?\n"); - - return m_secureHeaderOffset + m_secureHeaderBytes.size(); - } - - const HFS0FileEntry* XCI::GetFileEntry(unsigned int index) - { - if (index >= this->GetSecureHeader()->numFiles) - THROW_FORMAT("File entry index is out of bounds\n") - - return hfs0GetFileEntry(this->GetSecureHeader(), index); - } - - const HFS0FileEntry* XCI::GetFileEntryByName(std::string name) - { - for (unsigned int i = 0; i < this->GetSecureHeader()->numFiles; i++) - { - const HFS0FileEntry* fileEntry = this->GetFileEntry(i); - std::string foundName(this->GetFileEntryName(fileEntry)); - - if (foundName == name) - return fileEntry; - } - - return nullptr; - } - - const HFS0FileEntry* XCI::GetFileEntryByNcaId(const NcmContentId& ncaId) - { - const HFS0FileEntry* fileEntry = nullptr; - std::string ncaIdStr = tin::util::GetNcaIdString(ncaId); - - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".nca")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".cnmt.nca")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".ncz")) == nullptr) - { - if ((fileEntry = this->GetFileEntryByName(ncaIdStr + ".cnmt.ncz")) == nullptr) - { - return nullptr; - } - } - } - } - - return fileEntry; - } - - std::vector XCI::GetFileEntriesByExtension(std::string extension) - { - std::vector entryList; - - for (unsigned int i = 0; i < this->GetSecureHeader()->numFiles; i++) - { - const HFS0FileEntry* fileEntry = this->GetFileEntry(i); - std::string name(this->GetFileEntryName(fileEntry)); - auto foundExtension = name.substr(name.find(".") + 1); - - if (foundExtension == extension) - entryList.push_back(fileEntry); - } - - return entryList; - } - - const char* XCI::GetFileEntryName(const HFS0FileEntry* fileEntry) - { - return hfs0GetFileName(this->GetSecureHeader(), fileEntry); - } -} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp deleted file mode 100644 index 91f31e6..0000000 --- a/source/main.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "switch.h" -#include "util/error.hpp" -#include "ui/MainApplication.hpp" -#include "util/util.hpp" -#include "util/config.hpp" - -using namespace pu::ui::render; -int main(int argc, char* argv[]) -{ - inst::util::initApp(); - try { - //const auto default_font_path = ("romfs:/fonts/Roboto-Regular.ttf"); - auto renderer_opts = pu::ui::render::RendererInitOptions(SDL_INIT_EVERYTHING, pu::ui::render::RendererHardwareFlags); - renderer_opts.UseImage(pu::ui::render::IMGAllFlags); - renderer_opts.UseAudio(pu::ui::render::MixerAllFlags); - //renderer_opts.UseTTF(default_font_path); - renderer_opts.UseTTF(); - //renderer_opts.SetExtraDefaultFontSize(35); - renderer_opts.UseRomfs(); - auto renderer = pu::ui::render::Renderer::New(renderer_opts); - - auto main = inst::ui::MainApplication::New(renderer); - std::thread updateThread; - if (inst::config::autoUpdate && inst::util::getIPAddress() != "1.0.0.127") updateThread = std::thread(inst::util::checkForAppUpdate); - main->Prepare(); - main->ShowWithFadeIn(); - updateThread.join(); - } catch (std::exception& e) { - LOG_DEBUG("An error occurred:\n%s", e.what()); - } - inst::util::deinitApp(); - return 0; - } diff --git a/source/netInstall.cpp b/source/netInstall.cpp deleted file mode 100644 index f9884a0..0000000 --- a/source/netInstall.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "netInstall.hpp" -#include "install/install_nsp.hpp" -#include "install/http_nsp.hpp" -#include "install/install_xci.hpp" -#include "install/http_xci.hpp" -#include "install/install.hpp" -#include "util/error.hpp" -#include "util/network_util.hpp" -#include "util/config.hpp" -#include "util/util.hpp" -#include "util/curl.hpp" -#include "util/lang.hpp" -#include "ui/MainApplication.hpp" -#include "ui/instPage.hpp" - -const unsigned int MAX_URL_SIZE = 1024; -const unsigned int MAX_URLS = 256; -const int REMOTE_INSTALL_PORT = 2000; -static int m_serverSocket = 0; -static int m_clientSocket = 0; -bool netConnected = false; - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace netInstStuff{ - - void InitializeServerSocket() try - { - // Create a socket - m_serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - - if (m_serverSocket < -1) - { - THROW_FORMAT("Failed to create a server socket. Error code: %u\n", errno); - } - - struct sockaddr_in server; - server.sin_family = AF_INET; - server.sin_port = htons(REMOTE_INSTALL_PORT); - server.sin_addr.s_addr = htonl(INADDR_ANY); - - if (bind(m_serverSocket, (struct sockaddr*) &server, sizeof(server)) < 0) - { - THROW_FORMAT("Failed to bind server socket. Error code: %u\n", errno); - } - - // Set as non-blocking - fcntl(m_serverSocket, F_SETFL, fcntl(m_serverSocket, F_GETFL, 0) | O_NONBLOCK); - - if (listen(m_serverSocket, 5) < 0) - { - THROW_FORMAT("Failed to listen on server socket. Error code: %u\n", errno); - } - } - catch (std::exception& e) - { - LOG_DEBUG("Failed to initialize server socket!\n"); - fprintf(stdout, "%s", e.what()); - - if (m_serverSocket != 0) - { - close(m_serverSocket); - m_serverSocket = 0; - } - inst::ui::mainApp->CreateShowDialog("Failed to initialize server socket!", (std::string)e.what(), {"OK"}, true); - } - - void OnUnwound() - { - LOG_DEBUG("unwinding view\n"); - if (m_clientSocket != 0) - { - close(m_clientSocket); - m_clientSocket = 0; - } - - curl_global_cleanup(); - } - - void installTitleNet(std::vector ourUrlList, int ourStorage, std::vector urlListAltNames, std::string ourSource) - { - inst::util::initInstallServices(); - inst::ui::instPage::loadInstallScreen(); - bool nspInstalled = true; - NcmStorageId m_destStorageId = NcmStorageId_SdCard; - - if (ourStorage) m_destStorageId = NcmStorageId_BuiltInUser; - unsigned int urlItr; - - std::vector urlNames; - if (urlListAltNames.size() > 0) { - for (long unsigned int i = 0; i < urlListAltNames.size(); i++) { - urlNames.push_back(inst::util::shortenString(urlListAltNames[i], 38, true)); - } - } else { - for (long unsigned int i = 0; i < ourUrlList.size(); i++) { - urlNames.push_back(inst::util::shortenString(inst::util::formatUrlString(ourUrlList[i]), 38, true)); - } - } - - std::vector previousClockValues; - if (inst::config::overClock) { - previousClockValues.push_back(inst::util::setClockSpeed(0, 1785000000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(1, 76800000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(2, 1600000000)[0]); - } - - try { - for (urlItr = 0; urlItr < ourUrlList.size(); urlItr++) { - LOG_DEBUG("%s %s\n", "Install request from", ourUrlList[urlItr].c_str()); - inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + urlNames[urlItr] + ourSource); - std::unique_ptr installTask; - - if (inst::curl::downloadToBuffer(ourUrlList[urlItr], 0x100, 0x103) == "HEAD") { - auto httpXCI = std::make_shared(ourUrlList[urlItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, httpXCI); - } else { - auto httpNSP = std::make_shared(ourUrlList[urlItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, httpNSP); - } - - LOG_DEBUG("%s\n", "Preparing installation"); - inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang); - inst::ui::instPage::setInstBarPerc(0); - installTask->Prepare(); - installTask->Begin(); - } - } - catch (std::exception& e) { - LOG_DEBUG("Failed to install"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + urlNames[urlItr]); - inst::ui::instPage::setInstBarPerc(0); - std::string audioPath = ""; - if (std::filesystem::exists(inst::config::appDir + "/sounds/OHNO.WAV")) { - audioPath = (inst::config::appDir + "/sounds/OHNO.WAV"); - } - else { - audioPath = "romfs:/audio/bark.wav"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + urlNames[urlItr] + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true); - audioThread.join(); - nspInstalled = false; - } - - if (previousClockValues.size() > 0) { - inst::util::setClockSpeed(0, previousClockValues[0]); - inst::util::setClockSpeed(1, previousClockValues[1]); - inst::util::setClockSpeed(2, previousClockValues[2]); - } - - LOG_DEBUG("Telling the server we're done installing\n"); - // Send 1 byte ack to close the server - u8 ack = 0; - tin::network::WaitSendNetworkData(m_clientSocket, &ack, sizeof(u8)); - - if(nspInstalled) { - inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang); - inst::ui::instPage::setInstBarPerc(100); - std::string audioPath = ""; - - if (inst::config::useSound) { - if (std::filesystem::exists(inst::config::appDir + "/sounds/YIPPEE.WAV")) { - audioPath = (inst::config::appDir + "/sounds/YIPPEE.WAV"); - } - else { - audioPath = "romfs:/audio/ameizing.mp3"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - - if (ourUrlList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourUrlList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - else inst::ui::mainApp->CreateShowDialog(urlNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - audioThread.join(); - } - - else{ - if (ourUrlList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourUrlList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - else inst::ui::mainApp->CreateShowDialog(urlNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - } - - LOG_DEBUG("Done"); - inst::ui::instPage::loadMainMenu(); - inst::util::deinitInstallServices(); - return; - } - - std::vector OnSelected() - { - /* - https://switchbrew.github.io/libnx/hid_8h.html#aa163470a1a7b811662e5c38905cc86fba4d9ae7fa7e27704abaf86c8a8a5398bd - */ - padConfigureInput(8, HidNpadStyleSet_NpadStandard); - PadState pad; - padInitializeAny(&pad); - - u64 freq = armGetSystemTickFreq(); - u64 startTime = armGetSystemTick(); - - OnUnwound(); - - try - { - ASSERT_OK(curl_global_init(CURL_GLOBAL_ALL), "Curl failed to initialized"); - - // Initialize the server socket if it hasn't already been - if (m_serverSocket == 0) - { - InitializeServerSocket(); - - if (m_serverSocket <= 0) - { - THROW_FORMAT("Server socket failed to initialize.\n"); - close(m_serverSocket); //close if already open. - m_serverSocket = 0; //reset so we can try again. - } - } - - std::string ourIPAddress = inst::util::getIPAddress(); - inst::ui::mainApp->netinstPage->pageInfoText->SetText("inst.net.top_info1"_lang + ourIPAddress); - inst::ui::mainApp->CallForRender(); - netConnected = false; - LOG_DEBUG("%s %s\n", "Switch IP is ", ourIPAddress.c_str()); - LOG_DEBUG("%s\n", "Waiting for network"); - LOG_DEBUG("%s\n", "B to cancel"); - - std::vector urls; - - while (true) - { - padUpdate(&pad); - - // If we don't update the UI occasionally the Switch basically crashes on this screen if you press the home button - u64 newTime = armGetSystemTick(); - if (newTime - startTime >= freq * 0.25) { - startTime = newTime; - inst::ui::mainApp->CallForRender(); - } - - // Break on input pressed - u64 kDown = padGetButtonsDown(&pad); - - if (kDown & HidNpadButton_B) - { - break; - } - if (kDown & HidNpadButton_Y) - { - return {"supplyUrl"}; - } - if (kDown & HidNpadButton_X) - { - inst::ui::mainApp->CreateShowDialog("inst.net.help.title"_lang, "inst.net.help.desc"_lang, {"common.ok"_lang}, true); - } - - if (kDown & HidNpadButton_Minus) { - std::string url = inst::util::softwareKeyboard("inst.net.url.hint"_lang, inst::config::httpIndexUrl, 500); - if(url == "") { - url = "http://127.0.0.1"; - } - - else { - - inst::config::httpIndexUrl = url; - inst::config::setConfig(); - - - std::string response; - if (inst::util::formatUrlString(url) == "" || url == "https://" || url == "http://") - inst::ui::mainApp->CreateShowDialog("inst.net.url.invalid"_lang, "", {"common.ok"_lang}, false); - else { - if (url[url.size() - 1] != '/') - url += '/'; - response = inst::curl::downloadToBuffer(url); - } - - if (!response.empty()) { - if (response[0] == '{') - try { - nlohmann::json j = nlohmann::json::parse(response); - for (const auto &file : j["files"]) { - urls.push_back(file["url"]); - } - return urls; - } - catch (const nlohmann::detail::exception& ex) { - LOG_DEBUG("Failed to parse JSON\n"); - } - - else if (response[0] == '<') { - std::size_t index = 0; - while (index < response.size()) { - std::string link; - auto found = response.find("href=\"", index); - if (found == std::string::npos) - break; - - index = found + 6; - while (index < response.size()) { - if (response[index] == '"') { - if (link.find("../") == std::string::npos) - if (link.find(".nsp") != std::string::npos || link.find(".nsz") != std::string::npos || link.find(".xci") != std::string::npos || link.find(".xcz") != std::string::npos){ - if (inst::config::useoldphp) { - urls.push_back(url + link); - } - else { - urls.push_back(link); - } - } - break; - } - link += response[index++]; - } - - } - if (urls.size() > 0){ - /* - //debug - FILE * fp; - std::string debug = urls[0]; - const char *info = debug.c_str(); - fp = fopen ("debug.txt", "w+"); - fprintf(fp, "%s", info); - fclose(fp); - */ - return urls; - } - - LOG_DEBUG("Failed to parse games from HTML\n"); - } - } - - else { - LOG_DEBUG("Failed to fetch game list\n"); - inst::ui::mainApp->CreateShowDialog("inst.net.index_error"_lang, "inst.net.index_error_info"_lang, {"common.ok"_lang}, true); - } - } - } - - struct sockaddr_in client; - socklen_t clientLen = sizeof(client); - - m_clientSocket = accept(m_serverSocket, (struct sockaddr*)&client, &clientLen); - - if (m_clientSocket >= 0) - { - LOG_DEBUG("%s\n", "Server accepted"); - u32 size = 0; - tin::network::WaitReceiveNetworkData(m_clientSocket, &size, sizeof(u32)); - size = ntohl(size); - - LOG_DEBUG("Received url buf size: 0x%x\n", size); - - if (size > MAX_URL_SIZE * MAX_URLS) - { - THROW_FORMAT("URL size %x is too large!\n", size); - } - - // Make sure the last string is null terminated - auto urlBuf = std::make_unique(size+1); - memset(urlBuf.get(), 0, size+1); - - tin::network::WaitReceiveNetworkData(m_clientSocket, urlBuf.get(), size); - - // Split the string up into individual URLs - std::stringstream urlStream(urlBuf.get()); - std::string segment; - - while (std::getline(urlStream, segment, '\n')) urls.push_back(segment); - std::sort(urls.begin(), urls.end(), inst::util::ignoreCaseCompare); - - break; - } - else if (errno != EAGAIN) - { - THROW_FORMAT("Failed to open client socket with code %u\n", errno); - } - } - - return urls; - - } - catch (std::runtime_error& e) - { - close(m_serverSocket); - m_serverSocket = 0; - LOG_DEBUG("Failed to perform remote install!\n"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::mainApp->CreateShowDialog("inst.net.failed"_lang, (std::string)e.what(), {"common.ok"_lang}, true); - return {}; - } - } -} diff --git a/source/nx/content_meta.cpp b/source/nx/content_meta.cpp deleted file mode 100644 index 37deef6..0000000 --- a/source/nx/content_meta.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/content_meta.hpp" - -#include -#include "util/title_util.hpp" -#include "util/debug.h" -#include "util/error.hpp" - -namespace nx::ncm -{ - ContentMeta::ContentMeta() - { - m_bytes.Resize(sizeof(PackagedContentMetaHeader)); - } - - ContentMeta::ContentMeta(u8* data, size_t size) : - m_bytes(size) - { - if (size < sizeof(PackagedContentMetaHeader)) - THROW_FORMAT("Content meta data size is too small!"); - - m_bytes.Resize(size); - memcpy(m_bytes.GetData(), data, size); - } - - PackagedContentMetaHeader ContentMeta::GetPackagedContentMetaHeader() - { - return m_bytes.Read(0); - } - - NcmContentMetaKey ContentMeta::GetContentMetaKey() - { - NcmContentMetaKey metaRecord; - PackagedContentMetaHeader contentMetaHeader = this->GetPackagedContentMetaHeader(); - - memset(&metaRecord, 0, sizeof(NcmContentMetaKey)); - metaRecord.id = contentMetaHeader.title_id; - metaRecord.version = contentMetaHeader.version; - metaRecord.type = static_cast(contentMetaHeader.type); - - return metaRecord; - } - - // TODO: Cache this - std::vector ContentMeta::GetContentInfos() - { - PackagedContentMetaHeader contentMetaHeader = this->GetPackagedContentMetaHeader(); - - std::vector contentInfos; - PackagedContentInfo* packagedContentInfos = (PackagedContentInfo*)(m_bytes.GetData() + sizeof(PackagedContentMetaHeader) + contentMetaHeader.extended_header_size); - - for (unsigned int i = 0; i < contentMetaHeader.content_count; i++) - { - PackagedContentInfo packagedContentInfo = packagedContentInfos[i]; - - // Don't install delta fragments. Even patches don't seem to install them. - if (static_cast(packagedContentInfo.content_info.content_type) <= 5) - { - contentInfos.push_back(packagedContentInfo.content_info); - } - } - - return contentInfos; - } - - void ContentMeta::GetInstallContentMeta(tin::data::ByteBuffer& installContentMetaBuffer, NcmContentInfo& cnmtNcmContentInfo, bool ignoreReqFirmVersion) - { - PackagedContentMetaHeader packagedContentMetaHeader = this->GetPackagedContentMetaHeader(); - std::vector contentInfos = this->GetContentInfos(); - - // Setup the content meta header - NcmContentMetaHeader contentMetaHeader; - contentMetaHeader.extended_header_size = packagedContentMetaHeader.extended_header_size; - contentMetaHeader.content_count = contentInfos.size() + 1; // Add one for the cnmt content record - contentMetaHeader.content_meta_count = packagedContentMetaHeader.content_meta_count; - contentMetaHeader.attributes = packagedContentMetaHeader.attributes; - - installContentMetaBuffer.Append(contentMetaHeader); - - // Setup the meta extended header - LOG_DEBUG("Install content meta pre size: 0x%lx\n", installContentMetaBuffer.GetSize()); - installContentMetaBuffer.Resize(installContentMetaBuffer.GetSize() + contentMetaHeader.extended_header_size); - LOG_DEBUG("Install content meta post size: 0x%lx\n", installContentMetaBuffer.GetSize()); - auto* extendedHeaderSourceBytes = m_bytes.GetData() + sizeof(PackagedContentMetaHeader); - u8* installExtendedHeaderStart = installContentMetaBuffer.GetData() + sizeof(NcmContentMetaHeader); - memcpy(installExtendedHeaderStart, extendedHeaderSourceBytes, contentMetaHeader.extended_header_size); - - // Optionally disable the required system version field - if (ignoreReqFirmVersion && (packagedContentMetaHeader.type == NcmContentMetaType_Application || packagedContentMetaHeader.type == NcmContentMetaType_Patch)) - { - installContentMetaBuffer.Write(0, sizeof(NcmContentMetaHeader) + 8); - } - - // Setup cnmt content record - installContentMetaBuffer.Append(cnmtNcmContentInfo); - - // Setup the content records - for (auto& contentInfo : contentInfos) - { - installContentMetaBuffer.Append(contentInfo); - } - - if (packagedContentMetaHeader.type == NcmContentMetaType_Patch) - { - NcmPatchMetaExtendedHeader* patchMetaExtendedHeader = (NcmPatchMetaExtendedHeader*)extendedHeaderSourceBytes; - installContentMetaBuffer.Resize(installContentMetaBuffer.GetSize() + patchMetaExtendedHeader->extended_data_size); - } - } -} - diff --git a/source/nx/fs.cpp b/source/nx/fs.cpp deleted file mode 100644 index 64f352d..0000000 --- a/source/nx/fs.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/fs.hpp" - -#include -#include "util/error.hpp" - -namespace nx::fs -{ - // IFile - - IFile::IFile(FsFile& file) - { - m_file = file; - } - - IFile::~IFile() - { - fsFileClose(&m_file); - } - - void IFile::Read(u64 offset, void* buf, size_t size) - { - u64 sizeRead; - ASSERT_OK(fsFileRead(&m_file, offset, buf, size, FsReadOption_None, &sizeRead), "Failed to read file"); - - if (sizeRead != size) - { - std::string msg = "Size read " + std::string("" + sizeRead) + " doesn't match expected size " + std::string("" + size); - THROW_FORMAT(msg.c_str()); - } - } - - s64 IFile::GetSize() - { - s64 sizeOut; - ASSERT_OK(fsFileGetSize(&m_file, &sizeOut), "Failed to get file size"); - return sizeOut; - } - - // End IFile - - // IDirectory - IDirectory::IDirectory(FsDir& dir) - { - m_dir = dir; - } - - IDirectory::~IDirectory() - { - fsDirClose(&m_dir); - } - - void IDirectory::Read(s64 inval, FsDirectoryEntry* buf, size_t numEntries) - { - ASSERT_OK(fsDirRead(&m_dir, &inval, numEntries, buf), "Failed to read directory"); - - /*if (entriesRead != numEntries) - { - std::string msg = "Entries read " + std::string("" + entriesRead) + " doesn't match expected number " + std::string("" + numEntries); - THROW_FORMAT(msg); - }*/ - } - - u64 IDirectory::GetEntryCount() - { - s64 entryCount = 0; - ASSERT_OK(fsDirGetEntryCount(&m_dir, &entryCount), "Failed to get entry count"); - return entryCount; - } - - // End IDirectory - - IFileSystem::IFileSystem() {} - - IFileSystem::~IFileSystem() - { - this->CloseFileSystem(); - } - - Result IFileSystem::OpenSdFileSystem() - { - ASSERT_OK(fsOpenSdCardFileSystem(&m_fileSystem), "Failed to mount sd card"); - return 0; - } - - void IFileSystem::OpenFileSystemWithId(std::string path, FsFileSystemType fileSystemType, u64 titleId) - { - Result rc = 0; - if (path.length() >= FS_MAX_PATH) - THROW_FORMAT("Directory path is too long!"); - - // libnx expects a FS_MAX_PATH-sized buffer - path.reserve(FS_MAX_PATH); - - std::string errorMsg = "Failed to open file system with id: " + path; - rc = fsOpenFileSystemWithId(&m_fileSystem, titleId, fileSystemType, path.c_str()); - - if (rc == 0x236e02) - errorMsg = "File " + path + " is unreadable! You may have a bad dump, fs_mitm may need to be removed, or your firmware version may be too low to decrypt it."; - - ASSERT_OK(rc, errorMsg.c_str()); - } - - void IFileSystem::CloseFileSystem() - { - fsFsClose(&m_fileSystem); - } - - IFile IFileSystem::OpenFile(std::string path) - { - if (path.length() >= FS_MAX_PATH) - THROW_FORMAT("Directory path is too long!"); - - // libnx expects a FS_MAX_PATH-sized buffer - path.reserve(FS_MAX_PATH); - - FsFile file; - ASSERT_OK(fsFsOpenFile(&m_fileSystem, path.c_str(), FsOpenMode_Read, &file), ("Failed to open file " + path).c_str()); - return IFile(file); - } - - IDirectory IFileSystem::OpenDirectory(std::string path, int flags) - { - // Account for null at the end of c strings - if (path.length() >= FS_MAX_PATH) - THROW_FORMAT("Directory path is too long!"); - - // libnx expects a FS_MAX_PATH-sized buffer - path.reserve(FS_MAX_PATH); - - FsDir dir; - ASSERT_OK(fsFsOpenDirectory(&m_fileSystem, path.c_str(), flags, &dir), ("Failed to open directory " + path).c_str()); - return IDirectory(dir); - } -} diff --git a/source/nx/ipc/es.c b/source/nx/ipc/es.c deleted file mode 100644 index b94440f..0000000 --- a/source/nx/ipc/es.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/ipc/es.h" - -#include - -#include -#include "service_guard.h" - -static Service g_esSrv; - -NX_GENERATE_SERVICE_GUARD(es); - -Result _esInitialize() { - return smGetService(&g_esSrv, "es"); -} - -void _esCleanup() { - serviceClose(&g_esSrv); -} - -Service* esGetServiceSession() { - return &g_esSrv; -} - -Result esImportTicket(void const *tikBuf, size_t tikSize, void const *certBuf, size_t certSize) { - return serviceDispatch(&g_esSrv, 1, - .buffer_attrs = { - SfBufferAttr_HipcMapAlias | SfBufferAttr_In, - SfBufferAttr_HipcMapAlias | SfBufferAttr_In, - }, - .buffers = { - { tikBuf, tikSize }, - { certBuf, certSize }, - }, - ); -} - -Result esDeleteTicket(const RightsId *rightsIdBuf, size_t bufSize) { - return serviceDispatch(&g_esSrv, 3, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, - .buffers = { { rightsIdBuf, bufSize }, }, - ); -} - -Result esGetTitleKey(const RightsId *rightsId, u8 *outBuf, size_t bufSize) { - struct { - RightsId rights_Id; - u32 key_generation; - } in; - memcpy(&in.rights_Id, rightsId, sizeof(RightsId)); - in.key_generation = 0; - - return serviceDispatchIn(&g_esSrv, 8, in, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { outBuf, bufSize } }, - ); -} - -Result esCountCommonTicket(u32 *numTickets) { - struct { - u32 num_tickets; - } out; - - Result rc = serviceDispatchOut(&g_esSrv, 9, out); - if (R_SUCCEEDED(rc) && numTickets) *numTickets = out.num_tickets; - - return rc; -} - -Result esCountPersonalizedTicket(u32 *numTickets) { - struct { - u32 num_tickets; - } out; - - Result rc = serviceDispatchOut(&g_esSrv, 10, out); - if (R_SUCCEEDED(rc) && numTickets) *numTickets = out.num_tickets; - - return rc; -} - -Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) { - struct { - u32 num_rights_ids_written; - } out; - - Result rc = serviceDispatchInOut(&g_esSrv, 11, *numRightsIdsWritten, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { outBuf, bufSize } }, - ); - if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; - - return rc; -} - -Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize) { - struct { - u32 num_rights_ids_written; - } out; - - Result rc = serviceDispatchInOut(&g_esSrv, 12, *numRightsIdsWritten, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { outBuf, bufSize } }, - ); - if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; - - return rc; -} - -Result esGetCommonTicketData(u64 *unkOut, void *outBuf1, size_t bufSize1, const RightsId* rightsId) { - struct { - RightsId rights_id; - } in; - memcpy(&in.rights_id, rightsId, sizeof(RightsId)); - - struct { - u64 unk; - } out; - - Result rc = serviceDispatchInOut(&g_esSrv, 16, in, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { outBuf1, bufSize1 } }, - ); - return rc; -} \ No newline at end of file diff --git a/source/nx/ipc/ns_ext.c b/source/nx/ipc/ns_ext.c deleted file mode 100644 index f62213e..0000000 --- a/source/nx/ipc/ns_ext.c +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/ipc/ns_ext.h" - -#include -#include -#include -#include "service_guard.h" - -static Service g_nsAppManSrv, g_nsGetterSrv; - -static Result _nsextGetSession(Service* srv, Service* srv_out, u32 cmd_id); - -NX_GENERATE_SERVICE_GUARD(nsext); - -Result _nsextInitialize(void) { - Result rc=0; - - if(hosversionBefore(3,0,0)) - return smGetService(&g_nsAppManSrv, "ns:am"); - - rc = smGetService(&g_nsGetterSrv, "ns:am2");//TODO: Support the other services?(Only useful when ns:am2 isn't accessible) - if (R_FAILED(rc)) return rc; - - rc = _nsextGetSession(&g_nsGetterSrv, &g_nsAppManSrv, 7996); - - if (R_FAILED(rc)) serviceClose(&g_nsGetterSrv); - - return rc; -} - -void _nsextCleanup(void) { - serviceClose(&g_nsAppManSrv); - if(hosversionBefore(3,0,0)) return; - - serviceClose(&g_nsGetterSrv); -} - -static Result _nsextGetSession(Service* srv, Service* srv_out, u32 cmd_id) { - return serviceDispatch(srv, cmd_id, - .out_num_objects = 1, - .out_objects = srv_out, - ); -} - -Result nsPushApplicationRecord(u64 title_id, u8 last_modified_event, ContentStorageRecord *content_records_buf, size_t buf_size) { - - struct { - u8 last_modified_event; - u8 padding[0x7]; - u64 title_id; - } in = { last_modified_event, {0}, title_id }; - - return serviceDispatchIn(&g_nsAppManSrv, 16, in, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, - .buffers = { { content_records_buf, buf_size } }); -} - -Result nsListApplicationRecordContentMeta(u64 offset, u64 titleID, void *out_buf, size_t out_buf_size, u32 *entries_read_out) { - - struct { - u64 offset; - u64 titleID; - } in = { offset, titleID }; - - struct { - u32 entries_read; - } out; - - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 17, in, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out_buf, out_buf_size } }); - - if (R_SUCCEEDED(rc) && entries_read_out) *entries_read_out = out.entries_read; - - return rc; -} - -Result nsDeleteApplicationRecord(u64 titleID) { - struct { - u64 titleID; - } in = { titleID }; - - return serviceDispatchIn(&g_nsAppManSrv, 27, in); -} - -Result nsLaunchApplication(u64 titleID) { - struct { - u64 titleID; - } in = { titleID }; - - return serviceDispatchIn(&g_nsAppManSrv, 19, in); -} - -Result nsPushLaunchVersion(u64 titleID, u32 version) { - struct { - u64 titleID; - u32 version; - u32 padding; - } in = { titleID, version, 0 }; - - return serviceDispatchIn(&g_nsAppManSrv, 36, in); -} - -Result nsGetContentMetaStorage(const NcmContentMetaKey *record, u8 *storageOut) { - - struct { - NcmContentMetaKey metaRecord; - } in; - memcpy(&in.metaRecord, record, sizeof(NcmContentMetaKey)); - - struct { - u8 out; - } out; - - Result rc = serviceDispatchInOut(&g_nsAppManSrv, 606, in, out); - - if (R_SUCCEEDED(rc) && storageOut) *storageOut = out.out; - - return rc; -} - -Result nsBeginInstallApplication(u64 tid, u32 unk, u8 storageId) { - - struct { - u32 storageId; - u32 unk; - u64 tid; - } in = { storageId, unk, tid }; - - return serviceDispatchIn(&g_nsAppManSrv, 26, in); -} - -Result nsInvalidateAllApplicationControlCache(void) { - return serviceDispatch(&g_nsAppManSrv, 401); -} - -Result nsInvalidateApplicationControlCache(u64 tid) { - - struct { - u64 tid; - } in = { tid }; - - return serviceDispatchIn(&g_nsAppManSrv, 404, in); -} - -Result nsCheckApplicationLaunchRights(u64 tid) { - - struct { - u64 tid; - } in = { tid }; - - return serviceDispatchIn(&g_nsAppManSrv, 39, in); -} - -Result nsGetApplicationContentPath(u64 tid, u8 type, char *out, size_t buf_size) { - - struct { - u8 padding[0x7]; - u8 type; - u64 tid; - } in = { {0}, type, tid }; - - return serviceDispatchIn(&g_nsAppManSrv, 21, in, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out, buf_size } } - ); -} - -Result nsDisableApplicationAutoUpdate(u64 titleID) { - - struct { - u64 title_id; - } in = { titleID }; - - return serviceDispatchIn(&g_nsAppManSrv, 903, in); -} \ No newline at end of file diff --git a/source/nx/ipc/service_guard.h b/source/nx/ipc/service_guard.h deleted file mode 100644 index 2d627b4..0000000 --- a/source/nx/ipc/service_guard.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once -#include - -typedef struct ServiceGuard { - Mutex mutex; - u32 refCount; -} ServiceGuard; - -NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g) -{ - mutexLock(&g->mutex); - return (g->refCount++) == 0; -} - -NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void)) -{ - if (R_FAILED(rc)) { - cleanupFunc(); - --g->refCount; - } - mutexUnlock(&g->mutex); - return rc; -} - -NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void)) -{ - mutexLock(&g->mutex); - if (g->refCount && (--g->refCount) == 0) - cleanupFunc(); - mutexUnlock(&g->mutex); -} - -#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \ -\ -static ServiceGuard g_##name##Guard; \ -NX_INLINE Result _##name##Initialize _paramdecl; \ -static void _##name##Cleanup(void); \ -\ -Result name##Initialize _paramdecl \ -{ \ - Result rc = 0; \ - if (serviceGuardBeginInit(&g_##name##Guard)) \ - rc = _##name##Initialize _parampass; \ - return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \ -} \ -\ -void name##Exit(void) \ -{ \ - serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \ -} - -#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ()) diff --git a/source/nx/nca_writer.cpp b/source/nx/nca_writer.cpp deleted file mode 100644 index d6767d5..0000000 --- a/source/nx/nca_writer.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/nca_writer.h" -#include "util/error.hpp" -#include -#include -#include "util/crypto.hpp" -#include "util/config.hpp" -#include "util/title_util.hpp" -#include "install/nca.hpp" - -void append(std::vector& buffer, const u8* ptr, u64 sz) -{ - u64 offset = buffer.size(); - buffer.resize(offset + sz); - memcpy(buffer.data() + offset, ptr, sz); -} - -NcaBodyWriter::NcaBodyWriter(const NcmContentId& ncaId, u64 offset, std::shared_ptr& contentStorage) : m_contentStorage(contentStorage), m_ncaId(ncaId), m_offset(offset) -{ -} - -NcaBodyWriter::~NcaBodyWriter() -{ -} - -u64 NcaBodyWriter::write(const u8* ptr, u64 sz) -{ - if(isOpen()) - { - m_contentStorage->WritePlaceholder(*(NcmPlaceHolderId*)&m_ncaId, m_offset, (void*)ptr, sz); - m_offset += sz; - return sz; - } - - return 0; -} - -bool NcaBodyWriter::isOpen() const -{ - return m_contentStorage != NULL; -} - - -class NczHeader -{ -public: - static const u64 MAGIC = 0x4E544345535A434E; - - class Section - { - public: - u64 offset; - u64 size; - u8 cryptoType; - u8 padding1[7]; - u64 padding2; - u8 cryptoKey[0x10]; - u8 cryptoCounter[0x10]; - } PACKED; - - class SectionContext : public Section - { - public: - SectionContext(const Section& s) : Section(s), crypto(s.cryptoKey, Crypto::AesCtr(Crypto::swapEndian(((u64*)&s.cryptoCounter)[0]))) - { - } - - virtual ~SectionContext() - { - } - - void decrypt(void* p, u64 sz, u64 offset) - { - if (this->cryptoType != 3) - { - return; - } - - crypto.seek(offset); - crypto.decrypt(p, p, sz); - } - - void encrypt(void* p, u64 sz, u64 offset) - { - if (this->cryptoType != 3) - { - return; - } - - crypto.seek(offset); - crypto.encrypt(p, p, sz); - } - - Crypto::Aes128Ctr crypto; - }; - - const bool isValid() - { - return m_magic == MAGIC && m_sectionCount < 0xFFFF; - } - - const u64 size() const - { - return sizeof(m_magic) + sizeof(m_sectionCount) + sizeof(Section) * m_sectionCount; - } - - const Section& section(u64 i) const - { - return m_sections[i]; - } - - const u64 sectionCount() const - { - return m_sectionCount; - } - -protected: - u64 m_magic; - u64 m_sectionCount; - Section m_sections[1]; -} PACKED; - -class NczBodyWriter : public NcaBodyWriter -{ -public: - NczBodyWriter(const NcmContentId& ncaId, u64 offset, std::shared_ptr& contentStorage) : NcaBodyWriter(ncaId, offset, contentStorage) - { - buffIn = malloc(buffInSize); - buffOut = malloc(buffOutSize); - - dctx = ZSTD_createDCtx(); - } - - virtual ~NczBodyWriter() - { - close(); - - for (auto& i : sections) - { - if (i) - { - delete i; - i = NULL; - } - } - - if (dctx) - { - ZSTD_freeDCtx(dctx); - dctx = NULL; - } - } - - bool close() - { - if (this->m_buffer.size()) - { - processChunk(m_buffer.data(), m_buffer.size()); - } - - flush(); - - return true; - } - - bool flush() - { - if(!isOpen()) - { - return false; - } - - if (m_deflateBuffer.size()) - { - m_contentStorage->WritePlaceholder(*(NcmPlaceHolderId*)&m_ncaId, m_offset, m_deflateBuffer.data(), m_deflateBuffer.size()); - m_offset += m_deflateBuffer.size(); - m_deflateBuffer.resize(0); - } - return true; - } - - NczHeader::SectionContext& section(u64 offset) - { - for (u64 i = 0; i < sections.size(); i++) - { - if (offset >= sections[i]->offset && offset < sections[i]->offset + sections[i]->size) - { - return *sections[i]; - } - } - return *sections[0]; - } - - bool encrypt(const void* ptr, u64 sz, u64 offset) - { - const u8* start = (u8*)ptr; - const u8* end = start + sz; - - while (start < end) - { - auto& s = section(offset); - - u64 sectionEnd = s.offset + s.size; - - u64 chunk = offset + sz > sectionEnd ? sectionEnd - offset : sz; - - s.encrypt((void*)start, chunk, offset); - - offset += chunk; - start += chunk; - sz -= chunk; - } - - return true; - } - - u64 processChunk(const u8* ptr, u64 sz) - { - ZSTD_inBuffer input = { ptr, sz, 0 }; - ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; - m_deflateBuffer.resize(sz); - m_deflateBuffer.resize(0); - - while (input.pos < input.size || output.pos > 0) - { - output = { buffOut, buffOutSize, 0 }; - size_t const ret = ZSTD_decompressStream(dctx, &output, &input); - - if (ZSTD_isError(ret)) - { - LOG_DEBUG("%s\n", ZSTD_getErrorName(ret)); - return false; - } - - append(m_deflateBuffer, (const u8*)buffOut, output.pos); - - if (m_deflateBuffer.size() >= 0x1000000) // 16 MB - { - encrypt(m_deflateBuffer.data(), m_deflateBuffer.size(), m_offset); - - flush(); - } - - } - - if (m_deflateBuffer.size()) - { - encrypt(m_deflateBuffer.data(), m_deflateBuffer.size(), m_offset); - - flush(); - } - return 1; - } - - u64 write(const u8* ptr, u64 sz) override - { - if (!m_sectionsInitialized) - { - if (!m_buffer.size()) - { - append(m_buffer, ptr, sizeof(u64)*2); - ptr += sizeof(u64) * 2; - sz -= sizeof(u64) * 2; - } - - auto header = (NczHeader*)m_buffer.data(); - - if (m_buffer.size() + sz > header->size()) - { - u64 remainder = header->size() - m_buffer.size(); - append(m_buffer, ptr, remainder); - ptr += remainder; - sz -= remainder; - } - else - { - append(m_buffer, ptr, sz); - ptr += sz; - sz = 0; - } - - header = (NczHeader*)m_buffer.data(); - - if (m_buffer.size() == header->size()) - { - for (u64 i = 0; i < header->sectionCount(); i++) - { - sections.push_back(new NczHeader::SectionContext(header->section(i))); - } - - m_sectionsInitialized = true; - m_buffer.resize(0); - } - } - - while (sz) - { - if (m_buffer.size() + sz >= 0x1000000) - { - u64 chunk = 0x1000000 - m_buffer.size(); - append(m_buffer, ptr, chunk); - - processChunk(m_buffer.data(), m_buffer.size()); - m_buffer.resize(0); - - sz -= chunk; - ptr += chunk; - } - else - { - append(m_buffer, ptr, sz); - sz = 0; - } - - } - - return sz; - } - - size_t const buffInSize = ZSTD_DStreamInSize(); - size_t const buffOutSize = ZSTD_DStreamOutSize(); - - void* buffIn = NULL; - void* buffOut = NULL; - - ZSTD_DCtx* dctx = NULL; - - std::vector m_buffer; - std::vector m_deflateBuffer; - - bool m_sectionsInitialized = false; - - std::vector sections; -}; - -NcaWriter::NcaWriter(const NcmContentId& ncaId, std::shared_ptr& contentStorage) : m_ncaId(ncaId), m_contentStorage(contentStorage), m_writer(NULL) -{ -} - -NcaWriter::~NcaWriter() -{ - close(); -} - -bool NcaWriter::close() -{ - if (m_writer) - { - m_writer = NULL; - } - else if(m_buffer.size()) - { - if(isOpen()) - { - flushHeader(); - } - - m_buffer.resize(0); - } - m_contentStorage = NULL; - return true; -} - -bool NcaWriter::isOpen() const -{ - return (bool)m_contentStorage; -} - -u64 NcaWriter::write(const u8* ptr, u64 sz) -{ - if (m_buffer.size() < NCA_HEADER_SIZE) - { - if (m_buffer.size() + sz > NCA_HEADER_SIZE) - { - u64 remainder = NCA_HEADER_SIZE - m_buffer.size(); - append(m_buffer, ptr, remainder); - - ptr += remainder; - sz -= remainder; - } - else - { - append(m_buffer, ptr, sz); - ptr += sz; - sz = 0; - } - - if (m_buffer.size() == NCA_HEADER_SIZE) - { - flushHeader(); - } - } - - if (sz) - { - if (!m_writer) - { - if (sz >= sizeof(NczHeader::MAGIC)) - { - if (*(u64*)ptr == NczHeader::MAGIC) - { - m_writer = std::shared_ptr(new NczBodyWriter(m_ncaId, m_buffer.size(), m_contentStorage)); - } - else - { - m_writer = std::shared_ptr(new NcaBodyWriter(m_ncaId, m_buffer.size(), m_contentStorage)); - } - } - else - { - THROW_FORMAT("not enough data to read ncz header"); - } - } - - if(m_writer) - { - m_writer->write(ptr, sz); - } - else - { - THROW_FORMAT("null writer"); - } - } - - return sz; -} - -void NcaWriter::flushHeader() -{ - tin::install::NcaHeader header; - memcpy(&header, m_buffer.data(), sizeof(header)); - Crypto::AesXtr decryptor(Crypto::Keys().headerKey, false); - Crypto::AesXtr encryptor(Crypto::Keys().headerKey, true); - decryptor.decrypt(&header, &header, sizeof(header), 0, 0x200); - - if (header.magic == MAGIC_NCA3) - { - if(isOpen()) - { - m_contentStorage->CreatePlaceholder(m_ncaId, *(NcmPlaceHolderId*)&m_ncaId, header.nca_size); - } - } - else - { - THROW_FORMAT("Invalid NCA magic"); - } - - if (header.distribution == 1) - { - header.distribution = 0; - } - encryptor.encrypt(m_buffer.data(), &header, sizeof(header), 0, 0x200); - - if(isOpen()) - { - m_contentStorage->WritePlaceholder(*(NcmPlaceHolderId*)&m_ncaId, 0, m_buffer.data(), m_buffer.size()); - } -} diff --git a/source/nx/ncm.cpp b/source/nx/ncm.cpp deleted file mode 100644 index cac9f7b..0000000 --- a/source/nx/ncm.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "nx/ncm.hpp" -#include "util/error.hpp" - -namespace nx::ncm -{ - ContentStorage::ContentStorage(NcmStorageId storageId) - { - ASSERT_OK(ncmOpenContentStorage(&m_contentStorage, storageId), "Failed to open NCM ContentStorage"); - } - - ContentStorage::~ContentStorage() - { - serviceClose(&m_contentStorage.s); - } - - void ContentStorage::CreatePlaceholder(const NcmContentId &placeholderId, const NcmPlaceHolderId ®isteredId, size_t size) - { - ASSERT_OK(ncmContentStorageCreatePlaceHolder(&m_contentStorage, &placeholderId, ®isteredId, size), "Failed to create placeholder"); - } - - void ContentStorage::DeletePlaceholder(const NcmPlaceHolderId &placeholderId) - { - ASSERT_OK(ncmContentStorageDeletePlaceHolder(&m_contentStorage, &placeholderId), "Failed to delete placeholder"); - } - - void ContentStorage::WritePlaceholder(const NcmPlaceHolderId &placeholderId, u64 offset, void *buffer, size_t bufSize) - { - ASSERT_OK(ncmContentStorageWritePlaceHolder(&m_contentStorage, &placeholderId, offset, buffer, bufSize), "Failed to write to placeholder"); - } - - void ContentStorage::Register(const NcmPlaceHolderId &placeholderId, const NcmContentId ®isteredId) - { - ASSERT_OK(ncmContentStorageRegister(&m_contentStorage, ®isteredId, &placeholderId), "Failed to register placeholder NCA"); - } - - void ContentStorage::Delete(const NcmContentId ®isteredId) - { - ASSERT_OK(ncmContentStorageDelete(&m_contentStorage, ®isteredId), "Failed to delete registered NCA"); - } - - bool ContentStorage::Has(const NcmContentId ®isteredId) - { - bool hasNCA = false; - ASSERT_OK(ncmContentStorageHas(&m_contentStorage, &hasNCA, ®isteredId), "Failed to check if NCA is present"); - return hasNCA; - } - - std::string ContentStorage::GetPath(const NcmContentId ®isteredId) - { - char pathBuf[FS_MAX_PATH] = {0}; - ASSERT_OK(ncmContentStorageGetPath(&m_contentStorage, pathBuf, FS_MAX_PATH, ®isteredId), "Failed to get installed NCA path"); - return std::string(pathBuf); - } -} \ No newline at end of file diff --git a/source/nx/usbhdd.cpp b/source/nx/usbhdd.cpp deleted file mode 100644 index 7c7ec60..0000000 --- a/source/nx/usbhdd.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* -Microsoft Public License (Ms-PL) - -This license governs use of the accompanying software. If you use the -software, you accept this license. If you do not accept the license, -do not use the software. - - 1. Definitions - - The terms "reproduce," "reproduction," "derivative works," and - "distribution" have the same meaning here as under U.S. copyright - law. - - A "contribution" is the original software, or any additions or - changes to the software. - - A "contributor" is any person that distributes its contribution - under this license. - - "Licensed patents" are a contributor's patent claims that read - directly on its contribution. - - 2. Grant of Rights - - (A) Copyright Grant- Subject to the terms of this license, - including the license conditions and limitations in section 3, - each contributor grants you a non-exclusive, worldwide, - royalty-free copyright license to reproduce its contribution, - prepare derivative works of its contribution, and distribute its - contribution or any derivative works that you create. - - (B) Patent Grant- Subject to the terms of this license, including - the license conditions and limitations in section 3, each - contributor grants you a non-exclusive, worldwide, royalty-free - license under its licensed patents to make, have made, use, sell, - offer for sale, import, and/or otherwise dispose of its - contribution in the software or derivative works of the - contribution in the software. - - 3. Conditions and Limitations - - (A) No Trademark License- This license does not grant you rights - to use any contributors' name, logo, or trademarks. - - (B) If you bring a patent claim against any contributor over - patents that you claim are infringed by the software, your patent - license from such contributor to the software ends automatically. - - (C) If you distribute any portion of the software, you must retain - all copyright, patent, trademark, and attribution notices that are - present in the software. - - (D) If you distribute any portion of the software in source code - form, you may do so only under this license by including a - complete copy of this license with your distribution. If you - distribute any portion of the software in compiled or object code - form, you may only do so under a license that complies with this - license. - - (E) You may not distribute, copy, use, or link any portion of this - code to any other code that requires distribution of source code. - - (F) The software is licensed "as-is." You bear the risk of using - it. The contributors give no express warranties, guarantees, or - conditions. You may have additional consumer rights under your - local laws which this license cannot change. To the extent - permitted under your local laws, the contributors exclude the - implied warranties of merchantability, fitness for a particular - purpose and non-infringement. -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace nx::hdd -{ - static const u32 MAX_DEVICES = 32; - static UEvent *g_statusChangeEvent = NULL, g_exitEvent = { 0 }; - - static u32 g_usbDeviceCount = 0; - UsbHsFsDevice g_usbDevices[MAX_DEVICES]; - - static thrd_t g_thread = { 0 }; - static std::mutex g_mutex; - - static int entry(void *arg) - { - (void)arg; - - Result rc = 0; - int idx = 0; - u32 listed_device_count = 0; - - Waiter status_change_event_waiter = waiterForUEvent(g_statusChangeEvent); - Waiter exit_event_waiter = waiterForUEvent(&g_exitEvent); - - while(true) - { - rc = waitMulti(&idx, -1, status_change_event_waiter, exit_event_waiter); - if(R_FAILED(rc)) continue; - - std::scoped_lock lock(g_mutex); - - if(idx == 1) - { - break; - } - - g_usbDeviceCount = usbHsFsGetMountedDeviceCount(); - - if(!g_usbDeviceCount) continue; - - if(!(listed_device_count = usbHsFsListMountedDevices(g_usbDevices, std::min(g_usbDeviceCount, MAX_DEVICES)))) - { - continue; - } - } - - g_usbDeviceCount = 0; - - return 0; - } - - u32 count() - { - return std::min(g_usbDeviceCount, MAX_DEVICES); - } - - const char* rootPath(u32 index) - { - if(index >= MAX_DEVICES) - { - return nullptr; - } - - std::scoped_lock lock(g_mutex); - - if(index < usbHsFsGetMountedDeviceCount()) - { - return g_usbDevices[index].name; - } - - return nullptr; - } - - bool init() - { - if(g_statusChangeEvent) - { - return true; - } - - if(usbHsFsInitialize(0)) - { - return false; - } - - g_statusChangeEvent = usbHsFsGetStatusChangeUserEvent(); - - ueventCreate(&g_exitEvent, true); - - thrd_create(&g_thread, entry, NULL); - - return true; - } - - bool exit() - { - if(!g_statusChangeEvent) - { - return false; - } - - ueventSignal(&g_exitEvent); - - thrd_join(g_thread, NULL); - - g_statusChangeEvent = NULL; - - usbHsFsExit(); - - return true; - } -} diff --git a/source/sdInstall.cpp b/source/sdInstall.cpp deleted file mode 100644 index cf35ced..0000000 --- a/source/sdInstall.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "sdInstall.hpp" -#include "install/install_nsp.hpp" -#include "install/install_xci.hpp" -#include "install/sdmc_xci.hpp" -#include "install/sdmc_nsp.hpp" -#include "nx/fs.hpp" -#include "util/file_util.hpp" -#include "util/title_util.hpp" -#include "util/error.hpp" -#include "util/config.hpp" -#include "util/util.hpp" -#include "util/lang.hpp" -#include "ui/MainApplication.hpp" -#include "ui/instPage.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace nspInstStuff { - - void installNspFromFile(std::vector ourTitleList, int whereToInstall) - { - inst::util::initInstallServices(); - inst::ui::instPage::loadInstallScreen(); - bool nspInstalled = true; - NcmStorageId m_destStorageId = NcmStorageId_SdCard; - - if (whereToInstall) m_destStorageId = NcmStorageId_BuiltInUser; - unsigned int titleItr; - - std::vector previousClockValues; - if (inst::config::overClock) { - previousClockValues.push_back(inst::util::setClockSpeed(0, 1785000000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(1, 76800000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(2, 1600000000)[0]); - } - - try - { - for (titleItr = 0; titleItr < ourTitleList.size(); titleItr++) { - inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 40, true) + "inst.sd.source_string"_lang); - std::unique_ptr installTask; - - if (ourTitleList[titleItr].extension() == ".xci" || ourTitleList[titleItr].extension() == ".xcz") { - auto sdmcXCI = std::make_shared(ourTitleList[titleItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, sdmcXCI); - } else { - auto sdmcNSP = std::make_shared(ourTitleList[titleItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, sdmcNSP); - } - - LOG_DEBUG("%s\n", "Preparing installation"); - inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang); - inst::ui::instPage::setInstBarPerc(0); - installTask->Prepare(); - installTask->Begin(); - } - } - catch (std::exception& e) - { - LOG_DEBUG("Failed to install"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true)); - inst::ui::instPage::setInstBarPerc(0); - std::string audioPath = ""; - if (std::filesystem::exists(inst::config::appDir + "/sounds/OHNO.WAV")) { - audioPath = (inst::config::appDir + "/sounds/OHNO.WAV"); - } - else { - audioPath = "romfs:/audio/bark.wav"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true) + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true); - audioThread.join(); - nspInstalled = false; - } - - if (previousClockValues.size() > 0) { - inst::util::setClockSpeed(0, previousClockValues[0]); - inst::util::setClockSpeed(1, previousClockValues[1]); - inst::util::setClockSpeed(2, previousClockValues[2]); - } - - if(nspInstalled) { - inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang); - inst::ui::instPage::setInstBarPerc(100); - std::string audioPath = ""; - - if (inst::config::useSound) { - - if (std::filesystem::exists(inst::config::appDir + "/sounds/YIPPEE.WAV")) { - audioPath = (inst::config::appDir + "/sounds/YIPPEE.WAV"); - } - else { - audioPath = "romfs:/audio/ameizing.mp3"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - - if (ourTitleList.size() > 1) { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.sd.delete_info_multi"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) { - for (long unsigned int i = 0; i < ourTitleList.size(); i++) { - if (std::filesystem::exists(ourTitleList[i])) std::filesystem::remove(ourTitleList[i]); - } - } - } else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } else { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + "inst.sd.delete_info"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]); - } else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - - audioThread.join(); - } - - else{ - if (ourTitleList.size() > 1) { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.sd.delete_info_multi"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) { - for (long unsigned int i = 0; i < ourTitleList.size(); i++) { - if (std::filesystem::exists(ourTitleList[i])) std::filesystem::remove(ourTitleList[i]); - } - } - } else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } else { - if (inst::config::deletePrompt) { - if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + "inst.sd.delete_info"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]); - } else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - } - } - - LOG_DEBUG("Done"); - inst::ui::instPage::loadMainMenu(); - inst::util::deinitInstallServices(); - return; - } -} diff --git a/source/sigInstall.cpp b/source/sigInstall.cpp deleted file mode 100644 index 457397b..0000000 --- a/source/sigInstall.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include "util/error.hpp" -#include "ui/MainApplication.hpp" -#include "util/curl.hpp" -#include "util/util.hpp" -#include "util/unzip.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace sig { - void installSigPatches () { - bpcInitialize(); - try { - std::string patchesVersion = inst::util::readTextFromFile("sdmc:/atmosphere/exefs_patches/es_patches/patches.txt"); - std::string versionText = ""; - std::string installButtonText = "sig.install"_lang; - if (patchesVersion != "") { - versionText = "\n\n" + "sig.version_text"_lang + patchesVersion + "."; - installButtonText = "sig.update"_lang; - } - int ourResult = inst::ui::mainApp->CreateShowDialog("sig.title0"_lang, "sig.desc0"_lang + versionText, {installButtonText, "sig.uninstall"_lang, "common.cancel"_lang}, true); - if (ourResult == 0) { - if (inst::util::getIPAddress() == "1.0.0.127") { - inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true); - return; - } - if (!inst::util::copyFile("sdmc:/bootloader/patches.ini", inst::config::appDir + "/patches.ini.old")) { - if (inst::ui::mainApp->CreateShowDialog("sig.backup_failed"_lang, "sig.backup_failed_desc"_lang, {"common.yes"_lang, "common.no"_lang}, false)) return; - } - std::string ourPath = inst::config::appDir + "/patches.zip"; - bool didDownload = inst::curl::downloadFile(inst::config::sigPatchesUrl, ourPath.c_str()); - bool didExtract = false; - if (didDownload) didExtract = inst::zip::extractFile(ourPath, "sdmc:/"); - else { - inst::ui::mainApp->CreateShowDialog("sig.download_failed"_lang, "sig.download_failed_desc"_lang, {"common.ok"_lang}, true); - return; - } - std::filesystem::remove(ourPath); - if (didExtract) { - patchesVersion = inst::util::readTextFromFile("sdmc:/atmosphere/exefs_patches/es_patches/patches.txt"); - versionText = ""; - if (patchesVersion != "") versionText = "sig.version_text2"_lang + patchesVersion + "! "; - if (inst::ui::mainApp->CreateShowDialog("sig.install_complete"_lang, versionText + "\n\n" + "sig.complete_desc"_lang, {"sig.restart"_lang, "sig.later"_lang}, false) == 0) bpcRebootSystem(); - } - else { - inst::ui::mainApp->CreateShowDialog("sig.extract_failed"_lang, "", {"common.ok"_lang}, true); - return; - } - return; - } else if (ourResult == 1) { - if (!inst::util::copyFile( inst::config::appDir + "/patches.ini.old", "sdmc:/bootloader/patches.ini")) { - if (inst::ui::mainApp->CreateShowDialog("sig.restore_failed"_lang, "", {"common.yes"_lang, "common.no"_lang}, false)) return; - } else std::filesystem::remove(inst::config::appDir + "/patches.ini.old"); - if (inst::util::removeDirectory("sdmc:/atmosphere/exefs_patches/es_patches")) { - if (inst::ui::mainApp->CreateShowDialog("sig.uninstall_complete"_lang, "sig.complete_desc"_lang, {"sig.restart"_lang, "sig.later"_lang}, false) == 0) bpcRebootSystem(); - } - else inst::ui::mainApp->CreateShowDialog("sig.remove_failed"_lang, "sig.remove_failed_desc"_lang, {"common.ok"_lang}, true); - } else return; - } - catch (std::exception& e) - { - LOG_DEBUG("Failed to install Signature Patches"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::mainApp->CreateShowDialog("sig.generic_error"_lang, (std::string)e.what(), {"common.ok"_lang}, true); - } - bpcExit(); - } -} \ No newline at end of file diff --git a/source/ui/HDInstPage.cpp b/source/ui/HDInstPage.cpp deleted file mode 100644 index 63cc0ac..0000000 --- a/source/ui/HDInstPage.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include "ui/MainApplication.hpp" -#include "ui/mainPage.hpp" -#include "ui/HDInstPage.hpp" -#include "HDInstall.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - -namespace inst::ui { - extern MainApplication *mainApp; - s32 zzz=0; //touchscreen variable - - HDInstPage::HDInstPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if - (std::filesystem::exists(inst::config::appDir + "/images/Hd.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Hd.png")); - else - this->titleImage = Image::New(0, 0, "romfs:/images/Hd.png"); - - if - (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else - this->SetBackgroundImage("romfs:/images/Background.png"); - } - - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Hd.png"); - } - this->pageInfoText = TextBlock::New(10, 109, "inst.hd.top_info"_lang); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->butText = TextBlock::New(10, 678, "inst.hd.buttons"_lang); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 84, 6); - this->menu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->menu->SetScrollbarColor(COLOR("#1A1919FF")); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->butText); - this->Add(this->pageInfoText); - this->Add(this->menu); - } - - void HDInstPage::drawMenuItems(bool clearItems, std::filesystem::path ourPath) { - int myindex = this->menu->GetSelectedIndex(); //store index so when page redraws we can get the last item we checked. - if (clearItems) this->selectedTitles = {}; - this->currentDir = ourPath; - - auto pathStr = this->currentDir.string(); - if(pathStr.length()) - { - if(pathStr[pathStr.length() - 1] == ':') - { - this->currentDir = this->currentDir / ""; - } - } - - this->menu->ClearItems(); - try { - this->ourDirectories = util::getDirsAtPath(this->currentDir); - this->ourFiles = util::getDirectoryFiles(this->currentDir, {".nsp", ".nsz", ".xci", ".xcz"}); - } catch (std::exception& e) { - this->drawMenuItems(false, this->currentDir.parent_path()); - return; - } - - std::string itm = ".."; - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/folder-upload.png"); - this->menu->AddItem(ourEntry); - - for (auto& file: this->ourDirectories) { - if (file == "..") break; - std::string itm = file.filename().string(); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/folder.png"); - this->menu->AddItem(ourEntry); - } - for (auto& file: this->ourFiles) { - std::string itm = file.filename().string(); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/checkbox-blank-outline.png"); - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == file) { - ourEntry->SetIcon("romfs:/images/icons/check-box-outline.png"); - } - } - this->menu->AddItem(ourEntry); - this->menu->SetSelectedIndex(myindex); //jump to the index we saved from above - } - } - - void HDInstPage::followDirectory() { - int selectedIndex = this->menu->GetSelectedIndex(); - int dirListSize = this->ourDirectories.size(); - - dirListSize++; - selectedIndex--; - - if (selectedIndex < dirListSize) { - if (this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetName() == ".." && this->menu->GetSelectedIndex() == 0) { - this->drawMenuItems(true, this->currentDir.parent_path()); - } else { - this->drawMenuItems(true, this->ourDirectories[selectedIndex]); - } - this->menu->SetSelectedIndex(0); - } - } - - void HDInstPage::selectNsp(int selectedIndex) { - int dirListSize = this->ourDirectories.size(); - dirListSize++; - - if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") { - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == this->ourFiles[selectedIndex - dirListSize]) this->selectedTitles.erase(this->selectedTitles.begin() + i); - } - } else if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/checkbox-blank-outline.png") this->selectedTitles.push_back(this->ourFiles[selectedIndex - dirListSize]); - else { - this->followDirectory(); - return; - } - this->drawMenuItems(false, currentDir); - } - - void HDInstPage::startInstall() { - int dialogResult = -1; - if (this->selectedTitles.size() == 1) { - dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + inst::util::shortenString(std::filesystem::path(this->selectedTitles[0]).filename().string(), 32, true) + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - } else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedTitles.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - if (dialogResult == -1) return; - nspInstStuff_B::installNspFromFile(this->selectedTitles, dialogResult); - } - - void HDInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - if (Down & HidNpadButton_B) { - mainApp->LoadLayout(mainApp->mainPage); - } - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if ((Down & HidNpadButton_A) || (state.count != zzz)) - { - zzz = state.count; - - if (zzz != 1) { - this->selectNsp(this->menu->GetSelectedIndex()); - if (this->ourFiles.size() == 1 && this->selectedTitles.size() == 1) { - this->startInstall(); - } - - } - } - } - - if ((Down & HidNpadButton_Y)) { - if (this->selectedTitles.size() == this->ourFiles.size()) this->drawMenuItems(true, currentDir); - else { - int topDir = 0; - topDir++; - for (long unsigned int i = this->ourDirectories.size() + topDir; i < this->menu->GetItems().size(); i++) { - if (this->menu->GetItems()[i]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") continue; - else this->selectNsp(i); - } - this->drawMenuItems(false, currentDir); - } - } - - if ((Down & HidNpadButton_X)) { - inst::ui::mainApp->CreateShowDialog("inst.hd.help.title"_lang, "inst.hd.help.desc"_lang, {"common.ok"_lang}, true); - } - - if (Down & HidNpadButton_Plus) { - if (this->selectedTitles.size() == 0 && this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetIconPath() == "romfs:/images/icons/checkbox-blank-outline.png") { - this->selectNsp(this->menu->GetSelectedIndex()); - } - if (this->selectedTitles.size() > 0) this->startInstall(); - } - - if (Down & HidNpadButton_ZL) - this->menu->SetSelectedIndex(std::max(0, this->menu->GetSelectedIndex() - 6)); - - if (Down & HidNpadButton_ZR) - this->menu->SetSelectedIndex(std::min((s32)this->menu->GetItems().size() - 1, this->menu->GetSelectedIndex() + 6)); - } -} diff --git a/source/ui/MainApplication.cpp b/source/ui/MainApplication.cpp deleted file mode 100644 index f1adc6b..0000000 --- a/source/ui/MainApplication.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "ui/MainApplication.hpp" -#include "util/lang.hpp" - -namespace inst::ui { - MainApplication *mainApp; - - void MainApplication::OnLoad() { - mainApp = this; - - Language::Load(); - - this->mainPage = MainPage::New(); - this->netinstPage = netInstPage::New(); - this->sdinstPage = sdInstPage::New(); - this->HDinstPage = HDInstPage::New(); - this->usbinstPage = usbInstPage::New(); - this->instpage = instPage::New(); - this->optionspage = optionsPage::New(); - this->mainPage->SetOnInput(std::bind(&MainPage::onInput, this->mainPage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->netinstPage->SetOnInput(std::bind(&netInstPage::onInput, this->netinstPage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->sdinstPage->SetOnInput(std::bind(&sdInstPage::onInput, this->sdinstPage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->HDinstPage->SetOnInput(std::bind(&HDInstPage::onInput, this->HDinstPage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->usbinstPage->SetOnInput(std::bind(&usbInstPage::onInput, this->usbinstPage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->instpage->SetOnInput(std::bind(&instPage::onInput, this->instpage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->optionspage->SetOnInput(std::bind(&optionsPage::onInput, this->optionspage, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - this->LoadLayout(this->mainPage); - } -} \ No newline at end of file diff --git a/source/ui/instPage.cpp b/source/ui/instPage.cpp deleted file mode 100644 index 734ce55..0000000 --- a/source/ui/instPage.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include "ui/MainApplication.hpp" -#include "ui/instPage.hpp" -#include "util/config.hpp" - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - -namespace inst::ui { - extern MainApplication *mainApp; - - instPage::instPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Install.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Install.png")); - else this->titleImage = Image::New(0, 0, "romfs:/images/Install.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else this->SetBackgroundImage("romfs:/images/Background.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Install.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - this->appVersionText->SetColor(COLOR("#FFFFFFFF")); - this->pageInfoText = TextBlock::New(10, 109, ""); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->installInfoText = TextBlock::New(15, 648, ""); - this->installInfoText->SetFont(pu::ui::MakeDefaultFontName(22)); - this->installInfoText->SetColor(COLOR("#FFFFFFFF")); - this->installBar = pu::ui::elm::ProgressBar::New(10, 680, 1260, 30, 100.0f); - this->installBar->SetBackgroundColor(COLOR("#000000FF")); - this->installBar->SetProgressColor(COLOR("#565759FF")); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->titleImage); - this->Add(this->appVersionText); - this->Add(this->pageInfoText); - this->Add(this->installInfoText); - this->Add(this->installBar); - } - - void instPage::setTopInstInfoText(std::string ourText){ - mainApp->instpage->pageInfoText->SetText(ourText); - mainApp->CallForRender(); - } - - void instPage::setInstInfoText(std::string ourText){ - mainApp->instpage->installInfoText->SetText(ourText); - mainApp->CallForRender(); - } - - void instPage::setInstBarPerc(double ourPercent){ - mainApp->instpage->installBar->SetVisible(true); - mainApp->instpage->installBar->SetProgress(ourPercent); - mainApp->CallForRender(); - } - - void instPage::loadMainMenu(){ - mainApp->LoadLayout(mainApp->mainPage); - } - - void instPage::loadInstallScreen(){ - mainApp->instpage->pageInfoText->SetText(""); - mainApp->instpage->installInfoText->SetText(""); - mainApp->instpage->installBar->SetProgress(0); - mainApp->instpage->installBar->SetVisible(false); - mainApp->LoadLayout(mainApp->instpage); - mainApp->CallForRender(); - } - - void instPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - } -} \ No newline at end of file diff --git a/source/ui/mainPage.cpp b/source/ui/mainPage.cpp deleted file mode 100644 index 955f59c..0000000 --- a/source/ui/mainPage.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include -#include -#include -#include -#include "ui/MainApplication.hpp" -#include "ui/mainPage.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" -#include "sigInstall.hpp" -#include "HDInstall.hpp" -#include "data/buffered_placeholder_writer.hpp" -#include "nx/usbhdd.h" -#include - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - - - -int statvfs(const char *path, struct statvfs *buf); -s32 prev_touchcount=0; - -double GetAvailableSpace(const char* path) -{ - struct statvfs stat; - - if (statvfs(path, &stat) != 0) { - // error happens, just quits here - return -1; - } - - // the available size is f_bsize * f_bavail - return stat.f_bsize * stat.f_bavail; -} - -double amountOfDiskSpaceUsed(const char* path) -{ - struct statvfs stat; - - if (statvfs(path, &stat) != 0) { - // error happens, just quits here - return -1; - } - const auto total = static_cast(stat.f_blocks); - const auto available = static_cast(stat.f_bavail); - const auto availableToRoot = static_cast(stat.f_bfree); - const auto used = total - availableToRoot; - const auto nonRootTotal = used + available; - return 100.0 * static_cast(used) / static_cast(nonRootTotal); -} - -double totalsize(const char* path) -{ - struct statvfs stat; - - if (statvfs(path, &stat) != 0) { - // error happens, just quits here - return -1; - } - return stat.f_blocks * stat.f_frsize; -} - -namespace inst::ui { - extern MainApplication *mainApp; - bool appletFinished = false; - bool updateFinished = false; - - void mathstuff() { - double math = (GetAvailableSpace("./") / 1024) / 1024; //megabytes - float math2 = ((float)math / 1024); //gigabytes - - double used = (amountOfDiskSpaceUsed("./")); //same file path as sdmc - - double total = (totalsize("sdmc:/") / 1024) / 1024; //megabytes - float total2 = ((float)total / 1024); //gigabytes - // - float GB = math2; - std::stringstream stream; - stream << std::fixed << std::setprecision(2) << GB; //only show 2 decimal places - std::string freespace = stream.str(); - - - float GB2 = total2; - std::stringstream stream2; - stream2 << std::fixed << std::setprecision(2) << GB2; //only show 2 decimal places - std::string sdsize = stream2.str(); - - //printf("\nSdCard Free Space in MB: %li", math); - //printf("\nSdCard Free Space in GB: %.2f", math2); - std::stringstream stream3; - stream3 << std::fixed << std::setprecision(2) << used; //only show 2 decimal places - std::string percent = stream3.str(); - - //unmount sd here and mount system.... - //fsdevUnmountDevice("sdmc"); - FsFileSystem nandFS; - fsOpenBisFileSystem(&nandFS, FsBisPartitionId_User, ""); - fsdevMountDevice("user", nandFS); - - double math3 = (GetAvailableSpace("user:/") / 1024) / 1024; //megabytes - float math4 = ((float)math3 / 1024); //gigabytes - - double used2 = (amountOfDiskSpaceUsed("user:/")); //same file path as sdmc - - double total3 = (totalsize("user:/") / 1024) / 1024; //megabytes - float total4 = ((float)total3 / 1024); //gigabytes - // - float GB3 = math4; - std::stringstream stream4; - stream4 << std::fixed << std::setprecision(2) << GB3; //only show 2 decimal places - std::string freespace2 = stream4.str(); - - - float GB4 = total4; - std::stringstream stream5; - stream5 << std::fixed << std::setprecision(2) << GB4; //only show 2 decimal places - std::string sdsize2 = stream5.str(); - - //printf("\nSdCard Free Space in MB: %li", math); - //printf("\nSdCard Free Space in GB: %.2f", math2); - std::stringstream stream6; - stream6 << std::fixed << std::setprecision(2) << used2; //only show 2 decimal places - std::string percent2 = stream6.str(); - - //unmount user now as we already know how much space we have - fsdevUnmountDevice("user"); - - - std::string Info = ("System total size: " + sdsize2 + " GB" + "\nSystem free space: " + freespace2 + " GB" + "\nSystem percent used: " + percent2 + "%" + "\n\n" + "SD card total size: " + sdsize + " GB" + "\nSD card free space: " + freespace + " GB" + "\nSD card percent used: " + percent + "%"); - inst::ui::mainApp->CreateShowDialog("Space Usage Information", Info, {"common.ok"_lang}, true); - } - - void mainMenuThread() { - bool menuLoaded = mainApp->IsShown(); - if (!appletFinished && appletGetAppletType() == AppletType_LibraryApplet) { - tin::data::NUM_BUFFER_SEGMENTS = 2; - if (menuLoaded) { - inst::ui::appletFinished = true; - mainApp->CreateShowDialog("main.applet.title"_lang, "main.applet.desc"_lang, {"common.ok"_lang}, true); - } - } else if (!appletFinished) { - inst::ui::appletFinished = true; - tin::data::NUM_BUFFER_SEGMENTS = 128; - } - if (!updateFinished && (!inst::config::autoUpdate || inst::util::getIPAddress() == "1.0.0.127")) updateFinished = true; - - if (!updateFinished && menuLoaded && inst::config::updateInfo.size()) { - updateFinished = true; - optionsPage::askToUpdate(inst::config::updateInfo); - } - } - - MainPage::MainPage() : Layout::Layout() { - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Main.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Main.png")); - else - this->titleImage = Image::New(0, 0, "romfs:/images/Main.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else - this->SetBackgroundImage("romfs:/images/Background.png"); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Main.png"); - } - this->butText = TextBlock::New(10, 678, "main.buttons"_lang); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->optionMenu = pu::ui::elm::Menu::New(0, 95, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 94, 6); - this->optionMenu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->optionMenu->SetScrollbarColor(COLOR("#1A1919FF")); - this->installMenuItem = pu::ui::elm::MenuItem::New("main.menu.sd"_lang); - this->installMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->installMenuItem->SetIcon("romfs:/images/icons/micro-sd.png"); - this->netInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.net"_lang); - this->netInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->netInstallMenuItem->SetIcon("romfs:/images/icons/cloud-download.png"); - this->usbInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.usb"_lang); - this->usbInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->usbInstallMenuItem->SetIcon("romfs:/images/icons/usb-port.png"); - this->HdInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.hdd"_lang); - this->HdInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->HdInstallMenuItem->SetIcon("romfs:/images/icons/usb-hd.png"); - this->settingsMenuItem = pu::ui::elm::MenuItem::New("main.menu.set"_lang); - this->settingsMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->settingsMenuItem->SetIcon("romfs:/images/icons/settings.png"); - this->exitMenuItem = pu::ui::elm::MenuItem::New("main.menu.exit"_lang); - this->exitMenuItem->SetColor(COLOR("#FFFFFFFF")); - this->exitMenuItem->SetIcon("romfs:/images/icons/exit-run.png"); - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Main.png")) this->awooImage = Image::New(0, 0, inst::config::appDir + "/images/Main.png"); - else this->awooImage = Image::New(0, 0, "romfs:/images/Main.png"); - } - else{ - this->awooImage = Image::New(0, 0, "romfs:/images/Main.png"); - } - this->eggImage = Image::New(0, 0, ""); - this->Add(this->topRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->butText); - this->optionMenu->AddItem(this->installMenuItem); - this->optionMenu->AddItem(this->netInstallMenuItem); - this->optionMenu->AddItem(this->usbInstallMenuItem); - this->optionMenu->AddItem(this->HdInstallMenuItem); - this->optionMenu->AddItem(this->settingsMenuItem); - this->optionMenu->AddItem(this->exitMenuItem); - this->Add(this->awooImage); - this->Add(this->eggImage); - this->awooImage->SetVisible(!inst::config::gayMode); - this->Add(this->optionMenu); - this->AddRenderCallback(mainMenuThread); - } - - void MainPage::installMenuItem_Click() { - mainApp->sdinstPage->drawMenuItems(true, "sdmc:/"); - mainApp->sdinstPage->menu->SetSelectedIndex(0); - mainApp->LoadLayout(mainApp->sdinstPage); - } - - void MainPage::netInstallMenuItem_Click() { - if (inst::util::getIPAddress() == "1.0.0.127") { - inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true); - return; - } - mainApp->netinstPage->startNetwork(); - } - - void MainPage::usbInstallMenuItem_Click() { - if (!inst::config::usbAck) { - if (mainApp->CreateShowDialog("main.usb.warn.title"_lang, "main.usb.warn.desc"_lang, {"common.ok"_lang, "main.usb.warn.opt1"_lang}, false) == 1) { - inst::config::usbAck = true; - inst::config::setConfig(); - } - } - if (inst::util::getUsbState() == 5) mainApp->usbinstPage->startUsb(); - else mainApp->CreateShowDialog("main.usb.error.title"_lang, "main.usb.error.desc"_lang, {"common.ok"_lang}, false); - } - - void MainPage::HdInstallMenuItem_Click() { - if(nx::hdd::count() && nx::hdd::rootPath()) { - mainApp->HDinstPage->drawMenuItems(true, nx::hdd::rootPath()); - mainApp->HDinstPage->menu->SetSelectedIndex(0); - mainApp->LoadLayout(mainApp->HDinstPage); - } else { - inst::ui::mainApp->CreateShowDialog("main.hdd.title"_lang, "main.hdd.notfound"_lang, {"common.ok"_lang}, true); - } - } - - void MainPage::exitMenuItem_Click() { - mainApp->FadeOut(); - mainApp->Close(); - } - - void MainPage::settingsMenuItem_Click() { - mainApp->LoadLayout(mainApp->optionspage); - } - - void MainPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - - if (((Down & HidNpadButton_Plus) || (Down & HidNpadButton_Minus) || ((Held & HidNpadButton_L) && ( Down & HidNpadButton_R)) || ((Down & HidNpadButton_L) && ( Held & HidNpadButton_R))) && mainApp->IsShown()) { - mainApp->FadeOut(); - mainApp->Close(); - } - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if ((Down & HidNpadButton_A) || (state.count != prev_touchcount)) - { - prev_touchcount = state.count; - - if (prev_touchcount != 1) { - int menuindex = this->optionMenu->GetSelectedIndex(); - switch (menuindex) { - case 0: - this->installMenuItem_Click(); - break; - case 1: - this->netInstallMenuItem_Click(); - break; - case 2: - MainPage::usbInstallMenuItem_Click(); - break; - case 3: - MainPage::HdInstallMenuItem_Click(); - break; - case 4: - MainPage::settingsMenuItem_Click(); - break; - case 5: - MainPage::exitMenuItem_Click(); - break; - default: - break; - } - } - } - } - - if (Down & HidNpadButton_X) { - this->awooImage->SetVisible(false); - this->eggImage->SetVisible(true); - } - if (Up & HidNpadButton_A) { - this->eggImage->SetVisible(false); - if (!inst::config::gayMode) this->awooImage->SetVisible(true); - } - - - if (Down & HidNpadButton_Y) { - mathstuff(); - } - } -} \ No newline at end of file diff --git a/source/ui/netInstPage.cpp b/source/ui/netInstPage.cpp deleted file mode 100644 index d785449..0000000 --- a/source/ui/netInstPage.cpp +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include -#include "ui/MainApplication.hpp" -#include "ui/mainPage.hpp" -#include "ui/netInstPage.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/curl.hpp" -#include "util/lang.hpp" -#include "netInstall.hpp" -#include - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - -namespace inst::ui { - extern MainApplication *mainApp; - s32 xxx=0; - - std::string httplastUrl = "http://"; - std::string lastFileID = ""; - std::string sourceString = ""; - - netInstPage::netInstPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Net.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Net.png")); - else this->titleImage = Image::New(0, 0, "romfs:/images/Net.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else this->SetBackgroundImage("romfs:/images/Background.png"); - this->appVersionText = TextBlock::New(1210, 680, ""); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Net.png"); - this->appVersionText = TextBlock::New(1210, 680, ""); - } - this->appVersionText->SetColor(COLOR("#FFFFFFFF")); - this->pageInfoText = TextBlock::New(10, 109, ""); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->butText = TextBlock::New(10, 678, ""); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 84, (506 / 84)); - this->menu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->menu->SetScrollbarColor(COLOR("#1A1919FF")); - this->infoImage = Image::New(453, 292, "romfs:/images/icons/lan-connection-waiting.png"); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->appVersionText); - this->Add(this->butText); - this->Add(this->pageInfoText); - this->Add(this->menu); - this->Add(this->infoImage); - } - - void netInstPage::drawMenuItems(bool clearItems) { - int myindex = this->menu->GetSelectedIndex(); //store index so when page redraws we can get the last item we checked. - if (clearItems) this->selectedUrls = {}; - if (clearItems) this->alternativeNames = {}; - this->menu->ClearItems(); - for (auto& url: this->ourUrls) { - std::string itm = inst::util::shortenString(inst::util::formatUrlString(url), 56, true); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/checkbox-blank-outline.png"); - long unsigned int i; - for (i = 0; i < this->selectedUrls.size(); i++) { - if (this->selectedUrls[i] == url) { - ourEntry->SetIcon("romfs:/images/icons/check-box-outline.png"); - } - } - this->menu->AddItem(ourEntry); - this->menu->SetSelectedIndex(myindex); //jump to the index we saved from above - } - } - - void netInstPage::selectTitle(int selectedIndex) { - if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") { - for (long unsigned int i = 0; i < this->selectedUrls.size(); i++) { - if (this->selectedUrls[i] == this->ourUrls[selectedIndex]) this->selectedUrls.erase(this->selectedUrls.begin() + i); - } - } - - else this->selectedUrls.push_back(this->ourUrls[selectedIndex]); - this->drawMenuItems(false); - } - - void netInstPage::startNetwork() { - this->butText->SetText("inst.net.buttons"_lang); - //this->butText->SetText("inst.net.buttons"_lang + " \ue0f0 Install From HTTP Directory"); - this->menu->SetVisible(false); - this->menu->ClearItems(); - this->infoImage->SetVisible(true); - mainApp->LoadLayout(mainApp->netinstPage); - this->ourUrls = netInstStuff::OnSelected(); - - if (!this->ourUrls.size()) { - mainApp->LoadLayout(mainApp->mainPage); - return; - } - - else if (this->ourUrls[0] == "supplyUrl") { - std::string keyboardResult; - switch (mainApp->CreateShowDialog("inst.net.src.title"_lang, "common.cancel_desc"_lang, {"inst.net.src.opt0"_lang, "inst.net.src.opt1"_lang}, false)) { - case 0: - keyboardResult = inst::util::softwareKeyboard("inst.net.url.hint"_lang, inst::config::httplastUrl, 500); - if (keyboardResult.size() > 0) { - httplastUrl = keyboardResult; - - if(keyboardResult == "") { - keyboardResult = "http://127.0.0.1"; - } - else { - inst::config::httplastUrl = keyboardResult; - inst::config::setConfig(); - } - - if (inst::util::formatUrlString(keyboardResult) == "" || keyboardResult == "https://" || keyboardResult == "http://") { - mainApp->CreateShowDialog("inst.net.url.invalid"_lang, "", {"common.ok"_lang}, false); - break; - } - sourceString = "inst.net.url.source_string"_lang; - this->selectedUrls = {keyboardResult}; - this->startInstall(true); - return; - } - break; - case 1: - keyboardResult = inst::util::softwareKeyboard("inst.net.gdrive.hint"_lang, lastFileID, 50); - if (keyboardResult.size() > 0) { - lastFileID = keyboardResult; - std::string fileName = inst::util::getDriveFileName(keyboardResult); - if (fileName.size() > 0) this->alternativeNames = {fileName}; - else this->alternativeNames = {"inst.net.gdrive.alt_name"_lang}; - sourceString = "inst.net.gdrive.source_string"_lang; - this->selectedUrls = {"https://www.googleapis.com/drive/v3/files/" + keyboardResult + "?key=" + inst::config::gAuthKey + "&alt=media"}; - this->startInstall(true); - return; - } - break; - } - this->startNetwork(); - return; - } else { - mainApp->CallForRender(); // If we re-render a few times during this process the main screen won't flicker - sourceString = "inst.net.source_string"_lang; - netConnected = true; - this->pageInfoText->SetText("inst.net.top_info"_lang); - this->butText->SetText("inst.net.buttons1"_lang); - this->drawMenuItems(true); - mainApp->CallForRender(); - this->infoImage->SetVisible(false); // - this->menu->SetVisible(true); - this->menu->SetSelectedIndex(0); //when page first loads jump to start of the menu - } - return; - } - - void netInstPage::startInstall(bool urlMode) { - int dialogResult = -1; - if (this->selectedUrls.size() == 1) { - std::string ourUrlString; - if (this->alternativeNames.size() > 0) ourUrlString = inst::util::shortenString(this->alternativeNames[0], 32, true); - else ourUrlString = inst::util::shortenString(inst::util::formatUrlString(this->selectedUrls[0]), 32, true); - dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + ourUrlString + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - } else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedUrls.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - if (dialogResult == -1 && !urlMode) return; - else if (dialogResult == -1 && urlMode) { - this->startNetwork(); - return; - } - netInstStuff::installTitleNet(this->selectedUrls, dialogResult, this->alternativeNames, sourceString); - return; - } - - void netInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - - if (Down & HidNpadButton_B) { - mainApp->LoadLayout(mainApp->mainPage); - } - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if (netConnected) { - if ((Down & HidNpadButton_A) || (state.count != xxx)) - { - xxx = state.count; - - if (xxx != 1) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - else { - this->selectTitle(this->menu->GetSelectedIndex()); - if (this->menu->GetItems().size() == 1 && this->selectedUrls.size() == 1) { - this->startInstall(false); - } - } - } - } - } - - if ((Down & HidNpadButton_Minus) || (state.count != xxx)) - { - xxx = state.count; - - if (xxx != 1) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - //std::string s = ourUrlString; //debug stuff - //this->appVersionText->SetText(s); //debug stuff - - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - else { - this->selectTitle(this->menu->GetSelectedIndex()); - if (this->menu->GetItems().size() == 1 && this->selectedUrls.size() == 1) { - this->startInstall(false); - } - } - } - } - } - - - if ((Down & HidNpadButton_Y)) { - if (this->selectedUrls.size() == this->menu->GetItems().size()) this->drawMenuItems(true); - else { - for (long unsigned int i = 0; i < this->menu->GetItems().size(); i++) { - if (this->menu->GetItems()[i]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") continue; - else this->selectTitle(i); - } - this->drawMenuItems(false); - } - } - - if (Down & HidNpadButton_Plus) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - - else { - if (this->selectedUrls.size() == 0) { - this->selectTitle(this->menu->GetSelectedIndex()); - this->startInstall(false); - return; - } - this->startInstall(false); - } - } - - if (Down & HidNpadButton_ZL) - this->menu->SetSelectedIndex(std::max(0, this->menu->GetSelectedIndex() - 6)); - - if (Down & HidNpadButton_ZR) - this->menu->SetSelectedIndex(std::min((s32)this->menu->GetItems().size() - 1, this->menu->GetSelectedIndex() + 6)); - } -} \ No newline at end of file diff --git a/source/ui/optionsPage.cpp b/source/ui/optionsPage.cpp deleted file mode 100644 index e579e46..0000000 --- a/source/ui/optionsPage.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include "ui/MainApplication.hpp" -#include "ui/mainPage.hpp" -#include "ui/instPage.hpp" -#include "ui/optionsPage.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/curl.hpp" -#include "util/unzip.hpp" -#include "util/lang.hpp" -#include "ui/instPage.hpp" -#include "sigInstall.hpp" - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - - -namespace inst::ui { - extern MainApplication *mainApp; - s32 prev_touchcount=0; - - std::vector languageStrings = {"En", "Jpn", "Fr", "De", "It", "Ru", "Zh"}; - - optionsPage::optionsPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Settings.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Settings.png")); - else this->titleImage = Image::New(0, 0, "romfs:/images/Settings.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else this->SetBackgroundImage("romfs:/images/Background.png"); - this->appVersionText = TextBlock::New(1210, 680, "v" + inst::config::appVersion); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Settings.png"); - this->appVersionText = TextBlock::New(1210, 680, "v" + inst::config::appVersion); - } - this->appVersionText->SetColor(COLOR("#FFFFFFFF")); - this->appVersionText->SetFont(pu::ui::MakeDefaultFontName(20)); - this->pageInfoText = TextBlock::New(10, 109, "options.title"_lang); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->butText = TextBlock::New(10, 678, "options.buttons"_lang); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 84, (506 / 84)); - this->menu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->menu->SetScrollbarColor(COLOR("#1A1919FF")); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->appVersionText); - this->Add(this->butText); - this->Add(this->pageInfoText); - this->setMenuText(); - this->Add(this->menu); - } - - void optionsPage::askToUpdate(std::vector updateInfo) { - if (!mainApp->CreateShowDialog("options.update.title"_lang, "options.update.desc0"_lang + updateInfo[0] + "options.update.desc1"_lang, {"options.update.opt0"_lang, "common.cancel"_lang}, false)) { - inst::ui::instPage::loadInstallScreen(); - inst::ui::instPage::setTopInstInfoText("options.update.top_info"_lang + updateInfo[0]); - inst::ui::instPage::setInstBarPerc(0); - inst::ui::instPage::setInstInfoText("options.update.bot_info"_lang + updateInfo[0]); - try { - std::string downloadName = inst::config::appDir + "/temp_download.zip"; - inst::curl::downloadFile(updateInfo[1], downloadName.c_str(), 0, true); - romfsExit(); - inst::ui::instPage::setInstInfoText("options.update.bot_info2"_lang + updateInfo[0]); - inst::zip::extractFile(downloadName, "sdmc:/"); - std::filesystem::remove(downloadName); - mainApp->CreateShowDialog("options.update.complete"_lang, "options.update.end_desc"_lang, {"common.ok"_lang}, false); - } catch (...) { - mainApp->CreateShowDialog("options.update.failed"_lang, "options.update.end_desc"_lang, {"common.ok"_lang}, false); - } - mainApp->FadeOut(); - mainApp->Close(); - } - return; - } - - std::string optionsPage::getMenuOptionIcon(bool ourBool) { - if(ourBool) return "romfs:/images/icons/check-box-outline.png"; - else return "romfs:/images/icons/checkbox-blank-outline.png"; - } - - std::string optionsPage::getMenuLanguage(int ourLangCode) { - if (ourLangCode >= 0) return languageStrings[ourLangCode]; - else { - return "options.language.system_language"_lang; - } - } - - void sigPatchesMenuItem_Click() { - sig::installSigPatches(); - } - - void thememessage() { - int ourResult = inst::ui::mainApp->CreateShowDialog("main.theme.title"_lang, "main.theme.desc"_lang, {"common.ok"_lang, "common.cancel"_lang}, true); - if (ourResult != 0) { - // - } - else{ - mainApp->FadeOut(); - mainApp->Close(); - } - } - - void optionsPage::setMenuText() { - this->menu->ClearItems(); - auto ignoreFirmOption = pu::ui::elm::MenuItem::New("options.menu_items.ignore_firm"_lang); - ignoreFirmOption->SetColor(COLOR("#FFFFFFFF")); - ignoreFirmOption->SetIcon(this->getMenuOptionIcon(inst::config::ignoreReqVers)); - this->menu->AddItem(ignoreFirmOption); - auto validateOption = pu::ui::elm::MenuItem::New("options.menu_items.nca_verify"_lang); - validateOption->SetColor(COLOR("#FFFFFFFF")); - validateOption->SetIcon(this->getMenuOptionIcon(inst::config::validateNCAs)); - this->menu->AddItem(validateOption); - auto overclockOption = pu::ui::elm::MenuItem::New("options.menu_items.boost_mode"_lang); - overclockOption->SetColor(COLOR("#FFFFFFFF")); - overclockOption->SetIcon(this->getMenuOptionIcon(inst::config::overClock)); - this->menu->AddItem(overclockOption); - auto deletePromptOption = pu::ui::elm::MenuItem::New("options.menu_items.ask_delete"_lang); - deletePromptOption->SetColor(COLOR("#FFFFFFFF")); - deletePromptOption->SetIcon(this->getMenuOptionIcon(inst::config::deletePrompt)); - this->menu->AddItem(deletePromptOption); - auto autoUpdateOption = pu::ui::elm::MenuItem::New("options.menu_items.auto_update"_lang); - autoUpdateOption->SetColor(COLOR("#FFFFFFFF")); - autoUpdateOption->SetIcon(this->getMenuOptionIcon(inst::config::autoUpdate)); - this->menu->AddItem(autoUpdateOption); - - auto gayModeOption = pu::ui::elm::MenuItem::New("options.menu_items.gay_option"_lang); - gayModeOption->SetColor(COLOR("#FFFFFFFF")); - gayModeOption->SetIcon(this->getMenuOptionIcon(inst::config::gayMode)); - this->menu->AddItem(gayModeOption); - - auto useSoundOption = pu::ui::elm::MenuItem::New("options.menu_items.useSound"_lang); - useSoundOption->SetColor(COLOR("#FFFFFFFF")); - useSoundOption->SetIcon(this->getMenuOptionIcon(inst::config::useSound)); - this->menu->AddItem(useSoundOption); - - auto useoldphp = pu::ui::elm::MenuItem::New("options.menu_items.useoldphp"_lang); - useoldphp->SetColor(COLOR("#FFFFFFFF")); - useoldphp->SetIcon(this->getMenuOptionIcon(inst::config::useoldphp)); - this->menu->AddItem(useoldphp); - - auto SigPatch = pu::ui::elm::MenuItem::New("main.menu.sig"_lang); - SigPatch->SetColor(COLOR("#FFFFFFFF")); - this->menu->AddItem(SigPatch); - - auto sigPatchesUrlOption = pu::ui::elm::MenuItem::New("options.menu_items.sig_url"_lang + inst::util::shortenString(inst::config::sigPatchesUrl, 42, false)); - sigPatchesUrlOption->SetColor(COLOR("#FFFFFFFF")); - this->menu->AddItem(sigPatchesUrlOption); - auto languageOption = pu::ui::elm::MenuItem::New("options.menu_items.language"_lang + this->getMenuLanguage(inst::config::languageSetting)); - languageOption->SetColor(COLOR("#FFFFFFFF")); - this->menu->AddItem(languageOption); - auto updateOption = pu::ui::elm::MenuItem::New("options.menu_items.check_update"_lang); - updateOption->SetColor(COLOR("#FFFFFFFF")); - this->menu->AddItem(updateOption); - auto creditsOption = pu::ui::elm::MenuItem::New("options.menu_items.credits"_lang); - creditsOption->SetColor(COLOR("#FFFFFFFF")); - this->menu->AddItem(creditsOption); - } - - void optionsPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - - if (Down & HidNpadButton_B) { - mainApp->LoadLayout(mainApp->mainPage); - } - - if (Down & HidNpadButton_ZL) - this->menu->SetSelectedIndex(std::max(0, this->menu->GetSelectedIndex() - 6)); - - if (Down & HidNpadButton_ZR) - this->menu->SetSelectedIndex(std::min((s32)this->menu->GetItems().size() - 1, this->menu->GetSelectedIndex() + 6)); - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if ((Down & HidNpadButton_A) || (state.count != prev_touchcount)) - { - prev_touchcount = state.count; - - if (prev_touchcount != 1) { - - std::string keyboardResult; - int rc; - std::vector downloadUrl; - std::vector languageList; - int index = this->menu->GetSelectedIndex(); - switch (index) { - case 0: - inst::config::ignoreReqVers = !inst::config::ignoreReqVers; - inst::config::setConfig(); - this->setMenuText(); - //makes sure to jump back to the selected item once the menu is reloaded - this->menu->SetSelectedIndex(index); - // - break; - case 1: - if (inst::config::validateNCAs) { - if (inst::ui::mainApp->CreateShowDialog("options.nca_warn.title"_lang, "options.nca_warn.desc"_lang, {"common.cancel"_lang, "options.nca_warn.opt1"_lang}, false) == 1) inst::config::validateNCAs = false; - } else inst::config::validateNCAs = true; - inst::config::setConfig(); - this->setMenuText(); - this->menu->SetSelectedIndex(index); - break; - case 2: - inst::config::overClock = !inst::config::overClock; - inst::config::setConfig(); - this->setMenuText(); - this->menu->SetSelectedIndex(index); - break; - case 3: - inst::config::deletePrompt = !inst::config::deletePrompt; - inst::config::setConfig(); - this->setMenuText(); - this->menu->SetSelectedIndex(index); - break; - case 4: - inst::config::autoUpdate = !inst::config::autoUpdate; - inst::config::setConfig(); - this->setMenuText(); - this->menu->SetSelectedIndex(index); - break; - case 5: - if (inst::config::gayMode) { - inst::config::gayMode = false; - mainApp->mainPage->awooImage->SetVisible(false); - - } - else { - inst::config::gayMode = true; - mainApp->mainPage->awooImage->SetVisible(true); - } - this->setMenuText(); - this->menu->SetSelectedIndex(index); - thememessage(); - inst::config::setConfig(); - break; - - case 6: - if (inst::config::useSound) { - inst::config::useSound = false; - } - else { - inst::config::useSound = true; - } - this->setMenuText(); - this->menu->SetSelectedIndex(index); - inst::config::setConfig(); - break; - - case 7: - if (inst::config::useoldphp) { - inst::config::useoldphp = false; - } - else { - inst::config::useoldphp = true; - } - this->setMenuText(); - this->menu->SetSelectedIndex(index); - inst::config::setConfig(); - break; - - case 8: - sigPatchesMenuItem_Click(); - break; - - case 9: - keyboardResult = inst::util::softwareKeyboard("options.sig_hint"_lang, inst::config::sigPatchesUrl.c_str(), 500); - if (keyboardResult.size() > 0) { - inst::config::sigPatchesUrl = keyboardResult; - inst::config::setConfig(); - this->setMenuText(); - this->menu->SetSelectedIndex(index); - } - break; - case 10: - languageList = languageStrings; - languageList.push_back("options.language.system_language"_lang); - rc = inst::ui::mainApp->CreateShowDialog("options.language.title"_lang, "options.language.desc"_lang, languageList, false); - if (rc == -1) break; - switch(rc) { - case 0: - inst::config::languageSetting = 0; - break; - case 1: - inst::config::languageSetting = 1; - break; - case 2: - inst::config::languageSetting = 2; - break; - case 3: - inst::config::languageSetting = 3; - break; - case 4: - inst::config::languageSetting = 4; - break; - case 5: - inst::config::languageSetting = 5; - break; - case 6: - inst::config::languageSetting = 6; - break; - default: - inst::config::languageSetting = 99; - } - inst::config::setConfig(); - mainApp->FadeOut(); - mainApp->Close(); - break; - case 11: - if (inst::util::getIPAddress() == "1.0.0.127") { - inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true); - break; - } - downloadUrl = inst::util::checkForAppUpdate(); - if (!downloadUrl.size()) { - mainApp->CreateShowDialog("options.update.title_check_fail"_lang, "options.update.desc_check_fail"_lang, {"common.ok"_lang}, false); - break; - } - this->askToUpdate(downloadUrl); - break; - case 12: - inst::ui::mainApp->CreateShowDialog("options.credits.title"_lang, "options.credits.desc"_lang, {"common.close"_lang}, true); - break; - default: - break; - } - } - } - } - } -} \ No newline at end of file diff --git a/source/ui/sdInstPage.cpp b/source/ui/sdInstPage.cpp deleted file mode 100644 index 515b992..0000000 --- a/source/ui/sdInstPage.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include -#include "ui/MainApplication.hpp" -#include "ui/mainPage.hpp" -#include "ui/sdInstPage.hpp" -#include "sdInstall.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - -namespace inst::ui { - extern MainApplication *mainApp; - s32 yyy=0; - - sdInstPage::sdInstPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Sd.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Sd.png")); - else this->titleImage = Image::New(0, 0, "romfs:/images/Sd.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else this->SetBackgroundImage("romfs:/images/Background.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Sd.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - this->appVersionText->SetColor(COLOR("#FFFFFFFF")); - this->pageInfoText = TextBlock::New(10, 109, "inst.sd.top_info"_lang); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->butText = TextBlock::New(10, 678, "inst.sd.buttons"_lang); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 84, (506 / 84)); - this->menu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->menu->SetScrollbarColor(COLOR("#1A1919FF")); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->appVersionText); - this->Add(this->butText); - this->Add(this->pageInfoText); - this->Add(this->menu); - } - - void sdInstPage::drawMenuItems(bool clearItems, std::filesystem::path ourPath) { - int myindex = this->menu->GetSelectedIndex(); //store index so when page redraws we can get the last item we checked. - - if (clearItems) this->selectedTitles = {}; - this->currentDir = ourPath; - - auto pathStr = this->currentDir.string(); - - if(pathStr.length()) - { - if(pathStr[pathStr.length() - 1] == ':') - { - this->currentDir = this->currentDir / ""; - } - } - - this->menu->ClearItems(); - try { - this->ourDirectories = util::getDirsAtPath(this->currentDir); - this->ourFiles = util::getDirectoryFiles(this->currentDir, {".nsp", ".nsz", ".xci", ".xcz"}); - } - - catch (std::exception& e) { - this->drawMenuItems(false, this->currentDir.parent_path()); - return; - } - - std::string itm = ".."; - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/folder-upload.png"); - this->menu->AddItem(ourEntry); - - for (auto& file: this->ourDirectories) { - if (file == "..") break; - std::string itm = file.filename().string(); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/folder.png"); - this->menu->AddItem(ourEntry); - } - - for (auto& file: this->ourFiles) { - std::string itm = file.filename().string(); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/checkbox-blank-outline.png"); - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == file) { - ourEntry->SetIcon("romfs:/images/icons/check-box-outline.png"); - } - } - this->menu->AddItem(ourEntry); - this->menu->SetSelectedIndex(myindex); //jump to the index we saved from above - } - } - - void sdInstPage::followDirectory() { - int selectedIndex = this->menu->GetSelectedIndex(); - int dirListSize = this->ourDirectories.size(); - - dirListSize++; - selectedIndex--; - - if (selectedIndex < dirListSize) { - if (this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetName() == ".." && this->menu->GetSelectedIndex() == 0) { - this->drawMenuItems(true, this->currentDir.parent_path()); - } else { - this->drawMenuItems(true, this->ourDirectories[selectedIndex]); - } - this->menu->SetSelectedIndex(0); - } - } - - void sdInstPage::selectNsp(int selectedIndex) { - int dirListSize = this->ourDirectories.size(); - dirListSize++; - - if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") { - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == this->ourFiles[selectedIndex - dirListSize]) this->selectedTitles.erase(this->selectedTitles.begin() + i); - } - } else if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/checkbox-blank-outline.png") this->selectedTitles.push_back(this->ourFiles[selectedIndex - dirListSize]); - else { - this->followDirectory(); - return; - } - this->drawMenuItems(false, currentDir); - } - - void sdInstPage::startInstall() { - int dialogResult = -1; - if (this->selectedTitles.size() == 1) { - dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + inst::util::shortenString(std::filesystem::path(this->selectedTitles[0]).filename().string(), 32, true) + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - } else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedTitles.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - if (dialogResult == -1) return; - nspInstStuff::installNspFromFile(this->selectedTitles, dialogResult); - } - - void sdInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - - if (Down & HidNpadButton_B) { - mainApp->LoadLayout(mainApp->mainPage); - } - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if ((Down & HidNpadButton_A) || (state.count != yyy)) - { - yyy = state.count; - - if (yyy != 1) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - - else { - this->selectNsp(this->menu->GetSelectedIndex()); - - if (this->ourFiles.size() == 1 && this->selectedTitles.size() == 1) { - this->startInstall(); - } - } - - } - } - } - - if ((Down & HidNpadButton_Y)) { - if (this->selectedTitles.size() == this->ourFiles.size()) this->drawMenuItems(true, currentDir); - else { - int topDir = 0; - topDir++; - for (long unsigned int i = this->ourDirectories.size() + topDir; i < this->menu->GetItems().size(); i++) { - if (this->menu->GetItems()[i]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") continue; - else this->selectNsp(i); - } - this->drawMenuItems(false, currentDir); - } - } - - if ((Down & HidNpadButton_X)) { - inst::ui::mainApp->CreateShowDialog("inst.sd.help.title"_lang, "inst.sd.help.desc"_lang, {"common.ok"_lang}, true); - } - - if (Down & HidNpadButton_Plus) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - - else { - if (this->selectedTitles.size() == 0 && this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetIconPath() == "romfs:/images/icons/checkbox-blank-outline.png") { - this->selectNsp(this->menu->GetSelectedIndex()); - } - if (this->selectedTitles.size() > 0) this->startInstall(); - } - } - - if (Down & HidNpadButton_ZL) - this->menu->SetSelectedIndex(std::max(0, this->menu->GetSelectedIndex() - 6)); - - if (Down & HidNpadButton_ZR) - this->menu->SetSelectedIndex(std::min((s32)this->menu->GetItems().size() - 1, this->menu->GetSelectedIndex() + 6)); - } -} \ No newline at end of file diff --git a/source/ui/usbInstPage.cpp b/source/ui/usbInstPage.cpp deleted file mode 100644 index 9c5ee7b..0000000 --- a/source/ui/usbInstPage.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "ui/usbInstPage.hpp" -#include "ui/MainApplication.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" -#include "usbInstall.hpp" - - -#define COLOR(hex) pu::ui::Color::FromHex(hex) - -namespace inst::ui { - extern MainApplication *mainApp; - s32 www=0; //touchscreen variable - - usbInstPage::usbInstPage() : Layout::Layout() { - this->infoRect = Rectangle::New(0, 95, 1280, 60, COLOR("#00000080")); - this->SetBackgroundColor(COLOR("#000000FF")); - this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); - this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); - - if (inst::config::gayMode) { - if (std::filesystem::exists(inst::config::appDir + "/images/Usb.png")) this->titleImage = Image::New(0, 0, (inst::config::appDir + "/images/Usb.png")); - else this->titleImage = Image::New(0, 0, "romfs:/images/Usb.png"); - if (std::filesystem::exists(inst::config::appDir + "/images/Background.png")) this->SetBackgroundImage(inst::config::appDir + "/images/Background.png"); - else this->SetBackgroundImage("romfs:/images/Background.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - else { - this->SetBackgroundImage("romfs:/images/Background.png"); - this->titleImage = Image::New(0, 0, "romfs:/images/Usb.png"); - this->appVersionText = TextBlock::New(0, 0, ""); - } - this->appVersionText->SetColor(COLOR("#FFFFFFFF")); - this->pageInfoText = TextBlock::New(10, 109, ""); - this->pageInfoText->SetColor(COLOR("#FFFFFFFF")); - this->pageInfoText->SetFont(pu::ui::MakeDefaultFontName(30)); - this->butText = TextBlock::New(10, 678, ""); - this->butText->SetColor(COLOR("#FFFFFFFF")); - this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 84, (506 / 84)); - this->menu->SetItemsFocusColor(COLOR("#4f4f4dAA")); - this->menu->SetScrollbarColor(COLOR("#1A1919FF")); - this->infoImage = Image::New(460, 332, "romfs:/images/icons/usb-connection-waiting.png"); - this->Add(this->topRect); - this->Add(this->infoRect); - this->Add(this->botRect); - this->Add(this->titleImage); - this->Add(this->appVersionText); - this->Add(this->butText); - this->Add(this->pageInfoText); - this->Add(this->menu); - this->Add(this->infoImage); - } - - void usbInstPage::drawMenuItems(bool clearItems) { - int myindex = this->menu->GetSelectedIndex(); //store index so when page redraws we can get the last item we checked. - if (clearItems) this->selectedTitles = {}; - this->menu->ClearItems(); - for (auto& url: this->ourTitles) { - std::string itm = inst::util::shortenString(inst::util::formatUrlString(url), 56, true); - auto ourEntry = pu::ui::elm::MenuItem::New(itm); - ourEntry->SetColor(COLOR("#FFFFFFFF")); - ourEntry->SetIcon("romfs:/images/icons/checkbox-blank-outline.png"); - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == url) { - ourEntry->SetIcon("romfs:/images/icons/check-box-outline.png"); - } - } - this->menu->AddItem(ourEntry); - this->menu->SetSelectedIndex(myindex); //jump to the index we saved from above - } - } - - void usbInstPage::selectTitle(int selectedIndex) { - if (this->menu->GetItems()[selectedIndex]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") { - for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) { - if (this->selectedTitles[i] == this->ourTitles[selectedIndex]) this->selectedTitles.erase(this->selectedTitles.begin() + i); - } - } else this->selectedTitles.push_back(this->ourTitles[selectedIndex]); - this->drawMenuItems(false); - } - - void usbInstPage::startUsb() { - this->pageInfoText->SetText("inst.usb.top_info"_lang); - this->butText->SetText("inst.usb.buttons"_lang); - this->menu->SetVisible(false); - this->menu->ClearItems(); - this->infoImage->SetVisible(true); - mainApp->LoadLayout(mainApp->usbinstPage); - mainApp->CallForRender(); - this->ourTitles = usbInstStuff::OnSelected(); - if (!this->ourTitles.size()) { - mainApp->LoadLayout(mainApp->mainPage); - return; - } else { - mainApp->CallForRender(); // If we re-render a few times during this process the main screen won't flicker - this->pageInfoText->SetText("inst.usb.top_info2"_lang); - this->butText->SetText("inst.usb.buttons2"_lang); - this->drawMenuItems(true); - this->menu->SetSelectedIndex(0); - mainApp->CallForRender(); - this->infoImage->SetVisible(false); - this->menu->SetVisible(true); - } - return; - } - - void usbInstPage::startInstall() { - int dialogResult = -1; - if (this->selectedTitles.size() == 1) dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + inst::util::shortenString(inst::util::formatUrlString(this->selectedTitles[0]), 32, true) + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedTitles.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false); - if (dialogResult == -1) return; - usbInstStuff::installTitleUsb(this->selectedTitles, dialogResult); - return; - } - - void usbInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { - if (Down & HidNpadButton_B) { - mainApp->LoadLayout(mainApp->mainPage); - } - - HidTouchScreenState state={0}; - - if (hidGetTouchScreenStates(&state, 1)) { - - if ((Down & HidNpadButton_A) || (state.count != www)) - { - www = state.count; - - if (www != 1) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - else { - this->selectTitle(this->menu->GetSelectedIndex()); - if (this->menu->GetItems().size() == 1 && this->selectedTitles.size() == 1) { - this->startInstall(); - } - } - } - } - } - - if ((Down & HidNpadButton_Y)) { - if (this->selectedTitles.size() == this->menu->GetItems().size()) this->drawMenuItems(true); - else { - for (long unsigned int i = 0; i < this->menu->GetItems().size(); i++) { - if (this->menu->GetItems()[i]->GetIconPath() == "romfs:/images/icons/check-box-outline.png") continue; - else this->selectTitle(i); - } - this->drawMenuItems(false); - } - } - - if (Down & HidNpadButton_Plus) { - int var = this->menu->GetItems().size(); - auto s = std::to_string(var); - - if (s == "0") { - //do nothing here because there's no items in the list, that way the app won't freeze - } - - else { - if (this->selectedTitles.size() == 0) { - this->selectTitle(this->menu->GetSelectedIndex()); - this->startInstall(); - return; - } - this->startInstall(); - } - } - - if (Down & HidNpadButton_ZL) - this->menu->SetSelectedIndex(std::max(0, this->menu->GetSelectedIndex() - 6)); - - if (Down & HidNpadButton_ZR) - this->menu->SetSelectedIndex(std::min((s32)this->menu->GetItems().size() - 1, this->menu->GetSelectedIndex() + 6)); - } -} \ No newline at end of file diff --git a/source/usbInstall.cpp b/source/usbInstall.cpp deleted file mode 100644 index 1199c3e..0000000 --- a/source/usbInstall.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include -#include "usbInstall.hpp" -#include "install/usb_nsp.hpp" -#include "install/install_nsp.hpp" -#include "install/usb_xci.hpp" -#include "install/install_xci.hpp" -#include "util/error.hpp" -#include "util/usb_util.hpp" -#include "util/util.hpp" -#include "util/config.hpp" -#include "util/lang.hpp" -#include "ui/MainApplication.hpp" -#include "ui/usbInstPage.hpp" -#include "ui/instPage.hpp" - -namespace inst::ui { - extern MainApplication *mainApp; -} - -namespace usbInstStuff { - struct TUSHeader - { - u32 magic; // TUL0 (Tinfoil Usb List 0) - u32 titleListSize; - u64 padding; - } PACKED; - - int bufferData(void* buf, size_t size, u64 timeout = 5000000000) - { - u8* tempBuffer = (u8*)memalign(0x1000, size); - if (tin::util::USBRead(tempBuffer, size, timeout) == 0) return 0; - memcpy(buf, tempBuffer, size); - free(tempBuffer); - return size; - } - - std::vector OnSelected() { - TUSHeader header; - - padConfigureInput(8, HidNpadStyleSet_NpadStandard); - PadState pad; - padInitializeAny(&pad); - - while(true) { - if (bufferData(&header, sizeof(TUSHeader), 500000000) != 0) break; - - padUpdate(&pad); - u64 kDown = padGetButtonsDown(&pad); - - if (kDown & HidNpadButton_B) return {}; - if (kDown & HidNpadButton_X) inst::ui::mainApp->CreateShowDialog("inst.usb.help.title"_lang, "inst.usb.help.desc"_lang, {"common.ok"_lang}, true); - if (inst::util::getUsbState() != 5) return {}; - } - - if (header.magic != 0x304C5554) return {}; - - std::vector titleNames; - char* titleNameBuffer = (char*)memalign(0x1000, header.titleListSize + 1); - memset(titleNameBuffer, 0, header.titleListSize + 1); - - tin::util::USBRead(titleNameBuffer, header.titleListSize, 10000000000); - - // Split the string up into individual title names - std::stringstream titleNamesStream(titleNameBuffer); - std::string segment; - while (std::getline(titleNamesStream, segment, '\n')) titleNames.push_back(segment); - free(titleNameBuffer); - std::sort(titleNames.begin(), titleNames.end(), inst::util::ignoreCaseCompare); - - return titleNames; - } - - void installTitleUsb(std::vector ourTitleList, int ourStorage) - { - inst::util::initInstallServices(); - inst::ui::instPage::loadInstallScreen(); - bool nspInstalled = true; - NcmStorageId m_destStorageId = NcmStorageId_SdCard; - - if (ourStorage) m_destStorageId = NcmStorageId_BuiltInUser; - unsigned int fileItr; - - std::vector fileNames; - for (long unsigned int i = 0; i < ourTitleList.size(); i++) { - fileNames.push_back(inst::util::shortenString(inst::util::formatUrlString(ourTitleList[i]), 40, true)); - } - - std::vector previousClockValues; - if (inst::config::overClock) { - previousClockValues.push_back(inst::util::setClockSpeed(0, 1785000000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(1, 76800000)[0]); - previousClockValues.push_back(inst::util::setClockSpeed(2, 1600000000)[0]); - } - - try { - for (fileItr = 0; fileItr < ourTitleList.size(); fileItr++) { - inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + fileNames[fileItr] + "inst.usb.source_string"_lang); - std::unique_ptr installTask; - - if (ourTitleList[fileItr].compare(ourTitleList[fileItr].size() - 3, 2, "xc") == 0) { - auto usbXCI = std::make_shared(ourTitleList[fileItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, usbXCI); - } else { - auto usbNSP = std::make_shared(ourTitleList[fileItr]); - installTask = std::make_unique(m_destStorageId, inst::config::ignoreReqVers, usbNSP); - } - - LOG_DEBUG("%s\n", "Preparing installation"); - inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang); - inst::ui::instPage::setInstBarPerc(0); - installTask->Prepare(); - - installTask->Begin(); - } - } - catch (std::exception& e) { - LOG_DEBUG("Failed to install"); - LOG_DEBUG("%s", e.what()); - fprintf(stdout, "%s", e.what()); - inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + fileNames[fileItr]); - inst::ui::instPage::setInstBarPerc(0); - std::string audioPath = ""; - if (std::filesystem::exists(inst::config::appDir + "/sounds/OHNO.WAV")) { - audioPath = (inst::config::appDir + "/sounds/OHNO.WAV"); - } - else { - audioPath = "romfs:/audio/bark.wav"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + fileNames[fileItr] + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true); - audioThread.join(); - nspInstalled = false; - } - - if (previousClockValues.size() > 0) { - inst::util::setClockSpeed(0, previousClockValues[0]); - inst::util::setClockSpeed(1, previousClockValues[1]); - inst::util::setClockSpeed(2, previousClockValues[2]); - } - - if(nspInstalled) { - tin::util::USBCmdManager::SendExitCmd(); - inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang); - inst::ui::instPage::setInstBarPerc(100); - std::string audioPath = ""; - - if (inst::config::useSound) { - if (std::filesystem::exists(inst::config::appDir + "/sounds/YIPPEE.WAV")) { - audioPath = (inst::config::appDir + "/sounds/YIPPEE.WAV"); - } - else { - audioPath = "romfs:/audio/ameizing.mp3"; - } - std::thread audioThread(inst::util::playAudio,audioPath); - - if (ourTitleList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - else inst::ui::mainApp->CreateShowDialog(fileNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - audioThread.join(); - } - else{ - if (ourTitleList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - else inst::ui::mainApp->CreateShowDialog(fileNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true); - } - } - - LOG_DEBUG("Done"); - inst::ui::instPage::loadMainMenu(); - inst::util::deinitInstallServices(); - return; - } -} \ No newline at end of file diff --git a/source/util/config.cpp b/source/util/config.cpp deleted file mode 100644 index 0987686..0000000 --- a/source/util/config.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include "util/config.hpp" -#include "util/json.hpp" - -namespace inst::config { - std::string gAuthKey; - std::string sigPatchesUrl; - std::string httpIndexUrl; - std::string httplastUrl; - std::vector updateInfo; - int languageSetting; - bool autoUpdate; - bool deletePrompt; - bool ignoreReqVers; - bool overClock; - bool gayMode; - bool useSound; - bool usbAck; - bool validateNCAs; - bool useoldphp; - - void setConfig() { - nlohmann::json j = { - {"autoUpdate", autoUpdate}, - {"deletePrompt", deletePrompt}, - {"gAuthKey", gAuthKey}, - {"gayMode", gayMode}, - {"useSound", useSound}, - {"ignoreReqVers", ignoreReqVers}, - {"languageSetting", languageSetting}, - {"overClock", overClock}, - {"sigPatchesUrl", sigPatchesUrl}, - {"usbAck", usbAck}, - {"validateNCAs", validateNCAs}, - {"httpIndexUrl", httpIndexUrl}, - {"httplastUrl", httplastUrl}, - {"httpoldphp", useoldphp} - }; - std::ofstream file(inst::config::configPath); - file << std::setw(4) << j << std::endl; - } - - void parseConfig() { - try { - std::ifstream file(inst::config::configPath); - nlohmann::json j; - file >> j; - autoUpdate = j["autoUpdate"].get(); - useoldphp = j["httpoldphp"].get(); - deletePrompt = j["deletePrompt"].get(); - gAuthKey = j["gAuthKey"].get(); - gayMode = j["gayMode"].get(); - useSound = j["useSound"].get(); - ignoreReqVers = j["ignoreReqVers"].get(); - languageSetting = j["languageSetting"].get(); - overClock = j["overClock"].get(); - sigPatchesUrl = j["sigPatchesUrl"].get(); - httpIndexUrl = j["httpIndexUrl"].get(); - httplastUrl = j["httplastUrl"].get(); - usbAck = j["usbAck"].get(); - validateNCAs = j["validateNCAs"].get(); - } - catch (...) { - // If loading values from the config fails, we just load the defaults and overwrite the old config - gAuthKey = {0x41,0x49,0x7a,0x61,0x53,0x79,0x42,0x4d,0x71,0x76,0x34,0x64,0x58,0x6e,0x54,0x4a,0x4f,0x47,0x51,0x74,0x5a,0x5a,0x53,0x33,0x43,0x42,0x6a,0x76,0x66,0x37,0x34,0x38,0x51,0x76,0x78,0x53,0x7a,0x46,0x30}; - sigPatchesUrl = "https://github.com/mrdude2478/patches/releases/download/1/patches.zip"; - languageSetting = 0; - httpIndexUrl = "http://"; - httplastUrl = "http://"; - autoUpdate = true; - deletePrompt = true; - gayMode = false; - useSound = false; - useoldphp = false; - ignoreReqVers = true; - overClock = false; - usbAck = false; - validateNCAs = true; - setConfig(); - } - } -} \ No newline at end of file diff --git a/source/util/crypto.cpp b/source/util/crypto.cpp deleted file mode 100644 index 58265d5..0000000 --- a/source/util/crypto.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "util/crypto.hpp" -#include -#include -#include -#include "util/error.hpp" - -void Crypto::calculateMGF1andXOR(unsigned char* data, size_t data_size, const void* source, size_t source_size) { - unsigned char h_buf[RSA_2048_BYTES] = {0}; - memcpy(h_buf, source, source_size); - - unsigned char mgf1_buf[0x20]; - size_t ofs = 0; - unsigned int seed = 0; - while (ofs < data_size) { - for (unsigned int i = 0; i < sizeof(seed); i++) { - h_buf[source_size + 3 - i] = (seed >> (8 * i)) & 0xFF; - } - sha256CalculateHash(mgf1_buf, h_buf, source_size + 4); - for (unsigned int i = ofs; i < data_size && i < ofs + 0x20; i++) { - data[i] ^= mgf1_buf[i - ofs]; - } - seed++; - ofs += 0x20; - } -} - -bool Crypto::rsa2048PssVerify(const void *data, size_t len, const unsigned char *signature, const unsigned char *modulus) { - mbedtls_mpi signature_mpi; - mbedtls_mpi modulus_mpi; - mbedtls_mpi e_mpi; - mbedtls_mpi message_mpi; - - mbedtls_mpi_init(&signature_mpi); - mbedtls_mpi_init(&modulus_mpi); - mbedtls_mpi_init(&e_mpi); - mbedtls_mpi_init(&message_mpi); - mbedtls_mpi_lset(&message_mpi, RSA_2048_BITS); - - unsigned char m_buf[RSA_2048_BYTES]; - unsigned char h_buf[0x24]; - const unsigned char E[3] = {1, 0, 1}; - - mbedtls_mpi_read_binary(&e_mpi, E, 3); - mbedtls_mpi_read_binary(&signature_mpi, signature, RSA_2048_BYTES); - mbedtls_mpi_read_binary(&modulus_mpi, modulus, RSA_2048_BYTES); - mbedtls_mpi_exp_mod(&message_mpi, &signature_mpi, &e_mpi, &modulus_mpi, NULL); - - if (mbedtls_mpi_write_binary(&message_mpi, m_buf, RSA_2048_BYTES) != 0) { - THROW_FORMAT("Failed to export exponentiated RSA message!"); - } - - mbedtls_mpi_free(&signature_mpi); - mbedtls_mpi_free(&modulus_mpi); - mbedtls_mpi_free(&e_mpi); - mbedtls_mpi_free(&message_mpi); - - /* There's no automated PSS verification as far as I can tell. */ - if (m_buf[RSA_2048_BYTES-1] != 0xBC) { - return false; - } - - memset(h_buf, 0, 0x24); - memcpy(h_buf, m_buf + RSA_2048_BYTES - 0x20 - 0x1, 0x20); - - /* Decrypt maskedDB. */ - calculateMGF1andXOR(m_buf, RSA_2048_BYTES - 0x20 - 1, h_buf, 0x20); - - m_buf[0] &= 0x7F; /* Constant lmask for rsa-2048-pss. */ - - /* Validate DB. */ - for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) { - if (m_buf[i] != 0) { - return false; - } - } - if (m_buf[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) { - return false; - } - - /* Check hash correctness. */ - unsigned char validate_buf[8 + 0x20 + 0x20]; - unsigned char validate_hash[0x20]; - memset(validate_buf, 0, 0x48); - - sha256CalculateHash(&validate_buf[8], data, len); - memcpy(&validate_buf[0x28], &m_buf[RSA_2048_BYTES - 0x20 - 0x20 - 1], 0x20); - sha256CalculateHash(validate_hash, validate_buf, 0x48); - - return memcmp(h_buf, validate_hash, 0x20) == 0; -} \ No newline at end of file diff --git a/source/util/curl.cpp b/source/util/curl.cpp deleted file mode 100644 index 861b4cc..0000000 --- a/source/util/curl.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include "util/curl.hpp" -#include "util/config.hpp" -#include "util/error.hpp" -#include "ui/instPage.hpp" - -static size_t writeDataFile(void *ptr, size_t size, size_t nmemb, void *stream) { - size_t written = fwrite(ptr, size, nmemb, (FILE *)stream); - return written; -} - -size_t writeDataBuffer(char *ptr, size_t size, size_t nmemb, void *userdata) { - std::ostringstream *stream = (std::ostringstream*)userdata; - size_t count = size * nmemb; - stream->write(ptr, count); - return count; -} - -int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { - if (ultotal) { - int uploadProgress = (int)(((double)ulnow / (double)ultotal) * 100.0); - inst::ui::instPage::setInstBarPerc(uploadProgress); - } else if (dltotal) { - int downloadProgress = (int)(((double)dlnow / (double)dltotal) * 100.0); - inst::ui::instPage::setInstBarPerc(downloadProgress); - } - return 0; -} - -namespace inst::curl { - bool downloadFile (const std::string ourUrl, const char *pagefilename, long timeout, bool writeProgress) { - CURL *curl_handle; - CURLcode result; - FILE *pagefile; - - curl_global_init(CURL_GLOBAL_ALL); - curl_handle = curl_easy_init(); - - curl_easy_setopt(curl_handle, CURLOPT_URL, ourUrl.c_str()); - curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "TinWoo"); - curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout); - curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, timeout); - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeDataFile); - if (writeProgress) curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, progress_callback); - - pagefile = fopen(pagefilename, "wb"); - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile); - result = curl_easy_perform(curl_handle); - - curl_easy_cleanup(curl_handle); - curl_global_cleanup(); - fclose(pagefile); - - if (result == CURLE_OK) return true; - else { - LOG_DEBUG(curl_easy_strerror(result)); - return false; - } - } - - std::string downloadToBuffer (const std::string ourUrl, int firstRange, int secondRange, long timeout) { - CURL *curl_handle; - CURLcode result; - std::ostringstream stream; - - curl_global_init(CURL_GLOBAL_ALL); - curl_handle = curl_easy_init(); - - curl_easy_setopt(curl_handle, CURLOPT_URL, ourUrl.c_str()); - curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "TinWoo"); - curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout); - curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, timeout); - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeDataBuffer); - if (firstRange && secondRange) { - const char * ourRange = (std::to_string(firstRange) + "-" + std::to_string(secondRange)).c_str(); - curl_easy_setopt(curl_handle, CURLOPT_RANGE, ourRange); - } - - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &stream); - result = curl_easy_perform(curl_handle); - - curl_easy_cleanup(curl_handle); - curl_global_cleanup(); - - if (result == CURLE_OK) return stream.str(); - else { - LOG_DEBUG(curl_easy_strerror(result)); - return ""; - } - } -} \ No newline at end of file diff --git a/source/util/debug.c b/source/util/debug.c deleted file mode 100644 index 6446de0..0000000 --- a/source/util/debug.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "util/debug.h" - -#include - -#include -#include -#include -#include - -void printBytes(u8 *bytes, size_t size, bool includeHeader) -{ -#ifdef NXLINK_DEBUG - int count = 0; - - if (includeHeader) - { - printf("\n\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"); - printf("-----------------------------------------------\n"); - } - - for (int i = 0; i < size; i++) - { - printf("%02x ", bytes[i]); - count++; - if ((count % 16) == 0) - printf("\n"); - } - - printf("\n"); -#endif -} \ No newline at end of file diff --git a/source/util/file_util.cpp b/source/util/file_util.cpp deleted file mode 100644 index a099355..0000000 --- a/source/util/file_util.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "util/file_util.hpp" - -#include - -#include "install/simple_filesystem.hpp" -#include "nx/fs.hpp" -#include "data/byte_buffer.hpp" -#include "util/title_util.hpp" - -namespace tin::util -{ - // TODO: do this manually so we don't have to "install" the cnmt's - nx::ncm::ContentMeta GetContentMetaFromNCA(const std::string& ncaPath) - { - // Create the cnmt filesystem - nx::fs::IFileSystem cnmtNCAFileSystem; - cnmtNCAFileSystem.OpenFileSystemWithId(ncaPath, FsFileSystemType_ContentMeta, 0); - tin::install::nsp::SimpleFileSystem cnmtNCASimpleFileSystem(cnmtNCAFileSystem, "/", ncaPath + "/"); - - // Find and read the cnmt file - auto cnmtName = cnmtNCASimpleFileSystem.GetFileNameFromExtension("", "cnmt"); - auto cnmtFile = cnmtNCASimpleFileSystem.OpenFile(cnmtName); - u64 cnmtSize = cnmtFile.GetSize(); - - tin::data::ByteBuffer cnmtBuf; - cnmtBuf.Resize(cnmtSize); - cnmtFile.Read(0x0, cnmtBuf.GetData(), cnmtSize); - - return nx::ncm::ContentMeta(cnmtBuf.GetData(), cnmtBuf.GetSize()); - } -} \ No newline at end of file diff --git a/source/util/lang.cpp b/source/util/lang.cpp deleted file mode 100644 index 4d3f965..0000000 --- a/source/util/lang.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include "util/lang.hpp" -#include "util/config.hpp" - -namespace Language { - json lang; - - void Load() { - std::ifstream ifs; - std::string languagePath; - int langInt = inst::config::languageSetting; - if (langInt == 99) { - SetLanguage ourLang; - u64 lcode = 0; - setInitialize(); - setGetSystemLanguage(&lcode); - setMakeLanguage(lcode, &ourLang); - setExit(); - langInt = (int)ourLang; - } - switch (langInt) { - case 0: - languagePath = "romfs:/lang/en.json"; - break; - case 1: - languagePath = "romfs:/lang/jp.json"; - break; - case 2: - languagePath = "romfs:/lang/fr.json"; - break; - case 3: - languagePath = "romfs:/lang/de.json"; - break; - case 4: - languagePath = "romfs:/lang/it.json"; - break; - case 5: - languagePath = "romfs:/lang/ru.json"; - break; - case 6: - languagePath = "romfs:/lang/zh-rTW.json"; - break; - case 99: - languagePath = "romfs:/lang/en.json"; - break; - default: - if (std::filesystem::exists(inst::config::appDir + "/lang/custom.json")) { - languagePath = (inst::config::appDir + "/lang/custom.json"); - } - else{ - languagePath = "romfs:/lang/en.json"; - } - } - if (std::filesystem::exists(languagePath)) ifs = std::ifstream(languagePath); - else ifs = std::ifstream("romfs:/lang/en.json"); - if (!ifs.good()) { - std::cout << "[FAILED TO LOAD LANGUAGE FILE]" << std::endl; - return; - } - lang = json::parse(ifs); - ifs.close(); - } - - std::string LanguageEntry(std::string key) { - json j = GetRelativeJson(lang, key); - if (j == nullptr) { - return "didn't find: " + key; - } - return j.get(); - } - - std::string GetRandomMsg() { - json j = Language::GetRelativeJson(lang, "inst.finished"); - srand(time(NULL)); - return(j[rand() % j.size()]); - } -} \ No newline at end of file diff --git a/source/util/network_util.cpp b/source/util/network_util.cpp deleted file mode 100644 index 5269ca9..0000000 --- a/source/util/network_util.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "util/network_util.hpp" - -#include -#include -#include -#include -#include -#include "util/error.hpp" - -namespace tin::network -{ - // HTTPHeader - - HTTPHeader::HTTPHeader(std::string url) : - m_url(url) - { - } - - size_t HTTPHeader::ParseHTMLHeader(char* bytes, size_t size, size_t numItems, void* userData) - { - HTTPHeader* header = reinterpret_cast(userData); - size_t numBytes = size * numItems; - std::string line(bytes, numBytes); - - // Remove any newlines or carriage returns - line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); - line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); - - // Split into key and value - if (!line.empty()) - { - auto keyEnd = line.find(": "); - - if (keyEnd != 0) - { - std::string key = line.substr(0, keyEnd); - std::string value = line.substr(keyEnd + 2); - - // Make key lowercase - std::transform(key.begin(), key.end(), key.begin(), ::tolower); - header->m_values[key] = value; - } - } - - return numBytes; - } - - void HTTPHeader::PerformRequest() - { - // We don't want any existing values to get mixed up with this request - m_values.clear(); - - CURL* curl = curl_easy_init(); - CURLcode rc = (CURLcode)0; - - if (!curl) - { - THROW_FORMAT("Failed to initialize curl\n"); - } - - curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOBODY, true); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "tinfoil"); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, this); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &tin::network::HTTPHeader::ParseHTMLHeader); - - rc = curl_easy_perform(curl); - if (rc != CURLE_OK) - { - THROW_FORMAT("Failed to retrieve HTTP Header: %s\n", curl_easy_strerror(rc)); - } - - u64 httpCode = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); - curl_easy_cleanup(curl); - - if (httpCode != 200 && httpCode != 204) - { - THROW_FORMAT("Unexpected HTTP response code when retrieving header: %lu\n", httpCode); - } - } - - bool HTTPHeader::HasValue(std::string key) - { - return m_values.count(key); - } - - std::string HTTPHeader::GetValue(std::string key) - { - return m_values[key]; - } - - // End HTTPHeader - // HTTPDownload - - HTTPDownload::HTTPDownload(std::string url) : - m_url(url), m_header(url) - { - // The header won't be populated until we do this - m_header.PerformRequest(); - - if (m_header.HasValue("accept-ranges")) - { - m_rangesSupported = m_header.GetValue("accept-ranges") == "bytes"; - } - else - { - CURL* curl = curl_easy_init(); - CURLcode rc = (CURLcode)0; - - if (!curl) - { - THROW_FORMAT("Failed to initialize curl\n"); - } - - curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOBODY, true); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "tinfoil"); - curl_easy_setopt(curl, CURLOPT_RANGE, "0-0"); - - rc = curl_easy_perform(curl); - if (rc != CURLE_OK) - { - THROW_FORMAT("Failed to retrieve HTTP Header: %s\n", curl_easy_strerror(rc)); - } - - u64 httpCode = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); - curl_easy_cleanup(curl); - - m_rangesSupported = httpCode == 206; - } - } - - size_t HTTPDownload::ParseHTMLData(char* bytes, size_t size, size_t numItems, void* userData) - { - auto streamFunc = *reinterpret_cast*>(userData); - size_t numBytes = size * numItems; - - if (streamFunc != nullptr) - return streamFunc((u8*)bytes, numBytes); - - return numBytes; - } - - void HTTPDownload::BufferDataRange(void* buffer, size_t offset, size_t size, std::function progressFunc) - { - size_t sizeRead = 0; - - auto streamFunc = [&](u8* streamBuf, size_t streamBufSize) -> size_t - { - if (sizeRead + streamBufSize > size) - { - LOG_DEBUG("New read size 0x%lx would exceed total expected size 0x%lx\n", sizeRead + streamBufSize, size); - return 0; - } - - if (progressFunc != nullptr) - progressFunc(sizeRead); - - memcpy(reinterpret_cast(buffer) + sizeRead, streamBuf, streamBufSize); - sizeRead += streamBufSize; - return streamBufSize; - }; - - this->StreamDataRange(offset, size, streamFunc); - } - - int HTTPDownload::StreamDataRange(size_t offset, size_t size, std::function streamFunc) - { - if (!m_rangesSupported) - { - THROW_FORMAT("Attempted range request when ranges aren't supported!\n"); - } - - auto writeDataFunc = streamFunc; - - CURL* curl = curl_easy_init(); - CURLcode rc = (CURLcode)0; - - if (!curl) - { - THROW_FORMAT("Failed to initialize curl\n"); - } - - std::stringstream ss; - ss << offset << "-" << (offset + size - 1); - auto range = ss.str(); - - curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str()); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "tinfoil"); - curl_easy_setopt(curl, CURLOPT_RANGE, range.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &writeDataFunc); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &tin::network::HTTPDownload::ParseHTMLData); - - rc = curl_easy_perform(curl); - - u64 httpCode = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); - curl_easy_cleanup(curl); - - if (httpCode != 206 || rc != CURLE_OK) return 1; - return 0; - } - - // End HTTPDownload - - size_t WaitReceiveNetworkData(int sockfd, void* buf, size_t len) - { - int ret = 0; - size_t read = 0; - padConfigureInput(1, HidNpadStyleSet_NpadStandard); - PadState pad; - padInitializeDefault(&pad); - - while ((((ret = recv(sockfd, (u8*)buf + read, len - read, 0)) > 0 && (read += ret) < len) || errno == EAGAIN) && !(padGetButtonsDown(&pad) & HidNpadButton_B)) - { - errno = 0; - padUpdate(&pad); //test - } - - return read; - } - - size_t WaitSendNetworkData(int sockfd, void* buf, size_t len) - { - errno = 0; - int ret = 0; - size_t written = 0; - padConfigureInput(1, HidNpadStyleSet_NpadStandard); - PadState pad; - padInitializeDefault(&pad); - - while ((((ret = send(sockfd, (u8*)buf + written, len - written, 0)) > 0 && (written += ret) < len) || errno == EAGAIN) && !(padGetButtonsDown(&pad) & HidNpadButton_B)) - { - errno = 0; - padUpdate(&pad); //test - } - - return written; - } -} \ No newline at end of file diff --git a/source/util/title_util.cpp b/source/util/title_util.cpp deleted file mode 100644 index 7e05cef..0000000 --- a/source/util/title_util.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "util/title_util.hpp" - -#include -#include "util/error.hpp" - -namespace tin::util -{ - u64 GetRightsIdTid(RightsId rightsId) - { - return __bswap64(*(u64 *)rightsId.c); - } - - u64 GetRightsIdKeyGen(RightsId rightsId) - { - return __bswap64(*(u64 *)(rightsId.c + 8)); - } - - std::string GetNcaIdString(const NcmContentId& ncaId) - { - char ncaIdStr[FS_MAX_PATH] = {0}; - u64 ncaIdLower = __bswap64(*(u64 *)ncaId.c); - u64 ncaIdUpper = __bswap64(*(u64 *)(ncaId.c + 0x8)); - snprintf(ncaIdStr, FS_MAX_PATH, "%016lx%016lx", ncaIdLower, ncaIdUpper); - return std::string(ncaIdStr); - } - - NcmContentId GetNcaIdFromString(std::string ncaIdStr) - { - NcmContentId ncaId = {0}; - char lowerU64[17] = {0}; - char upperU64[17] = {0}; - memcpy(lowerU64, ncaIdStr.c_str(), 16); - memcpy(upperU64, ncaIdStr.c_str() + 16, 16); - - *(u64 *)ncaId.c = __bswap64(strtoul(lowerU64, NULL, 16)); - *(u64 *)(ncaId.c + 8) = __bswap64(strtoul(upperU64, NULL, 16)); - - return ncaId; - } - - u64 GetBaseTitleId(u64 titleId, NcmContentMetaType contentMetaType) - { - switch (contentMetaType) - { - case NcmContentMetaType_Patch: - return titleId ^ 0x800; - - case NcmContentMetaType_AddOnContent: - return (titleId ^ 0x1000) & ~0xFFF; - - default: - return titleId; - } - } - - std::string GetBaseTitleName(u64 baseTitleId) - { - Result rc = 0; - NsApplicationControlData appControlData; - size_t sizeRead; - - if (R_FAILED(rc = nsGetApplicationControlData(NsApplicationControlSource_Storage, baseTitleId, &appControlData, sizeof(NsApplicationControlData), &sizeRead))) - { - LOG_DEBUG("Failed to get application control data. Error code: 0x%08x\n", rc); - return "Unknown"; - } - - if (sizeRead < sizeof(appControlData.nacp)) - { - LOG_DEBUG("Incorrect size for nacp\n"); - return "Unknown"; - } - - NacpLanguageEntry *languageEntry; - - if (R_FAILED(rc = nacpGetLanguageEntry(&appControlData.nacp, &languageEntry))) - { - LOG_DEBUG("Failed to get language entry. Error code: 0x%08x\n", rc); - return "Unknown"; - } - - if (languageEntry == NULL) - { - LOG_DEBUG("Language entry is null! Error code: 0x%08x\n", rc); - return "Unknown"; - } - - return languageEntry->name; - } - - std::string GetTitleName(u64 titleId, NcmContentMetaType contentMetaType) - { - u64 baseTitleId = GetBaseTitleId(titleId, contentMetaType); - std::string titleName = GetBaseTitleName(baseTitleId); - - switch (contentMetaType) - { - case NcmContentMetaType_Patch: - titleName += " (Update)"; - break; - - case NcmContentMetaType_AddOnContent: - titleName += " (DLC)"; - break; - - default: - break; - } - - return titleName; - } -} \ No newline at end of file diff --git a/source/util/unzip.cpp b/source/util/unzip.cpp deleted file mode 100644 index e91dcf3..0000000 --- a/source/util/unzip.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// https://github.com/AtlasNX/Kosmos-Updater/blob/master/source/FileManager.cpp - -unz_file_info_s * _getFileInfo(unzFile unz) { - unz_file_info_s * fileInfo = (unz_file_info_s*) malloc(sizeof(unz_file_info_s)); - unzGetCurrentFileInfo(unz, fileInfo, NULL, 0, NULL, 0, NULL, 0); - return fileInfo; -} - -std::string _getFullFileName(unzFile unz, unz_file_info_s * fileInfo) { - char filePath[fileInfo->size_filename + 1]; - - unzGetCurrentFileInfo(unz, fileInfo, filePath, fileInfo->size_filename, NULL, 0, NULL, 0); - filePath[fileInfo->size_filename] = '\0'; - - std::string path(filePath); - path.resize(fileInfo->size_filename); - - return path; -} - -bool _makeDirectoryParents(std::string path) -{ - bool bSuccess = false; - int nRC = ::mkdir(path.c_str(), 0775); - if(nRC == -1) - { - switch(errno) - { - case ENOENT: - //parent didn't exist, try to create it - if( _makeDirectoryParents(path.substr(0, path.find_last_of('/')))) - //Now, try to create again. - bSuccess = 0 == ::mkdir(path.c_str(), 0775); - else - bSuccess = false; - break; - case EEXIST: - //Done! - bSuccess = true; - break; - //std::string getHost(); - default: - bSuccess = false; - break; - } - } - else - bSuccess = true; - - return bSuccess; -} - -int _extractFile(const char * path, unzFile unz, unz_file_info_s * fileInfo) { - //check to make sure filepath or fileInfo isnt null - if (path == NULL || fileInfo == NULL) - return -1; - - if (unzOpenCurrentFile(unz) != UNZ_OK) - return -2; - - char folderPath[strlen(path) + 1]; - strcpy(folderPath, path); - char * pos = strrchr(folderPath, '/'); - if (pos != NULL) { - *pos = '\0'; - _makeDirectoryParents(std::string(folderPath)); - } - - u32 blocksize = 0x8000; - u8 * buffer = (u8*) malloc(blocksize); - if (buffer == NULL) - return -3; - u32 done = 0; - int writeBytes = 0; - FILE * fp = fopen(path, "w"); - if (fp == NULL) { - free(buffer); - return -4; - } - - while (done < fileInfo->uncompressed_size) { - if (done + blocksize > fileInfo->uncompressed_size) { - blocksize = fileInfo->uncompressed_size - done; - } - unzReadCurrentFile(unz, buffer, blocksize); - writeBytes = write(fileno(fp), buffer, blocksize); - if (writeBytes <= 0) { - break; - } - done += writeBytes; - } - - fflush(fp); - fsync(fileno(fp)); - fclose(fp); - - free(buffer); - if (done != fileInfo->uncompressed_size) - return -4; - - unzCloseCurrentFile(unz); - return 0; -} - -namespace inst::zip { - bool extractFile(const std::string filename, const std::string destination) { - unzFile unz = unzOpen(filename.c_str()); - - int i = 0; - for (;;) { - int code; - if (i == 0) { - code = unzGoToFirstFile(unz); - } else { - code = unzGoToNextFile(unz); - } - i++; - - if (code == UNZ_END_OF_LIST_OF_FILE) { - break; - } else { - unz_file_pos pos; - unzGetFilePos(unz, &pos); - } - - unz_file_info_s * fileInfo = _getFileInfo(unz); - - std::string fileName = destination; - fileName += _getFullFileName(unz, fileInfo); - - if (fileName.back() != '/') { - int result = _extractFile(fileName.c_str(), unz, fileInfo); - if (result < 0) { - free(fileInfo); - unzClose(unz); - return false; - } - } - - free(fileInfo); - } - - if (i <= 0) { - unzClose(unz); - return false; - } - - unzClose(unz); - return true; - } -} \ No newline at end of file diff --git a/source/util/usb_comms_tinleaf.c b/source/util/usb_comms_tinleaf.c deleted file mode 100644 index 92edfa7..0000000 --- a/source/util/usb_comms_tinleaf.c +++ /dev/null @@ -1,595 +0,0 @@ -#include -#include -#include "switch/types.h" -#include "switch/result.h" -#include "switch/kernel/rwlock.h" -#include "switch/services/fatal.h" -#include "switch/services/usbds.h" -#include "switch/runtime/hosversion.h" -#include "util/usb_comms_tinleaf.h" -#include - -#define TOTAL_INTERFACES 4 - -typedef struct { - RwLock lock, lock_in, lock_out; - bool initialized; - - UsbDsInterface* interface; - UsbDsEndpoint *endpoint_in, *endpoint_out; - - u8 *endpoint_in_buffer, *endpoint_out_buffer; -} usbCommsInterface; - -static bool g_usbCommsInitialized = false; - -static usbCommsInterface g_usbCommsInterfaces[TOTAL_INTERFACES]; - -static bool g_usbCommsErrorHandling = 0; - -static RwLock g_usbCommsLock; - -static Result _usbCommsInterfaceInit1x(u32 intf_ind, const tinleaf_UsbCommsInterfaceInfo *info); -static Result _usbCommsInterfaceInit5x(u32 intf_ind, const tinleaf_UsbCommsInterfaceInfo *info); -static Result _usbCommsInterfaceInit(u32 intf_ind, const tinleaf_UsbCommsInterfaceInfo *info); - -static Result _usbCommsWrite(usbCommsInterface *interface, const void* buffer, size_t size, size_t *transferredSize, u64 timeout); - -static void _usbCommsUpdateInterfaceDescriptor(struct usb_interface_descriptor *desc, const tinleaf_UsbCommsInterfaceInfo *info) { - if (info != NULL) { - desc->bInterfaceClass = info->bInterfaceClass; - desc->bInterfaceSubClass = info->bInterfaceSubClass; - desc->bInterfaceProtocol = info->bInterfaceProtocol; - } -} - -Result tinleaf_usbCommsInitializeEx(u32 num_interfaces, const tinleaf_UsbCommsInterfaceInfo *infos) -{ - Result rc = 0; - rwlockWriteLock(&g_usbCommsLock); - - if (g_usbCommsInitialized) { - rc = MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); - } else if (num_interfaces > TOTAL_INTERFACES) { - rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); - } else { - rc = usbDsInitialize(); - - if (R_SUCCEEDED(rc)) { - if (hosversionAtLeast(5,0,0)) { - u8 iManufacturer, iProduct, iSerialNumber; - static const u16 supported_langs[1] = {0x0409}; - // Send language descriptor - rc = usbDsAddUsbLanguageStringDescriptor(NULL, supported_langs, sizeof(supported_langs)/sizeof(u16)); - // Send manufacturer - if (R_SUCCEEDED(rc)) rc = usbDsAddUsbStringDescriptor(&iManufacturer, "Nintendo"); - // Send product - if (R_SUCCEEDED(rc)) rc = usbDsAddUsbStringDescriptor(&iProduct, "Nintendo Switch"); - // Send serial number - if (R_SUCCEEDED(rc)) rc = usbDsAddUsbStringDescriptor(&iSerialNumber, "SerialNumber"); - - // Send device descriptors - struct usb_device_descriptor device_descriptor = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0110, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = 0x40, - .idVendor = 0x057e, - .idProduct = 0x3000, - .bcdDevice = 0x0100, - .iManufacturer = iManufacturer, - .iProduct = iProduct, - .iSerialNumber = iSerialNumber, - .bNumConfigurations = 0x01 - }; - // Full Speed is USB 1.1 - if (R_SUCCEEDED(rc)) rc = usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Full, &device_descriptor); - - // High Speed is USB 2.0 - device_descriptor.bcdUSB = 0x0200; - if (R_SUCCEEDED(rc)) rc = usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, &device_descriptor); - - // Super Speed is USB 3.0 - device_descriptor.bcdUSB = 0x0300; - // Upgrade packet size to 512 - device_descriptor.bMaxPacketSize0 = 0x09; - if (R_SUCCEEDED(rc)) rc = usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Super, &device_descriptor); - - // Define Binary Object Store - u8 bos[0x16] = { - 0x05, // .bLength - USB_DT_BOS, // .bDescriptorType - 0x16, 0x00, // .wTotalLength - 0x02, // .bNumDeviceCaps - - // USB 2.0 - 0x07, // .bLength - USB_DT_DEVICE_CAPABILITY, // .bDescriptorType - 0x02, // .bDevCapabilityType - 0x02, 0x00, 0x00, 0x00, // dev_capability_data - - // USB 3.0 - 0x0A, // .bLength - USB_DT_DEVICE_CAPABILITY, // .bDescriptorType - 0x03, // .bDevCapabilityType - 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00 - }; - if (R_SUCCEEDED(rc)) rc = usbDsSetBinaryObjectStore(bos, sizeof(bos)); - } - - if (R_SUCCEEDED(rc)) { - for (u32 i = 0; i < num_interfaces; i++) { - usbCommsInterface *intf = &g_usbCommsInterfaces[i]; - rwlockWriteLock(&intf->lock); - rwlockWriteLock(&intf->lock_in); - rwlockWriteLock(&intf->lock_out); - rc = _usbCommsInterfaceInit(i, infos == NULL ? NULL : infos + i); - rwlockWriteUnlock(&intf->lock_out); - rwlockWriteUnlock(&intf->lock_in); - rwlockWriteUnlock(&intf->lock); - if (R_FAILED(rc)) { - break; - } - } - } - } - - if (R_SUCCEEDED(rc) && hosversionAtLeast(5,0,0)) { - rc = usbDsEnable(); - } - } - - if (R_SUCCEEDED(rc)) { - g_usbCommsInitialized = true; - g_usbCommsErrorHandling = false; - } - - rwlockWriteUnlock(&g_usbCommsLock); - - if (R_FAILED(rc)) { - tinleaf_usbCommsExit(); - } - - return rc; -} - -Result tinleaf_usbCommsInitialize(void) -{ - return tinleaf_usbCommsInitializeEx(1, NULL); -} - -static void _usbCommsInterfaceFree(usbCommsInterface *interface) -{ - rwlockWriteLock(&interface->lock); - if (!interface->initialized) { - rwlockWriteUnlock(&interface->lock); - return; - } - - rwlockWriteLock(&interface->lock_in); - rwlockWriteLock(&interface->lock_out); - - interface->initialized = 0; - - interface->endpoint_in = NULL; - interface->endpoint_out = NULL; - interface->interface = NULL; - - free(interface->endpoint_in_buffer); - free(interface->endpoint_out_buffer); - interface->endpoint_in_buffer = NULL; - interface->endpoint_out_buffer = NULL; - - rwlockWriteUnlock(&interface->lock_out); - rwlockWriteUnlock(&interface->lock_in); - - rwlockWriteUnlock(&interface->lock); -} - -void tinleaf_usbCommsExit(void) -{ - u32 i; - - rwlockWriteLock(&g_usbCommsLock); - - usbDsExit(); - - g_usbCommsInitialized = false; - - rwlockWriteUnlock(&g_usbCommsLock); - - for (i=0; iinitialized = 1; - - //The buffer for PostBufferAsync commands must be 0x1000-byte aligned. - interface->endpoint_in_buffer = memalign(0x1000, 0x1000); - if (interface->endpoint_in_buffer==NULL) rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); - - if (R_SUCCEEDED(rc)) { - interface->endpoint_out_buffer = memalign(0x1000, 0x1000); - if (interface->endpoint_out_buffer==NULL) rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); - } - - if (R_SUCCEEDED(rc)) { - memset(interface->endpoint_in_buffer, 0, 0x1000); - memset(interface->endpoint_out_buffer, 0, 0x1000); - } - - if (R_FAILED(rc)) return rc; - - rc = usbDsRegisterInterface(&interface->interface); - if (R_FAILED(rc)) return rc; - - interface_descriptor.bInterfaceNumber = interface->interface->interface_index; - endpoint_descriptor_in.bEndpointAddress += interface_descriptor.bInterfaceNumber + 1; - endpoint_descriptor_out.bEndpointAddress += interface_descriptor.bInterfaceNumber + 1; - - // Full Speed Config - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &interface_descriptor, USB_DT_INTERFACE_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &endpoint_descriptor_in, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &endpoint_descriptor_out, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - - // High Speed Config - endpoint_descriptor_in.wMaxPacketSize = 0x200; - endpoint_descriptor_out.wMaxPacketSize = 0x200; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_High, &interface_descriptor, USB_DT_INTERFACE_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_High, &endpoint_descriptor_in, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_High, &endpoint_descriptor_out, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - - // Super Speed Config - endpoint_descriptor_in.wMaxPacketSize = 0x400; - endpoint_descriptor_out.wMaxPacketSize = 0x400; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Super, &interface_descriptor, USB_DT_INTERFACE_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Super, &endpoint_descriptor_in, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Super, &endpoint_companion, USB_DT_SS_ENDPOINT_COMPANION_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Super, &endpoint_descriptor_out, USB_DT_ENDPOINT_SIZE); - if (R_FAILED(rc)) return rc; - rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Super, &endpoint_companion, USB_DT_SS_ENDPOINT_COMPANION_SIZE); - if (R_FAILED(rc)) return rc; - - //Setup endpoints. - rc = usbDsInterface_RegisterEndpoint(interface->interface, &interface->endpoint_in, endpoint_descriptor_in.bEndpointAddress); - if (R_FAILED(rc)) return rc; - - rc = usbDsInterface_RegisterEndpoint(interface->interface, &interface->endpoint_out, endpoint_descriptor_out.bEndpointAddress); - if (R_FAILED(rc)) return rc; - - rc = usbDsInterface_EnableInterface(interface->interface); - if (R_FAILED(rc)) return rc; - - return rc; -} - - -static Result _usbCommsInterfaceInit1x(u32 intf_ind, const tinleaf_UsbCommsInterfaceInfo *info) -{ - Result rc = 0; - usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind]; - - struct usb_interface_descriptor interface_descriptor = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = intf_ind, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceProtocol = USB_CLASS_VENDOR_SPEC, - }; - _usbCommsUpdateInterfaceDescriptor(&interface_descriptor, info); - - struct usb_endpoint_descriptor endpoint_descriptor_in = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_ENDPOINT_IN, - .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, - }; - - struct usb_endpoint_descriptor endpoint_descriptor_out = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_ENDPOINT_OUT, - .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, - }; - - interface->initialized = 1; - - //The buffer for PostBufferAsync commands must be 0x1000-byte aligned. - interface->endpoint_in_buffer = memalign(0x1000, 0x1000); - if (interface->endpoint_in_buffer==NULL) rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); - - if (R_SUCCEEDED(rc)) { - interface->endpoint_out_buffer = memalign(0x1000, 0x1000); - if (interface->endpoint_out_buffer==NULL) rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); - } - - if (R_SUCCEEDED(rc)) { - memset(interface->endpoint_in_buffer, 0, 0x1000); - memset(interface->endpoint_out_buffer, 0, 0x1000); - } - - if (R_FAILED(rc)) return rc; - - //Setup interface. - rc = usbDsGetDsInterface(&interface->interface, &interface_descriptor, "usb"); - if (R_FAILED(rc)) return rc; - - //Setup endpoints. - rc = usbDsInterface_GetDsEndpoint(interface->interface, &interface->endpoint_in, &endpoint_descriptor_in);//device->host - if (R_FAILED(rc)) return rc; - - rc = usbDsInterface_GetDsEndpoint(interface->interface, &interface->endpoint_out, &endpoint_descriptor_out);//host->device - if (R_FAILED(rc)) return rc; - - rc = usbDsInterface_EnableInterface(interface->interface); - if (R_FAILED(rc)) return rc; - - return rc; -} - -void tinleaf_usbCommsSetErrorHandling(bool flag) { - g_usbCommsErrorHandling = flag; -} - -static Result _usbCommsRead(usbCommsInterface *interface, void* buffer, size_t size, size_t *transferredSize, u64 timeout) -{ - Result rc=0; - u32 urbId=0; - u8 *bufptr = (u8*)buffer; - u8 *transfer_buffer = NULL; - u8 transfer_type=0; - u32 chunksize=0; - u32 tmp_transferredSize = 0; - size_t total_transferredSize=0; - UsbDsReportData reportdata; - - //Makes sure endpoints are ready for data-transfer / wait for init if needed. - rc = usbDsWaitReady(timeout); - if (R_FAILED(rc)) return rc; - - while(size) - { - if(((u64)bufptr) & 0xfff)//When bufptr isn't page-aligned copy the data into g_usbComms_endpoint_in_buffer and transfer that, otherwise use the bufptr directly. - { - transfer_buffer = interface->endpoint_out_buffer; - memset(interface->endpoint_out_buffer, 0, 0x1000); - - chunksize = 0x1000; - chunksize-= ((u64)bufptr) & 0xfff;//After this transfer, bufptr will be page-aligned(if size is large enough for another transfer). - if (sizedevice transfer. - rc = usbDsEndpoint_PostBufferAsync(interface->endpoint_out, transfer_buffer, chunksize, &urbId); - if (R_FAILED(rc)) return rc; - //Wait for the transfer to finish. - rc = eventWait(&interface->endpoint_out->CompletionEvent, timeout); - if (R_FAILED(rc)) - { - usbDsEndpoint_Cancel(interface->endpoint_out); - eventWait(&interface->endpoint_out->CompletionEvent, UINT64_MAX); - eventClear(&interface->endpoint_out->CompletionEvent); - return rc; - } - eventClear(&interface->endpoint_out->CompletionEvent); - - rc = usbDsEndpoint_GetReportData(interface->endpoint_out, &reportdata); - if (R_FAILED(rc)) return rc; - - rc = usbDsParseReportData(&reportdata, urbId, NULL, &tmp_transferredSize); - if (R_FAILED(rc)) return rc; - - if (tmp_transferredSize > chunksize) tmp_transferredSize = chunksize; - total_transferredSize+= (size_t)tmp_transferredSize; - - if (transfer_type==0) memcpy(bufptr, transfer_buffer, tmp_transferredSize); - bufptr+= tmp_transferredSize; - size-= tmp_transferredSize; - - if(tmp_transferredSize < chunksize)break; - } - - if (transferredSize) *transferredSize = total_transferredSize; - - return rc; -} - -static Result _usbCommsWrite(usbCommsInterface *interface, const void* buffer, size_t size, size_t *transferredSize, u64 timeout) -{ - Result rc=0; - u32 urbId=0; - u32 chunksize=0; - u8 *bufptr = (u8*)buffer; - u8 *transfer_buffer = NULL; - u32 tmp_transferredSize = 0; - size_t total_transferredSize=0; - UsbDsReportData reportdata; - - //Makes sure endpoints are ready for data-transfer / wait for init if needed. - rc = usbDsWaitReady(timeout); - if (R_FAILED(rc)) return rc; - - while(size) - { - if(((u64)bufptr) & 0xfff)//When bufptr isn't page-aligned copy the data into g_usbComms_endpoint_in_buffer and transfer that, otherwise use the bufptr directly. - { - transfer_buffer = interface->endpoint_in_buffer; - memset(interface->endpoint_in_buffer, 0, 0x1000); - - chunksize = 0x1000; - chunksize-= ((u64)bufptr) & 0xfff;//After this transfer, bufptr will be page-aligned(if size is large enough for another transfer). - if (sizeendpoint_in_buffer, bufptr, chunksize); - } - else - { - transfer_buffer = bufptr; - chunksize = size; - } - - //Start a device->host transfer. - rc = usbDsEndpoint_PostBufferAsync(interface->endpoint_in, transfer_buffer, chunksize, &urbId); - if(R_FAILED(rc))return rc; - - //Wait for the transfer to finish. - rc = eventWait(&interface->endpoint_in->CompletionEvent, timeout); - if (R_FAILED(rc)) - { - usbDsEndpoint_Cancel(interface->endpoint_in); - eventWait(&interface->endpoint_in->CompletionEvent, UINT64_MAX); - eventClear(&interface->endpoint_in->CompletionEvent); - return rc; - } - eventClear(&interface->endpoint_in->CompletionEvent); - - rc = usbDsEndpoint_GetReportData(interface->endpoint_in, &reportdata); - if (R_FAILED(rc)) return rc; - - rc = usbDsParseReportData(&reportdata, urbId, NULL, &tmp_transferredSize); - if (R_FAILED(rc)) return rc; - - if (tmp_transferredSize > chunksize) tmp_transferredSize = chunksize; - - total_transferredSize+= (size_t)tmp_transferredSize; - - bufptr+= tmp_transferredSize; - size-= tmp_transferredSize; - - if (tmp_transferredSize < chunksize) break; - } - - if (transferredSize) *transferredSize = total_transferredSize; - - return rc; -} - -size_t tinleaf_usbCommsReadEx(void* buffer, size_t size, u32 interface, u64 timeout) -{ - size_t transferredSize=0; - Result rc; - usbCommsInterface *inter = &g_usbCommsInterfaces[interface]; - bool initialized; - - if (interface>=TOTAL_INTERFACES) return 0; - - rwlockReadLock(&inter->lock); - initialized = inter->initialized; - rwlockReadUnlock(&inter->lock); - if (!initialized) return 0; - - rwlockWriteLock(&inter->lock_in); - rc = _usbCommsRead(&g_usbCommsInterfaces[interface], buffer, size, &transferredSize, timeout); - rwlockWriteUnlock(&inter->lock_in); - if (R_SUCCEEDED(rc)) return transferredSize; - else if (R_FAILED(rc)) return 0; - return 0; -} - -size_t tinleaf_usbCommsRead(void* buffer, size_t size, u64 timeout) -{ - return tinleaf_usbCommsReadEx(buffer, size, 0, timeout); -} - -size_t tinleaf_usbCommsWriteEx(const void* buffer, size_t size, u32 interface, u64 timeout) -{ - size_t transferredSize=0; - Result rc; - usbCommsInterface *inter = &g_usbCommsInterfaces[interface]; - bool initialized; - - if (interface>=TOTAL_INTERFACES) return 0; - - rwlockReadLock(&inter->lock); - initialized = inter->initialized; - rwlockReadUnlock(&inter->lock); - if (!initialized) return 0; - - rwlockWriteLock(&inter->lock_in); - rc = _usbCommsWrite(&g_usbCommsInterfaces[interface], buffer, size, &transferredSize, timeout); - rwlockWriteUnlock(&inter->lock_in); - if (R_SUCCEEDED(rc)) return transferredSize; - else if (R_FAILED(rc)) return 0; - return 0; -} - -size_t tinleaf_usbCommsWrite(const void* buffer, size_t size, u64 timeout) -{ - return tinleaf_usbCommsWriteEx(buffer, size, 0, timeout); -} - diff --git a/source/util/usb_util.cpp b/source/util/usb_util.cpp deleted file mode 100644 index a377fd2..0000000 --- a/source/util/usb_util.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright (c) 2017-2018 Adubbz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "util/usb_util.hpp" -#include "util/usb_comms_tinleaf.h" - -#include "data/byte_buffer.hpp" -#include "debug.h" -#include "error.hpp" - -namespace tin::util -{ - void USBCmdManager::SendCmdHeader(u32 cmdId, size_t dataSize) - { - USBCmdHeader header; - header.magic = 0x30435554; // TUC0 (Tinfoil USB Command 0) - header.type = USBCmdType::REQUEST; - header.cmdId = cmdId; - header.dataSize = dataSize; - - USBWrite(&header, sizeof(USBCmdHeader)); - } - - void USBCmdManager::SendExitCmd() - { - USBCmdManager::SendCmdHeader(0, 0); - } - - USBCmdHeader USBCmdManager::SendFileRangeCmd(std::string nspName, u64 offset, u64 size) - { - struct FileRangeCmdHeader - { - u64 size; - u64 offset; - u64 nspNameLen; - u64 padding; - } fRangeHeader; - - fRangeHeader.size = size; - fRangeHeader.offset = offset; - fRangeHeader.nspNameLen = nspName.size(); - fRangeHeader.padding = 0; - - USBCmdManager::SendCmdHeader(1, sizeof(FileRangeCmdHeader) + fRangeHeader.nspNameLen); - USBWrite(&fRangeHeader, sizeof(FileRangeCmdHeader)); - USBWrite(nspName.c_str(), fRangeHeader.nspNameLen); - - USBCmdHeader responseHeader; - USBRead(&responseHeader, sizeof(USBCmdHeader)); - return responseHeader; - } - - size_t USBRead(void* out, size_t len, u64 timeout) - { - u8* tmpBuf = (u8*)out; - size_t sizeRemaining = len; - size_t tmpSizeRead = 0; - - while (sizeRemaining) - { - tmpSizeRead = tinleaf_usbCommsRead(tmpBuf, sizeRemaining, timeout); - if (tmpSizeRead == 0) return 0; - tmpBuf += tmpSizeRead; - sizeRemaining -= tmpSizeRead; - } - - return len; - } - - size_t USBWrite(const void* in, size_t len, u64 timeout) - { - const u8 *bufptr = (const u8 *)in; - size_t cursize = len; - size_t tmpsize = 0; - - while (cursize) - { - tmpsize = tinleaf_usbCommsWrite(bufptr, cursize, timeout); - if (tmpsize == 0) return 0; - bufptr += tmpsize; - cursize -= tmpsize; - } - - return len; - } -} \ No newline at end of file diff --git a/source/util/util.cpp b/source/util/util.cpp deleted file mode 100644 index d42bb95..0000000 --- a/source/util/util.cpp +++ /dev/null @@ -1,317 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "switch.h" -#include "util/util.hpp" -#include "nx/ipc/tin_ipc.h" -#include "util/config.hpp" -#include "util/curl.hpp" -#include "ui/MainApplication.hpp" -#include "util/usb_comms_tinleaf.h" -#include "util/json.hpp" -#include "nx/usbhdd.h" - -namespace inst::util { - void initApp () { - // Seethe - //if (!pu::IsReiNX()) pu::IsAtmosphere(); - if (!std::filesystem::exists("sdmc:/switch")) std::filesystem::create_directory("sdmc:/switch"); - if (!std::filesystem::exists(inst::config::appDir)) std::filesystem::create_directory(inst::config::appDir); - inst::config::parseConfig(); - - socketInitializeDefault(); - #ifdef __DEBUG__ - nxlinkStdio(); - #endif - tinleaf_usbCommsInitialize(); - - nx::hdd::init(); - } - - void deinitApp () { - nx::hdd::exit(); - socketExit(); - tinleaf_usbCommsExit(); - } - - void initInstallServices() { - ncmInitialize(); - nsInitialize(); - nsextInitialize(); - esInitialize(); - splCryptoInitialize(); - splInitialize(); - } - - void deinitInstallServices() { - ncmExit(); - nsExit(); - nsextExit(); - esExit(); - splCryptoExit(); - splExit(); - } - - struct caseInsensitiveLess : public std::binary_function< char,char,bool > { - bool operator () (char x, char y) const { - return toupper(static_cast< unsigned char >(x)) < toupper(static_cast< unsigned char >(y)); - } - }; - - bool ignoreCaseCompare(const std::string &a, const std::string &b) { - return std::lexicographical_compare(a.begin(), a.end() , b.begin() ,b.end() , caseInsensitiveLess()); - } - - std::vector getDirectoryFiles(const std::string & dir, const std::vector & extensions) { - std::vector files; - for(auto & p: std::filesystem::directory_iterator(dir)) - { - if (std::filesystem::is_regular_file(p)) - { - std::string ourExtension = p.path().extension().string(); - std::transform(ourExtension.begin(), ourExtension.end(), ourExtension.begin(), ::tolower); - if (extensions.empty() || std::find(extensions.begin(), extensions.end(), ourExtension) != extensions.end()) - { - files.push_back(p.path()); - } - } - } - std::sort(files.begin(), files.end(), ignoreCaseCompare); - return files; - } - - std::vector getDirsAtPath(const std::string & dir) { - std::vector files; - for(auto & p: std::filesystem::directory_iterator(dir)) - { - if (std::filesystem::is_directory(p)) - { - files.push_back(p.path()); - } - } - std::sort(files.begin(), files.end(), ignoreCaseCompare); - return files; - } - - bool removeDirectory(std::string dir) { - try { - for(auto & p: std::filesystem::recursive_directory_iterator(dir)) - { - if (std::filesystem::is_regular_file(p)) - { - std::filesystem::remove(p); - } - } - rmdir(dir.c_str()); - return true; - } - catch (std::filesystem::filesystem_error & e) { - return false; - } - } - - bool copyFile(std::string inFile, std::string outFile) { - char ch; - std::ifstream f1(inFile); - std::ofstream f2(outFile); - - if(!f1 || !f2) return false; - - while(f1 && f1.get(ch)) f2.put(ch); - return true; - } - - std::string formatUrlString(std::string ourString) { - std::stringstream ourStream(ourString); - std::string segment; - std::vector seglist; - - while(std::getline(ourStream, segment, '/')) { - seglist.push_back(segment); - } - - CURL *curl = curl_easy_init(); - int outlength; - std::string finalString = curl_easy_unescape(curl, seglist[seglist.size() - 1].c_str(), seglist[seglist.size() - 1].length(), &outlength); - curl_easy_cleanup(curl); - - return finalString; - } - - std::string shortenString(std::string ourString, int ourLength, bool isFile) { - std::filesystem::path ourStringAsAPath = ourString; - std::string ourExtension = ourStringAsAPath.extension().string(); - if (ourString.size() - ourExtension.size() > (unsigned long)ourLength) { - if(isFile) return (std::string)ourString.substr(0,ourLength) + "(...)" + ourExtension; - else return (std::string)ourString.substr(0,ourLength) + "..."; - } else return ourString; - } - - std::string readTextFromFile(std::string ourFile) { - if (std::filesystem::exists(ourFile)) { - FILE * file = fopen(ourFile.c_str(), "r"); - char line[1024]; - fgets(line, 1024, file); - std::string url = line; - fflush(file); - fclose(file); - return url; - } - return ""; - } - - std::string softwareKeyboard(std::string guideText, std::string initialText, int LenMax) { - Result rc=0; - SwkbdConfig kbd; - char tmpoutstr[LenMax + 1] = {0}; - rc = swkbdCreate(&kbd, 0); - if (R_SUCCEEDED(rc)) { - swkbdConfigMakePresetDefault(&kbd); - swkbdConfigSetGuideText(&kbd, guideText.c_str()); - swkbdConfigSetInitialText(&kbd, initialText.c_str()); - swkbdConfigSetStringLenMax(&kbd, LenMax); - rc = swkbdShow(&kbd, tmpoutstr, sizeof(tmpoutstr)); - swkbdClose(&kbd); - if (R_SUCCEEDED(rc) && tmpoutstr[0] != 0) return(((std::string)(tmpoutstr))); - } - return ""; - } - - std::string getDriveFileName(std::string fileId) { - std::string htmlData = inst::curl::downloadToBuffer("https://drive.google.com/file/d/" + fileId + "/view"); - if (htmlData.size() > 0) { - std::smatch ourMatches; - std::regex ourRegex("\\s*(.+?)\\s*"); - std::regex_search(htmlData, ourMatches, ourRegex); - if (ourMatches.size() > 1) { - if (ourMatches[1].str() == "Google Drive -- Page Not Found") return ""; - return ourMatches[1].str().substr(0, ourMatches[1].str().size() - 15); - } - } - return ""; - } - - std::vector setClockSpeed(int deviceToClock, uint32_t clockSpeed) { - uint32_t hz = 0; - uint32_t previousHz = 0; - - if (deviceToClock > 2 || deviceToClock < 0) return {0,0}; - - if(hosversionAtLeast(8,0,0)) { - ClkrstSession session = {0}; - PcvModuleId pcvModuleId; - pcvInitialize(); - clkrstInitialize(); - - switch (deviceToClock) { - case 0: - pcvGetModuleId(&pcvModuleId, PcvModule_CpuBus); - break; - case 1: - pcvGetModuleId(&pcvModuleId, PcvModule_GPU); - break; - case 2: - pcvGetModuleId(&pcvModuleId, PcvModule_EMC); - break; - } - - clkrstOpenSession(&session, pcvModuleId, 3); - clkrstGetClockRate(&session, &previousHz); - clkrstSetClockRate(&session, clockSpeed); - clkrstGetClockRate(&session, &hz); - - pcvExit(); - clkrstCloseSession(&session); - clkrstExit(); - - return {previousHz, hz}; - } else { - PcvModule pcvModule; - pcvInitialize(); - - switch (deviceToClock) { - case 0: - pcvModule = PcvModule_CpuBus; - break; - case 1: - pcvModule = PcvModule_GPU; - break; - case 2: - pcvModule = PcvModule_EMC; - break; - } - - pcvGetClockRate(pcvModule, &previousHz); - pcvSetClockRate(pcvModule, clockSpeed); - pcvGetClockRate(pcvModule, &hz); - - pcvExit(); - - return {previousHz, hz}; - } - } - - std::string getIPAddress() { - struct in_addr addr = {(in_addr_t) gethostid()}; - return inet_ntoa(addr); - } - - int getUsbState() { - UsbState usbState = UsbState_Detached; - usbDsGetState(&usbState); - return (u32)usbState; - } - - void playAudio(std::string audioPath) { - int audio_rate = 22050; - Uint16 audio_format = AUDIO_S16SYS; - int audio_channels = 2; - int audio_buffers = 4096; - - if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) return; - - Mix_Chunk *sound = NULL; - sound = Mix_LoadWAV(audioPath.c_str()); - if(sound == NULL) { - Mix_FreeChunk(sound); - Mix_CloseAudio(); - return; - } - - int channel = Mix_PlayChannel(-1, sound, 0); - if(channel == -1) { - Mix_FreeChunk(sound); - Mix_CloseAudio(); - return; - } - - while(Mix_Playing(channel) != 0); - - Mix_FreeChunk(sound); - Mix_CloseAudio(); - - return; - } - - std::vector checkForAppUpdate() { - try { - std::string giturl = "https://api.github.com/repos/mrdude2478/TinWoo/releases/latest"; - std::string jsonData = inst::curl::downloadToBuffer(giturl, 0, 0, 1000L); - if (jsonData.size() == 0) return {}; - nlohmann::json ourJson = nlohmann::json::parse(jsonData); - if (ourJson["tag_name"].get() != inst::config::appVersion) { - std::vector ourUpdateInfo = {ourJson["tag_name"].get(), ourJson["assets"][0]["browser_download_url"].get()}; - inst::config::updateInfo = ourUpdateInfo; - return ourUpdateInfo; - } - } catch (...) {} - return {}; - } -} \ No newline at end of file