mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 12:46:53 +01:00
9e79c9d99b
* code cleanup
295 lines
7.1 KiB
C
295 lines
7.1 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;
|
|
}
|