This is a console example of how to read data from z zip storage using zipfldr.dll.// ZIP extraction using zipfldr.dll from Windows XP
// compile for console
#include "shlwapi.inc"
#include "shlobj.inc"
#include "stdio.inc"
#include "stierr.inc" // just for STIERR_OBJECTNOTFOUND
#define ZIP_PATH "D:\\download\\myzip.zip"
//#define UNPACK_TO "D:\\download\\myzip"
sub ExtractFiles(IStorage *storage, string *pszTargetDir, IMalloc *memory)
{
if (!memory)
{
if (CoGetMalloc(1, &memory)) return;
}
else
{
memory->AddRef();
}
if (!CreateDirectory(pszTargetDir, NULL))
{
DWORD dwError = GetLastError();
if (dwError != ERROR_ALREADY_EXISTS)
{
printf("Failed (%d) to create directory %s\n", dwError, pszTargetDir);
return;
}
}
IEnumSTATSTG *enumerator;
if (!storage->EnumElements(0,0,0,&enumerator))
{
ULONG celtFetched;
STATSTG stat;
while (!enumerator->Next(1, &stat, &celtFetched) && celtFetched)
{
if (stat.pwcsName)
{
string *pszPath = new(byte, lstrlen(pszTargetDir) + wcslen(stat.pwcsName) + 2);
if (pszPath)
{
wsprintf(pszPath, "%s\\%S", pszTargetDir, stat.pwcsName);
if (stat.type == STGTY_STORAGE) // directory
{
IStorage *subfolder;
if (!storage->OpenStorage(stat.pwcsName, 0, STGM_READ, 0, 0, &subfolder))
{
ExtractFiles(subfolder, pszPath, memory);
subfolder->Release();
}
}
else if (stat.type == STGTY_STREAM) // file
{
printf("processing %s ", pszPath);
if (stat.cbSize.QuadPart < 1024q)
printf("(%d bytes)\n", stat.cbSize.LowPart)
else if (stat.cbSize.QuadPart < 1048576q)
printf("(%.2f KB)\n", stat.cbSize.LowPart/1024.0)
else
printf("(%.2f MB)\n", stat.cbSize.QuadPart/1048576.0);
IStream *stream;
if (!storage->OpenStream(stat.pwcsName, 0, STGM_READ, 0, &stream))
{
IStream *file;
// check if the file exists
dwError = SHCreateStreamOnFile(pszPath, STGM_FAILIFTHERE, &file);
if (dwError == STG_E_FILEALREADYEXISTS)
{
BOOL fOverwrite = FALSE;
if (fOverwrite)
{
dwError = SHCreateStreamOnFile(pszPath, STGM_WRITE | STGM_CREATE, &file);
}
}
else if (dwError == STIERR_OBJECTNOTFOUND)
{
dwError = SHCreateStreamOnFile(pszPath, STGM_WRITE | STGM_CREATE, &file);
}
if (dwError && (dwError != STG_E_FILEALREADYEXISTS))
{
printf("Failed to create '%s' (%x)\n", pszPath, dwError);
}
else if (!dwError)
{
ULARGE_INTEGER cbSize;
dwError = stream->CopyTo(file, stat.cbSize, NULL, &cbSize);
file->Release();
//if (dwError || (stat.cbSize.QuadPart != cbSize.QuadPart))
//{
// todo
//}
}
stream->Release();
}
}
delete pszPath;
}
memory->Free(stat.pwcsName);
}
}
enumerator->Release();
}
memory->Release();
}
sub OpenZip(string *pszZip, string *pszTargetDir)
{
dstring szDir[MAX_PATH];
if (!pszTargetDir)
{
byte *pName = PathFindFileName(pszZip);
if (!pName) return;
pName--;
int size = pName - pszZip;
sprintf(szDir, "%.*s", size, pszZip);
pszTargetDir = szDir;
}
ITEMIDLIST *pidl = ILCreateFromPath(pszZip);
if (pidl)
{
IShellFolder *psfParent;
ITEMIDLIST *pidlChild;
if (!SHBindToParent(pidl, _IID_IShellFolder, &psfParent, &pidlChild))
{
// open the virtual zip root directory as a storage
IStorage *storage;
if (!psfParent->BindToObject(pidlChild, NULL, _IID_IStorage, &storage))
{
ExtractFiles(storage, pszTargetDir, NULL);
storage->Release();
}
psfParent->Release();
}
ILFree(pidl);
}
}
sub main()
{
CoInitialize(0);
#ifdef UNPACK_TO
OpenZip(ZIP_PATH, UNPACK_TO);
#else
OpenZip(ZIP_PATH, NULL);
#endif
CoUninitialize();
return 0;
}
EDIT: added file overwrite check, but didn't checked if it is working without extracted files :)
Sapero,
I get errors trying to compile and link the program.
This is what I get:
Compiling...
Zip_read.src
No Errors
Linking...
Aurora Linker v1.0 Copyright ÂÃ,©2005,2006 Ionic Wind Software
Unresolved external __imp_ILCreateFromPathA
Error: Unresolved extern __imp_ILCreateFromPathA
Error: Unresolved extern __imp_ILFree
Error(s) in linking C:\Program Files\Aurora\examples\sapero\Zip_read.exe
I am using your headers of June 2009.
Any ideas?
Haim
Haim,
just re-create import library for shell32.dll overwriting the existing. I think the "original" shell32.lib comes from OS older than Windows 2000.
Sapero,
That did it.
Thank you for the program and for the tip on Shell32.
Haim
Sapero,
Almost ashamed to ask.
Do you have an EB version of this?
Do you know if Vista machines have the zipfldr.dll ?
Larry
Hi Larry, click here for Emergence version (http://www.ionicwind.com/forums/index.php/topic,3444.0.html)
I have checked the zipfldr.dll, it is available on Windows7, thus on Vista should be no problem.
Thanks, Sapero.
Larry