s32 getdir(char *path, dirent_t **ent, u32 *cnt){ s32 res; u32 num = 0; int i, j, k; res = ISFS_ReadDir(path, NULL, &num); if(res != ISFS_OK){ printf("Error: could not get dir entry count! (result: %d)\n", res); return -1; } char ebuf[ISFS_MAXPATH + 1]; char *nbuf = (char *)allocate_memory((ISFS_MAXPATH + 1) * num); if(nbuf == NULL){ printf("ERROR: could not allocate buffer for name list!\n"); return -2; } res = ISFS_ReadDir(path, nbuf, &num); DCFlushRange(nbuf,13*num); //quick fix for cache problems? if(res != ISFS_OK){ printf("ERROR: could not get name list! (result: %d)\n", res); free(nbuf); return -3; } *cnt = num; *ent = allocate_memory(sizeof(dirent_t) * num); if(*ent==NULL){ printf("Error: could not allocate buffer\n"); free(nbuf); return -4; } for(i = 0, k = 0; i < num; i++){ for(j = 0; nbuf[k] != 0; j++, k++) ebuf[j] = nbuf[k]; ebuf[j] = 0; k++; strcpy((*ent)[i].name, ebuf); } qsort(*ent, *cnt, sizeof(dirent_t), __FileCmp); free(nbuf); return 0; }
int fileBrowser_WiiFS_readDir(fileBrowser_file* file, fileBrowser_file** dir){ static char dirents[32*(8+1+3+1)] __attribute__((aligned(32))); unsigned int numDirents = 32; // Call the corresponding ISFS function char* name = getAlignedName(&file->name); int ret = ISFS_ReadDir(name, dirents, &numDirents); // If it was not successful, just return the error if(ret < 0) return ret; // Convert the ISFS data to fileBrowser_files *dir = malloc( numDirents * sizeof(fileBrowser_file) ); int i; char* dirent = &dirents[0]; for(i=0; i<numDirents; ++i){ sprintf((*dir)[i].name, "%s/%s", name, dirent); // Collect info about this file int fd = ISFS_Open( getAlignedName((*dir)[i].name), 1 ); if(fd >= 0){ fstats* stats = memalign( 32, sizeof(fstats) ); ISFS_GetFileStats(fd, stats); (*dir)[i].attr = 0; (*dir)[i].size = stats->file_length; free(stats); ISFS_Close(fd); } else { (*dir)[i].attr = FILE_BROWSER_ATTR_DIR; (*dir)[i].size = 0; } (*dir)[i].offset = 0; while(*(dirent++)); // Advance to the next dirent } return numDirents; }
int fileBrowser_WiiFSROM_init(fileBrowser_file* f){ if(!identified) identify(); fillInTitleDir(f); strcat(&f->name, "/N64ROMS"); recOpenLib(); // Make sure our ROM directory exists char* name = getAlignedName(&f->name); if(ISFS_ReadDir(name, NULL, NULL) < 0) ISFS_CreateDir(name, 0, 3, 3, 1); return 0; }
s32 Enable_Emu(int selection) { if (mounted != 0) return -1; if (selection == 0) return 0; s32 ret; nandDevice *ndev = NULL; ndev = &ndevList[selection]; ret = Nand_Mount(ndev); if (ret < 0) { Print(" ERROR Mount! (ret = %d)\n", ret); return ret; } ret = Nand_Enable(ndev); if (ret < 0) { Print(" ERROR Enable! (ret = %d)\n", ret); Nand_Unmount(ndev); return ret; } u32 temp = 0; ret = ISFS_ReadDir("/", NULL, &temp); if (ret < 0) { Print("ISFS_ReadDir('/') failed ret = %d. No FAT partition?", ret); Nand_Disable(); Nand_Unmount(ndev); return ret; } mounted = selection; return 0; }
static bool read_directory(DIR_ENTRY *parent) { if(!parent || !parent->abspath) return false; u32 fileCount; if(parent->size != 0 && is_dir(parent)) { fileCount = parent->size; } else { s32 ret = ISFS_ReadDir(parent->abspath, NULL, &fileCount); if (ret != ISFS_OK) { return false; } } parent->flags = FLAG_DIR; parent->size = fileCount; parent->childCount = 0; if(strcmp(parent->abspath, "/") != 0) { DIR_ENTRY *child = add_child_entry(parent, "."); if (!child) return false; child->flags = FLAG_DIR; child->size = 0; child = add_child_entry(parent, ".."); if (!child) return false; child->flags = FLAG_DIR; child->size = 0; } if (fileCount > 0) { char *buffer = (char *) memalign(32, ISFS_MAXPATHLEN * fileCount); if(!buffer) return false; s32 ret = ISFS_ReadDir(parent->abspath, buffer, &fileCount); if (ret != ISFS_OK) { free(buffer); return false; } u32 fileNum; char *name = buffer; for (fileNum = 0; fileNum < fileCount; fileNum++) { DIR_ENTRY *child = add_child_entry(parent, name); if (!child) { free(buffer); return false; } name += strlen(name) + 1; u32 childFileCount; ret = ISFS_ReadDir(child->abspath, NULL, &childFileCount); if (ret == ISFS_OK) { child->flags = FLAG_DIR; child->size = childFileCount; } else { s32 fd = ISFS_Open(child->abspath, ISFS_OPEN_READ); if (fd >= 0) { if (ISFS_GetFileStats(fd, &filest) == ISFS_OK) child->size = filest.file_length; ISFS_Close(fd); } } } free(buffer); } return true; }
int NandTitle::InternalExtractDir(char *nandPath, std::string &filepath) { int ret = -1; u32 list_len = 0; ret = ISFS_ReadDir(nandPath, NULL, &list_len); if(ret < 0) return ret; char * name_list = (char *) memalign(32, ALIGN32(list_len * ISFS_MAXPATH)); if(!name_list) return -666; ret = ISFS_ReadDir(nandPath, name_list, &list_len); if(ret < 0) { free(name_list); return ret; } char *entry = name_list; for(u32 i = 0; i < list_len; ++i) { u32 dummy; int posNandPath = strlen(nandPath); int posFilePath = filepath.size(); if(posFilePath > 0 && filepath[posFilePath-1] != '/') filepath += '/'; filepath += entry; if(posNandPath > 0 && nandPath[posNandPath-1] != '/') strcat(nandPath, "/"); strcat(nandPath, entry); if(ISFS_ReadDir(nandPath, NULL, &dummy) < 0) { std::string filepathCpy = filepath; ConvertInvalidCharacters(filepathCpy); int res = ExtractFile(nandPath, filepathCpy.c_str()); if(res < 0) { gprintf("ExtractFile: Error %i occured on file extract: %s\n", res, nandPath); ret = -2; } } else { int res = InternalExtractDir(nandPath, filepath); if(res < 0) { gprintf("InternalExtractDir: Error %i occured in: %s\n", res, nandPath); ret = -3; } } nandPath[posNandPath] = 0; filepath.erase(posFilePath); entry += strlen(entry) + 1; } free(name_list); return ret; }
bool NandSave::CheckSave() { /* 10 million variables */ u32 u8_bin_size = 0; u8 *u8_bin = NULL; u32 certSize = 0; signed_blob *certBuffer = NULL; u32 tmd_bin_size = 0; const signed_blob *tmd_bin = NULL; u32 tik_bin_size = 0; const signed_blob *tik_bin = NULL; u32 banner_bin_size = 0; const u8 *banner_bin = NULL; u32 entries = 0; /* May our banner already exist */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_READ); if(fd >= 0) { ISFS_Close(fd); gprintf("Found WiiFlow Save\n"); goto done; } /* extract our archive */ u8_bin = DecompressCopy(save_bin, save_bin_size, &u8_bin_size); if(u8_bin == NULL || u8_bin_size == 0) goto error; /* grab cert.sys */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/sys/cert.sys"); certBuffer = (signed_blob*)ISFS_GetFile(ISFS_Path, &certSize, -1); if(certBuffer == NULL || certSize == 0) goto error; /* Install tik and tmd */ tik_bin = (const signed_blob*)u8_get_file(u8_bin, "tik.bin", &tik_bin_size); if(tik_bin == NULL || tik_bin_size == 0) goto error; ret = ES_AddTicket(tik_bin, tik_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; tmd_bin = (const signed_blob*)u8_get_file(u8_bin, "tmd.bin", &tmd_bin_size); if(tmd_bin == NULL || tmd_bin_size == 0) goto error; ret = ES_AddTitleStart(tmd_bin, tmd_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; ret = ES_AddTitleFinish(); if(ret < 0) goto error; /* WARNING dirty, delete tik again */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000/57465346.tik"); ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; /* Delete the unused ticket folder */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000"); ret = ISFS_ReadDir(ISFS_Path, NULL, &entries); if(ret < 0) goto error; if(entries == 0) { ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; } banner_bin = u8_get_file(u8_bin, "banner.bin", &banner_bin_size); if(banner_bin == NULL || banner_bin_size == 0) goto error; memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); /* Write our banner */ ISFS_CreateFile(ISFS_Path, 0, 3, 3, 3); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_WRITE); if(fd < 0) goto error; ret = ISFS_Write(fd, banner_bin, banner_bin_size); ISFS_Close(fd); if(ret < 0) { ISFS_Delete(ISFS_Path); goto error; } free(certBuffer); if(u8_bin != save_bin) free(u8_bin); gprintf("Created WiiFlow Save\n"); done: loaded = true; return loaded; error: gprintf("Error while creating WiiFlow Save\n"); loaded = false; ES_AddTitleCancel(); if(certBuffer != NULL) free(certBuffer); certBuffer = NULL; if(u8_bin != NULL) free(u8_bin); u8_bin = NULL; tik_bin = NULL; tmd_bin = NULL; banner_bin = NULL; return loaded; }