bool ArkFile::WriteFile(FILE* srcFd, const FileEntry& entry) { if( !IsOpen() ) return false; // this gets a handle to the correct file at the correct offset FILE* ark_fd = GetHandleFromOffset(entry.Offset(), false); if(ark_fd == NULL) return false; if( entry.Encrypted() ) { // file needs to be encrypted unsigned char* temp = new unsigned char[(int)entry.Arksize()]; *(int*)temp = G_CRYPT_KEY; if( fread( temp+4, 1, (int)entry.Filesize(), srcFd) != entry.Filesize() ) { delete[] temp; return false; } if(mNewEncryption) dtb_crypt_new(temp, (int)entry.Arksize()); else dtb_crypt_old(temp, (int)entry.Arksize()); if( fwrite(temp, 1, (int)entry.Arksize(), ark_fd) != entry.Arksize() ) { delete[] temp; return false; } delete[] temp; return true; } else { for(s64 i=0; i<entry.Arksize(); i+=MS_WORK_BUFFER_SIZE) { int read_size = (int)(min(entry.Arksize()-i, MS_WORK_BUFFER_SIZE)); if( fread( mpWorkBuff, 1, read_size, srcFd) != read_size || fwrite(mpWorkBuff, 1, read_size, ark_fd) != read_size ) { return false; } } return true; } }
// reads a file from ark into currently open file descriptor "destFd" bool ArkFile::ReadFile(FILE* destFd, const FileEntry& entry, bool performDecrypts) { if( !IsOpen() ) return false; if(destFd == NULL) return false; // test for possible encrypted song files bool is_mogg_file = performDecrypts && (strstr(entry.Arkname(), ".mogg") != 0); bool is_pss_file = performDecrypts && (strstr(entry.Arkname(), ".pss") != 0); bool is_vgs_file = performDecrypts && (strstr(entry.Arkname(), ".vgs") != 0); if( entry.IsExternal() ) { // read out file from external file on pc FILE* src_fd = fopen(entry.Filename(), "rb"); if(src_fd == NULL) return false; s64 filesize; if( !performDecrypts && entry.Encrypted() ) { // external file is in decrypted form on pc // but is required to be read out in encrypted form // this occurs when an external file is added to an ark then the ark is "saved as" unsigned char* temp = new unsigned char[(int)entry.Arksize()]; memcpy(temp, &G_CRYPT_KEY, 4); if( fread( temp+4, 1, (int)entry.Filesize(), src_fd) != entry.Filesize() ) { delete[] temp; return false; } if( mNewEncryption ) dtb_crypt_new(temp, (int)entry.Arksize()); else dtb_crypt_old(temp, (int)entry.Arksize()); if( fwrite(temp, 1, (int)entry.Arksize(), destFd) != entry.Arksize() ) { delete[] temp; return false; } delete[] temp; return true; } else if( performDecrypts && entry.Encrypted() ) { // external file is in decrypted form on pc // but is required to be read out in decrypted form // so just read it straight out filesize = entry.Filesize(); } else if( !entry.Encrypted() ) { // external file either isnt encrypted filesize = entry.Arksize(); } for(s64 i=0; i<filesize; i+=MS_WORK_BUFFER_SIZE) { int read_size = (int)(min(filesize-i, MS_WORK_BUFFER_SIZE)); if( fread( mpWorkBuff, 1, read_size, src_fd) != read_size || fwrite(mpWorkBuff, 1, read_size, destFd) != read_size ) { fclose(src_fd); return false; } } bool read_result = true; // decrypt output song files if they need to be if(is_mogg_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsMoggEncrypted(destFd) ) read_result = DecryptMogg(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } else if(is_pss_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsPssEncrypted(destFd) ) read_result = DecryptPss(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } else if(is_vgs_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsVgsEncrypted(destFd) ) read_result = DecryptVgs(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } // close external source file fclose(src_fd); return read_result; } else { // read out file from inside ark file FILE* src_fd = GetHandleFromOffset(entry.Offset(), true); if(src_fd == NULL) return false; if( performDecrypts && entry.Encrypted() ) { // file needs to be decrypted unsigned char* temp = new unsigned char[(int)entry.Arksize()]; if( fread( temp, 1, (int)entry.Arksize(), src_fd) != entry.Arksize() ) { delete[] temp; return false; } if( mNewEncryption ) dtb_crypt_new(temp, (int)entry.Arksize()); else dtb_crypt_old(temp, (int)entry.Arksize()); if( fwrite(temp+4, 1, (int)entry.Filesize(), destFd) != entry.Filesize() ) { delete[] temp; return false; } delete[] temp; return true; } else { for(s64 i=0; i<entry.Arksize(); i+=MS_WORK_BUFFER_SIZE) { int read_size = (int)(min(entry.Arksize()-i, MS_WORK_BUFFER_SIZE)); if( fread( mpWorkBuff, 1, read_size, src_fd) != read_size || fwrite(mpWorkBuff, 1, read_size, destFd) != read_size ) { return false; } } bool read_result = true; if(is_mogg_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsMoggEncrypted(destFd) ) read_result = DecryptMogg(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } else if(is_pss_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsPssEncrypted(destFd) ) read_result = DecryptPss(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } else if(is_vgs_file) { s64 end_file_loc = FTELL64(destFd); FSEEK64(destFd, -entry.Arksize(), SEEK_CUR); if( IsVgsEncrypted(destFd) ) read_result = DecryptVgs(destFd); else FSEEK64(destFd, end_file_loc, SEEK_SET); } return read_result; } } }