void CZipCentralDir::OpenFile(ZIP_INDEX_TYPE uIndex) { CZipFileHeader* pOpenedFile = (*this)[uIndex]; if (!pOpenedFile->ReadLocal(this)) ThrowError(CZipException::badZipFile); m_pOpenedFile = pOpenedFile; }
void DocXDocumentStore::GetDocumentTexts(const CStdString& sFileName, std::vector<std::string>& vDocumentTexts) const { vDocumentTexts.clear(); CZipArchive zipArchive; zipArchive.Open(sFileName, CZipArchive::zipOpenReadOnly); if( !zipArchive.IsClosed() ) { CZipWordArray ar; zipArchive.FindMatches( L"word\\\\*.xml", ar ); for( int uIndex = 0; uIndex < ar.GetSize(); uIndex++ ) { CZipFileHeader fhInfo; if( zipArchive.GetFileInfo( fhInfo, ar[uIndex] ) ) { const CZipString fileName( fhInfo.GetFileName() ); if( fileName.find_first_of( '\\' ) == fileName.find_last_of( '\\' ) ) { C2007DocFile mf; zipArchive.ExtractFile( ar[uIndex], mf ); const CStdStringA sDocText = mf.GetWTInnerText(); if( sDocText.size() > 0 ) vDocumentTexts.push_back( sDocText ); } } } zipArchive.Flush(); zipArchive.Close(); } }
void CZipCentralDir::RenameFile(WORD uIndex, LPCTSTR lpszNewName) { CZipFileHeader* pHeader = m_headers[uIndex]; pHeader->SetFileName(lpszNewName); if (!m_bConvertAfterOpen) ZipCompatibility::FileNameUpdate(*pHeader, false); if (m_bFindFastEnabled) BuildFindFastArray(m_bCaseSensitive); }
void CMetadata::AllFind(CString csFind,int nCase,int nWorld) { if(csFind.IsEmpty()) return; csFind.TrimRight(); csFind.TrimLeft(); if(!nCase) csFind.MakeUpper(); int nCount=0; if(OpenZip(OPEN_LOAD)) { int nEntries=m_zip.GetNoEntries(); CZipFileHeader fhInfo; for (WORD i = 0; i < nEntries; i++) { if(EscapePress()) { Message("Поиск прерван пользователем"); return; } if(!m_zip.IsFileDirectory(i)) { m_zip.GetFileInfo(fhInfo, i); CString csFileName=fhInfo.GetFileName(); CMetaObject *pObj=GetMetaObject(csFileName,"",1); if(pObj) { CString csFile=pObj->csFile; if(!nCase) csFile.MakeUpper(); int nPos=csFile.Find(csFind); if(nPos>=0) { CString csText=FindErrorCodeLine(pObj->csFile,nPos,3); CString StrMessage; StrMessage.Format("%s %s",csFileName,csText); Message(StrMessage); nCount++; nPos=csFile.Find(csFind,nPos+1); } } } } } CString Str; Str.Format("Всего найдено %d",nCount); Message(Str); }
void CZipCentralDir::ReadHeaders() { m_pStorage->m_pFile->Seek(m_info.m_uOffset + m_info.m_uBytesBeforeZip, CZipAbstractFile::begin); RemoveHeaders(); //just in case for (int i = 0; i < m_info.m_uEntriesNumber; i++) { CZipFileHeader* pHeader = new CZipFileHeader; m_headers.Add(pHeader); if (!pHeader->Read(m_pStorage)) ThrowError(CZipException::badZipFile); ConvertFileName(true, true, pHeader); } SortHeaders(); // this is necessary when deleting files and removing data descriptors if (m_bFindFastEnabled) BuildFindFastArray(m_bCaseSensitive); }
////////////////////////////////////////////////////////////////////////// // // 번역기를 사용하여 스크립트 전체를 번역한다. // ////////////////////////////////////////////////////////////////////////// BOOL CKAGScriptMgr::SaveToZip(LPCTSTR strFileName, LPCWSTR cwszScript) { BOOL bRetVal = FALSE; if(strFileName && cwszScript) { // 파일로 저장될 내용 생성 size_t len = wcslen(cwszScript); wchar_t* buf = new wchar_t[len + 1]; buf[0] = 0xFEFF; memcpy(&buf[1], cwszScript, len*sizeof(wchar_t)); // 기존 ZIP 파일 삭제 ZIP_INDEX_TYPE zip_idx = m_zip.FindFile(strFileName, CZipArchive::ffNoCaseSens); if( ZIP_FILE_INDEX_NOT_FOUND != zip_idx ) { m_zip.RemoveFile(zip_idx); } // ZIP 파일에 추가 CZipFileHeader templ; templ.SetFileName(strFileName); m_zip.SetFileHeaderAttr(templ, 0); // 아카이브에 새 레코드를 생성한다. if( m_zip.OpenNewFile(templ, CZipCompressor::levelFastest) ) { // 데이터 압축 쓰기 if( m_zip.WriteNewFile(buf, (len+1)*sizeof(wchar_t)) ) { bRetVal = TRUE; } // 새 레코드 닫기 m_zip.CloseNewFile(); } // 퍼버 해제 delete [] buf; } return bRetVal; }
void CZipCentralDir::ReadHeaders() { if (!m_pStorage->IsBinarySplit()) m_pStorage->Seek(m_pInfo->m_uOffset); else m_pStorage->SeekInBinary(m_pInfo->m_uOffset, true); RemoveHeaders(); //just in case for (ZIP_INDEX_TYPE i = 0; i < m_pInfo->m_uEntriesNumber; i++) { CZipFileHeader* pHeader = new CZipFileHeader(this); m_pHeaders->Add(pHeader); if (!pHeader->Read(true)) ThrowError(CZipException::badZipFile); } if (m_specialFlags.IsSetAny(CZipArchive::sfExhaustiveRead)) { ZIP_FILE_USIZE uPosition = m_pStorage->GetPosition(); // different offset, or different parts if (uPosition != m_pInfo->m_uEndOffset || (m_pStorage->IsSegmented() && !m_pStorage->IsBinarySplit() && m_pStorage->GetCurrentVolume() != m_pInfo->m_uLastVolume)) for(;;) { CZipAutoBuffer buf(4); m_pStorage->Read(buf, 4, true); if (!CZipFileHeader::VerifySignature(buf)) break; CZipFileHeader* pHeader = new CZipFileHeader(this); m_pHeaders->Add(pHeader); if (!pHeader->Read(false)) ThrowError(CZipException::badZipFile); } } // this is necessary when removing data descriptors, CZipArchive::MakeSpaceForReplace, deleting, replacing or encrypting files // sort always, to yield the same results in requesting files by index regardless of the reason for opening m_pHeaders->Sort(CompareHeaders); RebuildFindFastArray(); }
void ZipCompatibility::FileNameUpdate(CZipFileHeader& header, bool bFromZip) { int iSysHeader = header.GetSystemCompatibility(); int iCurSystem = ZipPlatform::GetSystemID(); if (bFromZip) { if (iCurSystem == zcDosFat) SlashBackslashChg(header.m_pszFileName, true); if (iSysHeader == zcDosFat) ZipPlatform::AnsiOem(header.m_pszFileName, false); } else { if (iSysHeader == zcDosFat) { ZipPlatform::AnsiOem(header.m_pszFileName, true); } SlashBackslashChg(header.m_pszFileName, false); } }
bool CWebCDCovers::DownloadImage(CString strLetter, CString strName, CString strFilename, RESOURCEHOST* pHost, HWND hwndProgress, HWND hwndStatus, CString& strLocalFilename) { // get the html page for the image source *m_pbCancelDownload = false; WCC_GETIMAGEREQUEST* pfn_wccRequest = (WCC_GETIMAGEREQUEST*) GetProcAddress (pHost->hInst, "GetImageRequest"); WCC_GETIMAGEURL* pfn_wccImgURL = (WCC_GETIMAGEURL*) GetProcAddress (pHost->hInst, "GetImageURL"); char szUrl[300], szHeaders[300], szData[300]; int nMethod; pfn_wccRequest (strFilename.GetBuffer (0), strLetter.GetBuffer (0), "", szUrl, &nMethod, szHeaders, szData); CString strHTML = (*szUrl == 0) ? strFilename.GetBuffer (0) : CHttpRequest::DownloadBuffer (szUrl, nMethod, szHeaders, szData, m_pbCancelDownload, m_dwDownloadId, m_nError); // MCH 29/08/04 // Send version info to the DLL strcpy (szData, ((CCdCoverCreator2App*) AfxGetApp ())->GetVersion ().GetBuffer (-1)); // get the URL of the image CString strURL; if (!pfn_wccImgURL (strHTML.GetBuffer (0), strURL.GetBuffer (500), &nMethod, szHeaders, szData)) return false; strURL.ReleaseBuffer (); // generate a local temporary file name strLocalFilename = ((CCdCoverCreator2App*) AfxGetApp ())->GetImageCacheDir () + strURL.Mid (strURL.ReverseFind ('/') + 1); if (strLocalFilename.Find (".php?") >= 0) { // MCH 15/09/04 // www.darktown.to sends again JPGs, but via a PHP script. Filename provided as HTTP header which is not available here strLocalFilename = ((CCdCoverCreator2App*) AfxGetApp ())->GetImageCacheDir (); strLocalFilename.AppendFormat ("dld%d.jpg", GetTickCount ()); } // get the jpeg image *m_pbCancelDownload = false; CHttpRequest::DownloadFile (strURL, nMethod, szHeaders, szData, strLocalFilename, m_pbCancelDownload, m_dwDownloadId, m_nError, 0, hwndProgress, hwndStatus); if (m_nError) return false; // MCH 29/08/04 // if the download is a zip file, extract the image if (strLocalFilename.Right (4).MakeLower () == ".zip") { CString strPath = strLocalFilename.Left (strLocalFilename.ReverseFind ('\\')); CString strZipFile = strLocalFilename; // set up and open a zip archive, get the image files inside the zip file CZipArchive zip; zip.Open (strZipFile); CZipWordArray ar; zip.FindMatches ("*.jp*g", ar); strLocalFilename.Empty (); // extract the image files for (int i = 0; i < ar.GetSize (); i++) { // set the local file name CZipFileHeader info; zip.GetFileInfo (info, i); if (!strLocalFilename.IsEmpty ()) strLocalFilename += ";"; strLocalFilename += strPath + "\\" + info.GetFileName (); // extract the file zip.ExtractFile (ar.GetAt (i), strPath, false); } zip.Close (); // delete the zip file ::DeleteFile (strZipFile); } return true; }
//Заполнение списка метаданных BOOL CMetadata::Load(CString csFileName) { m_csConfigPath=csFileName; Clear(); if(!bIsLibrary) LoadSystemLibrary(); if(!OpenZip(OPEN_LOAD)) return 0; int nEntries=m_zip.GetNoEntries(); for (WORD i = 0; i < nEntries; i++) { CZipFileHeader fhInfo; m_zip.GetFileInfo(fhInfo, i); CString Str=fhInfo.GetFileName()+"\\"; if(!m_zip.IsFileDirectory(i)) AddToMeta(fhInfo.GetFileName()); int nPoint=Str.ReverseFind('.'); CString csExt; if(nPoint>0) { csExt=mUpper(Str.Mid(nPoint)); csExt.TrimRight('\\'); } if(csExt==".INF") Str=Str.Left(nPoint)+"\\"; int nIndex1=Str.Find("\\"); if(nIndex1>0) { int nIndex2=Str.Find("\\",nIndex1+1); if(nIndex2>0) { CString Str2=Str.Left(nIndex2); int n=Str2.ReverseFind('\\'); CString csName=Str2.Mid(n+1); CString csType=mUpper(Str2.Left(n)); if(csType==mUpper(OBJECTSNAME)) { csName.TrimRight(); if(csName.IsEmpty()) continue; if(!ListObjectAdd[mUpper(csName)]) { ListObjectAdd[mUpper(csName)]=(void*)1; ListObjectName.Add(csName); } //Объекты\Документ\Модули\Модуль среды исполнения.2c int nIndex3=Str.Find("\\",nIndex2+1); int nIndex4=Str.ReverseFind('.'); int nPoint=nIndex4; if(nIndex4<=0) nIndex4=Str.Find("\\",nIndex3+1); if(nIndex3>0&&nIndex4>0) { CString csGroup=mUpper(Str.Mid(nIndex2+1,nIndex3-nIndex2-1)); CString csModule=Str.Mid(nIndex3+1,nIndex4-nIndex3-1); csModule.TrimRight(); if(csModule.IsEmpty()) continue; ObjectDescription *pObject; pObject=(ObjectDescription *)OList[mUpper(csName)]; if(!pObject) pObject=new ObjectDescription(); pObject->bReadOnly=bIsLibrary; OList[mUpper(csName)]=pObject; if(csGroup==mUpper(OBJFORM)) { if(csExt==".FRM") pObject->Add(pObject->aForms,pObject->ListFormAdd,csModule); //pObject->aForms.Add(csModule); } else if(csGroup==mUpper(OBJMODULE)) { //if(csExt==".2C"&&mUpper(csModule)!=mUpper(CONFIGMODULENAME)&&mUpper(csModule)!=mUpper(ENTERPRISEMODULENAME)) if(csExt!=".INF") if(mUpper(csModule)!=mUpper(CONFIGMODULENAME)&&mUpper(csModule)!=mUpper(ENTERPRISEMODULENAME)) pObject->Add(pObject->aModule,pObject->ListModuleAdd,csModule); //pObject->aModule.Add(csModule); } else if(csGroup==mUpper(OBJMAKET)) { pObject->Add(pObject->aMakets,pObject->ListMaketAdd,csModule); //pObject->aMakets.Add(csModule); } else if(csGroup==mUpper(OBJCONST)) { if(pObject->Add(pObject->aConst,pObject->ListConstAdd,csModule)) if(!aHashKeywordList[mUpper(csModule)]) { aGlVariables.Add(csModule); aHashKeywordList[mUpper(csModule)]=(void*)1; } /* if(!mUpper(csModule).IsEmpty()) if(!aHashKeywordList[mUpper(csModule)]) { aGlVariables.Add(csModule); aHashKeywordList[mUpper(csModule)]=(void*)1; } pObject->aConst.Add(csModule);*/ } } } /* else if(csType==mUpper(METADATANAME)) { if(csExt==".ATR") { ObjectDescription *pObject; pObject=(ObjectDescription *)OList[mUpper(csName)]; if(!pObject) pObject=new ObjectDescription(); OList[mUpper(csName)]=pObject; pObject->aAttrList.Add(csModule); } } */ else if(csType==mUpper(MODULESNAME)) { CString csFileType=mUpper(Str2.Right(3)); if(csFileType!=".INF") { if(csFileType==".2C") csName=csName.Left(csName.GetLength()-3); csName.TrimRight(); if(csName.IsEmpty()) continue; if(!ListModuleAdd[mUpper(csName)]) { ListModuleAdd[mUpper(csName)]=(void*)1; ListModuleName.Add(csName); } } } else if(csType==mUpper(FORMSNAME)) { CString csFileType=mUpper(Str2.Right(4)); if(csFileType==".FRM") { csName=csName.Left(csName.GetLength()-4); csName.TrimRight(); if(csName.IsEmpty()) continue; if(!ListFormAdd[mUpper(csName)]) { ListFormAdd[mUpper(csName)]=(void*)1; ListFormName.Add(csName); } } } else if(csType==mUpper(MAKETSNAME)) { csName.TrimRight(); if(csName.IsEmpty()) continue; if(!ListMaketAdd[mUpper(csName)]) { ListMaketAdd[mUpper(csName)]=(void*)1; ListMaketName.Add(csName); } } } } } SortList(ListFormName); SortList(ListMaketName); SortList(ListModuleName); SortList(ListObjectName); // SortList(ListMetadataName); OpenZip(CLOSE_FILE); //временное закрытие return TRUE; }
DWORD WINAPI zipCompress(LPVOID lpParam){ _filename = COMPRESS_PREPARING; sTime = time(NULL); CZipArchive zip; vector<__int64>filesize; _size_all = 1; /*char b[123]; sprintf(b, "%d", spanSize); MessageBox(0, b, "", 0);*/ if(spanSize == 0) zip.Open(archive_name, CZipArchive::OpenMode::zipCreate); else zip.Open(archive_name, CZipArchive::OpenMode::zipCreateSpan, spanSize); zip.SetPassword(passwd); //zip.SetAutoFlush(); _filename = COMPRESS_GETTING_FILE_SIZES; for (int i=0; i<int(filename.size()); ++i) { FILE* f=fopen(filename[i].c_str(), "rb"); if(f){ _fseeki64(f, 0LL, SEEK_END); filesize.push_back(_ftelli64(f)); _size_all += _ftelli64(f); fclose(f); } } for(int i=0;i<filename.size();i++){ _filename = filename[i]; //zip.AddNewFile(filename[i].c_str(), MEM); zip.AddNewFile(filename[i].c_str(), filename[i].c_str(), MEM); _done_all += filesize[i]; CZipFileHeader fhInfo; zip.GetFileInfo(fhInfo, i); _compressed += fhInfo.GetEffComprSize() + fhInfo.GetSize() + fhInfo.GetExtraFieldSize(); } zip.Close(); /*FILE *f = fopen(archive_name, "rb"); if(f){ _fseeki64(f, 0LL, SEEK_END); _compressed = _ftelli64(f); fclose(f); }*/ if(sfx_arch){ //do³¹czamy modu³ sfx _filename = COMPRESS_ADDING_SFX_MOD; /*archive_name[strlen(archive_name)-3] = '\0'; sprintf(archive_name, "%sexe", archive_name);*/ //odczytujemy œcie¿kê do modu³u HANDLE hProc = GetCurrentProcess(); HMODULE hMod; DWORD cbNeeded; char processName[MAX_PATH]; EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeeded); GetModuleFileNameEx(hProc, hMod, processName, MAX_PATH); for(int i=strlen(processName)-1;i>=0;i--){ if(processName[i] == '\\' || processName[i] == '/'){ processName[i+1] = '\0'; sprintf(processName, "%skgb_arch_sfx_zip.mod", processName); break; } } FILE *sfx = fopen(processName, "rb"); //MessageBox(0, "", "", 0); if(sfx == NULL){ MessageBox(0, "An internal error has occured, please reinstall KGB Archiver!", "KGB Archiver", 0); _fcloseall(); DeleteFile(archive_name); return false; } //MessageBox(0, archive_name, "", 0); FILE *archive = fopen(archive_name, "rb"); if(archive == NULL){ _fcloseall(); return false; } //MessageBox(0, "", "", 0); archive_name[strlen(archive_name)-3] = '\0'; sprintf(archive_name, "%sexe", archive_name); //MessageBox(0, archive_name, "", 0); FILE *archive_sfx = fopen(archive_name, "wb"); if(archive_sfx == NULL){ _fcloseall(); return false; } //MessageBox(0, "2", "", 0); int count=0; char buffer[65536]; while(!feof(sfx)){ count = fread(buffer, sizeof(char), sizeof(buffer), sfx); fwrite(buffer, sizeof(char), count, archive_sfx); } while(!feof(archive)){ count = fread(buffer, sizeof(char), sizeof(buffer), archive); fwrite(buffer, sizeof(char), count, archive_sfx); } fclose(archive); fclose(sfx); fclose(archive_sfx); archive_name[strlen(archive_name)-3] = '\0'; sprintf(archive_name, "%szip", archive_name); DeleteFile(archive_name); } _done_all++; return true; }
bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer) { ziparchv::CZipFileMapping fm; char* pFile; DWORD uSize; if (bFromBuffer) { uSize = m_pStorage->m_uBytesInWriteBuffer; pFile = m_pStorage->m_pWriteBuffer; } else { uSize = m_pStorage->m_pFile->GetLength(); // we cannot use CZipMemFile in multidisk archive // so it MUST be CZipFile if (!fm.CreateMapping(static_cast<CZipFile*>(m_pStorage->m_pFile))) return false; pFile = fm.GetMappedMemory(); } DWORD uOffsetToChange = 4; DWORD uPosInBuffer = 0; DWORD uExtraHeaderLen; int iCount = m_headers.GetSize(); for (int i = 0; i < iCount; i++) { // update the flag value in the local and central header // int uDataDescr = (m_headers[i]->m_uFlag & 8) ? (4 + 12) : 0; CZipFileHeader* pHeader = m_headers[i]; char* pSour = pFile + pHeader->m_uOffset; if (!pHeader->IsEncrypted()) { // removing data descriptor pHeader->m_uFlag &= ~8; // update local header: // write modified flag in the local header memcpy(pSour + 6, &pHeader->m_uFlag, 2); uExtraHeaderLen = 4/*ext. header signature*/ + 12/*data descriptor*/; } else // do not remove data descriptors from encrypted files uExtraHeaderLen = 0; // update crc32 and sizes' values pHeader->GetCrcAndSizes(pSour+ 14); DWORD uToCopy = (i == (iCount - 1) ? uSize : m_headers[i + 1]->m_uOffset) - pHeader->m_uOffset - uExtraHeaderLen; memmove(pFile + uPosInBuffer, pSour, uToCopy); uPosInBuffer += uToCopy; pHeader->m_uOffset -= uOffsetToChange; uOffsetToChange += uExtraHeaderLen; } if (bFromBuffer) m_pStorage->m_uBytesInWriteBuffer = uPosInBuffer; else { m_pStorage->m_iBytesWritten = uPosInBuffer; fm.RemoveMapping(); m_pStorage->m_pFile->SetLength(uPosInBuffer); } return true; }
void CZipCentralDir::WriteHeaders(CZipActionCallback* pCallback, bool bOneDisk) { m_info.m_uDiskEntriesNo = 0; m_info.m_uDiskWithCD = (WORD)m_pStorage->GetCurrentDisk(); m_info.m_uOffset = m_pStorage->GetPosition() - m_info.m_uBytesBeforeZip; if (!m_info.m_uEntriesNumber) return; WORD iDisk = m_info.m_uDiskWithCD; int iStep = 0; // for the compiler if (pCallback) { pCallback->Init(); pCallback->SetTotal(m_info.m_uEntriesNumber); iStep = CZipActionCallback::m_iStep;// we don't want to wait forever } int iAborted = 0; for (int i = 0; i < m_info.m_uEntriesNumber; i++) { CZipFileHeader* pHeader = (*this)[i]; CZipString szRemember; if (m_bConvertAfterOpen) // if CZipArchive::Flush is called we will be still using the archive, so restore changed name szRemember = pHeader->GetFileName(); ConvertFileName(false, true, pHeader); m_info.m_uSize += pHeader->Write(m_pStorage); if (m_bConvertAfterOpen) pHeader->SetFileName(szRemember); if (m_pStorage->GetCurrentDisk() != iDisk) { m_info.m_uDiskEntriesNo = 1; iDisk = (WORD)m_pStorage->GetCurrentDisk(); // update the information about the offset and starting disk if the // first header was written on the new disk if (i == 0) { m_info.m_uOffset = 0; m_info.m_uDiskWithCD = iDisk; } } else m_info.m_uDiskEntriesNo++; if (pCallback && !(i%iStep)) if (!pCallback->Callback(iStep)) { if (bOneDisk) { if (!m_pStorage->IsSpanMode()) m_pStorage->EmptyWriteBuffer(); else m_pStorage->Flush(); // must be flush before - flush was not called in span mode // remove saved part from the disk m_pStorage->m_pFile->SetLength(m_info.m_uBytesBeforeZip + m_info.m_uOffset); // We can now abort safely iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; break; } } if (pCallback) pCallback->CallbackEnd(); if (iAborted) ThrowError(iAborted); }
CValue CValueMetadata::Method(int iName,CValue **p) { CMetadata *pMeta=0; if(bWasOpenZip==0 && iName!=enOpen && iName!=enClose && AfxGetModuleManager()==NULL) { Error("Конфигурация не инициализирована"); } if(AfxGetModuleManager()) pMeta=AfxGetModuleManager()->pMetadata; CValue Ret; switch(iName) { case enOpen: { if(bWasOpenZip) Close(); CString csFileName=p[0]->GetString(); BOOL bReadOnly=p[1]->GetNumber(); if(!bReadOnly) if(!FileExist(csFileName)) { try { m_zip.Open(csFileName, CZipArchive::create,0);//Новый архив m_zip.Close(); } catch(...) { Error("Ошибка при попытке создания нового файла: %s",csFileName); return 0; } } if(m_zip.FileExists(csFileName)) { try { if(bReadOnly) m_zip.Open(csFileName, CZipArchive::openReadOnly,0); else m_zip.Open(csFileName, CZipArchive::open,0); } catch(...) { Error("Ошибка открытия файла: %s",csFileName); return 0; } } else Error("Не найден файл: %s",csFileName); m_zip.EnableFindFast(1); bWasOpenZip=1; return 1; } case enSaveData3: { CString csPath=GetFullMetaPath(csPathObject,p[0]->GetString()); CString csFile=p[1]->GetString(); int nSize=0; char *buf=LoadFromFileBin(csFile,nSize); if(buf) { if(bWasOpenZip) { return ::WriteFileFromStream(buf,nSize,csFile,m_zip,p[0]->GetString(),p[2]->GetString(),p[3]->GetString(),1); } else { return pMeta->WriteFileFromStream(buf,nSize,csFile,csPath,p[2]->GetString(),p[3]->GetString()); } } } case enSaveData: case enSaveData2: case enSaveText: { CString csData; CString csPath=GetFullMetaPath(csPathObject,p[0]->GetString()); if(enSaveText==iName) { csData=p[1]->GetString(); } else { p[1]->SaveToString(csData); } if(bWasOpenZip) { return ::WriteFileFromString(csData,m_zip,p[0]->GetString(),p[2]->GetString(),p[3]->GetString(),1); } else { return pMeta->WriteFileFromString(csData,csPath,p[2]->GetString(),p[3]->GetString()); } } case enLoadData3: { CString csAlias,csComment; CString csPath=GetFullMetaPath(csPathObject,p[0]->GetString()); CString csFile=p[1]->GetString(); if(bWasOpenZip) { if(!csPath.IsEmpty()) { int nRes=m_zip.FindFile(csPath); if(nRes>=0) { bool bRes=m_zip.OpenFile(nRes); CZipFileHeader fhInfo; m_zip.GetFileInfo(fhInfo, nRes); CString csDescription=fhInfo.GetComment(); int nIndex=csDescription.Find("\n"); csAlias=csDescription.Left(nIndex); csComment=csDescription.Mid(nIndex+1); int nSize=fhInfo.m_uUncomprSize; char* pBuffer=new char [nSize+1]; pBuffer[nSize]=0; DWORD nRez=m_zip.ReadFile(pBuffer,nSize); if(FILE *sFile=fopen(csFile,"w+b")) { fwrite(pBuffer,sizeof(char),nSize, sFile); fclose(sFile); } delete []pBuffer; m_zip.CloseFile(); } } } Ret=1; p[2]->SetString(csAlias); p[3]->SetString(csComment); break; } case enLoadData: case enLoadData2: case enLoadText: { CString csAlias,csComment; CString csPath=GetFullMetaPath(csPathObject,p[0]->GetString()); CString csData; if(bWasOpenZip) { csData=::ReadFileToString(m_zip,p[0]->GetString(),csAlias,csComment); } else { csData=pMeta->ReadFileToString(csPath,csAlias,csComment); } if(enLoadText==iName) { Ret=String(csData); } else { Ret.LoadFromString(csData); } *p[1]=Ret; p[2]->SetString(csAlias); p[3]->SetString(csComment); break; } case enDeleteData: { CString csPath=METADATANAME+"\\"+csPathObject+p[0]->GetString(); if(bWasOpenZip) { if(m_zip.FindFile(p[0]->GetString())) return ::DeleteFile(m_zip,p[0]->GetString()); else return ::DeleteFolder(m_zip,p[0]->GetString()); } else { return pMeta->DeleteData(csPath); } } case enClose: { Close(); break; } case enGetCountEntries: { if(!bWasOpenZip) Error("Внешний файл метаданных не открыт"); return m_zip.GetNoEntries(); } case enGetName: { if(!bWasOpenZip) Error("Внешний файл метаданных не открыт"); int n=p[0]->GetNumber(); if(n<1 || n>m_zip.GetNoEntries()) Error("Значение индекса выходит за границу допустимых значений"); CZipFileHeader fhInfo; m_zip.GetFileInfo(fhInfo, n-1); return String(fhInfo.GetFileName()); } } return Ret; }
DWORD ProgressDialog::UpgradeAsync() { typedef std::list<CString> BackupFiles; CZipArchive ar; if (!ar.Open(upgradeFilePath_)) { ::PostMessage(m_hWnd, WM_UPGRADE_DONE, FALSE, 0); return 0; } bool copySuccess = true; TCHAR filePath[MAX_PATH]; BackupFiles backupFiles; WORD fileCount = ar.GetCount(); for (WORD i = 0; i < fileCount; i++) { CZipFileHeader *fileInfo = ar.GetFileInfo(i); if (fileInfo->IsDirectory()) { continue; } const CZipString &fileName = fileInfo->GetFileName(); _tcscpy(filePath, appDir_); PathAddBackslash(filePath); _tcscat(filePath, fileName); if (PathFileExists(filePath)) { TCHAR backupFilePath[MAX_PATH]; _tcscpy(backupFilePath, appDir_); PathAddBackslash(backupFilePath); _tcscat(backupFilePath, fileName); _tcscat(backupFilePath, _T(".bak")); if (PathFileExists(backupFilePath)) { DeleteFile(backupFilePath); } if (!MoveFile(filePath, backupFilePath)) { copySuccess = false; break; } backupFiles.push_back((LPCTSTR)fileName); } if (!ar.ExtractFile(i, appDir_)) { copySuccess = false; break; } } if (copySuccess) { AfxGetApp()->WriteProfileString(_T(""), _T("Version"), appVersion_); // remove backup files. for (BackupFiles::const_iterator i = backupFiles.begin(); i != backupFiles.end(); ++i) { TCHAR backupFilePath[MAX_PATH]; _tcscpy(backupFilePath, appDir_); PathAddBackslash(backupFilePath); _tcscat(backupFilePath, *i); _tcscat(backupFilePath, _T(".bak")); DeleteFile(backupFilePath); } } else { // upgrade failed, restore backup. for (BackupFiles::const_iterator i = backupFiles.begin(); i != backupFiles.end(); ++i) { TCHAR backupFilePath[MAX_PATH]; _tcscpy(backupFilePath, appDir_); PathAddBackslash(backupFilePath); _tcscat(backupFilePath, *i); _tcscat(backupFilePath, _T(".bak")); TCHAR filePath[MAX_PATH]; _tcscpy(filePath, appDir_); PathAddBackslash(filePath); _tcscat(filePath, *i); DeleteFile(filePath); MoveFile(backupFilePath, filePath); } } ::PostMessage(m_hWnd, WM_UPGRADE_DONE, TRUE, 0); return 0; }
bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer) { // this will not work if there are bytes before zip CZipFileMapping fm; char* pFile; ZIP_SIZE_TYPE uSize; if (bFromBuffer) { uSize = m_pStorage->m_uBytesInWriteBuffer; pFile = m_pStorage->m_pWriteBuffer; } else { uSize = (ZIP_SIZE_TYPE)m_pStorage->m_pFile->GetLength(); // we cannot use CZipMemFile in multi-volume archive // so it must be CZipFile if (!fm.CreateMapping(static_cast<CZipFile*>(m_pStorage->m_pFile))) return false; pFile = fm.GetMappedMemory(); } ZIP_SIZE_TYPE uOffsetToChange = 4; ZIP_SIZE_TYPE uPosInBuffer = 0; WORD uExtraHeaderLen; ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) { CZipFileHeader* pHeader = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i]; char* pSource = pFile + pHeader->m_uOffset; if (pHeader->NeedsDataDescriptor()) uExtraHeaderLen = (WORD)(pHeader->IsEncrypted() ? 0 : 4); else { uExtraHeaderLen = pHeader->GetDataDescriptorSize(true); // removing data descriptor pHeader->m_uFlag &= ~8; // update local header: // write modified flag in the local header CBytesWriter::WriteBytes(pSource + 6, pHeader->m_uFlag); pHeader->WriteSmallDataDescriptor(pSource + 14, false); } ZIP_SIZE_TYPE uToCopy = (i == (uCount - 1) ? uSize : (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)(i + 1)]->m_uOffset) - pHeader->m_uOffset - uExtraHeaderLen; if (uToCopy > 0) // TODO: [postponed] the size_t limit on uToCopy, but creating such a big segment is unlikely (at least at the moment of writing) memmove(pFile + uPosInBuffer, pSource, (size_t)uToCopy); uPosInBuffer += uToCopy; pHeader->m_uOffset -= uOffsetToChange; uOffsetToChange += uExtraHeaderLen; } if (bFromBuffer) m_pStorage->m_uBytesInWriteBuffer = (DWORD)uPosInBuffer; else { m_pStorage->m_uBytesWritten = uPosInBuffer; fm.RemoveMapping(); m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)uPosInBuffer); } return true; }
void CZipCentralDir::WriteHeaders(bool bOneDisk) { CZipActionCallback* pCallback = m_pArchive->GetCallback(CZipActionCallback::cbSave); m_pInfo->m_uVolumeEntriesNo = 0; bool binarySplit = m_pStorage->IsBinarySplit(); if (binarySplit) { m_pStorage->AssureFree(1); m_pInfo->m_uVolumeWithCD = 0; } else m_pInfo->m_uVolumeWithCD = m_pStorage->GetCurrentVolume(); m_pInfo->m_uOffset = m_pStorage->GetPosition(); if (!m_pInfo->m_uEntriesNumber) return; ZIP_VOLUME_TYPE uDisk = m_pStorage->GetCurrentVolume(); if (pCallback) { pCallback->Init(); pCallback->SetTotal(m_pInfo->m_uEntriesNumber); } int iAborted = 0; if (m_pInfo->m_uEntriesNumber > 0) { ZIP_INDEX_TYPE uLast = (ZIP_INDEX_TYPE)(m_pInfo->m_uEntriesNumber - 1); ZIP_INDEX_TYPE i = 0; for (;;) { CZipFileHeader* pHeader = (*this)[i]; m_pInfo->m_uSize += pHeader->Write(m_pStorage); if (!binarySplit && m_pStorage->GetCurrentVolume() != uDisk) { m_pInfo->m_uVolumeEntriesNo = 1; uDisk = m_pStorage->GetCurrentVolume(); // update the information about the offset and starting volume if the // first header was written in the new volume if (i == 0) { m_pInfo->m_uOffset = 0; m_pInfo->m_uVolumeWithCD = uDisk; } } else m_pInfo->m_uVolumeEntriesNo++; if (pCallback) { bool ret, last; if (i == uLast) { ret = pCallback->RequestLastCallback(1); last = true; } else { ret = pCallback->RequestCallback(); last = false; } if (ret) { if (last) break; } else { if (bOneDisk) { ASSERT(!m_pStorage->IsSegmented()); // if segmented, would need to m_pStorage->Flush(), but the headers can span multiple volumes m_pStorage->EmptyWriteBuffer(); // remove saved part from the volume m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)(m_pStorage->m_uBytesBeforeZip + m_pInfo->m_uOffset)); // We can now abort safely iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; break; } } else if (i == uLast) break; i++; } } if (pCallback) { pCallback->CallbackEnd(); if (iAborted) ThrowError(iAborted); } }
void CZipCentralDir::Write() { if (m_pInfo->m_bInArchive) return; m_pInfo->m_uEntriesNumber = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); if (!m_pStorage->IsSegmented()) { m_pStorage->Flush(); m_pStorage->m_pFile->SeekToEnd(); } // else // we are at the end already m_pInfo->m_uSize = 0; bool bDontAllowVolumeChange = false; if (m_pStorage->IsSegmented()) { // segmentation signature at the beginning (4 bytes) + the size of the data descr. for each file ZIP_SIZE_TYPE uSize = GetSize(true); // if there is a segmented archive in creation and it is only one-volume, // (current volume number is 0 so far, no bytes has been written so we know they are // all in the buffer) make sure that it will be after writing central dir // and make it a not segmented archive if (m_pStorage->GetCurrentVolume() == 0) { // calculate the size of data descriptors already in the buffer or on the disk // (they will be removed in the not segmented archive). ZIP_SIZE_TYPE uToGrow = uSize - 4; for (ZIP_INDEX_TYPE i = 0; i < m_pInfo->m_uEntriesNumber; i++) { CZipFileHeader* pHeader = (*this)[i]; if (pHeader->NeedsDataDescriptor()) { if (!pHeader->IsEncrypted()) uToGrow -= 4; // remove the signature only } else uToGrow -= pHeader->GetDataDescriptorSize(true); } ZIP_SIZE_TYPE uVolumeFree = m_pStorage->VolumeLeft(); if (uVolumeFree >= uToGrow) // lets make sure it will be one-volume archive { // can the operation be done only in the buffer? if (!m_pStorage->m_uBytesWritten && // no bytes on the disk yet (m_pStorage->GetFreeInBuffer() >= uToGrow)) // is the buffer big enough? { RemoveDataDescr(true); bDontAllowVolumeChange = true; // if a volume change occurs somehow, we'll throw an error later } else { m_pStorage->Flush(); if (RemoveDataDescr(false)) bDontAllowVolumeChange = true; // if a volume change occurs somehow, we'll throw an error later } } } // make sure that in a segmented archive, the whole central directory will fit on the single volume if (!bDontAllowVolumeChange && !m_pStorage->IsBinarySplit()) m_pStorage->AssureFree(uSize); } try { WriteHeaders(bDontAllowVolumeChange || !m_pStorage->IsSegmented()); WriteCentralEnd(); if (bDontAllowVolumeChange) { if (m_pStorage->GetCurrentVolume() != 0) ThrowError(CZipException::badZipFile); } } catch (...) { if (bDontAllowVolumeChange) { m_pStorage->FinalizeSegm(); m_pInfo->m_uLastVolume = 0; } throw; } m_pInfo->m_bInArchive = true; }
// add new header using the argument as a template CZipFileHeader* CZipCentralDir::AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy) { // copy some of the template data m_pOpenedFile = NULL; ZIP_INDEX_TYPE uIndex; CZipFileHeader* pHeader = new CZipFileHeader(this); try { pHeader->m_uMethod = header.m_uMethod; pHeader->m_uModDate = header.m_uModDate; pHeader->m_uModTime = header.m_uModTime; pHeader->m_tModificationTime = header.m_tModificationTime; pHeader->m_tCreationTime = header.m_tCreationTime; pHeader->m_tLastAccessTime = header.m_tLastAccessTime; pHeader->m_uExternalAttr = header.m_uExternalAttr; pHeader->m_uLocalComprSize = header.m_uLocalComprSize; pHeader->m_uLocalUncomprSize = header.m_uLocalUncomprSize; pHeader->m_uLocalHeaderSize = header.m_uLocalHeaderSize; pHeader->m_fileName = header.m_fileName; pHeader->m_comment = header.m_comment; pHeader->m_aLocalExtraData = header.m_aLocalExtraData; // local will be removed in a moment in PrepareData pHeader->m_aCentralExtraData = header.m_aCentralExtraData; pHeader->m_aCentralExtraData.RemoveInternalHeaders(); pHeader->m_iSystemCompatibility = header.m_iSystemCompatibility; pHeader->m_uEncryptionMethod = header.m_uEncryptionMethod; pHeader->UpdateStringsFlags(false); #ifdef _ZIP_UNICODE_CUSTOM // current settings pHeader->m_stringSettings = GetStringStoreSettings(); #endif // set only when adding a new file, not in PrepareData (which may be called under different circumstances) // we need the proper encryption method to be set already RemoveFromDisk(); bool bReplace = IsValidIndex(uReplaceIndex); pHeader->PrepareData(iLevel, m_pStorage->IsSegmented()); if (bRichHeaderTemplateCopy) { // call here, because PrepareData will zero them pHeader->m_uCrc32 = header.m_uCrc32; pHeader->m_uComprSize = header.m_uComprSize; pHeader->m_uUncomprSize = header.m_uUncomprSize; } // now that everything is all right, we can add the new file if (bReplace) { // PrepareStringBuffers was called in CZipArchive::OpenNewFile // the local extra field is updated if needed, so we can check the lengths if (!pHeader->CheckLengths(true)) ThrowError(CZipException::tooLongData); CZipFileHeader* pfh = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uReplaceIndex]; m_pStorage->Seek(pfh->m_uOffset); RemoveFile(pfh, uReplaceIndex, false); m_pHeaders->InsertAt((ZIP_ARRAY_SIZE_TYPE)uReplaceIndex, pHeader); m_pOpenedFile = pHeader; uIndex = uReplaceIndex; } else { uIndex = (ZIP_INDEX_TYPE)m_pHeaders->Add(pHeader); m_pOpenedFile = pHeader; m_pStorage->m_pFile->SeekToEnd(); } } catch(...) { // otherwise it is added to the collection and will be auto-deleted if (pHeader != NULL && m_pOpenedFile == NULL) delete pHeader; throw; } if (m_pInfo->m_bFindFastEnabled) InsertFindFastElement(pHeader, uIndex); // GetCount > 0, because we have just added a header m_pInfo->m_iLastIndexAdded = uIndex; return pHeader; }