DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) { int my_ret = -1; error = 0xffffffff; if ((int)bss_ptr != 0x0a000000) { int client = client_num(pClient); if (client < MAX_CLIENT && client >= 0) { int ret; my_ret = cafiine_fopen(bss.socket_fsa[client], &ret, path, mode, handle); if (my_ret == 0) { // File exists in cafiine server, a new handle has been created return ret; } else if (my_ret >= 1) { // File has been requested from cafiine server, ret = real_FSOpenFile(pClient, pCmd, path, mode, handle, error); if (ret >= 0) { int size = (my_ret == 1 ? DUMP_BLOCK_SIZE : DUMP_BLOCK_SIZE_SLOW); cafiine_send_handle(bss.socket_fsa[client], client, path, *handle); void* buffer = memalign(sizeof(char) * size, 0x40); int ret2; while ((ret2 = real_FSReadFile(pClient, pCmd, buffer, 1, size, *handle, 0, error)) > 0) cafiine_send_file(bss.socket_fsa[client], buffer, ret2, *handle); cafiine_fclose(bss.socket_fsa[client], &ret2, *handle); real_FSSetPosFile(pClient, pCmd, *handle, 0, error); } return ret; } } } return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); }
DECL(int, FSOpenFile, void *pClient, void *pCmd, char *path, char *mode, int *handle, int error) { int client = GetCurClient(pClient); if (client != -1) { // log log_string(bss.socket_fs[client], path, BYTE_OPEN_FILE); // change path if it is a game file int is_save = 0; if (is_gamefile(path) || (is_save = is_savefile(path))) { int len = strlen(path); int len_base = (is_save ? (strlen(bss.save_base) + 8) : strlen(bss.mount_base)); char new_path[len + len_base + 1]; compute_new_path(new_path, path, len, is_save); // log new path log_string(bss.socket_fs[client], new_path, BYTE_LOG_STR); return real_FSOpenFile(pClient, pCmd, new_path, mode, handle, error); } } return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); }
DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) { if ((int)bss_ptr != 0x0a000000) { int client = client_num(pClient); if (client < MAX_CLIENT && client >= 0) { int ret; if (cafiine_fopen(bss.socket_fsa[client], &ret, path, mode, handle) == 0) { return ret; } } } return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); }
/* ***************************************************************************** * Dynamic RPL loading to memory * ****************************************************************************/ static int LoadRPLToMemory(s_rpx_rpl *rpl_entry) { if ((int)bss_ptr != 0x0a000000) { char buffer[200]; __os_snprintf(buffer, sizeof(buffer), "CheckAndLoadRPL(%s) found and loading", rpl_entry->name); log_string(bss.global_sock, buffer, BYTE_LOG_STR); } // initialize FS FSInit(); FSClient *pClient = (FSClient*) MEMAllocFromDefaultHeap(sizeof(FSClient)); if (!pClient) return 0; FSCmdBlock *pCmd = (FSCmdBlock*) MEMAllocFromDefaultHeap(sizeof(FSCmdBlock)); if (!pCmd) { MEMFreeToDefaultHeap(pClient); return 0; } // calculate path length for SD access of RPL int path_len = strlen(CAFE_OS_SD_PATH) + strlen(SD_GAMES_PATH) + strlen(GAME_DIR_NAME) + strlen(RPX_RPL_PATH) + strlen(rpl_entry->name) + 3; char *path_rpl = MEMAllocFromDefaultHeap(path_len); if(!path_rpl) { MEMFreeToDefaultHeap(pCmd); MEMFreeToDefaultHeap(pClient); return 0; } // create path __os_snprintf(path_rpl, path_len, "%s%s/%s%s/%s", CAFE_OS_SD_PATH, SD_GAMES_PATH, GAME_DIR_NAME, RPX_RPL_PATH, rpl_entry->name); // malloc mem for read file unsigned char* dataBuf = (unsigned char*)MEMAllocFromDefaultHeapEx(0x1000, 0x40); if(!dataBuf) { MEMFreeToDefaultHeap(pCmd); MEMFreeToDefaultHeap(pClient); MEMFreeToDefaultHeap(path_rpl); return 0; } // do more initial FS stuff FSInitCmdBlock(pCmd); FSAddClientEx(pClient, 0, FS_RET_NO_ERROR); // set RPL size to 0 to avoid wrong RPL being loaded when opening file fails rpl_entry->size = 0; rpl_entry->offset = 0; int fd = 0; if (real_FSOpenFile(pClient, pCmd, path_rpl, "r", &fd, FS_RET_ALL_ERROR) == FS_STATUS_OK) { int ret; int rpl_size = 0; // Get current memory area s_mem_area* mem_area = (s_mem_area*)(MEM_AREA_ARRAY); int mem_area_addr_start = mem_area->address; int mem_area_addr_end = mem_area->address + mem_area->size; int mem_area_offset = 0; // Copy rpl in memory while ((ret = FSReadFile(pClient, pCmd, dataBuf, 0x1, 0x1000, fd, 0, FS_RET_ALL_ERROR)) > 0) { // Copy in memory and save offset for (int j = 0; j < ret; j++) { if ((mem_area_addr_start + mem_area_offset) >= mem_area_addr_end) { // Set next memory area mem_area = mem_area->next; mem_area_addr_start = mem_area->address; mem_area_addr_end = mem_area->address + mem_area->size; mem_area_offset = 0; } *(volatile unsigned char*)(mem_area_addr_start + mem_area_offset) = dataBuf[j]; mem_area_offset += 1; } rpl_size += ret; } // Fill rpl entry rpl_entry->area = (s_mem_area*)(MEM_AREA_ARRAY); rpl_entry->offset = 0; rpl_entry->size = rpl_size; // flush memory // DCFlushRange((void*)rpl_entry, sizeof(s_rpx_rpl)); // DCFlushRange((void*)rpl_entry->address, rpl_entry->size); if ((int)bss_ptr != 0x0a000000) { char buffer[200]; __os_snprintf(buffer, sizeof(buffer), "CheckAndLoadRPL(%s) file loaded 0x%08X %i", rpl_entry->name, rpl_entry->area->address, rpl_entry->size); log_string(bss.global_sock, buffer, BYTE_LOG_STR); } FSCloseFile(pClient, pCmd, fd, FS_RET_NO_ERROR); } FSDelClient(pClient); MEMFreeToDefaultHeap(dataBuf); MEMFreeToDefaultHeap(pCmd); MEMFreeToDefaultHeap(pClient); MEMFreeToDefaultHeap(path_rpl); return 1; }