// ================================================== Result FS_loadFile(char* path, void* dst, FS_archive* fsArchive, Handle* fsHandle, u64 maxSize, u32* bytesRead) // -------------------------------------------------- { if (!path || !dst || !fsArchive) return -1; Result ret = 0; u64 size; Handle fileHandle; if (!ret) { ret = FSUSER_OpenFile(fsHandle, &fileHandle, *fsArchive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if (ret) return ret; } if (!ret) { ret = FSFILE_GetSize(fileHandle, &size); if (ret || size > maxSize) ret = -2; } if (!ret) { ret = FSFILE_Read(fileHandle, bytesRead, 0, dst, size); if (ret || *bytesRead < size) ret=-3; } FSFILE_Close(fileHandle); return ret; }
Result getFile(u8 ** buffer, u64 * size) { Result ret = 0; Handle filehandle = 0; u32 tmpval = 0; ret = FSUSER_OpenFile(&filehandle, extdata_archive, verListPath, FS_OPEN_READ, 0); if (ret != 0) return ret; ret = FSFILE_GetSize(filehandle, size); if (ret != 0) return ret; if (*size <= ENTRY_SIZE) { *size = 0; return ret; } if (mode == MODE_ALL) *size = ENTRY_SIZE; *buffer = malloc(*size); ret = FSFILE_Read(filehandle, &tmpval, 0, *buffer, *size); if (ret != 0) return ret; FSFILE_Close(filehandle); return ret; }
Result FS_ReadFile(const char* path, void* dst, u64 maxSize, FS_Archive archive, u32* bytesRead) { if (!path || !dst || !archive || !bytesRead) return -1; Result ret; u64 size; Handle fileHandle; debug_print("FS_ReadFile:\n"); ret = FSUSER_OpenFile(&fileHandle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); r(" > FSUSER_OpenFile: %lx\n", ret); if (R_FAILED(ret)) return ret; ret = FSFILE_GetSize(fileHandle, &size); r(" > FSFILE_GetSize: %lx\n", ret); if (R_FAILED(ret) || size > maxSize) ret = -2; if (R_SUCCEEDED(ret)) { ret = FSFILE_Read(fileHandle, bytesRead, 0x0, dst, size); r(" > FSFILE_Read: %lx\n", ret); if (R_FAILED(ret) || *bytesRead < size) ret = -3; } FSFILE_Close(fileHandle); r(" > FSFILE_Close\n"); return ret; }
Result archive_getfilesize(Archive archive, char *path, u32 *outsize) { Result ret=0; struct stat filestats; u64 tmp64=0; Handle filehandle=0; char filepath[256]; if(archive==SDArchive) { memset(filepath, 0, 256); strncpy(filepath, path, 255); if(stat(filepath, &filestats)==-1)return errno; *outsize = filestats.st_size; return 0; } ret = FSUSER_OpenFile(NULL, &filehandle, extdata_archive, FS_makePath(PATH_CHAR, path), 1, 0); if(ret!=0)return ret; ret = FSFILE_GetSize(filehandle, &tmp64); if(ret==0)*outsize = (u32)tmp64; FSFILE_Close(filehandle); return ret; }
static bool ndspFindAndLoadComponent(void) { Result rc; Handle rsrc; void* bin; componentProgMask = 0xFF; componentDataMask = 0xFF; // Try loading the DSP component from the filesystem do { static const char dsp_filename[] = "/3ds/dspfirm.cdc"; FS_Archive arch = { ARCHIVE_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0 }; FS_Path path = { PATH_ASCII, sizeof(dsp_filename), (u8*)dsp_filename }; rc = FSUSER_OpenFileDirectly(&rsrc, arch, path, FS_OPEN_READ, 0); if (R_FAILED(rc)) break; u64 size = 0; rc = FSFILE_GetSize(rsrc, &size); if (R_FAILED(rc)) { FSFILE_Close(rsrc); break; } bin = malloc(size); if (!bin) { FSFILE_Close(rsrc); break; } u32 dummy = 0; rc = FSFILE_Read(rsrc, &dummy, 0, bin, size); FSFILE_Close(rsrc); if (R_FAILED(rc)) { free(bin); return false; } componentBin = bin; componentSize = size; componentFree = true; return true; } while (0); // Try loading the DSP component from hb:ndsp rsrc = envGetHandle("hb:ndsp"); if (rsrc) do { extern u32 fake_heap_end; u32 mapAddr = (fake_heap_end+0xFFF) &~ 0xFFF; rc = svcMapMemoryBlock(rsrc, mapAddr, 0x3, 0x3); if (R_FAILED(rc)) break; componentSize = *(u32*)(mapAddr + 0x104); bin = malloc(componentSize); if (bin) memcpy(bin, (void*)mapAddr, componentSize); svcUnmapMemoryBlock(rsrc, mapAddr); if (!bin) break; componentBin = bin; componentFree = true; return true; } while (0); return false; }
void NES_LoadSelectedGame() { u32 bytesRead = 0; u32 SRAM_Size = 0; u32 ROMDIR_Size = (strlen("/3DNES/ROMS/") + strlen(fileSystem.fileList[fileSystem.currFile]) + 1); Handle fileHandle; CPU_Running = false; /* Alloc ROM Directory */ char ROM_DIR[ROMDIR_Size]; /* Clear ROM_Dir */ memset(ROM_DIR, 0x0, ROMDIR_Size); //FS_StringConc(ROM_DIR, "/3DNES/ROMS/", fileSystem.fileList[fileSystem.currFile]); /* TODO: FIX IT /*if (SRAM_Name != NULL) { linearFree(SRAM_Name); SRAM_Size = (strlen(fileSystem.fileList[fileSystem.currFile]) - 4); SRAM_Name = linearAlloc(SRAM_Size); strncpy((char*)SRAM_Name, fileSystem.fileList[fileSystem.currFile], SRAM_Size); } */ FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, FS_makePath(PATH_CHAR, ROM_DIR), FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_GetSize(fileHandle, &ROM_Size); FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)ROM_Cache, (u32)ROM_Size); FSFILE_Close(fileHandle); /* Start Emulation */ inGame = true; }
u8* loadSmdh(u64 tid, u8 mediatype) { Result ret; Handle fileHandle; u32 archivePath[] = {tid & 0xFFFFFFFF, (tid >> 32) & 0xFFFFFFFF, mediatype, 0x00000000}; static const u32 filePath[] = {0x00000000, 0x00000000, 0x00000002, 0x6E6F6369, 0x00000000}; // icon ret = FSUSER_OpenFileDirectly(NULL, &fileHandle, (FS_archive){0x2345678a, (FS_path){PATH_BINARY, 0x10, (u8*)archivePath}}, (FS_path){PATH_BINARY, 0x14, (u8*)filePath}, FS_OPEN_READ, FS_ATTRIBUTE_NONE); printf("loading smdh : %08X\n", (unsigned int)ret); u8* fileBuffer = NULL; u64 fileSize = 0; { u32 bytesRead; ret = FSFILE_GetSize(fileHandle, &fileSize); if(ret)return NULL; fileBuffer = malloc(fileSize); if(ret)return NULL; ret = FSFILE_Read(fileHandle, &bytesRead, 0x0, fileBuffer, fileSize); if(ret)return NULL; ret = FSFILE_Close(fileHandle); if(ret)return NULL; printf("loaded code : %08X\n", (unsigned int)fileSize); } return fileBuffer; }
Result IFile_GetSize(IFile *file, u64 *size) { Result res; res = FSFILE_GetSize(file->handle, size); file->size = *size; return res; }
/*! Write to an open file * * @param[in,out] r newlib reentrancy struct * @param[in,out] fd Pointer to sdmc_file_t * @param[in] ptr Pointer to data to write * @param[in] len Length of data to write * * @returns number of bytes written * @returns -1 for error */ static ssize_t sdmc_write(struct _reent *r, int fd, const char *ptr, size_t len) { Result rc; u32 bytes; u32 sync = 0; u64 offset; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fd; /* check that the file was opened with write access */ if((file->flags & O_ACCMODE) == O_RDONLY) { r->_errno = EBADF; return -1; } /* check if this is synchronous or not */ if(file->flags & O_SYNC) sync = 0x10001; /* initialize offset */ offset = file->offset; if(file->flags & O_APPEND) { /* append means write from the end of the file */ rc = FSFILE_GetSize(file->fd, &offset); if(rc != 0) { r->_errno = rc; return -1; } } /* TODO: Copy to internal buffer and write in chunks. * You cannot write from read-only memory. */ /* write the data */ rc = FSFILE_Write(file->fd, &bytes, offset, (u32*)ptr, (u32)len, sync); if(rc == 0) { /* update current file offset; if O_APPEND, this moves it to the * new end-of-file */ file->offset = offset + bytes; return (ssize_t)bytes; } r->_errno = rc; return -1; }
/*! Update an open file's current offset * * @param[in,out] r newlib reentrancy struct * @param[in,out] fd Pointer to sdmc_file_t * @param[in] pos Offset to seek to * @param[in] whence Where to seek from * * @returns new offset for success * @returns -1 for error */ static off_t sdmc_seek(struct _reent *r, void *fd, off_t pos, int whence) { Result rc; u64 offset; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fd; /* find the offset to see from */ switch(whence) { /* set absolute position; start offset is 0 */ case SEEK_SET: offset = 0; break; /* set position relative to the current position */ case SEEK_CUR: offset = file->offset; break; /* set position relative to the end of the file */ case SEEK_END: rc = FSFILE_GetSize(file->fd, &offset); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } break; /* an invalid option was provided */ default: r->_errno = EINVAL; return -1; } /* TODO: A better check that prevents overflow. */ if(pos < 0 && offset < -pos) { /* don't allow seek to before the beginning of the file */ r->_errno = EINVAL; return -1; } /* update the current offset */ file->offset = offset + pos; return file->offset; }
/*! Write to an open file * * @param[in,out] r newlib reentrancy struct * @param[in,out] fd Pointer to sdmc_file_t * @param[in] ptr Pointer to data to write * @param[in] len Length of data to write * * @returns number of bytes written * @returns -1 for error */ static ssize_t sdmc_write(struct _reent *r, void *fd, const char *ptr, size_t len) { Result rc; u32 bytes; u32 sync = 0; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fd; /* check that the file was opened with write access */ if((file->flags & O_ACCMODE) == O_RDONLY) { r->_errno = EBADF; return -1; } /* check if this is synchronous or not */ if(file->flags & O_SYNC) sync = FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME; if(file->flags & O_APPEND) { /* append means write from the end of the file */ rc = FSFILE_GetSize(file->fd, &file->offset); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } } rc = FSFILE_Write(file->fd, &bytes, file->offset, (u32*)ptr, len, sync); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } file->offset += bytes; return bytes; }
static int installCia(Handle ciaFile){ Result failed; Handle outputHandle; u64 fileSize; u64 fileOffset = 0; u32 bytesRead; u32 bytesWritten; u8 transferBuffer[FILE_CHUNK_SIZE]; failed = AM_StartCiaInstall(MEDIATYPE_SD, &outputHandle); if(R_FAILED(failed)) return -1; failed = FSFILE_GetSize(ciaFile, &fileSize); if(R_FAILED(failed)) return -1; while(fileOffset < fileSize){ u64 bytesRemaining = fileSize - fileOffset; failed = FSFILE_Read(ciaFile, &bytesRead, fileOffset, transferBuffer, bytesRemaining < FILE_CHUNK_SIZE ? bytesRemaining : FILE_CHUNK_SIZE); if(R_FAILED(failed)){ AM_CancelCIAInstall(outputHandle); return -1; } failed = FSFILE_Write(outputHandle, &bytesWritten, fileOffset, transferBuffer, bytesRead, 0); if(R_FAILED(failed)){ AM_CancelCIAInstall(outputHandle); if(R_DESCRIPTION(failed) == RD_ALREADY_EXISTS) return 1; return -1; } if(bytesWritten != bytesRead){ AM_CancelCIAInstall(outputHandle); return -1; } fileOffset += bytesWritten; } failed = AM_FinishCiaInstall(outputHandle); if(R_FAILED(failed)) return -1; return 1; }
off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) { struct VFile3DS* vf3d = (struct VFile3DS*) vf; u64 size; switch (whence) { case SEEK_SET: vf3d->offset = offset; break; case SEEK_END: FSFILE_GetSize(vf3d->handle, &size); vf3d->offset = size; // Fall through case SEEK_CUR: vf3d->offset += offset; break; } return vf3d->offset; }
void DumpSharedRomFS(u8* archive_binary_lowpath) { std::string output_file = BuildSharedRomFSFilename(archive_binary_lowpath); // Read RomFS bin from SaveDataCheck... Handle romfs_handle; u64 romfs_size = 0; u32 romfs_bytes_read = 0; FS_archive savedatacheck_archive = { 0x2345678a, { PATH_BINARY, 16, archive_binary_lowpath } }; u8 file_binary_lowpath[20] = {}; FS_path romfs_path = { PATH_BINARY, 20, file_binary_lowpath }; print(GFX_TOP, "Dumping SaveDataCheck RomFS (%s)... ", output_file.c_str()); FSUSER_OpenFileDirectly(NULL, &romfs_handle, savedatacheck_archive, romfs_path, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_GetSize(romfs_handle, &romfs_size); std::unique_ptr<u8> romfs_data_buffer(new u8[romfs_size]); FSFILE_Read(romfs_handle, &romfs_bytes_read, 0, romfs_data_buffer.get(), romfs_size); FSFILE_Close(romfs_handle); // Dump RomFS bin to SDMC... Handle file_handle; u32 bytes_written = 0; FS_path fs_path = FS_makePath(PATH_CHAR, output_file.c_str()); FS_archive sdmc_archive = (FS_archive) { 0x00000009, { PATH_EMPTY, 1, (u8*) "" } }; FSUSER_OpenArchive(NULL, &sdmc_archive); FSUSER_OpenFile(NULL, &file_handle, sdmc_archive, fs_path, FS_OPEN_CREATE | FS_OPEN_WRITE, FS_ATTRIBUTE_NONE); Result res = FSFILE_Write(file_handle, &bytes_written, 0x0, romfs_data_buffer.get(), romfs_size, FS_WRITE_FLUSH); FSFILE_Close(file_handle); FSUSER_CloseArchive(NULL, &sdmc_archive); // Check result... if (res == 0 && bytes_written == romfs_size) print(GFX_TOP, "Done!\n"); else print(GFX_TOP, "Failed!\n"); }
/*! Get file stats from an open file * * @param[in,out] r newlib reentrancy struct * @param[in] fd Pointer to sdmc_file_t * @param[out] st Pointer to file stats to fill * * @returns 0 for success * @returns -1 for error */ static int sdmc_fstat(struct _reent *r, void *fd, struct stat *st) { Result rc; u64 size; sdmc_file_t *file = (sdmc_file_t*)fd; rc = FSFILE_GetSize(file->fd, &size); if(R_SUCCEEDED(rc)) { memset(st, 0, sizeof(struct stat)); st->st_size = (off_t)size; st->st_nlink = 1; st->st_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; return 0; } r->_errno = sdmc_translate_error(rc); return -1; }
static int lua_loadBMPV(lua_State *L) { int argc = lua_gettop(L); if (argc != 1) return luaL_error(L, "wrong number of arguments"); const char *file_tbo = luaL_checkstring(L, 1); Handle fileHandle; FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}}; FS_path filePath=FS_makePath(PATH_CHAR, file_tbo); Result ret=FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(ret) return luaL_error(L, "error opening file"); u32 magic,frame_size,bytesRead; u64 size; FSFILE_GetSize(fileHandle, &size); FSFILE_Read(fileHandle, &bytesRead, 0, &magic, 4); if (magic == 0x56504D42){ BMPV* BMPV_file = (BMPV*)malloc(sizeof(BMPV)); FSFILE_Read(fileHandle, &bytesRead, 4, &(BMPV_file->framerate), 4); FSFILE_Read(fileHandle, &bytesRead, 8, &(BMPV_file->width), 4); FSFILE_Read(fileHandle, &bytesRead, 12,&(BMPV_file->height), 4); if (!GW_MODE) FSFILE_Read(fileHandle, &bytesRead, 16,&(BMPV_file->audiotype), 2); FSFILE_Read(fileHandle, &bytesRead, 18,&(BMPV_file->bytepersample), 2); FSFILE_Read(fileHandle, &bytesRead, 20,&(BMPV_file->samplerate), 4); FSFILE_Read(fileHandle, &bytesRead, 24,&(BMPV_file->audio_size), 4); BMPV_file->isPlaying = false; BMPV_file->currentFrame = 0; BMPV_file->sourceFile = fileHandle; BMPV_file->tick = 0; BMPV_file->audiobuf = NULL; BMPV_file->audiobuf2 = NULL; frame_size = BMPV_file->width*BMPV_file->height*3; u8* framebuf = (u8*)(malloc(frame_size)); BMPV_file->framebuf = framebuf; int tot_frame = (size-28-BMPV_file->audio_size)/frame_size; BMPV_file->mem_size = BMPV_file->audio_size; BMPV_file->tot_frame = tot_frame; lua_pushnumber(L, (u32)BMPV_file); } return 1; }
int loadFile(char* path, void* dst, FS_archive* archive, u64 maxSize) { if(!path || !dst || !archive)return -1; u64 size; u32 bytesRead; Result ret; Handle fileHandle; ret=FSUSER_OpenFile(&fileHandle, *archive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(ret!=0)return ret; ret=FSFILE_GetSize(fileHandle, &size); if(ret!=0)goto loadFileExit; if(size>maxSize){ret=-2; goto loadFileExit;} ret=FSFILE_Read(fileHandle, &bytesRead, 0x0, dst, size); if(ret!=0)goto loadFileExit; if(bytesRead<size){ret=-3; goto loadFileExit;} loadFileExit: FSFILE_Close(fileHandle); return ret; }
Result read_savedata(const char* path, void** data, size_t* size) { if(!path || !data || !size) return -1; Result ret = -1; int fail = 0; void* buffer = NULL; fsUseSession(save_session); ret = FSUSER_OpenArchive(&save_archive, ARCHIVE_SAVEDATA, (FS_Path){PATH_EMPTY, 1, (u8*)""}); if(R_FAILED(ret)) { fail = -1; goto readFail; } Handle file = 0; ret = FSUSER_OpenFile(&file, save_archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, 0); if(R_FAILED(ret)) { fail = -2; goto readFail; } u64 file_size = 0; ret = FSFILE_GetSize(file, &file_size); buffer = malloc(file_size); if(!buffer) { fail = -3; goto readFail; } u32 bytes_read = 0; ret = FSFILE_Read(file, &bytes_read, 0, buffer, file_size); if(R_FAILED(ret)) { fail = -4; goto readFail; } ret = FSFILE_Close(file); if(R_FAILED(ret)) { fail = -5; goto readFail; } readFail: FSUSER_CloseArchive(save_archive); fsEndUseSession(); if(fail) { sprintf(status, "Failed to read file: %d\n %08lX %08lX", fail, ret, bytes_read); if(buffer) free(buffer); } else { sprintf(status, "Successfully read file.\n %08lX ", bytes_read); *data = buffer; *size = bytes_read; } return ret; }
/*! Write to an open file * * @param[in,out] r newlib reentrancy struct * @param[in,out] fd Pointer to sdmc_file_t * @param[in] ptr Pointer to data to write * @param[in] len Length of data to write * * @returns number of bytes written * @returns -1 for error */ static ssize_t sdmc_write_safe(struct _reent *r, void *fd, const char *ptr, size_t len) { Result rc; u32 bytes, bytesWritten = 0; u32 sync = 0; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fd; /* check that the file was opened with write access */ if((file->flags & O_ACCMODE) == O_RDONLY) { r->_errno = EBADF; return -1; } /* check if this is synchronous or not */ if(file->flags & O_SYNC) sync = FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME; if(file->flags & O_APPEND) { /* append means write from the end of the file */ rc = FSFILE_GetSize(file->fd, &file->offset); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } } /* Copy to internal buffer and write in chunks. * You cannot write from read-only memory. */ static __thread char tmp_buffer[8192]; while(len > 0) { size_t toWrite = len; if(toWrite > sizeof(tmp_buffer)) toWrite = sizeof(tmp_buffer); /* copy to internal buffer */ memcpy(tmp_buffer, ptr, toWrite); /* write the data */ rc = FSFILE_Write(file->fd, &bytes, file->offset, (u32*)tmp_buffer, (u32)toWrite, sync); if(R_FAILED(rc)) { /* return partial transfer */ if(bytesWritten > 0) return bytesWritten; r->_errno = sdmc_translate_error(rc); return -1; } file->offset += bytes; bytesWritten += bytes; ptr += bytes; len -= bytes; } return bytesWritten; }
static Result action_paste_files_get_src_size(void* data, u32 handle, u64* size) { return FSFILE_GetSize(handle, size); }
int main(int argc, char **argv) { srvInit(); aptInit(); gfxInitDefault(); acInit(); cfguInit(); httpcInit(); ptmuInit(); hidInit(); irrstInit(); aptOpenSession(); Result ret=APT_SetAppCpuTimeLimit(30); aptCloseSession(); fsInit(); ftp_state = false; isTopLCDOn = true; isBottomLCDOn = true; Handle fileHandle; u64 size; u32 bytesRead; int restore; // Check user build and enables kernel access if (nsInit()==0){ CIA_MODE = true; nsExit(); }else CIA_MODE = false; isNinjhax2 = false; if (!hbInit()) khaxInit(); else isNinjhax2 = true; // Select Audio System (csnd:SND preferred) if (csndInit() == 0){ csndAccess = true; csndExit(); }else csndAccess = false; // Init Audio-Device int i = 0; for (i=0;i < 32; i++){ audioChannels[i] = false; if (!isNinjhax2 && (i < 0x08)) audioChannels[i] = true; else if (csndAccess && (i < 0x08)) audioChannels[i] = true; } // Set main script char path[256]; if (argc > 0){ int latest_slash = 0; int i=5; while (argv[0][i] != '\0'){ if (argv[0][i] == '/') latest_slash = i; i++; } strcpy(path,&argv[0][5]); path[latest_slash-5] = 0; strcpy(start_dir,path); strcpy(cur_dir,path); // Set current dir strcat(path,"/index.lua"); }else{ strcpy(start_dir,"/"); strcpy(cur_dir,"/"); // Set current dir for GW Mode strcpy(path,"/index.lua"); } while(aptMainLoop()) { restore=0; char error[2048]; // Load main script FS_Path filePath=fsMakePath(PATH_ASCII, path); FS_Archive script=(FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}}; Result ret = FSUSER_OpenFileDirectly(&fileHandle, script, filePath, FS_OPEN_READ, 0x00000000); if (!ret){ FSFILE_GetSize(fileHandle, &size); buffer = (unsigned char*)(malloc((size+1) * sizeof (char))); FSFILE_Read(fileHandle, &bytesRead, 0x0, buffer, size); buffer[size]=0; FSFILE_Close(fileHandle); svcCloseHandle(fileHandle); errMsg = runScript((const char*)buffer, true); free(buffer); }else errMsg = "index.lua file not found."; // Force LCDs power on if ((!isTopLCDOn) || (!isBottomLCDOn)){ gspLcdInit(); if (!isTopLCDOn) GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_TOP); if (!isBottomLCDOn) GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTTOM); gspLcdExit(); isTopLCDOn = true; isBottomLCDOn = true; } // Fake error to force interpreter shutdown if (strstr(errMsg, "lpp_exit_04")) break; if (ftp_state) ftp_exit(); ftp_state = false; int connfd; while (restore==0){ gspWaitForVBlank(); RefreshScreen(); ClearScreen(0); ClearScreen(1); strcpy(error,"Error: "); strcat(error,errMsg); if (ftp_state){ u32 ip=(u32)gethostid(); char ip_address[64]; strcat(error,"\n\nPress A to restart\nPress B to exit\nPress Y to enable FTP server\n\nFTP state: ON\nIP: "); sprintf(ip_address,"%lu.%lu.%lu.%lu", ip & 0xFF, (ip>>8)&0xFF, (ip>>16)&0xFF, (ip>>24)&0xFF); strcat(error,ip_address); strcat(error,"\nPort: 5000"); if(connfd<0)connfd=ftp_getConnection(); else{ int ret=ftp_frame(connfd); if(ret==1) connfd=-1; } }else strcat(error,"\n\nPress A to restart\nPress B to exit\nPress Y to enable FTP server\n\nFTP state: OFF"); DebugOutput(error); hidScanInput(); if(hidKeysDown() & KEY_A){ strcpy(cur_dir,start_dir); restore=1; }else if(hidKeysDown() & KEY_B){ restore=2; }else if(hidKeysDown() & KEY_Y){ if (!ftp_state){ u32 wifiStatus; if ((u32)ACU_GetWifiStatus(&wifiStatus) != 0xE0A09D2E){ if (wifiStatus != 0){ ftp_init(); connfd = -1; ftp_state = true; } } } } gfxFlushBuffers(); gfxSwapBuffers(); } if (ftp_state) ftp_exit(); if (isCSND){ if (csndAccess) csndExit(); else ndspExit(); isCSND = false; } if (restore==2){ break; } }
unsigned char loadROM(char *filename) { char name[17]; enum romType type; int romSize; int ramSize; int i; #ifdef DS3 u64 length; u32 bytesRead; FS_archive sdmcArchive = (FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}}; FS_path filePath = FS_makePath(PATH_CHAR, filename); // /filename Result ret = FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(ret) return false; ret = FSFILE_GetSize(fileHandle, &length); if(ret) return false; ret = FSFILE_Read(fileHandle, &bytesRead, 0x0, cart, length); if(ret || length != bytesRead) return false; memset(name, '\0', 17); for(i = 0; i < 16; i++) { if(cart[i + ROM_OFFSET_NAME] == 0x80 || cart[i + ROM_OFFSET_NAME] == 0xc0) name[i] = '\0'; else name[i] = cart[i + ROM_OFFSET_NAME]; } printf("Internal ROM name: %s\n", name); type = cart[ROM_OFFSET_TYPE]; if(!romTypeString[type]) { printf("Unknown ROM type: %#02x\n", type); return false; } printf("ROM type: %s\n", romTypeString[type]); if(type != ROM_PLAIN) { printf("Only 32KB games with no mappers are supported!\n"); return false; } romSize = cart[ROM_OFFSET_ROM_SIZE]; if((romSize & 0xF0) == 0x50) romSize = (int)pow(2.0, (double)(((0x52) & 0xF) + 1)) + 64; else romSize = (int)pow(2.0, (double)(romSize + 1)); printf("ROM size: %dKB\n", romSize * 16); if(romSize * 16 != 32) { printf("Only 32KB games with no mappers are supported!\n"); return false; } if(length != romSize * 16 * 1024) { printf("ROM filesize does not equal ROM size!\n"); return false; } ramSize = cart[ROM_OFFSET_RAM_SIZE]; ramSize = (int)pow(4.0, (double)ramSize) / 2; printf("RAM size: %dKB\n", ramSize); ramSize = ceil(ramSize / 8.0f); ret = FSFILE_Close(fileHandle); if(ret) return false; return 1; #else #ifdef PS4 void ps4loadROM(void); ps4loadROM(); return 1; #else FILE *f; size_t length; unsigned char header[0x180]; f = fopen(filename, "rb"); if(!f) return 0; fseek(f, 0, SEEK_END); length = ftell(f); if(length < 0x180) { printf("ROM is too small!\n"); fclose(f); return 0; } rewind(f); fread(header, 0x180, 1, f); memset(name, '\0', 17); for(i = 0; i < 16; i++) { if(header[i + ROM_OFFSET_NAME] == 0x80 || header[i + ROM_OFFSET_NAME] == 0xc0) name[i] = '\0'; else name[i] = header[i + ROM_OFFSET_NAME]; } printf("Internal ROM name: %s\n", name); type = header[ROM_OFFSET_TYPE]; if(!romTypeString[type]) { printf("Unknown ROM type: %#02x\n", type); fclose(f); return 0; } printf("ROM type: %s\n", romTypeString[type]); if(type != ROM_PLAIN) { printf("Only 32KB games with no mappers are supported!\n"); fclose(f); return 0; } romSize = header[ROM_OFFSET_ROM_SIZE]; #ifndef PSP if((romSize & 0xF0) == 0x50) romSize = (int)pow(2.0, (double)(((0x52) & 0xF) + 1)) + 64; else romSize = (int)pow(2.0, (double)(romSize + 1)); #else // PSP doesn't support pow... romSize = 2; #endif printf("ROM size: %dKB\n", romSize * 16); if(romSize * 16 != 32) { printf("Only 32KB games with no mappers are supported!\n"); fclose(f); return 0; } if(length != romSize * 16 * 1024) { printf("ROM filesize does not equal ROM size!\n"); //fclose(f); //return 0; } ramSize = header[ROM_OFFSET_RAM_SIZE]; #ifndef PSP ramSize = (int)pow(4.0, (double)(ramSize)) / 2; #else // PSP doesn't support pow... ramSize = 0; #endif printf("RAM size: %dKB\n", ramSize); ramSize = ceil(ramSize / 8.0f); /*cart = malloc(length); if(!cart) { printf("Could not allocate memory!\n"); fclose(f); return 0; }*/ rewind(f); fread(cart, length, 1, f); fclose(f); return 1; #endif #endif }
bool ROM_LoadFile(char* name) { Handle fileHandle; FS_path filePath; filePath.type = PATH_CHAR; filePath.size = strlen(name) + 1; filePath.data = (u8*)name; Result res = FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); if ((res & 0xFFFC03FF) != 0) { bprintf("Error %08X while opening file\n", res); return false; } u64 size; FSFILE_GetSize(fileHandle, &size); if (size < 16 || size >= 0x100000000ULL) { FSFILE_Close(fileHandle); bprintf("File size bad: size=%lld\n", size); return false; } ROM_FileSize = (u32)size; int bestone = 0; int score[4]; score[0] = ROM_ScoreHeader(fileHandle, 0x7FC0); score[1] = ROM_ScoreHeader(fileHandle, 0x81C0); score[2] = ROM_ScoreHeader(fileHandle, 0xFFC0); score[3] = ROM_ScoreHeader(fileHandle, 0x101C0); if (score[1] > score[0]) { score[0] = score[1]; bestone = 1; } if (score[2] > score[0]) { score[0] = score[2]; bestone = 2; } if (score[3] > score[0]) bestone = 3; if (bestone == 0 && score[0] < 0) { bprintf("Invalid ROM\n"); return false; } ROM_BaseOffset = (bestone & 1) ? 0x200 : 0; SNES_HiROM = (bestone & 2) ? true : false; ROM_HeaderOffset = SNES_HiROM ? 0xFFC0 : 0x7FC0; bprintf("ROM type: %s %s\n", (bestone & 1) ? "headered":"headerless", SNES_HiROM ? "HiROM":"LoROM"); size -= ROM_BaseOffset; u32 nbanks = (size + (SNES_HiROM ? 0xFFFF:0x7FFF)) >> (SNES_HiROM ? 16:15); ROM_NumBanks = 1; while (ROM_NumBanks < nbanks) ROM_NumBanks <<= 1; bprintf("ROM size: %dKB / %d banks\n", ((u32)size) >> 10, ROM_NumBanks); ROM_BufferSize = ROM_NumBanks << (SNES_HiROM ? 16:15); ROM_Buffer = (u8*)MemAlloc(ROM_BufferSize); if (!ROM_Buffer) { FSFILE_Close(fileHandle); bprintf("Error while allocating ROM buffer\n"); return false; } u32 bytesread; FSFILE_Read(fileHandle, &bytesread, ROM_BaseOffset, (u32*)ROM_Buffer, (u32)size); FSFILE_Close(fileHandle); u32 b = 0; u32 offset = 0; for (; b < ROM_NumBanks; b++) { ROM_MapBank((SNES_HiROM ? 0x40:0x00) + b, &ROM_Buffer[offset]); offset += (SNES_HiROM ? 0x10000:0x8000); } return true; }
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path) { Result res = 0; list_item* item = (list_item*) calloc(1, sizeof(list_item)); if(item != NULL) { file_info* fileInfo = (file_info*) calloc(1, sizeof(file_info)); if(fileInfo != NULL) { fileInfo->archive = archive; util_get_path_file(fileInfo->name, path, FILE_NAME_MAX); fileInfo->attributes = 0; fileInfo->size = 0; fileInfo->isCia = false; fileInfo->isTicket = false; if(util_is_dir(archive, path)) { item->color = COLOR_DIRECTORY; size_t len = strlen(path); if(len > 1 && path[len - 1] != '/') { snprintf(fileInfo->path, FILE_PATH_MAX, "%s/", path); } else { strncpy(fileInfo->path, path, FILE_PATH_MAX); } fileInfo->attributes = FS_ATTRIBUTE_DIRECTORY; } else { item->color = COLOR_FILE; strncpy(fileInfo->path, path, FILE_PATH_MAX); FS_Path* fileFsPath = util_make_path_utf8(fileInfo->path); if(fileFsPath != NULL) { Handle fileHandle; if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, archive, *fileFsPath, FS_OPEN_READ, 0))) { FSFILE_GetAttributes(fileHandle, &fileInfo->attributes); FSFILE_GetSize(fileHandle, &fileInfo->size); size_t len = strlen(fileInfo->path); if(len > 4) { if(strcasecmp(&fileInfo->path[len - 4], ".cia") == 0) { AM_TitleEntry titleEntry; if(R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_SD, &titleEntry, fileHandle))) { fileInfo->isCia = true; fileInfo->ciaInfo.titleId = titleEntry.titleID; fileInfo->ciaInfo.version = titleEntry.version; fileInfo->ciaInfo.installedSize = titleEntry.size; fileInfo->ciaInfo.hasMeta = false; if((titleEntry.titleID & 0x0000801000000002) != 0 && R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_NAND, &titleEntry, fileHandle))) { fileInfo->ciaInfo.installedSize = titleEntry.size; } SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH)); if(smdh != NULL) { if(R_SUCCEEDED(util_get_cia_file_smdh(smdh, fileHandle))) { if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') { u8 systemLanguage = CFG_LANGUAGE_EN; CFGU_GetSystemLanguage(&systemLanguage); fileInfo->ciaInfo.hasMeta = true; utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(fileInfo->ciaInfo.meta.shortDescription) - 1); utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(fileInfo->ciaInfo.meta.longDescription) - 1); utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(fileInfo->ciaInfo.meta.publisher) - 1); fileInfo->ciaInfo.meta.region = smdh->region; fileInfo->ciaInfo.meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); } } free(smdh); } } } else if(strcasecmp(&fileInfo->path[len - 4], ".tik") == 0) { u32 bytesRead = 0; u8 sigType = 0; if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 3, &sigType, sizeof(sigType))) && bytesRead == sizeof(sigType) && sigType <= 5) { static u32 dataOffsets[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80}; static u32 titleIdOffset = 0x9C; u64 titleId = 0; if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, dataOffsets[sigType] + titleIdOffset, &titleId, sizeof(titleId))) && bytesRead == sizeof(titleId)) { fileInfo->isTicket = true; fileInfo->ticketInfo.titleId = __builtin_bswap64(titleId); } } } } FSFILE_Close(fileHandle); } util_free_path_utf8(fileFsPath); } } strncpy(item->name, fileInfo->name, LIST_ITEM_NAME_MAX); item->data = fileInfo; *out = item; } else { free(item); res = R_FBI_OUT_OF_MEMORY; } } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
static Result dumpnand_get_src_size(void* data, u32 handle, u64* size) { return FSFILE_GetSize(handle, size); }
ssize_t _vf3dSize(struct VFile* vf) { struct VFile3DS* vf3d = (struct VFile3DS*) vf; u64 size; FSFILE_GetSize(vf3d->handle, &size); return size; }
static Result action_install_tickets_get_src_size(void* data, u32 handle, u64* size) { return FSFILE_GetSize(handle, size); }
static Result action_import_twl_save_get_src_size(void* data, u32 handle, u64* size) { return FSFILE_GetSize(handle, size); }