u8* U8Archive::GetFileAllocated( u32 fstIdx, u32 *size ) const { u32 len; const u8 *stuff = GetFile( fstIdx, &len ); if( !stuff ) { return NULL; } return DecompressCopy( stuff, len, size ); }
u8* U8Archive::GetFileAllocated( const char *path, u32 *size ) const { u32 len; const u8 *stuff = GetFile( path, &len ); if( !stuff ) { return NULL; } return DecompressCopy( stuff, len, size ); }
CprsErr TextCompressor::Decompress(char* dest, int dlen, char* src, int slen, char** index, const ushort* lens, int nrec) { MEASURE_FET("TextCompressor::Decompress(...)"); if((!dest) || (!src) || (!index) || (slen <= 0) || (nrec <= 0)) return CPRS_ERR_PAR; if(slen < 2) return CPRS_ERR_BUF; // old versions if(src[0]) return DecompressVer2(dest, dlen, src, slen, index, lens, nrec); int spos = 1; // copy compress char ver = src[spos++]; if(ver == 0) return DecompressCopy(dest, dlen, src+spos, slen-spos, index, lens, nrec); // Version 3 if(slen <= spos) return CPRS_ERR_BUF; char lev = src[spos++]; if((ver != 3) || (lev < 1) || (lev > 9)) return CPRS_ERR_VER; // check if 'dlen' is large enough //int sumlen = 0; //for(int i = 0; i < nrec; i++) // sumlen += lens[i]; //if(sumlen > dlen) return CPRS_ERR_BUF; // decompress with IncWGraph try { RangeCoder coder; coder.InitDecompress(src, slen, spos); graph->Decode(&coder, index, lens, nrec, dest, dlen); } catch(CprsErr& e) { return e; } return CPRS_SUCCESS; }
bool NandSave::CheckSave() { /* 10 million variables */ u32 u8_bin_size = 0; u8 *u8_bin = NULL; u32 certSize = 0; signed_blob *certBuffer = NULL; u32 tmd_bin_size = 0; const signed_blob *tmd_bin = NULL; u32 tik_bin_size = 0; const signed_blob *tik_bin = NULL; u32 banner_bin_size = 0; const u8 *banner_bin = NULL; u32 entries = 0; /* May our banner already exist */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_READ); if(fd >= 0) { ISFS_Close(fd); gprintf("Found WiiFlow Save\n"); goto done; } /* extract our archive */ u8_bin = DecompressCopy(save_bin, save_bin_size, &u8_bin_size); if(u8_bin == NULL || u8_bin_size == 0) goto error; /* grab cert.sys */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/sys/cert.sys"); certBuffer = (signed_blob*)ISFS_GetFile(ISFS_Path, &certSize, -1); if(certBuffer == NULL || certSize == 0) goto error; /* Install tik and tmd */ tik_bin = (const signed_blob*)u8_get_file(u8_bin, "tik.bin", &tik_bin_size); if(tik_bin == NULL || tik_bin_size == 0) goto error; ret = ES_AddTicket(tik_bin, tik_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; tmd_bin = (const signed_blob*)u8_get_file(u8_bin, "tmd.bin", &tmd_bin_size); if(tmd_bin == NULL || tmd_bin_size == 0) goto error; ret = ES_AddTitleStart(tmd_bin, tmd_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; ret = ES_AddTitleFinish(); if(ret < 0) goto error; /* WARNING dirty, delete tik again */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000/57465346.tik"); ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; /* Delete the unused ticket folder */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000"); ret = ISFS_ReadDir(ISFS_Path, NULL, &entries); if(ret < 0) goto error; if(entries == 0) { ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; } banner_bin = u8_get_file(u8_bin, "banner.bin", &banner_bin_size); if(banner_bin == NULL || banner_bin_size == 0) goto error; memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); /* Write our banner */ ISFS_CreateFile(ISFS_Path, 0, 3, 3, 3); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_WRITE); if(fd < 0) goto error; ret = ISFS_Write(fd, banner_bin, banner_bin_size); ISFS_Close(fd); if(ret < 0) { ISFS_Delete(ISFS_Path); goto error; } free(certBuffer); if(u8_bin != save_bin) free(u8_bin); gprintf("Created WiiFlow Save\n"); done: loaded = true; return loaded; error: gprintf("Error while creating WiiFlow Save\n"); loaded = false; ES_AddTitleCancel(); if(certBuffer != NULL) free(certBuffer); certBuffer = NULL; if(u8_bin != NULL) free(u8_bin); u8_bin = NULL; tik_bin = NULL; tmd_bin = NULL; banner_bin = NULL; return loaded; }