void RestoreSM (int nidx) { bool find = FALSE; char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char pathBack[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char *sm[] = {"00000088","00000085","0000008b","0000008e","00000098","00000095","0000009b","0000009e"}; s32 smsize; bool issm = FALSE; ISFS_Initialize(); int i; s32 fd; for (i = 0; i < sizeof(sm) / sizeof(char*); i++) { sprintf (path, "%s/title/00000001/00000002/content/%s.app", nandConfig->NandInfo[nidx], sm[i]); sprintf (pathBack, "%s/title/00000001/00000002/content/%s.bak", nandConfig->NandInfo[nidx], sm[i]); fd = ISFS_Open (path, ISFS_OPEN_READ); Debug ("ReplaceNandSystemMenu: checking %s (%d)", sm[i], fd); if (fd < 0) continue; smsize = ISFS_Seek(fd, 0, 2); Debug ("ReplaceNandSystemMenu: sm size %d", smsize); if (smsize > 1000000) // E' piu' grande di 1MB... e' il sistem menu issm = TRUE; ISFS_Close (fd); find = TRUE; break; } if (find && !issm) { // Restore filesistem ISFS_Delete (path); ISFS_Rename (pathBack, path); } ISFS_Deinitialize (); }
int fileBrowser_WiiFSROM_readFile(fileBrowser_file* file, void* buffer, unsigned int length){ if(fd < 0) fd = ISFS_Open( getAlignedName(&file->name), 1 ); if(fd < 0) return FILE_BROWSER_ERROR; // Make sure everything is aligned (address and length) int isUnaligned = ((int)buffer)%32 | length%32; int alignedLen = (length+31)&0xffffffe0; char* alignedBuf = isUnaligned ? memalign(32, alignedLen) : buffer; // Do the actual read, into the aligned buffer if we need to ISFS_Seek(fd, file->offset, 0); int bytes_read = ISFS_Read(fd, alignedBuf, alignedLen); if(bytes_read > 0) file->offset += bytes_read; // If it was unaligned, you have to copy it and clean up if(isUnaligned){ memcpy(buffer, alignedBuf, length); free(alignedBuf); } return bytes_read; }
u8* U8NandArchive::GetFileAllocated( const char *path, u32 *size ) const { //gprintf( "U8NandArchive::GetFileAllocated( %s )\n" ); if( !path || !fst ) { return NULL; } // find file int f = EntryFromPath( path, 0 ); if( f < 1 || f >= (int)fst[ 0 ].filelen ) { gprintf( "U8: \"%s\" wasn't found in the archive.\n", path ); return NULL; } if( fst[ f ].filetype ) { gprintf( "U8: \"%s\" is a folder\n", path ); return NULL; } // create a buffer u8* ret = (u8*)memalign( 32, RU( fst[ f ].filelen, 32 ) ); if( !ret ) { gprintf( "U8: out of memory\n" ); return NULL; } // seek and read if( ISFS_Seek( fd, dataOffset + fst[ f ].fileoffset, SEEK_SET ) != (s32)( dataOffset + fst[ f ].fileoffset ) || ISFS_Read( fd, ret, fst[ f ].filelen ) != (s32)fst[ f ].filelen ) { free( ret ); gprintf( "U8: error reading data from nand\n" ); gprintf( "fd: %i fst[ fd ].filelen: %08x\n", fd, fst[ f ].filelen ); return NULL; } u32 len = fst[ f ].filelen; u8* ret2; // determine if it needs to be decompressed if( IsAshCompressed( ret, len ) ) { // ASH0 ret2 = DecompressAsh( ret, len ); if( !ret2 ) { free( ret ); gprintf( "out of memory\n" ); return NULL; } free( ret ); } else if( isLZ77compressed( ret ) ) { // LZ77 with no magic word if( decompressLZ77content( ret, len, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else if( *(u32*)( ret ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( ret + 4, len - 4, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else { // already got what we are after ret2 = ret; } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret2, len ); return ret2; }
bool U8NandArchive::SetFile( const char* nandPath ) { if(fst) free(fst); if(name_table) free(name_table); CloseFile(); // open file if( (fd = ISFS_Open( nandPath, ISFS_OPEN_READ ) ) < 0 ) { gprintf( "U8NandArchive: ISFS_Open( \"%s\" ) failed\n", nandPath ); return false; } // get file size fstats stats __attribute__(( aligned( 32 ) )); int ret = ISFS_GetFileStats( fd, &stats ); if( ret < 0 ) { CloseFile(); gprintf( "U8NandArchive: ISFS_GetFileStats( \"%s\" ) failed\n", nandPath ); return false; } // buffer for reading the header and stuff u8* buffer = (u8*)memalign( 32, 0x800 ); if( !buffer ) { CloseFile(); gprintf( "U8NandArchive: enomem\n" ); return false; } // read a chunk big enough that it should contain the U8 header if there is going to be one if( (ret = ISFS_Read( fd, buffer, 0x800 )) != 0x800 ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: ISFS_Read( 0x800 ) = %i\n", ret ); return false; } // find the start of the U8 data U8Header* tagStart = (U8Header*)FindU8Tag( buffer, ret ); if( !tagStart ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: didn't see a U8 tag\n" ); return false; } // remember where in the file the U8 starts dataOffset = ( (u8*)tagStart - buffer ); // allocate memory and read the fst if( !(fst = (FstEntry *)memalign( 32, RU( tagStart->dataOffset - dataOffset, 32 ) ) ) || ( ISFS_Seek( fd, dataOffset + tagStart->rootNodeOffset, SEEK_SET ) != (s32)( dataOffset + tagStart->rootNodeOffset ) ) || ( ISFS_Read( fd, fst, tagStart->dataOffset - dataOffset ) != (s32)( tagStart->dataOffset - dataOffset ) ) || ( fst->filelen * 0xC > tagStart->dataOffset ) ) { dataOffset = 0; free( buffer ); if( fst ) free( fst ); CloseFile(); gprintf( "U8NandArchive: error reading fst\n" ); } // set name table pointer u32 name_table_offset = fst->filelen * 0xC; name_table = ((char *)fst) + name_table_offset; free( buffer ); return true; }
static int _ISFS_open_r(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { FILE_STRUCT *file = (FILE_STRUCT *)fileStruct; char *abspath = malloc(ISFS_MAXPATHLEN); if(!abspath) { r->_errno = ENOMEM; return -1; } char *ptr = strchr(path, ':'); if (ptr != NULL) snprintf(abspath, ISFS_MAXPATHLEN, "%s", ptr + 1); else snprintf(abspath, ISFS_MAXPATHLEN, "%s/%s", current->entry->abspath, path); RemoveDoubleSlash(abspath); if (!READ_ONLY && (flags & O_CREAT)) { int iOwnerPerm = 0; int iGroupPerm = 0; int iOtherPerm = 0; if (flags & S_IRUSR) iOwnerPerm |= ISFS_OPEN_READ; if (flags & S_IWUSR) iOwnerPerm |= ISFS_OPEN_WRITE; if (flags & S_IRGRP) iGroupPerm |= ISFS_OPEN_READ; if (flags & S_IWGRP) iGroupPerm |= ISFS_OPEN_WRITE; if (iGroupPerm & S_IROTH) iOtherPerm |= ISFS_OPEN_READ; if (flags & S_IWOTH) iOtherPerm |= ISFS_OPEN_WRITE; ISFS_CreateFile(abspath, 0, iOwnerPerm, iGroupPerm, iOtherPerm); } int iOpenMode = 0; if ((flags & 0x03) == O_RDONLY) iOpenMode |= ISFS_OPEN_READ; if (!READ_ONLY && ((flags & 0x03) == O_WRONLY)) iOpenMode |= ISFS_OPEN_WRITE; if ((flags & 0x03) == O_RDWR) iOpenMode |= READ_ONLY ? ISFS_OPEN_READ : ISFS_OPEN_RW; file->fd = ISFS_Open(abspath, iOpenMode); free(abspath); if (file->fd < 0) { if (file->fd == ISFS_EINVAL) r->_errno = EACCES; else r->_errno = -file->fd; return -1; } file->flags = flags; file->mode = mode; if (ISFS_GetFileStats(file->fd, &filest) == ISFS_OK) file->size = filest.file_length; if (!READ_ONLY && (flags & O_APPEND)) ISFS_Seek(file->fd, 0, SEEK_END); return (int)file; }
s32 extractChannelContents(u64 titleID, char* location) { u32 TitleIDH=TITLE_UPPER(titleID); u32 TitleIDL=TITLE_LOWER(titleID); if(ES_SetUID(titleID)<0) return ERR_UID; u32 tmd_size ATTRIBUTE_ALIGN(32); if(ES_GetStoredTMDSize(titleID, &tmd_size)<0) return ERR_TMDSIZE; signed_blob *TMD = (signed_blob *)memalign( 32, tmd_size ); memset(TMD, 0, tmd_size); if(ES_GetStoredTMD(titleID, TMD, tmd_size)<0) { free(TMD); return ERR_TMD; } u32 cnt ATTRIBUTE_ALIGN(32); if(ES_GetNumTicketViews(titleID, &cnt)<0) { free(TMD); return ERR_TIKCOUNT; } if( cnt <= 0 ) { free(TMD); return ERR_TIKCOUNT; } tikview *views = (tikview *)memalign( 32, sizeof(tikview)*cnt ); if(ES_GetTicketViews(titleID, views, cnt)<0) { free(views); free(TMD); return ERR_TIK; } printf("Allocated and filled views.\n"); sleep(3); Identify_SU(); int z; tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); // OH GOD CREDIAR, WTF WAS THAT MESS! // List format is "XXXXXXXX = YYYYYYYY" where X is index, and Y is cid. char *lookup_list=calloc(21,((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents); ClearScreen(); printf("\nNumber of contents: %d\n",((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents); sleep(1); for(z=0; z < ((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents; z++) { /* Get Content */ char nameDirectory[80]; sprintf(nameDirectory,"/title/%08x/%08x/content/%08x.app",TitleIDH,TitleIDL,TMDc[z].cid); s32 contentFd=ISFS_Open(nameDirectory,ISFS_OPEN_READ); u8 *data=calloc(TMDc[z].size,1); if(contentFd<0) { switch(contentFd) { case ISFS_EINVAL: printf("FAILED! (Invalid Argument %s)\n\tQuitting...\n",nameDirectory); sleep(5); Finish(1); break; case ISFS_ENOMEM: printf("FAILED! (Out of memory %s)\n\tQuitting...\n",nameDirectory); sleep(5); Finish(1); break; default: goto skip; // Finish(1); break; } } int isUnaligned = ((int)data)%32 | TMDc[z].size%32; int alignedLen = (TMDc[z].size+31)&0xffffffe0; unsigned char* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = data; ISFS_Seek(contentFd,0,0); ISFS_Read(contentFd, alignedBuf, alignedLen); // If it was unaligned, you have to copy it and clean up if(isUnaligned){ memcpy(data, alignedBuf, TMDc[z].size); free(alignedBuf); } ISFS_Close(contentFd); // Do copying here. // data is the actual content data (use fwrite with it :P). // Copy the file with it's index as it's filename char* destination=calloc(sizeof(location)+14, 1); char lookup_entry[21]; sprintf(destination, "%s/%08x.app",location,TMDc[z].index); sprintf(lookup_entry, "%08x = %08x\n",TMDc[z].index,TMDc[z].cid); strcat(lookup_list, lookup_entry); printf("Got destination as: %s\n", destination); sleep(3); FILE *dfd=fopen(destination,"wb+"); printf("Opened %s\n", destination); sleep(3); // free(destination); fwrite(data, TMDc[z].size, 1, dfd); printf("Wrote data to %s\n", destination); sleep(3); fclose(dfd); printf("Closed %s\n", destination); sleep(2); skip: _nop(); } // Make a file containing the lookups called files.txt char* lookup_file=calloc(sizeof(location)+14, 1); sprintf(lookup_file, "%s/files.txt",location); printf("Got destination as: %s\n", lookup_file); sleep(3); FILE* lfd=fopen(lookup_file,"wb+"); printf("Opened %s\n", lookup_file); sleep(3); // free(lookup_file); fwrite(lookup_list, 21, ((tmd*)SIGNATURE_PAYLOAD(TMD))->num_contents, lfd); printf("Wrote lookups to %s\n", lookup_file); sleep(3); fclose(lfd); printf("Closed %s\n", lookup_file); sleep(2); printf("Freed TMD and views"); sleep(1);
return ERR_NONE; } void changeChannelName(u64 titleID) { printf("Identifying as 00000001-00000000 (SU)!... "); CheckESRetval(ES_Identify(SU_IDENTIFY)); // if(ES_SetUID(titleID)<0) // return; u32 tmd_size ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetStoredTMDSize(titleID, &tmd_size))!=0) return; signed_blob *TMD = (signed_blob *)memalign( 32, tmd_size ); memset(TMD, 0, tmd_size); if(CheckESRetval(ES_GetStoredTMD(titleID, TMD, tmd_size))!=0) { free(TMD); return; } u32 cnt ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetNumTicketViews(titleID, &cnt))!=0) { free(TMD); return; } if( cnt <= 0 ) { free(TMD); return; } tikview *views = (tikview *)memalign( 32, sizeof(tikview)*cnt ); if(CheckESRetval(ES_GetTicketViews(titleID, views, cnt))!=0) { free(views); free(TMD); return; } char *name=calloc((0x54/2),1); int z; for(z=0; z < 1; ++z) { tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); // OH GOD CREDIAR, WTF WAS THAT MESS!!! //printf("%d,",TMDc->index); s32 cfd = ES_OpenTitleContent( titleID, TMDc->index); free(views); if(CheckESRetval(cfd)!=0) { ; //printf("ES_OpenContent(%d) failed\n", cfd); //sleep(10); //exit(0); } else { u64 sz ATTRIBUTE_ALIGN(32) = 0x140; u8 *data = (u8*)memalign(32, sz); if( TMDc->size < sz ) sz = TMDc->size; if( data != NULL ) { if(ES_ReadContent(cfd, data, sz)<0) { free(data); return; } int y; int chan_name_offset=(language_setting*0x54); // Set to WiiMU's language for(y=0;y<(0x54/2);y++) name[y]=data[(0x9C+chan_name_offset)+(y*2)+1]; } if(CheckESRetval(ES_CloseContent(cfd))!=0) { ; //printf("ES_CloseContent failed\n"); //sleep(10); //exit(0); } free(data); } } int wiistring_size; reenter: wiistring_size=type_string_wiimote(name, 0x54/2); if(wiistring_size<=0) { printf("\n\nPlease enter a name!\n"); sleep(3); goto reenter; } name[wiistring_size+1]=0; /* Get Content */ char nameDirectory[80]; tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); sprintf(nameDirectory,"/title/%08x/%08x/content/%08x.app",TITLE_UPPER(titleID),TITLE_LOWER(titleID),TMDc->cid); s32 contentFd=ISFS_Open(nameDirectory,ISFS_OPEN_RW); CheckISFSRetval(contentFd); ClearScreen(); printf("\n\nOpened content!\n"); u8 *data=calloc(TMDc->size,1); int isUnaligned = ((int)data)%32 | TMDc->size%32; int alignedLen = (TMDc->size+31)&0xffffffe0; u8* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = data; CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); int y; int chan_name_offset=(SYSCONF_GetArea()*0x54); // Edits the one for the Wii's system Menu char* nameOut=calloc(96,1); for(y=0;y<(0x54/2);y++) nameOut[(y*2)+1]=name[y]; printf("Wrote new name! %s\n", name); CheckISFSRetval(ISFS_Seek(contentFd,(0x9C+chan_name_offset),0)); printf("Seeked to location!\n"); if(nameOut==NULL) { printf("FAILED! (Name Out is NULL!)\n"); sleep(5); Finish(1); } if(((u32)nameOut%32)!=0) { isUnaligned = ((int)nameOut)%32 | 0x54%32; alignedLen = (0x54+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, nameOut, 0x54); } else alignedBuf = (u8*)nameOut; } CheckISFSRetval(ISFS_Write(contentFd, alignedBuf, 0x54)); printf("Wrote content name!\nReading new Header Chunk!\n"); CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); u8* header_chunk=calloc(0x640, 1); int i; for(i=0;i<0x630;i++) header_chunk[i]=alignedBuf[i]; for(i=0x630;i<0x640;i++) header_chunk[i]=0; u8* hash=calloc(0x10,1); md5(header_chunk, 0x640, hash); CheckISFSRetval(ISFS_Seek(contentFd,0x630,0)); printf("Seeked to location!\n"); if(hash==NULL) { printf("FAILED! (Hash is NULL!)\n"); sleep(5); Finish(1); } if(((u32)hash%32)!=0) { isUnaligned = ((int)hash)%32 | 0x10%32; alignedLen = (0x10+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, hash, 0x10); } else alignedBuf = hash;
DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count) { int retval = 0; #ifdef DEBUG printf("disk write sector %x num %x\n", (unsigned int)sector, (unsigned int)count); #endif if(sector==0)return 0; if(sector==1 && vff_fat_types[(int)drv]==32)return 0; sector--; if((sector>=0 && sector<31) && vff_fat_types[(int)drv]==32) { return 0; } if(sector>=31 && vff_fat_types[(int)drv]==32)sector-=31; //sector-=2; #ifdef HW_RVL if(vff_types[(int)drv]==0) { retval = ISFS_Seek((s32)disk_vff_handles[(int)drv], 0x20 + (sector*0x200), SEEK_SET); if(retval<0) { #ifdef DEBUG printf("seek fail\n"); #endif return RES_PARERR; } } #endif if(vff_types[(int)drv]==1) { retval = fseek((FILE*)disk_vff_handles[(int)drv], 0x20 + (sector*0x200), SEEK_SET); if(retval<0)return RES_PARERR; } if(vff_types[(int)drv]==1) { retval = fwrite(buff, 0x200, count, (FILE*)disk_vff_handles[(int)drv]); if(retval!=(0x200 * count))return RES_PARERR; } else { while(count>0) { memcpy(diskio_buffer, buff, 0x200); #ifdef HW_RVL retval = ISFS_Write((s32)disk_vff_handles[(int)drv], diskio_buffer, 0x200); #endif if(retval!=0x200) { #ifdef DEBUG printf("wrote only %x bytes, wanted %x bytes\n", retval, 0x200); #endif return RES_PARERR; } buff+=0x200; count--; } } return 0; }