mirror of
https://github.com/jakcron/nstool
synced 2024-12-25 14:11:14 +00:00
Merge pull request #14 from jakcron/xci-development
[nx|nstool] Added support for xci logo partition.
This commit is contained in:
commit
f13b4ec2a4
8 changed files with 93 additions and 111 deletions
|
@ -23,6 +23,11 @@ namespace nx
|
|||
static const uint32_t kCertAreaPageCount = 64;
|
||||
static const uint32_t kNormalAreaStartPageAddress = kReservedAreaPageCount + kCertAreaPageCount + kCardHeaderPageCount + kCardKeyAreaPageCount;
|
||||
|
||||
const std::string kUpdatePartitionStr = "update";
|
||||
const std::string kNormalPartitionStr = "normal";
|
||||
const std::string kSecurePartitionStr = "secure";
|
||||
const std::string kLogoPartitionStr = "logo";
|
||||
|
||||
|
||||
enum KekIndex
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <fnd/IFile.h>
|
||||
#include <nx/npdm.h>
|
||||
#include <nx/NsoHeader.h>
|
||||
|
||||
#include "nstool.h"
|
||||
|
|
|
@ -48,6 +48,7 @@ void UserSettings::showHelp()
|
|||
printf(" --listfs Print file system in embedded partitions\n");
|
||||
printf(" --update Extract \"update\" partition to directory\n");
|
||||
printf(" --normal Extract \"normal\" partition to directory\n");
|
||||
printf(" --logo Extract \"logo\" partition to directory\n");
|
||||
printf(" --secure Extract \"secure\" partition to directory\n");
|
||||
printf("\n PFS0/HFS0 (PartitionFs), RomFs, NSP (Ninendo Submission Package)\n");
|
||||
printf(" nstool [--listfs] [--fsdir <dir>] <file>\n");
|
||||
|
@ -103,19 +104,24 @@ const sOptional<nx::npdm::InstructionType>& UserSettings::getArchType() const
|
|||
return mArchType;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getUpdatePath() const
|
||||
const sOptional<std::string>& UserSettings::getXciUpdatePath() const
|
||||
{
|
||||
return mUpdatePath;
|
||||
return mXciUpdatePath;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getNormalPath() const
|
||||
const sOptional<std::string>& UserSettings::getXciNormalPath() const
|
||||
{
|
||||
return mNormalPath;
|
||||
return mXciNormalPath;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getSecurePath() const
|
||||
const sOptional<std::string>& UserSettings::getXciSecurePath() const
|
||||
{
|
||||
return mSecurePath;
|
||||
return mXciSecurePath;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getXciLogoPath() const
|
||||
{
|
||||
return mXciLogoPath;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getFsPath() const
|
||||
|
@ -123,24 +129,24 @@ const sOptional<std::string>& UserSettings::getFsPath() const
|
|||
return mFsPath;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getPart0Path() const
|
||||
const sOptional<std::string>& UserSettings::getNcaPart0Path() const
|
||||
{
|
||||
return mPart0Path;
|
||||
return mNcaPart0Path;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getPart1Path() const
|
||||
const sOptional<std::string>& UserSettings::getNcaPart1Path() const
|
||||
{
|
||||
return mPart1Path;
|
||||
return mNcaPart1Path;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getPart2Path() const
|
||||
const sOptional<std::string>& UserSettings::getNcaPart2Path() const
|
||||
{
|
||||
return mPart2Path;
|
||||
return mNcaPart2Path;
|
||||
}
|
||||
|
||||
const sOptional<std::string>& UserSettings::getPart3Path() const
|
||||
const sOptional<std::string>& UserSettings::getNcaPart3Path() const
|
||||
{
|
||||
return mPart3Path;
|
||||
return mNcaPart3Path;
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,7 +166,6 @@ void UserSettings::populateCmdArgs(int argc, char** argv, sCmdArgs& cmd_args)
|
|||
throw fnd::Exception(kModuleName, "Not enough arguments.");
|
||||
}
|
||||
|
||||
cmd_args.clear();
|
||||
cmd_args.input_path = args.back();
|
||||
|
||||
for (size_t i = 1; i < args.size(); i++)
|
||||
|
@ -236,6 +241,12 @@ void UserSettings::populateCmdArgs(int argc, char** argv, sCmdArgs& cmd_args)
|
|||
cmd_args.secure_path = args[i+1];
|
||||
}
|
||||
|
||||
else if (args[i] == "--logo")
|
||||
{
|
||||
if (!hasParamter) throw fnd::Exception(kModuleName, args[i] + " requries a parameter.");
|
||||
cmd_args.logo_path = args[i+1];
|
||||
}
|
||||
|
||||
else if (args[i] == "--fsdir")
|
||||
{
|
||||
if (!hasParamter) throw fnd::Exception(kModuleName, args[i] + " requries a parameter.");
|
||||
|
@ -530,20 +541,20 @@ void UserSettings::populateUserSettings(sCmdArgs& args)
|
|||
mInputPath = *args.input_path;
|
||||
mVerifyFile = args.verify_file.isSet;
|
||||
mListFs = args.list_fs.isSet;
|
||||
mUpdatePath = args.update_path;
|
||||
mNormalPath = args.normal_path;
|
||||
mSecurePath = args.secure_path;
|
||||
mXciUpdatePath = args.update_path;
|
||||
mXciNormalPath = args.normal_path;
|
||||
mXciSecurePath = args.secure_path;
|
||||
mXciLogoPath = args.logo_path;
|
||||
|
||||
mFsPath = args.fs_path;
|
||||
mPart0Path = args.part0_path;
|
||||
mPart1Path = args.part1_path;
|
||||
mPart2Path = args.part2_path;
|
||||
mPart3Path = args.part3_path;
|
||||
mNcaPart0Path = args.part0_path;
|
||||
mNcaPart1Path = args.part1_path;
|
||||
mNcaPart2Path = args.part2_path;
|
||||
mNcaPart3Path = args.part3_path;
|
||||
|
||||
// determine the architecture type for NSO
|
||||
if (args.arch_type.isSet)
|
||||
mArchType = getInstructionTypeFromString(*args.arch_type);
|
||||
else
|
||||
mArchType.isSet = false;
|
||||
|
||||
// determine output path
|
||||
if (args.verbose_output.isSet)
|
||||
|
|
|
@ -24,20 +24,22 @@ public:
|
|||
const sOptional<nx::npdm::InstructionType>& getArchType() const;
|
||||
|
||||
// specialised paths
|
||||
const sOptional<std::string>& getUpdatePath() const;
|
||||
const sOptional<std::string>& getNormalPath() const;
|
||||
const sOptional<std::string>& getSecurePath() const;
|
||||
const sOptional<std::string>& getXciUpdatePath() const;
|
||||
const sOptional<std::string>& getXciNormalPath() const;
|
||||
const sOptional<std::string>& getXciSecurePath() const;
|
||||
const sOptional<std::string>& getXciLogoPath() const;
|
||||
const sOptional<std::string>& getFsPath() const;
|
||||
const sOptional<std::string>& getPart0Path() const;
|
||||
const sOptional<std::string>& getPart1Path() const;
|
||||
const sOptional<std::string>& getPart2Path() const;
|
||||
const sOptional<std::string>& getPart3Path() const;
|
||||
const sOptional<std::string>& getNcaPart0Path() const;
|
||||
const sOptional<std::string>& getNcaPart1Path() const;
|
||||
const sOptional<std::string>& getNcaPart2Path() const;
|
||||
const sOptional<std::string>& getNcaPart3Path() const;
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "UserSettings";
|
||||
|
||||
struct sCmdArgs
|
||||
{
|
||||
sCmdArgs() {}
|
||||
sOptional<std::string> input_path;
|
||||
sOptional<bool> devkit_keys;
|
||||
sOptional<std::string> keyset_path;
|
||||
|
@ -49,6 +51,7 @@ private:
|
|||
sOptional<std::string> update_path;
|
||||
sOptional<std::string> normal_path;
|
||||
sOptional<std::string> secure_path;
|
||||
sOptional<std::string> logo_path;
|
||||
sOptional<std::string> fs_path;
|
||||
sOptional<std::string> nca_titlekey;
|
||||
sOptional<std::string> nca_bodykey;
|
||||
|
@ -57,29 +60,6 @@ private:
|
|||
sOptional<std::string> part2_path;
|
||||
sOptional<std::string> part3_path;
|
||||
sOptional<std::string> arch_type;
|
||||
|
||||
void clear()
|
||||
{
|
||||
input_path.isSet = false;
|
||||
devkit_keys.isSet = false;
|
||||
keyset_path.isSet = false;
|
||||
file_type.isSet = false;
|
||||
verify_file.isSet = false;
|
||||
verbose_output.isSet = false;
|
||||
minimal_output.isSet = false;
|
||||
list_fs.isSet = false;
|
||||
update_path.isSet = false;
|
||||
normal_path.isSet = false;
|
||||
secure_path.isSet = false;
|
||||
fs_path.isSet = false;
|
||||
nca_titlekey.isSet = false;
|
||||
nca_bodykey.isSet = false;
|
||||
part0_path.isSet = false;
|
||||
part1_path.isSet = false;
|
||||
part2_path.isSet = false;
|
||||
part3_path.isSet = false;
|
||||
arch_type.isSet = false;
|
||||
}
|
||||
};
|
||||
|
||||
std::string mInputPath;
|
||||
|
@ -89,15 +69,16 @@ private:
|
|||
CliOutputType mOutputType;
|
||||
|
||||
bool mListFs;
|
||||
sOptional<std::string> mUpdatePath;
|
||||
sOptional<std::string> mNormalPath;
|
||||
sOptional<std::string> mSecurePath;
|
||||
sOptional<std::string> mXciUpdatePath;
|
||||
sOptional<std::string> mXciNormalPath;
|
||||
sOptional<std::string> mXciSecurePath;
|
||||
sOptional<std::string> mXciLogoPath;
|
||||
sOptional<std::string> mFsPath;
|
||||
|
||||
sOptional<std::string> mPart0Path;
|
||||
sOptional<std::string> mPart1Path;
|
||||
sOptional<std::string> mPart2Path;
|
||||
sOptional<std::string> mPart3Path;
|
||||
sOptional<std::string> mNcaPart0Path;
|
||||
sOptional<std::string> mNcaPart1Path;
|
||||
sOptional<std::string> mNcaPart2Path;
|
||||
sOptional<std::string> mNcaPart3Path;
|
||||
|
||||
sOptional<nx::npdm::InstructionType> mArchType;
|
||||
|
||||
|
|
|
@ -163,12 +163,13 @@ void XciProcess::processPartitionPfs()
|
|||
tmp.setVerifyMode(mVerify);
|
||||
tmp.setCliOutputMode(mCliOutputType);
|
||||
tmp.setMountPointName(kXciMountPointName + rootPartitions[i].name);
|
||||
if (mUpdatePath.doExtract && rootPartitions[i].name == "update")
|
||||
tmp.setExtractPath(mUpdatePath.path);
|
||||
if (mNormalPath.doExtract && rootPartitions[i].name == "normal")
|
||||
tmp.setExtractPath(mNormalPath.path);
|
||||
if (mSecurePath.doExtract && rootPartitions[i].name == "secure")
|
||||
tmp.setExtractPath(mSecurePath.path);
|
||||
for (size_t j = 0; j < mExtractInfo.size(); j++)
|
||||
{
|
||||
if (mExtractInfo[j].partition_name == rootPartitions[i].name)
|
||||
{
|
||||
tmp.setExtractPath(mExtractInfo[j].extract_path);
|
||||
}
|
||||
}
|
||||
tmp.process();
|
||||
}
|
||||
}
|
||||
|
@ -180,13 +181,8 @@ XciProcess::XciProcess() :
|
|||
mVerify(false),
|
||||
mListFs(false),
|
||||
mRootPfs(),
|
||||
mUpdatePfs(),
|
||||
mNormalPfs(),
|
||||
mSecurePfs()
|
||||
mExtractInfo()
|
||||
{
|
||||
mUpdatePath.doExtract = false;
|
||||
mNormalPath.doExtract = false;
|
||||
mSecurePath.doExtract = false;
|
||||
}
|
||||
|
||||
XciProcess::~XciProcess()
|
||||
|
@ -255,22 +251,9 @@ void XciProcess::setVerifyMode(bool verify)
|
|||
mVerify = verify;
|
||||
}
|
||||
|
||||
void XciProcess::setUpdateExtractPath(const std::string& path)
|
||||
void XciProcess::setPartitionForExtract(const std::string& partition_name, const std::string& extract_path)
|
||||
{
|
||||
mUpdatePath.path = path;
|
||||
mUpdatePath.doExtract = true;
|
||||
}
|
||||
|
||||
void XciProcess::setNormalExtractPath(const std::string& path)
|
||||
{
|
||||
mNormalPath.path = path;
|
||||
mNormalPath.doExtract = true;
|
||||
}
|
||||
|
||||
void XciProcess::setSecureExtractPath(const std::string& path)
|
||||
{
|
||||
mSecurePath.path = path;
|
||||
mSecurePath.doExtract = true;
|
||||
mExtractInfo.push_back({partition_name, extract_path});
|
||||
}
|
||||
|
||||
void XciProcess::setListFs(bool list_fs)
|
||||
|
|
|
@ -24,9 +24,7 @@ public:
|
|||
void setVerifyMode(bool verify);
|
||||
|
||||
// xci specific
|
||||
void setUpdateExtractPath(const std::string& path);
|
||||
void setNormalExtractPath(const std::string& path);
|
||||
void setSecureExtractPath(const std::string& path);
|
||||
void setPartitionForExtract(const std::string& partition_name, const std::string& extract_path);
|
||||
void setListFs(bool list_fs);
|
||||
|
||||
private:
|
||||
|
@ -39,17 +37,18 @@ private:
|
|||
CliOutputType mCliOutputType;
|
||||
bool mVerify;
|
||||
|
||||
struct sExtract
|
||||
struct sExtractInfo
|
||||
{
|
||||
std::string path;
|
||||
bool doExtract;
|
||||
} mUpdatePath, mNormalPath, mSecurePath;
|
||||
std::string partition_name;
|
||||
std::string extract_path;
|
||||
};
|
||||
|
||||
bool mListFs;
|
||||
|
||||
nx::sXciHeaderPage mHdrPage;
|
||||
nx::XciHeader mHdr;
|
||||
PfsProcess mRootPfs, mUpdatePfs, mNormalPfs, mSecurePfs;
|
||||
PfsProcess mRootPfs;
|
||||
std::vector<sExtractInfo> mExtractInfo;
|
||||
|
||||
void displayHeader();
|
||||
bool validateRegionOfFile(size_t offset, size_t len, const byte_t* test_hash);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "CnmtProcess.h"
|
||||
#include "NsoProcess.h"
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
UserSettings user_set;
|
||||
|
@ -29,12 +28,14 @@ int main(int argc, char** argv)
|
|||
xci.setCliOutputMode(user_set.getCliOutputType());
|
||||
xci.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
if (user_set.getUpdatePath().isSet)
|
||||
xci.setUpdateExtractPath(user_set.getUpdatePath().var);
|
||||
if (user_set.getNormalPath().isSet)
|
||||
xci.setNormalExtractPath(user_set.getNormalPath().var);
|
||||
if (user_set.getSecurePath().isSet)
|
||||
xci.setSecureExtractPath(user_set.getSecurePath().var);
|
||||
if (user_set.getXciUpdatePath().isSet)
|
||||
xci.setPartitionForExtract(nx::xci::kUpdatePartitionStr, user_set.getXciUpdatePath().var);
|
||||
if (user_set.getXciNormalPath().isSet)
|
||||
xci.setPartitionForExtract(nx::xci::kNormalPartitionStr, user_set.getXciNormalPath().var);
|
||||
if (user_set.getXciSecurePath().isSet)
|
||||
xci.setPartitionForExtract(nx::xci::kSecurePartitionStr, user_set.getXciSecurePath().var);
|
||||
if (user_set.getXciLogoPath().isSet)
|
||||
xci.setPartitionForExtract(nx::xci::kLogoPartitionStr, user_set.getXciLogoPath().var);
|
||||
xci.setListFs(user_set.isListFs());
|
||||
|
||||
xci.process();
|
||||
|
@ -77,14 +78,14 @@ int main(int argc, char** argv)
|
|||
nca.setVerifyMode(user_set.isVerifyFile());
|
||||
|
||||
|
||||
if (user_set.getPart0Path().isSet)
|
||||
nca.setPartition0ExtractPath(user_set.getPart0Path().var);
|
||||
if (user_set.getPart1Path().isSet)
|
||||
nca.setPartition1ExtractPath(user_set.getPart1Path().var);
|
||||
if (user_set.getPart2Path().isSet)
|
||||
nca.setPartition2ExtractPath(user_set.getPart2Path().var);
|
||||
if (user_set.getPart3Path().isSet)
|
||||
nca.setPartition3ExtractPath(user_set.getPart3Path().var);
|
||||
if (user_set.getNcaPart0Path().isSet)
|
||||
nca.setPartition0ExtractPath(user_set.getNcaPart0Path().var);
|
||||
if (user_set.getNcaPart1Path().isSet)
|
||||
nca.setPartition1ExtractPath(user_set.getNcaPart1Path().var);
|
||||
if (user_set.getNcaPart2Path().isSet)
|
||||
nca.setPartition2ExtractPath(user_set.getNcaPart2Path().var);
|
||||
if (user_set.getNcaPart3Path().isSet)
|
||||
nca.setPartition3ExtractPath(user_set.getNcaPart3Path().var);
|
||||
nca.setListFs(user_set.isListFs());
|
||||
|
||||
nca.process();
|
||||
|
|
|
@ -35,6 +35,7 @@ struct sOptional
|
|||
{
|
||||
bool isSet;
|
||||
T var;
|
||||
inline sOptional() : isSet(false) {}
|
||||
inline const T& operator=(const T& other) { isSet = true; var = other; return var; }
|
||||
inline const sOptional<T>& operator=(const sOptional<T>& other)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue