[1101] | 1 | #include <types.h>
|
---|
| 2 | #include <irx.h>
|
---|
| 3 | #include <stdio.h>
|
---|
| 4 | #include <sysclib.h>
|
---|
| 5 | #include <sysmem.h>
|
---|
| 6 | #include <iomanX.h>
|
---|
| 7 | #include <sys/fcntl.h>
|
---|
| 8 | #include <cdvdman.h>
|
---|
| 9 |
|
---|
| 10 |
|
---|
| 11 | // Define this to enable debugging, will later support debugging levels, so only messages greater then a certain level will be displayed
|
---|
| 12 | //#define DEBUG 8
|
---|
| 13 | //For release versions of uLE, DEBUG should not be defined
|
---|
| 14 | //To avoid slowdown and size bloat
|
---|
| 15 |
|
---|
| 16 | // Define this to enable some basic profiling support, each function will display the time it took to run.
|
---|
| 17 | // #define PROFILING
|
---|
| 18 |
|
---|
| 19 |
|
---|
| 20 | // Misc defintions
|
---|
| 21 | #define malloc( a ) AllocSysMemory( 0, ( a ), NULL )
|
---|
| 22 | #define free( a ) FreeSysMemory( ( a ) )
|
---|
| 23 |
|
---|
| 24 | #define TRUE 1
|
---|
| 25 | #define FALSE 0
|
---|
| 26 |
|
---|
| 27 | #define MAX_NAME 32
|
---|
| 28 | #define MAX_PATH 1024
|
---|
| 29 |
|
---|
| 30 |
|
---|
| 31 | // Vmcfs error definitions
|
---|
| 32 | #define VMCFS_ERR_NO 0
|
---|
| 33 | #define VMCFS_ERR_INITIALIZED -1
|
---|
| 34 | #define VMCFS_ERR_VMC_OPEN -2
|
---|
| 35 | #define VMCFS_ERR_VMC_READ -3
|
---|
| 36 | #define VMCFS_ERR_CARD_TYPE -4
|
---|
| 37 | #define VMCFS_ERR_NOT_FORMATED -5
|
---|
| 38 | #define VMCFS_ERR_VMC_SIZE -6
|
---|
| 39 | #define VMCFS_ERR_NOT_MOUNT -7
|
---|
| 40 | #define VMCFS_ERR_MOUNT_BUSY -8
|
---|
| 41 | #define VMCFS_ERR_IMPLEMENTED -9
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | // The devctl commands: 0x56 == V, 0x4D == M, 0x43 == C, 0x01, 0x02, ... == command number.
|
---|
| 45 | #define DEVCTL_VMCFS_CLEAN 0x564D4301 // Set as free all fat cluster corresponding to a none existing object. ( Object are just marked as none existing but not removed from fat table when rmdir or remove fonctions are call. This allow to recover a deleted file. )
|
---|
| 46 | #define DEVCTL_VMCFS_CKFREE 0x564D4302 // Check free space available on vmc.
|
---|
| 47 |
|
---|
| 48 | // The ioctl commands: 0x56 == V, 0x4D == M, 0x43 == C, 0x01, 0x02, ... == command number.
|
---|
| 49 | #define IOCTL_VMCFS_RECOVER 0x564D4303 // Recover an object marked as none existing. ( data must be a valid path to an object in vmc file )
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | // Vmc format enum
|
---|
| 53 | typedef enum {
|
---|
| 54 | FORMAT_FULL,
|
---|
| 55 | FORMAT_FAST
|
---|
| 56 | } Vmc_Format_Enum;
|
---|
| 57 |
|
---|
| 58 |
|
---|
| 59 | // Memorycard type definitions
|
---|
| 60 | #define PSX_MEMORYCARD 0x1
|
---|
| 61 | #define PS2_MEMORYCARD 0x2
|
---|
| 62 | #define PDA_MEMORYCARD 0x3
|
---|
| 63 |
|
---|
| 64 | // Directory Entry Mode Flags
|
---|
| 65 | #define DF_READ 0x0001 // Read permission.
|
---|
| 66 | #define DF_WRITE 0x0002 // Write permission.
|
---|
| 67 | #define DF_EXECUTE 0x0004 // Execute permission.
|
---|
| 68 | #define DF_PROTECTED 0x0008 // Directory is copy protected.
|
---|
| 69 | #define DF_FILE 0x0010 // Regular file.
|
---|
| 70 | #define DF_DIRECTORY 0x0020 // Directory.
|
---|
| 71 | #define DF_040 0x0040 // Used internally to create directories.
|
---|
| 72 | #define DF_080 0x0080 // Copied?
|
---|
| 73 | #define DF_0100 0x0100 // -
|
---|
| 74 | #define O_CREAT 0x0200 // Used to create files.
|
---|
| 75 | #define DF_0400 0x0400 // Set when files and directories are created, otherwise ignored.
|
---|
| 76 | #define DF_POCKETSTN 0x0800 // PocketStation application save file.
|
---|
| 77 | #define DF_PSX 0x1000 // PlayStation save file.
|
---|
| 78 | #define DF_HIDDEN 0x2000 // File is hidden.
|
---|
| 79 | #define DF_04000 0x4000 // -
|
---|
| 80 | #define DF_EXISTS 0x8000 // This entry is in use. If this flag is clear, then the file or directory has been deleted.
|
---|
| 81 |
|
---|
| 82 |
|
---|
| 83 | // Cluster definitions
|
---|
| 84 | #define MAX_CLUSTER_SIZE 0x400
|
---|
| 85 |
|
---|
| 86 | #define ROOT_CLUSTER 0x00000000
|
---|
| 87 | #define FREE_CLUSTER 0x7FFFFFFF
|
---|
| 88 | #define EOF_CLUSTER 0xFFFFFFFF
|
---|
| 89 | #define ERROR_CLUSTER 0xFFFFFFFF
|
---|
| 90 | #define NOFOUND_CLUSTER 0xFFFFFFFF
|
---|
| 91 | #define MASK_CLUSTER 0x80000000
|
---|
| 92 |
|
---|
| 93 |
|
---|
| 94 | // The debugging functions, very very handy
|
---|
| 95 | #ifdef DEBUG
|
---|
| 96 | #define DEBUGPRINT( level, args... ) \
|
---|
| 97 | if( DEBUG >= level ) printf( args )
|
---|
| 98 | #else
|
---|
| 99 | #define DEBUGPRINT( args... )
|
---|
| 100 | #endif
|
---|
| 101 |
|
---|
| 102 |
|
---|
| 103 | // Used for timing functions, use this to optimize stuff
|
---|
| 104 | #ifdef PROFILING
|
---|
| 105 | void profilerStart( iop_sys_clock_t *iopclock );
|
---|
| 106 | void profilerEnd( const char *function, const char* name, iop_sys_clock_t *iopclock1 );
|
---|
| 107 | //This creates 2 variables with the names name1/name2, and starts the profiler
|
---|
| 108 | #define PROF_START( name ) \
|
---|
| 109 | iop_sys_clock_t name;\
|
---|
| 110 | profilerStart( &name );
|
---|
| 111 | //this takes the 2 variable names and ends the profiler, printing the time taken
|
---|
| 112 | #define PROF_END( name ) \
|
---|
| 113 | profilerEnd( __func__, #name, &name );
|
---|
| 114 | #else
|
---|
| 115 | //define away the profiler functions
|
---|
| 116 | #define PROF_START( args ) ;
|
---|
| 117 | #define PROF_END( args ) ;
|
---|
| 118 | #endif
|
---|
| 119 |
|
---|
| 120 |
|
---|
| 121 | // Global Structures Defintions
|
---|
| 122 |
|
---|
| 123 | // General data struct shared by both files / folders that we have opened
|
---|
| 124 | struct gen_privdata
|
---|
| 125 | {
|
---|
| 126 | int fd;
|
---|
| 127 | unsigned int indir_fat_clusters[ 32 ];
|
---|
| 128 | unsigned int first_allocatable;
|
---|
| 129 | unsigned int last_allocatable;
|
---|
| 130 | unsigned char dirent_page;
|
---|
| 131 | };
|
---|
| 132 |
|
---|
| 133 | // the structure used by files that we have opened
|
---|
| 134 | struct file_privdata
|
---|
| 135 | {
|
---|
| 136 | struct gen_privdata gendata;
|
---|
| 137 | unsigned int file_startcluster;
|
---|
| 138 | unsigned int file_length;
|
---|
| 139 | unsigned int file_position;
|
---|
| 140 | unsigned int file_cluster;
|
---|
| 141 | unsigned int cluster_offset;
|
---|
| 142 | unsigned int file_dirpage;
|
---|
| 143 | };
|
---|
| 144 |
|
---|
| 145 | // the structure used by directories that we have opened
|
---|
| 146 | struct dir_privdata
|
---|
| 147 | {
|
---|
| 148 | struct gen_privdata gendata;
|
---|
| 149 | unsigned int dir_number; // first or second entry in the cluster?
|
---|
| 150 | unsigned int dir_cluster; // what cluster we are currently reading directory entries from
|
---|
| 151 | unsigned int dir_length; // the length of the directory
|
---|
| 152 | };
|
---|
| 153 |
|
---|
| 154 | // date / time descriptor
|
---|
| 155 | typedef struct {
|
---|
| 156 | unsigned char unused0;
|
---|
| 157 | unsigned char sec;
|
---|
| 158 | unsigned char min;
|
---|
| 159 | unsigned char hour;
|
---|
| 160 | unsigned char day;
|
---|
| 161 | unsigned char month;
|
---|
| 162 | unsigned short year;
|
---|
| 163 | } vmc_datetime;
|
---|
| 164 |
|
---|
| 165 | // the structure of a directory entry
|
---|
| 166 | struct direntry
|
---|
| 167 | {
|
---|
| 168 | unsigned short mode; // See directory mode definitions.
|
---|
| 169 | unsigned char unused0[ 2 ]; // -
|
---|
| 170 | unsigned int length; // Length in bytes if a file, or entries if a directory.
|
---|
| 171 | vmc_datetime created; // created time.
|
---|
| 172 | unsigned int cluster; // First cluster of the file, or 0xFFFFFFFF for an empty file. In "." entries it's the first cluster of the parent directory relative to first_allocatable.
|
---|
| 173 | unsigned int dir_entry; // Only in "." entries. Entry of this directory in its parent's directory.
|
---|
| 174 | vmc_datetime modified; // Modification time.
|
---|
| 175 | unsigned int attr; // User defined attribute.
|
---|
| 176 | unsigned char unused1[ 28 ]; // -
|
---|
| 177 | unsigned char name[ 32 ]; // Zero terminated name for this directory entry.
|
---|
| 178 | unsigned char unused2[ 416 ]; // -
|
---|
| 179 | };
|
---|
| 180 |
|
---|
| 181 | // A structure containing all of the information about the superblock on a memory card.
|
---|
| 182 | struct superblock
|
---|
| 183 | {
|
---|
| 184 | unsigned char magic[ 40 ];
|
---|
| 185 | unsigned short page_size;
|
---|
| 186 | unsigned short pages_per_cluster;
|
---|
| 187 | unsigned short pages_per_block;
|
---|
| 188 | unsigned short unused0; // always 0xFF00
|
---|
| 189 | unsigned int clusters_per_card;
|
---|
| 190 | unsigned int first_allocatable;
|
---|
| 191 | unsigned int last_allocatable;
|
---|
| 192 | unsigned int root_cluster; // must be 0
|
---|
| 193 | unsigned int backup_block1; // 1023
|
---|
| 194 | unsigned int backup_block2; // 1024
|
---|
| 195 | unsigned char unused1[ 8 ]; // unused / who knows what it is
|
---|
| 196 | unsigned int indir_fat_clusters[ 32 ];
|
---|
| 197 | unsigned int bad_block_list[ 32 ];
|
---|
| 198 | unsigned char mc_type;
|
---|
| 199 | unsigned char mc_flag;
|
---|
| 200 | unsigned short unused2; // zero
|
---|
| 201 | unsigned int cluster_size; // 1024 always, 0x400
|
---|
| 202 | unsigned int unused3; // 0x100
|
---|
| 203 | unsigned int size_in_megs; // size in megabytes
|
---|
| 204 | unsigned int unused4; // 0xffffffff
|
---|
| 205 | unsigned char unused5[ 12 ]; // zero
|
---|
| 206 | unsigned int max_used; // 97%of total clusters
|
---|
| 207 | unsigned char unused6[ 8 ]; // zero
|
---|
| 208 | unsigned int unused7; // 0xffffffff
|
---|
| 209 | };
|
---|
| 210 |
|
---|
| 211 | // General vmc image structure
|
---|
| 212 | struct global_vmc
|
---|
| 213 | {
|
---|
| 214 | int fd; // global descriptor
|
---|
| 215 | struct superblock header; // superblock header
|
---|
| 216 | int formated; // card is formated
|
---|
| 217 | int ecc_flag; // ecc data found in vmc file
|
---|
| 218 | unsigned int card_size; // vmc file size
|
---|
| 219 | unsigned int total_pages; // total number of pages in the vmc file
|
---|
| 220 | unsigned int cluster_size; // size in byte of a cluster
|
---|
| 221 | unsigned short erase_byte; // erased blocks have all bits set to 0x0 or 0xFF
|
---|
| 222 | unsigned int last_idc; // last indirect cluster
|
---|
| 223 | unsigned int last_cluster; // last cluster
|
---|
| 224 | unsigned int indirect_cluster[ MAX_CLUSTER_SIZE ]; // indirect fat cluster
|
---|
| 225 | unsigned int fat_cluster[ MAX_CLUSTER_SIZE ]; // fat cluster
|
---|
| 226 | unsigned int last_free_cluster; // adress of the last free cluster found when getting free cluster
|
---|
| 227 | };
|
---|
| 228 |
|
---|
| 229 |
|
---|
| 230 | extern struct global_vmc g_Vmc_Image[ 2 ];
|
---|
| 231 | extern int g_Vmc_Format_Mode;
|
---|
| 232 | extern int g_Vmc_Remove_Flag;
|
---|
| 233 | extern int g_Vmc_Initialized;
|
---|
| 234 |
|
---|
| 235 |
|
---|
| 236 | // vmc_fs.c
|
---|
| 237 | int Vmc_Initialize ( iop_device_t * driver );
|
---|
| 238 | int Vmc_Deinitialize ( iop_device_t * driver );
|
---|
| 239 |
|
---|
| 240 | // vmc_io.c
|
---|
| 241 | int Vmc_Format ( iop_file_t *, const char *dev, const char *blockdev, void *arg, size_t arglen );
|
---|
| 242 | int Vmc_Open ( iop_file_t *f, const char *name, int flags, int mode );
|
---|
| 243 | int Vmc_Close ( iop_file_t* f );
|
---|
| 244 | int Vmc_Read ( iop_file_t* f, void* buffer, int size );
|
---|
| 245 | int Vmc_Write ( iop_file_t* f, void* buffer, int size );
|
---|
| 246 | int Vmc_Lseek ( iop_file_t* f, unsigned long offset, int whence );
|
---|
| 247 | int Vmc_Ioctl ( iop_file_t* f, unsigned long request, void* data );
|
---|
| 248 | int Vmc_Remove ( iop_file_t* f, const char* path );
|
---|
| 249 | int Vmc_Mkdir ( iop_file_t* f, const char* path1, int mode );
|
---|
| 250 | int Vmc_Rmdir ( iop_file_t* f, const char* path1 );
|
---|
| 251 | int Vmc_Dopen ( iop_file_t* f, const char* path );
|
---|
| 252 | int Vmc_Dclose ( iop_file_t* f );
|
---|
| 253 | int Vmc_Dread ( iop_file_t* f, iox_dirent_t *buf );
|
---|
| 254 | int Vmc_Getstat ( iop_file_t* f, const char* path, iox_stat_t * stat );
|
---|
| 255 | int Vmc_Chstat ( iop_file_t* f, const char* path, iox_stat_t * stat, unsigned int unknown );
|
---|
| 256 | int Vmc_Rename ( iop_file_t* f, const char* path, const char* new_name );
|
---|
| 257 | int Vmc_Chdir ( iop_file_t* f, const char* path );
|
---|
| 258 | int Vmc_Sync ( iop_file_t* f, const char* device, int flag );
|
---|
| 259 | int Vmc_Mount ( iop_file_t* f, const char* fsname, const char* devname, int flag, void *arg, unsigned int arg_len );
|
---|
| 260 | int Vmc_Umount ( iop_file_t* f, const char* fsname );
|
---|
| 261 | int Vmc_Lseek64 ( iop_file_t* f, long long offset, int whence );
|
---|
| 262 | int Vmc_Devctl ( iop_file_t* f, const char* path, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen );
|
---|
| 263 | int Vmc_Symlink ( iop_file_t* f, const char* old, const char* new );
|
---|
| 264 | int Vmc_Readlink ( iop_file_t* f, const char* path, char* buf, unsigned int buf_len );
|
---|
| 265 | int Vmc_Ioctl2 ( iop_file_t* f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen );
|
---|
| 266 | int Vmc_Recover ( int unit, const char* path1 );
|
---|
| 267 | unsigned int Vmc_Checkfree ( int unit );
|
---|
| 268 | int Vmc_Clean ( int unit );
|
---|
| 269 |
|
---|
| 270 | // mcfat.c
|
---|
| 271 | typedef enum {
|
---|
| 272 | FAT_VALUE,
|
---|
| 273 | FAT_MASK
|
---|
| 274 | } GetFat_Mode;
|
---|
| 275 |
|
---|
| 276 | typedef enum {
|
---|
| 277 | FAT_RESET,
|
---|
| 278 | FAT_SET
|
---|
| 279 | } SetFat_Mode;
|
---|
| 280 |
|
---|
| 281 | unsigned int getFatEntry ( int fd, unsigned int cluster, unsigned int* indir_fat_clusters, GetFat_Mode Mode );
|
---|
| 282 | unsigned int setFatEntry ( int fd, unsigned int cluster, unsigned int value, unsigned int* indir_fat_clusters, SetFat_Mode Mode );
|
---|
| 283 |
|
---|
| 284 |
|
---|
| 285 | // ps2.c
|
---|
| 286 | int eraseBlock ( int fd, unsigned int block );
|
---|
| 287 | int writePage ( int fd, unsigned char* page, unsigned int pagenum );
|
---|
| 288 | int writeCluster ( int fd, unsigned char* cluster, unsigned int clusternum );
|
---|
| 289 | int writeClusterPart ( int fd, unsigned char* cluster, unsigned int clusternum, int cluster_offset, int size );
|
---|
| 290 | int readPage ( int fd, unsigned char* page, unsigned int pagenum );
|
---|
| 291 | int readCluster ( int fd, unsigned char* cluster, unsigned int clusternum );
|
---|
| 292 |
|
---|
| 293 |
|
---|
| 294 | // misc.c
|
---|
| 295 | unsigned int getDirentryFromPath ( struct direntry* retval, const char* path, struct gen_privdata* gendata, int unit );
|
---|
| 296 | unsigned int addObject ( struct gen_privdata* gendata, unsigned int parentcluster, struct direntry* parent, struct direntry* dirent, int unit );
|
---|
| 297 | void removeObject ( struct gen_privdata* gendata, unsigned int dirent_cluster, struct direntry* dirent, int unit );
|
---|
| 298 | unsigned int getFreeCluster ( struct gen_privdata* gendata, int unit );
|
---|
| 299 | int getPs2Time ( vmc_datetime* tm );
|
---|
| 300 | int setDefaultSpec ( int unit );
|
---|
| 301 | int buildECC ( int unit, char* Page_Data, char* ECC_Data );
|
---|