Zip and Unzip, the MFC Way

This library allows creating, modifying and extracting zip archives in the compatible way with PKZIP and WinZip. Supported are all possible operations on the zip archive: creating, extracting, adding, deleting files from the archive, modifications of the existing archive. There is also the support for creating and extracting multiple disk archives (this is probably the first free code on the internet that supports disk spanned archives). This module uses compression and decompression functions from zlib library by Jean-loup Gailly and Mark Adler.

How to integrate with the project

Zip is a static library and statically links to compiled zlib.lib (version 1.13 nowadays). The zlib library can be replaced with a newer version providing you also replace the files: "zlib.h" and "zconf.h" in the Zip project. The Zip library uses MFC in a shared library as a Release and Debug Configuration. Your project must use MFC in the same way in the appropriate project configuration. You may need to adapt this to your needs. To add Zip library functionality to your project you need to link the library to the project. You can do this in at least two ways:

Method 1

Add "..\Zip\debug(release)\Zip.lib" to Project Settings->Link->Input->Object/library modules and add Zip directory to the preprocessor searches (Project Settings -> C++ -> Preprocessor -> Additional include directories).

Method 2 (simpler)

Insert Zip project into workspace and set project dependencies (your project dependent on Zip project).

How to use

The details about using this library are in the sources. The example available for download at the bottom of the page is an almost complete compression\decompression program. There are only main issues mentioned below about using this library. If you have a question about using the library and you can't find the answer here, don't hesitate to ask.

Compression and decompression

There are some functions defined for fast operations on archive; among others: AddNewFile(), ExtractFile(), DeleteFile(). You only need to call functions Open() - before and Close() - after using them.
Remember to call Close() function when you finish working with CZipArchive class.

Disk spanning

This library supports two kinds of disk spanning:
1. Disk spanning performed in the compatible way with all other main zip programs. It means that the archive can only be created on a removable device, the size of the volume is autodetected and the label is written to the disk. To use this kind of disk spanning you need to define a static callback function for changing disks and set it with SetSpanCallback() function.
2. Disk spanning performed in the internal mode, called in the sources TD span mode. This allows creating multi disk archives also on non-removable devices and with user-defined volume size. There is no need to set callback function in this mode.

This two disk spanning modes create volumes with compatible internal structure. It means that you can easily convert the volumes created in one mode to the other one by renaming the files (in TD mode each volume but last has a number as an extension).

There is a limited functions set available during work with multi disk archives. Only adding is allowed when creating an archive and only extracting when opening an existing one. Deleting files from these archives isn't allowed in any of these cases.

Class CZipArchive uses write buffer to make write operations extremly fast. You can change its size with SetAdvanced() function. While creating multi disk archive, set the size of the buffer to the maximum size of the volume  for the best performance.

Self extract support

The library automatically detects self-extracting archives. This is the simplest self-extract code :

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
 CZipArchive zip;

 // get path of executable
 TCHAR szBuff[_MAX_PATH];
 if (!::GetModuleFileName(hInstance, szBuff, _MAX_PATH))
  return -1;

 CString szDest;
 // ...
 // add the code here to get the destination directory 
 // from the user we assume it is in szDest variable

 zip.Open(szBuff, CZipArchive::openReadOnly); 
 // openReadOnly mode is necessary for self extract archives
 for (WORD i = 0; i < zip.GetNoEntries(); i++)
  zip.ExtractFile(i, szDest);

 zip.Close();
 return 0;
}

After compiling it and appending a zip archive to it (e.g. with the DOS command: copy /b SelfExtract.exe + ZipFile.zip FinalFile.exe) we have a self extracting archive.

Exceptions

The library throws the following exceptions: CMemoryException, CFileExeption and CZipException. The first two don't need an explanation. The last is thrown when some internal error occurs. Handling them may be done in the following way:

try
{
 // ...
 // some operations on Zip library
}
catch (CException* e)
{
 if (e->IsKindOf( RUNTIME_CLASS( CZipException )))
 {
  CZipException* p = (CZipException*) e;
  //... and so on 
 }
 else if (e->IsKindOf( RUNTIME_CLASS( CFileException )))
 {
  CFileException* p = (CFileException*) e;
  //... and so on 
 } 
 else
 {
  // the only possibility is a memory exception I suppose
  //... and so on 
 }
 e->Delete();
}

Example

To run the example, integrate first Zip library into it (Zip library is not included in the example, you must download it separately); you should be asked at the beginnig about the location of the Zip project, if not, use one of the integration methods descripted above. If you don't put Zip library project at the same directory level what example is, you also have to change the path pointing to ZipArchive.h in the file testzipdlgdlg.h.

Last Words

This library does not support password encryption nor decryption due to lack of documentation I have. If anyone is so kind to send me the algorithm, I will add this feature next time.

