Save unencrypted PARAM.SFO

This commit is contained in:
Xele02 2012-12-14 20:55:57 +01:00
parent 1ea6fe7e4d
commit ab71c3d1d0
5 changed files with 193 additions and 25 deletions

View File

@ -19,6 +19,7 @@
#include "../System.h"
#include "image/png_load.h"
#include "../HLE/sceKernelMemory.h"
#include "../ELF/ParamSFO.h"
std::string icon0Name = "ICON0.PNG";
std::string icon1Name = "ICON1.PNG";
@ -45,8 +46,7 @@ void SavedataParam::Init()
}
}
std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId)
std::string SavedataParam::GetSaveDir(SceUtilitySavedataParam* param, int saveId)
{
if (!param) {
return "";
@ -56,7 +56,16 @@ std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int s
if(saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
dirPath = std::string(GetGameName(param))+GetFilename(saveId);
return savePath + dirPath;
return dirPath;
}
std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId)
{
if (!param) {
return "";
}
return savePath + GetSaveDir(param,saveId);
}
std::string SavedataParam::GetGameName(SceUtilitySavedataParam* param)
@ -134,9 +143,27 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
{
pspFileSystem.CloseFile(handle);
// TODO SAVE PARAM.SFO
/*data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->dataBuf));
writeDataToFile(false, );*/
// SAVE PARAM.SFO
ParamSFOData sfoFile;
sfoFile.SetValue("TITLE",param->sfoParam.title,128);
sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.savedataTitle,1024);
sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
sfoFile.SetValue("CATEGORY","MS",4);
sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);
sfoFile.SetValue("SAVEDATA_FILE_LIST","",3168);
sfoFile.SetValue("SAVEDATA_PARAMS","",128);
u8* sfoData;
size_t sfoSize;
sfoFile.WriteSFO(&sfoData,&sfoSize);
std::string sfopath = dirPath+"/"+sfoName;
handle = pspFileSystem.OpenFile(sfopath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
if(handle)
{
pspFileSystem.WriteFile(handle, sfoData, sfoSize);
pspFileSystem.CloseFile(handle);
}
delete[] sfoData;
// SAVE ICON0
if(param->icon0FileData.buf)

View File

@ -134,6 +134,7 @@ class SavedataParam
public:
static void Init();
std::string GetSaveFilePath(SceUtilitySavedataParam* param, int saveId = -1);
std::string GetSaveDir(SceUtilitySavedataParam* param, int saveId = -1);
bool Delete(SceUtilitySavedataParam* param, int saveId = -1);
bool Save(SceUtilitySavedataParam* param, int saveId = -1);
bool Load(SceUtilitySavedataParam* param, int saveId = -1);

View File

@ -38,22 +38,48 @@ struct IndexTable
u32 data_table_offset; /* Offset of the param_data from start of data_table */
};
void ParseDataString(const char *key, const char *utfdata, ParamSFOData *sfodata, int maxlen = 0)
void ParamSFOData::SetValue(std::string key, unsigned int value, int max_size)
{
std::string data;
if (maxlen)
data = std::string(utfdata, maxlen);
else
data = std::string(utfdata);
if (!strcmp(key, "DISC_ID")) {
sfodata->discID = data;
} else if (!strcmp(key, "TITLE")) {
sfodata->title = data;
values[key].type = VT_INT;
values[key].i_value = value;
values[key].max_size = max_size;
}
void ParamSFOData::SetValue(std::string key, std::string value, int max_size)
{
if(key == "ACCOUNT_ID" ||
key == "PADDING" ||
key == "PARAMS" ||
key == "PARAMS2" ||
key == "SAVEDATA_FILE_LIST" ||
key == "SAVEDATA_PARAMS")
{
values[key].type = VT_UTF8_SPE;
}
else
{
values[key].type = VT_UTF8;
}
values[key].s_value = value;
values[key].max_size = max_size;
}
int ParamSFOData::GetValueInt(std::string key)
{
std::map<std::string,ValueData>::iterator it = values.find(key);
if(it == values.end() || it->second.type != VT_INT)
return 0;
return it->second.i_value;
}
std::string ParamSFOData::GetValueString(std::string key)
{
std::map<std::string,ValueData>::iterator it = values.find(key);
if(it == values.end() || (it->second.type != VT_UTF8 && it->second.type != VT_UTF8_SPE))
return "";
return it->second.s_value;
}
// I'm so sorry Ced but this is highly endian unsafe :(
bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size)
{
const Header *header = (const Header *)paramsfo;
if (header->magic != 0x46535000)
@ -75,6 +101,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
{
// Unsigned int
const u32 *data = (const u32 *)(data_start + indexTables[i].data_table_offset);
SetValue(key,*data,indexTables[i].param_max_len);
DEBUG_LOG(LOADER, "%s %08x", key, *data);
}
break;
@ -83,7 +110,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
{
const char *utfdata = (const char *)(data_start + indexTables[i].data_table_offset);
DEBUG_LOG(LOADER, "%s %s", key, utfdata);
ParseDataString(key, utfdata, data, indexTables[i].param_len);
SetValue(key,std::string(utfdata,indexTables[i].param_len),indexTables[i].param_max_len);
}
break;
case 0x0204:
@ -91,7 +118,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
{
const char *utfdata = (const char *)(data_start + indexTables[i].data_table_offset);
DEBUG_LOG(LOADER, "%s %s", key, utfdata);
ParseDataString(key, utfdata, data, indexTables[i].param_len);
SetValue(key,std::string(utfdata,indexTables[i].param_len),indexTables[i].param_max_len);
}
break;
}
@ -99,3 +126,92 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
return true;
}
bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size)
{
size_t total_size = 0;
size_t key_size = 0;
size_t data_size = 0;
Header header;
header.magic = 0x46535000;
header.version = 0x00000101;
header.index_table_entries = 0;
total_size += sizeof(Header);
// Get size info
for(std::map<std::string,ValueData>::iterator it = values.begin(); it != values.end(); it++)
{
key_size += it->first.size()+1;
data_size += it->second.max_size;
header.index_table_entries++;
}
// Padding
while((key_size%4)) key_size++;
header.key_table_start = sizeof(Header) + header.index_table_entries * sizeof(IndexTable);
header.data_table_start = header.key_table_start + key_size;
total_size += sizeof(IndexTable) * header.index_table_entries;
total_size += key_size;
total_size += data_size;
*size = total_size;
u8* data = new u8[total_size];
*paramsfo = data;
memset(data,0,total_size);
memcpy(data,&header,sizeof(Header));
// Now fill
IndexTable *index_ptr = (IndexTable*)(data + sizeof(Header));
u8* key_ptr = data + header.key_table_start;
u8* data_ptr = data + header.data_table_start;
for(std::map<std::string,ValueData>::iterator it = values.begin(); it != values.end(); it++)
{
u16 offset = (u16)(key_ptr - (data+header.key_table_start));
index_ptr->key_table_offset = offset;
offset = (u16)(data_ptr - (data+header.data_table_start));
index_ptr->data_table_offset = offset;
index_ptr->param_max_len = it->second.max_size;
if(it->second.type == VT_INT)
{
index_ptr->param_fmt = 0x0404;
index_ptr->param_len = 4;
*(int*)data_ptr = it->second.i_value;
}
else if(it->second.type == VT_UTF8_SPE)
{
index_ptr->param_fmt = 0x0004;
index_ptr->param_len = it->second.s_value.size()+1;
memcpy(data_ptr,it->second.s_value.c_str(),index_ptr->param_len);
data_ptr[index_ptr->param_len] = 0;
}
else if(it->second.type == VT_UTF8)
{
index_ptr->param_fmt = 0x0204;
index_ptr->param_len = it->second.s_value.size()+1;
memcpy(data_ptr,it->second.s_value.c_str(),index_ptr->param_len);
data_ptr[index_ptr->param_len] = 0;
}
memcpy(key_ptr,it->first.c_str(),it->first.size());
key_ptr[it->first.size()] = 0;
data_ptr += index_ptr->param_max_len;
key_ptr += it->first.size()+1;
index_ptr++;
}
return true;
}

View File

@ -18,11 +18,35 @@
#pragma once
#include <map>
struct ParamSFOData
class ParamSFOData
{
std::string discID;
std::string title; // utf-8
public:
void SetValue(std::string key, unsigned int value, int max_size);
void SetValue(std::string key, std::string value, int max_size);
int GetValueInt(std::string key);
std::string GetValueString(std::string key);
bool ReadSFO(const u8 *paramsfo, size_t size);
bool WriteSFO(u8 **paramsfo, size_t *size);
private:
enum ValueType
{
VT_INT,
VT_UTF8,
VT_UTF8_SPE
};
struct ValueData
{
ValueType type;
int max_size;
std::string s_value;
int i_value;
};
std::map<std::string,ValueData> values;
};
bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data);

View File

@ -78,10 +78,10 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string)
pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
pspFileSystem.CloseFile(fd);
ParamSFOData data;
if (ParseParamSFO(paramsfo, (size_t)fileInfo.size, &data))
if (data.ReadSFO(paramsfo, (size_t)fileInfo.size))
{
char title[1024];
sprintf(title, "%s : %s", data.discID.c_str(), data.title.c_str());
sprintf(title, "%s : %s", data.GetValueString("DISC_ID").c_str(), data.GetValueString("TITLE").c_str());
INFO_LOG(LOADER, "%s", title);
host->SetWindowTitle(title);
}