PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
main.c
1#include <stdio.h>
2#include <ioman.h>
3#include <iox_stat.h>
4#include <loadcore.h>
5#include <sysclib.h>
6#include <errno.h>
7
8#include "cdfs_iop.h"
9
10// 16 sectors worth of toc entry
11#define MAX_FILES_PER_FOLDER 256
12#define MAX_FILES_OPENED 4
13#define MAX_FOLDERS_OPENED 4
14#define MAX_BYTES_READ 16384
15
16#define DRIVER_UNIT_NAME "cdfs"
17#define DRIVER_MAJOR_VERSION 2
18#define DRIVER_MINOR_VERSION 2
19
20#define STRINGIFY(x) #x
21#define TOSTRING(x) STRINGIFY(x)
22#define DRIVER_DESC DRIVER_UNIT_NAME " Filedriver v" TOSTRING(DRIVER_MAJOR_VERSION) "." TOSTRING(DRIVER_MINOR_VERSION)
23
24IRX_ID(MODNAME, DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION);
25
26struct fdtable
27{
28 iop_file_t *fd;
29 int fileSize;
30 int LBA;
31 int filePos;
32};
33
35{
36 iop_file_t *fd;
37 int files;
38 int filesIndex;
39 struct TocEntry entries[MAX_FILES_PER_FOLDER];
40};
41
42// File Descriptors
43static struct fdtable fd_table[MAX_FILES_OPENED];
44static int fd_used[MAX_FILES_OPENED];
45
46// Folder Descriptors
47static struct fodtable fod_table[MAX_FOLDERS_OPENED];
48static int fod_used[MAX_FOLDERS_OPENED];
49
50// global variables
51static int lastsector = -1;
52static int last_bk = 0;
53
54/***********************************************
55* *
56* DRIVER FUNCTIONS *
57* *
58***********************************************/
59
60static int fio_init(iop_device_t *driver)
61{
62 printf("%s\n", driver->desc);
63 printf("Re-edited by fjtrujy\n");
64 printf("Original implementation\n");
65 printf("by A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)\n");
66 printf("CDFS: Initializing '%s' file driver.\n", driver->name);
67
68 cdfs_start();
69 return 0;
70}
71
72static int fio_deinit(iop_device_t *f)
73{
74 (void)f;
75
76 DPRINTF("CDFS: fio_deinit called.\n");
77 DPRINTF(" kernel_fd.. %p\n", f);
78 return cdfs_finish();
79}
80
81static int fio_open(iop_file_t *f, const char *name, int mode)
82{
83 int j;
84 static struct TocEntry tocEntry;
85
86 DPRINTF("CDFS: fio_open called.\n");
87 DPRINTF(" kernel_fd.. %p\n", f);
88 DPRINTF(" name....... %s %x\n", name, (int)name);
89 DPRINTF(" mode....... %d\n\n", mode);
90
91 // Invalidate last sector cache if disk changed
92 if (cdfs_checkDiskChanged(CHANGED_FIO)) {
93 lastsector = -1;
94 last_bk = 0;
95 }
96
97 // check if the file exists
98 if (!cdfs_findfile(name, &tocEntry)) {
99 printf("***** FILE %s CAN NOT FOUND ******\n\n", name);
100 return -EPERM;
101 }
102
103 if (mode != O_RDONLY) {
104 printf("mode is different than O_RDONLY, expected %i, received %i\n\n", O_RDONLY, mode);
105 return -ENOENT;
106 }
107
108 DPRINTF("CDFS: fio_open TocEntry info\n");
109 DPRINTF(" TocEntry....... %p\n", &tocEntry);
110 DPRINTF(" fileLBA........ %i\n", tocEntry.fileLBA);
111 DPRINTF(" fileSize....... %i\n", tocEntry.fileSize);
112 DPRINTF(" fileProperties. %i\n", tocEntry.fileProperties);
113 DPRINTF(" dateStamp...... %s\n", tocEntry.dateStamp);
114 DPRINTF(" filename....... %s\n", tocEntry.filename);
115
116 // set up a new file descriptor
117 for (j = 0; j < MAX_FILES_OPENED; j++) {
118 if (fd_used[j] == 0)
119 break;
120 }
121
122 if (j >= MAX_FILES_OPENED) {
123 printf("File descriptor overflow!!\n\n");
124 return -ESRCH;
125 }
126
127 fd_used[j] = 1;
128 fd_table[j].fd = f;
129 fd_table[j].fileSize = tocEntry.fileSize;
130 fd_table[j].LBA = tocEntry.fileLBA;
131 fd_table[j].filePos = 0;
132
133 f->privdata = (void *)j;
134
135 return j;
136}
137
138static int fio_close(iop_file_t *f)
139{
140 int i;
141
142 DPRINTF("CDFS: fio_close called.\n");
143 DPRINTF(" kernel fd.. %p\n\n", f);
144
145 i = (int)f->privdata;
146
147 if (i >= MAX_FILES_OPENED) {
148 printf("fio_close: ERROR: File does not appear to be open!\n");
149 return -EPERM;
150 }
151
152 fd_used[i] = 0;
153
154 return 0;
155}
156
157static int fio_read(iop_file_t *f, void *buffer, int size)
158{
159 int i;
160
161 int start_sector;
162 int off_sector;
163 int num_sectors;
164
165 int read = 0;
166 static u8 local_buffer[9 * 2048];
167
168 DPRINTF("CDFS: fio_read called\n\n");
169 DPRINTF(" kernel_fd... %p\n", f);
170 DPRINTF(" buffer...... 0x%X\n", (int)buffer);
171 DPRINTF(" size........ %d\n\n", size);
172
173 i = (int)f->privdata;
174
175 if (i >= MAX_FILES_OPENED) {
176 printf("fio_read: ERROR: File does not appear to be open!\n");
177 return -EPERM;
178 }
179
180 // A few sanity checks
181 if (fd_table[i].filePos > fd_table[i].fileSize) {
182 // We cant start reading from past the beginning of the file
183 return 0; // File exists but we couldnt read anything from it
184 }
185
186 if ((fd_table[i].filePos + size) > fd_table[i].fileSize)
187 size = fd_table[i].fileSize - fd_table[i].filePos;
188
189 if (size <= 0)
190 return 0;
191
192 if (size > MAX_BYTES_READ)
193 size = MAX_BYTES_READ;
194
195 // Now work out where we want to start reading from
196 start_sector = fd_table[i].LBA + (fd_table[i].filePos >> 11);
197 off_sector = (fd_table[i].filePos & 0x7FF);
198
199 num_sectors = (off_sector + size);
200 num_sectors = (num_sectors >> 11) + ((num_sectors & 2047) != 0);
201
202 DPRINTF("fio_read: read sectors %d to %d\n", start_sector, start_sector + num_sectors);
203
204 // Skip a Sector for equal (use the last sector in buffer)
205 if (start_sector == lastsector) {
206 read = 1;
207 if (last_bk > 0)
208 memcpy(local_buffer, local_buffer + 2048 * (last_bk), 2048);
209 last_bk = 0;
210 }
211
212 lastsector = start_sector + num_sectors - 1;
213 // Read the data (we only ever get 16KB max request at once)
214
215 if (read == 0 || (read == 1 && num_sectors > 1)) {
216 if (!cdfs_readSect(start_sector + read, num_sectors - read, local_buffer + ((read) << 11))) {
217 DPRINTF("Couldn't Read from file for some reason\n");
218 }
219
220 last_bk = num_sectors - 1;
221 }
222
223 memcpy(buffer, local_buffer + off_sector, size);
224 fd_table[i].filePos += size;
225
226 return (size);
227}
228
229static int fio_write(iop_file_t *f, void *buffer, int size)
230{
231 (void)f;
232 (void)buffer;
233
234 if (size == 0)
235 return 0;
236 else {
237 printf("CDFS: dummy fio_write function called, this is not a re-writer xD");
238 return -EPERM;
239 }
240}
241
242static int fio_lseek(iop_file_t *f, int offset, int whence)
243{
244 int i;
245
246 DPRINTF("CDFS: fio_lseek called.\n");
247 DPRINTF(" kernel_fd... %p\n", f);
248 DPRINTF(" offset...... %d\n", offset);
249 DPRINTF(" whence...... %d\n\n", whence);
250
251 i = (int) f->privdata;
252
253 if (i >= 16) {
254 DPRINTF("fio_lseek: ERROR: File does not appear to be open!\n");
255 return -EPERM;
256 }
257
258 switch (whence) {
259 case SEEK_SET:
260 fd_table[i].filePos = offset;
261 break;
262
263 case SEEK_CUR:
264 fd_table[i].filePos += offset;
265 break;
266
267 case SEEK_END:
268 fd_table[i].filePos = fd_table[i].fileSize + offset;
269 break;
270
271 default:
272 return -1;
273 }
274
275 if (fd_table[i].filePos < 0)
276 fd_table[i].filePos = 0;
277
278 if (fd_table[i].filePos > fd_table[i].fileSize)
279 fd_table[i].filePos = fd_table[i].fileSize;
280
281 return fd_table[i].filePos;
282}
283
284static int fio_openDir(iop_file_t *f, const char *path) {
285 int j;
286
287 DPRINTF("CDFS: fio_openDir called.\n");
288 DPRINTF(" kernel_fd.. %p\n", f);
289 DPRINTF(" name....... %s\n", f->device->name);
290 DPRINTF(" mode....... %d\n\n", f->mode);
291 DPRINTF(" path....... %s\n\n", path);
292
293 // set up a new file descriptor
294 for (j = 0; j < MAX_FOLDERS_OPENED; j++) {
295 if (fod_used[j] == 0)
296 break;
297 }
298
299 if (j >= MAX_FOLDERS_OPENED)
300 return -ESRCH;
301
302 fod_table[j].files = cdfs_getDir(path, fod_table[j].entries, MAX_FILES_PER_FOLDER);
303 if (fod_table[j].files < 0) {
304 printf("The path doesn't exist\n\n");
305 return -ENOENT;
306 }
307
308 fod_table[j].filesIndex = 0;
309 fod_table[j].fd = f;
310 fod_used[j] = 1;
311
312 DPRINTF("ITEMS %i\n\n", fod_table[j].files);
313#ifdef DEBUG
314 int index = 0;
315 for (index=0; index < fod_table[j].files; index++) {
316 struct TocEntry tocEntry = fod_table[j].entries[index];
317
318 DPRINTF("CDFS: fio_openDir index=%d TocEntry info\n", index);
319 DPRINTF(" TocEntry....... %p\n", &tocEntry);
320 DPRINTF(" fileLBA........ %i\n", tocEntry.fileLBA);
321 DPRINTF(" fileSize....... %i\n", tocEntry.fileSize);
322 DPRINTF(" fileProperties. %i\n", tocEntry.fileProperties);
323 DPRINTF(" dateStamp....... %s\n", tocEntry.dateStamp);
324 DPRINTF(" filename....... %s\n", tocEntry.filename);
325 }
326#endif
327
328 f->privdata = (void *)j;
329
330 return j;
331}
332
333static int fio_closeDir(iop_file_t *fd)
334{
335 int i;
336
337 DPRINTF("CDFS: fio_closeDir called.\n");
338 DPRINTF(" kernel_fd.. %p\n", fd);
339
340 i = (int)fd->privdata;
341
342 if (i >= MAX_FOLDERS_OPENED) {
343 printf("fio_close: ERROR: File does not appear to be open!\n");
344 return -EPERM;
345 }
346
347 fod_used[i] = 0;
348 return 0;
349}
350
351static int fio_dread(iop_file_t *fd, io_dirent_t *dirent)
352{
353 int i;
354 int filesIndex;
355 struct TocEntry entry;
356
357 DPRINTF("CDFS: fio_dread called.\n");
358 DPRINTF(" kernel_fd.. %p\n", fd);
359 DPRINTF(" mode....... %p\n\n", dirent);
360
361 i = (int)fd->privdata;
362
363 if (i >= MAX_FOLDERS_OPENED) {
364 printf("fio_dread: ERROR: Folder does not appear to be open!\n\n");
365 return -EPERM;
366 }
367
368 filesIndex = fod_table[i].filesIndex;
369 if (filesIndex >= fod_table[i].files) {
370 printf("fio_dread: No more items pending to read!\n\n");
371 return -EPERM;
372 }
373
374 entry = fod_table[i].entries[filesIndex];
375
376 DPRINTF("fio_dread: fod_table index=%i, fileIndex=%i\n\n", i, filesIndex);
377 DPRINTF("fio_dread: entries=%i\n\n", fod_table[i].files);
378 DPRINTF("fio_dread: reading entry\n\n");
379 DPRINTF(" entry.. %p\n", &entry);
380 DPRINTF(" filesize....... %i\n\n", entry.fileSize);
381 DPRINTF(" filename....... %s\n\n", entry.filename);
382 DPRINTF(" fileproperties.. %i\n\n", entry.fileProperties);
383
384 dirent->stat.mode = (entry.fileProperties == CDFS_FILEPROPERTY_DIR) ? FIO_SO_IFDIR : FIO_SO_IFREG;
385 dirent->stat.attr = entry.fileProperties;
386 dirent->stat.size = entry.fileSize;
387 memcpy(dirent->stat.ctime, entry.dateStamp, sizeof(entry.dateStamp));
388 memcpy(dirent->stat.atime, entry.dateStamp, sizeof(entry.dateStamp));
389 memcpy(dirent->stat.mtime, entry.dateStamp, sizeof(entry.dateStamp));
390 strncpy(dirent->name, entry.filename, sizeof(dirent->name));
391
392 fod_table[i].filesIndex++;
393 return fod_table[i].filesIndex;
394}
395
396static int fio_getstat(iop_file_t *fd, const char *name, io_stat_t *stat)
397{
398 struct TocEntry entry;
399 int ret = -EPERM;
400
401 (void)fd;
402
403 DPRINTF("CDFS: fio_getstat called.\n");
404 DPRINTF(" kernel_fd.. %p\n", fd);
405 DPRINTF(" name....... %s\n\n", name);
406
407 ret = cdfs_findfile(name, &entry);
408
409 DPRINTF(" entry.. %p\n", &entry);
410 DPRINTF(" filesize....... %i\n\n", entry.fileSize);
411 DPRINTF(" filename....... %s\n\n", entry.filename);
412 DPRINTF(" fileproperties.. %i\n\n", entry.fileProperties);
413
414 stat->mode = (entry.fileProperties == CDFS_FILEPROPERTY_DIR) ? FIO_SO_IFDIR : FIO_SO_IFREG;
415 stat->attr = entry.fileProperties;
416 stat->size = entry.fileSize;
417 memcpy(stat->ctime, entry.dateStamp, sizeof(entry.dateStamp));
418 memcpy(stat->atime, entry.dateStamp, sizeof(entry.dateStamp));
419 memcpy(stat->mtime, entry.dateStamp, sizeof(entry.dateStamp));
420
421 return ret;
422}
423
424IOMAN_RETURN_VALUE_IMPL(EIO);
425
426static iop_device_ops_t fio_ops = {
427 &fio_init, // init
428 &fio_deinit, // deinit
429 IOMAN_RETURN_VALUE(EIO), // format
430 &fio_open, // open
431 &fio_close, // close
432 &fio_read, // read
433 &fio_write, // write
434 &fio_lseek, // lseek
435 IOMAN_RETURN_VALUE(EIO), // ioctl
436 IOMAN_RETURN_VALUE(EIO), // remove
437 IOMAN_RETURN_VALUE(EIO), // mkdir
438 IOMAN_RETURN_VALUE(EIO), // rmdir
439 &fio_openDir, // dopen
440 &fio_closeDir, // dclose
441 &fio_dread, // dread
442 &fio_getstat, // getstat
443 IOMAN_RETURN_VALUE(EIO), // chstat
444};
445
446static iop_device_t fio_driver = {
447 DRIVER_UNIT_NAME,
448 IOP_DT_FS,
449 DRIVER_MAJOR_VERSION,
450 DRIVER_DESC,
451 &fio_ops,
452};
453
454int _start(int argc, char *argv[])
455{
456 (void)argc;
457 (void)argv;
458
459 // Prepare cache and read mode
460 cdfs_prepare();
461
462 DelDrv(fio_driver.name);
463 if(AddDrv(&fio_driver) != 0) { return MODULE_NO_RESIDENT_END; }
464
465 return MODULE_RESIDENT_END;
466}
#define ENOENT
Definition errno.h:23
#define ESRCH
Definition errno.h:25
#define EIO
Definition errno.h:29
#define EPERM
Definition errno.h:21
struct _iop_device * device
Definition ioman.h:59
void * privdata
Definition ioman.h:61
int mode
Definition ioman.h:55
#define FIO_SO_IFDIR
Definition iox_stat.h:128
#define FIO_SO_IFREG
Definition iox_stat.h:126
Definition cdfs_iop.h:13
Definition main.c:27