Merge pull request #21 from jakcron/nacp-development

Added NACP support.
This commit is contained in:
Jack 2018-06-11 23:09:37 +08:00 committed by GitHub
commit 0c7333fa74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 1923 additions and 9 deletions

View file

@ -6,7 +6,7 @@ Tools & Libraries for NX (Nintendo Switch).
# Tools
* __nstool__ - read *.npdm, read/extract PartitionFS (PFS0|HFS0) blobs (including *.nsp), read/extract RomFS blobs, read/extract *.xci, read/extract *.nca, read *.cnmt, read *.nso, read *.nro
* __nstool__ - read *.npdm, read/extract PartitionFS (PFS0|HFS0) blobs (including *.nsp), read/extract RomFS blobs, read/extract *.xci, read/extract *.nca, read *.cnmt, read *.nso, read *.nro, read *.nacp
# Libraries

View file

@ -0,0 +1,270 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <fnd/MemoryBlob.h>
#include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
#include <nx/nacp.h>
namespace nx
{
class ApplicationControlPropertyBinary :
public fnd::ISerialiseableBinary
{
public:
struct sTitle
{
nacp::Language language;
std::string name;
std::string publisher;
void operator=(const sTitle& other)
{
language = other.language;
name = other.name;
publisher = other.publisher;
}
bool operator==(const sTitle& other) const
{
return (language == other.language) \
&& (name == other.name) \
&& (publisher == other.publisher);
}
bool operator!=(const sTitle& other) const
{
return !operator==(other);
}
};
struct sRating
{
nacp::Organisation organisation;
int8_t age;
void operator=(const sRating& other)
{
organisation = other.organisation;
age = other.age;
}
bool operator==(const sRating& other) const
{
return (organisation == other.organisation) \
&& (age == other.age);
}
bool operator!=(const sRating& other) const
{
return !operator==(other);
}
};
struct sStorageSize
{
int64_t size;
int64_t journal_size;
void operator=(const sStorageSize& other)
{
size = other.size;
journal_size = other.journal_size;
}
bool operator==(const sStorageSize& other) const
{
return (size == other.size) \
&& (journal_size == other.journal_size);
}
bool operator!=(const sStorageSize& other) const
{
return !operator==(other);
}
};
ApplicationControlPropertyBinary();
ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other);
ApplicationControlPropertyBinary(const byte_t* bytes, size_t len);
bool operator==(const ApplicationControlPropertyBinary& other) const;
bool operator!=(const ApplicationControlPropertyBinary& other) const;
void operator=(const ApplicationControlPropertyBinary& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
void exportBinary();
void importBinary(const byte_t* bytes, size_t len);
// variables
void clear();
const fnd::List<sTitle>& getTitle() const;
void setTitle(const fnd::List<sTitle>& title);
const std::string& getIsbn() const;
void setIsbn(const std::string& isbn);
nacp::StartupUserAccount getStartupUserAccount() const;
void setStartupUserAccount(nacp::StartupUserAccount var);
nacp::TouchScreenUsageMode getTouchScreenUsageMode() const;
void setTouchScreenUsageMode(nacp::TouchScreenUsageMode var);
nacp::AocRegistrationType getAocRegistrationType() const;
void setAocRegistrationType(nacp::AocRegistrationType var);
nacp::AttributeFlag getAttributeFlag() const;
void setAttributeFlag(nacp::AttributeFlag var);
nacp::ParentalControlFlag getParentalControlFlag() const;
void setParentalControlFlag(nacp::ParentalControlFlag var);
nacp::ScreenshotMode getScreenshotMode() const;
void setScreenshotMode(nacp::ScreenshotMode var);
nacp::VideoCaptureMode getVideoCaptureMode() const;
void setVideoCaptureMode(nacp::VideoCaptureMode var);
nacp::DataLossConfirmation getDataLossConfirmation() const;
void setDataLossConfirmation(nacp::DataLossConfirmation var);
nacp::PlayLogPolicy getPlayLogPolicy() const;
void setPlayLogPolicy(nacp::PlayLogPolicy var);
uint64_t getPresenceGroupId() const;
void setPresenceGroupId(uint64_t var);
const fnd::List<sRating>& getRatingAge() const;
void setRatingAge(const fnd::List<sRating>& var);
const std::string& getDisplayVersion() const;
void setDisplayVersion(const std::string& var);
uint64_t getAocBaseId() const;
void setAocBaseId(uint64_t var);
uint64_t getSaveDatawOwnerId() const;
void setSaveDatawOwnerId(uint64_t var);
const sStorageSize& getUserAccountSaveDataSize() const;
void setUserAccountSaveDataSize(const sStorageSize& var);
const sStorageSize& getDeviceSaveDataSize() const;
void setDeviceSaveDataSize(const sStorageSize& var);
int64_t getBcatDeliveryCacheStorageSize() const;
void setBcatDeliveryCacheStorageSize(int64_t var);
const std::string& getApplicationErrorCodeCategory() const;
void setApplicationErrorCodeCategory(const std::string& var);
const fnd::List<uint64_t>& getLocalCommunicationId() const;
void setLocalCommunicationId(const fnd::List<uint64_t>& var);
nacp::LogoType getLogoType() const;
void setLogoType(nacp::LogoType var);
nacp::LogoHandling getLogoHandling() const;
void setLogoHandling(nacp::LogoHandling var);
nacp::RuntimeAocInstallMode getRuntimeAocInstallMode() const;
void setRuntimeAocInstallMode(nacp::RuntimeAocInstallMode var);
nacp::CrashReportMode getCrashReportMode() const;
void setCrashReportMode(nacp::CrashReportMode var);
nacp::Hdcp getHdcp() const;
void setHdcp(nacp::Hdcp var);
uint64_t getSeedForPsuedoDeviceId() const;
void setSeedForPsuedoDeviceId(uint64_t var);
const std::string& getBcatPassphase() const;
void setBcatPassphase(const std::string& var);
const sStorageSize& getUserAccountSaveDataMax() const;
void setUserAccountSaveDataMax(const sStorageSize& var);
const sStorageSize& getDeviceSaveDataMax() const;
void setDeviceSaveDataMax(const sStorageSize& var);
int64_t getTemporaryStorageSize() const;
void setTemporaryStorageSize(int64_t var);
const sStorageSize& getCacheStorageSize() const;
void setCacheStorageSize(const sStorageSize& var);
int64_t getCacheStorageDataAndJournalSizeMax() const;
void setCacheStorageDataAndJournalSizeMax(int64_t var);
uint16_t getCacheStorageIndex() const;
void setCacheStorageIndex(uint16_t var);
const fnd::List<uint64_t>& getPlayLogQueryableApplicationId() const;
void setPlayLogQueryableApplicationId(const fnd::List<uint64_t>& var);
nacp::PlayLogQueryCapability getPlayLogQueryCapability() const;
void setPlayLogQueryCapability(nacp::PlayLogQueryCapability var);
nacp::RepairFlag getRepairFlag() const;
void setRepairFlag(nacp::RepairFlag var);
byte_t getProgramIndex() const;
void setProgramIndex(byte_t var);
private:
const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY";
// raw data
fnd::MemoryBlob mBinaryBlob;
// variables
fnd::List<sTitle> mTitle;
std::string mIsbn;
nacp::StartupUserAccount mStartupUserAccount;
nacp::TouchScreenUsageMode mTouchScreenUsageMode;
nacp::AocRegistrationType mAocRegistrationType;
nacp::AttributeFlag mAttributeFlag;
nacp::ParentalControlFlag mParentalControlFlag;
nacp::ScreenshotMode mScreenshotMode;
nacp::VideoCaptureMode mVideoCaptureMode;
nacp::DataLossConfirmation mDataLossConfirmation;
nacp::PlayLogPolicy mPlayLogPolicy;
uint64_t mPresenceGroupId;
fnd::List<sRating> mRatingAge;
std::string mDisplayVersion;
uint64_t mAocBaseId;
uint64_t mSaveDatawOwnerId;
sStorageSize mUserAccountSaveDataSize;
sStorageSize mDeviceSaveDataSize;
int64_t mBcatDeliveryCacheStorageSize;
std::string mApplicationErrorCodeCategory;
fnd::List<uint64_t> mLocalCommunicationId;
nacp::LogoType mLogoType;
nacp::LogoHandling mLogoHandling;
nacp::RuntimeAocInstallMode mRuntimeAocInstallMode;
nacp::CrashReportMode mCrashReportMode;
nacp::Hdcp mHdcp;
uint64_t mSeedForPsuedoDeviceId;
std::string mBcatPassphase;
sStorageSize mUserAccountSaveDataMax;
sStorageSize mDeviceSaveDataMax;
int64_t mTemporaryStorageSize;
sStorageSize mCacheStorageSize;
int64_t mCacheStorageDataAndJournalSizeMax;
uint16_t mCacheStorageIndex;
fnd::List<uint64_t> mPlayLogQueryableApplicationId;
nacp::PlayLogQueryCapability mPlayLogQueryCapability;
nacp::RepairFlag mRepairFlag;
byte_t mProgramIndex;
bool isEqual(const ApplicationControlPropertyBinary& other) const;
void copyFrom(const ApplicationControlPropertyBinary& other);
};
}

