bool SavedataParam::GetSize(SceUtilitySavedataParam *param) { if (!param) { return false; } std::string saveDir = savePath + GetGameName(param) + GetSaveName(param); PSPFileInfo info = pspFileSystem.GetFileInfo(saveDir); bool exists = info.exists; if (Memory::IsValidAddress(param->sizeAddr)) { PspUtilitySavedataSizeInfo sizeInfo; Memory::ReadStruct(param->sizeAddr, &sizeInfo); // TODO: Read the entries and count up the size vs. existing size? sizeInfo.sectorSize = (int)MemoryStick_SectorSize(); sizeInfo.freeSectors = (int)(MemoryStick_FreeSpace() / MemoryStick_SectorSize()); // TODO: Is this after the specified files? Before? sizeInfo.freeKB = (int)(MemoryStick_FreeSpace() / 1024); std::string spaceTxt = SavedataParam::GetSpaceText((int)MemoryStick_FreeSpace()); strncpy(sizeInfo.freeString, spaceTxt.c_str(), 8); sizeInfo.freeString[7] = '\0'; // TODO. sizeInfo.neededKB = 0; strcpy(sizeInfo.neededString, "0 KB"); sizeInfo.overwriteKB = 0; strcpy(sizeInfo.overwriteString, "0 KB"); Memory::WriteStruct(param->sizeAddr, &sizeInfo); } return exists; }
size_t DirectoryFileHandle::Write(const u8* pointer, s64 size) { size_t bytesWritten = 0; bool diskFull = false; #ifdef _WIN32 BOOL success = ::WriteFile(hFile, (LPVOID)pointer, (DWORD)size, (LPDWORD)&bytesWritten, 0); if (success == FALSE) { DWORD err = GetLastError(); diskFull = err == ERROR_DISK_FULL || err == ERROR_NOT_ENOUGH_QUOTA; } #else bytesWritten = write(hFile, pointer, size); if (bytesWritten == (size_t)-1) { diskFull = errno == ENOSPC; } #endif if (needsTrunc_ != -1) { off_t off = (off_t)Seek(0, FILEMOVE_CURRENT); if (needsTrunc_ < off) { needsTrunc_ = off; } } if (diskFull) { // Sign extend on 64-bit. ERROR_LOG(FILESYS, "Disk full"); I18NCategory *err = GetI18NCategory("Error"); osm.Show(err->T("Disk full while writing data")); // We only return an error when the disk is actually full. // When writing this would cause the disk to be full, so it wasn't written, we return 0. if (MemoryStick_FreeSpace() == 0) { return (size_t)(s64)(s32)SCE_KERNEL_ERROR_ERRNO_DEVICE_NO_FREE_SPACE; } } return bytesWritten; }
bool SavedataParam::GetSizes(SceUtilitySavedataParam *param) { if (!param) { return false; } bool ret = true; if (Memory::IsValidAddress(param->msFree)) { Memory::Write_U32((u32)MemoryStick_SectorSize(),param->msFree); // cluster Size Memory::Write_U32((u32)(MemoryStick_FreeSpace() / MemoryStick_SectorSize()),param->msFree+4); // Free cluster Memory::Write_U32((u32)(MemoryStick_FreeSpace() / 0x400),param->msFree+8); // Free space (in KB) std::string spaceTxt = SavedataParam::GetSpaceText((int)MemoryStick_FreeSpace()); Memory::Memset(param->msFree+12,0,(u32)spaceTxt.size()+1); Memory::Memcpy(param->msFree+12,spaceTxt.c_str(),(u32)spaceTxt.size()); // Text representing free space } if (Memory::IsValidAddress(param->msData)) { std::string path = GetSaveFilePath(param,0); PSPFileInfo finfo = pspFileSystem.GetFileInfo(path); if(finfo.exists) { // TODO : fill correctly with the total save size Memory::Write_U32(1,param->msData+36); //1 Memory::Write_U32(0x20,param->msData+40); // 0x20 Memory::Write_U8(0,param->msData+44); // "32 KB" // 8 u8 Memory::Write_U32(0x20,param->msData+52); // 0x20 Memory::Write_U8(0,param->msData+56); // "32 KB" // 8 u8 } else { Memory::Write_U32(0,param->msData+36); Memory::Write_U32(0,param->msData+40); Memory::Write_U8(0,param->msData+44); Memory::Write_U32(0,param->msData+52); Memory::Write_U8(0,param->msData+56); ret = false; // this should return SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA } } if (Memory::IsValidAddress(param->utilityData)) { int total_size = 0; total_size += getSizeNormalized(1); // SFO; total_size += getSizeNormalized(param->dataSize); // Save Data total_size += getSizeNormalized(param->icon0FileData.size); total_size += getSizeNormalized(param->icon1FileData.size); total_size += getSizeNormalized(param->pic1FileData.size); total_size += getSizeNormalized(param->snd0FileData.size); Memory::Write_U32(total_size / (u32)MemoryStick_SectorSize(),param->utilityData); // num cluster Memory::Write_U32(total_size / 0x400,param->utilityData+4); // save size in KB std::string spaceTxt = SavedataParam::GetSpaceText(total_size); Memory::Memset(param->utilityData+8,0,(u32)spaceTxt.size()+1); Memory::Memcpy(param->utilityData+8,spaceTxt.c_str(),(u32)spaceTxt.size()); // save size in text Memory::Write_U32(total_size / 0x400,param->utilityData+16); // save size in KB spaceTxt = SavedataParam::GetSpaceText(total_size); Memory::Memset(param->utilityData+20,0,(u32)spaceTxt.size()+1); Memory::Memcpy(param->utilityData+20,spaceTxt.c_str(),(u32)spaceTxt.size()); // save size in text } return ret; }
void PSPSaveDialog::ExecuteNotVisibleIOAction() { switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; } break; case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE; } break; case SCE_UTILITY_SAVEDATA_TYPE_SIZES: param.GetPspParam()->common.result = param.GetSizes(param.GetPspParam()); break; case SCE_UTILITY_SAVEDATA_TYPE_LIST: param.GetList(param.GetPspParam()); param.GetPspParam()->common.result = 0; break; case SCE_UTILITY_SAVEDATA_TYPE_FILES: param.GetPspParam()->common.result = param.GetFilesList(param.GetPspParam()); break; case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE: { bool result = param.GetSize(param.GetPspParam()); // TODO: According to JPCSP, should test/verify this part but seems edge casey. if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_DRIVER_READY) { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK; } else if (result) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; } } break; case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: DEBUG_LOG(SCEUTILITY, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName); param.GetPspParam()->common.result = param.DeleteData(param.GetPspParam()); break; //case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; } break; // TODO: Should reset the directory's other files. case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE)) { param.GetPspParam()->common.result = 0; } else if (MemoryStick_FreeSpace() == 0) { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; } break; case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE)) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; } break; case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: if (!param.IsSaveDirectoryExist(param.GetPspParam())){ param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; } else if (!param.IsSfoFileExist(param.GetPspParam())) { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN; } else if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE)) { param.GetPspParam()->common.result = 0; } else { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; } break; default: break; } }