std::unordered_map<ResourceID, unz64_file_pos> CZipLoader::listFiles(const std::string & mountPoint, const boost::filesystem::path & archive) { std::unordered_map<ResourceID, unz64_file_pos> ret; unzFile file = unzOpen2_64(archive.c_str(), &zlibApi); if(file == nullptr) logGlobal->errorStream() << archive << " failed to open"; if (unzGoToFirstFile(file) == UNZ_OK) { do { unz_file_info64 info; std::vector<char> filename; // Fill unz_file_info structure with current file info unzGetCurrentFileInfo64 (file, &info, nullptr, 0, nullptr, 0, nullptr, 0); filename.resize(info.size_filename); // Get name of current file. Contrary to docs "info" parameter can't be null unzGetCurrentFileInfo64 (file, &info, filename.data(), filename.size(), nullptr, 0, nullptr, 0); std::string filenameString(filename.data(), filename.size()); unzGetFilePos64(file, &ret[ResourceID(mountPoint + filenameString)]); } while (unzGoToNextFile(file) == UNZ_OK); } unzClose(file); return ret; }
void ZipFile::ExtractFilenames(ZipMethod method) { if (!uf) return; unz_global_info64 ginfo; int err = unzGetGlobalInfo64(uf, &ginfo); if (err != UNZ_OK) return; unzGoToFirstFile(uf); for (int i = 0; i < ginfo.number_entry && UNZ_OK == err; i++) { unz_file_info64 finfo; char fileName[MAX_PATH]; err = unzGetCurrentFileInfo64(uf, &finfo, fileName, dimof(fileName), NULL, 0, NULL, 0); // some file format specifications only allow Deflate as compression method (e.g. XPS and EPUB) bool isSupported = Zip_Any == method || Zip_None == finfo.compression_method || method == finfo.compression_method; if (err == UNZ_OK && isSupported) { WCHAR fileNameW[MAX_PATH]; UINT cp = (finfo.flag & (1 << 11)) ? CP_UTF8 : CP_ZIP; str::conv::FromCodePageBuf(fileNameW, dimof(fileNameW), fileName, cp); filenames.Append(Allocator::StrDup(allocator, fileNameW)); fileinfo.Append(finfo); unz64_file_pos fpos; err = unzGetFilePos64(uf, &fpos); if (err != UNZ_OK) fpos.num_of_file = INVALID_ZIP_FILE_POS; filepos.Append(fpos); } err = unzGoToNextFile(uf); } commentLen = ginfo.size_comment; }
int archiveOpen(char *file) { // Start position of the archive path archive_path_start = strlen(file) + 1; // Close previous zip file first if (uf) unzClose(uf); // Open zip file uf = unzOpen64(file); if (!uf) return -1; // Clear archive list memset(&archive_list, 0, sizeof(FileList)); // Go through all files int res; char name[MAX_PATH_LENGTH]; unz_file_info64 file_info; res = unzGoToFirstFile2(uf, &file_info, name, MAX_PATH_LENGTH, NULL, 0, NULL, 0); if (res < 0) return res; while (res >= 0) { FileListEntry *entry = malloc(sizeof(FileListEntry)); // File info strcpy(entry->name, name); entry->is_folder = 0; entry->name_length = file_info.size_filename; entry->size = file_info.uncompressed_size; entry->size2 = file_info.compressed_size; // Time SceDateTime time; sceRtcSetDosTime(&time, file_info.dosDate); convertLocalTimeToUtc(&time, &time); memcpy(&entry->ctime, &time, sizeof(SceDateTime)); memcpy(&entry->mtime, &time, sizeof(SceDateTime)); memcpy(&entry->atime, &time, sizeof(SceDateTime)); // Get pos unzGetFilePos64(uf, (unz64_file_pos *)&entry->reserved); // Add entry fileListAddEntry(&archive_list, entry, SORT_BY_NAME); // Next res = unzGoToNextFile2(uf, &file_info, name, MAX_PATH_LENGTH, NULL, 0, NULL, 0); } return 0; }
void ZipFile::init() { zlib_filefunc64_def file_functions; unz_file_info64 info; unz64_file_pos position; boost::scoped_array<char> file_name; String index; Uint32 size; Sint32 ok; file_functions.zopen64_file = open_ifstream_func; file_functions.zread_file = read_istream_func; file_functions.zwrite_file = write_istream_func; file_functions.ztell64_file = tell_istream_func; file_functions.zseek64_file = seek_istream_func; file_functions.zclose_file = close_istream_func; file_functions.zerror_file = error_istream_func; m_file = unzOpen2_64(utf8_to_string(get_name()).c_str(), &file_functions); ok = unzGoToFirstFile(m_file); while (ok == UNZ_OK) { unzGetFilePos64(m_file, &position); unzGetCurrentFileInfo64(m_file, &info, 0, 0, 0, 0, 0, 0); size = info.size_filename; file_name.reset(new char[size + 1]); unzGetCurrentFileInfo64(m_file, 0, file_name.get(), size, 0, 0, 0, 0); index = String(string_to_utf8(std::string( file_name.get(), size))); m_files[index] = ZipFileEntry(position); ok = unzGoToNextFile(m_file); } }
void load_zip_archive(const char* file_name) { unzFile file; unz_file_info64 info; unz_global_info64 global_info; el_zip_file_entry_t* files; char* name; Uint32 i, count, size, index; if (file_name == 0) { LOG_ERROR("Empty zip file name", file_name); return; } if (num_zip_files >= MAX_NUM_ZIP_FILES) { LOG_ERROR("Can't add zip file %s", file_name); return; } file = unzOpen64(file_name); if (unzGetGlobalInfo64(file, &global_info) != UNZ_OK) { LOG_ERROR("Can't load zip file %s", file_name); unzClose(file); return; } count = global_info.number_entry; if (unzGoToFirstFile(file) != UNZ_OK) { LOG_ERROR("Can't load zip file %s", file_name); unzClose(file); return; } ENTER_DEBUG_MARK("load zip"); LOG_DEBUG("Loading zip file '%s' with %d files", file_name, count); files = malloc(count * sizeof(el_zip_file_entry_t)); for (i = 0; i < count; i++) { unzGetFilePos64(file, &files[i].position); unzGetCurrentFileInfo64(file, &info, 0, 0, 0, 0, 0, 0); size = info.size_filename; files[i].file_name = calloc(size + 1, 1); unzGetCurrentFileInfo64(file, 0, files[i].file_name, size, 0, 0, 0, 0); LOG_DEBUG("Loading file (%d) '%s' from zip file '%s'.", i, files[i].file_name, file_name); files[i].hash = mem_hash(files[i].file_name, size); unzGoToNextFile(file); } size = strlen(file_name); name = calloc(size + 1, 1); memcpy(name, file_name, size); LOG_DEBUG("Sorting files from zip file '%s'.", file_name); qsort(files, count, sizeof(el_zip_file_entry_t), compare_el_zip_file_entry); CHECK_AND_LOCK_MUTEX(zip_mutex); index = num_zip_files; for (i = 0; i < num_zip_files; i++) { if (zip_files[i].file_name == 0) { index = i; break; } } num_zip_files = max2u(num_zip_files, index + 1); CHECK_AND_LOCK_MUTEX(zip_files[index].mutex); CHECK_AND_UNLOCK_MUTEX(zip_mutex); LOG_DEBUG("Adding zip file '%s' at position %d.", file_name, index); zip_files[index].file_name = name; zip_files[index].file = file; zip_files[index].files = files; zip_files[index].count = count; CHECK_AND_UNLOCK_MUTEX(zip_files[index].mutex); LEAVE_DEBUG_MARK("load zip"); LOG_DEBUG("Loaded zip file '%s' with %d files", file_name, count); }
HRESULT WINAPI CZipFs::ReCreate(__in_opt void* handle, __in_opt ULONG const flags /*= 0*/) { if (flags) m_flags = flags; if ((HANDLE)handle == m_handle) return S_OK; m_handle = (HANDLE)handle; StringA strNameA = UnicodeToAnsi(m_FileName); if (UNZ_OK != unzGetFilePos64((unzFile)m_handle, &m_currentFilePos)) return E_NOT_SET; if (unzLocateFile((unzFile)m_handle, strNameA.c_str(), 0) != UNZ_OK) return E_FAIL; HRESULT hr = (unzOpenCurrentFile((unzFile)m_handle) == UNZ_OK) ? S_OK : E_FAIL; if (FAILED(hr)) { m_handle = INVALID_HANDLE_VALUE; return hr; } if (m_stream) { m_stream->Release(); m_stream = NULL; } m_stream = new CBufferedStream(); if (m_stream == NULL) { Close(); return E_OUTOFMEMORY; } int err = 0; unsigned char *pTemp = new unsigned char[WRITEBUFFERSIZE]; if (pTemp) { do { err = unzReadCurrentFile((unzFile)m_handle, pTemp, WRITEBUFFERSIZE); if (err < 0) { break; } if (err > 0) { ULONG writtenSize; if (FAILED(m_stream->Write(pTemp, (ULONG)err, &writtenSize))) break; if (writtenSize == 0) break; } } while (err > 0); delete[] pTemp; } // goto the beginning of file ULARGE_INTEGER pos = {}; LARGE_INTEGER distanceToMove = {}; m_stream->Seek(&pos, distanceToMove, IFsStream::FsStreamBegin); m_attribute->SetFilePath(m_FileName.c_str(), handle); return S_OK; }