/** => zzip_opendir * This function uses explicit ext and io instead of the internal * defaults, setting them to zero is equivalent to => zzip_opendir */ ZZIP_DIR * zzip_opendir_ext_io(zzip_char_t * filename, int o_modes, zzip_strings_t * ext, zzip_plugin_io_t io) { zzip_error_t e; ZZIP_DIR *dir; # ifdef ZZIP_HAVE_SYS_STAT_H struct stat st; # endif if (o_modes & (ZZIP_PREFERZIP | ZZIP_ONLYZIP)) goto try_zzip; try_real: # ifdef ZZIP_HAVE_SYS_STAT_H if (stat(filename, &st) >= 0 && S_ISDIR(st.st_mode)) { if (USE_DIRENT) { _zzip_DIR *realdir = _zzip_opendir(filename); if (realdir) { if (! (dir = (ZZIP_DIR *) calloc(1, sizeof(*dir)))) { _zzip_closedir(realdir); return 0; } else { dir->realdir = realdir; dir->realname = kdStrdup(filename); return dir; } } } return 0; } # endif /* HAVE_SYS_STAT_H */ try_zzip: dir = zzip_dir_open_ext_io(filename, &e, ext, io); if (! dir && (o_modes & ZZIP_PREFERZIP)) goto try_real; if (e) kdSetError ( zzip_errno(e) ); return dir; }
//----------------------------------------------------------------------- void ZipArchive::load() { OGRE_LOCK_AUTO_MUTEX; if (!mZzipDir) { zzip_error_t zzipError; mZzipDir = zzip_dir_open_ext_io(mName.c_str(), &zzipError, 0, mPluginIo); checkZzipError(zzipError, "opening archive"); // Cache names ZZIP_DIRENT zzipEntry; while (zzip_dir_read(mZzipDir, &zzipEntry)) { FileInfo info; info.archive = this; // Get basename / path StringUtil::splitFilename(zzipEntry.d_name, info.basename, info.path); info.filename = zzipEntry.d_name; // Get sizes info.compressedSize = static_cast<size_t>(zzipEntry.d_csize); info.uncompressedSize = static_cast<size_t>(zzipEntry.st_size); // folder entries if (info.basename.empty()) { info.filename = info.filename.substr (0, info.filename.length () - 1); StringUtil::splitFilename(info.filename, info.basename, info.path); // Set compressed size to -1 for folders; anyway nobody will check // the compressed size of a folder, and if he does, its useless anyway info.compressedSize = size_t (-1); } #if !OGRE_RESOURCEMANAGER_STRICT else { info.filename = info.basename; } #endif mFileList.push_back(info); } } }
/******************************************** 添加一个Patch升级包到升级操作中,后添加的后操作 *********************************************/ bool Updater::addPatchFile(const char* szPatchFile) { //参数检查 assert(szPatchFile); if(!szPatchFile || szPatchFile[0]==0) { setLastError(AXP_ERR_PARAM); return false; } //已经加入过 if(m_mapPatchFile.find(normaliseName(szPatchFile)) != m_mapPatchFile.end()) { //Log something... return true; } //打开zip文件,根据是否是加密后文件自动选择是否需要使用自定义文件读取接口 zzip_error_t zzipError; ZZIP_DIR* mZzipDir = zzip_dir_open_ext_io(szPatchFile, &zzipError, 0, (zzip_plugin_io_t)getEncryptZipPluginIO(szPatchFile)); if (zzipError != ZZIP_NO_ERROR) { setLastError(AXP_ERR_ZIPFILE, "ziperr=%d", zzipError); return false; } //保存zip文件句柄 m_mapPatchFile.insert(std::make_pair(normaliseName(szPatchFile), (void*)mZzipDir)); //打开(command)文件 char* pCmdFile=0; unsigned int nCmdFileSize = 0; if(!_readContentsFromZip(szPatchFile, PatchMaker::PATCH_COMMAND, 0, &pCmdFile, nCmdFileSize)) return false; //分解command文件 std::vector< std::string > vCommand; convertStringToVector(pCmdFile, vCommand, "\r\n", true, true); //空的更新包文件 if(vCommand.empty()) { //Log some thing... return true; } //逐行分析命令 for(int i=0; i<(int)vCommand.size(); i++) { const char* szCmdLine = vCommand[i].c_str(); std::vector< std::string > vFileCmd; convertStringToVector(vCommand[i].c_str(), vFileCmd, "|", true, false); if(vFileCmd.size() != 3) { //Log some thing... continue; } UPDATE_FILE fileCmd; fileCmd.process = (UPDATE_PROCESS)atoi(vFileCmd[0].c_str()); fileCmd.strPakFileName = vFileCmd[1]; fileCmd.strFileName = vFileCmd[2]; fileCmd.strSourceZip = szPatchFile; //规范后的文件名 std::string strNorFileName = normaliseName(fileCmd.strFileName); std::string strNorPakFile = normaliseName(fileCmd.strPakFileName); const char* szNorExt = ::PathFindExtension(strNorFileName.c_str()); //散文件 if(fileCmd.strPakFileName.empty()) { m_scatteredFiles[strNorFileName] = fileCmd; //如果这个文件本身是一个pak文件 if(szNorExt && strcmp(szNorExt, PackFile::PAKFILE_EXT) == 0) { //说明该包被删除或者重新添加, 重置对该pak包的所有操作 m_pakFiles.erase(strNorFileName); } } //pak包内文件 else { //获得目前该包的操作集合 UPDATE_PAKFILES::iterator itPak = m_pakFiles.find(strNorPakFile); if(itPak == m_pakFiles.end()) { //尚未对该pak进行任何操作,创建 m_pakFiles.insert(std::make_pair(strNorPakFile, UPDATE_FILES())); itPak = m_pakFiles.find(strNorPakFile); } assert(itPak != m_pakFiles.end()); //加入操作 itPak->second[strNorFileName] = fileCmd; } } return true; }
: Archive(name, archType), mZzipDir(0), mPluginIo(pluginIo) { } //----------------------------------------------------------------------- ZipArchive::~ZipArchive() { unload(); } //----------------------------------------------------------------------- void ZipArchive::load() { OGRE_LOCK_AUTO_MUTEX if (!mZzipDir) { zzip_error_t zzipError; mZzipDir = zzip_dir_open_ext_io(mName.c_str(), &zzipError, 0, mPluginIo); checkZzipError(zzipError, "opening archive"); // Cache names ZZIP_DIRENT zzipEntry; while (zzip_dir_read(mZzipDir, &zzipEntry)) { FileInfo info; info.archive = this; // Get basename / path StringUtil::splitFilename(zzipEntry.d_name, info.basename, info.path); info.filename = zzipEntry.d_name; // Get sizes info.compressedSize = static_cast<size_t>(zzipEntry.d_csize); info.uncompressedSize = static_cast<size_t>(zzipEntry.st_size); // folder entries
bool ExtractFileFromZip(AXP::IUpdater* pUpdater, const char* szZipFile, const char* szFileInZip, const char* szFileInDisk) { //打开zip文件 zzip_error_t zzipError; ZZIP_DIR* mZzipDir = zzip_dir_open_ext_io(szZipFile, &zzipError, 0, (zzip_plugin_io_t)(pUpdater->getEncryptZipPluginIO(szZipFile))); if (zzipError != ZZIP_NO_ERROR) { return false; } //得到文件信息 ZZIP_STAT zstat; memset(&zstat, 0, sizeof(ZZIP_STAT)); //打开文件,如果打不开,是空文件 ZZIP_FILE* zzipFile = zzip_file_open(mZzipDir, szFileInZip, ZZIP_ONLYZIP | ZZIP_CASELESS); if(!zzipFile) { zzip_dir_close(mZzipDir); return false; } //获得文件信息 int zip_err = zzip_dir_stat(mZzipDir, szFileInZip, &zstat, ZZIP_CASEINSENSITIVE); if(zip_err!=0) { zzip_file_close(zzipFile); zzip_dir_close(mZzipDir); return false; } //创建该文件 HANDLE hDiskFile = ::CreateFile(szFileInDisk, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0); if(hDiskFile == INVALID_HANDLE_VALUE) { zzip_file_close(zzipFile); zzip_dir_close(mZzipDir); return false; } if(zstat.st_size > 0) { const int MAX_BUFFER_SIZE = 4096; char buffer[MAX_BUFFER_SIZE] = {0}; zzip_seek(zzipFile, 0, SEEK_SET); zzip_ssize_t zReadSize = zzip_file_read(zzipFile, buffer, sizeof(buffer)); //实际已经写入的尺寸 unsigned int nActWriteSize = 0; //分块读写文件内容 do { //文件结束 if(zReadSize==0) break; //写入磁盘文件 DWORD dwBytesWrite; if(!WriteFile(hDiskFile, buffer, (DWORD)zReadSize, &dwBytesWrite, 0) || dwBytesWrite != (DWORD)zReadSize) { zzip_file_close(zzipFile); zzip_dir_close(mZzipDir); CloseHandle(hDiskFile); return false; } //文件结束 if(zzip_tell(zzipFile) >=zstat.st_size) break; zReadSize = zzip_file_read(zzipFile, buffer, sizeof(buffer)); }while(true); } //关闭句柄 CloseHandle(hDiskFile); hDiskFile=0; zzip_file_close(zzipFile); zzipFile=0; zzip_dir_close(mZzipDir); mZzipDir=0; return true; }