CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Core/Dialog/SavedataParam.h
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#pragma once1819#include <memory>20#include <mutex>21#include <set>22#include <unordered_map>23#include <cstdint>2425#include "Common/CommonTypes.h"26#include "Core/ELF/ParamSFO.h"27#include "Core/MemMap.h"28#include "Core/HLE/sceRtc.h"29#include "Core/Dialog/PSPDialog.h"3031#undef st_ctime32#undef st_atime33#undef st_mtime3435class PPGeImage;36struct PSPFileInfo;37typedef u32_le SceSize_le;3839enum SceUtilitySavedataType40{41SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD = 0,42SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE = 1,43SCE_UTILITY_SAVEDATA_TYPE_LOAD = 2,44SCE_UTILITY_SAVEDATA_TYPE_SAVE = 3,45SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD = 4,46SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE = 5,47SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6,48SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE = 7,// When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space)49SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8,50SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE = 9,51SCE_UTILITY_SAVEDATA_TYPE_DELETE = 10,52SCE_UTILITY_SAVEDATA_TYPE_LIST = 11,53SCE_UTILITY_SAVEDATA_TYPE_FILES = 12,54SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE = 13,55SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA = 14,56SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE = 15,57SCE_UTILITY_SAVEDATA_TYPE_READDATA = 16,58SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE = 17,59SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA = 18,60SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE = 19,61SCE_UTILITY_SAVEDATA_TYPE_ERASE = 20,62SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA = 21,63SCE_UTILITY_SAVEDATA_TYPE_GETSIZE = 22,64};6566static const char *const utilitySavedataTypeNames[] = {67"AUTOLOAD",68"AUTOSAVE",69"LOAD",70"SAVE",71"LISTLOAD",72"LISTSAVE",73"LISTDELETE",74"LISTALLDELETE",75"SIZES",76"AUTODELETE",77"DELETE",78"LIST",79"FILES",80"MAKEDATASECURE",81"MAKEDATA",82"READDATASECURE",83"READDATA",84"WRITEDATASECURE",85"WRITEDATA",86"ERASESECURE",87"ERASE",88"DELETEDATA",89"GETSIZE",90};9192enum SceUtilitySavedataFocus93{94SCE_UTILITY_SAVEDATA_FOCUS_NAME = 0, // specified by saveName[]95SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST = 1, // first listed (on screen or of all?)96SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST = 2, // last listed (on screen or of all?)97SCE_UTILITY_SAVEDATA_FOCUS_LATEST = 3, // latest by modification date (first if none)98SCE_UTILITY_SAVEDATA_FOCUS_OLDEST = 4, // oldest by modification date (first if none)99SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA = 5, // first non-empty (first if none)100SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA = 6, // last non-empty (first if none)101SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY = 7, // first empty (what if no empty?)102SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY = 8, // last empty (what if no empty?)103};104105#if COMMON_LITTLE_ENDIAN106typedef SceUtilitySavedataType SceUtilitySavedataType_le;107typedef SceUtilitySavedataFocus SceUtilitySavedataFocus_le;108#else109typedef swap_struct_t<SceUtilitySavedataType, swap_32_t<SceUtilitySavedataType> > SceUtilitySavedataType_le;110typedef swap_struct_t<SceUtilitySavedataFocus, swap_32_t<SceUtilitySavedataFocus> > SceUtilitySavedataFocus_le;111#endif112113typedef char SceUtilitySavedataSaveName[20];114115// title, savedataTitle, detail: parts of the unencrypted SFO116// data, it contains what the VSH and standard load screen shows117struct PspUtilitySavedataSFOParam118{119char title[0x80];120char savedataTitle[0x80];121char detail[0x400];122unsigned char parentalLevel;123unsigned char unknown[3];124};125126struct PspUtilitySavedataFileData {127PSPPointer<u8> buf;128SceSize_le bufSize; // Size of the buffer pointed to by buf129SceSize_le size; // Actual file size to write / was read130s32_le unknown;131};132133struct PspUtilitySavedataSizeEntry {134u64_le size;135char name[16];136};137138struct PspUtilitySavedataSizeInfo {139s32_le numSecureEntries;140s32_le numNormalEntries;141PSPPointer<PspUtilitySavedataSizeEntry> secureEntries;142PSPPointer<PspUtilitySavedataSizeEntry> normalEntries;143s32_le sectorSize;144s32_le freeSectors;145s32_le freeKB;146char freeString[8];147s32_le neededKB;148char neededString[8];149s32_le overwriteKB;150char overwriteString[8];151};152153struct SceUtilitySavedataIdListEntry154{155s32_le st_mode;156ScePspDateTime st_ctime;157ScePspDateTime st_atime;158ScePspDateTime st_mtime;159SceUtilitySavedataSaveName name;160};161162struct SceUtilitySavedataIdListInfo163{164s32_le maxCount;165s32_le resultCount;166PSPPointer<SceUtilitySavedataIdListEntry> entries;167};168169struct SceUtilitySavedataFileListEntry170{171s32_le st_mode;172u32_le st_unk0;173u64_le st_size;174ScePspDateTime st_ctime;175ScePspDateTime st_atime;176ScePspDateTime st_mtime;177char name[16];178};179180struct SceUtilitySavedataFileListInfo181{182u32_le maxSecureEntries;183u32_le maxNormalEntries;184u32_le maxSystemEntries;185u32_le resultNumSecureEntries;186u32_le resultNumNormalEntries;187u32_le resultNumSystemEntries;188PSPPointer<SceUtilitySavedataFileListEntry> secureEntries;189PSPPointer<SceUtilitySavedataFileListEntry> normalEntries;190PSPPointer<SceUtilitySavedataFileListEntry> systemEntries;191};192193struct SceUtilitySavedataMsFreeInfo194{195s32_le clusterSize;196s32_le freeClusters;197s32_le freeSpaceKB;198char freeSpaceStr[8];199};200201struct SceUtilitySavedataUsedDataInfo202{203s32_le usedClusters;204s32_le usedSpaceKB;205char usedSpaceStr[8];206s32_le usedSpace32KB;207char usedSpace32Str[8];208};209210struct SceUtilitySavedataMsDataInfo211{212char gameName[13];213char pad[3];214SceUtilitySavedataSaveName saveName;215SceUtilitySavedataUsedDataInfo info;216};217218// Structure to hold the parameters for the sceUtilitySavedataInitStart function.219struct SceUtilitySavedataParam220{221pspUtilityDialogCommon common;222223SceUtilitySavedataType_le mode; // 0 to load, 1 to save224s32_le bind;225226s32_le overwriteMode; // use 0x10 ?227228/** gameName: name used from the game for saves, equal for all saves */229char gameName[13];230char unused[3];231/** saveName: name of the particular save, normally a number */232SceUtilitySavedataSaveName saveName;233PSPPointer<SceUtilitySavedataSaveName> saveNameList;234/** fileName: name of the data file of the game for example DATA.BIN */235char fileName[13];236char unused2[3];237238/** pointer to a buffer that will contain data file unencrypted data */239PSPPointer<u8> dataBuf;240/** size of allocated space to dataBuf */241SceSize_le dataBufSize;242SceSize_le dataSize; // Size of the actual save data243244PspUtilitySavedataSFOParam sfoParam;245246PspUtilitySavedataFileData icon0FileData;247PspUtilitySavedataFileData icon1FileData;248PspUtilitySavedataFileData pic1FileData;249PspUtilitySavedataFileData snd0FileData;250251PSPPointer<PspUtilitySavedataFileData> newData;252SceUtilitySavedataFocus_le focus;253s32_le abortStatus;254255// Function SCE_UTILITY_SAVEDATA_TYPE_SIZES256PSPPointer<SceUtilitySavedataMsFreeInfo> msFree;257PSPPointer<SceUtilitySavedataMsDataInfo> msData;258PSPPointer<SceUtilitySavedataUsedDataInfo> utilityData;259260u8 key[16];261262u32_le secureVersion;263s32_le multiStatus;264265// Function 11 LIST266PSPPointer<SceUtilitySavedataIdListInfo> idList;267268// Function 12 FILES269PSPPointer<SceUtilitySavedataFileListInfo> fileList;270271// Function 22 GETSIZES272PSPPointer<PspUtilitySavedataSizeInfo> sizeInfo;273};274275// Non native, this one we can reorganize as we like276struct SaveFileInfo277{278s64 size = 0;279std::string saveName;280std::string saveDir;281int idx = 0;282283char title[128]{};284char saveTitle[128]{};285char saveDetail[1024]{};286287bool broken = false;288289tm modif_time{};290291PPGeImage *texture = nullptr;292293void DoState(PointerWrap &p);294};295296struct SaveSFOFileListEntry {297char filename[13];298u8 hash[16];299u8 pad[3];300};301302class SavedataParam303{304public:305SavedataParam();306307static void Init();308std::string GetSaveFilePath(const SceUtilitySavedataParam *param, int saveId = -1) const;309std::string GetSaveFilePath(const SceUtilitySavedataParam *param, const std::string &saveDir) const;310std::string GetSaveDirName(const SceUtilitySavedataParam *param, int saveId = -1) const;311std::string GetSaveDir(const SceUtilitySavedataParam *param, int saveId = -1) const;312std::string GetSaveDir(const SceUtilitySavedataParam *param, const std::string &saveDirName) const;313bool Delete(SceUtilitySavedataParam* param, int saveId = -1);314int DeleteData(SceUtilitySavedataParam* param);315int Save(SceUtilitySavedataParam* param, const std::string &saveDirName, bool secureMode = true);316int Load(SceUtilitySavedataParam* param, const std::string &saveDirName, int saveId = -1, bool secureMode = true);317int GetSizes(SceUtilitySavedataParam* param);318bool GetList(SceUtilitySavedataParam* param);319int GetFilesList(SceUtilitySavedataParam* param, u32 requestAddr);320bool GetSize(SceUtilitySavedataParam* param);321int GetSaveCryptMode(const SceUtilitySavedataParam *param, const std::string &saveDirName);322bool IsInSaveDataList(const std::string &saveName, int count);323324std::string GetGameName(const SceUtilitySavedataParam *param) const;325std::string GetSaveName(const SceUtilitySavedataParam *param) const;326std::string GetFileName(const SceUtilitySavedataParam *param) const;327std::string GetKey(const SceUtilitySavedataParam *param) const;328bool HasKey(const SceUtilitySavedataParam *param) const;329330static std::string GetSpaceText(u64 size, bool roundUp);331332void SetIgnoreTextures(bool state) {333ignoreTextures_ = state;334}335int SetPspParam(SceUtilitySavedataParam* param);336SceUtilitySavedataParam *GetPspParam();337const SceUtilitySavedataParam *GetPspParam() const;338339int GetFilenameCount();340const SaveFileInfo& GetFileInfo(int idx);341std::string GetFilename(int idx) const;342std::string GetSaveDir(int idx) const;343344int GetSelectedSave();345void SetSelectedSave(int idx);346347int GetFirstListSave();348int GetLastListSave();349int GetLatestSave();350int GetOldestSave();351int GetFirstDataSave();352int GetLastDataSave();353int GetFirstEmptySave();354int GetLastEmptySave();355int GetSaveNameIndex(const SceUtilitySavedataParam *param);356357bool WouldHaveMultiSaveName(const SceUtilitySavedataParam *param);358359void ClearSFOCache();360361void DoState(PointerWrap &p);362363private:364void Clear();365void SetFileInfo(int idx, PSPFileInfo &info, const std::string &saveName, const std::string &saveDir = "");366void SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, const std::string &saveName, const std::string &saveDir = "");367void ClearFileInfo(SaveFileInfo &saveInfo, const std::string &saveName);368PSPFileInfo GetSaveInfo(const std::string &saveDir);369370int LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode);371u32 LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone);372u32 LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize);373bool LoadSFO(SceUtilitySavedataParam *param, const std::string& dirPath);374void LoadFile(const std::string& dirPath, const std::string& filename, PspUtilitySavedataFileData *fileData);375376int DecryptData(unsigned int mode, unsigned char *data, int *dataLen, int *alignedLen, unsigned char *cryptkey, const u8 *expectedHash);377int EncryptData(unsigned int mode, unsigned char *data, int *dataLen, int *alignedLen, unsigned char *hash, unsigned char *cryptkey);378int UpdateHash(u8* sfoData, int sfoSize, int sfoDataParamsOffset, int encryptmode);379380// data must be zero-padded from len to alignedLen (which should be the next multiply of 16)!381int BuildHash(uint8_t *output, const uint8_t *data, unsigned int len, unsigned int alignedLen, int mode, const uint8_t *cryptkey);382int DetermineCryptMode(const SceUtilitySavedataParam *param) const;383384std::vector<SaveSFOFileListEntry> GetSFOEntries(const std::string &dirPath);385std::set<std::string> GetSecureFileNames(const std::string &dirPath);386bool GetExpectedHash(const std::string &dirPath, const std::string &filename, u8 hash[16]);387388std::shared_ptr<ParamSFOData> LoadCachedSFO(const std::string &path, bool orCreate = false);389390SceUtilitySavedataParam* pspParam = nullptr;391int selectedSave = 0;392SaveFileInfo *saveDataList = nullptr;393SaveFileInfo *noSaveIcon = nullptr;394int saveDataListCount = 0;395int saveNameListDataCount = 0;396bool ignoreTextures_ = false;397398// Cleared before returning to PSP, no need to save state.399std::mutex cacheLock_;400std::unordered_map<std::string, std::shared_ptr<ParamSFOData>> sfoCache_;401};402403404