Exemplo n.º 1
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
quakefile_t *FindQuakeFilesInZip(char *zipfile, char *filter)
{
	unzFile			uf;
	int				err;
	unz_global_info gi;
	char			filename_inzip[MAX_PATH];
	unz_file_info	file_info;
	int				i;
	quakefile_t		*qfiles, *lastqf, *qf;

	uf = unzOpen(zipfile);
	err = unzGetGlobalInfo(uf, &gi);

	if (err != UNZ_OK) return NULL;

	unzGoToFirstFile(uf);

	qfiles = NULL;
	lastqf = NULL;
	for (i = 0; i < gi.number_entry; i++)
	{
		err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL,0,NULL,0);
		if (err != UNZ_OK) break;

		ConvertPath(filename_inzip);
		if (FileFilter(filter, filename_inzip, false))
		{
			qf = malloc(sizeof(quakefile_t));
			if (!qf) Error("out of memory");
			memset(qf, 0, sizeof(quakefile_t));
			strcpy(qf->pakfile, zipfile);
			strcpy(qf->filename, zipfile);
			strcpy(qf->origname, filename_inzip);
			qf->zipfile = true;
			qf->pos = unzGetOffset(uf);
			qf->length = file_info.uncompressed_size;
			qf->type = QuakeFileType(filename_inzip);
			//add the file ot the list
			qf->next = NULL;
			if (lastqf) lastqf->next = qf;
			else qfiles = qf;
			lastqf = qf;
		} //end if
		unzGoToNextFile(uf);
	} //end for

	unzClose(uf);

	return qfiles;
} //end of the function FindQuakeFilesInZip
Exemplo n.º 2
0
	//-----------------------------------------------------------------//
	bool unzip::open(const std::string& archive)
	{
		close();

		hnd_ = unzOpen(archive.c_str());
		if(hnd_ == 0) {
			return false;
		}

		do {
			file_info fi;
			char fn[2048];
			fn[0] = 0;
			if(unzGetCurrentFileInfo(hnd_, &fi.info_, fn, sizeof(fn), NULL, 0, NULL, 0) != UNZ_OK) {
				break;
			}
			const char* p = strrchr(fn, '/');
			if(p != 0 && p[1] == 0) {	// 最後の文字が「/」で終わる場合はアーカイブに含めない
				dirs_.push_back(fn);
			} else {
				fi.ofs_ = unzGetOffset(hnd_);
				fi.path_ = fn;

				zmap::iterator it = zmap_.find(fn);
				if(it == zmap_.end()) {
					zmap::value_type stb(fn, files_.size());
					zmap_.insert(stb);
					files_.push_back(fi);
				} else {
					files_[it->second] = fi;
				}
			}
		} while(unzGoToNextFile(hnd_) != UNZ_END_OF_LIST_OF_FILE) ;

		zname_ = archive;

		return true;
	}
