mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-11-02 00:11:07 -04:00
Warn if file too large to copy (#163)
This commit is contained in:
parent
ca3d9a8638
commit
fb9b56f622
@ -160,12 +160,12 @@ void dm_drawBottomScreen(void) {
|
||||
case DriveMenuOperation::sdCard:
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, STR_SDCARD_LABEL.c_str(), sdLabel[0] == 0 ? STR_UNTITLED.c_str() : sdLabel);
|
||||
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SD_FAT.c_str(), getBytes(sdSize).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("sd:/")).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::sdCard)).c_str());
|
||||
break;
|
||||
case DriveMenuOperation::flashcard:
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, STR_FLASHCARD_LABEL.c_str(), fatLabel[0] == 0 ? STR_UNTITLED.c_str() : fatLabel);
|
||||
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SLOT1_FAT.c_str(), getBytes(fatSize).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("fat:/")).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::flashcard)).c_str());
|
||||
break;
|
||||
case DriveMenuOperation::gbaCart:
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, STR_GBA_GAMECART.c_str(), romTitle[1]);
|
||||
@ -186,16 +186,17 @@ void dm_drawBottomScreen(void) {
|
||||
case DriveMenuOperation::ramDrive:
|
||||
font->print(0, 0, false, STR_RAMDRIVE_LABEL);
|
||||
font->printf(0, 1, false, Alignment::left, Palette::white, STR_RAMDRIVE_FAT.c_str(), getBytes(ramdSize).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("ram:/")).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::ramDrive)).c_str());
|
||||
break;
|
||||
case DriveMenuOperation::sysNand:
|
||||
font->print(0, 0, false, STR_SYSNAND_LABEL);
|
||||
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(nandSize).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("nand:/")).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nand)).c_str());
|
||||
break;
|
||||
case DriveMenuOperation::fatImage:
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel);
|
||||
font->printf(0, 1, false, Alignment::left, Palette::white, STR_FAT_IMAGE.c_str(), getBytes(imgSize).c_str());
|
||||
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::fatImg)).c_str());
|
||||
break;
|
||||
case DriveMenuOperation::none:
|
||||
break;
|
||||
|
||||
@ -443,3 +443,22 @@ bool driveRemoved(Drive drive) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 driveSizeFree(Drive drive) {
|
||||
switch(drive) {
|
||||
case Drive::sdCard:
|
||||
return getBytesFree("sd:/");
|
||||
case Drive::flashcard:
|
||||
return getBytesFree("fat:/");
|
||||
case Drive::ramDrive:
|
||||
return getBytesFree("ram:/");
|
||||
case Drive::nand:
|
||||
return getBytesFree("nand:/");
|
||||
case Drive::nitroFS:
|
||||
return 0;
|
||||
case Drive::fatImg:
|
||||
return getBytesFree("img:/");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -56,5 +56,6 @@ extern void imgUnmount(void);
|
||||
extern u64 getBytesFree(const char* drivePath);
|
||||
extern bool driveWritable(Drive drive);
|
||||
extern bool driveRemoved(Drive drive);
|
||||
extern u64 driveSizeFree(Drive drive);
|
||||
|
||||
#endif //FLASHCARD_H
|
||||
|
||||
@ -180,17 +180,56 @@ void dirCopy(const DirEntry &entry, int i, const char *destinationPath, const ch
|
||||
if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry.name)).c_str(), (destinationPath + ("/" + entry.name)).c_str());
|
||||
}
|
||||
|
||||
int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
u64 dirSize(const std::vector<DirEntry> &dirContents) {
|
||||
u64 size = 0;
|
||||
|
||||
for(const DirEntry &entry : dirContents) {
|
||||
if(entry.name == "." || entry.name == "..")
|
||||
continue;
|
||||
|
||||
if(entry.isDirectory) {
|
||||
std::vector<DirEntry> subdirContents;
|
||||
if(chdir(entry.name.c_str()) == 0 && getDirectoryContents(subdirContents)) {
|
||||
size += dirSize(subdirContents);
|
||||
chdir("..");
|
||||
}
|
||||
} else {
|
||||
size += getFileSize(entry.name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
DIR *isDir = opendir(sourcePath);
|
||||
|
||||
if (isDir != NULL) {
|
||||
closedir(isDir);
|
||||
|
||||
// Source path is a directory
|
||||
char startPath[PATH_MAX];
|
||||
getcwd(startPath, PATH_MAX);
|
||||
|
||||
chdir(sourcePath);
|
||||
std::vector<DirEntry> dirContents;
|
||||
getDirectoryContents(dirContents);
|
||||
|
||||
// Check that everything will fit
|
||||
if(dirSize(dirContents) > driveSizeFree(currentDrive)) {
|
||||
font->clear(false);
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, (STR_FILE_TOO_BIG + "\n\n" + STR_A_OK).c_str(), sourcePath);
|
||||
font->update(false);
|
||||
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
} while(!(keysDown() & KEY_A));
|
||||
|
||||
chdir(startPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
mkdir(destinationPath, 0777);
|
||||
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
||||
chdir(sourcePath);
|
||||
@ -199,25 +238,39 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
|
||||
chdir(destinationPath);
|
||||
chdir("..");
|
||||
return 1;
|
||||
return true;
|
||||
} else {
|
||||
closedir(isDir);
|
||||
|
||||
// Source path is a file
|
||||
FILE* sourceFile = fopen(sourcePath, "rb");
|
||||
off_t fsize = 0;
|
||||
long fsize = 0;
|
||||
if (sourceFile) {
|
||||
fseek(sourceFile, 0, SEEK_END);
|
||||
fsize = ftell(sourceFile); // Get source file's size
|
||||
fseek(sourceFile, 0, SEEK_SET);
|
||||
} else {
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the file will fit
|
||||
if((u64)fsize > driveSizeFree(currentDrive)) {
|
||||
font->clear(false);
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, (STR_FILE_TOO_BIG + "\n\n" + STR_A_OK).c_str(), sourcePath);
|
||||
font->update(false);
|
||||
|
||||
do {
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
} while(!(keysDown() & KEY_A));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* destinationFile = fopen(destinationPath, "wb");
|
||||
if (!destinationFile) {
|
||||
fclose(sourceFile);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
font->clear(false);
|
||||
@ -233,8 +286,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
// Cancel copying
|
||||
fclose(sourceFile);
|
||||
fclose(destinationFile);
|
||||
return -1;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
font->print((offset / (fsize / (SCREEN_COLS - 2))) + 1, 1, false, "=");
|
||||
@ -246,7 +298,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
if(fwrite(copyBuf, 1, numr, destinationFile) != numr) {
|
||||
fclose(sourceFile);
|
||||
fclose(destinationFile);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
offset += copyBufSize;
|
||||
|
||||
@ -254,12 +306,12 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||
fclose(sourceFile);
|
||||
fclose(destinationFile);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ extern std::string getBytes(off_t bytes);
|
||||
extern off_t getFileSize(const char *fileName);
|
||||
extern bool calculateSHA1(const char *fileName, u8 *sha1);
|
||||
extern int trimNds(const char *fileName);
|
||||
extern int fcopy(const char *sourcePath, const char *destinationPath);
|
||||
extern bool fcopy(const char *sourcePath, const char *destinationPath);
|
||||
void changeFileAttribs(const DirEntry *entry);
|
||||
|
||||
#endif // FILE_COPY
|
||||
|
||||
@ -76,7 +76,7 @@ bool dirEntryPredicate (const DirEntry& lhs, const DirEntry& rhs) {
|
||||
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
|
||||
}
|
||||
|
||||
void getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
||||
bool getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
||||
dirContents.clear();
|
||||
|
||||
DIR *pdir = opendir (".");
|
||||
@ -84,6 +84,7 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
||||
if (pdir == nullptr) {
|
||||
font->print(0, 0, true, STR_UNABLE_TO_OPEN_DIRECTORY);
|
||||
font->update(true);
|
||||
return false;
|
||||
} else {
|
||||
while (true) {
|
||||
dirent *pent = readdir(pdir);
|
||||
@ -109,6 +110,8 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
||||
|
||||
// Add ".." to top of list
|
||||
dirContents.insert(dirContents.begin(), {"..", 0, true, false});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void showDirectoryContents(std::vector<DirEntry> &dirContents, int fileOffset, int startRow) {
|
||||
@ -559,18 +562,18 @@ bool fileBrowse_paste(char dest[256]) {
|
||||
}
|
||||
|
||||
void recRemove(const char *path, std::vector<DirEntry> dirContents) {
|
||||
chdir (path);
|
||||
getDirectoryContents(dirContents);
|
||||
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
||||
DirEntry &entry = dirContents[i];
|
||||
if (entry.isDirectory)
|
||||
recRemove(entry.name.c_str(), dirContents);
|
||||
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
|
||||
remove(entry.name.c_str());
|
||||
if(chdir(path) == 0 && getDirectoryContents(dirContents)) {
|
||||
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
||||
DirEntry &entry = dirContents[i];
|
||||
if (entry.isDirectory)
|
||||
recRemove(entry.name.c_str(), dirContents);
|
||||
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
|
||||
remove(entry.name.c_str());
|
||||
}
|
||||
}
|
||||
chdir("..");
|
||||
remove(path);
|
||||
}
|
||||
chdir ("..");
|
||||
remove(path);
|
||||
}
|
||||
|
||||
void fileBrowse_drawBottomScreen(DirEntry* entry) {
|
||||
|
||||
@ -57,7 +57,7 @@ enum class FileOperation {
|
||||
bool extension(const std::string_view filename, const std::vector<std::string_view> &extensions);
|
||||
|
||||
std::string browseForFile (void);
|
||||
void getDirectoryContents (std::vector<DirEntry>& dirContents);
|
||||
bool getDirectoryContents (std::vector<DirEntry>& dirContents);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ STRING(START_FAILED_ERROR_N, "Start failed. Error %d")
|
||||
STRING(HEADER_TITLE, "Header Title: %s")
|
||||
STRING(TITLE_ID, "Title ID: %s")
|
||||
STRING(TITLE_IN_LANGUAGE, "Title: (\\DV %s)")
|
||||
STRING(FILE_TOO_BIG, "%s is too large to copy to this drive. Please delete some files and try again.")
|
||||
|
||||
// Drive labels
|
||||
STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)")
|
||||
|
||||
@ -37,6 +37,7 @@ START_FAILED_ERROR_N=Start failed. Error %d
|
||||
HEADER_TITLE=Header Title: %s
|
||||
TITLE_ID=Title ID: %s
|
||||
TITLE_IN_LANGUAGE=Title: (\DV %s)
|
||||
FILE_TOO_BIG=%s is too large to copy to this drive. Please delete some files and try again.
|
||||
|
||||
SDCARD_LABEL=[sd:] SDCARD (%s)
|
||||
FLASHCARD_LABEL=[fat:] FLASHCARD (%s)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user