mirror of
https://github.com/rvtr/TDT.git
synced 2025-10-31 13:51:07 -04:00
Delete storage.c
This commit is contained in:
parent
977ea6e7de
commit
fb8e630a4f
539
src/storage.c
539
src/storage.c
@ -1,539 +0,0 @@
|
|||||||
#include "storage.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include <nds.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#define TITLE_LIMIT 39
|
|
||||||
|
|
||||||
//Printing
|
|
||||||
void printBytes(unsigned long long bytes)
|
|
||||||
{
|
|
||||||
if (bytes < 1024)
|
|
||||||
iprintf("%dB", (unsigned int)bytes);
|
|
||||||
|
|
||||||
else if (bytes < 1024 * 1024)
|
|
||||||
printf("%.2fKB", (float)bytes / 1024);
|
|
||||||
|
|
||||||
else if (bytes < 1024 * 1024 * 1024)
|
|
||||||
printf("%.2fMB", (float)bytes / 1024 / 1024);
|
|
||||||
|
|
||||||
else
|
|
||||||
printf("%.2fGB", (float)bytes / 1024 / 1024 / 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printFileInfo(const char* path)
|
|
||||||
{
|
|
||||||
if (path == NULL) return;
|
|
||||||
|
|
||||||
clearScreen(&topScreen);
|
|
||||||
|
|
||||||
tDSiHeader* header = (tDSiHeader*)malloc(sizeof(tDSiHeader));
|
|
||||||
tNDSBanner* banner = (tNDSBanner*)malloc(sizeof(tNDSBanner));
|
|
||||||
|
|
||||||
FILE* f = fopen(path, "rb");
|
|
||||||
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
if (fread(header, sizeof(tDSiHeader), 1, f) != 1)
|
|
||||||
iprintf("Could not read dsi header.\n");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fseek(f, header->ndshdr.bannerOffset, SEEK_SET);
|
|
||||||
|
|
||||||
if (fread(banner, sizeof(tNDSBanner), 1, f) != 1)
|
|
||||||
iprintf("Could not read banner.\n");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Proper title
|
|
||||||
{
|
|
||||||
char gameTitle[128+1];
|
|
||||||
gameTitle[128] = '\0';
|
|
||||||
|
|
||||||
//Convert 2 byte characters to 1 byte
|
|
||||||
for (int i = 0; i < 128; i++)
|
|
||||||
gameTitle[i] = (char)banner->titles[1][i];
|
|
||||||
|
|
||||||
iprintf("%s\n\n", gameTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
//File size
|
|
||||||
{
|
|
||||||
iprintf("Size: ");
|
|
||||||
printBytes(getFileSize(f));
|
|
||||||
iprintf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
iprintf("Label: %.12s\n", header->ndshdr.gameTitle);
|
|
||||||
iprintf("Game Code: %.4s\n", header->ndshdr.gameCode);
|
|
||||||
|
|
||||||
//System type
|
|
||||||
{
|
|
||||||
iprintf("Unit Code: ");
|
|
||||||
|
|
||||||
switch (header->ndshdr.unitCode)
|
|
||||||
{
|
|
||||||
case 0: iprintf("NDS"); break;
|
|
||||||
case 2: iprintf("NDS+DSi"); break;
|
|
||||||
case 3: iprintf("DSi"); break;
|
|
||||||
default: iprintf("unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
iprintf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Application type
|
|
||||||
{
|
|
||||||
iprintf("Program Type: ");
|
|
||||||
|
|
||||||
switch (header->ndshdr.reserved1[7])
|
|
||||||
{
|
|
||||||
case 0x3: iprintf("Normal"); break;
|
|
||||||
case 0xB: iprintf("Sys"); break;
|
|
||||||
case 0xF: iprintf("Debug/Sys"); break;
|
|
||||||
default: iprintf("unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
iprintf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//DSi data
|
|
||||||
if (header->tid_high == 0x00030004 ||
|
|
||||||
header->tid_high == 0x00030005 ||
|
|
||||||
header->tid_high == 0x00030015 ||
|
|
||||||
header->tid_high == 0x00030017 ||
|
|
||||||
header->tid_high == 0x00030000)
|
|
||||||
{
|
|
||||||
iprintf("Title ID: %08x %08x\n", (unsigned int)header->tid_high,
|
|
||||||
(unsigned int)header->tid_low);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Print full file path
|
|
||||||
iprintf("\n%s\n", path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
free(banner);
|
|
||||||
free(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Progress bar
|
|
||||||
void printProgressBar(int percent)
|
|
||||||
{
|
|
||||||
//Limit 100 max
|
|
||||||
if (percent > 100)
|
|
||||||
percent = 100;
|
|
||||||
|
|
||||||
//Print frame
|
|
||||||
iprintf("\x1b[23;0H[");
|
|
||||||
iprintf("\x1b[23;31H]");
|
|
||||||
|
|
||||||
//Skip if there are no bars
|
|
||||||
if (percent <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Print bars
|
|
||||||
int bars = (int)(30.f * (percent / 100.f)) + 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < bars; i++)
|
|
||||||
iprintf("\x1b[23;%dH|", 1 + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearProgressBar()
|
|
||||||
{
|
|
||||||
iprintf("\x1b[23;0H ");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Files
|
|
||||||
bool copyFile(const char* in, char* out)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (in == NULL || out == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FILE* fin = fopen(in, "rb");
|
|
||||||
FILE* fout = fopen(out, "wb");
|
|
||||||
|
|
||||||
if (fin == NULL || fout == NULL)
|
|
||||||
{
|
|
||||||
fclose(fin);
|
|
||||||
fclose(fout);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
consoleSelect(&topScreen);
|
|
||||||
|
|
||||||
int fileSize = getFileSize(fin);
|
|
||||||
int totalBytesRead = 0;
|
|
||||||
|
|
||||||
int percent = 0;
|
|
||||||
int lastPercent = 0;
|
|
||||||
|
|
||||||
const int buffSize = 1024*8; //Arbitrary. A value too large freezes the system.
|
|
||||||
unsigned char* buffer = (unsigned char*)malloc(sizeof(unsigned char) * buffSize);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int bytesRead = fread(buffer, 1, buffSize, fin);
|
|
||||||
fwrite(buffer, 1, bytesRead, fout);
|
|
||||||
|
|
||||||
totalBytesRead += bytesRead;
|
|
||||||
|
|
||||||
//Re-print progress bar every so often, but not every time
|
|
||||||
percent = (int)( ((float)totalBytesRead / (float)fileSize) * 100.f );
|
|
||||||
if (percent != lastPercent)
|
|
||||||
{
|
|
||||||
lastPercent = percent;
|
|
||||||
printProgressBar(percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (feof(fin))
|
|
||||||
{
|
|
||||||
result = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ferror(fin))
|
|
||||||
{
|
|
||||||
result = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
|
|
||||||
clearProgressBar();
|
|
||||||
consoleSelect(&bottomScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fin);
|
|
||||||
fclose(fout);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long getFileSize(FILE* f)
|
|
||||||
{
|
|
||||||
if (!f)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
unsigned long long size = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long getFileSizePath(const char* path)
|
|
||||||
{
|
|
||||||
if (path == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
FILE* f = fopen(path, "rb");
|
|
||||||
unsigned long long size = getFileSize(f);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool padFile(const char* path, int size)
|
|
||||||
{
|
|
||||||
FILE* f = fopen(path, "ab");
|
|
||||||
|
|
||||||
if (!f)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char zero = 0;
|
|
||||||
fwrite(&zero, sizeof(char), size, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Directories
|
|
||||||
bool dirExists(const char* path)
|
|
||||||
{
|
|
||||||
if (path == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
DIR* dir = opendir(path);
|
|
||||||
|
|
||||||
if (dir)
|
|
||||||
{
|
|
||||||
closedir(dir);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Incomplete
|
|
||||||
int copyDir(char* in, char* out)
|
|
||||||
{
|
|
||||||
if (in == NULL || out == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
DIR* dir;
|
|
||||||
struct dirent *ent;
|
|
||||||
|
|
||||||
dir = opendir(in);
|
|
||||||
|
|
||||||
if (!dir)
|
|
||||||
{
|
|
||||||
closedir(dir);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mkdir(out, 0777);
|
|
||||||
|
|
||||||
while ( (ent = readdir(dir)) != NULL )
|
|
||||||
{
|
|
||||||
if(strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ent->d_type == DT_DIR)
|
|
||||||
{
|
|
||||||
char inPath[512];
|
|
||||||
char outPath[512];
|
|
||||||
|
|
||||||
sprintf(inPath, "%s%s/", in, ent->d_name);
|
|
||||||
sprintf(outPath, "%s%s/", out, ent->d_name);
|
|
||||||
|
|
||||||
copyDir(inPath, outPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char inPath[512];
|
|
||||||
char outPath[512];
|
|
||||||
|
|
||||||
sprintf(inPath, "%s%s", in, ent->d_name);
|
|
||||||
sprintf(outPath, "%s%s", out, ent->d_name);
|
|
||||||
|
|
||||||
copyFile(inPath, outPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool deleteDir(const char* path)
|
|
||||||
{
|
|
||||||
if (strcmp("/", path) == 0)
|
|
||||||
{
|
|
||||||
//oh fuck no
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR* dir;
|
|
||||||
struct dirent *ent;
|
|
||||||
|
|
||||||
dir = opendir(path);
|
|
||||||
|
|
||||||
if (!dir)
|
|
||||||
{
|
|
||||||
closedir(dir);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ( (ent = readdir(dir)) != NULL )
|
|
||||||
{
|
|
||||||
if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ent->d_type == DT_DIR)
|
|
||||||
{
|
|
||||||
//Delete directory
|
|
||||||
char subpath[512];
|
|
||||||
sprintf(subpath, "%s%s/", path, ent->d_name);
|
|
||||||
|
|
||||||
deleteDir(subpath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Delete file
|
|
||||||
char fpath[512];
|
|
||||||
sprintf(fpath, "%s%s", path, ent->d_name);
|
|
||||||
|
|
||||||
remove(fpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
rmdir(path);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long getDirSize(const char* path)
|
|
||||||
{
|
|
||||||
if (path == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unsigned long long size = 0;
|
|
||||||
|
|
||||||
DIR* dir;
|
|
||||||
struct dirent *ent;
|
|
||||||
|
|
||||||
dir = opendir(path);
|
|
||||||
|
|
||||||
if (dir)
|
|
||||||
{
|
|
||||||
while ( (ent = readdir(dir)) != NULL )
|
|
||||||
{
|
|
||||||
if(strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ent->d_type == DT_DIR)
|
|
||||||
{
|
|
||||||
char fullpath[512];
|
|
||||||
sprintf(fullpath, "%s%s/", path, ent->d_name);
|
|
||||||
|
|
||||||
size += getDirSize(fullpath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char fullpath[256];
|
|
||||||
sprintf(fullpath, "%s%s", path, ent->d_name);
|
|
||||||
|
|
||||||
size += getFileSizePath(fullpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Home menu
|
|
||||||
int getMenuSlots()
|
|
||||||
{
|
|
||||||
//Assume the home menu has a hard limit on slots
|
|
||||||
//Find a better way to do this
|
|
||||||
return TITLE_LIMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NUM_OF_DIRECTORIES 3
|
|
||||||
static const char* directories[] = {
|
|
||||||
"00030004",
|
|
||||||
"00030005",
|
|
||||||
"00030015"
|
|
||||||
};
|
|
||||||
|
|
||||||
int getMenuSlotsFree()
|
|
||||||
{
|
|
||||||
//Get number of open menu slots by subtracting the number of directories in the title folders
|
|
||||||
//Find a better way to do this
|
|
||||||
|
|
||||||
int freeSlots = TITLE_LIMIT;
|
|
||||||
|
|
||||||
DIR* dir;
|
|
||||||
struct dirent* ent;
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_OF_DIRECTORIES; i++)
|
|
||||||
{
|
|
||||||
char path[256];
|
|
||||||
sprintf(path, "/title/%s", directories[i]);
|
|
||||||
|
|
||||||
dir = opendir(path);
|
|
||||||
|
|
||||||
if (dir)
|
|
||||||
{
|
|
||||||
while ( (ent = readdir(dir)) != NULL )
|
|
||||||
{
|
|
||||||
if(strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ent->d_type == DT_DIR)
|
|
||||||
freeSlots -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return freeSlots;
|
|
||||||
}
|
|
||||||
|
|
||||||
//SD Card
|
|
||||||
bool sdIsInserted()
|
|
||||||
{
|
|
||||||
// return sdmmc_cardinserted();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long getSDCardSize()
|
|
||||||
{
|
|
||||||
if (sdIsInserted())
|
|
||||||
{
|
|
||||||
struct statvfs st;
|
|
||||||
if (statvfs("/", &st) == 0)
|
|
||||||
return st.f_bsize * st.f_blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long getSDCardFree()
|
|
||||||
{
|
|
||||||
if (sdIsInserted())
|
|
||||||
{
|
|
||||||
struct statvfs st;
|
|
||||||
if (statvfs("/", &st) == 0)
|
|
||||||
return st.f_bsize * st.f_bavail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Internal storage
|
|
||||||
int getDsiSize()
|
|
||||||
{
|
|
||||||
//The DSi has 256MB of internal storage. Some is unavailable and used by other things.
|
|
||||||
//Find a better way to do this
|
|
||||||
//return 248 * 1024 * 1024;
|
|
||||||
return 240 * 1024 * 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getDsiFree()
|
|
||||||
{
|
|
||||||
//Get free space by subtracting file sizes in emulated nand folders
|
|
||||||
//Find a better way to do this
|
|
||||||
int size = getDsiSize();
|
|
||||||
|
|
||||||
size -= getDirSize("/sys/");
|
|
||||||
size -= getDirSize("/title/");
|
|
||||||
size -= getDirSize("/ticket/");
|
|
||||||
size -= getDirSize("/shared1/");
|
|
||||||
size -= getDirSize("/shared2/");
|
|
||||||
size -= getDirSize("/import/");
|
|
||||||
size -= getDirSize("/tmp/");
|
|
||||||
size -= getDirSize("/progress/");
|
|
||||||
|
|
||||||
size -= getDirSize("/photo/");
|
|
||||||
size -= getDirSize("/private/");
|
|
||||||
|
|
||||||
size += getDirSize("/title/00030015/");
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user