2020-04-04 05:40:46 +00:00
/*
2021-10-04 19:59:10 +00:00
* Copyright ( c ) Atmosphère - NX
2020-04-04 05:40:46 +00:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# pragma once
# include <stratosphere/ncm/ncm_install_task_data.hpp>
# include <stratosphere/ncm/ncm_install_task_occupied_size.hpp>
namespace ams : : ncm {
enum class ListContentMetaKeyFilter : u8 {
All = 0 ,
Committed = 1 ,
NotCommitted = 2 ,
} ;
enum InstallConfig {
InstallConfig_None = ( 0 < < 0 ) ,
InstallConfig_SystemUpdate = ( 1 < < 2 ) ,
InstallConfig_RequiresExFatDriver = ( 1 < < 3 ) ,
InstallConfig_IgnoreTicket = ( 1 < < 4 ) ,
} ;
struct InstallThroughput {
s64 installed ;
TimeSpan elapsed_time ;
} ;
struct InstallContentMetaInfo {
ContentId content_id ;
s64 content_size ;
ContentMetaKey key ;
bool verify_digest ;
bool has_key ;
Digest digest ;
static constexpr InstallContentMetaInfo MakeVerifiable ( const ContentId & cid , s64 sz , const ContentMetaKey & ky , const Digest & d ) {
return {
. content_id = cid ,
. content_size = sz ,
. key = ky ,
. verify_digest = true ,
. has_key = true ,
. digest = d ,
} ;
}
static constexpr InstallContentMetaInfo MakeUnverifiable ( const ContentId & cid , s64 sz , const ContentMetaKey & ky ) {
return {
. content_id = cid ,
. content_size = sz ,
. key = ky ,
. verify_digest = false ,
. has_key = true ,
} ;
}
static constexpr InstallContentMetaInfo MakeUnverifiable ( const ContentId & cid , s64 sz ) {
return {
. content_id = cid ,
. content_size = sz ,
. verify_digest = false ,
. has_key = false ,
} ;
}
} ;
static_assert ( sizeof ( InstallContentMetaInfo ) = = 0x50 ) ;
class InstallTaskBase {
NON_COPYABLE ( InstallTaskBase ) ;
NON_MOVEABLE ( InstallTaskBase ) ;
private :
2022-03-22 21:02:14 +00:00
crypto : : Sha256Generator m_sha256_generator { } ;
StorageId m_install_storage { } ;
InstallTaskDataBase * m_data { } ;
InstallProgress m_progress { } ;
os : : SdkMutex m_progress_mutex { } ;
u32 m_config { } ;
os : : SdkMutex m_cancel_mutex { } ;
bool m_cancel_requested { } ;
InstallThroughput m_throughput { } ;
TimeSpan m_throughput_start_time { } ;
os : : SdkMutex m_throughput_mutex { } ;
FirmwareVariationId m_firmware_variation_id { } ;
2020-04-04 05:40:46 +00:00
private :
ALWAYS_INLINE Result SetLastResultOnFailure ( Result result ) {
if ( R_FAILED ( result ) ) {
this - > SetLastResult ( result ) ;
}
2022-03-26 21:48:33 +00:00
R_RETURN ( result ) ;
2020-04-04 05:40:46 +00:00
}
public :
2021-10-10 07:14:06 +00:00
InstallTaskBase ( ) : m_data ( ) , m_progress ( ) , m_progress_mutex ( ) , m_cancel_mutex ( ) , m_cancel_requested ( ) , m_throughput_mutex ( ) { /* ... */ }
2020-04-04 05:40:46 +00:00
virtual ~ InstallTaskBase ( ) { /* ... */ } ;
public :
virtual void Cancel ( ) ;
virtual void ResetCancel ( ) ;
Result Prepare ( ) ;
Result GetPreparedPlaceHolderPath ( Path * out_path , u64 id , ContentMetaType meta_type , ContentType type ) ;
Result CalculateRequiredSize ( s64 * out_size ) ;
Result Cleanup ( ) ;
Result ListContentMetaKey ( s32 * out_keys_written , StorageContentMetaKey * out_keys , s32 out_keys_count , s32 offset , ListContentMetaKeyFilter filter ) ;
2022-03-26 21:48:33 +00:00
Result ListContentMetaKey ( s32 * out_keys_written , StorageContentMetaKey * out_keys , s32 out_keys_count , s32 offset ) { R_RETURN ( this - > ListContentMetaKey ( out_keys_written , out_keys , out_keys_count , offset , ListContentMetaKeyFilter : : All ) ) ; }
2020-04-04 05:40:46 +00:00
Result ListApplicationContentMetaKey ( s32 * out_keys_written , ApplicationContentMetaKey * out_keys , s32 out_keys_count , s32 offset ) ;
Result Execute ( ) ;
Result PrepareAndExecute ( ) ;
Result Commit ( const StorageContentMetaKey * keys , s32 num_keys ) ;
2022-03-26 21:48:33 +00:00
Result Commit ( ) { R_RETURN ( this - > Commit ( nullptr , 0 ) ) ; }
2020-04-04 05:40:46 +00:00
virtual InstallProgress GetProgress ( ) ;
void ResetLastResult ( ) ;
Result IncludesExFatDriver ( bool * out ) ;
InstallThroughput GetThroughput ( ) ;
Result CalculateContentsSize ( s64 * out_size , const ContentMetaKey & key , StorageId storage_id ) ;
Result ListOccupiedSize ( s32 * out_written , InstallTaskOccupiedSize * out_list , s32 out_list_size , s32 offset ) ;
Result FindMaxRequiredApplicationVersion ( u32 * out ) ;
Result FindMaxRequiredSystemVersion ( u32 * out ) ;
protected :
Result Initialize ( StorageId install_storage , InstallTaskDataBase * data , u32 config ) ;
2021-07-08 09:37:26 +00:00
Result PrepareContentMeta ( const InstallContentMetaInfo & meta_info , util : : optional < ContentMetaKey > key , util : : optional < u32 > source_version ) ;
2020-04-04 05:40:46 +00:00
Result PrepareContentMeta ( ContentId content_id , s64 size , ContentMetaType meta_type , AutoBuffer * buffer ) ;
Result WritePlaceHolderBuffer ( InstallContentInfo * content_info , const void * data , size_t data_size ) ;
void PrepareAgain ( ) ;
Result CountInstallContentMetaData ( s32 * out_count ) ;
Result GetInstallContentMetaData ( InstallContentMeta * out_content_meta , s32 index ) ;
Result DeleteInstallContentMetaData ( const ContentMetaKey * keys , s32 num_keys ) ;
2020-05-18 15:03:38 +00:00
virtual Result GetInstallContentMetaInfo ( InstallContentMetaInfo * out_info , const ContentMetaKey & key ) = 0 ;
2020-04-04 05:40:46 +00:00
virtual Result PrepareDependency ( ) ;
Result PrepareSystemUpdateDependency ( ) ;
2020-05-18 15:03:38 +00:00
virtual Result PrepareContentMetaIfLatest ( const ContentMetaKey & key ) ; /* NOTE: This is not virtual in Nintendo's code. We do so to facilitate downgrades. */
2021-10-10 07:14:06 +00:00
u32 GetConfig ( ) const { return m_config ; }
2021-07-08 09:37:26 +00:00
Result WriteContentMetaToPlaceHolder ( InstallContentInfo * out_install_content_info , ContentStorage * storage , const InstallContentMetaInfo & meta_info , util : : optional < bool > is_temporary ) ;
2020-04-04 05:40:46 +00:00
2021-10-10 07:14:06 +00:00
StorageId GetInstallStorage ( ) const { return m_install_storage ; }
2020-04-04 05:40:46 +00:00
2022-03-26 07:14:36 +00:00
virtual Result OnPrepareComplete ( ) { R_SUCCEED ( ) ; }
2020-04-04 05:40:46 +00:00
Result GetSystemUpdateTaskApplyInfo ( SystemUpdateTaskApplyInfo * out ) ;
Result CanContinue ( ) ;
private :
bool IsCancelRequested ( ) ;
Result PrepareImpl ( ) ;
Result ExecuteImpl ( ) ;
Result CommitImpl ( const StorageContentMetaKey * keys , s32 num_keys ) ;
Result CleanupOne ( const InstallContentMeta & content_meta ) ;
Result VerifyAllNotCommitted ( const StorageContentMetaKey * keys , s32 num_keys ) ;
virtual Result PrepareInstallContentMetaData ( ) = 0 ;
2022-03-26 07:14:36 +00:00
virtual Result GetLatestVersion ( util : : optional < u32 > * out_version , u64 id ) { AMS_UNUSED ( out_version , id ) ; R_THROW ( ncm : : ResultContentMetaNotFound ( ) ) ; }
2020-04-04 05:40:46 +00:00
2022-03-26 07:14:36 +00:00
virtual Result OnExecuteComplete ( ) { R_SUCCEED ( ) ; }
2020-04-04 05:40:46 +00:00
Result WritePlaceHolder ( const ContentMetaKey & key , InstallContentInfo * content_info ) ;
virtual Result OnWritePlaceHolder ( const ContentMetaKey & key , InstallContentInfo * content_info ) = 0 ;
bool IsNecessaryInstallTicket ( const fs : : RightsId & rights_id ) ;
virtual Result InstallTicket ( const fs : : RightsId & rights_id , ContentMetaType meta_type ) = 0 ;
Result IsNewerThanInstalled ( bool * out , const ContentMetaKey & key ) ;
Result PreparePlaceHolder ( ) ;
void SetProgressState ( InstallProgressState state ) ;
void IncrementProgress ( s64 size ) ;
void SetTotalSize ( s64 size ) ;
void SetLastResult ( Result last_result ) ;
void CleanupProgress ( ) ;
void ResetThroughputMeasurement ( ) ;
void StartThroughputMeasurement ( ) ;
void UpdateThroughputMeasurement ( s64 throughput ) ;
2021-07-08 09:37:26 +00:00
Result GetInstallContentMetaDataFromPath ( AutoBuffer * out , const Path & path , const InstallContentInfo & content_info , util : : optional < u32 > source_version ) ;
2020-04-04 05:40:46 +00:00
2021-07-08 09:37:26 +00:00
InstallContentInfo MakeInstallContentInfoFrom ( const InstallContentMetaInfo & info , const PlaceHolderId & placeholder_id , util : : optional < bool > is_temporary ) ;
2020-04-04 05:40:46 +00:00
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 ) ;
public :
2022-03-26 07:14:36 +00:00
virtual Result CheckInstallable ( ) { R_SUCCEED ( ) ; }
2020-04-04 05:40:46 +00:00
2021-10-10 07:14:06 +00:00
void SetFirmwareVariationId ( FirmwareVariationId id ) { m_firmware_variation_id = id ; }
2020-04-04 05:40:46 +00:00
Result ListRightsIds ( s32 * out_count , Span < RightsId > out_span , const ContentMetaKey & key , s32 offset ) ;
} ;
}