mirror of
https://github.com/Huntereb/Awoo-Installer
synced 2024-11-10 06:04:20 +00:00
Merge branch 'real_usb' into xci
This commit is contained in:
commit
3cebefb785
45 changed files with 943 additions and 230 deletions
11
Makefile
11
Makefile
|
@ -55,9 +55,10 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
|||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -D__DEBUG__ -DNXLINK_DEBUG
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -D__DEBUG__ -Wall
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++17 -Wall
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
@ -166,17 +167,17 @@ all: $(BUILD)
|
|||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
#comment this out if you are hacking on the code or compilation will take for ever
|
||||
$(MAKE) --no-print-directory -C include/Plutonium -f Makefile lib-switch
|
||||
#$(MAKE) --no-print-directory -C include/Plutonium -f Makefile lib-switch
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
@$(MAKE) --no-print-directory -C include/Plutonium/Plutonium -f Makefile clean
|
||||
#@$(MAKE) --no-print-directory -C include/Plutonium/Plutonium -f Makefile clean
|
||||
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||
else
|
||||
@$(MAKE) --no-print-directory -C include/Plutonium/Plutonium -f Makefile clean
|
||||
#@$(MAKE) --no-print-directory -C include/Plutonium/Plutonium -f Makefile clean
|
||||
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
|
||||
endif
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace tin::install::nsp
|
|||
|
||||
HTTPNSP(std::string url);
|
||||
|
||||
virtual void BufferNCAHeader(void* buf, NcmContentId placeholderId) override;
|
||||
virtual void StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId) override;
|
||||
virtual void BufferData(void* buf, off_t offset, size_t size) override;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace tin::install::xci
|
|||
void InstallTicketCert() override;
|
||||
|
||||
public:
|
||||
XCIInstallTask(tin::install::xci::XCI& xci, NcmStorageId destStorageId, bool ignoreReqFirmVersion);
|
||||
XCIInstallTask(NcmStorageId destStorageId, bool ignoreReqFirmVersion, tin::install::xci::XCI* xci);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace tin::install
|
|||
u8 _0x148[0xB8]; /* Padding. */
|
||||
} PACKED;
|
||||
|
||||
static_assert(sizeof(NcaFsHeader) == 0x200, "PFS0FileEntry must be 0x18");
|
||||
static_assert(sizeof(NcaFsHeader) == 0x200, "NcaFsHeader must be 0x200");
|
||||
|
||||
struct NcaSectionEntry
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ namespace tin::install
|
|||
u8 _0x8[0x8]; /* Padding. */
|
||||
} PACKED;
|
||||
|
||||
static_assert(sizeof(NcaSectionEntry) == 0x10, "PFS0FileEntry must be 0x18");
|
||||
static_assert(sizeof(NcaSectionEntry) == 0x10, "NcaSectionEntry must be 0x10");
|
||||
|
||||
struct NcaHeader
|
||||
{
|
||||
|
@ -73,5 +73,5 @@ namespace tin::install
|
|||
NcaFsHeader fs_headers[4]; /* FS section headers. */
|
||||
} PACKED;
|
||||
|
||||
static_assert(sizeof(NcaHeader) == 0xc00, "PFS0FileEntry must be 0x18");
|
||||
static_assert(sizeof(NcaHeader) == 0xc00, "NcaHeader must be 0xc00");
|
||||
}
|
|
@ -40,7 +40,6 @@ namespace tin::install::nsp
|
|||
RemoteNSP();
|
||||
|
||||
public:
|
||||
virtual void BufferNCAHeader(void* buf, NcmContentId placeholderId) = 0;
|
||||
virtual void StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId) = 0;
|
||||
virtual void BufferData(void* buf, off_t offset, size_t size) = 0;
|
||||
|
||||
|
|
19
include/install/usb_nsp.hpp
Normal file
19
include/install/usb_nsp.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "install/remote_nsp.hpp"
|
||||
|
||||
namespace tin::install::nsp
|
||||
{
|
||||
class USBNSP : public RemoteNSP
|
||||
{
|
||||
private:
|
||||
std::string m_nspName;
|
||||
|
||||
public:
|
||||
USBNSP(std::string nspName);
|
||||
|
||||
virtual void StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId) override;
|
||||
virtual void BufferData(void* buf, off_t offset, size_t size) override;
|
||||
};
|
||||
}
|
19
include/install/usb_xci.hpp
Normal file
19
include/install/usb_xci.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "install/xci.hpp"
|
||||
|
||||
namespace tin::install::xci
|
||||
{
|
||||
class USBXCI : public XCI
|
||||
{
|
||||
private:
|
||||
std::string m_xciName;
|
||||
|
||||
public:
|
||||
USBXCI(std::string xciName);
|
||||
|
||||
virtual void StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId) override;
|
||||
virtual void BufferData(void* buf, off_t offset, size_t size) override;
|
||||
};
|
||||
}
|
|
@ -21,6 +21,6 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
namespace netInstStuff {
|
||||
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames);
|
||||
void installTitleNet(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames);
|
||||
std::vector<std::string> OnSelected();
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
#include <pu/Plutonium>
|
||||
#include "ui/mainPage.hpp"
|
||||
#include "ui/netInstPage.hpp"
|
||||
#include "ui/nspInstPage.hpp"
|
||||
#include "ui/sdInstPage.hpp"
|
||||
#include "ui/usbInstPage.hpp"
|
||||
#include "ui/instPage.hpp"
|
||||
#include "ui/optionsPage.hpp"
|
||||
|
||||
|
@ -14,7 +15,8 @@ namespace inst::ui {
|
|||
void OnLoad() override;
|
||||
MainPage::Ref mainPage;
|
||||
netInstPage::Ref netinstPage;
|
||||
nspInstPage::Ref nspinstPage;
|
||||
sdInstPage::Ref sdinstPage;
|
||||
usbInstPage::Ref usbinstPage;
|
||||
instPage::Ref instpage;
|
||||
optionsPage::Ref optionspage;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace inst::ui {
|
|||
PU_SMART_CTOR(MainPage)
|
||||
void installMenuItem_Click();
|
||||
void netInstallMenuItem_Click();
|
||||
void usbInstallMenuItem_Click();
|
||||
void sigPatchesMenuItem_Click();
|
||||
void settingsMenuItem_Click();
|
||||
void exitMenuItem_Click();
|
||||
|
@ -24,6 +25,7 @@ namespace inst::ui {
|
|||
pu::ui::elm::Menu::Ref optionMenu;
|
||||
pu::ui::elm::MenuItem::Ref installMenuItem;
|
||||
pu::ui::elm::MenuItem::Ref netInstallMenuItem;
|
||||
pu::ui::elm::MenuItem::Ref usbInstallMenuItem;
|
||||
pu::ui::elm::MenuItem::Ref sigPatchesMenuItem;
|
||||
pu::ui::elm::MenuItem::Ref settingsMenuItem;
|
||||
pu::ui::elm::MenuItem::Ref exitMenuItem;
|
||||
|
|
|
@ -13,9 +13,9 @@ namespace inst::ui {
|
|||
void onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos);
|
||||
TextBlock::Ref pageInfoText;
|
||||
private:
|
||||
static std::vector<std::string> ourUrls;
|
||||
static std::vector<std::string> selectedUrls;
|
||||
static std::vector<std::string> alternativeNames;
|
||||
std::vector<std::string> ourUrls;
|
||||
std::vector<std::string> selectedUrls;
|
||||
std::vector<std::string> alternativeNames;
|
||||
TextBlock::Ref butText;
|
||||
Rectangle::Ref topRect;
|
||||
Rectangle::Ref infoRect;
|
||||
|
@ -25,6 +25,6 @@ namespace inst::ui {
|
|||
pu::ui::elm::Menu::Ref menu;
|
||||
Image::Ref infoImage;
|
||||
void drawMenuItems(bool clearItems);
|
||||
void selectNsp(int selectedIndex);
|
||||
void selectTitle(int selectedIndex);
|
||||
};
|
||||
}
|
|
@ -4,21 +4,21 @@
|
|||
|
||||
using namespace pu::ui::elm;
|
||||
namespace inst::ui {
|
||||
class nspInstPage : public pu::ui::Layout
|
||||
class sdInstPage : public pu::ui::Layout
|
||||
{
|
||||
public:
|
||||
nspInstPage();
|
||||
PU_SMART_CTOR(nspInstPage)
|
||||
sdInstPage();
|
||||
PU_SMART_CTOR(sdInstPage)
|
||||
pu::ui::elm::Menu::Ref menu;
|
||||
void startInstall();
|
||||
void onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos);
|
||||
TextBlock::Ref pageInfoText;
|
||||
void drawMenuItems(bool clearItems, std::filesystem::path ourPath);
|
||||
private:
|
||||
static std::vector<std::filesystem::path> ourDirectories;
|
||||
static std::vector<std::filesystem::path> ourFiles;
|
||||
static std::vector<std::filesystem::path> selectedNsps;
|
||||
static std::filesystem::path currentDir;
|
||||
std::vector<std::filesystem::path> ourDirectories;
|
||||
std::vector<std::filesystem::path> ourFiles;
|
||||
std::vector<std::filesystem::path> selectedTitles;
|
||||
std::filesystem::path currentDir;
|
||||
TextBlock::Ref butText;
|
||||
Rectangle::Ref topRect;
|
||||
Rectangle::Ref infoRect;
|
31
include/ui/usbInstPage.hpp
Executable file
31
include/ui/usbInstPage.hpp
Executable file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include <pu/Plutonium>
|
||||
|
||||
using namespace pu::ui::elm;
|
||||
namespace inst::ui {
|
||||
class usbInstPage : public pu::ui::Layout
|
||||
{
|
||||
public:
|
||||
usbInstPage();
|
||||
PU_SMART_CTOR(usbInstPage)
|
||||
void startInstall();
|
||||
void startUsb();
|
||||
void onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos);
|
||||
TextBlock::Ref pageInfoText;
|
||||
private:
|
||||
std::vector<std::string> ourTitles;
|
||||
std::vector<std::string> selectedTitles;
|
||||
std::string lastUrl;
|
||||
std::string lastFileID;
|
||||
TextBlock::Ref butText;
|
||||
Rectangle::Ref topRect;
|
||||
Rectangle::Ref infoRect;
|
||||
Rectangle::Ref botRect;
|
||||
Image::Ref titleImage;
|
||||
TextBlock::Ref appVersionText;
|
||||
pu::ui::elm::Menu::Ref menu;
|
||||
Image::Ref infoImage;
|
||||
void drawMenuItems(bool clearItems);
|
||||
void selectTitle(int selectedIndex);
|
||||
};
|
||||
}
|
8
include/usbInstall.hpp
Normal file
8
include/usbInstall.hpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace usbInstStuff {
|
||||
std::vector<std::string> OnSelected();
|
||||
void installTitleUsb(std::vector<std::string> ourNspList, int ourStorage);
|
||||
}
|
|
@ -29,12 +29,7 @@ extern "C" {
|
|||
#include <stdio.h>
|
||||
#include <switch/types.h>
|
||||
|
||||
extern FILE *nxlinkout;
|
||||
|
||||
int nxLinkInitialize(void);
|
||||
void nxLinkExit(void);
|
||||
|
||||
void printBytes(FILE* out, u8 *bytes, size_t size, bool includeHeader);
|
||||
void printBytes(u8 *bytes, size_t size, bool includeHeader);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ SOFTWARE.
|
|||
strncat(error_prefix, formatted_msg, 512-1); throw std::runtime_error(error_prefix); }
|
||||
|
||||
#ifdef NXLINK_DEBUG
|
||||
#define LOG_DEBUG(format, ...) { fprintf(nxlinkout, "%s:%u: ", __func__, __LINE__); fprintf(nxlinkout, format, ##__VA_ARGS__); }
|
||||
#define LOG_DEBUG(format, ...) { printf("%s:%u: ", __func__, __LINE__); printf(format, ##__VA_ARGS__); }
|
||||
#else
|
||||
#define LOG_DEBUG(format, ...) ;
|
||||
#endif
|
37
include/util/usb_util.hpp
Normal file
37
include/util/usb_util.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <switch.h>
|
||||
#include <string>
|
||||
|
||||
namespace tin::util
|
||||
{
|
||||
enum USBCmdType : u8
|
||||
{
|
||||
REQUEST = 0,
|
||||
RESPONSE = 1
|
||||
};
|
||||
|
||||
struct USBCmdHeader
|
||||
{
|
||||
u32 magic;
|
||||
USBCmdType type;
|
||||
u8 padding[0x3] = {0};
|
||||
u32 cmdId;
|
||||
u64 dataSize;
|
||||
u8 reserved[0xC] = {0};
|
||||
} PACKED;
|
||||
|
||||
static_assert(sizeof(USBCmdHeader) == 0x20, "USBCmdHeader must be 0x20!");
|
||||
|
||||
class USBCmdManager
|
||||
{
|
||||
public:
|
||||
static void SendCmdHeader(u32 cmdId, size_t dataSize);
|
||||
|
||||
static void SendExitCmd();
|
||||
static USBCmdHeader SendFileRangeCmd(std::string nspName, u64 offset, u64 size);
|
||||
};
|
||||
|
||||
size_t USBRead(void* out, size_t len);
|
||||
size_t USBWrite(const void* in, size_t len);
|
||||
}
|
|
@ -17,4 +17,5 @@ namespace inst::util {
|
|||
std::string getDriveFileName(std::string fileId);
|
||||
std::vector<uint32_t> setClockSpeed(int deviceToClock, uint32_t clockSpeed);
|
||||
std::string getIPAddress();
|
||||
int getUsbState();
|
||||
}
|
BIN
romfs/usb-connection-waiting.png
Executable file
BIN
romfs/usb-connection-waiting.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
romfs/usb-port.png
Executable file
BIN
romfs/usb-port.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -208,7 +208,7 @@ namespace tin::data
|
|||
for (int i = 0; i < NUM_BUFFER_SEGMENTS; i++)
|
||||
{
|
||||
printf("Buffer %u:\n", i);
|
||||
printBytes(nxlinkout, m_bufferSegments[i].data, BUFFER_SEGMENT_DATA_SIZE, true);
|
||||
printBytes(m_bufferSegments[i].data, BUFFER_SEGMENT_DATA_SIZE, true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ namespace tin::data
|
|||
|
||||
void ByteBuffer::DebugPrintContents()
|
||||
{
|
||||
fprintf(nxlinkout, "Buffer Size: 0x%lx\n", this->GetSize());
|
||||
printBytes(nxlinkout, this->GetData(), this->GetSize(), true);
|
||||
printf("Buffer Size: 0x%lx\n", this->GetSize());
|
||||
printBytes(this->GetData(), this->GetSize(), true);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ SOFTWARE.
|
|||
#include "util/title_util.hpp"
|
||||
#include "util/error.hpp"
|
||||
#include "util/debug.h"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/util.hpp"
|
||||
|
||||
namespace tin::install::nsp
|
||||
|
@ -80,13 +80,6 @@ namespace tin::install::nsp
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HTTPNSP::BufferNCAHeader(void* buf, NcmContentId placeholderId)
|
||||
{
|
||||
const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId);
|
||||
u64 pfs0Offset = this->GetDataOffset() + fileEntry->dataOffset;
|
||||
this->BufferData(buf, pfs0Offset, 0xc00);
|
||||
}
|
||||
|
||||
void HTTPNSP::StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId)
|
||||
{
|
||||
const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId);
|
||||
|
@ -131,7 +124,7 @@ namespace tin::install::nsp
|
|||
u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000;
|
||||
int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
|
||||
//printf("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
|
||||
inst::ui::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
|
||||
inst::ui::setInstBarPerc((double)downloadProgress);
|
||||
}
|
||||
|
@ -147,7 +140,7 @@ namespace tin::install::nsp
|
|||
u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000;
|
||||
int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%");
|
||||
//printf("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%");
|
||||
inst::ui::setInstBarPerc((double)installProgress);
|
||||
}
|
||||
inst::ui::setInstBarPerc(100);
|
||||
|
|
|
@ -25,7 +25,7 @@ SOFTWARE.
|
|||
#include <threads.h>
|
||||
#include "data/buffered_placeholder_writer.hpp"
|
||||
#include "util/error.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/util.hpp"
|
||||
|
||||
namespace tin::install::xci
|
||||
|
|
|
@ -233,9 +233,9 @@ namespace tin::install
|
|||
}
|
||||
|
||||
printf("Application content meta key: \n");
|
||||
printBytes(nxlinkout, (u8*)&latestApplicationContentMetaKey, sizeof(NcmContentMetaKey), true);
|
||||
printBytes((u8*)&latestApplicationContentMetaKey, sizeof(NcmContentMetaKey), true);
|
||||
printf("Application content meta: \n");
|
||||
printBytes(nxlinkout, appContentRecordBuf.get(), appContentRecordSize, true);
|
||||
printBytes(appContentRecordBuf.get(), appContentRecordSize, true);
|
||||
|
||||
if (hasUpdate)
|
||||
{
|
||||
|
@ -252,9 +252,9 @@ namespace tin::install
|
|||
}
|
||||
|
||||
printf("Patch content meta key: \n");
|
||||
printBytes(nxlinkout, (u8*)&latestPatchContentMetaKey, sizeof(NcmContentMetaKey), true);
|
||||
printBytes((u8*)&latestPatchContentMetaKey, sizeof(NcmContentMetaKey), true);
|
||||
printf("Patch content meta: \n");
|
||||
printBytes(nxlinkout, patchContentRecordBuf.get(), patchContentRecordsSize, true);
|
||||
printBytes(patchContentRecordBuf.get(), patchContentRecordsSize, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -266,7 +266,7 @@ namespace tin::install
|
|||
ASSERT_OK(nsListApplicationRecordContentMeta(0, baseTitleId, appRecordBuf.get(), 0x100, &numEntriesRead), "Failed to list application record content meta");
|
||||
|
||||
printf("Application record content meta: \n");
|
||||
printBytes(nxlinkout, appRecordBuf.get(), 0x100, true);
|
||||
printBytes(appRecordBuf.get(), 0x100, true);
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ SOFTWARE.
|
|||
#include "util/error.hpp"
|
||||
#include "util/file_util.hpp"
|
||||
#include "util/title_util.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "ui/MainApplication.hpp"
|
||||
|
||||
namespace inst::ui {
|
||||
|
@ -162,7 +162,7 @@ namespace tin::install::nsp
|
|||
progress = (float)fileOff / (float)ncaSize;
|
||||
|
||||
if (fileOff % (0x400000 * 3) == 0) {
|
||||
printf("> Progress: %lu/%lu MB (%d%s)\r", (fileOff / 1000000), (ncaSize / 1000000), (int)(progress * 100.0), "%");
|
||||
//printf("> Progress: %lu/%lu MB (%d%s)\r", (fileOff / 1000000), (ncaSize / 1000000), (int)(progress * 100.0), "%");
|
||||
inst::ui::setInstBarPerc((double)(progress * 100.0));
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ namespace tin::install::nsp
|
|||
writer.close();
|
||||
|
||||
// Clean up the line for whatever comes next
|
||||
printf(" \r");
|
||||
//printf(" \r");
|
||||
printf("Registering placeholder...\n");
|
||||
|
||||
if (!failed)
|
||||
|
|
|
@ -94,15 +94,16 @@ namespace tin::install::nsp
|
|||
|
||||
if (inst::config::validateNCAs && !declinedValidation)
|
||||
{
|
||||
tin::install::NcaHeader header;
|
||||
m_remoteNSP->BufferNCAHeader(&header, ncaId);
|
||||
Crypto::AesXtr decryptor(Crypto::Keys().headerKey, false);
|
||||
decryptor.decrypt(&header, &header, sizeof(header), 0, 0x200);
|
||||
tin::install::NcaHeader* header = new NcaHeader;
|
||||
m_remoteNSP->BufferData(header, m_remoteNSP->GetDataOffset() + fileEntry->dataOffset, sizeof(tin::install::NcaHeader));
|
||||
|
||||
if (header.magic != MAGIC_NCA3)
|
||||
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))
|
||||
if (!Crypto::rsa2048PssVerify(&header->magic, 0x200, header->fixed_key_sig, Crypto::NCAHeaderSignature))
|
||||
{
|
||||
int rc = inst::ui::mainApp->CreateShowDialog("Invalid NCA signature detected!", "Improperly signed software should only be installed from trustworthy\nsources. Files containing cartridge repacks and DLC unlockers will always\nshow this warning. You can disable this check in Awoo Installer's settings.\n\nAre you sure you want to continue the installation?", {"Cancel", "Yes, I understand the risks"}, false);
|
||||
if (rc != 1)
|
||||
|
@ -114,7 +115,7 @@ namespace tin::install::nsp
|
|||
m_remoteNSP->StreamToPlaceholder(contentStorage, ncaId);
|
||||
|
||||
// Clean up the line for whatever comes next
|
||||
printf(" \r");
|
||||
//printf(" \r");
|
||||
printf("Registering placeholder...\n");
|
||||
|
||||
try
|
||||
|
|
|
@ -28,7 +28,7 @@ SOFTWARE.
|
|||
#include "util/config.hpp"
|
||||
#include "util/crypto.hpp"
|
||||
#include "install/nca.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "ui/MainApplication.hpp"
|
||||
|
||||
namespace inst::ui {
|
||||
|
@ -37,8 +37,8 @@ namespace inst::ui {
|
|||
|
||||
namespace tin::install::xci
|
||||
{
|
||||
XCIInstallTask::XCIInstallTask(tin::install::xci::XCI& xci, NcmStorageId destStorageId, bool ignoreReqFirmVersion) :
|
||||
Install(destStorageId, ignoreReqFirmVersion), m_xci(&xci)
|
||||
XCIInstallTask::XCIInstallTask(NcmStorageId destStorageId, bool ignoreReqFirmVersion, tin::install::xci::XCI* xci) :
|
||||
Install(destStorageId, ignoreReqFirmVersion), m_xci(xci)
|
||||
{
|
||||
m_xci->RetrieveHeader();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "error.hpp"
|
||||
#include "debug.h"
|
||||
#include "nx/nca_writer.h"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
|
||||
namespace tin::install::xci
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace tin::install::nsp
|
|||
this->BufferData(m_headerBytes.data(), 0x0, sizeof(PFS0BaseHeader));
|
||||
|
||||
printf("Base header: \n");
|
||||
printBytes(nxlinkout, m_headerBytes.data(), sizeof(PFS0BaseHeader), true);
|
||||
printBytes(m_headerBytes.data(), sizeof(PFS0BaseHeader), true);
|
||||
|
||||
// Retrieve the full header
|
||||
size_t remainingHeaderSize = this->GetBaseHeader()->numFiles * sizeof(PFS0FileEntry) + this->GetBaseHeader()->stringTableSize;
|
||||
|
@ -53,7 +53,7 @@ namespace tin::install::nsp
|
|||
this->BufferData(m_headerBytes.data() + sizeof(PFS0BaseHeader), sizeof(PFS0BaseHeader), remainingHeaderSize);
|
||||
|
||||
printf("Full header: \n");
|
||||
printBytes(nxlinkout, m_headerBytes.data(), m_headerBytes.size(), true);
|
||||
printBytes(m_headerBytes.data(), m_headerBytes.size(), true);
|
||||
}
|
||||
|
||||
const PFS0FileEntry* RemoteNSP::GetFileEntry(unsigned int index)
|
||||
|
|
150
source/install/usb_nsp.cpp
Executable file
150
source/install/usb_nsp.cpp
Executable file
|
@ -0,0 +1,150 @@
|
|||
#include "install/usb_nsp.hpp"
|
||||
|
||||
|
||||
#include <switch.h>
|
||||
#include <algorithm>
|
||||
#include <malloc.h>
|
||||
#include <threads.h>
|
||||
#include "data/byte_buffer.hpp"
|
||||
#include "data/buffered_placeholder_writer.hpp"
|
||||
#include "util/usb_util.hpp"
|
||||
#include "error.hpp"
|
||||
#include "debug.h"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/util.hpp"
|
||||
|
||||
namespace tin::install::nsp
|
||||
{
|
||||
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<USBFuncArgs*>(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)
|
||||
{
|
||||
tmpSizeRead = usbCommsRead(buf, std::min(sizeRemaining, (u64)0x800000));
|
||||
sizeRemaining -= tmpSizeRead;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (args->bufferedPlaceholderWriter->CanAppendData(tmpSizeRead))
|
||||
break;
|
||||
}
|
||||
|
||||
args->bufferedPlaceholderWriter->AppendData(buf, tmpSizeRead);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
printf("An error occurred:\n%s", e.what());
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int USBPlaceholderWriteFunc(void* in)
|
||||
{
|
||||
USBFuncArgs* args = reinterpret_cast<USBFuncArgs*>(in);
|
||||
|
||||
while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete())
|
||||
{
|
||||
if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder())
|
||||
args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBNSP::StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId)
|
||||
{
|
||||
const PFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId);
|
||||
std::string ncaFileName = this->GetFileEntryName(fileEntry);
|
||||
|
||||
printf("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;
|
||||
|
||||
thrd_create(&usbThread, USBThreadFunc, &args);
|
||||
thrd_create(&writeThread, USBPlaceholderWriteFunc, &args);
|
||||
|
||||
u64 freq = armGetSystemTickFreq();
|
||||
u64 startTime = armGetSystemTick();
|
||||
size_t startSizeBuffered = 0;
|
||||
double speed = 0.0;
|
||||
|
||||
while (!bufferedPlaceholderWriter.IsBufferDataComplete())
|
||||
{
|
||||
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;
|
||||
|
||||
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
|
||||
u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000;
|
||||
int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
|
||||
inst::ui::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
|
||||
inst::ui::setInstBarPerc((double)downloadProgress);
|
||||
}
|
||||
}
|
||||
|
||||
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
|
||||
|
||||
while (!bufferedPlaceholderWriter.IsPlaceholderComplete())
|
||||
{
|
||||
u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000;
|
||||
int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%");
|
||||
inst::ui::setInstBarPerc((double)installProgress);
|
||||
}
|
||||
|
||||
thrd_join(usbThread, NULL);
|
||||
thrd_join(writeThread, NULL);
|
||||
}
|
||||
|
||||
void USBNSP::BufferData(void* buf, off_t offset, size_t size)
|
||||
{
|
||||
printf("buffering 0x%lx-0x%lx", offset, offset + size);
|
||||
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_nspName, offset, size);
|
||||
tin::util::USBRead(buf, header.dataSize);
|
||||
}
|
||||
}
|
150
source/install/usb_xci.cpp
Normal file
150
source/install/usb_xci.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
#include "install/usb_xci.hpp"
|
||||
|
||||
|
||||
#include <switch.h>
|
||||
#include <algorithm>
|
||||
#include <malloc.h>
|
||||
#include <threads.h>
|
||||
#include "data/byte_buffer.hpp"
|
||||
#include "data/buffered_placeholder_writer.hpp"
|
||||
#include "util/usb_util.hpp"
|
||||
#include "error.hpp"
|
||||
#include "debug.h"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/util.hpp"
|
||||
|
||||
namespace tin::install::xci
|
||||
{
|
||||
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<USBFuncArgs*>(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)
|
||||
{
|
||||
tmpSizeRead = usbCommsRead(buf, std::min(sizeRemaining, (u64)0x800000));
|
||||
sizeRemaining -= tmpSizeRead;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (args->bufferedPlaceholderWriter->CanAppendData(tmpSizeRead))
|
||||
break;
|
||||
}
|
||||
|
||||
args->bufferedPlaceholderWriter->AppendData(buf, tmpSizeRead);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
printf("An error occurred:\n%s", e.what());
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int USBPlaceholderWriteFunc(void* in)
|
||||
{
|
||||
USBFuncArgs* args = reinterpret_cast<USBFuncArgs*>(in);
|
||||
|
||||
while (!args->bufferedPlaceholderWriter->IsPlaceholderComplete())
|
||||
{
|
||||
if (args->bufferedPlaceholderWriter->CanWriteSegmentToPlaceholder())
|
||||
args->bufferedPlaceholderWriter->WriteSegmentToPlaceholder();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBXCI::StreamToPlaceholder(std::shared_ptr<nx::ncm::ContentStorage>& contentStorage, NcmContentId placeholderId)
|
||||
{
|
||||
const HFS0FileEntry* fileEntry = this->GetFileEntryByNcaId(placeholderId);
|
||||
std::string ncaFileName = this->GetFileEntryName(fileEntry);
|
||||
|
||||
printf("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;
|
||||
|
||||
thrd_create(&usbThread, USBThreadFunc, &args);
|
||||
thrd_create(&writeThread, USBPlaceholderWriteFunc, &args);
|
||||
|
||||
u64 freq = armGetSystemTickFreq();
|
||||
u64 startTime = armGetSystemTick();
|
||||
size_t startSizeBuffered = 0;
|
||||
double speed = 0.0;
|
||||
|
||||
while (!bufferedPlaceholderWriter.IsBufferDataComplete())
|
||||
{
|
||||
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;
|
||||
|
||||
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
|
||||
u64 downloadSizeMB = bufferedPlaceholderWriter.GetSizeBuffered() / 1000000;
|
||||
int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
|
||||
inst::ui::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
|
||||
inst::ui::setInstBarPerc((double)downloadProgress);
|
||||
}
|
||||
}
|
||||
|
||||
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
|
||||
|
||||
while (!bufferedPlaceholderWriter.IsPlaceholderComplete())
|
||||
{
|
||||
u64 installSizeMB = bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / 1000000;
|
||||
int installProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeWrittenToPlaceholder() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
|
||||
|
||||
printf("> Install Progress: %lu/%lu MB (%i%s)\r", installSizeMB, totalSizeMB, installProgress, "%");
|
||||
inst::ui::setInstBarPerc((double)installProgress);
|
||||
}
|
||||
|
||||
thrd_join(usbThread, NULL);
|
||||
thrd_join(writeThread, NULL);
|
||||
}
|
||||
|
||||
void USBXCI::BufferData(void* buf, off_t offset, size_t size)
|
||||
{
|
||||
printf("buffering 0x%lx-0x%lx", offset, offset + size);
|
||||
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_xciName, offset, size);
|
||||
tin::util::USBRead(buf, header.dataSize);
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ namespace tin::install::xci
|
|||
this->BufferData(m_headerBytes.data(), hfs0Offset, sizeof(HFS0BaseHeader));
|
||||
|
||||
printf("Base header: \n");
|
||||
printBytes(nxlinkout, m_headerBytes.data(), sizeof(HFS0BaseHeader), true);
|
||||
printBytes(m_headerBytes.data(), sizeof(HFS0BaseHeader), true);
|
||||
|
||||
// Retrieve full header
|
||||
HFS0BaseHeader *header = reinterpret_cast<HFS0BaseHeader*>(m_headerBytes.data());
|
||||
|
@ -56,7 +56,7 @@ namespace tin::install::xci
|
|||
this->BufferData(m_headerBytes.data() + sizeof(HFS0BaseHeader), hfs0Offset + sizeof(HFS0BaseHeader), remainingHeaderSize);
|
||||
|
||||
printf("Base header: \n");
|
||||
printBytes(nxlinkout, m_headerBytes.data(), sizeof(HFS0BaseHeader) + remainingHeaderSize, true);
|
||||
printBytes(m_headerBytes.data(), sizeof(HFS0BaseHeader) + remainingHeaderSize, true);
|
||||
|
||||
// Find Secure partition
|
||||
header = reinterpret_cast<HFS0BaseHeader*>(m_headerBytes.data());
|
||||
|
@ -73,7 +73,7 @@ namespace tin::install::xci
|
|||
this->BufferData(m_secureHeaderBytes.data(), m_secureHeaderOffset, sizeof(HFS0BaseHeader));
|
||||
|
||||
printf("Secure header: \n");
|
||||
printBytes(nxlinkout, m_secureHeaderBytes.data(), sizeof(HFS0BaseHeader), true);
|
||||
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);
|
||||
|
|
|
@ -38,7 +38,7 @@ SOFTWARE.
|
|||
|
||||
#include "ui/MainApplication.hpp"
|
||||
#include "netInstall.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/config.hpp"
|
||||
#include "util/util.hpp"
|
||||
#include "util/curl.hpp"
|
||||
|
@ -113,7 +113,7 @@ namespace netInstStuff{
|
|||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
void installNspLan(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames)
|
||||
void installTitleNet(std::vector<std::string> ourUrlList, int ourStorage, std::vector<std::string> urlListAltNames)
|
||||
{
|
||||
inst::util::initInstallServices();
|
||||
if (appletGetAppletType() == AppletType_Application || appletGetAppletType() == AppletType_SystemApplication) appletBeginBlockingHomeButton(0);
|
||||
|
@ -144,35 +144,25 @@ namespace netInstStuff{
|
|||
|
||||
try {
|
||||
for (urlItr = 0; urlItr < ourUrlList.size(); urlItr++) {
|
||||
printf("%s %s\n", "Install request from", ourUrlList[urlItr].c_str());
|
||||
inst::ui::setTopInstInfoText("Installing " + urlNames[urlItr]);
|
||||
|
||||
tin::install::Install* installTask;
|
||||
|
||||
if (inst::curl::downloadToBuffer(ourUrlList[urlItr], 0x100, 0x103) == "HEAD") {
|
||||
inst::ui::setTopInstInfoText("Installing " + urlNames[urlItr]);
|
||||
|
||||
tin::install::xci::HTTPXCI httpXCI(ourUrlList[urlItr]);
|
||||
|
||||
printf("%s %s\n", "Install request from", ourUrlList[urlItr].c_str());
|
||||
tin::install::xci::XCIInstallTask install(httpXCI, m_destStorageId, inst::config::ignoreReqVers);
|
||||
|
||||
printf("%s\n", "Preparing installation");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
install.Prepare();
|
||||
|
||||
install.Begin();
|
||||
auto httpXCI = new tin::install::xci::HTTPXCI(ourUrlList[urlItr]);
|
||||
installTask = new tin::install::xci::XCIInstallTask(m_destStorageId, inst::config::ignoreReqVers, httpXCI);
|
||||
} else {
|
||||
inst::ui::setTopInstInfoText("Installing " + urlNames[urlItr]);
|
||||
|
||||
tin::install::nsp::HTTPNSP httpNSP(ourUrlList[urlItr]);
|
||||
|
||||
printf("%s %s\n", "Install request from", ourUrlList[urlItr].c_str());
|
||||
tin::install::nsp::RemoteNSPInstall install(m_destStorageId, inst::config::ignoreReqVers, &httpNSP);
|
||||
|
||||
printf("%s\n", "Preparing installation");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
install.Prepare();
|
||||
|
||||
install.Begin();
|
||||
auto httpNSP = new tin::install::nsp::HTTPNSP(ourUrlList[urlItr]);
|
||||
installTask = new tin::install::nsp::RemoteNSPInstall(m_destStorageId, inst::config::ignoreReqVers, httpNSP);
|
||||
}
|
||||
|
||||
printf("%s\n", "Preparing installation");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
installTask->Prepare();
|
||||
|
||||
installTask->Begin();
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
|
|
|
@ -34,7 +34,7 @@ SOFTWARE.
|
|||
#include "util/error.hpp"
|
||||
|
||||
#include "ui/MainApplication.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/config.hpp"
|
||||
#include "util/util.hpp"
|
||||
|
||||
|
@ -66,8 +66,7 @@ namespace inst::ui {
|
|||
mainApp->instpage->installInfoText->SetText("");
|
||||
mainApp->instpage->installBar->SetProgress(0);
|
||||
mainApp->instpage->installBar->SetVisible(false);
|
||||
if (inst::config::gayMode) mainApp->instpage->awooImage->SetVisible(false);
|
||||
else mainApp->instpage->awooImage->SetVisible(true);
|
||||
mainApp->instpage->awooImage->SetVisible(!inst::config::gayMode);
|
||||
mainApp->LoadLayout(mainApp->instpage);
|
||||
mainApp->CallForRender();
|
||||
}
|
||||
|
@ -81,7 +80,7 @@ namespace nspInstStuff {
|
|||
return(finishMessages[rand() % finishMessages.size()]);
|
||||
}
|
||||
|
||||
void installNspFromFile(std::vector<std::filesystem::path> ourNspList, int whereToInstall)
|
||||
void installNspFromFile(std::vector<std::filesystem::path> ourTitleList, int whereToInstall)
|
||||
{
|
||||
inst::util::initInstallServices();
|
||||
if (appletGetAppletType() == AppletType_Application || appletGetAppletType() == AppletType_SystemApplication) appletBeginBlockingHomeButton(0);
|
||||
|
@ -92,7 +91,7 @@ namespace nspInstStuff {
|
|||
std::vector<std::string> oldNamesOfFiles = {};
|
||||
|
||||
if (whereToInstall) m_destStorageId = NcmStorageId_BuiltInUser;
|
||||
unsigned int nspItr;
|
||||
unsigned int titleItr;
|
||||
|
||||
std::vector<int> previousClockValues;
|
||||
if (inst::config::overClock) {
|
||||
|
@ -103,45 +102,43 @@ namespace nspInstStuff {
|
|||
|
||||
try
|
||||
{
|
||||
for (nspItr = 0; nspItr < ourNspList.size(); nspItr++) {
|
||||
if (ourNspList[nspItr].extension() == ".xci" || ourNspList[nspItr].extension() == ".xcz") {
|
||||
inst::ui::setTopInstInfoText("Installing " + inst::util::shortenString(ourNspList[nspItr].filename().string(), 42, true));
|
||||
for (titleItr = 0; titleItr < ourTitleList.size(); titleItr++) {
|
||||
inst::ui::setTopInstInfoText("Installing " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true));
|
||||
tin::install::Install* installTask;
|
||||
|
||||
tin::install::xci::LocalXCI xci(ourNspList[nspItr]);
|
||||
tin::install::xci::XCIInstallTask task(xci, m_destStorageId, inst::config::ignoreReqVers);
|
||||
inst::ui::mainApp->CreateShowDialog(ourTitleList[titleItr].filename().string(), ourTitleList[titleItr].filename().string(), {ourTitleList[titleItr].filename().string()}, true);
|
||||
|
||||
if (ourTitleList[titleItr].extension() == ".xci" || ourTitleList[titleItr].extension() == ".xcz") {
|
||||
auto localXCI = new tin::install::xci::LocalXCI(ourTitleList[titleItr]);
|
||||
installTask = new tin::install::xci::XCIInstallTask(m_destStorageId, inst::config::ignoreReqVers, localXCI);
|
||||
|
||||
printf("Preparing installation\n");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
task.Prepare();
|
||||
installTask->Prepare();
|
||||
|
||||
task.Begin();
|
||||
installTask->Begin();
|
||||
} else {
|
||||
inst::ui::setTopInstInfoText("Installing " + inst::util::shortenString(ourNspList[nspItr].filename().string(), 42, true));
|
||||
|
||||
if (ourNspList[nspItr].extension() == ".nsz") {
|
||||
oldNamesOfFiles.push_back(ourNspList[nspItr]);
|
||||
std::string newfilename = ourNspList[nspItr].string().substr(0, ourNspList[nspItr].string().find_last_of('.'))+"_temp.nsp";
|
||||
rename(ourNspList[nspItr], newfilename);
|
||||
if (ourTitleList[titleItr].extension() == ".nsz") {
|
||||
oldNamesOfFiles.push_back(ourTitleList[titleItr]);
|
||||
std::string newfilename = ourTitleList[titleItr].string().substr(0, ourTitleList[titleItr].string().find_last_of('.'))+"_temp.nsp";
|
||||
rename(ourTitleList[titleItr], newfilename);
|
||||
filesToBeRenamed.push_back(newfilename);
|
||||
ourNspList[nspItr] = newfilename;
|
||||
ourTitleList[titleItr] = newfilename;
|
||||
}
|
||||
|
||||
std::string path = "@Sdcard://" + ourNspList[nspItr].string().erase(0, 6);
|
||||
std::string path = "@Sdcard://" + ourTitleList[titleItr].string().erase(0, 6);
|
||||
|
||||
nx::fs::IFileSystem fileSystem;
|
||||
fileSystem.OpenFileSystemWithId(path, FsFileSystemType_ApplicationPackage, 0);
|
||||
tin::install::nsp::SimpleFileSystem simpleFS(fileSystem, "/", path + "/");
|
||||
tin::install::nsp::NSPInstallTask task(simpleFS, m_destStorageId, inst::config::ignoreReqVers);
|
||||
installTask = new tin::install::nsp::NSPInstallTask(simpleFS, m_destStorageId, inst::config::ignoreReqVers);
|
||||
|
||||
printf("Preparing installation\n");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
task.Prepare();
|
||||
installTask->Prepare();
|
||||
|
||||
task.Begin();
|
||||
installTask->Begin();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -149,9 +146,9 @@ namespace nspInstStuff {
|
|||
printf("Failed to install");
|
||||
printf("%s", e.what());
|
||||
fprintf(stdout, "%s", e.what());
|
||||
inst::ui::setInstInfoText("Failed to install " + inst::util::shortenString(ourNspList[nspItr].filename().string(), 42, true));
|
||||
inst::ui::setInstInfoText("Failed to install " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true));
|
||||
inst::ui::setInstBarPerc(0);
|
||||
inst::ui::mainApp->CreateShowDialog("Failed to install " + inst::util::shortenString(ourNspList[nspItr].filename().string(), 42, true) + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
|
||||
inst::ui::mainApp->CreateShowDialog("Failed to install " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true) + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
|
||||
nspInstalled = false;
|
||||
}
|
||||
|
||||
|
@ -162,7 +159,7 @@ namespace nspInstStuff {
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < filesToBeRenamed.size(); i++) {
|
||||
if (ourNspList.size() == 1) ourNspList[0] = oldNamesOfFiles[i];
|
||||
if (ourTitleList.size() == 1) ourTitleList[0] = oldNamesOfFiles[i];
|
||||
if (std::filesystem::exists(filesToBeRenamed[i])) {
|
||||
rename(filesToBeRenamed[i].c_str(), oldNamesOfFiles[i].c_str());
|
||||
}
|
||||
|
@ -171,18 +168,18 @@ namespace nspInstStuff {
|
|||
if(nspInstalled) {
|
||||
inst::ui::setInstInfoText("Install complete");
|
||||
inst::ui::setInstBarPerc(100);
|
||||
if (ourNspList.size() > 1) {
|
||||
if (ourTitleList.size() > 1) {
|
||||
if (inst::config::deletePrompt) {
|
||||
if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourNspList.size()) + " files installed successfully! Delete them from the SD card?", "The original files aren't needed anymore after they've been installed", {"No","Yes"}, false) == 1) {
|
||||
for (long unsigned int i = 0; i < ourNspList.size(); i++) {
|
||||
if (std::filesystem::exists(ourNspList[i])) std::filesystem::remove(ourNspList[i]);
|
||||
if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully! Delete them from the SD card?", "The original files aren't needed anymore after they've been installed", {"No","Yes"}, 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(ourNspList.size()) + " files installed successfully!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
} else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
} else {
|
||||
if (inst::config::deletePrompt) {
|
||||
if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourNspList[0].filename().string(), 32, true) + " installed! Delete it from the SD card?", "The original file isn't needed anymore after it's been installed", {"No","Yes"}, false) == 1) if (std::filesystem::exists(ourNspList[0])) std::filesystem::remove(ourNspList[0]);
|
||||
} else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourNspList[0].filename().string(), 42, true) + " installed!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + " installed! Delete it from the SD card?", "The original file isn't needed anymore after it's been installed", {"No","Yes"}, 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) + " installed!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,12 +8,14 @@ namespace inst::ui {
|
|||
|
||||
this->mainPage = MainPage::New();
|
||||
this->netinstPage = netInstPage::New();
|
||||
this->nspinstPage = nspInstPage::New();
|
||||
this->sdinstPage = sdInstPage::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->nspinstPage->SetOnInput(std::bind(&nspInstPage::onInput, this->nspinstPage, 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->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);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace inst::ui {
|
|||
this->appVersionText->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->butText = TextBlock::New(10, 678, "\ue0e0 Select \ue0e1 Exit ", 24);
|
||||
this->butText->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->optionMenu = pu::ui::elm::Menu::New(0, 93, 1280, COLOR("#67000000"), 113, (567 / 113));
|
||||
this->optionMenu = pu::ui::elm::Menu::New(0, 93, 1280, COLOR("#67000000"), 94, (567 / 94));
|
||||
this->optionMenu->SetOnFocusColor(COLOR("#00000033"));
|
||||
this->optionMenu->SetScrollbarColor(COLOR("#170909FF"));
|
||||
this->installMenuItem = pu::ui::elm::MenuItem::New("Install from SD card");
|
||||
|
@ -30,6 +30,9 @@ namespace inst::ui {
|
|||
this->netInstallMenuItem = pu::ui::elm::MenuItem::New("Install over LAN or internet");
|
||||
this->netInstallMenuItem->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->netInstallMenuItem->SetIcon("romfs:/cloud-download.png");
|
||||
this->usbInstallMenuItem = pu::ui::elm::MenuItem::New("Install Over USB");
|
||||
this->usbInstallMenuItem->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->usbInstallMenuItem->SetIcon("romfs:/usb-port.png");
|
||||
this->sigPatchesMenuItem = pu::ui::elm::MenuItem::New("Manage signature patches");
|
||||
this->sigPatchesMenuItem->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->sigPatchesMenuItem->SetIcon("romfs:/wrench.png");
|
||||
|
@ -49,6 +52,7 @@ namespace inst::ui {
|
|||
this->Add(this->butText);
|
||||
this->optionMenu->AddItem(this->installMenuItem);
|
||||
this->optionMenu->AddItem(this->netInstallMenuItem);
|
||||
this->optionMenu->AddItem(this->usbInstallMenuItem);
|
||||
this->optionMenu->AddItem(this->sigPatchesMenuItem);
|
||||
this->optionMenu->AddItem(this->settingsMenuItem);
|
||||
this->optionMenu->AddItem(this->exitMenuItem);
|
||||
|
@ -60,9 +64,9 @@ namespace inst::ui {
|
|||
}
|
||||
|
||||
void MainPage::installMenuItem_Click() {
|
||||
mainApp->nspinstPage->drawMenuItems(true, "sdmc:/");
|
||||
mainApp->nspinstPage->menu->SetSelectedIndex(0);
|
||||
mainApp->LoadLayout(mainApp->nspinstPage);
|
||||
mainApp->sdinstPage->drawMenuItems(true, "sdmc:/");
|
||||
mainApp->sdinstPage->menu->SetSelectedIndex(0);
|
||||
mainApp->LoadLayout(mainApp->sdinstPage);
|
||||
}
|
||||
|
||||
void MainPage::netInstallMenuItem_Click() {
|
||||
|
@ -73,6 +77,14 @@ namespace inst::ui {
|
|||
mainApp->netinstPage->startNetwork();
|
||||
}
|
||||
|
||||
void MainPage::usbInstallMenuItem_Click() {
|
||||
if (inst::util::getUsbState() == 5) mainApp->usbinstPage->startUsb();
|
||||
else {
|
||||
mainApp->CreateShowDialog("No USB connection detected", "Plug in to a compatible device to install over USB", {"OK"}, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::sigPatchesMenuItem_Click() {
|
||||
sig::installSigPatches();
|
||||
}
|
||||
|
@ -98,13 +110,16 @@ namespace inst::ui {
|
|||
this->netInstallMenuItem_Click();
|
||||
break;
|
||||
case 2:
|
||||
this->sigPatchesMenuItem_Click();
|
||||
MainPage::usbInstallMenuItem_Click();
|
||||
break;
|
||||
case 3:
|
||||
this->settingsMenuItem_Click();
|
||||
MainPage::sigPatchesMenuItem_Click();
|
||||
break;
|
||||
case 4:
|
||||
this->exitMenuItem_Click();
|
||||
MainPage::settingsMenuItem_Click();
|
||||
break;
|
||||
case 5:
|
||||
MainPage::exitMenuItem_Click();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
namespace inst::ui {
|
||||
extern MainApplication *mainApp;
|
||||
|
||||
std::vector<std::string> netInstPage::ourUrls;
|
||||
std::vector<std::string> netInstPage::selectedUrls;
|
||||
std::vector<std::string> netInstPage::alternativeNames;
|
||||
std::string lastUrl = "https://";
|
||||
std::string lastFileID = "";
|
||||
|
||||
|
@ -66,7 +63,7 @@ namespace inst::ui {
|
|||
}
|
||||
}
|
||||
|
||||
void netInstPage::selectNsp(int selectedIndex) {
|
||||
void netInstPage::selectTitle(int selectedIndex) {
|
||||
if (this->menu->GetItems()[selectedIndex]->GetIcon() == "romfs:/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);
|
||||
|
@ -139,7 +136,7 @@ namespace inst::ui {
|
|||
this->startNetwork();
|
||||
return;
|
||||
}
|
||||
netInstStuff::installNspLan(this->selectedUrls, dialogResult, this->alternativeNames);
|
||||
netInstStuff::installTitleNet(this->selectedUrls, dialogResult, this->alternativeNames);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,7 +145,7 @@ namespace inst::ui {
|
|||
mainApp->LoadLayout(mainApp->mainPage);
|
||||
}
|
||||
if ((Down & KEY_A) || (Up & KEY_TOUCH)) {
|
||||
this->selectNsp(this->menu->GetSelectedIndex());
|
||||
this->selectTitle(this->menu->GetSelectedIndex());
|
||||
if (this->menu->GetItems().size() == 1 && this->selectedUrls.size() == 1) {
|
||||
this->startInstall(false);
|
||||
}
|
||||
|
@ -158,14 +155,14 @@ namespace inst::ui {
|
|||
else {
|
||||
for (long unsigned int i = 0; i < this->menu->GetItems().size(); i++) {
|
||||
if (this->menu->GetItems()[i]->GetIcon() == "romfs:/check-box-outline.png") continue;
|
||||
else this->selectNsp(i);
|
||||
else this->selectTitle(i);
|
||||
}
|
||||
this->drawMenuItems(false);
|
||||
}
|
||||
}
|
||||
if (Down & KEY_PLUS) {
|
||||
if (this->selectedUrls.size() == 0) {
|
||||
this->selectNsp(this->menu->GetSelectedIndex());
|
||||
this->selectTitle(this->menu->GetSelectedIndex());
|
||||
this->startInstall(false);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <filesystem>
|
||||
#include "ui/MainApplication.hpp"
|
||||
#include "ui/mainPage.hpp"
|
||||
#include "ui/nspInstPage.hpp"
|
||||
#include "nspInstall.hpp"
|
||||
#include "ui/sdInstPage.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "util/util.hpp"
|
||||
#include "util/config.hpp"
|
||||
|
||||
|
@ -11,12 +11,7 @@
|
|||
namespace inst::ui {
|
||||
extern MainApplication *mainApp;
|
||||
|
||||
std::vector<std::filesystem::path> nspInstPage::ourDirectories;
|
||||
std::vector<std::filesystem::path> nspInstPage::ourFiles;
|
||||
std::vector<std::filesystem::path> nspInstPage::selectedNsps;
|
||||
std::filesystem::path nspInstPage::currentDir;
|
||||
|
||||
nspInstPage::nspInstPage() : Layout::Layout() {
|
||||
sdInstPage::sdInstPage() : Layout::Layout() {
|
||||
this->SetBackgroundColor(COLOR("#670000FF"));
|
||||
if (std::filesystem::exists(inst::config::appDir + "/background.png")) this->SetBackgroundImage(inst::config::appDir + "/background.png");
|
||||
else this->SetBackgroundImage("romfs:/background.jpg");
|
||||
|
@ -43,8 +38,8 @@ namespace inst::ui {
|
|||
this->Add(this->menu);
|
||||
}
|
||||
|
||||
void nspInstPage::drawMenuItems(bool clearItems, std::filesystem::path ourPath) {
|
||||
if (clearItems) this->selectedNsps = {};
|
||||
void sdInstPage::drawMenuItems(bool clearItems, std::filesystem::path ourPath) {
|
||||
if (clearItems) this->selectedTitles = {};
|
||||
if (ourPath == "sdmc:") this->currentDir = std::filesystem::path(ourPath.string() + "/");
|
||||
else this->currentDir = ourPath;
|
||||
this->menu->ClearItems();
|
||||
|
@ -75,8 +70,8 @@ namespace inst::ui {
|
|||
auto ourEntry = pu::ui::elm::MenuItem::New(itm);
|
||||
ourEntry->SetColor(COLOR("#FFFFFFFF"));
|
||||
ourEntry->SetIcon("romfs:/checkbox-blank-outline.png");
|
||||
for (long unsigned int i = 0; i < this->selectedNsps.size(); i++) {
|
||||
if (this->selectedNsps[i] == file) {
|
||||
for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) {
|
||||
if (this->selectedTitles[i] == file) {
|
||||
ourEntry->SetIcon("romfs:/check-box-outline.png");
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +79,7 @@ namespace inst::ui {
|
|||
}
|
||||
}
|
||||
|
||||
void nspInstPage::followDirectory() {
|
||||
void sdInstPage::followDirectory() {
|
||||
int selectedIndex = this->menu->GetSelectedIndex();
|
||||
int dirListSize = this->ourDirectories.size();
|
||||
if (this->currentDir != "sdmc:/") {
|
||||
|
@ -101,14 +96,14 @@ namespace inst::ui {
|
|||
}
|
||||
}
|
||||
|
||||
void nspInstPage::selectNsp(int selectedIndex) {
|
||||
void sdInstPage::selectNsp(int selectedIndex) {
|
||||
int dirListSize = this->ourDirectories.size();
|
||||
if (this->currentDir != "sdmc:/") dirListSize++;
|
||||
if (this->menu->GetItems()[selectedIndex]->GetIcon() == "romfs:/check-box-outline.png") {
|
||||
for (long unsigned int i = 0; i < this->selectedNsps.size(); i++) {
|
||||
if (this->selectedNsps[i] == this->ourFiles[selectedIndex - dirListSize]) this->selectedNsps.erase(this->selectedNsps.begin() + i);
|
||||
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]->GetIcon() == "romfs:/checkbox-blank-outline.png") this->selectedNsps.push_back(this->ourFiles[selectedIndex - dirListSize]);
|
||||
} else if (this->menu->GetItems()[selectedIndex]->GetIcon() == "romfs:/checkbox-blank-outline.png") this->selectedTitles.push_back(this->ourFiles[selectedIndex - dirListSize]);
|
||||
else {
|
||||
this->followDirectory();
|
||||
return;
|
||||
|
@ -116,27 +111,27 @@ namespace inst::ui {
|
|||
this->drawMenuItems(false, currentDir);
|
||||
}
|
||||
|
||||
void nspInstPage::startInstall() {
|
||||
void sdInstPage::startInstall() {
|
||||
int dialogResult = -1;
|
||||
if (this->selectedNsps.size() == 1) {
|
||||
dialogResult = mainApp->CreateShowDialog("Where should " + inst::util::shortenString(std::filesystem::path(this->selectedNsps[0]).filename().string(), 32, true) + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
} else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedNsps.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
if (this->selectedTitles.size() == 1) {
|
||||
dialogResult = mainApp->CreateShowDialog("Where should " + inst::util::shortenString(std::filesystem::path(this->selectedTitles[0]).filename().string(), 32, true) + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
} else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedTitles.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
if (dialogResult == -1) return;
|
||||
nspInstStuff::installNspFromFile(this->selectedNsps, dialogResult);
|
||||
nspInstStuff::installNspFromFile(this->selectedTitles, dialogResult);
|
||||
}
|
||||
|
||||
void nspInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos) {
|
||||
void sdInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos) {
|
||||
if (Down & KEY_B) {
|
||||
mainApp->LoadLayout(mainApp->mainPage);
|
||||
}
|
||||
if ((Down & KEY_A) || (Up & KEY_TOUCH)) {
|
||||
this->selectNsp(this->menu->GetSelectedIndex());
|
||||
if (this->ourFiles.size() == 1 && this->selectedNsps.size() == 1) {
|
||||
if (this->ourFiles.size() == 1 && this->selectedTitles.size() == 1) {
|
||||
this->startInstall();
|
||||
}
|
||||
}
|
||||
if ((Down & KEY_Y)) {
|
||||
if (this->selectedNsps.size() == this->ourFiles.size()) this->drawMenuItems(true, currentDir);
|
||||
if (this->selectedTitles.size() == this->ourFiles.size()) this->drawMenuItems(true, currentDir);
|
||||
else {
|
||||
int topDir = 0;
|
||||
if (this->currentDir != "sdmc:/") topDir++;
|
||||
|
@ -151,10 +146,10 @@ namespace inst::ui {
|
|||
inst::ui::mainApp->CreateShowDialog("Help", "Copy your NSP, NSZ, XCI, or XCZ files to your SD card, browse to and\nselect the ones you want to install, then press the Plus button.", {"OK"}, true);
|
||||
}
|
||||
if (Down & KEY_PLUS) {
|
||||
if (this->selectedNsps.size() == 0 && this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetIcon() == "romfs:/checkbox-blank-outline.png") {
|
||||
if (this->selectedTitles.size() == 0 && this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetIcon() == "romfs:/checkbox-blank-outline.png") {
|
||||
this->selectNsp(this->menu->GetSelectedIndex());
|
||||
}
|
||||
if (this->selectedNsps.size() > 0) this->startInstall();
|
||||
if (this->selectedTitles.size() > 0) this->startInstall();
|
||||
}
|
||||
}
|
||||
}
|
127
source/ui/usbInstPage.cpp
Executable file
127
source/ui/usbInstPage.cpp
Executable file
|
@ -0,0 +1,127 @@
|
|||
#include "ui/usbInstPage.hpp"
|
||||
#include "ui/MainApplication.hpp"
|
||||
#include "util/util.hpp"
|
||||
#include "util/config.hpp"
|
||||
#include "usbInstall.hpp"
|
||||
|
||||
|
||||
#define COLOR(hex) pu::ui::Color::FromHex(hex)
|
||||
|
||||
namespace inst::ui {
|
||||
extern MainApplication *mainApp;
|
||||
|
||||
usbInstPage::usbInstPage() : Layout::Layout() {
|
||||
this->SetBackgroundColor(COLOR("#670000FF"));
|
||||
this->SetBackgroundImage("romfs:/background.jpg");
|
||||
this->topRect = Rectangle::New(0, 0, 1280, 93, COLOR("#170909FF"));
|
||||
this->infoRect = Rectangle::New(0, 93, 1280, 60, COLOR("#17090980"));
|
||||
this->botRect = Rectangle::New(0, 660, 1280, 60, COLOR("#17090980"));
|
||||
this->titleImage = Image::New(0, 0, "romfs:/logo.png");
|
||||
this->appVersionText = TextBlock::New(480, 49, "v" + inst::config::appVersion, 22);
|
||||
this->appVersionText->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->pageInfoText = TextBlock::New(10, 109, "", 30);
|
||||
this->pageInfoText->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->butText = TextBlock::New(10, 678, "", 24);
|
||||
this->butText->SetColor(COLOR("#FFFFFFFF"));
|
||||
this->menu = pu::ui::elm::Menu::New(0, 154, 1280, COLOR("#FFFFFF00"), 84, (506 / 84));
|
||||
this->menu->SetOnFocusColor(COLOR("#00000033"));
|
||||
this->menu->SetScrollbarColor(COLOR("#17090980"));
|
||||
this->infoImage = Image::New(460, 332, "romfs:/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) {
|
||||
if (clearItems) this->selectedTitles = {};
|
||||
this->menu->ClearItems();
|
||||
for (auto& url: this->ourTitles) {
|
||||
pu::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:/checkbox-blank-outline.png");
|
||||
for (long unsigned int i = 0; i < this->selectedTitles.size(); i++) {
|
||||
if (this->selectedTitles[i] == url) {
|
||||
ourEntry->SetIcon("romfs:/check-box-outline.png");
|
||||
}
|
||||
}
|
||||
this->menu->AddItem(ourEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void usbInstPage::selectTitle(int selectedIndex) {
|
||||
if (this->menu->GetItems()[selectedIndex]->GetIcon() == "romfs:/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("USB connection successful! Waiting for files to be sent...");
|
||||
this->butText->SetText("");
|
||||
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 {
|
||||
this->pageInfoText->SetText("Select what files you want to install over USB, then press the Plus button!");
|
||||
this->butText->SetText("\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e1 Cancel ");
|
||||
this->drawMenuItems(true);
|
||||
}
|
||||
this->infoImage->SetVisible(false);
|
||||
this->menu->SetVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
void usbInstPage::startInstall() {
|
||||
int dialogResult = -1;
|
||||
if (this->selectedTitles.size() == 1) dialogResult = mainApp->CreateShowDialog("Where should " + selectedTitles[0] + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedTitles.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
|
||||
if (dialogResult == -1) return;
|
||||
usbInstStuff::installTitleUsb(this->selectedTitles, dialogResult);
|
||||
return;
|
||||
}
|
||||
|
||||
void usbInstPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos) {
|
||||
if (Down & KEY_B) {
|
||||
mainApp->LoadLayout(mainApp->mainPage);
|
||||
}
|
||||
if ((Down & KEY_A) || (Up & KEY_TOUCH)) {
|
||||
this->selectTitle(this->menu->GetSelectedIndex());
|
||||
if (this->menu->GetItems().size() == 1 && this->selectedTitles.size() == 1) {
|
||||
this->startInstall();
|
||||
}
|
||||
}
|
||||
if ((Down & KEY_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]->GetIcon() == "romfs:/check-box-outline.png") continue;
|
||||
else this->selectTitle(i);
|
||||
}
|
||||
this->drawMenuItems(false);
|
||||
}
|
||||
}
|
||||
if (Down & KEY_PLUS) {
|
||||
if (this->selectedTitles.size() == 0) {
|
||||
this->selectTitle(this->menu->GetSelectedIndex());
|
||||
this->startInstall();
|
||||
return;
|
||||
}
|
||||
this->startInstall();
|
||||
}
|
||||
}
|
||||
}
|
139
source/usbInstall.cpp
Executable file
139
source/usbInstall.cpp
Executable file
|
@ -0,0 +1,139 @@
|
|||
#include <string>
|
||||
#include "usbInstall.hpp"
|
||||
#include "install/usb_nsp.hpp"
|
||||
#include "install/install_nsp_remote.hpp"
|
||||
#include "util/usb_util.hpp"
|
||||
#include "util/util.hpp"
|
||||
#include "util/config.hpp"
|
||||
#include "ui/usbInstPage.hpp"
|
||||
|
||||
#include "install/usb_xci.hpp"
|
||||
#include "install/install_xci.hpp"
|
||||
#include "sdInstall.hpp"
|
||||
#include "ui/MainApplication.hpp"
|
||||
|
||||
namespace inst::ui {
|
||||
extern MainApplication *mainApp;
|
||||
|
||||
void setUsbInfoText(std::string ourText){
|
||||
mainApp->usbinstPage->pageInfoText->SetText(ourText);
|
||||
mainApp->CallForRender();
|
||||
}
|
||||
}
|
||||
|
||||
namespace usbInstStuff {
|
||||
struct TUSHeader
|
||||
{
|
||||
u32 magic; // TUL0 (Tinfoil Usb List 0)
|
||||
u32 titleListSize;
|
||||
u64 padding;
|
||||
} PACKED;
|
||||
|
||||
std::vector<std::string> OnSelected() {
|
||||
Result rc = 0;
|
||||
|
||||
while(true) {
|
||||
rc = usbDsWaitReady(1000000);
|
||||
if (R_SUCCEEDED(rc)) break;
|
||||
else if ((rc & 0x3FFFFF) != 0xEA01)
|
||||
return {};
|
||||
}
|
||||
|
||||
TUSHeader header;
|
||||
tin::util::USBRead(&header, sizeof(TUSHeader));
|
||||
|
||||
if (header.magic != 0x304C5554)
|
||||
return {};
|
||||
|
||||
auto titleListBuf = std::make_unique<char[]>(header.titleListSize+1);
|
||||
std::vector<std::string> titleNames;
|
||||
memset(titleListBuf.get(), 0, header.titleListSize+1);
|
||||
|
||||
tin::util::USBRead(titleListBuf.get(), header.titleListSize);
|
||||
|
||||
// Split the string up into individual title names
|
||||
std::stringstream titleNamesStream(titleListBuf.get());
|
||||
std::string segment;
|
||||
while (std::getline(titleNamesStream, segment, '\n')) {
|
||||
titleNames.push_back(segment);
|
||||
}
|
||||
|
||||
return titleNames;
|
||||
}
|
||||
|
||||
void installTitleUsb(std::vector<std::string> ourTitleList, int ourStorage)
|
||||
{
|
||||
inst::util::initInstallServices();
|
||||
inst::ui::loadInstallScreen();
|
||||
bool nspInstalled = true;
|
||||
NcmStorageId m_destStorageId = NcmStorageId_SdCard;
|
||||
|
||||
if (ourStorage) m_destStorageId = NcmStorageId_BuiltInUser;
|
||||
unsigned int fileItr;
|
||||
|
||||
std::vector<std::string> fileNames;
|
||||
for (long unsigned int i = 0; i < ourTitleList.size(); i++) {
|
||||
fileNames.push_back(inst::util::shortenString(ourTitleList[i], 42, true));
|
||||
}
|
||||
/*
|
||||
std::vector<int> 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::setTopInstInfoText("Installing " + fileNames[fileItr]);
|
||||
|
||||
tin::install::Install* installTask;
|
||||
|
||||
if (ourTitleList[fileItr].compare(ourTitleList[fileItr].size() - 3, 2, "xc") == 0) {
|
||||
auto usbXCI = new tin::install::xci::USBXCI(ourTitleList[fileItr]);
|
||||
installTask = new tin::install::xci::XCIInstallTask(m_destStorageId, inst::config::ignoreReqVers, usbXCI);
|
||||
} else {
|
||||
auto usbNSP = new tin::install::nsp::USBNSP(ourTitleList[fileItr]);
|
||||
installTask = new tin::install::nsp::RemoteNSPInstall(m_destStorageId, inst::config::ignoreReqVers, usbNSP);
|
||||
}
|
||||
|
||||
printf("%s\n", "Preparing installation");
|
||||
inst::ui::setInstInfoText("Preparing installation...");
|
||||
inst::ui::setInstBarPerc(0);
|
||||
installTask->Prepare();
|
||||
|
||||
installTask->Begin();
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
printf("Failed to install");
|
||||
printf("%s", e.what());
|
||||
fprintf(stdout, "%s", e.what());
|
||||
inst::ui::setInstInfoText("Failed to install " + fileNames[fileItr]);
|
||||
inst::ui::setInstBarPerc(0);
|
||||
inst::ui::mainApp->CreateShowDialog("Failed to install " + fileNames[fileItr] + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
|
||||
nspInstalled = false;
|
||||
}
|
||||
|
||||
tin::util::USBCmdManager::SendExitCmd();
|
||||
/*
|
||||
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::setInstInfoText("Install complete");
|
||||
inst::ui::setInstBarPerc(100);
|
||||
if (ourTitleList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
else inst::ui::mainApp->CreateShowDialog(fileNames[0] + " installed!", nspInstStuff::finishedMessage(), {"OK"}, true);
|
||||
}
|
||||
|
||||
printf("Done");
|
||||
inst::ui::loadMainMenu();
|
||||
inst::util::deinitInstallServices();
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -29,69 +29,23 @@ SOFTWARE.
|
|||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <switch/runtime/nxlink.h>
|
||||
|
||||
#ifdef NXLINK_DEBUG
|
||||
static int sock = -1;
|
||||
#endif
|
||||
FILE *nxlinkout;
|
||||
|
||||
int nxLinkInitialize(void)
|
||||
void printBytes(u8 *bytes, size_t size, bool includeHeader)
|
||||
{
|
||||
#ifdef NXLINK_DEBUG
|
||||
int ret = -1;
|
||||
struct sockaddr_in srv_addr;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (!sock) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bzero(&srv_addr, sizeof srv_addr);
|
||||
srv_addr.sin_family = AF_INET;
|
||||
srv_addr.sin_addr = __nxlink_host;
|
||||
srv_addr.sin_port = htons(NXLINK_CLIENT_PORT);
|
||||
|
||||
ret = connect(sock, (struct sockaddr *) &srv_addr, sizeof(srv_addr));
|
||||
if (ret != 0) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fflush(nxlinkout);
|
||||
nxlinkout = fdopen(sock, "w");
|
||||
setvbuf(nxlinkout, NULL, _IONBF, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nxLinkExit(void)
|
||||
{
|
||||
#ifdef NXLINK_DEBUG
|
||||
fclose(nxlinkout);
|
||||
#endif
|
||||
}
|
||||
|
||||
void printBytes(FILE* out, u8 *bytes, size_t size, bool includeHeader)
|
||||
{
|
||||
if (out == NULL)
|
||||
return;
|
||||
|
||||
int count = 0;
|
||||
|
||||
if (includeHeader)
|
||||
{
|
||||
fprintf(out, "\n\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
|
||||
fprintf(out, "-----------------------------------------------\n");
|
||||
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++)
|
||||
{
|
||||
fprintf(out, "%02x ", bytes[i]);
|
||||
printf("%02x ", bytes[i]);
|
||||
count++;
|
||||
if ((count % 16) == 0)
|
||||
fprintf(out, "\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
fprintf(out, "\n");
|
||||
printf("\n");
|
||||
}
|
82
source/util/usb_util.cpp
Executable file
82
source/util/usb_util.cpp
Executable file
|
@ -0,0 +1,82 @@
|
|||
#include "util/usb_util.hpp"
|
||||
|
||||
#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)
|
||||
{
|
||||
u8* tmpBuf = (u8*)out;
|
||||
size_t sizeRemaining = len;
|
||||
size_t tmpSizeRead = 0;
|
||||
|
||||
while (sizeRemaining)
|
||||
{
|
||||
tmpSizeRead = usbCommsRead(tmpBuf, sizeRemaining);
|
||||
tmpBuf += tmpSizeRead;
|
||||
sizeRemaining -= tmpSizeRead;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t USBWrite(const void* in, size_t len)
|
||||
{
|
||||
const u8 *bufptr = (const u8 *)in;
|
||||
size_t cursize = len;
|
||||
size_t tmpsize = 0;
|
||||
|
||||
while (cursize)
|
||||
{
|
||||
tmpsize = usbCommsWrite(bufptr, cursize);
|
||||
//LOG_DEBUG("USB Bytes Written: \n");
|
||||
//printBytes((u8*)bufptr, tmpsize, true);
|
||||
bufptr += tmpsize;
|
||||
cursize -= tmpsize;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
|
@ -28,10 +28,12 @@ namespace inst::util {
|
|||
#ifdef __DEBUG__
|
||||
nxlinkStdio();
|
||||
#endif
|
||||
usbCommsInitialize();
|
||||
}
|
||||
|
||||
void deinitApp () {
|
||||
socketExit();
|
||||
usbCommsExit();
|
||||
}
|
||||
|
||||
void initInstallServices() {
|
||||
|
@ -255,4 +257,10 @@ namespace inst::util {
|
|||
struct in_addr addr = {(in_addr_t) gethostid()};
|
||||
return inet_ntoa(addr);
|
||||
}
|
||||
|
||||
int getUsbState() {
|
||||
u32 usbState = 0;
|
||||
usbDsGetState(&usbState);
|
||||
return usbState;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue