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:
|
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, 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, 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;
|
break;
|
||||||
case DriveMenuOperation::flashcard:
|
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, 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, 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;
|
break;
|
||||||
case DriveMenuOperation::gbaCart:
|
case DriveMenuOperation::gbaCart:
|
||||||
font->printf(0, 0, false, Alignment::left, Palette::white, STR_GBA_GAMECART.c_str(), romTitle[1]);
|
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:
|
case DriveMenuOperation::ramDrive:
|
||||||
font->print(0, 0, false, STR_RAMDRIVE_LABEL);
|
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, 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;
|
break;
|
||||||
case DriveMenuOperation::sysNand:
|
case DriveMenuOperation::sysNand:
|
||||||
font->print(0, 0, false, STR_SYSNAND_LABEL);
|
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, 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;
|
break;
|
||||||
case DriveMenuOperation::fatImage:
|
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, 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, 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;
|
break;
|
||||||
case DriveMenuOperation::none:
|
case DriveMenuOperation::none:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -443,3 +443,22 @@ bool driveRemoved(Drive drive) {
|
|||||||
|
|
||||||
return false;
|
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 u64 getBytesFree(const char* drivePath);
|
||||||
extern bool driveWritable(Drive drive);
|
extern bool driveWritable(Drive drive);
|
||||||
extern bool driveRemoved(Drive drive);
|
extern bool driveRemoved(Drive drive);
|
||||||
|
extern u64 driveSizeFree(Drive drive);
|
||||||
|
|
||||||
#endif //FLASHCARD_H
|
#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());
|
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);
|
DIR *isDir = opendir(sourcePath);
|
||||||
|
|
||||||
if (isDir != NULL) {
|
if (isDir != NULL) {
|
||||||
closedir(isDir);
|
closedir(isDir);
|
||||||
|
|
||||||
// Source path is a directory
|
// Source path is a directory
|
||||||
|
char startPath[PATH_MAX];
|
||||||
|
getcwd(startPath, PATH_MAX);
|
||||||
|
|
||||||
chdir(sourcePath);
|
chdir(sourcePath);
|
||||||
std::vector<DirEntry> dirContents;
|
std::vector<DirEntry> dirContents;
|
||||||
getDirectoryContents(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);
|
mkdir(destinationPath, 0777);
|
||||||
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
||||||
chdir(sourcePath);
|
chdir(sourcePath);
|
||||||
@ -199,25 +238,39 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
|||||||
|
|
||||||
chdir(destinationPath);
|
chdir(destinationPath);
|
||||||
chdir("..");
|
chdir("..");
|
||||||
return 1;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
closedir(isDir);
|
closedir(isDir);
|
||||||
|
|
||||||
// Source path is a file
|
// Source path is a file
|
||||||
FILE* sourceFile = fopen(sourcePath, "rb");
|
FILE* sourceFile = fopen(sourcePath, "rb");
|
||||||
off_t fsize = 0;
|
long fsize = 0;
|
||||||
if (sourceFile) {
|
if (sourceFile) {
|
||||||
fseek(sourceFile, 0, SEEK_END);
|
fseek(sourceFile, 0, SEEK_END);
|
||||||
fsize = ftell(sourceFile); // Get source file's size
|
fsize = ftell(sourceFile); // Get source file's size
|
||||||
fseek(sourceFile, 0, SEEK_SET);
|
fseek(sourceFile, 0, SEEK_SET);
|
||||||
} else {
|
} 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");
|
FILE* destinationFile = fopen(destinationPath, "wb");
|
||||||
if (!destinationFile) {
|
if (!destinationFile) {
|
||||||
fclose(sourceFile);
|
fclose(sourceFile);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
font->clear(false);
|
font->clear(false);
|
||||||
@ -233,8 +286,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
|||||||
// Cancel copying
|
// Cancel copying
|
||||||
fclose(sourceFile);
|
fclose(sourceFile);
|
||||||
fclose(destinationFile);
|
fclose(destinationFile);
|
||||||
return -1;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
font->print((offset / (fsize / (SCREEN_COLS - 2))) + 1, 1, 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) {
|
if(fwrite(copyBuf, 1, numr, destinationFile) != numr) {
|
||||||
fclose(sourceFile);
|
fclose(sourceFile);
|
||||||
fclose(destinationFile);
|
fclose(destinationFile);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
offset += copyBufSize;
|
offset += copyBufSize;
|
||||||
|
|
||||||
@ -254,12 +306,12 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
|
|||||||
fclose(sourceFile);
|
fclose(sourceFile);
|
||||||
fclose(destinationFile);
|
fclose(destinationFile);
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ extern std::string getBytes(off_t bytes);
|
|||||||
extern off_t getFileSize(const char *fileName);
|
extern off_t getFileSize(const char *fileName);
|
||||||
extern bool calculateSHA1(const char *fileName, u8 *sha1);
|
extern bool calculateSHA1(const char *fileName, u8 *sha1);
|
||||||
extern int trimNds(const char *fileName);
|
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);
|
void changeFileAttribs(const DirEntry *entry);
|
||||||
|
|
||||||
#endif // FILE_COPY
|
#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;
|
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();
|
dirContents.clear();
|
||||||
|
|
||||||
DIR *pdir = opendir (".");
|
DIR *pdir = opendir (".");
|
||||||
@ -84,6 +84,7 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
|||||||
if (pdir == nullptr) {
|
if (pdir == nullptr) {
|
||||||
font->print(0, 0, true, STR_UNABLE_TO_OPEN_DIRECTORY);
|
font->print(0, 0, true, STR_UNABLE_TO_OPEN_DIRECTORY);
|
||||||
font->update(true);
|
font->update(true);
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while (true) {
|
||||||
dirent *pent = readdir(pdir);
|
dirent *pent = readdir(pdir);
|
||||||
@ -109,6 +110,8 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
|
|||||||
|
|
||||||
// Add ".." to top of list
|
// Add ".." to top of list
|
||||||
dirContents.insert(dirContents.begin(), {"..", 0, true, false});
|
dirContents.insert(dirContents.begin(), {"..", 0, true, false});
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showDirectoryContents(std::vector<DirEntry> &dirContents, int fileOffset, int startRow) {
|
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) {
|
void recRemove(const char *path, std::vector<DirEntry> dirContents) {
|
||||||
chdir (path);
|
if(chdir(path) == 0 && getDirectoryContents(dirContents)) {
|
||||||
getDirectoryContents(dirContents);
|
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
||||||
for (int i = 1; i < ((int)dirContents.size()); i++) {
|
DirEntry &entry = dirContents[i];
|
||||||
DirEntry &entry = dirContents[i];
|
if (entry.isDirectory)
|
||||||
if (entry.isDirectory)
|
recRemove(entry.name.c_str(), dirContents);
|
||||||
recRemove(entry.name.c_str(), dirContents);
|
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
|
||||||
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
|
remove(entry.name.c_str());
|
||||||
remove(entry.name.c_str());
|
}
|
||||||
}
|
}
|
||||||
|
chdir("..");
|
||||||
|
remove(path);
|
||||||
}
|
}
|
||||||
chdir ("..");
|
|
||||||
remove(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fileBrowse_drawBottomScreen(DirEntry* entry) {
|
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);
|
bool extension(const std::string_view filename, const std::vector<std::string_view> &extensions);
|
||||||
|
|
||||||
std::string browseForFile (void);
|
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(HEADER_TITLE, "Header Title: %s")
|
||||||
STRING(TITLE_ID, "Title ID: %s")
|
STRING(TITLE_ID, "Title ID: %s")
|
||||||
STRING(TITLE_IN_LANGUAGE, "Title: (\\DV %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
|
// Drive labels
|
||||||
STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)")
|
STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)")
|
||||||
|
|||||||
@ -37,6 +37,7 @@ START_FAILED_ERROR_N=Start failed. Error %d
|
|||||||
HEADER_TITLE=Header Title: %s
|
HEADER_TITLE=Header Title: %s
|
||||||
TITLE_ID=Title ID: %s
|
TITLE_ID=Title ID: %s
|
||||||
TITLE_IN_LANGUAGE=Title: (\DV %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)
|
SDCARD_LABEL=[sd:] SDCARD (%s)
|
||||||
FLASHCARD_LABEL=[fat:] FLASHCARD (%s)
|
FLASHCARD_LABEL=[fat:] FLASHCARD (%s)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user