mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 12:34:47 +00:00
ncm client: finished InstallTaskBase
This commit is contained in:
parent
f70fecfcff
commit
cce292e524
6 changed files with 116 additions and 28 deletions
|
@ -19,12 +19,26 @@
|
|||
namespace ams::fs {
|
||||
|
||||
union RightsId {
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
};
|
||||
static_assert(sizeof(RightsId) == 0x10);
|
||||
static_assert(std::is_pod<RightsId>::value);
|
||||
|
||||
inline bool operator==(const RightsId &lhs, const RightsId& rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const RightsId &lhs, const RightsId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const RightsId &lhs, const RightsId& rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) < 0;
|
||||
}
|
||||
|
||||
constexpr inline RightsId InvalidRightsId = {};
|
||||
|
||||
/* Rights ID API */
|
||||
Result GetRightsId(RightsId *out, const char *path);
|
||||
Result GetRightsId(RightsId *out, u8 *out_key_generation, const char *path);
|
||||
|
|
|
@ -340,13 +340,11 @@ namespace ams::ncm {
|
|||
void ConvertToContentMeta(void *dst, size_t size, const ContentInfo &meta);
|
||||
|
||||
Result CalculateConvertFragmentOnlyInstallContentMetaSize(size_t *out_size, u32 source_version) {
|
||||
/* TODO */
|
||||
return ResultSuccess();
|
||||
AMS_ABORT("Not implemented");
|
||||
};
|
||||
|
||||
Result ConvertToFragmentOnlyInstallContentMeta(void *dst, size_t size, const InstallContentInfo &content_info, u32 source_version) {
|
||||
/* TODO */
|
||||
return ResultSuccess();
|
||||
AMS_ABORT("Not implemented");
|
||||
}
|
||||
|
||||
size_t CountDeltaFragments() const;
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
namespace ams::ncm {
|
||||
|
||||
/* protected:
|
||||
PrepareContentMeta (both), WritePlaceHolderBuffer, Get/Delete InstallContentMetaData, PrepareDependency, PrepareSystemDependency, PrepareContentMetaIfLatest, GetConfig, WriteContentMetaToPlaceHolder, GetInstallStorage, GetSystemUpdateTaskApplyInfo, CanContinue
|
||||
*/
|
||||
enum class ListContentMetaKeyFilter : u8 {
|
||||
All = 0,
|
||||
Committed = 1,
|
||||
|
@ -91,18 +88,30 @@ PrepareContentMeta (both), WritePlaceHolderBuffer, Get/Delete InstallContentMeta
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Result PrepareImpl();
|
||||
Result CleanupOne(const InstallContentMeta &content_meta);
|
||||
Result ExecuteImpl();
|
||||
Result CommitImpl(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_temporary);
|
||||
Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key);
|
||||
Result ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset);
|
||||
protected:
|
||||
Result Initialize(StorageId install_storage, InstallTaskDataBase *data, u32 config);
|
||||
Result CountInstallContentMetaData(s32 *out_count);
|
||||
Result GetInstallContentMetaData(InstallContentMeta *out_content_meta, s32 index);
|
||||
|
||||
Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size);
|
||||
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary);
|
||||
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> key, std::optional<u32> source_version);
|
||||
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version);
|
||||
Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer);
|
||||
void PrepareAgain();
|
||||
Result PrepareSystemUpdateDependency();
|
||||
Result PrepareContentMetaIfLatest(const ContentMetaKey &key);
|
||||
Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out);
|
||||
Result DeleteInstallContentMetaData(const ContentMetaKey *keys, s32 num_keys);
|
||||
Result CanContinue();
|
||||
public:
|
||||
/* TODO: Fix access types. */
|
||||
bool IsCancelRequested();
|
||||
Result Prepare();
|
||||
void SetLastResult(Result last_result);
|
||||
|
@ -110,14 +119,12 @@ PrepareContentMeta (both), WritePlaceHolderBuffer, Get/Delete InstallContentMeta
|
|||
Result CalculateRequiredSize(size_t *out_size);
|
||||
void ResetThroughputMeasurement();
|
||||
void SetProgressState(InstallProgressState state);
|
||||
|
||||
void IncrementProgress(s64 size);
|
||||
void UpdateThroughputMeasurement(s64 throughput);
|
||||
bool IsNecessaryInstallTicket(const fs::RightsId &rights_id);
|
||||
void SetTotalSize(s64 size);
|
||||
Result PreparePlaceHolder();
|
||||
Result Cleanup();
|
||||
Result CleanupOne(const InstallContentMeta &content_meta);
|
||||
void CleanupProgress();
|
||||
Result ListContentMetaKey(s32 *out_keys_written, StorageContentMetaKey *out_keys, s32 out_keys_count, s32 offset, ListContentMetaKeyFilter filter);
|
||||
Result ListApplicationContentMetaKey(s32 *out_keys_written, ApplicationContentMetaKey *out_keys, s32 out_keys_count, s32 offset);
|
||||
|
@ -128,32 +135,19 @@ PrepareContentMeta (both), WritePlaceHolderBuffer, Get/Delete InstallContentMeta
|
|||
Result VerifyAllNotCommitted(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
Result Commit(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
Result IncludesExFatDriver(bool *out);
|
||||
Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size);
|
||||
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary);
|
||||
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_temporary);
|
||||
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> key, std::optional<u32> source_version);
|
||||
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version);
|
||||
Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer);
|
||||
Result PrepareSystemUpdateDependency();
|
||||
Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key);
|
||||
Result PrepareContentMetaIfLatest(const ContentMetaKey &key);
|
||||
Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out);
|
||||
Result IsNewerThanInstalled(bool *out, const ContentMetaKey &key);
|
||||
Result DeleteInstallContentMetaData(const ContentMetaKey *keys, s32 num_keys);
|
||||
void ResetLastResult();
|
||||
s64 GetThroughput();
|
||||
Result CalculateContentsSize(s64 *out_size, const ContentMetaKey &key, StorageId storage_id);
|
||||
Result FindMaxRequiredApplicationVersion(u32 *out);
|
||||
Result FindMaxRequiredSystemVersion(u32 *out);
|
||||
Result ListOccupiedSize(s32 *out_written, InstallTaskOccupiedSize *out_list, s32 out_list_size, s32 offset);
|
||||
|
||||
Result CanContinue();
|
||||
void SetFirmwareVariationId(FirmwareVariationId id);
|
||||
Result ListRightsIds(s32 *out_count, Span<RightsId> out_span, const ContentMetaKey &key, s32 offset);
|
||||
protected:
|
||||
virtual Result OnPrepareComplete();
|
||||
virtual Result PrepareDependency();
|
||||
public:
|
||||
/* TODO: Fix access types. */
|
||||
virtual void Cancel();
|
||||
virtual void ResetCancel();
|
||||
virtual InstallProgress GetProgress();
|
||||
|
|
|
@ -25,4 +25,6 @@ namespace ams::ncm {
|
|||
u8 reserved[7];
|
||||
};
|
||||
|
||||
static_assert(sizeof(InstallTaskOccupiedSize) == 0x20);
|
||||
|
||||
}
|
|
@ -27,4 +27,15 @@ namespace ams::ncm {
|
|||
static_assert(sizeof(RightsId) == 0x18);
|
||||
static_assert(std::is_pod<RightsId>::value);
|
||||
|
||||
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::tie(lhs.id, lhs.key_generation) == std::tie(rhs.id, rhs.key_generation);
|
||||
}
|
||||
|
||||
inline bool operator!=(const RightsId &lhs, const RightsId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::tie(lhs.id, lhs.key_generation) < std::tie(rhs.id, rhs.key_generation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1305,4 +1305,73 @@ namespace ams::ncm {
|
|||
void InstallTaskBase::SetFirmwareVariationId(FirmwareVariationId id) {
|
||||
this->firmware_variation_id = id;
|
||||
}
|
||||
|
||||
Result InstallTaskBase::ListRightsIds(s32 *out_count, Span<RightsId> out_span, const ContentMetaKey &key, s32 offset) {
|
||||
/* Count the number of content meta entries. */
|
||||
s32 count;
|
||||
R_TRY(this->data->Count(std::addressof(count)));
|
||||
|
||||
/* Ensure count is >= 1. */
|
||||
R_UNLESS(count >= 1, ncm::ResultContentMetaNotFound());
|
||||
|
||||
/* Iterate over content meta. */
|
||||
for (s32 i = 0; i < count; i++) {
|
||||
/* Obtain the content meta. */
|
||||
InstallContentMeta content_meta;
|
||||
R_TRY(this->data->Get(std::addressof(content_meta), i));
|
||||
|
||||
/* Create a reader. */
|
||||
const InstallContentMetaReader reader = content_meta.GetReader();
|
||||
|
||||
/* List rights ids if the reader's key matches ours. */
|
||||
if (reader.GetKey() == key) {
|
||||
return this->ListRightsIdsByInstallContentMeta(out_count, out_span, content_meta, offset);
|
||||
}
|
||||
}
|
||||
|
||||
return ncm::ResultContentMetaNotFound();
|
||||
}
|
||||
|
||||
Result InstallTaskBase::ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset) {
|
||||
/* If the offset is greater than zero, we can't create a unique span of rights ids. */
|
||||
/* Thus, we have nothing to list. */
|
||||
if (offset > 0) {
|
||||
*out_count = 0;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Create a reader. */
|
||||
const InstallContentMetaReader reader = content_meta.GetReader();
|
||||
|
||||
s32 count = 0;
|
||||
for (size_t i = 0; i < reader.GetContentCount(); i++) {
|
||||
const auto *content_info = reader.GetContentInfo(i);
|
||||
|
||||
/* Skip meta content infos and already installed content infos. Also skip if the content meta has already been comitted. */
|
||||
if (content_info->GetType() == ContentType::Meta || content_info->GetInstallState() == InstallState::Installed || reader.GetHeader()->committed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Open the relevant content storage. */
|
||||
ContentStorage content_storage;
|
||||
R_TRY(ncm::OpenContentStorage(&content_storage, content_info->storage_id));
|
||||
|
||||
/* Get the rights id. */
|
||||
RightsId rights_id;
|
||||
R_TRY(content_storage.GetRightsId(std::addressof(rights_id), content_info->GetPlaceHolderId()));
|
||||
|
||||
/* Skip empty rights ids. */
|
||||
if (rights_id.id == fs::InvalidRightsId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Output the rights id. */
|
||||
out_span[count++] = rights_id;
|
||||
}
|
||||
|
||||
/* Sort and remove duplicate ids from the output span. */
|
||||
std::sort(out_span.begin(), out_span.end());
|
||||
*out_count = std::distance(out_span.begin(), std::unique(out_span.begin(), out_span.end()));
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue