Skip to content

Instantly share code, notes, and snippets.

@Kethen
Last active November 15, 2023 10:00
Show Gist options
  • Save Kethen/ec3d47527f1d4beec807abff06414697 to your computer and use it in GitHub Desktop.
Save Kethen/ec3d47527f1d4beec807abff06414697 to your computer and use it in GitHub Desktop.
read out known non pointer psp save utility params
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
struct pspUtilityDialogCommon
{
uint32_t size; /** Size of the structure */
int32_t language; /** Language */
int32_t buttonSwap; /** Set to 1 for X/O button swap */
int32_t graphicsThread; /** Graphics thread priority */
int32_t accessThread; /** Access/fileio thread priority (SceJobThread) */
int32_t fontThread; /** Font thread priority (ScePafThread) */
int32_t soundThread; /** Sound thread priority */
int32_t result; /** Result */
int32_t reserved[4]; /** Set to 0 */
};
enum SceUtilitySavedataType_le
{
SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD = 0,
SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE = 1,
SCE_UTILITY_SAVEDATA_TYPE_LOAD = 2,
SCE_UTILITY_SAVEDATA_TYPE_SAVE = 3,
SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD = 4,
SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE = 5,
SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6,
SCE_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)
SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8,
SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE = 9,
SCE_UTILITY_SAVEDATA_TYPE_DELETE = 10,
SCE_UTILITY_SAVEDATA_TYPE_LIST = 11,
SCE_UTILITY_SAVEDATA_TYPE_FILES = 12,
SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE = 13,
SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA = 14,
SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE = 15,
SCE_UTILITY_SAVEDATA_TYPE_READDATA = 16,
SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE = 17,
SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA = 18,
SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE = 19,
SCE_UTILITY_SAVEDATA_TYPE_ERASE = 20,
SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA = 21,
SCE_UTILITY_SAVEDATA_TYPE_GETSIZE = 22,
};
typedef char SceUtilitySavedataSaveName[20];
typedef uint32_t PSPPointer;
struct PspUtilitySavedataSFOParam
{
char title[0x80];
char savedataTitle[0x80];
char detail[0x400];
unsigned char parentalLevel;
unsigned char unknown[3];
};
struct PspUtilitySavedataFileData {
//char *buf;
PSPPointer buf;
uint32_t bufSize; // Size of the buffer pointed to by buf
uint32_t size; // Actual file size to write / was read
int32_t unknown;
};
enum SceUtilitySavedataFocus_le
{
SCE_UTILITY_SAVEDATA_FOCUS_NAME = 0, // specified by saveName[]
SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST = 1, // first listed (on screen or of all?)
SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST = 2, // last listed (on screen or of all?)
SCE_UTILITY_SAVEDATA_FOCUS_LATEST = 3, // latest by modification date (first if none)
SCE_UTILITY_SAVEDATA_FOCUS_OLDEST = 4, // oldest by modification date (first if none)
SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA = 5, // first non-empty (first if none)
SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA = 6, // last non-empty (first if none)
SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY = 7, // first empty (what if no empty?)
SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY = 8, // last empty (what if no empty?)
};
struct SceUtilitySavedataMsFreeInfo
{
int32_t clusterSize;
int32_t freeClusters;
int32_t freeSpaceKB;
char freeSpaceStr[8];
};
struct SceUtilitySavedataUsedDataInfo
{
int32_t usedClusters;
int32_t usedSpaceKB;
char usedSpaceStr[8];
int32_t usedSpace32KB;
char usedSpace32Str[8];
};
struct SceUtilitySavedataMsDataInfo
{
char gameName[13];
char pad[3];
SceUtilitySavedataSaveName saveName;
struct SceUtilitySavedataUsedDataInfo info;
};
struct ScePspDateTime {
int16_t year;
int16_t month;
int16_t day;
int16_t hour;
int16_t minute;
int16_t second;
uint32_t microsecond;
};
struct SceUtilitySavedataIdListEntry
{
int32_t st_mode;
struct ScePspDateTime ctime;
struct ScePspDateTime atime;
struct ScePspDateTime mtime;
SceUtilitySavedataSaveName name;
};
struct SceUtilitySavedataIdListInfo
{
int32_t maxCount;
int32_t resultCount;
//struct SceUtilitySavedataIdListEntry *entries;
PSPPointer entries;
};
struct SceUtilitySavedataFileListEntry
{
int32_t st_mode;
uint32_t st_unk0;
uint64_t st_size;
struct ScePspDateTime ctime;
struct ScePspDateTime atime;
struct ScePspDateTime mtime;
char name[16];
};
struct SceUtilitySavedataFileListInfo
{
uint32_t maxSecureEntries;
uint32_t maxNormalEntries;
uint32_t maxSystemEntries;
uint32_t resultNumSecureEntries;
uint32_t resultNumNormalEntries;
uint32_t resultNumSystemEntries;
//struct SceUtilitySavedataFileListEntry *secureEntries;
PSPPointer secureEntries;
//struct SceUtilitySavedataFileListEntry *normalEntries;
PSPPointer normalEntries;
//struct SceUtilitySavedataFileListEntry *systemEntries;
PSPPointer systemEntries;
};
struct PspUtilitySavedataSizeEntry {
uint64_t size;
char name[16];
};
struct PspUtilitySavedataSizeInfo {
int32_t numSecureEntries;
int32_t numNormalEntries;
//struct PspUtilitySavedataSizeEntry *secureEntries;
PSPPointer secureEntries;
//struct PspUtilitySavedataSizeEntry *normalEntries;
PSPPointer normalEntries;
int32_t sectorSize;
int32_t freeSectors;
int32_t freeKB;
char freeString[8];
int32_t neededKB;
char neededString[8];
int32_t overwriteKB;
char overwriteString[8];
};
struct SceUtilitySavedataParam
{
struct pspUtilityDialogCommon common;
enum SceUtilitySavedataType_le mode; // 0 to load, 1 to save
int32_t bind;
int32_t overwriteMode; // use 0x10 ?
/** gameName: name used from the game for saves, equal for all saves */
char gameName[13];
char unused[3];
/** saveName: name of the particular save, normally a number */
SceUtilitySavedataSaveName saveName;
//SceUtilitySavedataSaveName *saveNameList;
PSPPointer saveNameList;
/** fileName: name of the data file of the game for example DATA.BIN */
char fileName[13];
char unused2[3];
/** pointer to a buffer that will contain data file unencrypted data */
//char *dataBuf;
PSPPointer dataBuf;
/** size of allocated space to dataBuf */
uint32_t dataBufSize;
uint32_t dataSize; // Size of the actual save data
struct PspUtilitySavedataSFOParam sfoParam;
struct PspUtilitySavedataFileData icon0FileData;
struct PspUtilitySavedataFileData icon1FileData;
struct PspUtilitySavedataFileData pic1FileData;
struct PspUtilitySavedataFileData snd0FileData;
//struct PspUtilitySavedataFileData *newData;
PSPPointer newData;
enum SceUtilitySavedataFocus_le focus;
int32_t abortStatus;
// Function SCE_UTILITY_SAVEDATA_TYPE_SIZES
//struct SceUtilitySavedataMsFreeInfo *msFree;
PSPPointer msFree;
//struct SceUtilitySavedataMsDataInfo *msData;
PSPPointer msData;
//struct SceUtilitySavedataUsedDataInfo *utilityData;
PSPPointer utilityData;
uint8_t key[16];
uint32_t secureVersion;
int32_t multiStatus;
// Function 11 LIST
//struct SceUtilitySavedataIdListInfo *idList;
PSPPointer idList;
// Function 12 FILES
//struct SceUtilitySavedataFileListInfo *fileList;
PSPPointer fileList;
// Function 22 GETSIZES
//struct PspUtilitySavedataSizeInfo *sizeInfo;
PSPPointer sizeInfo;
};
void print_buffer(const char *name, uint8_t *src, uint64_t size){
printf("%s as string: ", name);
uint64_t i;
for(i = 0;i < size; i++){
printf("%c", (char)src[i]);
}
printf("\n");
printf("%s as hex: ", name);
for(i = 0;i < size; i++){
if(i != 0 && i % 16 == 0){
printf("| ");
}
printf("0x%02x ", src[i]);
}
printf("\n");
}
int main(int argc, char** argv){
if(argc != 2){
printf("expects exactly one argument, path to param dump\n");
exit(1);
}
int fd = open(argv[1], O_RDONLY);
if(fd <= 0){
printf("failed opening %s for reading\n", argv[1]);
exit(1);
}
struct SceUtilitySavedataParam param;
if(read(fd, &param, sizeof(param)) != sizeof(param)){
printf("failed reading param dump\n");
}
printf("mode: %d\n", param.mode);
printf("bind: %d\n", param.bind);
printf("overwriteMode: %d\n", param.overwriteMode);
print_buffer("gameName", (uint8_t *)param.gameName, 13);
print_buffer("unused", (uint8_t *)param.unused, 3);
print_buffer("saveName", (uint8_t *)param.saveName, 20);
print_buffer("fileName", (uint8_t *)param.fileName, 13);
print_buffer("unused2", (uint8_t *)param.unused2, 3);
printf("dataBufSize: %u\n", param.dataBufSize);
printf("dataBufSize: %u\n", param.dataSize);
print_buffer("sfoParam.title", (uint8_t *)param.sfoParam.title, 0x80);
print_buffer("sfoParam.savedataTitle", (uint8_t *)param.sfoParam.savedataTitle, 0x80);
print_buffer("sfoParam.detail", (uint8_t *)param.sfoParam.detail, 0x400);
printf("sfoParam.parentalLevel: %u\n", param.sfoParam.parentalLevel);
print_buffer("sfoParam.unknown", (uint8_t *)param.sfoParam.unknown, 3);
printf("focus: %d\n", param.focus);
printf("abortStatus: %d\n", param.abortStatus);
print_buffer("key", (uint8_t *)param.key, 16);
printf("secureVersion: %u\n", param.secureVersion);
printf("multiStatus: %d\n", param.multiStatus);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment