int cellSaveDataListLoad2(u32 version, mem_ptr_t<CellSaveDataSetList> setList, mem_ptr_t<CellSaveDataSetBuf> setBuf,
						  mem_func_ptr_t<CellSaveDataListCallback> funcList, mem_func_ptr_t<CellSaveDataStatCallback> funcStat, mem_func_ptr_t<CellSaveDataFileCallback> funcFile,
						  u32 container, u32 userdata_addr)
{
	cellSysutil.Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)",
		version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata_addr);
	
	if (!setList.IsGood() || !setBuf.IsGood() || !funcList.IsGood() || !funcStat.IsGood() || !funcFile.IsGood())
		return CELL_SAVEDATA_ERROR_PARAM;

	MemoryAllocator<CellSaveDataCBResult> result;
	MemoryAllocator<CellSaveDataListGet> listGet;
	MemoryAllocator<CellSaveDataListSet> listSet;
	MemoryAllocator<CellSaveDataStatGet> statGet;
	MemoryAllocator<CellSaveDataStatSet> statSet;
	MemoryAllocator<CellSaveDataFileGet> fileGet;
	MemoryAllocator<CellSaveDataFileSet> fileSet;

	std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user
	vfsDir dir(saveBaseDir);
	if(!dir.IsOpened())
		return CELL_SAVEDATA_ERROR_INTERNAL;

	std::string dirNamePrefix = Memory.ReadString(setList->dirNamePrefix_addr);
	std::vector<SaveDataEntry> saveEntries;
	for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read())
	{
		if (entry->flags & DirEntry_TypeDir && entry->name.substr(0,dirNamePrefix.size()) == dirNamePrefix)
		{
			// Count the amount of matches and the amount of listed directories
			listGet->dirListNum++;
			if (listGet->dirListNum > setBuf->dirListMax)
				continue;
			listGet->dirNum++;

			std::string saveDir = saveBaseDir + entry->name;
			addSaveDataEntry(saveEntries, saveDir);
		}
	}

	// Sort the entries and fill the listGet->dirList array
	std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
	listGet->dirList.SetAddr(setBuf->buf_addr);
	CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList.GetAddr());
	for (u32 i=0; i<saveEntries.size(); i++) {
		memcpy(dirList[i].dirName, saveEntries[i].dirName.c_str(), CELL_SAVEDATA_DIRNAME_SIZE);
		memcpy(dirList[i].listParam, saveEntries[i].listParam.c_str(), CELL_SAVEDATA_SYSP_LPARAM_SIZE);
	}

	funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr());
	if (result->result < 0)	{
		ConLog.Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}
	if (!listSet->fixedList.IsGood())
		return CELL_SAVEDATA_ERROR_PARAM;

	setSaveDataList(saveEntries, (u32)listSet->fixedList.GetAddr(), listSet->fixedListNum);
	if (listSet->newData.IsGood())
		addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr());
	if (saveEntries.size() == 0) {
		ConLog.Warning("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error
		return CELL_SAVEDATA_RET_OK;
	}

	u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition);
	// TODO: Display the dialog here
	u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry
	getSaveDataStat(saveEntries[selectedIndex], statGet.GetAddr());
	result->userdata_addr = userdata_addr;

	funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr());
	Memory.Free(statGet->fileList.GetAddr());
	if (result->result < 0)	{
		ConLog.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}
	/*if (statSet->setParam.IsGood())
		// TODO: Write PARAM.SFO file
	*/

	fileGet->excSize = 0;
	while(true)
	{
		funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr());
		if (result->result < 0)	{
			ConLog.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
			return CELL_SAVEDATA_ERROR_CBRESULT;
		}
		if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
			break;
		switch (fileSet->fileOperation)
		{
		case CELL_SAVEDATA_FILEOP_READ:
			fileGet->excSize = readSaveDataFile(fileSet.GetAddr(), saveBaseDir + (char*)statGet->dir.dirName);
			break;
		case CELL_SAVEDATA_FILEOP_WRITE:
			fileGet->excSize = writeSaveDataFile(fileSet.GetAddr(), saveBaseDir + (char*)statGet->dir.dirName);
			break;
		case CELL_SAVEDATA_FILEOP_DELETE:
		case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC:
			ConLog.Warning("cellSaveDataListLoad2: TODO: fileSet->fileOperation not yet implemented");
			break;
		}
	}

	// TODO: There are other returns in this function that doesn't free the memory. Fix it (without using goto's, please).
	for (auto& entry : saveEntries) {
		delete[] entry.iconBuf;
		entry.iconBuf = nullptr;
	}

	return CELL_SAVEDATA_RET_OK;
}
Example #2
0
int cellSaveDataListLoad2(u32 version, mem_ptr_t<CellSaveDataSetList> setList, mem_ptr_t<CellSaveDataSetBuf> setBuf,
						  mem_func_ptr_t<CellSaveDataListCallback> funcList, mem_func_ptr_t<CellSaveDataStatCallback> funcStat, mem_func_ptr_t<CellSaveDataFileCallback> funcFile,
						  u32 container, u32 userdata_addr)
{
	cellSysutil->Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)",
		version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata_addr);
	
	MemoryAllocator<CellSaveDataCBResult> result;
	MemoryAllocator<CellSaveDataListGet> listGet;
	MemoryAllocator<CellSaveDataListSet> listSet;
	MemoryAllocator<CellSaveDataStatGet> statGet;
	MemoryAllocator<CellSaveDataStatSet> statSet;

	std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user
	vfsDir dir(saveBaseDir);
	if(!dir.IsOpened())
		return CELL_SAVEDATA_ERROR_INTERNAL;

	std::string dirNamePrefix = Memory.ReadString(setList->dirNamePrefix_addr);
	std::vector<SaveDataEntry> saveEntries;
	for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read())
	{
		if (entry->flags & DirEntry_TypeDir && entry->name.substr(0,dirNamePrefix.size()) == dirNamePrefix)
		{
			// Count the amount of matches and the amount of listed directories
			listGet->dirListNum++;
			if (listGet->dirListNum > setBuf->dirListMax)
				continue;
			listGet->dirNum++;

			std::string saveDir = saveBaseDir + entry->name;
			addSaveDataEntry(saveEntries, saveDir);
		}
	}

	// Sort the entries and fill the listGet->dirList array
	std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
	listGet->dirList.SetAddr(setBuf->buf_addr);
	CellSaveDataDirList* dirList = (CellSaveDataDirList*)Memory.VirtualToRealAddr(listGet->dirList.GetAddr());
	for (u32 i=0; i<saveEntries.size(); i++) {
		memcpy(dirList[i].dirName, saveEntries[i].dirName.c_str(), CELL_SAVEDATA_DIRNAME_SIZE);
		memcpy(dirList[i].listParam, saveEntries[i].listParam.c_str(), CELL_SAVEDATA_SYSP_LPARAM_SIZE);
	}

	funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr());
	if (result->result < 0)	{
		LOG_ERROR(HLE, "cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}

	setSaveDataList(saveEntries, (u32)listSet->fixedList.GetAddr(), listSet->fixedListNum);
	if (listSet->newData.GetAddr())
		addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr());
	if (saveEntries.size() == 0) {
		LOG_WARNING(HLE, "cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error
		return CELL_SAVEDATA_RET_OK;
	}

	u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition);
	// TODO: Display the dialog here
	u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry
	getSaveDataStat(saveEntries[selectedIndex], statGet.GetAddr());
	result->userdata_addr = userdata_addr;

	funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr());
	Memory.Free(statGet->fileList.GetAddr());
	if (result->result < 0)	{
		LOG_ERROR(HLE, "cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}
	/*if (statSet->setParam.GetAddr())
		// TODO: Write PARAM.SFO file
	*/

	// Enter the loop where the save files are read/created/deleted.
	s32 ret = modifySaveDataFiles(funcFile, result.GetAddr(), saveBaseDir + (char*)statGet->dir.dirName);

	return ret;
}
Example #3
0
// Functions
int cellSaveDataListSave2(u32 version, vm::ptr<CellSaveDataSetList> setList, vm::ptr<CellSaveDataSetBuf> setBuf,
						  vm::ptr<CellSaveDataListCallback> funcList, vm::ptr<CellSaveDataStatCallback> funcStat, vm::ptr<CellSaveDataFileCallback> funcFile,
						  u32 container, vm::ptr<void> userdata)
{
	cellSysutil->Warning("cellSaveDataListSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=0x%x, userdata_addr=0x%x)",
		version, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr());

	vm::var<CellSaveDataCBResult> result;
	vm::var<CellSaveDataListGet> listGet;
	vm::var<CellSaveDataListSet> listSet;
	vm::var<CellSaveDataStatGet> statGet;
	vm::var<CellSaveDataStatSet> statSet;

	std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user
	vfsDir dir(saveBaseDir);
	if(!dir.IsOpened())
		return CELL_SAVEDATA_ERROR_INTERNAL;

	std::string dirNamePrefix = setList->dirNamePrefix.get_ptr();
	std::vector<SaveDataEntry> saveEntries;

	for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read())
	{
		if (entry->flags & DirEntry_TypeDir && entry->name.substr(0,dirNamePrefix.size()) == dirNamePrefix)
		{
			// Count the amount of matches and the amount of listed directories
			listGet->dirListNum++;
			if (listGet->dirListNum > setBuf->dirListMax)
				continue;
			listGet->dirNum++;

			std::string saveDir = saveBaseDir + entry->name;
			addSaveDataEntry(saveEntries, saveDir);
		}
	}

	// Sort the entries and fill the listGet->dirList array
	std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
	listGet->dirList = vm::bptr<CellSaveDataDirList>::make(setBuf->buf.addr());
	auto dirList = vm::get_ptr<CellSaveDataDirList>(listGet->dirList.addr());

	for (u32 i=0; i<saveEntries.size(); i++) {
		strcpy_trunc(dirList[i].dirName, saveEntries[i].dirName);
		strcpy_trunc(dirList[i].listParam, saveEntries[i].listParam);
		*dirList[i].reserved = {};
	}

	funcList(result, listGet, listSet);

	if (result->result < 0)	{
		cellSysutil->Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}

	setSaveDataList(saveEntries, vm::ptr<CellSaveDataDirList>::make(listSet->fixedList.addr()), listSet->fixedListNum);
	if (listSet->newData)
		addNewSaveDataEntry(saveEntries, vm::ptr<CellSaveDataListNewData>::make(listSet->newData.addr()));
	if (saveEntries.size() == 0) {
		cellSysutil->Warning("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error
		return CELL_SAVEDATA_RET_OK;
	}

	u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition);
	// TODO: Display the dialog here
	u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry
	getSaveDataStat(saveEntries[selectedIndex], statGet);
	result->userdata = userdata;

	funcStat(result, statGet, statSet);
	Memory.Free(statGet->fileList.addr());
	if (result->result < 0)	{
		cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
		return CELL_SAVEDATA_ERROR_CBRESULT;
	}

	/*if (statSet->setParam)
		addNewSaveDataEntry(saveEntries, (u32)listSet->newData.addr()); // TODO: This *is* wrong
	*/

	// Enter the loop where the save files are read/created/deleted.
	s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName);

	return ret;
}