View file

@ -0,0 +1,12 @@
#pragma once
#include <nx/nacp.h>
namespace nx
{
class ApplicationControlPropertyUtils
{
public:
static bool validateSaveDataSizeMax(int64_t size, int64_t alignment);
static bool validateSaveDataSize(int64_t size);
};
}

222
lib/libnx/include/nx/nacp.h Normal file
View file

@ -0,0 +1,222 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <fnd/ISerialiseableBinary.h>
namespace nx
{
namespace nacp
{
enum AocRegistrationType
{
AOC_AllOnLaunch,
AOC_OnDemand
};
enum AttributeFlag
{
ATTR_None,
ATTR_Demo,
ATTR_RetailInteractiveDisplay
};
enum CrashReportMode
{
CREP_Deny,
CREP_Allow
};
enum DataLossConfirmation
{
DLOSS_None,
DLOSS_Required
};
enum Hdcp
{
HDCP_None,
HDCP_Required
};
enum Language
{
LANG_AmericanEnglish,
LANG_BritishEnglish,
LANG_Japanese,
LANG_French,
LANG_German,
LANG_LatinAmericanSpanish,
LANG_Spanish,
LANG_Italian,
LANG_Dutch,
LANG_CanadianFrench,
LANG_Portuguese,
LANG_Russian,
LANG_Korean,
LANG_TraditionalChinese,
LANG_SimplifiedChinese
};
enum LogoHandling
{
LHND_Auto,
LHND_None
};
enum LogoType
{
LOGO_LicensedByNintendo,
LOGO_DistributedByNintendo,
LOGO_Nintendo
};
enum Organisation
{
ORGN_CERO,
ORGN_GRACGCRB,
ORGN_GSRMR,
ORGN_ESRB,
ORGN_ClassInd,
ORGN_USK,
ORGN_PEGI,
ORGN_PEGIPortugal,
ORGN_PEGIBBFC,
ORGN_Russian,
ORGN_ACB,
ORGN_OFLC
};
enum ParentalControlFlag
{
PC_None,
PC_FreeCommunication
};
enum PlayLogPolicy
{
PLP_All,
PLP_LogOnly,
PLP_None
};
enum PlayLogQueryCapability
{
PLQC_None,
PLQC_Whitelist,
PLQC_All
};
enum RepairFlag
{
REPF_None,
REPF_SuppressGameCardAccess
};
enum RuntimeAocInstallMode
{
RTAOC_Deny,
RTAOC_AllowAppend
};
enum ScreenshotMode
{
SCRN_Allow,
SCRN_Deny
};
enum StartupUserAccount
{
USER_None,
USER_Required,
USER_RequiredWithNetworkServiceAccountAvailable
};
enum TouchScreenUsageMode
{
TOUCH_None,
TOUCH_Supported,
TOUCH_Required,
};
enum VideoCaptureMode
{
VCAP_Disable,
VCAP_Manual,
VCAP_Enable
};
static const size_t kNameLength = 0x200;
static const size_t kPublisherLength = 0x100;
static const size_t kMaxLanguageCount = 16;
static const size_t kIsbnLength = 37;
static const size_t kRatingAgeCount = 32;
static const size_t kDisplayVersionLength = 16;
static const size_t kApplicationErrorCodeCategoryLength = 8;
static const size_t kLocalCommunicationIdCount = 8;
static const size_t kBcatPassphraseLength = 65;
static const size_t kPlayLogQueryableApplicationIdCount = 16;
static const int8_t kUnusedAgeRating = -1;
}
#pragma pack(push,1)
struct sApplicationTitle
{
char name[nacp::kNameLength];
char publisher[nacp::kPublisherLength];
};
struct sApplicationControlProperty
{
sApplicationTitle title[nacp::kMaxLanguageCount];
char isbn[nacp::kIsbnLength];
byte_t startup_user_account;
byte_t touch_screen_usage;
byte_t add_on_content_registration_type;
le_uint32_t attribute_flag;
le_uint32_t supported_language_flag;
le_uint32_t parental_control_flag;
byte_t screenshot;
byte_t video_capture;
byte_t data_loss_confirmation;
byte_t play_log_policy;
le_uint64_t presence_group_id;
int8_t rating_age[nacp::kRatingAgeCount];
char display_version[nacp::kDisplayVersionLength];
le_uint64_t add_on_content_base_id;
le_uint64_t save_data_owner_id;
le_uint64_t user_account_save_data_size;
le_uint64_t user_account_save_data_journal_size;
le_uint64_t device_save_data_size;
le_uint64_t device_save_data_journal_size;
le_uint64_t bcat_delivery_cache_storage_size;
char application_error_code_category[nacp::kApplicationErrorCodeCategoryLength];
le_uint64_t local_communication_id[nacp::kLocalCommunicationIdCount];
byte_t logo_type;
byte_t logo_handling;
byte_t runtime_add_on_content_install;
byte_t reserved_00[3];
byte_t crash_report;
byte_t hdcp;
le_uint64_t seed_for_pseudo_device_id;
char bcat_passphrase[nacp::kBcatPassphraseLength];
byte_t reserved_01;
byte_t reserved_02[6]; //reserved_for_user_account_save_data_operation
le_uint64_t user_account_save_data_size_max;
le_uint64_t user_account_save_data_journal_size_max;
le_uint64_t device_save_data_size_max;
le_uint64_t device_save_data_journal_size_max;
le_uint64_t temporary_storage_size;
le_uint64_t cache_storage_size;
le_uint64_t cache_storage_journal_size;
le_uint64_t cache_storage_data_and_journal_size_max;
le_uint16_t cache_storage_index;
byte_t reserved_03[6];
le_uint64_t play_log_queryable_application_id[nacp::kPlayLogQueryableApplicationIdCount];
byte_t play_log_query_capability;
byte_t repair_flag;
byte_t program_index;
byte_t reserved_04[0xDED];
};
#pragma pack(pop)
}

View file

@ -24,6 +24,8 @@
<ClInclude Include="include\nx\AcidBinary.h" />
<ClInclude Include="include\nx\AciHeader.h" />
<ClInclude Include="include\nx\AesKeygen.h" />
<ClInclude Include="include\nx\ApplicationControlPropertyBinary.h" />
<ClInclude Include="include\nx\ApplicationControlPropertyUtils.h" />
<ClInclude Include="include\nx\cnmt.h" />
<ClInclude Include="include\nx\ContentMetaBinary.h" />
<ClInclude Include="include\nx\dynamic_symbol.h" />
@ -49,6 +51,7 @@
<ClInclude Include="include\nx\MiscFlagsHandler.h" />
<ClInclude Include="include\nx\MiscParamsEntry.h" />
<ClInclude Include="include\nx\MiscParamsHandler.h" />
<ClInclude Include="include\nx\nacp.h" />
<ClInclude Include="include\nx\nca.h" />
<ClInclude Include="include\nx\NcaUtils.h" />
<ClInclude Include="include\nx\npdm.h" />
@ -82,6 +85,8 @@
<ClCompile Include="source\AcidBinary.cpp" />
<ClCompile Include="source\AciHeader.cpp" />
<ClCompile Include="source\AesKeygen.cpp" />
<ClCompile Include="source\ApplicationControlPropertyBinary.cpp" />
<ClCompile Include="source\ApplicationControlPropertyUtils.cpp" />
<ClCompile Include="source\ContentMetaBinary.cpp" />
<ClCompile Include="source\FacBinary.cpp" />
<ClCompile Include="source\FacHeader.cpp" />

