mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-23 10:21:55 +01:00
312 lines
7.2 KiB
C
312 lines
7.2 KiB
C
/*
|
|
From Custom IOS Module (FAT)
|
|
|
|
Copyright (C) 2009 Waninkoko.
|
|
Copyright (C) 2010 Hermes.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "fatffs_util.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/dir.h>
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
|
|
extern u32 nand_mode;
|
|
|
|
s32 FAT_DeleteDir(const char *dirpath)
|
|
{
|
|
DIR_ITER *dir;
|
|
|
|
s32 ret;
|
|
|
|
/* Open directory */
|
|
dir = diropen(dirpath);
|
|
if (!dir) return -1;
|
|
|
|
/* Read entries */
|
|
for (;;)
|
|
{
|
|
char filename[256], newpath[256];
|
|
struct stat filestat;
|
|
|
|
/* Read entry */
|
|
if (dirnext(dir, filename, &filestat)) break;
|
|
|
|
/* Non valid entry */
|
|
if (filename[0] == '.') continue;
|
|
|
|
/* Generate entry path */
|
|
strcpy(newpath, dirpath);
|
|
strcat(newpath, "/");
|
|
strcat(newpath, filename);
|
|
|
|
/* Delete directory contents */
|
|
if (filestat.st_mode & S_IFDIR) FAT_DeleteDir(newpath);
|
|
|
|
/* Delete object */
|
|
ret = remove(newpath);
|
|
|
|
/* Error */
|
|
if (ret != 0) break;
|
|
}
|
|
|
|
/* Close directory */
|
|
dirclose(dir);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int global_error = 0;
|
|
|
|
static char temp_read_buffer[16384] ATTRIBUTE_ALIGN( 32 );
|
|
|
|
s32 _FFS_to_FAT_Copy(const char *ffsdirpath, const char *fatdirpath)
|
|
{
|
|
int n;
|
|
u32 blocks, ionodes;
|
|
int pos = 0;
|
|
char *list;
|
|
s32 ret;
|
|
|
|
u32 ionodes_temp;
|
|
|
|
if (ISFS_GetUsage(ffsdirpath, &blocks, &ionodes))
|
|
{
|
|
global_error = -1;
|
|
return -1;
|
|
}
|
|
|
|
list = memalign(32, ionodes * 13);
|
|
|
|
if (!list)
|
|
{
|
|
global_error = -2;
|
|
return -2;
|
|
}
|
|
|
|
if (ISFS_ReadDir(ffsdirpath, list, &ionodes))
|
|
{
|
|
free(list);
|
|
global_error = -3;
|
|
return -3;
|
|
}
|
|
|
|
if (ionodes) mkdir(fatdirpath, S_IRWXO | S_IRWXG | S_IRWXU);
|
|
|
|
/* Read entries */
|
|
for (n = 0; n < ionodes; n++)
|
|
{
|
|
char * filename;
|
|
char newffspath[256], newfatpath[256];
|
|
|
|
/* Read entry */
|
|
filename = &list[pos];
|
|
pos += strlen(&list[pos]) + 1;
|
|
|
|
/* Non valid entry */
|
|
if (filename[0] == '.') continue;
|
|
|
|
/* Generate entry path */
|
|
strcpy(newffspath, ffsdirpath);
|
|
strcat(newffspath, "/");
|
|
strcat(newffspath, filename);
|
|
|
|
strcpy(newfatpath, fatdirpath);
|
|
strcat(newfatpath, "/");
|
|
strcat(newfatpath, filename);
|
|
|
|
ret = ISFS_ReadDir(newffspath, NULL, &ionodes_temp);
|
|
if (ret == 0) // it is a directory
|
|
{
|
|
|
|
_FFS_to_FAT_Copy(newffspath, newfatpath);
|
|
|
|
if (global_error)
|
|
{
|
|
free(list);
|
|
return global_error;
|
|
}
|
|
}
|
|
|
|
else // copy the file
|
|
{
|
|
int fd;
|
|
FILE *fp;
|
|
fd = ISFS_Open(newffspath, ISFS_OPEN_READ);
|
|
if (fd < 0)
|
|
{
|
|
global_error = -4;
|
|
free(list);
|
|
return global_error;
|
|
}
|
|
else
|
|
{
|
|
int len;
|
|
fp = fopen(newfatpath, "w");
|
|
if (!fd)
|
|
{
|
|
ISFS_Close(fd);
|
|
global_error = -5;
|
|
free(list);
|
|
return global_error;
|
|
}
|
|
|
|
len = ISFS_Seek(fd, 0, 2);
|
|
//if(len<0) {ISFS_Close(fd);global_error=-6;free(list);return global_error;}
|
|
ISFS_Seek(fd, 0, 0);
|
|
|
|
while (len > 0)
|
|
{
|
|
ret = len;
|
|
if (len > 16384) ret = 16384;
|
|
if (ISFS_Read(fd, temp_read_buffer, ret) != ret)
|
|
{
|
|
global_error = -7;
|
|
break;
|
|
}
|
|
if (fwrite(temp_read_buffer, 1, ret, fp) != ret)
|
|
{
|
|
global_error = -8;
|
|
break;
|
|
}
|
|
len -= ret;
|
|
}
|
|
|
|
fclose(fp);
|
|
ISFS_Close(fd);
|
|
|
|
if (global_error)
|
|
{
|
|
free(list);
|
|
return global_error;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
free(list);
|
|
return 0;
|
|
}
|
|
|
|
s32 FFS_to_FAT_Copy(const char *ffsdirpath, const char *fatdirpath)
|
|
{
|
|
u32 blocks, ionodes;
|
|
int ret;
|
|
|
|
char create_dir[256];
|
|
|
|
ISFS_Initialize();
|
|
|
|
ret = ISFS_GetUsage(ffsdirpath, &blocks, &ionodes);
|
|
|
|
if (ret == 0)
|
|
{
|
|
int n = 0;
|
|
|
|
// creating the path directory
|
|
|
|
strcpy(create_dir, fatdirpath);
|
|
|
|
while (create_dir[n] != 0 && create_dir[n] != '/')
|
|
n++;
|
|
|
|
if (create_dir[n] == '/') n++;
|
|
|
|
while (create_dir[n] != 0)
|
|
{
|
|
if (create_dir[n] == '/')
|
|
{
|
|
create_dir[n] = 0;
|
|
mkdir(create_dir, S_IRWXO | S_IRWXG | S_IRWXU);
|
|
create_dir[n] = '/';
|
|
}
|
|
n++;
|
|
}
|
|
global_error = 0;
|
|
// copy files
|
|
_FFS_to_FAT_Copy(ffsdirpath, fatdirpath);
|
|
|
|
ret = global_error = 0;
|
|
}
|
|
else ret = -101;
|
|
|
|
ISFS_Deinitialize();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
static char temp_cad[512];
|
|
|
|
void create_FAT_FFS_Directory(struct discHdr *header)
|
|
{
|
|
|
|
char device[2][4] = { "sd:", "ud:" };
|
|
|
|
if (!header) return;
|
|
|
|
sprintf((char *) temp_cad, "%s/nand%c", &device[(nand_mode & 2) != 0][0], (nand_mode & 0xc) ? 49
|
|
+ ((nand_mode >> 2) & 3) : '\0');
|
|
|
|
sprintf((char *) temp_cad + 32, "%2.2x%2.2x%2.2x%2.2x", header->id[0], header->id[1], header->id[2], header->id[3]);
|
|
|
|
sprintf((char *) temp_cad + 64, "%s/title/00010000/%s", temp_cad, temp_cad + 32);
|
|
sprintf((char *) temp_cad + 128, "%s/title/00010004/%s", temp_cad, temp_cad + 32);
|
|
sprintf((char *) temp_cad + 256, "/title/00010000/%s", temp_cad + 32);
|
|
sprintf((char *) temp_cad + 384, "/title/00010004/%s", temp_cad + 32);
|
|
|
|
}
|
|
|
|
int test_FAT_game(char * directory)
|
|
{
|
|
DIR_ITER * dir = NULL;
|
|
|
|
dir = diropen(directory);
|
|
|
|
if (dir)
|
|
{
|
|
dirclose(dir);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *get_FAT_directory1(void)
|
|
{
|
|
return temp_cad + 64;
|
|
}
|
|
|
|
char *get_FAT_directory2(void)
|
|
{
|
|
return temp_cad + 128;
|
|
}
|
|
|
|
char *get_FFS_directory1(void)
|
|
{
|
|
return temp_cad + 256;
|
|
}
|
|
|
|
char *get_FFS_directory2(void)
|
|
{
|
|
return temp_cad + 384;
|
|
}
|