private SearchEntry[] Find(SceSaveDataDirNameSearchCond searchCond, SceSaveDataDirNameSearchResult searchResult) { var searchCondAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult))); var searchResultAddr = searchCondAddr + (uint)Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)); ps4.WriteMemory(pid, searchCondAddr, searchCond); ps4.WriteMemory(pid, searchResultAddr, searchResult); var ret = ps4.Call(pid, stub, libSceSaveDataBase + offsets.sceSaveDataDirNameSearch, searchCondAddr, searchResultAddr); WriteLog($"sceSaveDataDirNameSearch ret = 0x{ret:X}"); if (ret == 0) { searchResult = ps4.ReadMemory <SceSaveDataDirNameSearchResult>(pid, searchResultAddr); SearchEntry[] sEntries = new SearchEntry[searchResult.hitNum]; var paramMemory = ps4.ReadMemory(pid, searchResult.param, (int)searchResult.hitNum * Marshal.SizeOf(typeof(SceSaveDataParam))); var dirNamesMemory = ps4.ReadMemory(pid, searchResult.dirNames, (int)searchResult.hitNum * 32); for (int i = 0; i < searchResult.hitNum; i++) { SceSaveDataParam tmp = (SceSaveDataParam)PS4DBG.GetObjectFromBytes(PS4DBG.SubArray(paramMemory, i * Marshal.SizeOf(typeof(SceSaveDataParam)), Marshal.SizeOf(typeof(SceSaveDataParam))), typeof(SceSaveDataParam)); sEntries[i] = new SearchEntry { dirName = System.Text.Encoding.UTF8.GetString(PS4DBG.SubArray(dirNamesMemory, i * 32, 32)), title = System.Text.Encoding.UTF8.GetString(tmp.title), subtitle = System.Text.Encoding.UTF8.GetString(tmp.subTitle), detail = System.Text.Encoding.UTF8.GetString(tmp.detail), time = new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(tmp.mtime).ToString(), }; } ps4.FreeMemory(pid, searchCondAddr, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult))); return(sEntries); } ps4.FreeMemory(pid, searchCondAddr, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult))); return(new SearchEntry[0]); }