Exemplo n.º 3
0
bool KAppRes::OpenResPack()
{
	bool retval = false;
	zlib_filefunc_def zip_funcs;
	std::string strPathAnsi;
	int nRetCode;

	HRSRC hResInfo = NULL;
	HGLOBAL hResDat = NULL;
	PVOID pResBuffer = NULL;
	DWORD dwResBuffer = 0;

 	fill_win32_filefunc(&zip_funcs);
 	strPathAnsi = UnicodeToAnsi(m_strResPackPath);
 	m_pResPackData = unzOpen2(strPathAnsi.c_str(), &zip_funcs);

	if (m_pResPackData)
		goto UNZRESPACKDATA;

	if (strlen((const char*)&m_memZipRes) == 0)
	{//防止.kui格式错误导致unzOpen2返回空的m_pResPackData
		hResInfo = FindResourceW(_ModulePtr->GetResourceInstance(), L"kuires.dat", L"SKIN");
		if (!hResInfo)
			goto clean0;

		hResDat = LoadResource(_ModulePtr->GetResourceInstance(), hResInfo);
		if (!hResDat)
			goto clean0;

		pResBuffer = LockResource(hResDat);
		if (!pResBuffer)
			goto clean0;

		dwResBuffer = SizeofResource(_ModulePtr->GetResourceInstance(), hResInfo);
		m_memZipRes.SetData(pResBuffer, dwResBuffer);
	}

	zip_funcs.zopen_file = ZipOpenFunc;
	zip_funcs.zread_file = ZipReadFunc;
	zip_funcs.zwrite_file = ZipWriteFunc;
	zip_funcs.ztell_file = ZipTellFunc;
	zip_funcs.zseek_file = ZipSeekFunc;
	zip_funcs.zclose_file = ZipCloseFunc;
	zip_funcs.zerror_file = ZipErrorFunc;
	zip_funcs.opaque=NULL;
	m_pResPackData = unzOpen2((const char*)&m_memZipRes, &zip_funcs);

	if (!m_pResPackData)
		goto clean0;

UNZRESPACKDATA:
	nRetCode = unzGoToFirstFile(m_pResPackData);
	while (UNZ_OK == nRetCode)
	{
		char szCurrentFile[260];
		unz_file_info fileInfo;
		uLong dwSeekPos;
		uLong dwSize;

		nRetCode = unzGetCurrentFileInfo(
			m_pResPackData, 
			&fileInfo, 
			szCurrentFile, 
			sizeof(szCurrentFile), 
			NULL, 
			0, 
			NULL, 
			0
			);
		if (nRetCode != UNZ_OK)
			goto clean0;

		dwSeekPos = unzGetOffset(m_pResPackData);
		dwSize = fileInfo.uncompressed_size;
		m_mapResOffset.insert(KResOffset::value_type(szCurrentFile, KResInfo(dwSeekPos, dwSize)));

		nRetCode = unzGoToNextFile(m_pResPackData);
	}

clean0:
	return retval;
}
Exemplo n.º 4
0
Arquivo: files.c Projeto: Slipyx/r1q2
/*
=================
FS_LoadPackFile

Takes an explicit (not game tree related) path to a pak file.

Loads the header and directory, adding the files at the beginning
of the list so they override previous pack files.
=================
*/
static pack_t /*@null@*/ *FS_LoadPackFile (const char *packfile, const char *ext)
{
	
	int				i;
	void			**newitem;
	pack_t			*pack = NULL;
	packfile_t		*info;

	if (!strcmp (ext, "pak"))
	{
		unsigned		pakLen;
		int				numpackfiles;
		FILE			*packhandle;
		dpackheader_t	header;

		packhandle = fopen(packfile, "rb");

		if (!packhandle)
			return NULL;

		fseek (packhandle, 0, SEEK_END);
		pakLen = ftell (packhandle);
		rewind (packhandle);

		if (fread (&header, sizeof(header), 1, packhandle) != 1)
			Com_Error (ERR_FATAL, "FS_LoadPackFile: Couldn't read pak header from %s", packfile);

		if (LittleLong(header.ident) != IDPAKHEADER)
			Com_Error (ERR_FATAL, "FS_LoadPackFile: %s is not a valid pak file.", packfile);
		
	#if YOU_HAVE_A_BROKEN_COMPUTER
		header.dirofs = LittleLong (header.dirofs);
		header.dirlen = LittleLong (header.dirlen);
	#endif

		if (header.dirlen % sizeof(packfile_t))
			Com_Error (ERR_FATAL, "FS_LoadPackFile: Bad pak file %s (directory length %u is not a multiple of %d)", packfile, header.dirlen, (int)sizeof(packfile_t));

		numpackfiles = header.dirlen / sizeof(packfile_t);

		if (numpackfiles > MAX_FILES_IN_PACK)
			//Com_Error (ERR_FATAL, "FS_LoadPackFile: packfile %s has %i files (max allowed %d)", packfile, numpackfiles, MAX_FILES_IN_PACK);
			Com_Printf ("WARNING: Pak file %s has %i files (max allowed %d) - may not be compatible with other clients\n", LOG_GENERAL, packfile, numpackfiles, MAX_FILES_IN_PACK);

		if (!numpackfiles)
		{
			fclose (packhandle);
			Com_Printf ("WARNING: Empty packfile %s\n", LOG_GENERAL|LOG_WARNING, packfile);
			return NULL;
		}

		//newfiles = Z_TagMalloc (numpackfiles * sizeof(packfile_t), TAGMALLOC_FSLOADPAK);
		info = Z_TagMalloc (numpackfiles * sizeof(packfile_t), TAGMALLOC_FSLOADPAK);

		if (fseek (packhandle, header.dirofs, SEEK_SET))
			Com_Error (ERR_FATAL, "FS_LoadPackFile: fseek() to offset %u in %s failed. Pak file is possibly corrupt.", header.dirofs, packfile);

		if ((int)fread (info, 1, header.dirlen, packhandle) != header.dirlen)
			Com_Error (ERR_FATAL, "FS_LoadPackFile: Error reading packfile directory from %s (failed to read %u bytes at %u). Pak file is possibly corrupt.", packfile, header.dirofs, header.dirlen);

		pack = Z_TagMalloc (sizeof (pack_t), TAGMALLOC_FSLOADPAK);
		pack->type = PAK_QUAKE;
		pack->rb = rbinit ((int (EXPORT *)(const void *, const void *))strcmp, numpackfiles);

		//entry = Z_TagMalloc (sizeof(packfile_t) * numpackfiles, TAGMALLOC_FSLOADPAK);

		for (i=0 ; i<numpackfiles ; i++)
		{
			fast_strlwr (info[i].name);
#if YOU_HAVE_A_BROKEN_COMPUTER
			info[i].filepos = LittleLong(info[i].filepos);
			info[i].filelen = LittleLong(info[i].filelen);
#endif
			if (info[i].filepos + info[i].filelen >= pakLen)
				Com_Error (ERR_FATAL, "FS_LoadPackFile: File '%.64s' in pak file %s has illegal offset %u past end of file %u. Pak file is possibly corrupt.", MakePrintable (info[i].name, 0), packfile, info[i].filepos, pakLen);
			
			newitem = rbsearch (info[i].name, pack->rb);
			*newitem = &info[i];
		}

		Q_strncpy (pack->filename, packfile, sizeof(pack->filename)-1);

		pack->h.handle = packhandle;
		pack->numfiles = numpackfiles;

		Com_Printf ("Added packfile %s (%i files)\n", LOG_GENERAL,  packfile, numpackfiles);
	}
#ifndef NO_ZLIB
	else if (!strcmp (ext, "pkz"))
	{
		unzFile			f;
		unz_global_info	zipinfo;
		char			zipFileName[56];
		unz_file_info	fileInfo;

		f = unzOpen (packfile);
		if (!f)
			return NULL;

		if (unzGetGlobalInfo (f, &zipinfo) != UNZ_OK)
			Com_Error (ERR_FATAL, "FS_LoadPackFile: Couldn't read .zip info from '%s'", packfile);

		info = Z_TagMalloc (zipinfo.number_entry * sizeof(*info), TAGMALLOC_FSLOADPAK);

		pack = Z_TagMalloc (sizeof (pack_t), TAGMALLOC_FSLOADPAK);
		pack->type = PAK_ZIP;
		pack->rb = rbinit ((int (EXPORT *)(const void *, const void *))strcmp, zipinfo.number_entry);

		if (unzGoToFirstFile (f) != UNZ_OK)
			Com_Error (ERR_FATAL, "FS_LoadPackFile: Couldn't seek to first .zip file in '%s'", packfile);

		zipFileName[sizeof(zipFileName)-1] = 0;
		i = 0;
		do
		{
			if (unzGetCurrentFileInfo (f, &fileInfo, zipFileName, sizeof(zipFileName)-1, NULL, 0, NULL, 0) == UNZ_OK)
			{
				//directory, ignored
				if (fileInfo.external_fa & 16)
					continue;
				strcpy (info[i].name, zipFileName);
				info[i].filepos = unzGetOffset (f);
				info[i].filelen = fileInfo.uncompressed_size;
				newitem = rbsearch (info[i].name, pack->rb);
				*newitem = &info[i];
				i++;
			}
		} while (unzGoToNextFile (f) == UNZ_OK);

		pack->h.zhandle = f;
		Com_Printf ("Added zpackfile %s (%i files)\n", LOG_GENERAL,  packfile, i);
	}
#endif
	else
	{
		Com_Error (ERR_FATAL, "FS_LoadPackFile: Unknown type %s", ext);
	}

	return pack;
}
Exemplo n.º 5
0
	void CArchive::InitItems()
	{
		// Loading archive info
		ArchiveGuard arch(mPath.string().c_str());
		unz_global_info gi;
		unzGetGlobalInfo(arch.file, &gi);

		// Reserving space for items
		mItems.reserve(gi.number_entry);

		if(unzGoToFirstFile(arch.file) != UNZ_OK) return;
		unz_file_info fi;
		std::vector<char> fnbuf(100);

		// Iterating through children and creating resource wrappers
		do
		{
			// Getting resource info
			unzGetCurrentFileInfo(arch.file, &fi, &fnbuf[0], (unsigned long)(fnbuf.size() - 1), 0, 0, 0, 0);
			if(fi.size_filename >= (fnbuf.size() - 1))
			{
				fnbuf.resize(fi.size_filename + 50);
				unzGetCurrentFileInfo(arch.file, &fi, &fnbuf[0], (unsigned long)(fnbuf.size() - 1), 0, 0, 0, 0);
			}


			// Forming name and path
			bool isFolder = fnbuf[fi.size_filename - 1] == '/';
			if(isFolder)
				fnbuf[fi.size_filename - 1] = 0;

			std::string itName(&fnbuf[0]);
			boost::filesystem::path p(mPath);
			p /= boost::filesystem::path(itName);

			IResource* loaded;
			mFileSystem->TryGetResource(p, &loaded);


			if(!loaded)
			{
				// Resolving file or folder
				if(isFolder)
				{
					CArchFolder* fld;
					create_instance_impl<CArchFolder>(&fld);
					fld->FinalConstruct(mFileSystem, mPath, p);
					loaded = fld;
				}
				else
				{
					CArchFile* file;
					create_instance_impl<CArchFile>(&file);
					file->FinalConstruct(mFileSystem, mPath, p, unzGetOffset(arch.file));
					loaded = file;
				}
				mFileSystem->AddHandle(p.string(), loaded);
			}

			// Ref count == 1 now
			mItems.push_back(loaded);
		}
		while(unzGoToNextFile(arch.file) != UNZ_END_OF_LIST_OF_FILE);

	}