mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-17 17:36:44 +00:00
Daybreak: support installing non-exfat update if only exfat firm is missing/corrupt
This commit is contained in:
parent
65b42497d7
commit
3d2eb8e903
4 changed files with 51 additions and 24 deletions
|
@ -25,6 +25,10 @@ namespace ams::mitm::sysupdater {
|
||||||
/* ExFat NCAs prior to 2.0.0 do not actually include the exfat driver, and don't boot. */
|
/* ExFat NCAs prior to 2.0.0 do not actually include the exfat driver, and don't boot. */
|
||||||
constexpr inline u32 MinimumVersionForExFatDriver = 65536;
|
constexpr inline u32 MinimumVersionForExFatDriver = 65536;
|
||||||
|
|
||||||
|
bool IsExFatDriverSupported(const ncm::ContentMetaInfo &info) {
|
||||||
|
return info.version >= MinimumVersionForExFatDriver && ((info.attributes & ncm::ContentMetaAttribute_IncludesExFatDriver) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Result ForEachFileInDirectory(const char *root_path, F f) {
|
Result ForEachFileInDirectory(const char *root_path, F f) {
|
||||||
/* Open the directory. */
|
/* Open the directory. */
|
||||||
|
@ -123,9 +127,10 @@ namespace ams::mitm::sysupdater {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ValidateSystemUpdate(Result *out_result, UpdateValidationInfo *out_info, const ncm::PackagedContentMetaReader &update_reader, const char *package_root) {
|
Result ValidateSystemUpdate(Result *out_result, Result *out_exfat_result, UpdateValidationInfo *out_info, const ncm::PackagedContentMetaReader &update_reader, const char *package_root) {
|
||||||
/* Clear output. */
|
/* Clear output. */
|
||||||
*out_result = ResultSuccess();
|
*out_result = ResultSuccess();
|
||||||
|
*out_exfat_result = ResultSuccess();
|
||||||
|
|
||||||
/* We want to track all content the update requires. */
|
/* We want to track all content the update requires. */
|
||||||
const size_t num_content_metas = update_reader.GetContentMetaCount();
|
const size_t num_content_metas = update_reader.GetContentMetaCount();
|
||||||
|
@ -264,22 +269,24 @@ namespace ams::mitm::sysupdater {
|
||||||
if (R_SUCCEEDED(*out_result)) {
|
if (R_SUCCEEDED(*out_result)) {
|
||||||
for (size_t i = 0; i < num_content_metas; ++i) {
|
for (size_t i = 0; i < num_content_metas; ++i) {
|
||||||
if (!content_meta_valid[i]) {
|
if (!content_meta_valid[i]) {
|
||||||
|
const ncm::ContentMetaInfo *info = update_reader.GetContentMetaInfo(i);
|
||||||
|
|
||||||
|
*out_info = { .invalid_key = info->ToKey(), };
|
||||||
|
|
||||||
|
if (IsExFatDriverSupported(*info)) {
|
||||||
|
*out_exfat_result = fs::ResultPathNotFound();
|
||||||
|
/* Continue, in case there's a non-exFAT failure result. */
|
||||||
|
} else {
|
||||||
*out_result = fs::ResultPathNotFound();
|
*out_result = fs::ResultPathNotFound();
|
||||||
*out_info = {
|
|
||||||
.invalid_key = update_reader.GetContentMetaInfo(i)->ToKey(),
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsExFatDriverSupported(const ncm::ContentMetaInfo &info) {
|
|
||||||
return info.version >= MinimumVersionForExFatDriver && ((info.attributes & ncm::ContentMetaAttribute_IncludesExFatDriver) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result FormatUserPackagePath(ncm::Path *out, const ncm::Path &user_path) {
|
Result FormatUserPackagePath(ncm::Path *out, const ncm::Path &user_path) {
|
||||||
/* Ensure that the user path is valid. */
|
/* Ensure that the user path is valid. */
|
||||||
R_UNLESS(user_path.str[0] == '/', fs::ResultInvalidPath());
|
R_UNLESS(user_path.str[0] == '/', fs::ResultInvalidPath());
|
||||||
|
@ -378,7 +385,7 @@ namespace ams::mitm::sysupdater {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SystemUpdateService::ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path) {
|
Result SystemUpdateService::ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<Result> out_validate_exfat_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path) {
|
||||||
/* Adjust the path. */
|
/* Adjust the path. */
|
||||||
ncm::Path package_root;
|
ncm::Path package_root;
|
||||||
R_TRY(FormatUserPackagePath(std::addressof(package_root), path));
|
R_TRY(FormatUserPackagePath(std::addressof(package_root), path));
|
||||||
|
@ -397,7 +404,7 @@ namespace ams::mitm::sysupdater {
|
||||||
const auto reader = ncm::PackagedContentMetaReader(content_meta_buffer.Get(), content_meta_buffer.GetSize());
|
const auto reader = ncm::PackagedContentMetaReader(content_meta_buffer.Get(), content_meta_buffer.GetSize());
|
||||||
|
|
||||||
/* Validate the update. */
|
/* Validate the update. */
|
||||||
R_TRY(ValidateSystemUpdate(out_validate_result.GetPointer(), out_validate_info.GetPointer(), reader, package_root.str));
|
R_TRY(ValidateSystemUpdate(out_validate_result.GetPointer(), out_validate_exfat_result.GetPointer(), out_validate_info.GetPointer(), reader, package_root.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace ams::mitm::sysupdater {
|
||||||
|
|
||||||
#define AMS_SYSUPDATER_SYSTEM_UPDATE_INTERFACE_INFO(C, H) \
|
#define AMS_SYSUPDATER_SYSTEM_UPDATE_INTERFACE_INFO(C, H) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GetUpdateInformation, (sf::Out<UpdateInformation> out, const ncm::Path &path)) \
|
AMS_SF_METHOD_INFO(C, H, 0, Result, GetUpdateInformation, (sf::Out<UpdateInformation> out, const ncm::Path &path)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, ValidateUpdate, (sf::Out<Result> out_validate_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path)) \
|
AMS_SF_METHOD_INFO(C, H, 1, Result, ValidateUpdate, (sf::Out<Result> out_validate_result, sf::Out<Result> out_validate_exfat_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetupUpdate, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat)) \
|
AMS_SF_METHOD_INFO(C, H, 2, Result, SetupUpdate, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, Result, SetupUpdateWithVariation, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id)) \
|
AMS_SF_METHOD_INFO(C, H, 3, Result, SetupUpdateWithVariation, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 4, Result, RequestPrepareUpdate, (sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async)) \
|
AMS_SF_METHOD_INFO(C, H, 4, Result, RequestPrepareUpdate, (sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async)) \
|
||||||
|
@ -70,7 +70,7 @@ namespace ams::mitm::sysupdater {
|
||||||
Result InitializeUpdateTask(os::ManagedHandle &transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
Result InitializeUpdateTask(os::ManagedHandle &transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||||
public:
|
public:
|
||||||
Result GetUpdateInformation(sf::Out<UpdateInformation> out, const ncm::Path &path);
|
Result GetUpdateInformation(sf::Out<UpdateInformation> out, const ncm::Path &path);
|
||||||
Result ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path);
|
Result ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<Result> out_validate_exfat_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path);
|
||||||
Result SetupUpdate(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat);
|
Result SetupUpdate(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat);
|
||||||
Result SetupUpdateWithVariation(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
Result SetupUpdateWithVariation(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||||
Result RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async);
|
Result RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async);
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Result result;
|
Result result;
|
||||||
|
Result exfat_result;
|
||||||
NcmContentMetaKey invalid_key;
|
NcmContentMetaKey invalid_key;
|
||||||
NcmContentId invalid_content_id;
|
NcmContentId invalid_content_id;
|
||||||
} AmsSuUpdateValidationInfo;
|
} AmsSuUpdateValidationInfo;
|
||||||
|
|
|
@ -814,6 +814,19 @@ namespace dbk {
|
||||||
if (R_SUCCEEDED(m_validation_info.result)) {
|
if (R_SUCCEEDED(m_validation_info.result)) {
|
||||||
this->LogText("Update is valid!\n");
|
this->LogText("Update is valid!\n");
|
||||||
|
|
||||||
|
if (R_FAILED(m_validation_info.exfat_result)) {
|
||||||
|
const u32 version = m_validation_info.invalid_key.version;
|
||||||
|
this->LogText("exFAT Validation failed with result: 0x%08x\n", m_validation_info.exfat_result);
|
||||||
|
this->LogText("Missing content:\n- Program id: %016lx\n- Version: %d.%d.%d\n", m_validation_info.invalid_key.id, (version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf);
|
||||||
|
|
||||||
|
/* Log the missing content id. */
|
||||||
|
this->LogText("- Content id: ");
|
||||||
|
for (size_t i = 0; i < sizeof(NcmContentId); i++) {
|
||||||
|
this->LogText("%02x", m_validation_info.invalid_content_id.c[i]);
|
||||||
|
}
|
||||||
|
this->LogText("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable the back and continue buttons and select the continue button. */
|
/* Enable the back and continue buttons and select the continue button. */
|
||||||
this->SetButtonEnabled(BackButtonId, true);
|
this->SetButtonEnabled(BackButtonId, true);
|
||||||
this->SetButtonEnabled(ContinueButtonId, true);
|
this->SetButtonEnabled(ContinueButtonId, true);
|
||||||
|
@ -867,12 +880,18 @@ namespace dbk {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if exfat is supported. */
|
/* Check if exfat is supported. */
|
||||||
g_exfat_supported = m_update_info.exfat_supported;
|
g_exfat_supported = m_update_info.exfat_supported && R_SUCCEEDED(m_validation_info.exfat_result);
|
||||||
if (!g_exfat_supported) {
|
if (!g_exfat_supported) {
|
||||||
g_use_exfat = false;
|
g_use_exfat = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Warn the user if they're updating with exFAT supposed to be supported but not present/corrupted. */
|
||||||
|
if (m_update_info.exfat_supported && R_FAILED(m_validation_info.exfat_result)) {
|
||||||
|
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, std::make_shared<ChooseResetMenu>(g_current_menu), "Warning: exFAT firmware is missing or corrupt", "Are you sure you want to proceed?"));
|
||||||
|
} else {
|
||||||
ChangeMenu(std::make_shared<ChooseResetMenu>(g_current_menu));
|
ChangeMenu(std::make_shared<ChooseResetMenu>(g_current_menu));
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue