/*! Create a directory * * @param[in,out] r newlib reentrancy struct * @param[in] path Path of directory to create * @param[in] mode Permissions of created directory * * @returns 0 for success * @returns -1 for error */ static int sdmc_mkdir(struct _reent *r, const char *path, int mode) { Result rc; const char *pathptr = NULL; pathptr = sdmc_fixpath(path); if(pathptr==NULL) { r->_errno=EINVAL; return -1; } /* TODO: Use mode to set directory attributes. */ rc = FSUSER_CreateDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, pathptr)); if(rc == 0) return 0; r->_errno = ENOSYS; return -1; }
// ================================================== Result FS_createDirectory(char* path, Handle* fsHandle, FS_archive* fsArchive) // -------------------------------------------------- { if (!path || !fsHandle || !fsArchive) return -1; Result ret; ret = FSUSER_CreateDirectory(fsHandle, *fsArchive, FS_makePath(PATH_CHAR, path)); return ret; }
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; }
void GBAConfigDirectory(char* out, size_t outLength) { struct VFile* portable; #ifdef _WIN32 wchar_t wpath[MAX_PATH]; wchar_t wprojectName[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH); HMODULE hModule = GetModuleHandleW(NULL); GetModuleFileNameW(hModule, wpath, MAX_PATH); PathRemoveFileSpecW(wpath); WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0); StringCchCatA(out, outLength, "\\portable.ini"); portable = VFileOpen(out, O_RDONLY); if (portable) { portable->close(portable); } else { wchar_t* home; SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &home); StringCchPrintfW(wpath, MAX_PATH, L"%ws\\%ws", home, wprojectName); CoTaskMemFree(home); CreateDirectoryW(wpath, NULL); } WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0); #elif defined(PSP2) UNUSED(portable); snprintf(out, outLength, "cache0:/%s", projectName); sceIoMkdir(out, 0777); #elif defined(GEKKO) UNUSED(portable); snprintf(out, outLength, "/%s", projectName); mkdir(out, 0777); #elif defined(_3DS) UNUSED(portable); snprintf(out, outLength, "/%s", projectName); FSUSER_CreateDirectory(sdmcArchive, fsMakePath(PATH_ASCII, out), 0); #else getcwd(out, outLength); strncat(out, PATH_SEP "portable.ini", outLength - strlen(out)); portable = VFileOpen(out, O_RDONLY); if (portable) { getcwd(out, outLength); portable->close(portable); return; } char* home = getenv("HOME"); snprintf(out, outLength, "%s/.config", home); mkdir(out, 0755); snprintf(out, outLength, "%s/.config/%s", home, binaryName); mkdir(out, 0755); #endif }
static Result action_paste_files_make_dst_directory(void* data, u32 index) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; u32 attributes = ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes; char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); FS_Path* fsPath = util_make_path_utf8(dstPath); if(fsPath != NULL) { Handle dirHandle = 0; if(R_SUCCEEDED(FSUSER_OpenDirectory(&dirHandle, pasteData->target->archive, *fsPath))) { FSDIR_Close(dirHandle); } else { res = FSUSER_CreateDirectory(pasteData->target->archive, *fsPath, attributes); } util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } if(R_SUCCEEDED(res)) { char parentPath[FILE_PATH_MAX]; util_get_parent_path(parentPath, dstPath, FILE_PATH_MAX); char baseDstPath[FILE_PATH_MAX]; if(pasteData->target->attributes & FS_ATTRIBUTE_DIRECTORY) { strncpy(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } else { util_get_parent_path(baseDstPath, pasteData->target->path, FILE_PATH_MAX); } if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) { list_item* dstItem = NULL; if(R_SUCCEEDED(res) && R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, attributes))) { linked_list_add(pasteData->items, dstItem); } } } return res; }
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; }