2019-12-01 00:49:36 +00:00
# include <string.h>
2019-12-10 21:46:34 +00:00
# include "../mem/heap.h"
2019-12-01 00:49:36 +00:00
# include "gfx.h"
# include "fs.h"
# include "../utils/types.h"
# include "../libs/fatfs/ff.h"
# include "../utils/sprintf.h"
# include "../utils/btn.h"
# include "../gfx/gfx.h"
2019-12-01 19:31:17 +00:00
# include "../utils/util.h"
2020-01-06 17:42:57 +00:00
# include "io.h"
2019-12-01 00:49:36 +00:00
2020-01-04 12:20:28 +00:00
fs_entry * fileobjects ;
2019-12-01 00:49:36 +00:00
char rootpath [ 10 ] = " " ;
2019-12-10 15:57:43 +00:00
char * currentpath = " " ;
char * clipboard = " " ;
2019-12-01 19:31:17 +00:00
u8 clipboardhelper = 0 ;
extern const char sizevalues [ 4 ] [ 3 ] ;
extern int launch_payload ( char * path ) ;
2020-01-07 14:28:23 +00:00
menu_item explfilemenu [ 10 ] = {
2019-12-01 19:31:17 +00:00
{ " -- File Menu -- " , COLOR_BLUE , - 1 , 0 } ,
{ " FILE " , COLOR_GREEN , - 1 , 0 } ,
{ " \n SIZE " , COLOR_VIOLET , - 1 , 0 } ,
2020-01-07 14:28:23 +00:00
{ " ATTRIB " , COLOR_VIOLET , - 1 , 0 } ,
2019-12-01 19:31:17 +00:00
{ " \n \n \n Back " , COLOR_WHITE , - 1 , 1 } ,
{ " \n Copy to clipboard " , COLOR_BLUE , COPY , 1 } ,
{ " Move to clipboard " , COLOR_BLUE , MOVE , 1 } ,
2019-12-07 20:49:58 +00:00
{ " \n Delete file \n " , COLOR_RED , DELETE , 1 } ,
{ " Launch Payload " , COLOR_ORANGE , PAYLOAD , 1 } ,
{ " View Hex " , COLOR_GREEN , HEXVIEW , 1 }
2019-12-01 19:31:17 +00:00
} ;
2019-12-01 00:49:36 +00:00
2020-01-07 14:28:23 +00:00
menu_item explfoldermenu [ 6 ] = {
2020-01-01 23:38:36 +00:00
{ " -- Folder Menu -- \n " , COLOR_BLUE , - 1 , 0 } ,
2020-01-07 14:28:23 +00:00
{ " ATTRIB " , COLOR_VIOLET , - 1 , 0 } ,
{ " \n \n Back " , COLOR_WHITE , - 1 , 1 } ,
2020-01-01 23:38:36 +00:00
{ " Return to main menu \n " , COLOR_BLUE , EXITFOLDER , 1 } ,
2020-01-04 19:18:26 +00:00
{ " Copy to clipboard " , COLOR_VIOLET , COPYFOLDER , 1 } ,
2020-01-01 23:38:36 +00:00
{ " Delete folder " , COLOR_RED , DELETEFOLDER , 1 }
} ;
2019-12-03 09:06:11 +00:00
void writecurpath ( const char * in ) {
if ( currentpath ! = NULL )
free ( currentpath ) ;
size_t len = strlen ( in ) + 1 ;
currentpath = ( char * ) malloc ( len ) ;
strcpy ( currentpath , in ) ;
2019-12-10 15:57:43 +00:00
2019-12-03 09:06:11 +00:00
strcpy ( currentpath , in ) ;
}
2019-12-10 21:46:34 +00:00
void writeclipboard ( const char * in , bool move , bool folder ) {
2019-12-10 15:57:43 +00:00
if ( clipboard ! = NULL )
free ( clipboard ) ;
2019-12-03 09:06:11 +00:00
clipboardhelper = 0 ;
2019-12-10 21:46:34 +00:00
if ( move )
clipboardhelper | = ( OPERATIONMOVE ) ;
else
clipboardhelper | = ( OPERATIONCOPY ) ;
2019-12-03 09:06:11 +00:00
if ( folder )
clipboardhelper | = ( ISDIR ) ;
size_t len = strlen ( in ) + 1 ;
clipboard = ( char * ) malloc ( len ) ;
strcpy ( clipboard , in ) ;
2019-12-10 15:57:43 +00:00
2019-12-03 09:06:11 +00:00
strcpy ( clipboard , in ) ;
}
2020-01-07 14:28:23 +00:00
char * getnextloc ( const char * current , const char * add ) {
2020-01-04 00:00:11 +00:00
static char * ret ;
if ( ret ! = NULL ) {
free ( ret ) ;
ret = NULL ;
}
2019-12-01 00:49:36 +00:00
size_t size = strlen ( current ) + strlen ( add ) + 1 ;
ret = ( char * ) malloc ( size ) ;
if ( ! strcmp ( rootpath , current ) )
sprintf ( ret , " %s%s " , current , add ) ;
else
sprintf ( ret , " %s/%s " , current , add ) ;
return ret ;
}
2019-12-01 14:42:37 +00:00
char * getprevloc ( char * current ) {
2020-01-04 00:00:11 +00:00
static char * ret ;
char * temp ;
if ( ret ! = NULL ) {
free ( ret ) ;
ret = NULL ;
}
2019-12-01 14:42:37 +00:00
size_t size = strlen ( current ) + 1 ;
ret = ( char * ) malloc ( size ) ;
strcpy ( ret , current ) ;
temp = strrchr ( ret , ' / ' ) ;
memset ( temp , ' \0 ' , 1 ) ;
if ( strlen ( rootpath ) > strlen ( ret ) )
strcpy ( ret , rootpath ) ;
return ret ;
}
2020-01-06 16:40:05 +00:00
int getfileobjamount ( ) {
int amount = 0 ;
while ( fileobjects [ amount ] . name ! = NULL )
amount + + ;
return amount ;
}
2019-12-01 14:42:37 +00:00
fs_entry getfileobj ( int spot ) {
return fileobjects [ spot ] ;
}
2019-12-10 21:46:34 +00:00
void copyfile ( const char * path , const char * outfolder ) {
2020-01-07 14:28:23 +00:00
char * filename = strrchr ( path , ' / ' ) + 1 ;
2019-12-10 21:46:34 +00:00
char * outstring ;
int res ;
clearscreen ( ) ;
2020-01-07 14:28:23 +00:00
makestring ( getnextloc ( outfolder , filename ) , & outstring ) ;
2019-12-10 21:46:34 +00:00
gfx_printf ( " Note: \n To stop the transfer hold Vol- \n \n %s \n Progress: " , outstring ) ;
2020-01-07 14:28:23 +00:00
if ( ! strcmp ( path , outstring ) ) {
message ( COLOR_RED , " \n In and out are the same! " ) ;
}
else if ( clipboardhelper & OPERATIONMOVE ) {
if ( strcmp ( rootpath , " emmc:/ " ) ) {
2019-12-11 12:18:57 +00:00
f_rename ( path , outstring ) ;
2020-01-07 14:28:23 +00:00
readfolder ( currentpath ) ;
}
2019-12-11 12:18:57 +00:00
else
2020-01-04 19:18:26 +00:00
message ( COLOR_RED , " \n Moving in emummc is not allowed! " ) ;
2019-12-10 21:46:34 +00:00
}
else if ( clipboardhelper & OPERATIONCOPY ) {
2020-01-04 19:18:26 +00:00
res = copy ( path , outstring , true , true ) ;
2019-12-10 21:46:34 +00:00
if ( res ) {
gfx_printf ( " \n \n %kSomething went wrong while copying! \n \n Errcode: %d%k " , COLOR_RED , res , COLOR_WHITE ) ;
btn_wait ( ) ;
}
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2019-12-10 21:46:34 +00:00
}
else {
2020-01-04 19:18:26 +00:00
message ( COLOR_RED , " \n Clipboard is empty! " ) ;
2019-12-10 21:46:34 +00:00
}
free ( outstring ) ;
clipboardhelper = 0 ;
}
2019-12-01 00:49:36 +00:00
void addobject ( char * name , int spot , bool isfol , bool isarc ) {
2019-12-10 15:57:43 +00:00
size_t length = strlen ( name ) + 1 ;
u64 size = 0 ;
int sizes = 0 ;
2019-12-01 00:49:36 +00:00
fileobjects [ spot ] . property = 0 ;
2019-12-03 09:06:11 +00:00
if ( fileobjects [ spot ] . name ! = NULL ) {
free ( fileobjects [ spot ] . name ) ;
fileobjects [ spot ] . name = NULL ;
}
2019-12-10 15:57:43 +00:00
fileobjects [ spot ] . name = ( char * ) malloc ( length ) ;
strlcpy ( fileobjects [ spot ] . name , name , length ) ;
2019-12-01 00:49:36 +00:00
if ( isfol )
fileobjects [ spot ] . property | = ( ISDIR ) ;
else {
2019-12-10 15:57:43 +00:00
size = getfilesize ( getnextloc ( currentpath , name ) ) ;
2019-12-01 00:49:36 +00:00
while ( size > 1024 ) {
size / = 1024 ;
sizes + + ;
}
if ( sizes > 3 )
sizes = 0 ;
fileobjects [ spot ] . property | = ( 1 < < ( 4 + sizes ) ) ;
fileobjects [ spot ] . size = size ;
}
if ( isarc )
fileobjects [ spot ] . property | = ( ISARC ) ;
}
2020-01-04 12:20:28 +00:00
void clearfileobjects ( ) {
if ( fileobjects ! = NULL ) {
for ( int i = 0 ; fileobjects [ i ] . name ! = NULL ; i + + ) {
free ( fileobjects [ i ] . name ) ;
fileobjects [ i ] . name = NULL ;
}
free ( fileobjects ) ;
fileobjects = NULL ;
}
}
void createfileobjects ( int size ) {
fileobjects = calloc ( size + 1 , sizeof ( fs_entry ) ) ;
fileobjects [ size ] . name = NULL ;
}
2019-12-01 00:49:36 +00:00
int readfolder ( const char * path ) {
DIR dir ;
FILINFO fno ;
int folderamount = 0 , res ;
2020-01-04 12:20:28 +00:00
clearfileobjects ( ) ;
createfileobjects ( getfolderentryamount ( path ) ) ;
2020-01-01 23:38:36 +00:00
if ( ( res = f_opendir ( & dir , path ) ) ) {
2020-01-04 19:18:26 +00:00
message ( COLOR_RED , " Error during f_opendir: %d " , res ) ;
return - 1 ;
2019-12-01 00:49:36 +00:00
}
2020-01-04 12:20:28 +00:00
while ( ! f_readdir ( & dir , & fno ) & & fno . fname [ 0 ] ) {
2019-12-01 00:49:36 +00:00
addobject ( fno . fname , folderamount + + , ( fno . fattrib & AM_DIR ) , ( fno . fattrib & AM_ARC ) ) ;
}
f_closedir ( & dir ) ;
return folderamount ;
}
2019-12-10 21:46:34 +00:00
int delfile ( const char * path , const char * filename ) {
2019-12-11 12:18:57 +00:00
char * tempmessage ;
size_t tempmessagesize = strlen ( filename ) + 65 ;
tempmessage = ( char * ) malloc ( tempmessagesize ) ;
sprintf ( tempmessage , " Are you sure you want to delete: \n %s \n \n Press vol+/- to cancel \n " , filename ) ;
if ( makewaitmenu ( tempmessage , " Press power to delete " , 3 ) ) {
f_unlink ( path ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
return 0 ;
2019-12-10 21:46:34 +00:00
}
2019-12-11 12:18:57 +00:00
else
return - 1 ;
2019-12-10 21:46:34 +00:00
}
2020-01-04 19:18:26 +00:00
void copyfolder ( char * in , char * out ) {
bool fatalerror = false ;
int res ;
if ( ! strcmp ( in , rootpath ) ) {
2020-01-06 13:24:29 +00:00
message ( COLOR_RED , " \n In is root \n Aborting! " ) ;
2020-01-04 19:18:26 +00:00
fatalerror = true ;
}
if ( strstr ( out , in ) ! = NULL & & ! fatalerror ) {
2020-01-06 13:24:29 +00:00
message ( COLOR_RED , " \n Out is a part of in! \n Aborting! " ) ;
fatalerror = true ;
}
if ( ! strcmp ( in , out ) & & ! fatalerror ) {
message ( COLOR_RED , " \n In is the same as out! \n Aborting! " ) ;
2020-01-04 19:18:26 +00:00
fatalerror = true ;
}
if ( ! fatalerror ) {
clearscreen ( ) ;
gfx_printf ( " \n Copying folder, please wait \n " ) ;
if ( ( res = copy_recursive ( in , out ) ) )
message ( COLOR_RED , " copy_recursive() failed! \n Errcode %d " , res ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2020-01-04 19:18:26 +00:00
}
clipboardhelper = 0 ;
}
2020-01-01 23:38:36 +00:00
int filemenu ( fs_entry file ) {
int temp ;
2020-01-07 14:28:23 +00:00
FILINFO attribs ;
2020-01-01 23:38:36 +00:00
strlcpy ( explfilemenu [ 1 ] . name , file . name , 43 ) ;
for ( temp = 4 ; temp < 8 ; temp + + )
if ( ( file . property & ( 1 < < temp ) ) )
break ;
sprintf ( explfilemenu [ 2 ] . name , " \n Size: %d %s " , file . size , sizevalues [ temp - 4 ] ) ;
2020-01-07 14:28:23 +00:00
if ( f_stat ( getnextloc ( currentpath , file . name ) , & attribs ) )
explfilemenu [ 3 ] . property = - 1 ;
else {
explfilemenu [ 3 ] . property = 0 ;
sprintf ( explfilemenu [ 3 ] . name , " Attribs: %c%c%c%c " ,
( attribs . fattrib & AM_RDO ) ? ' R ' : ' - ' ,
( attribs . fattrib & AM_SYS ) ? ' S ' : ' - ' ,
( attribs . fattrib & AM_HID ) ? ' H ' : ' - ' ,
( attribs . fattrib & AM_ARC ) ? ' A ' : ' - ' ) ;
}
2020-01-01 23:38:36 +00:00
if ( strstr ( file . name , " .bin " ) ! = NULL & & file . size & ISKB ) {
2020-01-07 14:28:23 +00:00
explfilemenu [ 8 ] . property = 1 ;
2020-01-01 23:38:36 +00:00
}
else
2020-01-07 14:28:23 +00:00
explfilemenu [ 8 ] . property = - 1 ;
2020-01-01 23:38:36 +00:00
2020-01-07 14:28:23 +00:00
temp = makemenu ( explfilemenu , 10 ) ;
2020-01-01 23:38:36 +00:00
switch ( temp ) {
case COPY :
writeclipboard ( getnextloc ( currentpath , file . name ) , false , false ) ;
break ;
case MOVE :
writeclipboard ( getnextloc ( currentpath , file . name ) , true , false ) ;
break ;
case DELETE :
2020-01-06 16:40:05 +00:00
delfile ( getnextloc ( currentpath , file . name ) , file . name ) ;
break ;
2020-01-01 23:38:36 +00:00
case PAYLOAD :
launch_payload ( getnextloc ( currentpath , file . name ) ) ;
break ;
case HEXVIEW :
viewbytes ( getnextloc ( currentpath , file . name ) ) ;
break ;
}
return 0 ;
}
int foldermenu ( ) {
int res ;
2020-01-07 14:28:23 +00:00
FILINFO attribs ;
if ( ! strcmp ( rootpath , currentpath ) ) {
explfoldermenu [ 4 ] . property = - 1 ;
explfoldermenu [ 5 ] . property = - 1 ;
}
else {
explfoldermenu [ 4 ] . property = 1 ;
explfoldermenu [ 5 ] . property = 1 ;
}
if ( f_stat ( currentpath , & attribs ) )
explfoldermenu [ 1 ] . property = - 1 ;
else {
explfoldermenu [ 1 ] . property = 0 ;
sprintf ( explfoldermenu [ 1 ] . name , " Attribs: %c%c%c%c " ,
( attribs . fattrib & AM_RDO ) ? ' R ' : ' - ' ,
( attribs . fattrib & AM_SYS ) ? ' S ' : ' - ' ,
( attribs . fattrib & AM_HID ) ? ' H ' : ' - ' ,
( attribs . fattrib & AM_ARC ) ? ' A ' : ' - ' ) ;
}
2020-01-01 23:38:36 +00:00
2020-01-07 14:28:23 +00:00
res = makemenu ( explfoldermenu , 6 ) ;
2020-01-01 23:38:36 +00:00
switch ( res ) {
case EXITFOLDER :
return - 1 ;
case DELETEFOLDER :
2020-01-04 19:18:26 +00:00
if ( makewaitmenu ( " Do you want to delete this folder? \n The entire folder, with all subcontents \n will be deleted!!! \n \n Press vol+/- to cancel \n " , " Press power to contine... " , 3 ) ) {
2020-01-01 23:38:36 +00:00
clearscreen ( ) ;
2020-01-04 19:18:26 +00:00
gfx_printf ( " \n Deleting folder, please wait... \n " ) ;
2020-01-01 23:38:36 +00:00
if ( ( res = del_recursive ( currentpath ) ) ) {
2020-01-04 19:18:26 +00:00
message ( COLOR_RED , " Error during del_recursive()! %d " , res ) ;
2020-01-01 23:38:36 +00:00
}
writecurpath ( getprevloc ( currentpath ) ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2020-01-01 23:38:36 +00:00
}
break ;
2020-01-04 19:18:26 +00:00
case COPYFOLDER :
writeclipboard ( currentpath , false , true ) ;
break ;
2020-01-01 23:38:36 +00:00
}
2020-01-04 19:18:26 +00:00
2020-01-01 23:38:36 +00:00
return 0 ;
}
void fileexplorer ( const char * startpath ) {
2020-01-06 16:40:05 +00:00
int res , tempint ;
2020-01-01 23:38:36 +00:00
bool breakfree = false ;
2019-12-22 11:10:59 +00:00
if ( ! strcmp ( rootpath , " emmc:/ " ) & & ! strcmp ( startpath , " emmc:/ " ) )
clipboardhelper = 0 ;
2019-12-01 00:49:36 +00:00
strcpy ( rootpath , startpath ) ;
2019-12-03 09:06:11 +00:00
writecurpath ( startpath ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2019-12-01 14:42:37 +00:00
2019-12-11 12:18:57 +00:00
if ( strcmp ( rootpath , " emmc:/ " ) )
2020-01-07 14:28:23 +00:00
explfilemenu [ 6 ] . property = 1 ;
2019-12-11 12:18:57 +00:00
else
2020-01-07 14:28:23 +00:00
explfilemenu [ 6 ] . property = - 1 ;
2019-12-11 12:18:57 +00:00
2019-12-01 14:42:37 +00:00
while ( 1 ) {
2020-01-06 16:40:05 +00:00
res = makefilemenu ( fileobjects , getfileobjamount ( ) , currentpath ) ;
2019-12-01 14:42:37 +00:00
if ( res < 1 ) {
2020-01-01 23:38:36 +00:00
switch ( res ) {
case - 2 :
if ( ! strcmp ( rootpath , currentpath ) )
breakfree = true ;
else {
writecurpath ( getprevloc ( currentpath ) ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2020-01-01 23:38:36 +00:00
}
2019-12-01 14:42:37 +00:00
break ;
2020-01-01 23:38:36 +00:00
case - 1 :
2020-01-06 16:40:05 +00:00
if ( clipboardhelper & ISDIR )
2020-01-04 19:18:26 +00:00
copyfolder ( clipboard , currentpath ) ;
2020-01-06 16:40:05 +00:00
else
2020-01-04 19:18:26 +00:00
copyfile ( clipboard , currentpath ) ;
2020-01-01 23:38:36 +00:00
break ;
case 0 :
tempint = foldermenu ( ) ;
2020-01-06 16:40:05 +00:00
if ( tempint = = - 1 )
2020-01-01 23:38:36 +00:00
breakfree = true ;
break ;
2019-12-01 14:42:37 +00:00
2020-01-01 23:38:36 +00:00
}
2019-12-01 14:42:37 +00:00
}
else {
if ( fileobjects [ res - 1 ] . property & ISDIR ) {
2019-12-03 09:06:11 +00:00
writecurpath ( getnextloc ( currentpath , fileobjects [ res - 1 ] . name ) ) ;
2020-01-06 16:40:05 +00:00
readfolder ( currentpath ) ;
2019-12-01 14:42:37 +00:00
}
2019-12-01 19:31:17 +00:00
else {
2020-01-06 16:40:05 +00:00
filemenu ( fileobjects [ res - 1 ] ) ;
2019-12-01 19:31:17 +00:00
}
2019-12-01 14:42:37 +00:00
}
2020-01-01 23:38:36 +00:00
if ( breakfree )
break ;
2019-12-01 14:42:37 +00:00
}
2019-12-01 00:49:36 +00:00
}