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 );
|
---|