static int cmd_fputc(int argc, char *argv[]) { char tempstr[1024]; if(argc > 3) { my_errno = TOO_MANY_ARGUMENTS; return 1; } if(argc < 3 ) { my_errno = TOO_FEW_ARGUMENTS; return 1; } int fd = strtoint(argv[1]); if(fd >= 0) { char buff = argv[2][0]; int bytesread = svc_write(fd,buff); if(bytesread == 1) { sprintf(tempstr,"%c written\r\n",buff);uprintf(tempstr); return 0; } } sprintf(tempstr,"could not write file\r\n");uprintf(tempstr); return 1; }
static int cmd_pb2led(int argc, char *argv[]) { if(argc > 1) { my_errno = TOO_MANY_ARGUMENTS; return 1; } int rfd1 = svc_open("/btn/sw1",'r'); if(rfd1 < 0) { return 1; } int rfd2 = svc_open("/btn/sw2",'r'); if(rfd2 < 0) { return 1; } int wfd1 = svc_open("/led/orange",'w'); if(wfd1 < 0) { return 1; } int wfd2 = svc_open("/led/yellow",'w'); if(wfd2 < 0) { return 1; } while(1) { char buff[2]; svc_read(rfd1,&buff[0]); svc_read(rfd2,&buff[1]); if(buff[0] == '1' && buff[1] == '1') { svc_close(rfd1); svc_close(rfd2); svc_close(wfd1); svc_close(wfd2); return 0; } svc_write(wfd1,buff[0]); svc_write(wfd2,buff[1]); } return 1; }
s32 __IOP_CheckOpeningRequest(char *path, u32 rights) { s32 tid, ret; /* Get current thread id */ tid = direct_os_get_thread_id(); /* Check thread rights */ ret = CheckThreadRights(tid, rights); /* Log unauthorized request */ if (!ret) { svc_write("IOP: Unauthorized access to '"); svc_write(path); svc_write("'. Blocking opening request.\n"); } return ret; }
void Stealth_Log(u32 type, const char* command) { svc_write(moduleName); svc_write(": "); if (type & STEALTH_RUNNING_TITLE) { svc_write("Title identified"); if (type & STEALTH_ES_REQUEST) svc_write(" or "); } if (type & STEALTH_ES_REQUEST) svc_write("Request not coming from ES"); svc_write(". Blocking "); if (command) { svc_write("custom command "); svc_write(command); } else svc_write("opening request"); svc_write(".\n"); }
static int cmd_touch2led(int argc, char *argv[]) { if(argc > 1) { my_errno = TOO_MANY_ARGUMENTS; return 1; } int rfd[4]; int wfd[4]; rfd[0] = svc_open("/tsr/orange",'r'); rfd[1] = svc_open("/tsr/yellow",'r'); rfd[2] = svc_open("/tsr/blue",'r'); rfd[3] = svc_open("/tsr/green",'r'); wfd[0] = svc_open("/led/orange",'w'); wfd[1] = svc_open("/led/yellow",'w'); wfd[2] = svc_open("/led/blue",'w'); wfd[3] = svc_open("/led/green",'w'); while(1) { char buff[4]; svc_read(rfd[0],&buff[0]); svc_read(rfd[1],&buff[1]); svc_read(rfd[2],&buff[2]); svc_read(rfd[3],&buff[3]); if(buff[0] == '1' && buff[1] == '1' && buff[2] == '1' && buff[3] == '1') { svc_close(rfd[0]);svc_close(rfd[1]); svc_close(rfd[2]);svc_close(rfd[3]); svc_close(wfd[0]);svc_close(wfd[1]); svc_close(wfd[2]);svc_close(wfd[3]); return 0; } svc_write(wfd[0],buff[0]); svc_write(wfd[1],buff[1]); svc_write(wfd[2],buff[2]); svc_write(wfd[3],buff[3]); } return 1; }
void demoProc1(int argc,char *argv[]) { int wfd = svc_open("/lcd",'w'); if(wfd > 0) { char buff; while((buff = ugetc()) != CHAR_EOF) { svc_write(wfd,buff); } svc_close(wfd); } }
void LOG_Write(const char *msg, const char* func, u32 line) { static char buffer[8]; svc_write(moduleName); svc_write(": ("); svc_write(func); svc_write(", "); svc_write(itoa(line, buffer, 10)); svc_write(") : "); svc_write(msg); }
s32 DI_Config_Load(struct dipConfigState *cfg) { s32 fd, ret; #ifdef DEBUG svc_write("DIP: Config_Load(): Loading config file "); svc_write(__dip_cfg_filename); svc_write("\n"); #endif /* Open config file */ fd = os_open(__dip_cfg_filename, ISFS_OPEN_READ); #ifdef DEBUG svc_write("DIP: Config_Load(): Config file "); svc_write(fd < 0 ? "NOT found\n" : "found\n"); #endif if (fd < 0) return fd; /* Read config */ ret = os_read(fd, cfg, sizeof(struct dipConfigState)); if (ret == sizeof(struct dipConfigState)) { if (cfg->mode == MODE_FRAG) { s32 ret2; /* Read frag list */ memset(&fraglist_data, 0, sizeof(fraglist_data)); if (cfg->frag_size > sizeof(fraglist_data)) { ret2 = -1; } else { ret2 = os_read(fd, &fraglist_data, cfg->frag_size); } if (ret2 != cfg->frag_size) ret = -1; } } else if (ret >= 0) ret = -1; /* Close config */ os_close(fd); /* Delete config file */ __Config_Delete(__dip_cfg_filename); #ifdef DEBUG if (ret < 0) svc_write("DIP: Config_Load(): Config file has unexpected size!!!\n"); #endif return ret; }
int main(void) { /* System patchers */ static patcher patchers[] = { {Patch_FfsModule, 0}, {Patch_IopModule, 0} }; /* Print info */ svc_write("$IOSVersion: FFSP: " __DATE__ " " __TIME__ " 64M$\n"); /* Initialize IOP */ IOP_Init(); /* Initialize plugin */ IOS_InitSystem(patchers, sizeof(patchers)); return 0; }
static int cmd_ser2lcd(int argc, char *argv[]) { if(argc > 1) { my_errno = TOO_MANY_ARGUMENTS; return 1; } int wfd = svc_open("/lcd",'w'); if(wfd > 0) { char buff; while((buff = ugetc()) != CHAR_EOF) { svc_write(wfd,buff); } svc_close(wfd); return 0; } return 1; }
s32 FFS_Config_Load(struct ffsConfigState *cfg) { s32 fd, ret; #ifdef DEBUG svc_write("DIP: Config_Load(): Loading config file "); svc_write(__ffs_cfg_filename); svc_write("\n"); #endif /* Open config file */ fd = os_open(__ffs_cfg_filename, ISFS_OPEN_READ); #ifdef DEBUG svc_write("DIP: Config_Load(): Config file "); svc_write(fd < 0 ? "NOT found\n" : "found\n"); #endif if (fd < 0) return fd; /* Read config */ ret = os_read(fd, cfg, sizeof(struct ffsConfigState)); if (ret != sizeof(struct ffsConfigState)) { #ifdef DEBUG svc_write("DIP: Config_Load(): Config file has unexpected size!!!\n"); #endif ret = -1; } /* Close config */ os_close(fd); /* Delete config file */ __Config_Delete(__ffs_cfg_filename); return ret; }
char *__IOP_SyscallOpen(char *path, s32 mode) { static char newpath[FAT_MAXPATH] ATTRIBUTE_ALIGN(32); s32 ret; #ifdef IOP_TRACE_OPEN svc_write("IOP: open ");svc_write(path);svc_write("\n"); #endif /* * Paths starting with '#' are always sent to real nand. * This is an internal feature, only authorized threads * can use it. */ if (*path == '#') { /* Check opening request */ ret = __IOP_CheckOpeningRequest(path, TID_RIGHTS_FORCE_REAL_NAND); /* Block request returning original invalid path */ if (!ret) return path; /* Copy path */ strcpy(newpath, path); /* Replace first character */ *newpath = '/'; /* Set flag for mode rev17-like */ forceRealPath = ((config.mode & MODE_REV17) != 0); /* Return new path */ return newpath; } /* * When a title is running only authorized threads * can open fat. * * NOTE: * Since v8 beta r42 relative fat paths, identified by the initial * '$', have been introduced to fix issue 16. * These paths are always relative to nand emulation folder. */ if (*path == '$' || !strncmp(path, "fat", 3)) { u32 running_title; /* Check a title is running */ running_title = Swi_GetRunningTitle(); /* Check thread rigths if a title is running */ if (running_title) { /* Check opening request */ ret = __IOP_CheckOpeningRequest(path, TID_RIGHTS_OPEN_FAT); /* Block opening request */ if (!ret) { /* Set new invalid path */ strcpy(newpath, "GTFO"); /* Return new path */ return newpath; } } /* Return original path */ return path; } /* Emulation mode */ if (config.mode) { /* SDHC mode */ if (config.mode & MODE_SDHC) { if (!strcmp(path, "/dev/sdio/slot0")) { /* Log */ svc_write("IOP: The game is trying to open /dev/sdio/slot0.\n"); svc_write("IOP: To avoid interferences with emu nand on sd card the request is redirected to /dev/null.\n"); /* Replace path */ strcpy(newpath, "/dev/null"); /* Return new path */ return newpath; } } /* Direct FAT mode */ if (!(config.mode & MODE_REV17)) { /* Check path */ ret = FS_CheckRealPath(path); /* Emulate path */ if (!ret) { /* Generate relative path */ ret = FS_GenerateRelativePath(path, newpath); /* Return new path */ if (ret) return newpath; } } } /* Return original path */ return path; }
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; }
void eputc(int fd, const char ch) { svc_write(fd, ch); }
void eputs(int fd, const char *str) { while(*str) svc_write(fd, *str++); }