int main(void) { u32 queuehandle; s32 ret; /* Print info */ svc_write("$IOSVersion: FAT: " __DATE__ " " __TIME__ " 64M$\n"); /* Create blinker thread */ Led_CreateBlinkThread(); /* Initialize module */ ret = __FAT_Initialize(&queuehandle); if (ret < 0) return ret; /* Main loop */ while (1) { ipcmessage *message = NULL; /* Wait for message */ ret = os_message_queue_receive(queuehandle, (void *)&message, 0); if (ret) continue; switch (message->command) { case IOS_OPEN: { char *devpath = message->open.device; u32 mode = message->open.mode; if (*devpath == '$') { char path[256]; /* Build absolute path to emu nand */ strcpy(path, emuNandPath); FAT_Escape(path+emuNandPathLen, devpath+1); dbg_printf("FAT: IOS_OPEN: Opening relative file %s\n", devpath); /* Open file */ ret = FAT_Open(path, mode); dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret); } else if (!strcmp(devpath, DEVICE_FAT)) { /* Open module */ dbg_printf("FAT: IOS_OPEN: Opening FAT module\n"); ret = 0; dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret); } else if (!strncmp(devpath, DEVICE_FAT, DEVICE_FAT_LEN)) { /* Open file */ dbg_printf("FAT: IOS_OPEN: Opening absolute file %s\n", devpath + DEVICE_FAT_LEN); ret = FAT_Open(devpath + DEVICE_FAT_LEN, mode); dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret); } else { dbg_printf("FAT: IOS_OPEN: Unknown device path %s\n", devpath); /* Error */ ret = IPC_EINVAL; } break; } case IOS_CLOSE: { ret = 0; // FIX d2x v7 beta1 // Check added because the fd might represent the module, // see IOS_OPEN. // Tipically a fd representing a module is far lower than 32, // while a fd representing a file is an address 32 byte aligned. if(message->fd != 0 && (message->fd % 32) == 0) { dbg_printf("FAT: IOS_CLOSE: Closing file... fd = %d\n", message->fd); /* Close file */ ret = FAT_Close(message->fd); } #ifdef DEBUG else { dbg_printf("FAT: IOS_CLOSE: Closing FAT module...\n"); } #endif dbg_printf("FAT: IOS_CLOSE: ret = %d\n", ret); break; } case IOS_READ: { void *buffer = message->read.data; u32 len = message->read.length; dbg_printf("FAT: IOS_READ: fd = %d, buffer = %x, len = %d\n", message->fd, buffer, len); /* Read file */ ret = FAT_Read(message->fd, buffer, len); /* Flush cache */ os_sync_after_write(buffer, len); dbg_printf("FAT: IOS_READ: ret = %d\n", ret); break; } case IOS_WRITE: { void *buffer = message->write.data; u32 len = message->write.length; dbg_printf("FAT: IOS_WRITE: fd = %d, buffer = %x, len = %d\n", message->fd, buffer, len); /* Invalidate cache */ os_sync_before_read(buffer, len); /* Sart blinking */ Led_BlinkOn(); /* Write file */ ret = FAT_Write(message->fd, buffer, len); dbg_printf("FAT: IOS_WRITE: ret = %d\n", ret); /* Stop blinking */ Led_BlinkOff(); break; } case IOS_SEEK: { s32 where = message->seek.offset; s32 whence = message->seek.origin; dbg_printf("FAT: IOS_SEEK: fd = %d, where = %d, whence = %d\n", message->fd, where, whence); /* Seek file */ ret = FAT_Seek(message->fd, where, whence); dbg_printf("FAT: IOS_SEEK: ret = %d\n", ret); break; } case IOS_IOCTL: { void *inbuf = message->ioctl.buffer_in; void *iobuf = message->ioctl.buffer_io; u32 inlen = message->ioctl.length_in; u32 iolen = message->ioctl.length_io; u32 cmd = message->ioctl.command; /* Parse IOCTL */ ret = __FAT_Ioctl(message->fd, cmd, inbuf, inlen, iobuf, iolen); break; } case IOS_IOCTLV: { ioctlv *vector = message->ioctlv.vector; u32 inlen = message->ioctlv.num_in; u32 iolen = message->ioctlv.num_io; u32 cmd = message->ioctlv.command; /* Parse IOCTLV */ ret = __FAT_Ioctlv(message->fd, cmd, vector, inlen, iolen); break; } default: /* Unknown command */ ret = IPC_EINVAL; } /* Acknowledge message */ os_message_queue_ack((void *)message, ret); } return 0; }
int main(void) { u32 queuehandle; s32 ret; /* Print info */ write("$IOSVersion: FAT: " __DATE__ " " __TIME__ " 64M$\n"); /* Initialize module */ ret = __FAT_Initialize(&queuehandle); if (ret < 0) return ret; /* Main loop */ while (1) { ipcmessage *message = NULL; /* Wait for message */ os_message_queue_receive(queuehandle, (void *)&message, 0); switch (message->command) { case IOS_OPEN: { char *devpath = message->open.device; u32 mode = message->open.mode; /* FAT device */ if (!strcmp(devpath, DEVICE_FAT)) { ret = 0; break; } /* Open file */ ret = FAT_Open(devpath, mode); break; } case IOS_CLOSE: { /* Close file */ ret = FAT_Close(message->fd); break; } case IOS_READ: { void *buffer = message->read.data; u32 len = message->read.length; /* Read file */ ret = FAT_Read(message->fd, buffer, len); break; } case IOS_WRITE: { void *buffer = message->write.data; u32 len = message->write.length; /* Write file */ ret = FAT_Write(message->fd, buffer, len); break; } case IOS_SEEK: { u32 where = message->seek.offset; u32 whence = message->seek.origin; /* Seek file */ ret = FAT_Seek(message->fd, where, whence); break; } case IOS_IOCTL: { void *inbuf = message->ioctl.buffer_in; u32 inlen = message->ioctl.length_in; void *iobuf = message->ioctl.buffer_io; u32 iolen = message->ioctl.length_io; u32 cmd = message->ioctl.command; /* Parse IOCTL message */ ret = FAT_Ioctl(message->fd, cmd, inbuf, inlen, iobuf, iolen); break; } case IOS_IOCTLV: { ioctlv *vector = message->ioctlv.vector; u32 inlen = message->ioctlv.num_in; u32 iolen = message->ioctlv.num_io; u32 cmd = message->ioctlv.command; /* Parse IOCTLV message */ ret = FAT_Ioctlv(message->fd, cmd, vector, inlen, iolen); break; } default: /* Unknown command */ ret = IPC_EINVAL; } /* Acknowledge message */ os_message_queue_ack((void *)message, ret); } return 0; }