View file

@ -177,6 +177,15 @@
<ClInclude Include="include\nx\NroHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\ApplicationControlPropertyBinary.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\ApplicationControlPropertyUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\nx\nacp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
@ -296,5 +305,11 @@
<ClCompile Include="source\XciUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\ApplicationControlPropertyBinary.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\ApplicationControlPropertyUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -0,0 +1,713 @@
#include <nx/ApplicationControlPropertyBinary.h>
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary()
{
clear();
}
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other)
{
copyFrom(other);
}
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const byte_t* bytes, size_t len)
{
importBinary(bytes, len);
}
bool nx::ApplicationControlPropertyBinary::operator==(const ApplicationControlPropertyBinary& other) const
{
return isEqual(other);
}
bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const
{
return !(*this == other);
}
void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other)
{
copyFrom(other);
}
const byte_t* nx::ApplicationControlPropertyBinary::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t nx::ApplicationControlPropertyBinary::getSize() const
{
return mBinaryBlob.getSize();
}
void nx::ApplicationControlPropertyBinary::exportBinary()
{
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
sApplicationControlProperty* data = (sApplicationControlProperty*)mBinaryBlob.getBytes();
// strings
uint32_t supported_langs = 0;
for (size_t i = 0; i < mTitle.getSize(); i++)
{
supported_langs = _BIT(mTitle[i].language);
strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength);
strncpy(data->title[mTitle[i].language].publisher, mTitle[i].publisher.c_str(), nacp::kPublisherLength);
}
data->supported_language_flag = supported_langs;
strncpy(data->isbn, mIsbn.c_str(), nacp::kIsbnLength);
strncpy(data->display_version, mDisplayVersion.c_str(), nacp::kDisplayVersionLength);
strncpy(data->application_error_code_category, mApplicationErrorCodeCategory.c_str(), nacp::kApplicationErrorCodeCategoryLength);
strncpy(data->bcat_passphrase, mBcatPassphase.c_str(), nacp::kBcatPassphraseLength);
// enum type casts
data->startup_user_account = mStartupUserAccount;
data->touch_screen_usage = mTouchScreenUsageMode;
data->add_on_content_registration_type = mAocRegistrationType;
data->attribute_flag = mAttributeFlag;
data->parental_control_flag = mParentalControlFlag;
data->screenshot = mScreenshotMode;
data->video_capture = mVideoCaptureMode;
data->data_loss_confirmation = mDataLossConfirmation;
data->play_log_policy = mPlayLogPolicy;
data->logo_type = mLogoType;
data->logo_handling = mLogoHandling;
data->runtime_add_on_content_install = mRuntimeAocInstallMode;
data->crash_report = mCrashReportMode;
data->hdcp = mHdcp;
data->play_log_query_capability = mPlayLogQueryCapability;
data->repair_flag = mRepairFlag;
// misc params
data->presence_group_id = mPresenceGroupId;
memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings
for (size_t i = 0; i < mRatingAge.getSize(); i++)
{
data->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age;
}
data->add_on_content_base_id = mAocBaseId;
data->save_data_owner_id = mSaveDatawOwnerId;
for (size_t i = 0; i < mLocalCommunicationId.getSize() && i < nacp::kLocalCommunicationIdCount; i++)
{
data->local_communication_id[i] = mLocalCommunicationId[i];
}
data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId;
for (size_t i = 0; i < mPlayLogQueryableApplicationId.getSize() && i < nacp::kPlayLogQueryableApplicationIdCount; i++)
{
data->play_log_queryable_application_id[i] = mPlayLogQueryableApplicationId[i];
}
data->cache_storage_index = mCacheStorageIndex;
data->program_index = mProgramIndex;
// sizes
data->user_account_save_data_size = mUserAccountSaveDataSize.size;
data->user_account_save_data_journal_size = mUserAccountSaveDataSize.journal_size;
data->device_save_data_size = mDeviceSaveDataSize.size;
data->device_save_data_journal_size = mDeviceSaveDataSize.journal_size;
data->bcat_delivery_cache_storage_size = mBcatDeliveryCacheStorageSize;
data->user_account_save_data_size_max = mUserAccountSaveDataMax.size;
data->user_account_save_data_journal_size_max = mUserAccountSaveDataMax.journal_size;
data->device_save_data_size_max = mDeviceSaveDataMax.size;
data->device_save_data_journal_size_max = mDeviceSaveDataMax.journal_size;
data->temporary_storage_size = mTemporaryStorageSize;
data->cache_storage_size = mCacheStorageSize.size;
data->cache_storage_journal_size = mCacheStorageSize.journal_size;
data->cache_storage_data_and_journal_size_max = mCacheStorageDataAndJournalSizeMax;
}
void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, size_t len)
{
if (len < sizeof(nx::sApplicationControlProperty))
{
throw fnd::Exception(kModuleName, "NACP too small");
}
clear();
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mBinaryBlob.getBytes();
// strings
for (size_t i = 0; i < nacp::kMaxLanguageCount; i++)
{
if (_HAS_BIT(data->supported_language_flag.get(), i))
{
mTitle.addElement({(nacp::Language)i, std::string(data->title[i].name, nacp::kNameLength), std::string(data->title[i].publisher, nacp::kPublisherLength)});
}
}
if (data->isbn[0] != 0)
mIsbn = std::string(data->isbn, nacp::kIsbnLength);
if (data->display_version[0] != 0)
mDisplayVersion = std::string(data->display_version, nacp::kDisplayVersionLength);
if (data->application_error_code_category[0] != 0)
mApplicationErrorCodeCategory = std::string(data->application_error_code_category, nacp::kApplicationErrorCodeCategoryLength);
if (data->bcat_passphrase[0] != 0)
mBcatPassphase = std::string(data->bcat_passphrase, nacp::kBcatPassphraseLength);
// enum type casts
mStartupUserAccount = (nacp::StartupUserAccount)data->startup_user_account;
mTouchScreenUsageMode = (nacp::TouchScreenUsageMode)data->touch_screen_usage;
mAocRegistrationType = (nacp::AocRegistrationType)data->add_on_content_registration_type;
mAttributeFlag = (nacp::AttributeFlag)data->attribute_flag.get();
mParentalControlFlag = (nacp::ParentalControlFlag)data->parental_control_flag.get();
mScreenshotMode = (nacp::ScreenshotMode)data->screenshot;
mVideoCaptureMode = (nacp::VideoCaptureMode)data->video_capture;
mDataLossConfirmation = (nacp::DataLossConfirmation)data->data_loss_confirmation;
mPlayLogPolicy = (nacp::PlayLogPolicy)data->play_log_policy;
mLogoType = (nacp::LogoType)data->logo_type;
mLogoHandling = (nacp::LogoHandling)data->logo_handling;
mRuntimeAocInstallMode = (nacp::RuntimeAocInstallMode)data->runtime_add_on_content_install;
mCrashReportMode = (nacp::CrashReportMode)data->crash_report;
mHdcp = (nacp::Hdcp)data->hdcp;
mPlayLogQueryCapability = (nacp::PlayLogQueryCapability)data->play_log_query_capability;
mRepairFlag = (nacp::RepairFlag)data->repair_flag;
// misc params
mPresenceGroupId = data->presence_group_id.get();
for (size_t i = 0; i < nacp::kRatingAgeCount; i++)
{
if (data->rating_age[i] != nacp::kUnusedAgeRating)
mRatingAge.addElement({(nacp::Organisation)i, data->rating_age[i]});
}
mAocBaseId = data->add_on_content_base_id.get();
mSaveDatawOwnerId = data->save_data_owner_id.get();
for (size_t i = 0; i < nacp::kLocalCommunicationIdCount; i++)
{
if (data->local_communication_id[i].get() != 0)
mLocalCommunicationId.addElement(data->local_communication_id[i].get());
}
mSeedForPsuedoDeviceId = data->seed_for_pseudo_device_id.get();
for (size_t i = 0; i < nacp::kPlayLogQueryableApplicationIdCount; i++)
{
if (data->play_log_queryable_application_id[i].get() != 0)
mPlayLogQueryableApplicationId.addElement(data->play_log_queryable_application_id[i].get());
}
mCacheStorageIndex = data->cache_storage_index.get();
mProgramIndex = data->program_index;
// sizes
mUserAccountSaveDataSize.size = (int64_t)data->user_account_save_data_size.get();
mUserAccountSaveDataSize.journal_size = (int64_t)data->user_account_save_data_journal_size.get();
mDeviceSaveDataSize.size = (int64_t)data->device_save_data_size.get();
mDeviceSaveDataSize.journal_size = (int64_t)data->device_save_data_journal_size.get();
mBcatDeliveryCacheStorageSize = (int64_t)data->bcat_delivery_cache_storage_size.get();
mUserAccountSaveDataMax.size = (int64_t)data->user_account_save_data_size_max.get();
mUserAccountSaveDataMax.journal_size = (int64_t)data->user_account_save_data_journal_size_max.get();
mDeviceSaveDataMax.size = (int64_t)data->device_save_data_size_max.get();
mDeviceSaveDataMax.journal_size = (int64_t)data->device_save_data_journal_size_max.get();
mTemporaryStorageSize = (int64_t)data->temporary_storage_size.get();
mCacheStorageSize.size = (int64_t)data->cache_storage_size.get();
mCacheStorageSize.journal_size = (int64_t)data->cache_storage_journal_size.get();
mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get();
}
void nx::ApplicationControlPropertyBinary::clear()
{
mBinaryBlob.clear();
mTitle.clear();
mIsbn.clear();
mStartupUserAccount = nacp::USER_None;
mTouchScreenUsageMode = nacp::TOUCH_None;
mAocRegistrationType = nacp::AOC_AllOnLaunch;
mAttributeFlag = nacp::ATTR_None;
mParentalControlFlag = nacp::PC_None;
mScreenshotMode = nacp::SCRN_Allow;
mVideoCaptureMode = nacp::VCAP_Disable;
mDataLossConfirmation = nacp::DLOSS_None;
mPlayLogPolicy = nacp::PLP_All;
mPresenceGroupId = 0;
mRatingAge.clear();
mDisplayVersion.clear();
mAocBaseId = 0;
mSaveDatawOwnerId = 0;
mUserAccountSaveDataSize = {0, 0};
mDeviceSaveDataSize = {0, 0};
mBcatDeliveryCacheStorageSize = 0;
mApplicationErrorCodeCategory.clear();
mLocalCommunicationId.clear();
mLogoType = nacp::LOGO_Nintendo;
mLogoHandling = nacp::LHND_Auto;
mRuntimeAocInstallMode = nacp::RTAOC_Deny;
mCrashReportMode = nacp::CREP_Deny;
mHdcp = nacp::HDCP_None;
mSeedForPsuedoDeviceId = 0;
mBcatPassphase.clear();
mUserAccountSaveDataMax;
mDeviceSaveDataMax = {0, 0};
mTemporaryStorageSize = 0;
mCacheStorageSize = {0, 0};
mCacheStorageDataAndJournalSizeMax = 0;
mCacheStorageIndex = 0;
mPlayLogQueryableApplicationId.clear();
mPlayLogQueryCapability = nacp::PLQC_None;
mRepairFlag = nacp::REPF_None;
mProgramIndex = 0;
}
const fnd::List<nx::ApplicationControlPropertyBinary::sTitle>& nx::ApplicationControlPropertyBinary::getTitle() const
{
return mTitle;
}
void nx::ApplicationControlPropertyBinary::setTitle(const fnd::List<sTitle>& title)
{
mTitle = title;
}
const std::string& nx::ApplicationControlPropertyBinary::getIsbn() const
{
return mIsbn;
}
void nx::ApplicationControlPropertyBinary::setIsbn(const std::string& isbn)
{
mIsbn = isbn;
}
nx::nacp::StartupUserAccount nx::ApplicationControlPropertyBinary::getStartupUserAccount() const
{
return mStartupUserAccount;
}
void nx::ApplicationControlPropertyBinary::setStartupUserAccount(nacp::StartupUserAccount var)
{
mStartupUserAccount = var;
}
nx::nacp::TouchScreenUsageMode nx::ApplicationControlPropertyBinary::getTouchScreenUsageMode() const
{
return mTouchScreenUsageMode;
}
void nx::ApplicationControlPropertyBinary::setTouchScreenUsageMode(nacp::TouchScreenUsageMode var)
{
mTouchScreenUsageMode = var;
}
nx::nacp::AocRegistrationType nx::ApplicationControlPropertyBinary::getAocRegistrationType() const
{
return mAocRegistrationType;
}
void nx::ApplicationControlPropertyBinary::setAocRegistrationType(nacp::AocRegistrationType var)
{
mAocRegistrationType = var;
}
nx::nacp::AttributeFlag nx::ApplicationControlPropertyBinary::getAttributeFlag() const
{
return mAttributeFlag;
}
void nx::ApplicationControlPropertyBinary::setAttributeFlag(nacp::AttributeFlag var)
{
mAttributeFlag = var;
}
nx::nacp::ParentalControlFlag nx::ApplicationControlPropertyBinary::getParentalControlFlag() const
{
return mParentalControlFlag;
}
void nx::ApplicationControlPropertyBinary::setParentalControlFlag(nacp::ParentalControlFlag var)
{
mParentalControlFlag = var;
}
nx::nacp::ScreenshotMode nx::ApplicationControlPropertyBinary::getScreenshotMode() const
{
return mScreenshotMode;
}
void nx::ApplicationControlPropertyBinary::setScreenshotMode(nacp::ScreenshotMode var)
{
mScreenshotMode = var;
}
nx::nacp::VideoCaptureMode nx::ApplicationControlPropertyBinary::getVideoCaptureMode() const
{
return mVideoCaptureMode;
}
void nx::ApplicationControlPropertyBinary::setVideoCaptureMode(nacp::VideoCaptureMode var)
{
mVideoCaptureMode = var;
}
nx::nacp::DataLossConfirmation nx::ApplicationControlPropertyBinary::getDataLossConfirmation() const
{
return mDataLossConfirmation;
}
void nx::ApplicationControlPropertyBinary::setDataLossConfirmation(nacp::DataLossConfirmation var)
{
mDataLossConfirmation = var;
}
nx::nacp::PlayLogPolicy nx::ApplicationControlPropertyBinary::getPlayLogPolicy() const
{
return mPlayLogPolicy;
}
void nx::ApplicationControlPropertyBinary::setPlayLogPolicy(nacp::PlayLogPolicy var)
{
mPlayLogPolicy = var;
}
uint64_t nx::ApplicationControlPropertyBinary::getPresenceGroupId() const
{
return mPresenceGroupId;
}
void nx::ApplicationControlPropertyBinary::setPresenceGroupId(uint64_t var)
{
mPresenceGroupId = var;
}
const fnd::List<nx::ApplicationControlPropertyBinary::sRating>& nx::ApplicationControlPropertyBinary::getRatingAge() const
{
return mRatingAge;
}
void nx::ApplicationControlPropertyBinary::setRatingAge(const fnd::List<sRating>& var)
{
mRatingAge = var;
}
const std::string& nx::ApplicationControlPropertyBinary::getDisplayVersion() const
{
return mDisplayVersion;
}
void nx::ApplicationControlPropertyBinary::setDisplayVersion(const std::string& var)
{
mDisplayVersion = var;
}
uint64_t nx::ApplicationControlPropertyBinary::getAocBaseId() const
{
return mAocBaseId;
}
void nx::ApplicationControlPropertyBinary::setAocBaseId(uint64_t var)
{
mAocBaseId = var;
}
uint64_t nx::ApplicationControlPropertyBinary::getSaveDatawOwnerId() const
{
return mSaveDatawOwnerId;
}
void nx::ApplicationControlPropertyBinary::setSaveDatawOwnerId(uint64_t var)
{
mSaveDatawOwnerId = var;
}
const nx::ApplicationControlPropertyBinary::sStorageSize& nx::ApplicationControlPropertyBinary::getUserAccountSaveDataSize() const
{
return mUserAccountSaveDataSize;
}
void nx::ApplicationControlPropertyBinary::setUserAccountSaveDataSize(const sStorageSize& var)
{
mUserAccountSaveDataSize = var;
}
const nx::ApplicationControlPropertyBinary::sStorageSize& nx::ApplicationControlPropertyBinary::getDeviceSaveDataSize() const
{
return mDeviceSaveDataSize;
}
void nx::ApplicationControlPropertyBinary::setDeviceSaveDataSize(const sStorageSize& var)
{
mDeviceSaveDataSize = var;
}
int64_t nx::ApplicationControlPropertyBinary::getBcatDeliveryCacheStorageSize() const
{
return mBcatDeliveryCacheStorageSize;
}
void nx::ApplicationControlPropertyBinary::setBcatDeliveryCacheStorageSize(int64_t var)
{
mBcatDeliveryCacheStorageSize = var;
}
const std::string& nx::ApplicationControlPropertyBinary::getApplicationErrorCodeCategory() const
{
return mApplicationErrorCodeCategory;
}
void nx::ApplicationControlPropertyBinary::setApplicationErrorCodeCategory(const std::string& var)
{
mApplicationErrorCodeCategory = var;
}
const fnd::List<uint64_t>& nx::ApplicationControlPropertyBinary::getLocalCommunicationId() const
{
return mLocalCommunicationId;
}
void nx::ApplicationControlPropertyBinary::setLocalCommunicationId(const fnd::List<uint64_t>& var)
{
mLocalCommunicationId = var;
}
nx::nacp::LogoType nx::ApplicationControlPropertyBinary::getLogoType() const
{
return mLogoType;
}
void nx::ApplicationControlPropertyBinary::setLogoType(nacp::LogoType var)
{
mLogoType = var;
}
nx::nacp::LogoHandling nx::ApplicationControlPropertyBinary::getLogoHandling() const
{
return mLogoHandling;
}
void nx::ApplicationControlPropertyBinary::setLogoHandling(nacp::LogoHandling var)
{
mLogoHandling = var;
}
nx::nacp::RuntimeAocInstallMode nx::ApplicationControlPropertyBinary::getRuntimeAocInstallMode() const
{
return mRuntimeAocInstallMode;
}
void nx::ApplicationControlPropertyBinary::setRuntimeAocInstallMode(nacp::RuntimeAocInstallMode var)
{
mRuntimeAocInstallMode = var;
}
nx::nacp::CrashReportMode nx::ApplicationControlPropertyBinary::getCrashReportMode() const
{
return mCrashReportMode;
}
void nx::ApplicationControlPropertyBinary::setCrashReportMode(nacp::CrashReportMode var)
{
mCrashReportMode = var;
}
nx::nacp::Hdcp nx::ApplicationControlPropertyBinary::getHdcp() const
{
return mHdcp;
}
void nx::ApplicationControlPropertyBinary::setHdcp(nacp::Hdcp var)
{
mHdcp = var;
}
uint64_t nx::ApplicationControlPropertyBinary::getSeedForPsuedoDeviceId() const
{
return mSeedForPsuedoDeviceId;
}
void nx::ApplicationControlPropertyBinary::setSeedForPsuedoDeviceId(uint64_t var)
{
mSeedForPsuedoDeviceId = var;
}
const std::string& nx::ApplicationControlPropertyBinary::getBcatPassphase() const
{
return mBcatPassphase;
}
void nx::ApplicationControlPropertyBinary::setBcatPassphase(const std::string& var)
{
mBcatPassphase = var;
}
const nx::ApplicationControlPropertyBinary::sStorageSize& nx::ApplicationControlPropertyBinary::getUserAccountSaveDataMax() const
{
return mUserAccountSaveDataMax;
}
void nx::ApplicationControlPropertyBinary::setUserAccountSaveDataMax(const sStorageSize& var)
{
mUserAccountSaveDataMax = var;
}
const nx::ApplicationControlPropertyBinary::sStorageSize& nx::ApplicationControlPropertyBinary::getDeviceSaveDataMax() const
{
return mDeviceSaveDataMax;
}
void nx::ApplicationControlPropertyBinary::setDeviceSaveDataMax(const sStorageSize& var)
{
mDeviceSaveDataMax = var;
}
int64_t nx::ApplicationControlPropertyBinary::getTemporaryStorageSize() const
{
return mTemporaryStorageSize;
}
void nx::ApplicationControlPropertyBinary::setTemporaryStorageSize(int64_t var)
{
mTemporaryStorageSize = var;
}
const nx::ApplicationControlPropertyBinary::sStorageSize& nx::ApplicationControlPropertyBinary::getCacheStorageSize() const
{
return mCacheStorageSize;
}
void nx::ApplicationControlPropertyBinary::setCacheStorageSize(const sStorageSize& var)
{
mCacheStorageSize = var;
}
int64_t nx::ApplicationControlPropertyBinary::getCacheStorageDataAndJournalSizeMax() const
{
return mCacheStorageDataAndJournalSizeMax;
}
void nx::ApplicationControlPropertyBinary::setCacheStorageDataAndJournalSizeMax(int64_t var)
{
mCacheStorageDataAndJournalSizeMax = var;
}
uint16_t nx::ApplicationControlPropertyBinary::getCacheStorageIndex() const
{
return mCacheStorageIndex;
}
void nx::ApplicationControlPropertyBinary::setCacheStorageIndex(uint16_t var)
{
mCacheStorageIndex = var;
}
const fnd::List<uint64_t>& nx::ApplicationControlPropertyBinary::getPlayLogQueryableApplicationId() const
{
return mPlayLogQueryableApplicationId;
}
void nx::ApplicationControlPropertyBinary::setPlayLogQueryableApplicationId(const fnd::List<uint64_t>& var)
{
mPlayLogQueryableApplicationId = var;
}
nx::nacp::PlayLogQueryCapability nx::ApplicationControlPropertyBinary::getPlayLogQueryCapability() const
{
return mPlayLogQueryCapability;
}
void nx::ApplicationControlPropertyBinary::setPlayLogQueryCapability(nacp::PlayLogQueryCapability var)
{
mPlayLogQueryCapability = var;
}
nx::nacp::RepairFlag nx::ApplicationControlPropertyBinary::getRepairFlag() const
{
return mRepairFlag;
}
void nx::ApplicationControlPropertyBinary::setRepairFlag(nacp::RepairFlag var)
{
mRepairFlag = var;
}
byte_t nx::ApplicationControlPropertyBinary::getProgramIndex() const
{
return mProgramIndex;
}
void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var)
{
mProgramIndex = var;
}
bool nx::ApplicationControlPropertyBinary::isEqual(const ApplicationControlPropertyBinary& other) const
{
return (mTitle == other.mTitle) \
&& (mIsbn == other.mIsbn) \
&& (mStartupUserAccount == other.mStartupUserAccount) \
&& (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \
&& (mAocRegistrationType == other.mAocRegistrationType) \
&& (mAttributeFlag == other.mAttributeFlag) \
&& (mParentalControlFlag == other.mParentalControlFlag) \
&& (mScreenshotMode == other.mScreenshotMode) \
&& (mVideoCaptureMode == other.mVideoCaptureMode) \
&& (mDataLossConfirmation == other.mDataLossConfirmation) \
&& (mPlayLogPolicy == other.mPlayLogPolicy) \
&& (mPresenceGroupId == other.mPresenceGroupId) \
&& (mRatingAge == other.mRatingAge) \
&& (mDisplayVersion == other.mDisplayVersion) \
&& (mAocBaseId == other.mAocBaseId) \
&& (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \
&& (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \
&& (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \
&& (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \
&& (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \
&& (mLocalCommunicationId == other.mLocalCommunicationId) \
&& (mLogoType == other.mLogoType) \
&& (mLogoHandling == other.mLogoHandling) \
&& (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \
&& (mCrashReportMode == other.mCrashReportMode) \
&& (mHdcp == other.mHdcp) \
&& (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \
&& (mBcatPassphase == other.mBcatPassphase) \
&& (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \
&& (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \
&& (mTemporaryStorageSize == other.mTemporaryStorageSize) \
&& (mCacheStorageSize == other.mCacheStorageSize) \
&& (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \
&& (mCacheStorageIndex == other.mCacheStorageIndex) \
&& (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \
&& (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \
&& (mRepairFlag == other.mRepairFlag) \
&& (mProgramIndex == other.mProgramIndex);
}
void nx::ApplicationControlPropertyBinary::copyFrom(const ApplicationControlPropertyBinary& other)
{
clear();
mTitle = other.mTitle;
mIsbn = other.mIsbn;
mStartupUserAccount = other.mStartupUserAccount;
mTouchScreenUsageMode = other.mTouchScreenUsageMode;
mAocRegistrationType = other.mAocRegistrationType;
mAttributeFlag = other.mAttributeFlag;
mParentalControlFlag = other.mParentalControlFlag;
mScreenshotMode = other.mScreenshotMode;
mVideoCaptureMode = other.mVideoCaptureMode;
mDataLossConfirmation = other.mDataLossConfirmation;
mPlayLogPolicy = other.mPlayLogPolicy;
mPresenceGroupId = other.mPresenceGroupId;
mRatingAge = other.mRatingAge;
mDisplayVersion = other.mDisplayVersion;
mAocBaseId = other.mAocBaseId;
mSaveDatawOwnerId = other.mSaveDatawOwnerId;
mUserAccountSaveDataSize = other.mUserAccountSaveDataSize;
mDeviceSaveDataSize = other.mDeviceSaveDataSize;
mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize;
mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory;
mLocalCommunicationId = other.mLocalCommunicationId;
mLogoType = other.mLogoType;
mLogoHandling = other.mLogoHandling;
mRuntimeAocInstallMode = other.mRuntimeAocInstallMode;
mCrashReportMode = other.mCrashReportMode;
mHdcp = other.mHdcp;
mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId;
mBcatPassphase = other.mBcatPassphase;
mUserAccountSaveDataMax = other.mUserAccountSaveDataMax;
mDeviceSaveDataMax = other.mDeviceSaveDataMax;
mTemporaryStorageSize = other.mTemporaryStorageSize;
mCacheStorageSize = other.mCacheStorageSize;
mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax;
mCacheStorageIndex = other.mCacheStorageIndex;
mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId;
mPlayLogQueryCapability = other.mPlayLogQueryCapability;
mRepairFlag = other.mRepairFlag;
mProgramIndex = other.mProgramIndex;
}

View file

@ -0,0 +1,11 @@
#include <nx/ApplicationControlPropertyUtils.h>
bool nx::ApplicationControlPropertyUtils::validateSaveDataSizeMax(int64_t size, int64_t alignment)
{
return (alignment != 0 && (size & (alignment - 1)) != 0) == false;
}
bool nx::ApplicationControlPropertyUtils::validateSaveDataSize(int64_t size)
{
return (size & 0x3fff) == 0;
}

View file

@ -174,6 +174,7 @@
<ClInclude Include="source\DynamicSymbolParser.h" />
<ClInclude Include="source\HashTreeMeta.h" />
<ClInclude Include="source\HashTreeWrappedIFile.h" />
<ClInclude Include="source\NacpProcess.h" />
<ClInclude Include="source\NcaProcess.h" />
<ClInclude Include="source\NpdmProcess.h" />
<ClInclude Include="source\NroProcess.h" />
@ -195,6 +196,7 @@
<ClCompile Include="source\HashTreeMeta.cpp" />
<ClCompile Include="source\HashTreeWrappedIFile.cpp" />
<ClCompile Include="source\main.cpp" />
<ClCompile Include="source\NacpProcess.cpp" />
<ClCompile Include="source\NcaProcess.cpp" />
<ClCompile Include="source\NpdmProcess.cpp" />
<ClCompile Include="source\NroProcess.cpp" />

View file

@ -69,6 +69,9 @@
<ClInclude Include="source\SdkApiString.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\NacpProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\main.cpp">
@ -122,6 +125,9 @@
<ClCompile Include="source\SdkApiString.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\NacpProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />

View file

@ -100,18 +100,27 @@ void AssetProcess::processSections()
outfile.close();
}
if (mHdr.getNacpInfo().size > 0 && mNacpExtractPath.isSet)
if (mHdr.getNacpInfo().size > 0)
{
if ((mHdr.getNacpInfo().size + mHdr.getNacpInfo().offset) > mFile->size())
throw fnd::Exception(kModuleName, "ASET geometry for nacp beyond file size");
fnd::SimpleFile outfile(mNacpExtractPath.var, fnd::SimpleFile::Create);
fnd::MemoryBlob cache;
if (mNacpExtractPath.isSet)
{
fnd::SimpleFile outfile(mNacpExtractPath.var, fnd::SimpleFile::Create);
fnd::MemoryBlob cache;
cache.alloc(mHdr.getNacpInfo().size);
mFile->read(cache.getBytes(), mHdr.getNacpInfo().offset, cache.getSize());
outfile.write(cache.getBytes(), cache.getSize());
outfile.close();
cache.alloc(mHdr.getNacpInfo().size);
mFile->read(cache.getBytes(), mHdr.getNacpInfo().offset, cache.getSize());
outfile.write(cache.getBytes(), cache.getSize());
outfile.close();
}
mNacp.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size), true);
mNacp.setCliOutputMode(mCliOutputType);
mNacp.setVerifyMode(mVerify);
mNacp.process();
}
if (mHdr.getRomfsInfo().size > 0)

View file

@ -3,6 +3,7 @@
#include <fnd/types.h>
#include <fnd/IFile.h>
#include <nx/AssetHeader.h>
#include "NacpProcess.h"
#include "RomfsProcess.h"
#include "nstool.h"
@ -38,6 +39,7 @@ private:
sOptional<std::string> mNacpExtractPath;
nx::AssetHeader mHdr;
NacpProcess mNacp;
RomfsProcess mRomfs;
void importHeader();

View file

@ -0,0 +1,599 @@
#include <sstream>
#include <fnd/SimpleTextOutput.h>
#include "OffsetAdjustedIFile.h"
#include "NacpProcess.h"
const char* getLanguageStr(nx::nacp::Language var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::LANG_AmericanEnglish):
str = "AmericanEnglish";
break;
case (nx::nacp::LANG_BritishEnglish):
str = "BritishEnglish";
break;
case (nx::nacp::LANG_Japanese):
str = "Japanese";
break;
case (nx::nacp::LANG_French):
str = "French";
break;
case (nx::nacp::LANG_German):
str = "German";
break;
case (nx::nacp::LANG_LatinAmericanSpanish):
str = "LatinAmericanSpanish";
break;
case (nx::nacp::LANG_Spanish):
str = "Spanish";
break;
case (nx::nacp::LANG_Italian):
str = "Italian";
break;
case (nx::nacp::LANG_Dutch):
str = "Dutch";
break;
case (nx::nacp::LANG_CanadianFrench):
str = "CanadianFrench";
break;
case (nx::nacp::LANG_Portuguese):
str = "Portuguese";
break;
case (nx::nacp::LANG_Russian):
str = "Russian";
break;
case (nx::nacp::LANG_Korean):
str = "Korean";
break;
case (nx::nacp::LANG_TraditionalChinese):
str = "TraditionalChinese";
break;
case (nx::nacp::LANG_SimplifiedChinese):
str = "SimplifiedChinese";
break;
default:
str = "Unknown";
}
return str;
}
const char* getStartupUserAccountStr(nx::nacp::StartupUserAccount var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::USER_None):
str = "None";
break;
case (nx::nacp::USER_Required):
str = "Required";
break;
case (nx::nacp::USER_RequiredWithNetworkServiceAccountAvailable):
str = "RequiredWithNetworkServiceAccountAvailable";
break;
default:
str = "Unknown";
}
return str;
}
const char* getTouchScreenUsageModeStr(nx::nacp::TouchScreenUsageMode var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::TOUCH_None):
str = "None";
break;
case (nx::nacp::TOUCH_Supported):
str = "Supported";
break;
case (nx::nacp::TOUCH_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* getAocRegistrationTypeStr(nx::nacp::AocRegistrationType var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::AOC_AllOnLaunch):
str = "AllOnLaunch";
break;
case (nx::nacp::AOC_OnDemand):
str = "OnDemand";
break;
default:
str = "Unknown";
}
return str;
}
const char* getAttributeFlagStr(nx::nacp::AttributeFlag var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::ATTR_None):
str = "None";
break;
case (nx::nacp::ATTR_Demo):
str = "Demo";
break;
case (nx::nacp::ATTR_RetailInteractiveDisplay):
str = "RetailInteractiveDisplay";
break;
default:
str = "Unknown";
}
return str;
}
const char* getParentalControlFlagStr(nx::nacp::ParentalControlFlag var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::PC_None):
str = "None";
break;
case (nx::nacp::PC_FreeCommunication):
str = "FreeCommunication";
break;
default:
str = "Unknown";
}
return str;
}
const char* getScreenshotModeStr(nx::nacp::ScreenshotMode var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::SCRN_Allow):
str = "Allow";
break;
case (nx::nacp::SCRN_Deny):
str = "Deny";
break;
default:
str = "Unknown";
}
return str;
}
const char* getVideoCaptureModeStr(nx::nacp::VideoCaptureMode var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::VCAP_Disable):
str = "Disable";
break;
case (nx::nacp::VCAP_Manual):
str = "Manual";
break;
case (nx::nacp::VCAP_Enable):
str = "Enable";
break;
default:
str = "Unknown";
}
return str;
}
const char* getDataLossConfirmationStr(nx::nacp::DataLossConfirmation var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::DLOSS_None):
str = "None";
break;
case (nx::nacp::DLOSS_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* getPlayLogPolicyStr(nx::nacp::PlayLogPolicy var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::PLP_All):
str = "All";
break;
case (nx::nacp::PLP_LogOnly):
str = "LogOnly";
break;
case (nx::nacp::PLP_None):
str = "None";
break;
default:
str = "Unknown";
}
return str;
}
const char* getOrganisationStr(nx::nacp::Organisation var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::ORGN_CERO):
str = "CERO";
break;
case (nx::nacp::ORGN_GRACGCRB):
str = "GRACGCRB";
break;
case (nx::nacp::ORGN_GSRMR):
str = "GSRMR";
break;
case (nx::nacp::ORGN_ESRB):
str = "ESRB";
break;
case (nx::nacp::ORGN_ClassInd):
str = "ClassInd";
break;
case (nx::nacp::ORGN_USK):
str = "USK";
break;
case (nx::nacp::ORGN_PEGI):
str = "PEGI";
break;
case (nx::nacp::ORGN_PEGIPortugal):
str = "PEGIPortugal";
break;
case (nx::nacp::ORGN_PEGIBBFC):
str = "PEGIBBFC";
break;
case (nx::nacp::ORGN_Russian):
str = "Russian";
break;
case (nx::nacp::ORGN_ACB):
str = "ACB";
break;
case (nx::nacp::ORGN_OFLC):
str = "OFLC";
break;
default:
str = "Unknown";
}
return str;
}
const char* getLogoTypeStr(nx::nacp::LogoType var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::LOGO_LicensedByNintendo):
str = "LicensedByNintendo";
break;
case (nx::nacp::LOGO_DistributedByNintendo):
str = "DistributedByNintendo";
break;
case (nx::nacp::LOGO_Nintendo):
str = "Nintendo";
break;
default:
str = "Unknown";
}
return str;
}
const char* getLogoHandlingStr(nx::nacp::LogoHandling var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::LHND_Auto):
str = "Auto";
break;
case (nx::nacp::LHND_None):
str = "None";
break;
default:
str = "Unknown";
}
return str;
}
const char* getRuntimeAocInstallModeStr(nx::nacp::RuntimeAocInstallMode var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::RTAOC_Deny):
str = "Deny";
break;
case (nx::nacp::RTAOC_AllowAppend):
str = "AllowAppend";
break;
default:
str = "Unknown";
}
return str;
}
const char* getCrashReportModeStr(nx::nacp::CrashReportMode var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::CREP_Deny):
str = "Deny";
break;
case (nx::nacp::CREP_Allow):
str = "Allow";
break;
default:
str = "Unknown";
}
return str;
}
const char* getHdcpStr(nx::nacp::Hdcp var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::HDCP_None):
str = "None";
break;
case (nx::nacp::HDCP_Required):
str = "Required";
break;
default:
str = "Unknown";
}
return str;
}
const char* getPlayLogQueryCapabilityStr(nx::nacp::PlayLogQueryCapability var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::PLQC_None):
str = "None";
break;
case (nx::nacp::PLQC_Whitelist):
str = "Whitelist";
break;
case (nx::nacp::PLQC_All):
str = "All";
break;
default:
str = "Unknown";
}
return str;
}
const char* getRepairFlagStr(nx::nacp::RepairFlag var)
{
const char* str = nullptr;
switch(var)
{
case (nx::nacp::REPF_None):
str = "None";
break;
case (nx::nacp::REPF_SuppressGameCardAccess):
str = "SuppressGameCardAccess";
break;
default:
str = "Unknown";
}
return str;
}
std::string getSaveDataSizeStr(int64_t size)
{
static const int64_t kKiloByte = 1024;
static const int64_t kMegaByte = 1024 * 1024;
std::stringstream sstr;
if (size < kKiloByte)
{
sstr << size << " B";
}
else if (size < kMegaByte)
{
sstr << (size/kKiloByte) << " KB";
}
else
{
sstr << (size/kMegaByte) << " MB";
}
return sstr.str();
}
NacpProcess::NacpProcess() :
mFile(nullptr),
mOwnIFile(false),
mCliOutputType(OUTPUT_NORMAL),
mVerify(false)
{
}
NacpProcess::~NacpProcess()
{
if (mOwnIFile)
{
delete mFile;
}
}
void NacpProcess::process()
{
fnd::MemoryBlob scratch;
if (mFile == nullptr)
{
throw fnd::Exception(kModuleName, "No file reader set.");
}
scratch.alloc(mFile->size());
mFile->read(scratch.getBytes(), 0, scratch.getSize());
mNacp.importBinary(scratch.getBytes(), scratch.getSize());
if (mCliOutputType >= OUTPUT_NORMAL)
{
displayNacp();
}
}
void NacpProcess::setInputFile(fnd::IFile* file, bool ownIFile)
{
mFile = file;
mOwnIFile = ownIFile;
}
void NacpProcess::setCliOutputMode(CliOutputType type)
{
mCliOutputType = type;
}
void NacpProcess::setVerifyMode(bool verify)
{
mVerify = verify;
}
const nx::ApplicationControlPropertyBinary& NacpProcess::getApplicationControlPropertyBinary() const
{
return mNacp;
}
void NacpProcess::displayNacp()
{
printf("[ApplicationControlProperty]\n");
printf(" Menu Description:\n");
printf(" DisplayVersion: %s\n", mNacp.getDisplayVersion().c_str());
if (mNacp.getIsbn().empty() == false)
printf(" ISBN: %s\n", mNacp.getIsbn().c_str());
for (size_t i = 0; i < mNacp.getTitle().getSize(); i++)
{
printf(" %s Title:\n", getLanguageStr(mNacp.getTitle()[i].language));
printf(" Name: %s\n", mNacp.getTitle()[i].name.c_str());
printf(" Publisher: %s\n", mNacp.getTitle()[i].publisher.c_str());
}
printf(" Logo:\n");
printf(" Type: %s\n", getLogoTypeStr(mNacp.getLogoType()));
printf(" Handling: %s\n", getLogoHandlingStr(mNacp.getLogoHandling()));
printf(" AddOnContent:\n");
printf(" BaseId: 0x%016" PRIx64 "\n", mNacp.getAocBaseId());
printf(" RegistrationType: %s\n", getAocRegistrationTypeStr(mNacp.getAocRegistrationType()));
printf(" RuntimeInstallMode: %s\n", getRuntimeAocInstallModeStr(mNacp.getRuntimeAocInstallMode()));
printf(" Play Log:\n");
printf(" PlayLogPolicy: %s\n", getPlayLogPolicyStr(mNacp.getPlayLogPolicy()));
printf(" PlayLogQueryCapability: %s\n", getPlayLogQueryCapabilityStr(mNacp.getPlayLogQueryCapability()));
if (mNacp.getPlayLogQueryableApplicationId().getSize() > 0)
{
printf(" PlayLogQueryableApplicationId:\n");
for (size_t i = 0; i < mNacp.getPlayLogQueryableApplicationId().getSize(); i++)
{
printf(" 0x%016" PRIx64 "\n", mNacp.getPlayLogQueryableApplicationId()[i]);
}
}
printf(" Parental Controls:\n");
printf(" ParentalControlFlag: %s\n", getParentalControlFlagStr(mNacp.getParentalControlFlag()));
for (size_t i = 0; i < mNacp.getRatingAge().getSize(); i++)
{
printf(" Age Restriction:\n");
printf(" Agency: %s\n", getOrganisationStr(mNacp.getRatingAge()[i].organisation));
printf(" Age: %d\n", mNacp.getRatingAge()[i].age);
}
if (mNacp.getBcatPassphase().empty() == false)
{
printf(" BCAT:\n");
printf(" BcatPassphase: %s\n", mNacp.getBcatPassphase().c_str());
printf(" DeliveryCacheStorageSize: 0x%016" PRIx64 "\n", mNacp.getBcatDeliveryCacheStorageSize());
}
if (mNacp.getLocalCommunicationId().getSize() > 0)
{
printf(" Local Area Communication:\n");
printf(" LocalCommunicationId:\n");
for (size_t i = 0; i < mNacp.getLocalCommunicationId().getSize(); i++)
{
printf(" 0x%016" PRIx64 "\n", mNacp.getLocalCommunicationId()[i]);
}
}
printf(" SaveData:\n");
printf(" SaveDatawOwnerId: 0x%016" PRIx64 "\n", mNacp.getSaveDatawOwnerId());
if (mNacp.getUserAccountSaveDataSize().journal_size > 0)
{
printf(" UserAccountSaveData:\n");
printf(" Size: %s\n", getSaveDataSizeStr(mNacp.getUserAccountSaveDataSize().size).c_str());
printf(" JournalSize: %s\n", getSaveDataSizeStr(mNacp.getUserAccountSaveDataSize().journal_size).c_str());
}
if (mNacp.getDeviceSaveDataSize().journal_size > 0)
{
printf(" DeviceSaveData:\n");
printf(" Size: %s\n", getSaveDataSizeStr(mNacp.getDeviceSaveDataSize().size).c_str());
printf(" JournalSize: %s\n", getSaveDataSizeStr(mNacp.getDeviceSaveDataSize().journal_size).c_str());
}
if (mNacp.getUserAccountSaveDataMax().journal_size > 0)
{
printf(" UserAccountSaveDataMax:\n");
printf(" Size: %s\n", getSaveDataSizeStr(mNacp.getUserAccountSaveDataMax().size).c_str());
printf(" JournalSize: %s\n", getSaveDataSizeStr(mNacp.getUserAccountSaveDataMax().journal_size).c_str());
}
if (mNacp.getDeviceSaveDataMax().journal_size > 0)
{
printf(" DeviceSaveDataMax:\n");
printf(" Size: %s\n", getSaveDataSizeStr(mNacp.getDeviceSaveDataMax().size).c_str());
printf(" JournalSize: %s\n", getSaveDataSizeStr(mNacp.getDeviceSaveDataMax().journal_size).c_str());
}
if (mNacp.getTemporaryStorageSize() > 0)
{
printf(" TemporaryStorageSize: %s\n", getSaveDataSizeStr(mNacp.getTemporaryStorageSize()).c_str());
}
if (mNacp.getCacheStorageSize().journal_size > 0)
{
printf(" CacheStorage:\n");
printf(" Size: %s\n", getSaveDataSizeStr(mNacp.getCacheStorageSize().size).c_str());
printf(" JournalSize: %s\n", getSaveDataSizeStr(mNacp.getCacheStorageSize().journal_size).c_str());
printf(" MaxDataAndJournalSize: %s\n", getSaveDataSizeStr(mNacp.getCacheStorageDataAndJournalSizeMax()).c_str());
printf(" StorageIndex: 0x%" PRIx16 "\n", mNacp.getCacheStorageIndex());
}
printf(" Other Flags:\n");
printf(" StartupUserAccount: %s\n", getStartupUserAccountStr(mNacp.getStartupUserAccount()));
//printf(" TouchScreenUsageMode: %s\n", getTouchScreenUsageModeStr(mNacp.getTouchScreenUsageMode()));
printf(" AttributeFlag: %s\n", getAttributeFlagStr(mNacp.getAttributeFlag()));
printf(" CrashReportMode: %s\n", getCrashReportModeStr(mNacp.getCrashReportMode()));
printf(" HDCP: %s\n", getHdcpStr(mNacp.getHdcp()));
printf(" ScreenshotMode: %s\n", getScreenshotModeStr(mNacp.getScreenshotMode()));
printf(" VideoCaptureMode: %s\n", getVideoCaptureModeStr(mNacp.getVideoCaptureMode()));
printf(" DataLossConfirmation: %s\n", getDataLossConfirmationStr(mNacp.getDataLossConfirmation()));
printf(" RepairFlag: %s\n", getRepairFlagStr(mNacp.getRepairFlag()));
printf(" ProgramIndex: 0x%02x\n", mNacp.getProgramIndex());
if (mNacp.getApplicationErrorCodeCategory().empty() == false)
{
printf(" ApplicationErrorCodeCategory: %s\n", mNacp.getApplicationErrorCodeCategory().c_str());
}
if (mNacp.getSeedForPsuedoDeviceId() > 0 || mNacp.getPresenceGroupId() > 0)
{
printf(" Other Ids:\n");
if (mNacp.getSeedForPsuedoDeviceId() > 0)
printf(" SeedForPsuedoDeviceId: 0x%016" PRIx64 "\n", mNacp.getSeedForPsuedoDeviceId());
if (mNacp.getPresenceGroupId() > 0)
printf(" PresenceGroupId: 0x%016" PRIx64 "\n", mNacp.getPresenceGroupId());
}
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <fnd/IFile.h>
#include <nx/ApplicationControlPropertyBinary.h>
#include "nstool.h"
class NacpProcess
{
public:
NacpProcess();
~NacpProcess();
void process();
void setInputFile(fnd::IFile* file, bool ownIFile);
void setCliOutputMode(CliOutputType type);
void setVerifyMode(bool verify);
const nx::ApplicationControlPropertyBinary& getApplicationControlPropertyBinary() const;
private:
const std::string kModuleName = "NacpProcess";
fnd::IFile* mFile;
bool mOwnIFile;
CliOutputType mCliOutputType;
bool mVerify;
nx::ApplicationControlPropertyBinary mNacp;
void displayNacp();
};

View file

@ -41,7 +41,7 @@ void UserSettings::showHelp()
printf("\n General Options:\n");
printf(" -d, --dev Use devkit keyset\n");
printf(" -k, --keyset Specify keyset file\n");
printf(" -t, --type Specify input file type [xci, pfs, romfs, nca, npdm, cnmt, nso, nro, aset]\n");
printf(" -t, --type Specify input file type [xci, pfs, romfs, nca, npdm, cnmt, nso, nro, nacp, aset]\n");
printf(" -y, --verify Verify file\n");
printf(" -v, --verbose Verbose output\n");
printf(" -q, --quiet Minimal output\n");
@ -676,6 +676,8 @@ FileType UserSettings::getFileTypeFromString(const std::string& type_str)
type = FILE_NSO;
else if (str == "nro")
type = FILE_NRO;
else if (str == "nacp")
type = FILE_NACP;
else if (str == "aset" || str == "asset")
type = FILE_HB_ASSET;
else

View file

@ -9,6 +9,7 @@
#include "CnmtProcess.h"
#include "NsoProcess.h"
#include "NroProcess.h"
#include "NacpProcess.h"
#include "AssetProcess.h"
int main(int argc, char** argv)
@ -147,6 +148,16 @@ int main(int argc, char** argv)
obj.process();
}
else if (user_set.getFileType() == FILE_NACP)
{
NacpProcess nacp;
nacp.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE);
nacp.setCliOutputMode(user_set.getCliOutputType());
nacp.setVerifyMode(user_set.isVerifyFile());
nacp.process();
}
else if (user_set.getFileType() == FILE_HB_ASSET)
{
AssetProcess obj;

View file

@ -26,6 +26,7 @@ enum FileType
FILE_CNMT,
FILE_NSO,
FILE_NRO,
FILE_NACP,
FILE_HB_ASSET,
FILE_INVALID = -1,
};