/* 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 #include #include #include #include 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; }