Create a password protected zip file using zlib and ZipEngine

If you want to create a zip file from your C/C++ application the first solution you can consider is to use the famous zlib library. This library is open source, permissive license and can be compiled in different operating systems. It allow to easily manage a zip file but, currently, doesn't have the feature for create zip file password protected. To fill this lack another developer created a small wrapper over zlib allowing to bypass this problem. Let's go to see how to use both these product.



First you need to download zlib package from here and ZipEngine from here.


Once got the sources put all the files in your project folder. There are no duplicate files name than you can keep all the files in the same path. As said before ZipEngine is a wrapper over zlib. This mean using this wrapper you don't need to use the zlib directly but sources (or precompiled library) are needed.

The first step is to create a new zip file or open an existing one with the following code:

#include "zip.h"

zipFile hZipFile;

m_ZipFile = zipOpen("myfile.zip", APPEND_STATUS_CREATE);

if(m_hZipFile == NULL)
{
     // Error here
}

The flags available for open a zip file are:

  • APPEND_STATUS_CREATE
    Create a new zip file from scratch
  • APPEND_STATUS_CREATEAFTER
    If file exist the zip will be created at the end of the file (useful if the file contain a self extractor code)
  • APPEND_STATUS_ADDINZIP
    Open an existing zip file and add the new files inside it

Now we have our zip handle we can proceed to add file inside the zip just created.Basically the procudure used by ZipEgine is to create a new item inside the zip file with the name of the file you want to insert. Once successfully create this new item you can write the content of the file connected to the item name. However, since in your example we want to protect our zip file with a password, we need also to have the CRC value of the file content we are going to insert. This mean we have to precalculate the CRC by reading all the file content with the following algorithm:

unsigned long CRC = crc32(0L, Z_NULL, 0);
const unsigned int BufferSize = 10000;
unsigned char Buffer[BufferSize];
size_t nRead; 
FILE* pFile; 

pFile = fopen("myfile.bin", "rb");

while((nRead = fread(Buffer, BufferSize, 1, pFile)) > 0)
{
     CRC = crc32(CRC, Buffer, nRead);
}

fclose(pFile);

Now we have our CRC number we can proceed to create a new item inside the zip with the name the the file we want to store inside:

zip_fileinfo zipInfo;
int Result;

zipInfo.dosDate = 0;
zipInfo.tmz_date.tm_sec = 0;
zipInfo.tmz_date.tm_min = 10;
zipInfo.tmz_date.tm_hour = 12;
zipInfo.tmz_date.tm_mday = 01;
zipInfo.tmz_date.tm_mon = 05;
zipInfo.tmz_date.tm_year = 2012;
zipInfo.internal_fa = 0;
zipInfo.external_fa = 0;

Result = zipOpenNewFileInZip3(hZipFile, 
                              "myfile.bin", 
                              &zipInfo, NULL, 0, 
                              NULL, 0, NULL,
                              Z_DEFLATED, Z_DEFAULT_COMPRESSION,
                              0,
                              15,
                              8,
                              Z_DEFAULT_STRATEGY,
                              "mypassword",
                              CRC
                              );

if(Result != ZIP_OK)
{
       // Error 
}

The function for create a new item get a lot of params. If you wan to have more info regarding the meaning of these params you can check the documentation provided with the ZipEngine package. Anyway, if you are not interested to read boring info regarding how many ways you have for "customize" a zip file and want to simply create a normal zip file, you can get the params above and live happy. The zipInfo structure must be filled with the date and time of the item you want to be saved as file info (in the example we used random date and time). Once successfully create the item you can proceed to fill them with the content of the file:

const unsigned int BufferSize = 10000;
unsigned char Buffer[BufferSize];
size_t nRead; 
FILE* pFile; 

pFile = fopen("myfile.bin", "rb");

while(Result == ZIP_OK && (nRead = fread(Buffer, BufferSize, 1, pFile)) > 0)
{
      Result = zipWriteInFileInZip(hZipFile, Buffer, nRead);
}

fclose(pFile);

Operation done. Now close the item:

zipCloseFileInZip(hZipFile);

and, if you have no other file to add, close the zip file itself:

zipClose(hZipFile, NULL);

This is a really simply tutorial. As already said, if you are interested in more info regarding the possible params to change in zip file management, you can check the documentation provided with both products. If you are not interested at all simply get these pieces of code and used them in your software. Enjoy!


Comments

Popular posts from this blog

Access GPIO from Linux user space

Android: adb push and read-only file system error

Tree in SQL database: The Nested Set Model