Version History

  • 08.2000
    • Bugs fixed
  • 06.2000
    • the code has been completely rewritten since the very beginning;
    • the main improvements are:
    • disk spannig archive operations allowed
    • creation of the disk spanning archives with the user-defined volume size
    • ability to modify existing archives (add, delete files)
    • modification self-extracting archives
    • write buffer used for faster disk write operations
    • one class for zip and unzip functions
    • fast adding, deleting and extracting files with a single funct call
  • 03.2000
    • international characters in filenames inside archive are now converted in a compatible way with other archivers (they are stored converted to OEM inside archive).
  • 01.2000

  • first version; it is just modified code from zip.c and unzip.c files written by Gilles Vollant and distributed with zlib library; the modifications are as follows
    • added class' wrappers
    • several bugs fixed
    • several enhancements added
    • MFC support added
    • memory leaks eliminated when write error occurred
    • automatically free used memory on destruction or exception
    • modern error notification using exceptions

Downloads

Download source - 92 Kb
Download demo project - 31 Kb


Comments

  • problem while unzipping

    Posted by codegurusiri on 08/08/2006 02:42am

    Hi , Thanks first for this very good and usefull article. I am having a problem with the test application when i try to zip the folders which has following structure such as XYX ->>> 1.cpp ->>> 1.h ->>> 2.cpp ->>> 2.h inc_path | --> 1.h --> 1.cpp i386Release _ ->>> 1.h ->> 1.cpp --> INC_PATH | ---> 1.h ->> 1.cpp Problem 1 :- when i try to zip this and unzip it (without using the appicaition in a normal unzip of pkZip) will as me that inc_path has already exists would you like to modify that or some thing Problem 2: ----(Problem that really bothers me) When i try to zip this a folder which contains the above structure and i again zip another folder of same structure to the same archive in one of the unzipped folder i386Release is completly missing. what might be the problem could you please address this .these issues are really stopping me to use this tool. Thank you , Prasanna

    Reply
  • Unresolved external

    Posted by Legacy on 01/20/2004 12:00am

    Originally posted by: Luigi

    Hi , i've compiled the lib with latest version of zlib and is ok , when i integrate it into another project they return
    me several "unresolved external" ,one for every zlib function what i forget?

    Thank'you..

    Reply
  • Active X Control

    Posted by Legacy on 03/03/2003 12:00am

    Originally posted by: RIck Justesen

    I work with several VB programmers and I am considering putting and OCX wroapper around your zip lib. Would you have any problems with that? I would be more than happy to give you the souce to the OCX.

    Thanks for the great code!

    Rick Justesen

    Reply
  • Awesome!

    Posted by Legacy on 11/20/2002 12:00am

    Originally posted by: Per Franck

    Great quality work, sir.

    I am in awe

    Reply
  • Good work!

    Posted by Legacy on 10/17/2002 12:00am

    Originally posted by: Jaws

    It works. Thank you for this great Package!

    Reply
  • Errors

    Posted by Legacy on 10/11/2002 12:00am

    Originally posted by: Jaws

    I got 33 damn errors by compiling the demo-project using the source-code from Zip.

    Reply
  • <font color=RED> Good </font>

    Posted by Legacy on 11/09/2001 12:00am

    Originally posted by: zac

    ghjn
    

    Reply
  • <font color=RED> Good </font>

    Posted by Legacy on 11/09/2001 12:00am

    Originally posted by: zac

    ghjn

    Reply
  • Updated library

    Posted by Legacy on 05/02/2001 12:00am

    Originally posted by: Tadeusz Dracz

    The newest version of the library is available at
    http:\\software.artpol.com.pl

    Reply
  • Problems with Quake and the zips generated by your classes

    Posted by Legacy on 04/17/2001 12:00am

    Originally posted by: M. Trost

    Hi,

    i'm currently developing a small tool that lets me create my own pk3 files without the use of winzip or the like.

    Here is some code i use for this:
    (assume m_aPakFiles an array of CStrings containing the filenames of the files to be archived)

    PK3.Open(pszFile, CZipArchive::create);
    for (DWORD ixFile = 0; ixFile < m_dwNumPakFiles; ixFile++)
    {
    if (F.Open(m_aPakFiles[ixFile], CFile::modeRead))
    {
    CFileHeader FileHdr;
    FileHdr.m_szFileName = szPK3Path + szFile; FileHdr.m_uMethod = Z_DEFAULT_COMPRESSION;
    if (PK3.OpenNewFil(FileHdr,Z_DEFAULT_COMPRESSION, m_aPakFiles[ixFile]))
    {
    dwRead = sizeof(buffer);
    while (dwRead == sizeof(buffer))
    {
    dwRead = F.Read(buffer, sizeof(buffer));
    PK3.WriteNewFile(buffer, dwRead);
    }
    PK3.CloseNewFile();
    F.Close();
    ::DeleteFile(m_aPakFiles[ixFile]);
    }
    }
    }
    PK3.Close();

    This works fine and winzip is able to read those files, but quake isnt. The compressed data seems to be exactly identical. However, if i compress a whole directory with winzip and select "save full path info", it adds an empty entry to the end of the zip (dir info??).

    I'd be glad if you could help me.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

  • Live Event Date: August 13, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT If you are developing applications, you'll want to join us to learn how applications are changing as a result of gesture recognition. This technology will change how you and your users interact - not simply with your devices, but with the world around you. Your devices will be able to see and hear what your users are doing. Are your applications ready for this? Join us to learn about Intel® RealSense™ Technology, including never been …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds