Exemplo n.º 1
0
void NES_LOADROMLIST() {
	Handle romHandle;
	
	FS_dirent dirStruct;
	FS_path dirPath = FS_makePath(PATH_CHAR, "/3DNES/ROMS");

	// init SDMC archive
	sdmcArchive = (FS_archive){0x9, (FS_path){PATH_EMPTY, 1, (u8*)""}};
	FSUSER_OpenArchive(NULL, &sdmcArchive);
	FSUSER_OpenDirectory(NULL, &romHandle, sdmcArchive, dirPath);

	// Get number of files in directory
	fileSystem.totalFiles = 0
	while(1) {
		u32 dataRead = 0;
		FSDIR_Read(romHandle, &dataRead, 1, &dirStruct);
		if(dataRead == 0) break;
		fileSystem.totalFiles++;
	}

	fileSystem.fileList = linearAlloc(MAX_FILENAME_SIZE * fileSystem.totalFiles);

	FSUSER_OpenDirectory(NULL, &romHandle, sdmcArchive, dirPath);

	fileSystem.totalFiles = 0;
	while(1) {
		u32 dataRead = 0;
		FSDIR_Read(romHandle, &dataRead, 1, &dirStruct);
		if(dataRead == 0) break;
		unicodeToChar(&fileSystem.fileList[MAX_FILENAME_SIZE * fileSystem.totalFiles), dirStruct.name);
		fileSystem.totalFiles++;
	}

	FSDIR_Close(romHandle);
}
Exemplo n.º 2
0
void scanHomebrewDirectory(menu_s* m, char* path)
{
	if(!path)return;

	Handle dirHandle;
	FS_path dirPath=FS_makePath(PATH_CHAR, path);
	FSUSER_OpenDirectory(NULL, &dirHandle, sdmcArchive, dirPath);
	
	static char fullPath[1024];
	u32 entriesRead;
	do
	{
		static FS_dirent entry;
		memset(&entry,0,sizeof(FS_dirent));
		entriesRead=0;
		FSDIR_Read(dirHandle, &entriesRead, 1, &entry);
		if(entriesRead)
		{
			strncpy(fullPath, path, 1024);
			int n=strlen(fullPath);
			unicodeToChar(&fullPath[n], entry.name, 1024-n);
			if(entry.isDirectory) //directories
			{
				addDirectoryToMenu(m, fullPath);
			}else{ //stray executables
				n=strlen(fullPath);
				if(n>5 && !strcmp(".3dsx", &fullPath[n-5]))addFileToMenu(m, fullPath);
			}
		}
	}while(entriesRead);

	FSDIR_Close(dirHandle);
}
Exemplo n.º 3
0
Directory::Directory(FS_Archive archive, const std::u16string& root)
{
	load = false;
	err = 0;
	Handle handle;

	list.clear();

	err = FSUSER_OpenDirectory(&handle, archive, fsMakePath(PATH_UTF16, root.c_str()));
	if (R_FAILED(err))
	{
		return;
	}

	u32 result = 0;
	do {
		FS_DirectoryEntry item;
		err = FSDIR_Read(handle, &result, 1, &item);
		if (result == 1)
		{
			list.push_back(item);
		}
	} while(result);

	err = FSDIR_Close(handle);
	if (R_FAILED(err))
	{
		list.clear();
		return;
	}

	load = true;
}
Exemplo n.º 4
0
static struct VDirEntry* _vd3dListNext(struct VDir* vd) {
	struct VDir3DS* vd3d = (struct VDir3DS*) vd;
	u32 n = 0;
	memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent));
	memset(vd3d->vde.utf8Name, 0, sizeof(vd3d->vde.utf8Name));
	FSDIR_Read(vd3d->handle, &n, 1, &vd3d->vde.ent);
	if (!n) {
		return 0;
	}
	return &vd3d->vde.d;
}
Exemplo n.º 5
0
bool renameRecursive(const FS_Archive archive, const std::string source, const std::string target) {
	const FS_Path sourcePath = fsMakePath(PATH_ASCII, source.c_str());
	const FS_Path targetPath = fsMakePath(PATH_ASCII, target.c_str());

	// Open source directory
	Handle directory = NULL;
	if (FSUSER_OpenDirectory(&directory, archive, sourcePath) != 0) {
		std::printf("\nCould not open %s\n\n", source.c_str());
		return false;
	}

	// Make target directory
	if (FSUSER_CreateDirectory(archive, targetPath, FS_ATTRIBUTE_DIRECTORY) != 0) {
		std::printf("\nCould not create %s\n\n", target.c_str());
		return false;
	}

	u32 fileRead = 0;
	while (true) {
		FS_DirectoryEntry entry = {};
		FSDIR_Read(directory, &fileRead, 1, &entry);
		if (!fileRead) {
			break;
		}

		// Convert name to ASCII (just cut the other bytes)
		char name8[262] = { 0 };
		for (size_t i = 0; i < 262; i++) {
			name8[i] = entry.name[i] % 0xff;
		}
		std::string filePath = std::string("/") + name8;
		std::string from = source + filePath;
		std::string to = target + filePath;

		// Is a directory? Recurse rename
		if (entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
			std::printf("  %s -> %s (DIR)\n", from.c_str(), to.c_str());
			if (!renameRecursive(archive, source + filePath, target + filePath)) {
				return false;
			}
		} else {
			FS_Path sourceFilePath = fsMakePath(PATH_ASCII, from.c_str());
			FS_Path targetFilePath = fsMakePath(PATH_ASCII, to.c_str());
			if (FSUSER_RenameFile(archive, sourceFilePath, archive, targetFilePath) != 0) {
				std::printf("\nCould not rename %s\n\n", (char*)sourceFilePath.data);
				return false;
			}
			std::printf("  %s -> %s\n", (char*)sourceFilePath.data, (char*)targetFilePath.data);
		}
	}

	return true;
}
Exemplo n.º 6
0
void dumpTicket(void) {
    Result res = 0;
    Handle nandDir;
    u32 entryCount;
    FS_dirent dirent;

    printf("Opening NAND...\n");
    res = FSUSER_OpenArchive(NULL, &nandArchive);
    if(res != 0) {
        printf("%sError opening NAND!\n%.8lX%s\n", TEXT_RED, res, TEXT_RESET);
        return;
    }

    printf("Opening /...\n");
    nandPath.data = (u8 *)nandPathString;
    nandPath.size = (wcslen(nandPathString) + 1) * 2;
    res = FSUSER_OpenDirectory(NULL, &nandDir, nandArchive, nandPath);
    if(res != 0) {
        printf("%sError opening /!\n%.8lX%s\n", TEXT_RED, res, TEXT_RESET);
        return;
    }

    printf("Reading...\n");
    for(;;) {
        res = FSDIR_Read(nandDir, &entryCount, 1, &dirent);
        if(res != 0) {
            printf("%sError reading dir!\n%.8lX%s\n", TEXT_RED, res, TEXT_RESET);
            return;
        }

        if(entryCount == 0) {
            break;
        }

        utf16_to_utf8(utf8, dirent.name, 0x106);
        printf("/%s\n", utf8);
    }

    printf("Closing /...\n");
    res = FSDIR_Close(nandDir);
    if(res != 0) {
        printf("%sError closing /!\n%.8lX%s\n", TEXT_RED, res, TEXT_RESET);
        return;
    }

    printf("Closing NAND...\n");
    res = FSUSER_CloseArchive(NULL, &nandArchive);
    if(res != 0) {
        printf("%sError closing NAND!\n%.8lX%s\n", TEXT_RED, res, TEXT_RESET);
        return;
    }
}
Exemplo n.º 7
0
int getNextFile(Handle dir, FS_DirectoryEntry *ent) {
  u32 count;
  
  if(R_FAILED(FSDIR_Read(dir, &count, 1, ent))) {
    return(-1);
  }
  
  if(count == 0) {
    return(0);
  }
  
  return(1);
}
Exemplo n.º 8
0
//same thing as contructor. can be used to reinit dirList too
void dirList::reassign(const std::u16string p)
{
    entry.clear();

    FSUSER_OpenDirectory(&d, a, fsMakePath(PATH_UTF16, p.data()));

    u32 read = 0;
    do
    {
        FS_DirectoryEntry getEnt;
        FSDIR_Read(d, &read, 1, &getEnt);
        entry.push_back(getEnt);
    }while(read > 0);

    FSDIR_Close(d);
}
Exemplo n.º 9
0
void scanHomebrewDirectory(menu_s* m, char* path) {
    if(!path)return;

    Handle dirHandle;
    FS_path dirPath=FS_makePath(PATH_CHAR, path);
    FSUSER_OpenDirectory(&dirHandle, sdmcArchive, dirPath);

    static char fullPath[1024][1024];
    u32 entriesRead;
    int totalentries = 0;
    do
    {
        static FS_dirent entry;
        memset(&entry,0,sizeof(FS_dirent));
        entriesRead=0;
        FSDIR_Read(dirHandle, &entriesRead, 1, &entry);
        if(entriesRead)
        {
            strncpy(fullPath[totalentries], path, 1024);
            int n=strlen(fullPath[totalentries]);
            unicodeToChar(&fullPath[totalentries][n], entry.name, 1024-n);
            if(entry.isDirectory) //directories
            {
                //addDirectoryToMenu(m, fullPath[totalentries]);
                totalentries++;
            }else{ //stray executables
                n=strlen(fullPath[totalentries]);
                if(n>5 && !strcmp(".3dsx", &fullPath[totalentries][n-5])){
                    //addFileToMenu(m, fullPath[totalentries]);
                    totalentries++;
                }
                if(n>4 && !strcmp(".xml", &fullPath[totalentries][n-4])) {
                    //addFileToMenu(m, fullPath[totalentries]);
                    totalentries++;
                }
            }
        }
    }while(entriesRead);

    FSDIR_Close(dirHandle);

    bool sortAlpha = getConfigBoolForKey("sortAlpha", false, configTypeMain);
    addMenuEntries(fullPath, totalentries, strlen(path), m, sortAlpha);

    updateMenuIconPositions(m);
}
Exemplo n.º 10
0
void dumpFolder(char *path, u32 lowpath_id, char *dumpfolder, u8 *filebuffer, size_t bufsize) {
	Handle extdata_dir;
	Result ret = FSUSER_OpenDirectory(NULL, &extdata_dir, extdata_archive, FS_makePath(PATH_CHAR, path));
	if (ret!=0) {
		printf("could not open dir\n");
		gfxFlushBuffers();
		gfxSwapBuffers();
		return;
	}
	char dirname[0x120];
	sprintf(dirname, "%s/%08x%s", dumpfolder, (unsigned int) lowpath_id, path);
	mkdir(dirname, 0777);
	
	FS_dirent dirStruct;
	char fileName[0x106] = "";
	int cont = 0;
	while(1) {
		u32 dataRead = 0;
		FSDIR_Read(extdata_dir, &dataRead, 1, &dirStruct);
		if(dataRead == 0) break;
		unicodeToChar(fileName, dirStruct.name);
		printf("name: %s%s%s\n", path, fileName, dirStruct.isDirectory ? " (DIRECTORY)" : "");
		gfxFlushBuffers();
		gfxSwapBuffers();
		cont++;
		if (dirStruct.isDirectory) {
			char newpath[0x120];
			sprintf(newpath, "%s%s/", path, fileName);
			dumpFolder(newpath, lowpath_id, dumpfolder, filebuffer, bufsize);
		} else {
			char file_inpath[0x120];
			char file_outpath[0x120];
			char file_display_path[0x120];

			sprintf(file_inpath, "%s%s", path, fileName);
			sprintf(file_outpath, "%s/%08x%s%s", dumpfolder, (unsigned int) lowpath_id, path, fileName);
			sprintf(file_display_path, "%08x%s%s", (unsigned int) lowpath_id, path, fileName);
			archive_copyfile(Extdata_Archive, SDArchive, file_inpath, file_outpath, filebuffer, 0, bufsize, file_display_path);
		}
	}
	printf("total files in 0x%08x%s: %d\n", (unsigned int) lowpath_id, path, (unsigned int) cont);
	gfxFlushBuffers();
	gfxSwapBuffers();
	FSDIR_Close(extdata_dir);
}
Exemplo n.º 11
0
/*! Fetch the next entry of an open directory
 *
 *  @param[in,out] r        newlib reentrancy struct
 *  @param[in]     dirState Pointer to open directory state
 *  @param[out]    filename Buffer to store entry name
 *  @param[out]    filestat Buffer to store entry attributes
 *
 *  @returns 0 for success
 *  @returns -1 for error
 */
static int
sdmc_dirnext(struct _reent *r,
             DIR_ITER      *dirState,
             char          *filename,
             struct stat   *filestat)
{
  Result         rc;
  u32            entries;
  u16            *name;

  /* get pointer to our data */
  sdmc_dir_t *dir = (sdmc_dir_t*)(dirState->dirStruct);

  /* fetch the next entry */
  rc = FSDIR_Read(dir->fd, &entries, 1, &dir->entry_data);
  if(rc == 0)
  {
    if(entries == 0)
    {
      /* there are no more entries; ENOENT signals end-of-directory */
      r->_errno = ENOENT;
      return -1;
    }

    /* fill in the stat info */
    filestat->st_ino = 0;
    if(dir->entry_data.isDirectory)
      filestat->st_mode = S_IFDIR;
    else
      filestat->st_mode = S_IFREG;

    /* copy the name */
    name = dir->entry_data.name;
    while(*name)
      *filename++ = *name++;
    *filename = 0;

    return 0;
  }

  r->_errno = rc;
  return -1;
}
Exemplo n.º 12
0
dirList::dirList(FS_Archive arch, const std::u16string p)
{
    //keep archive data
    a = arch;

    //save path
    path = p;

    //open path given by p
    FSUSER_OpenDirectory(&d, a, fsMakePath(PATH_UTF16, p.data()));

    //loop until we stop reading anymore entries
    u32 read = 0;
    do
    {
        FS_DirectoryEntry getEnt;
        FSDIR_Read(d, &read, 1, &getEnt);
        entry.push_back(getEnt);
    }while(read > 0);

    FSDIR_Close(d);
}
Exemplo n.º 13
0
std::vector<std::string> listPayloads() {
	std::vector<std::string> files = {};
	FS_Archive sdmcArchive;

	// Open SD card
	if (FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, NULL)) != 0) {
		logPrintf("\nCould not access SD Card (?)\n\n");
		return files;
	}

	// Open source directory
	Handle directory = 0;
	if (FSUSER_OpenDirectory(&directory, sdmcArchive, fsMakePath(PATH_ASCII, "/luma/payloads")) != 0) {
		logPrintf("\nCould not open /luma/payloads\n\n");
		FSUSER_CloseArchive(sdmcArchive);
		return files;
	}

	u32 fileRead = 0;
	while (true) {
		FS_DirectoryEntry entry = {};
		FSDIR_Read(directory, &fileRead, 1, &entry);
		if (!fileRead) {
			break;
		}

		// Convert name to ASCII (just cut the other bytes) and compare with prefix
		char name8[262] = { 0 };
		for (size_t i = 0; i < 262; i++) {
			name8[i] = entry.name[i] % 0xff;
		}

		files.push_back(std::string(name8));
	}

	FSUSER_CloseArchive(sdmcArchive);
	return files;
}
Exemplo n.º 14
0
directoryContents * contentsOfDirectoryAtPath(char * path, bool dirsOnly) {
    directoryContents * contents = malloc(sizeof(directoryContents));

    int numPaths = 0;

    Handle dirHandle;
    FS_path dirPath=FS_makePath(PATH_CHAR, path);
    FSUSER_OpenDirectory(&dirHandle, sdmcArchive, dirPath);

    u32 entriesRead;
    do
    {
        static FS_dirent entry;
        memset(&entry,0,sizeof(FS_dirent));
        entriesRead=0;
        FSDIR_Read(dirHandle, &entriesRead, 1, &entry);
        if(entriesRead) {
            if(!dirsOnly || (dirsOnly && entry.isDirectory)) {
                char fullPath[1024];
                strncpy(fullPath, path, 1024);
                int n=strlen(path);
                unicodeToChar(&fullPath[n], entry.name, 1024-n);

                strcpy(contents->paths[numPaths], fullPath);
                numPaths++;
            }
        }
    }while(entriesRead);

    FSDIR_Close(dirHandle);

//    qsort(contents->paths, numPaths, 1024, compareStrings);

    contents->numPaths = numPaths;
    return contents;
}
Exemplo n.º 15
0
static void task_populate_files_thread(void* arg) {
    populate_files_data* data = (populate_files_data*) arg;

    Result res = 0;

    list_item* baseItem = NULL;
    if(R_SUCCEEDED(res = task_create_file_item(&baseItem, data->archive, data->path))) {
        file_info* baseInfo = (file_info*) baseItem->data;
        if(baseInfo->attributes & FS_ATTRIBUTE_DIRECTORY) {
            strncpy(baseItem->name, "<current directory>", LIST_ITEM_NAME_MAX);
        } else {
            strncpy(baseItem->name, "<current file>", LIST_ITEM_NAME_MAX);
        }

        linked_list queue;
        linked_list_init(&queue);

        linked_list_add(&queue, baseItem);

        bool quit = false;
        while(!quit && R_SUCCEEDED(res) && linked_list_size(&queue) > 0) {
            u32 tail = linked_list_size(&queue) - 1;
            list_item* currItem = (list_item*) linked_list_get(&queue, tail);
            file_info* curr = (file_info*) currItem->data;
            linked_list_remove_at(&queue, tail);

            if(data->includeBase || currItem != baseItem) {
                linked_list_add(data->items, currItem);
            }

            if(curr->attributes & FS_ATTRIBUTE_DIRECTORY) {
                FS_Path* fsPath = util_make_path_utf8(curr->path);
                if(fsPath != NULL) {
                    Handle dirHandle = 0;
                    if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, curr->archive, *fsPath))) {
                        u32 entryCount = 0;
                        FS_DirectoryEntry* entries = (FS_DirectoryEntry*) calloc(MAX_FILES, sizeof(FS_DirectoryEntry));
                        if(entries != NULL) {
                            if(R_SUCCEEDED(res = FSDIR_Read(dirHandle, &entryCount, MAX_FILES, entries)) && entryCount > 0) {
                                qsort(entries, entryCount, sizeof(FS_DirectoryEntry), task_populate_files_compare_directory_entries);

                                for(u32 i = 0; i < entryCount && R_SUCCEEDED(res); i++) {
                                    svcWaitSynchronization(task_get_pause_event(), U64_MAX);
                                    if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) {
                                        quit = true;
                                        break;
                                    }

                                    char name[FILE_NAME_MAX] = {'\0'};
                                    utf16_to_utf8((uint8_t*) name, entries[i].name, FILE_NAME_MAX - 1);

                                    if(data->filter == NULL || data->filter(data->filterData, name, entries[i].attributes)) {
                                        char path[FILE_PATH_MAX] = {'\0'};
                                        snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name);

                                        list_item* item = NULL;
                                        if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) {
                                            if(data->recursive && (((file_info*) item->data)->attributes & FS_ATTRIBUTE_DIRECTORY)) {
                                                linked_list_add(&queue, item);
                                            } else {
                                                linked_list_add(data->items, item);
                                            }
                                        }
                                    }
                                }
                            }

                            free(entries);
                        } else {
                            res = R_FBI_OUT_OF_MEMORY;
                        }

                        FSDIR_Close(dirHandle);
                    }

                    util_free_path_utf8(fsPath);
                } else {
                    res = R_FBI_OUT_OF_MEMORY;
                }
            }
        }

        if(!data->includeBase) {
            task_free_file(baseItem);
        }
    }

    svcCloseHandle(data->cancelEvent);

    data->result = res;
    data->finished = true;
}
Exemplo n.º 16
0
bool installTTP(char* path, u8 mediatype) { // Install a TTP file. (needs libzip and installCIA)

	Result res;
	FS_Archive archive = {ARCHIVE_SDMC, {PATH_EMPTY, 0, 0}};
	FSUSER_OpenArchive(&archive);
	FSUSER_DeleteDirectoryRecursively(archive, fsMakePath(PATH_ASCII, "/tmp/cias"));
	FSUSER_CreateDirectory(archive, fsMakePath(PATH_ASCII, "/tmp/cias"), 0);
	FILE* ttp = fopen(path, "rb");
	FILE* tmp = fopen("/tmp/cias/ttp.tmp", "wb");

	u32 titlesAmount;
	AM_GetTitleCount(mediatype, &titlesAmount);
	u64* titleIDs = malloc(sizeof(u64) * titlesAmount);
	AM_GetTitleIdList(mediatype, titlesAmount, titleIDs);

	u32 size;
	fseek(ttp, 0x19, SEEK_SET);
	fread(&size, 0x4, 1, ttp);
	fseek(ttp, 0x1D, SEEK_SET);

	u32 blockAmount = size / 0x160000; // Finds how many blocks of 4MB you have in the file
	u32 i;
	char* block = malloc(0x160000);
	for (i = 0; i < blockAmount; i++) {
		fread(block, 1, 0x160000, ttp);
		fwrite(block, 1, 0x160000, tmp);
	}

	if (size % 0x160000 != 0) {
		fread(block, 1, size-0x160000*blockAmount, ttp);
		fwrite(block, 1, size-0x160000*blockAmount, tmp);
	}

	free(block);

	fclose(ttp);
	fclose(tmp);

	FSUSER_DeleteDirectoryRecursively(archive, fsMakePath(PATH_ASCII, "/tmp/cias"));
	FSUSER_CreateDirectory(archive, fsMakePath(PATH_ASCII, "/tmp/cias"), 0);

	Zip *zipHandle = ZipOpen("/tmp/cias/ttp.tmp");
	ZipExtract(zipHandle, NULL);
	ZipClose(zipHandle);

	Handle ciaDir;
	FS_Archive fsarchive;
	u32 actualAmount;
	FS_DirectoryEntry* entries;

	FSUSER_DeleteFile(archive, fsMakePath(PATH_ASCII, "/tmp/cias/ttp.tmp"));
	res = FSUSER_OpenDirectory(&ciaDir, fsarchive, fsMakePath(PATH_ASCII, "/tmp/cias"));
	if (res != 0) { free(titleIDs); return false; }
	entries = malloc(256 * sizeof(FS_DirectoryEntry));
	res = FSDIR_Read(ciaDir, &actualAmount, 256, entries);
	if (res != 0) { free(titleIDs); return false; }

	char* ciaPath;
	Handle ciaFileHandle;
	AM_TitleEntry ciaInfo;
	for (i = 0; i < actualAmount; i++) {
		ciaPath = malloc(14 + strlen(entries[i].shortName));
		strcpy(ciaPath, "/tmp/cias/");
		strcat(ciaPath, entries[i].shortName);
		strcat(ciaPath, ".cia");
		
		FSUSER_OpenFile(&ciaFileHandle, archive, fsMakePath(PATH_ASCII, ciaPath), FS_OPEN_READ, 0);
		AM_GetCiaFileInfo(mediatype, &ciaInfo, ciaFileHandle);
		FSFILE_Close(ciaFileHandle);
		
		if (ciaInfo.titleID == 0x0004013800000002LL || ciaInfo.titleID == 0x0004013820000002LL) {
			if (!installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName))
				if (!installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName)) // Tries to install the CIA 3 times then give up. If it has to give up, that probably means brick.
					if (!installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName))
						return false;

			break;
		}
		free(ciaPath);
	}

	for (i = 0; i < actualAmount; i++) {
		ciaPath = malloc(14 + strlen(entries[i].shortName));
		strcpy(ciaPath, "/tmp/cias/");
		strcat(ciaPath, entries[i].shortName);
		strcat(ciaPath, ".cia");
		if (!installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName))
			if (!installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName)) // Tries to install the CIA 3 times then give up. If it has to give up, that probably means brick.
				installCIA(ciaPath, mediatype, titleIDs, entries[i].shortName);

		free(ciaPath);
	}

	FSUSER_DeleteDirectoryRecursively(archive, fsMakePath(PATH_ASCII, "/tmp/cias"));

	FSUSER_CloseArchive(&archive);

	free(titleIDs);

	return true;

}
Exemplo n.º 17
0
Arquivo: gui.c Projeto: nop90/Vex3DS
int load_file(char **wildcards, char *result, bool startup)
{

	Handle dirHandle;
    FS_DirectoryEntry entry;
	char current_dir_name[MAX__PATH];
    char prev_dir_name[MAX__PATH];
	char current_dir_short[81];
	u32 current_dir_length;
	u32 total_filenames_allocated;
	u32 total_dirnames_allocated;
	char **file_list;
	char **dir_list;
	u32 num_files;
	u32 num_dirs;
	char *file_name;
	u32 file_name_length;
	u32 ext_pos = -1;
	s32 return_value = 1;
	u32 current_file_selection;
	u32 current_file_scroll_value;
	u32 current_dir_selection;
	u32 current_dir_scroll_value;
	u32 current_file_in_scroll;
	u32 current_dir_in_scroll;
	u32 current_file_number, current_dir_number;
	u32 current_column = 0;
	u32 repeat;
	u32 i;

    strcpy(current_dir_name, config_roms_path);
    strcpy(prev_dir_name, current_dir_name);
	while(return_value == 1) {
		current_file_selection = 0;
		current_file_scroll_value = 0;
		current_dir_selection = 0;
		current_dir_scroll_value = 0;
		current_file_in_scroll = 0;
		current_dir_in_scroll = 0;

		total_filenames_allocated = 32;
		total_dirnames_allocated = 32;
		file_list = (char **)malloc(sizeof(char *) * 32);
		dir_list = (char **)malloc(sizeof(char *) * 32);
		memset(file_list, 0, sizeof(char *) * 32);
		memset(dir_list, 0, sizeof(char *) * 32);

		num_files = 0;
		num_dirs = 0;
        
        file_name= (char*) malloc(0x105);

        FS_Path dirPath = (FS_Path){PATH_ASCII, strlen(current_dir_name)+1, (u8*)current_dir_name};
        FSUSER_OpenDirectory(&dirHandle, sdmcArchive, dirPath);

		// DEBUG
		printf("Current directory: %s\n", current_dir_name);
		u32 nread = 0;
		do {
            if(dirHandle) FSDIR_Read(dirHandle, &nread, 1, &entry);

            if(nread) { //(current_file) {
               strncpy_u2a(file_name, entry.name, 0x105);  //utf-16 to ascii function yoinked from blargSNES
				file_name_length = strlen(file_name);

                if(((file_name[0] != '.') || (file_name[1] == '.'))) {
					//if(S_ISDIR(file_info.st_mode)) {    //!!!!!!!!
                    if(entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
                        if((strcmp(file_name, "filer") != 0) && (strcmp(file_name, "Nintendo 3DS") != 0) && (strcmp(file_name, "private") != 0)) {
                            dir_list[num_dirs] = (char *)malloc(file_name_length + 1);
                            strcpy(dir_list[num_dirs], file_name);

                            num_dirs++;
                        }
					} else {
					// Must match one of the wildcards, also ignore the .
						if(file_name_length >= 4) {
							if(file_name[file_name_length - 4] == '.') ext_pos = file_name_length - 4;
							else if(file_name[file_name_length - 3] == '.') ext_pos = file_name_length - 3;
							else ext_pos = 0;

							for(i = 0; wildcards[i] != NULL; i++) {
								if(!strcasecmp((file_name + ext_pos), wildcards[i])) {
									file_list[num_files] = (char *)malloc(file_name_length + 1);

									strcpy(file_list[num_files], file_name);

									num_files++;
									break;
								}
							}
						}
					}
				}

				if(num_files == total_filenames_allocated) {
					file_list = (char **)realloc(file_list, sizeof(char *) * total_filenames_allocated * 2);
					memset(file_list + total_filenames_allocated, 0, sizeof(char *) * total_filenames_allocated);
					total_filenames_allocated *= 2;
				}

				if(num_dirs == total_dirnames_allocated) {
					dir_list = (char **)realloc(dir_list, sizeof(char *) * total_dirnames_allocated * 2);
					memset(dir_list + total_dirnames_allocated, 0, sizeof(char *) * total_dirnames_allocated);
					total_dirnames_allocated *= 2;
				}
			}
        } while(nread); 

		qsort((void *)file_list, num_files, sizeof(char *), sort_function);
		qsort((void *)dir_list, num_dirs, sizeof(char *), sort_function);

        FSDIR_Close(dirHandle);

		current_dir_length = strlen(current_dir_name);

		if(current_dir_length > 80) {
			memcpy(current_dir_short, "...", 3);
			memcpy(current_dir_short + 3, current_dir_name + current_dir_length - 77, 77);
			current_dir_short[80] = 0;
		} else {
			memcpy(current_dir_short, current_dir_name, current_dir_length + 1);
		}

		repeat = 1;

		if(num_files == 0) current_column = 1;
		if(num_dirs == 0) current_column = 0;

		char print_buffer[81];

		while(repeat) {
			sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); //!!
			sftd_draw_text(font, 0, 4, COLOR_ACTIVE_ITEM, 10, current_dir_short);
			const char strMsg[] = "[A] Select Rom [X] Run BIOS [Y] Dir up [B] Back";
			guitextwidth = sftd_get_text_width(font, 10, strMsg);
			sftd_draw_text(font, (320 - guitextwidth) / 2, 225, COLOR_HELP_TEXT, 10, strMsg);
			
			for(i = 0, current_file_number = i + current_file_scroll_value; i < FILE_LIST_ROWS; i++, current_file_number++) {
				if(current_file_number < num_files) {
                    strncpy(print_buffer,file_list[current_file_number], 30);   //38);
                    print_buffer[30] = 0;   //38] = 0;
					if((current_file_number == current_file_selection) && (current_column == 0)) {
						sftd_draw_text(font, FILE_LIST_POSITION, ((i + 2) * 10), COLOR_ACTIVE_ITEM, 10, print_buffer);
					} else {
						sftd_draw_text(font, FILE_LIST_POSITION, ((i + 2) * 10), COLOR_INACTIVE_ITEM, 10, print_buffer);
					}
				}
			}
			for(i = 0, current_dir_number = i + current_dir_scroll_value; i < FILE_LIST_ROWS; i++, current_dir_number++) {
				if(current_dir_number < num_dirs) {
                    strncpy(print_buffer,dir_list[current_dir_number], 8);  //13);
                    print_buffer[9] = 0;    //14] = 0;
					if((current_dir_number == current_dir_selection) && (current_column == 1)) {
						sftd_draw_text(font, DIR_LIST_POSITION, ((i + 2) * 10), COLOR_ACTIVE_ITEM, 10, print_buffer);
					} else {
						sftd_draw_text(font, DIR_LIST_POSITION, ((i + 2) * 10), COLOR_INACTIVE_ITEM, 10, print_buffer);
					}
				}
			}

			// Catch input
			// change to read key state later
            if (aptGetStatus() == APP_PREPARE_SLEEPMODE) {
                aptSignalReadyForSleep();
                aptWaitStatusEvent();
            } else if (aptGetStatus() == APP_SUSPENDING) {
                aptReturnToMenu();
            }
            hidScanInput();
            u32 keydown = hidKeysDown();
                   if (keydown & KEY_A) {  
						if(current_column == 1) {
							if(num_dirs != 0) {
								repeat = 0;
								strcpy(prev_dir_name, current_dir_name);
								if (strlen(current_dir_name)>1) strcat(current_dir_name, "/");
								strcat(current_dir_name, dir_list[current_dir_selection]);
							}
						} else {
							if(num_files != 0) {
								repeat = 0;
								return_value = 0;
								//strcpy(result, file_list[current_file_selection]);
								sprintf(result, "%s/%s", current_dir_name, file_list[current_file_selection]);
								break;
							}
						}
					}
                    if (keydown & KEY_Y) {
                            repeat = 0;
                            char* findpath = strrchr(current_dir_name,'/');
                        if(findpath > current_dir_name) 
                            findpath[0] = '\0';
                        else 
                            findpath[1] = '\0';
                    }
					if (keydown & KEY_B ) { 
						return_value = -1;
						repeat = 0;
						break;
					}
					if (keydown & KEY_X ) { 
						return_value = 1;
						repeat = 0;
						break;
					}
					if (keydown & KEY_UP) {  
						if(current_column == 0) {
							if(current_file_selection) {
								current_file_selection--;
								if(current_file_in_scroll == 0) {
									//clear_screen(COLOR_BG);
									current_file_scroll_value--;
								} else {
									current_file_in_scroll--;
								}
							}
						} else {
							if(current_dir_selection) {
								current_dir_selection--;
								if(current_dir_in_scroll == 0) {
									//clear_screen(COLOR_BG);
									current_dir_scroll_value--;
								} else {
									current_dir_in_scroll--;
								}
							}
						}
					}
					if (keydown & KEY_DOWN) { 
						if(current_column == 0) {
							if(current_file_selection < (num_files - 1)) {
								current_file_selection++;
								if(current_file_in_scroll == (FILE_LIST_ROWS - 1)) {
									//clear_screen(COLOR_BG);
									current_file_scroll_value++;
								} else {
									current_file_in_scroll++;
								}
							}
						} else {
							if(current_dir_selection < (num_dirs - 1)) {
								current_dir_selection++;
								if(current_dir_in_scroll == (FILE_LIST_ROWS - 1)) {
									//clear_screen(COLOR_BG);
									current_dir_scroll_value++;
								} else {
									current_dir_in_scroll++;
								}
							}
						}
					}
					if (keydown & KEY_L) {  
						if(current_column == 0) {
							if(current_file_selection>FILE_LIST_ROWS) {
								current_file_selection-=FILE_LIST_ROWS;
								current_file_scroll_value -= FILE_LIST_ROWS;
								if (current_file_in_scroll>current_file_selection){
									//clear_screen(COLOR_BG);
									current_file_scroll_value=0;
									current_file_in_scroll=current_file_selection;
								}
							} else {
								current_file_selection=0;
								current_file_scroll_value=0;
								current_file_in_scroll=0;
							}
						} else {
							if(current_dir_selection) {
								current_dir_selection--;
								if(current_dir_in_scroll == 0) {
									//clear_screen(COLOR_BG);
									current_dir_scroll_value--;
								} else {
									current_dir_in_scroll--;
								}
							}
						}
					}
					if (keydown & KEY_R) {  
						if(current_column == 0) {
							if(current_file_selection < (num_files - 1 - FILE_LIST_ROWS)) {
								current_file_selection+=FILE_LIST_ROWS;
								current_file_scroll_value+=FILE_LIST_ROWS;
								if (current_file_scroll_value>(num_files - FILE_LIST_ROWS)){
									//clear_screen(COLOR_BG);
									current_file_scroll_value=num_files - FILE_LIST_ROWS;
									current_file_in_scroll=  FILE_LIST_ROWS - (num_files - current_file_selection);
								}
									//clear_screen(COLOR_BG);
							} else {
								current_file_selection = num_files - 1;
								current_file_in_scroll = (num_files<=FILE_LIST_ROWS - 1)?num_files:FILE_LIST_ROWS - 1;
								current_file_scroll_value = (num_files > FILE_LIST_ROWS)?num_files - FILE_LIST_ROWS:0;
							}
						} else {
							if(current_dir_selection < (num_dirs - 1)) {
								current_dir_selection++;
								if(current_dir_in_scroll == (FILE_LIST_ROWS - 1)) {
									//clear_screen(COLOR_BG);
									current_dir_scroll_value++;
								} else {
									current_dir_in_scroll++;
								}
							}
						}
					}
					if (keydown & KEY_LEFT) { 
						if(current_column == 1) {
							if(num_files != 0) current_column = 0;
						}
					}
					if (keydown & KEY_RIGHT) {  
						if(current_column == 0) {
							if(num_dirs != 0) current_column = 1;
						}
					}

            sf2d_end_frame();
            
			gui_DrawTopScreen();
            
            sf2d_swapbuffers();


		}

		// free pointers
		for(i = 0; i < num_files; i++) free(file_list[i]);
		free(file_list);

		for(i = 0; i < num_dirs; i++) free(dir_list[i]);
		free(dir_list);
        
        free(file_name);
	}
	
	
	return return_value;
}