/// Decode /// /// @param archive Archive /// bool CPaz::Decode(CArcFile* archive) { if (archive->GetArcExten() != _T(".paz")) return false; // Initialize decryption key InitDecodeKey(archive); // Initialize Table InitTable(); // Decrypt table DecodeTable1(); DecodeTable2(); // Create output file const SFileInfo* file_info = archive->GetOpenFileInfo(); if (lstrcmpi(PathFindExtension(file_info->name), _T(".sc")) == 0) { archive->OpenScriptFile(); } else { archive->OpenFile(); } // Output if (file_info->format == _T("zlib")) { // ZLIB std::vector<u8> src(file_info->sizeCmp); std::vector<u8> dst(file_info->sizeOrg); // Decrypt archive->Read(src.data(), src.size()); Decrypt(src.data(), src.size()); DecodeData(src.data(), src.size()); Decrypt2(src.data(), src.size()); // Decompress CZlib zlib; zlib.Decompress(dst.data(), dst.size(), src.data(), src.size()); // Output archive->WriteFile(dst.data(), dst.size()); } else { if (archive->GetArcName() == _T("mov.paz")) { // Movie size_t buffer_size = GetMovieBufSize(archive); std::vector<u8> buffer(buffer_size); for (size_t total_written = 0; total_written != file_info->sizeOrg; total_written += buffer_size) { // Get buffer size archive->SetBufSize(&buffer_size, total_written, file_info->dwSizeOrg2); // Read archive->Read(buffer.data(), buffer_size); // Decrypt Decrypt(buffer.data(), buffer_size); DecodeMovieData(buffer.data(), buffer_size); Decrypt2(buffer.data(), buffer_size); // Adjust buffer size archive->SetBufSize(&buffer_size, total_written, file_info->sizeOrg); // Write archive->WriteFile(buffer.data(), buffer_size); } } else { // Other data size_t buffer_size = archive->GetBufSize(); std::vector<u8> buffer(buffer_size); for (size_t total_written = 0; total_written != file_info->sizeOrg; total_written += buffer_size) { // Adjust buffer size archive->SetBufSize(&buffer_size, total_written, file_info->dwSizeOrg2); // Read archive->Read(buffer.data(), buffer_size); // Decrypt Decrypt(buffer.data(), buffer_size); DecodeData(buffer.data(), buffer_size); Decrypt2(buffer.data(), buffer_size); // Adjust buffer size archive->SetBufSize(&buffer_size, total_written, file_info->sizeOrg); // Write archive->WriteFile(buffer.data(), buffer_size); } } } return true; }
/// Decode /// /// @param pclArc Archive /// BOOL CPaz::Decode(CArcFile* pclArc) { if (pclArc->GetArcExten() != _T(".paz")) return FALSE; // Initialize decryption key InitDecodeKey(pclArc); // Initialize Table InitTable(); // Decrypt table DecodeTable1(); DecodeTable2(); // Create output file SFileInfo* pstFileInfo = pclArc->GetOpenFileInfo(); if (lstrcmpi(PathFindExtension(pstFileInfo->name), _T(".sc")) == 0) { pclArc->OpenScriptFile(); } else { pclArc->OpenFile(); } // Output if (pstFileInfo->format == _T("zlib")) { // ZLIB DWORD dwSrcSize = pstFileInfo->sizeCmp; DWORD dwDstSize = pstFileInfo->sizeOrg; YCMemory<BYTE> clmbtSrc(dwSrcSize); YCMemory<BYTE> clmbtDst(dwDstSize); // Decrypt pclArc->Read(&clmbtSrc[0], dwSrcSize); Decrypt(&clmbtSrc[0], dwSrcSize); DecodeData(&clmbtSrc[0], dwSrcSize); Decrypt2(&clmbtSrc[0], dwSrcSize); // Decompress CZlib clZlib; clZlib.Decompress(&clmbtDst[0], dwDstSize, &clmbtSrc[0], dwSrcSize); // Output pclArc->WriteFile(&clmbtDst[0], dwDstSize); } else { if (pclArc->GetArcName() == _T("mov.paz")) { // Movie DWORD dwBufferSize = GetMovieBufSize(pclArc); YCMemory<BYTE> clmbtBuffer(dwBufferSize); for (DWORD dwWriteTotal = 0; dwWriteTotal != pstFileInfo->sizeOrg; dwWriteTotal += dwBufferSize) { // Get buffer size pclArc->SetBufSize(&dwBufferSize, dwWriteTotal, pstFileInfo->dwSizeOrg2); // Read pclArc->Read(&clmbtBuffer[0], dwBufferSize); // Decrypt Decrypt(&clmbtBuffer[0], dwBufferSize); DecodeMovieData(&clmbtBuffer[0], dwBufferSize); Decrypt2(&clmbtBuffer[0], dwBufferSize); // Adjust buffer size pclArc->SetBufSize(&dwBufferSize, dwWriteTotal, pstFileInfo->sizeOrg); // Write pclArc->WriteFile(&clmbtBuffer[0], dwBufferSize); } } else { // Other data DWORD dwBufferSize = pclArc->GetBufSize(); YCMemory<BYTE> clmbtBuffer(dwBufferSize); for (DWORD dwWriteTotal = 0; dwWriteTotal != pstFileInfo->sizeOrg; dwWriteTotal += dwBufferSize) { // Adjust buffer size pclArc->SetBufSize(&dwBufferSize, dwWriteTotal, pstFileInfo->dwSizeOrg2); // Read pclArc->Read(&clmbtBuffer[0], dwBufferSize); // Decrypt Decrypt(&clmbtBuffer[0], dwBufferSize); DecodeData(&clmbtBuffer[0], dwBufferSize); Decrypt2(&clmbtBuffer[0], dwBufferSize); // Adjust buffer size pclArc->SetBufSize(&dwBufferSize, dwWriteTotal, pstFileInfo->sizeOrg); // Write pclArc->WriteFile(&clmbtBuffer[0], dwBufferSize); } } } return TRUE; }
/// Mount /// /// @param archive Archive /// bool CPaz::Mount(CArcFile* archive) { if (archive->GetArcExten() != _T(".paz")) return false; // Initialize Mount Key InitMountKey(archive); // Initialize Table InitTable(); // Decode Table DecodeTable1(); DecodeTable2(); // Get index size u32 index_size; archive->ReadU32(&index_size); Decrypt(reinterpret_cast<u8*>(&index_size), sizeof(index_size)); // Get index size_t index_ptr = 0; std::vector<u8> index(index_size); archive->Read(index.data(), index.size()); // Decode Index Decrypt(index.data(), index.size()); DecodeData(index.data(), index.size()); // Get file count const u32 files = *reinterpret_cast<const u32*>(&index[0]); index_ptr += 4; // Initialization table for decoding movies if (archive->GetArcName() == _T("mov.paz")) { index_ptr += InitMovieTable(&index[index_ptr]); } // Get file info for (u32 i = 0; i < files; i++) { // Get file name TCHAR file_name[_MAX_FNAME]; lstrcpy(file_name, reinterpret_cast<LPCTSTR>(&index[index_ptr])); index_ptr += lstrlen(file_name) + 1; // Add .ogg extension if voice.paz (Don't know why they don't have extensions) if (archive->GetArcName().Left(5) == _T("voice")) { if (lstrcmp(PathFindExtension(file_name), _T("")) == 0) { lstrcat(file_name, _T(".ogg")); } } const u32 type = *reinterpret_cast<const u32*>(&index[index_ptr + 20]); // Add to list view SFileInfo file_info; file_info.name = file_name; file_info.sizeOrg = type == 1 ? *reinterpret_cast<const u32*>(&index[index_ptr + 8]) : *reinterpret_cast<const u32*>(&index[index_ptr + 12]); file_info.dwSizeOrg2 = *reinterpret_cast<const u32*>(&index[index_ptr + 16]); file_info.sizeCmp = type == 1 ? *reinterpret_cast<const u32*>(&index[index_ptr + 16]) : file_info.sizeOrg; file_info.start = *reinterpret_cast<const u32*>(&index[index_ptr + 0]); file_info.end = file_info.start + file_info.sizeCmp; if (type == 1) { file_info.format = _T("zlib"); } archive->AddFileInfo(file_info); index_ptr += 24; } return true; }
/// Mount /// /// @param pclArc Archive /// BOOL CPaz::Mount(CArcFile* pclArc) { if (pclArc->GetArcExten() != _T(".paz")) return FALSE; // Initialize Mount Key InitMountKey(pclArc); // Initialize Table InitTable(); // Decode Table DecodeTable1(); DecodeTable2(); // Get index size DWORD dwIndexSize; pclArc->Read(&dwIndexSize, 4); Decrypt(&dwIndexSize, 4); // Get index DWORD dwIndexPtr = 0; YCMemory<BYTE> clmbtIndex(dwIndexSize); pclArc->Read(&clmbtIndex[0], dwIndexSize); // Decode Index Decrypt(&clmbtIndex[0], dwIndexSize); DecodeData(&clmbtIndex[0], dwIndexSize); // Get file count DWORD dwFiles = *(DWORD*)&clmbtIndex[0]; dwIndexPtr += 4; // Initialization table for decoding movies if (pclArc->GetArcName() == _T("mov.paz")) { dwIndexPtr += InitMovieTable(&clmbtIndex[dwIndexPtr]); } // Get file info for (DWORD i = 0; i < dwFiles; i++) { // Get file name TCHAR szFileName[_MAX_FNAME]; lstrcpy(szFileName, (LPCTSTR)&clmbtIndex[dwIndexPtr]); dwIndexPtr += lstrlen(szFileName) + 1; // Add .ogg extension if voice.paz (Don't know why they don't have extensions) if (pclArc->GetArcName().Left(5) == _T("voice")) { if (lstrcmp(PathFindExtension(szFileName), _T("")) == 0) { lstrcat(szFileName, _T(".ogg")); } } DWORD dwType = *(DWORD*)&clmbtIndex[dwIndexPtr + 20]; // Add to list view SFileInfo stFileInfo; stFileInfo.name = szFileName; stFileInfo.sizeOrg = (dwType == 1) ? *(DWORD*)&clmbtIndex[dwIndexPtr + 8] : *(DWORD*)&clmbtIndex[dwIndexPtr + 12]; stFileInfo.dwSizeOrg2 = *(DWORD*)&clmbtIndex[dwIndexPtr + 16]; stFileInfo.sizeCmp = (dwType == 1) ? *(DWORD*)&clmbtIndex[dwIndexPtr + 16] : stFileInfo.sizeOrg; stFileInfo.start = *(DWORD*)&clmbtIndex[dwIndexPtr + 0]; stFileInfo.end = stFileInfo.start + stFileInfo.sizeCmp; if (dwType == 1) { stFileInfo.format = _T("zlib"); } pclArc->AddFileInfo(stFileInfo); dwIndexPtr += 24; } return TRUE; }