bool EFS_Utils::GetSaveName( LPCSTR initial, xr_string& buffer, LPCSTR offset, int start_flt_ext ) { string4096 buf; strcpy(buf,buffer.c_str()); bool bRes = GetSaveName(initial,buf,sizeof(buf),offset,start_flt_ext); if (bRes) buffer=buf; return bRes; }
std::string SavedataParam::GetSaveDir(SceUtilitySavedataParam* param, int saveId) { if (!param) { return ""; } std::string dirPath = GetGameName(param)+GetSaveName(param); if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it dirPath = std::string(GetGameName(param))+GetFilename(saveId); return dirPath; }
bool SavedataParam::GetFilesList(SceUtilitySavedataParam *param) { if (!param) { return false; } u32 dataAddr = param->fileListAddr; if (!Memory::IsValidAddress(dataAddr)) return false; // TODO : Need to be checked against more game u32 fileInfosAddr = Memory::Read_U32(dataAddr + 24); //for Valkyria2, dataAddr+0 and dataAddr+12 has "5" for 5 files int numFiles = Memory::Read_U32(dataAddr+12); int foundFiles = 0; for (int i = 0; i < numFiles; i++) { // for each file (80 bytes): // u32 mode, u32 ??, u64 size, u64 ctime, u64 ??, u64 atime, u64 ???, u64 mtime, u64 ??? // u8[16] filename (or 13 + padding?) u32 curFileInfoAddr = fileInfosAddr + i*80; char fileName[16]; strncpy(fileName, Memory::GetCharPointer(curFileInfoAddr + 64),16); std::string filePath = savePath + GetGameName(param) + GetSaveName(param) + "/" + fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(filePath); if (info.exists) { bool isCrypted = IsSaveEncrypted(param,0); Memory::Write_U32(0x21FF, curFileInfoAddr+0); if(isCrypted) // Crypted save are 16 bytes bigger Memory::Write_U64(info.size - 0x10, curFileInfoAddr+8); else Memory::Write_U64(info.size, curFileInfoAddr+8); Memory::Write_U64(0,curFileInfoAddr + 16); // TODO ctime Memory::Write_U64(0,curFileInfoAddr + 24); // TODO unknow Memory::Write_U64(0,curFileInfoAddr + 32); // TODO atime Memory::Write_U64(0,curFileInfoAddr + 40); // TODO unknow Memory::Write_U64(0,curFileInfoAddr + 48); // TODO mtime Memory::Write_U64(0,curFileInfoAddr + 56); // TODO unknow foundFiles++; } } // TODO : verify if return true if at least 1 file found or only if all found return foundFiles > 0; }
bool SavedataParam::GetList(SceUtilitySavedataParam *param) { if (!param) { return false; } if (Memory::IsValidAddress(param->idListAddr)) { u32 outputBuffer = Memory::Read_U32(param->idListAddr + 8); u32 maxFile = Memory::Read_U32(param->idListAddr + 0); std::vector<PSPFileInfo> validDir; std::vector<PSPFileInfo> allDir = pspFileSystem.GetDirListing(savePath); if (Memory::IsValidAddress(outputBuffer)) { std::string searchString = GetGameName(param)+GetSaveName(param); for (size_t i = 0; i < allDir.size() && i < maxFile; i++) { std::string dirName = allDir[i].name; if(PSPMatch(dirName, searchString)) { validDir.push_back(allDir[i]); } } for (u32 i = 0; i < (u32)validDir.size(); i++) { u32 baseAddr = outputBuffer + (i*72); Memory::Write_U32(0x11FF,baseAddr + 0); // mode Memory::Write_U64(0,baseAddr + 4); // TODO ctime Memory::Write_U64(0,baseAddr + 12); // TODO unknow Memory::Write_U64(0,baseAddr + 20); // TODO atime Memory::Write_U64(0,baseAddr + 28); // TODO unknow Memory::Write_U64(0,baseAddr + 36); // TODO mtime Memory::Write_U64(0,baseAddr + 44); // TODO unknow // folder name without gamename (max 20 u8) std::string outName = validDir[i].name.substr(GetGameName(param).size()); Memory::Memset(baseAddr + 52,0,20); Memory::Memcpy(baseAddr + 52, outName.c_str(), (u32)outName.size()); } } // Save num of folder found Memory::Write_U32((u32)validDir.size(), param->idListAddr + 4); } return true; }
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; }
/*------------------------------------------------------------------------ Procedure: HandleCommand ID:1 Purpose: Handles all menu commands. Input: Output: Errors: -------------------------------------------------------------------------- Edit History: 06 Oct 2003 - Chris Watford [email protected] - Removed entries that crashed OCaml - Removed useless entries - Added Save ML and Save Transcript ------------------------------------------------------------------------*/ void HandleCommand(HWND hwnd, WPARAM wParam,LPARAM lParam) { char *fname; int r; switch(LOWORD(wParam)) { case IDM_OPEN: fname = SafeMalloc(512); if (OpenMlFile(fname,512)) { char *buf = SafeMalloc(512); char *p = strrchr(fname,'.'); if (p && !stricmp(p,".ml")) { wsprintf(buf, "#use \"%s\";;", fname); AddLineToControl(buf); } else if (p && !stricmp(p,".cmo")) { wsprintf(buf, "#load \"%s\";;", fname); AddLineToControl(buf); } free(buf); } free(fname); break; case IDM_GC: AddLineToControl("Gc.full_major();;"); break; case IDCTRLC: InterruptOcaml(); break; case IDM_EDITPASTE: Add_Clipboard_To_Queue(); break; case IDM_EDITCOPY: CopyToClipboard(hwnd); break; // updated to save a transcript case IDM_SAVEAS: fname = SafeMalloc(512); if (GetSaveName(fname,512)) { SaveText(fname); } free(fname); break; // updated to save an ML file case IDM_SAVE: fname = SafeMalloc(512); if (GetSaveMLName(fname,512)) { SaveML(fname); } free(fname); break; // updated to work with new history system case IDM_HISTORY: r = CallDlgProc(HistoryDlgProc,IDD_HISTORY); if (r) { AddLineToControl(GetHistoryLine(r-1)); } break; case IDM_PRINTSU: // Removed by Chris Watford // seems to die // CallPrintSetup(); break; case IDM_FONT: CallChangeFont(hwndMain); break; case IDM_COLORTEXT: ProgramParams.TextColor = CallChangeColor(ProgramParams.TextColor); ForceRepaint(); break; case IDM_BACKCOLOR: BackColor = CallChangeColor(BackColor); DeleteObject(BackgroundBrush); BackgroundBrush = CreateSolidBrush(BackColor); ForceRepaint(); break; case IDM_EDITUNDO: Undo(hwnd); break; /* Removed, really not very useful in this IDE case IDM_WINDOWTILE: SendMessage(hwndMDIClient,WM_MDITILE,0,0); break; case IDM_WINDOWCASCADE: SendMessage(hwndMDIClient,WM_MDICASCADE,0,0); break; case IDM_WINDOWICONS: SendMessage(hwndMDIClient,WM_MDIICONARRANGE,0,0); break; */ case IDM_EXIT: PostMessage(hwnd,WM_CLOSE,0,0); break; case IDM_ABOUT: CallDlgProc(AboutDlgProc,IDD_ABOUT); break; default: if (LOWORD(wParam) >= IDEDITCONTROL && LOWORD(wParam) < IDEDITCONTROL+5) { switch (HIWORD(wParam)) { case EN_ERRSPACE: ResetText(); break; } } break; } }
int BuildMake( HWND h, char *cTitle, char *cMessage ) { int nFiles; int x; char cOut[4500]; char OutFile[MAX_PATH]; OPENFILENAME opf; CWSFMod wMod; CWSFPack *wP; wsfb *bPack; wsul nPack; memset(&opf,0,sizeof(OPENFILENAME)); opf.lStructSize = sizeof(OPENFILENAME); opf.hwndOwner = h; opf.hInstance = hinst; opf.Flags = OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT|OFN_EXPLORER; opf.lpstrFilter = "Supported Files (*.MOD;*.XM;*.IT;*.S3M)\0*.mod;*.it;*.xm;*.s3m\0\0"; opf.lpstrTitle = "Add Files"; opf.nMaxFile = 4500; opf.lpstrFile = cOut; memset(cOut,0,4500); if (GetOpenFileName(&opf)==0) return 1; FILE *fTest; int nDir; nDir=0; fTest = fopen(cOut,"rb"); if (!fTest) nDir=1; else fclose(fTest); nFiles = 0; if (nDir==0) { nFiles = 1; g_WD.cFiles = (char**)malloc(sizeof(char*)); g_WD.cFiles[0] = (char*)malloc(strlen(cOut)+1); strcpy(g_WD.cFiles[0],cOut); } else { // Directory char *cCur; char cTemp[200]; cCur = opf.lpstrFile + opf.nFileOffset; while (1) { char *c; strcpy(cTemp,cOut); strcat(cTemp,"\\"); strcat(cTemp,cCur); nFiles++; g_WD.cFiles = (char**)realloc(g_WD.cFiles,sizeof(char*)*nFiles); g_WD.cFiles[nFiles-1] = (char*)malloc(strlen(cTemp)+1); strcpy(g_WD.cFiles[nFiles-1],cTemp); c = cCur + strlen(cCur); c++; if (c[1] == '\0') break; cCur = c; } } /// MAKE! g_WD.nMods = nFiles; g_WD.bMods = (wsfb**)malloc(sizeof(wsfb*)*nFiles); g_WD.nModSizes = (wsul*)malloc(sizeof(wsul)*nFiles); wMod.SetPackName(""); for (x=0;x<nFiles;x++) { wsf_modout mo; if (wMod.LoadMod(g_WD.cFiles[x])) break; if (wMod.WriteMod(&mo,1)) break; g_WD.bMods[x] = mo.bModData; g_WD.nModSizes[x] = mo.nSize; } if (x!=nFiles){ MessageBox(h,"Error with one of the modules!","MiniWSF",MB_OK); return 0; } wP = wMod.GetPack(); wP->SavePack(&bPack,&nPack,1); if (GetSaveName(h,OutFile,"MiniWSF Executable (*.exe)\0*.exe\0\0",1,"exe")==-1) return 1; // Save Filebum { char cFile[200]; wsul num; wsul pnum; wsf_file *fbit; wsf_file *fout; wsfb *bd; GetModuleFileName(NULL,cFile,200); fbit = wsfopenfile(cFile); if (!fbit){ free(bPack); return 0; } pnum = fbit->nSize; // Check and see the length bit. { wsul nPos; wsfend(-1*(signed)sizeof(wsul),fbit); wsfread(&nPos,sizeof(wsul),fbit); if (nPos < fbit->nSize){ wsfbegin(nPos,fbit); wsfread(&nPos,sizeof(wsul),fbit); if (nPos == 666) pnum = fbit->nPos-sizeof(wsul); } wsfbegin(0,fbit); } bd = (wsfb*)malloc(pnum); wsfread(bd,pnum,fbit); wsfclose(fbit); fout = wsfcreatefile(OutFile); num = 666; wsfwrite(bd,pnum,fout); wsfwrite(&num,sizeof(wsul),fout); free(bd); wsfwrite(cTitle,30,fout); wsfwrite(cMessage,255,fout); wsfwrite(&nFiles,sizeof(wsul),fout); wsfwrite(&nPack,sizeof(wsul),fout); for (x=0;x<nFiles;x++) { wsul size; char *cN; // Make the Pack Name Small cN = strrchr(g_WD.cFiles[x],'\\'); if (!cN) cN = g_WD.cFiles[x]; else cN++; wsfwrite(&g_WD.nModSizes[x],sizeof(wsul),fout); wsfwrite(g_WD.bMods[x],g_WD.nModSizes[x],fout); size = strlen(cN); wsfwrite(&size,sizeof(wsul),fout); wsfwrite(cN,size,fout); free(g_WD.cFiles[x]); free(g_WD.bMods[x]); } free(g_WD.cFiles); wsfwrite(bPack,nPack,fout); wsfwrite(&pnum,sizeof(wsul),fout); wsfclose(fout); free(bPack); free(g_WD.bMods); free(g_WD.nModSizes); } return 0; }
int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) { pspParam = param; if (!pspParam) { Clear(); return 0; } bool listEmptyFile = true; if (param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD || param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE) { listEmptyFile = false; } char (*saveNameListData)[20]; bool hasMultipleFileName = false; if (param->saveNameList != 0) { Clear(); saveNameListData = (char(*)[20])Memory::GetPointer(param->saveNameList); // Get number of fileName in array saveDataListCount = 0; while(saveNameListData[saveDataListCount][0] != 0) { saveDataListCount++; } if(saveDataListCount > 0) { hasMultipleFileName = true; saveDataList = new SaveFileInfo[saveDataListCount]; // get and stock file info for each file int realCount = 0; for (int i = 0; i < saveDataListCount; i++) { DEBUG_LOG(HLE,"Name : %s",saveNameListData[i]); std::string fileDataPath = savePath+GetGameName(param)+saveNameListData[i]+"/"+param->fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); if (info.exists) { SetFileInfo(realCount, info, saveNameListData[i]); DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); realCount++; } else { if (listEmptyFile) { saveDataList[realCount].size = 0; saveDataList[realCount].saveName = saveNameListData[i]; saveDataList[realCount].idx = i; saveDataList[realCount].textureData = 0; if(Memory::IsValidAddress(param->newData)) { // We have a png to show PspUtilitySavedataFileData newData; Memory::ReadStruct(param->newData, &newData); CreatePNGIcon(Memory::GetPointer(newData.buf), (int)newData.size, saveDataList[realCount]); } DEBUG_LOG(HLE,"Don't Exist"); realCount++; } } } saveNameListDataCount = realCount; } } if(!hasMultipleFileName) // Load info on only save { saveNameListData = 0; Clear(); saveDataList = new SaveFileInfo[1]; saveDataListCount = 1; // get and stock file info for each file DEBUG_LOG(HLE,"Name : %s",GetSaveName(param).c_str()); std::string fileDataPath = savePath+GetGameName(param)+GetSaveName(param)+"/"+param->fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); if (info.exists) { SetFileInfo(0, info, GetSaveName(pspParam)); DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); saveNameListDataCount = 1; } else { if (listEmptyFile) { saveDataList[0].size = 0; saveDataList[0].saveName = GetSaveName(param); saveDataList[0].idx = 0; saveDataList[0].textureData = 0; if(Memory::IsValidAddress(param->newData)) { // We have a png to show PspUtilitySavedataFileData newData; Memory::ReadStruct(param->newData, &newData); CreatePNGIcon(Memory::GetPointer(newData.buf), (int)newData.size, saveDataList[0]); } DEBUG_LOG(HLE,"Don't Exist"); } saveNameListDataCount = 0; return 0; } } return 0; }
int SavedataParam::GetFilesList(SceUtilitySavedataParam *param) { if (!param) { return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_STATUS; } if (!param->fileList.Valid()) { ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): bad fileList address %08x", param->fileList.ptr); // Should crash. return -1; } auto &fileList = param->fileList; if (fileList->secureEntries.Valid() && fileList->maxSecureEntries > 99) { ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): too many secure entries, %d", fileList->maxSecureEntries); return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_PARAMS; } if (fileList->normalEntries.Valid() && fileList->maxNormalEntries > 8192) { ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): too many normal entries, %d", fileList->maxNormalEntries); return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_PARAMS; } if (fileList->systemEntries.Valid() && fileList->maxSystemEntries > 5) { ERROR_LOG_REPORT(HLE, "SavedataParam::GetFilesList(): too many system entries, %d", fileList->maxSystemEntries); return SCE_UTILITY_SAVEDATA_ERROR_RW_BAD_PARAMS; } std::string dirPath = savePath + GetGameName(param) + GetSaveName(param); if (!pspFileSystem.GetFileInfo(dirPath).exists) { DEBUG_LOG(HLE, "SavedataParam::GetFilesList(): directory %s does not exist", dirPath.c_str()); return SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; } // Even if there are no files, initialize to 0. fileList->resultNumSecureEntries = 0; fileList->resultNumNormalEntries = 0; fileList->resultNumSystemEntries = 0; // We need PARAMS.SFO's SAVEDATA_FILE_LIST to determine which entries are secure. PSPFileInfo sfoFileInfo = pspFileSystem.GetFileInfo(dirPath + "/" + SFO_FILENAME); std::set<std::string> secureFilenames; // TODO: Error code if not? if (sfoFileInfo.exists) { ParamSFOData sfoFile; size_t sfoSize = (size_t)sfoFileInfo.size; u8 *sfoData = new u8[sfoSize]; if (ReadPSPFile(dirPath + "/" + SFO_FILENAME, &sfoData, sfoSize, NULL)){ sfoFile.ReadSFO(sfoData, sfoSize); } delete[] sfoData; u32 sfoFileListSize = 0; char *sfoFileList = (char *)sfoFile.GetValueData("SAVEDATA_FILE_LIST", &sfoFileListSize); const int FILE_LIST_ITEM_SIZE = 13 + 16 + 3; const int FILE_LIST_COUNT_MAX = 99; // Filenames are 13 bytes long at most. Add a NULL so there's no surprises. char temp[14]; temp[13] = '\0'; for (u32 i = 0; i < FILE_LIST_COUNT_MAX; ++i) { // Ends at a NULL filename. if (i * FILE_LIST_ITEM_SIZE >= sfoFileListSize || sfoFileList[i * FILE_LIST_ITEM_SIZE] == '\0') { break; } strncpy(temp, &sfoFileList[i * FILE_LIST_ITEM_SIZE], 13); secureFilenames.insert(temp); } } // Does not list directories, nor recurse into them, and ignores files not ALL UPPERCASE. auto files = pspFileSystem.GetDirListing(dirPath); for (auto file = files.begin(), end = files.end(); file != end; ++file) { if (file->type == FILETYPE_DIRECTORY) { continue; } // TODO: What are the exact rules? It definitely skips lowercase, and allows FILE or FILE.EXT. if (file->name.find_first_of("abcdefghijklmnopqrstuvwxyz") != file->name.npos) { DEBUG_LOG(HLE, "SavedataParam::GetFilesList(): skipping file %s with lowercase", file->name.c_str()); continue; } bool isSystemFile = file->name == ICON0_FILENAME || file->name == ICON1_FILENAME || file->name == PIC1_FILENAME; isSystemFile = isSystemFile || file->name == SND0_FILENAME || file->name == SFO_FILENAME; SceUtilitySavedataFileListEntry *entry = NULL; int sizeOffset = 0; if (isSystemFile) { if (fileList->systemEntries.Valid() && fileList->resultNumSystemEntries < fileList->maxSystemEntries) { entry = &fileList->systemEntries[fileList->resultNumSystemEntries++]; } } else if (secureFilenames.find(file->name) != secureFilenames.end()) { if (fileList->secureEntries.Valid() && fileList->resultNumSecureEntries < fileList->maxSecureEntries) { entry = &fileList->secureEntries[fileList->resultNumSecureEntries++]; } // Secure files are slightly bigger. bool isCrypted = IsSaveEncrypted(param, GetSaveDirName(param, 0)); if (isCrypted) { sizeOffset = -0x10; } } else { if (fileList->normalEntries.Valid() && fileList->resultNumNormalEntries < fileList->maxNormalEntries) { entry = &fileList->normalEntries[fileList->resultNumNormalEntries++]; } } // Out of space for this file in the list. if (entry == NULL) { continue; } entry->st_mode = 0x21FF; entry->st_size = file->size + sizeOffset; // TODO: ctime, atime, mtime // TODO: Probably actually 13 + 3 pad... strncpy(entry->name, file->name.c_str(), 16); entry->name[15] = '\0'; } return 0; }
int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) { pspParam = param; if (!pspParam) { Clear(); return 0; } bool listEmptyFile = true; if (param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD || param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE) { listEmptyFile = false; } SceUtilitySavedataSaveName *saveNameListData; bool hasMultipleFileName = false; if (param->saveNameList.Valid()) { Clear(); saveNameListData = param->saveNameList; // Get number of fileName in array saveDataListCount = 0; while (saveNameListData[saveDataListCount][0] != 0) { saveDataListCount++; } if (saveDataListCount > 0) { hasMultipleFileName = true; saveDataList = new SaveFileInfo[saveDataListCount]; // get and stock file info for each file int realCount = 0; for (int i = 0; i < saveDataListCount; i++) { // TODO: Maybe we should fill the list with existing files instead? if (strcmp(saveNameListData[i], "<>") == 0) continue; DEBUG_LOG(HLE,"Name : %s",saveNameListData[i]); std::string fileDataPath = savePath+GetGameName(param) + saveNameListData[i] + "/" + param->fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); if (info.exists) { SetFileInfo(realCount, info, saveNameListData[i]); DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); realCount++; } else { if (listEmptyFile) { ClearFileInfo(saveDataList[realCount], saveNameListData[i]); DEBUG_LOG(HLE,"Don't Exist"); realCount++; } } } saveNameListDataCount = realCount; } } if (!hasMultipleFileName) // Load info on only save { saveNameListData = 0; Clear(); saveDataList = new SaveFileInfo[1]; saveDataListCount = 1; // get and stock file info for each file DEBUG_LOG(HLE,"Name : %s",GetSaveName(param).c_str()); std::string fileDataPath = savePath + GetGameName(param) + GetSaveName(param) + "/" + param->fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); if (info.exists) { SetFileInfo(0, info, GetSaveName(param)); DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str()); saveNameListDataCount = 1; } else { if (listEmptyFile) { ClearFileInfo(saveDataList[0], GetSaveName(param)); DEBUG_LOG(HLE,"Don't Exist"); } saveNameListDataCount = 0; return 0; } } return 0; }