|
kanetheterrible1 wrote:
lasterrorZ = zip->Add(szDest, src, len, flags);
You must have gone to some work to come up with the Add() function, since it isn't in Zip.h!
The correct function - as shown in the demo - is ZipAdd().
Example:
TCHAR * cp = _tcsrchr(lpszSrcFile, _T('\\'));
if (cp == NULL)
cp = (TCHAR *) lpszSrcFile;
else
cp++;
HZIP hz = CreateZip((void *)lpszZipArchive, 0, ZIP_FILENAME);
if (hz)
{
ZRESULT zr = ZipAdd(hz, cp, (void *)lpszSrcFile, 0, ZIP_FILENAME);
CloseZip(hz);
if (zr == ZR_OK)
{
...
|
|
|
|
|
hi !
i know...i used CreateZip () and ZipAdd( ) only. In fact i used the exact code u created in the function Zip( ). I saw thru messageboxes that CreateZip() is working fine, but say , i put a couple of checks , like :
HZIP hz = CreateZip((void *)lpszZipArchive, 0, ZIP_FILENAME); <br />
if (hz) { <br />
MessageBox("I am here");<br />
ZRESULT zr = ZipAdd(hz, cp, (void *)lpszSrcFile, 0, ZIP_FILENAME); <br />
MessageBox("I passed ");<br />
CloseZip(hz);
Then in the output , the messagebox "i am here " is gettign displayed, and then the application is crashing.
Then i went to explore why CreateZip( ) crashed , and then when i went to the function i saw that in the line i mentioned before it is crashing, that is this line : lasterrorZ = zip->Add(szDest, src, len, flags);
now here , zip itself is a member of class TZIP , and i went to look at the function Add() of the class, but didn't understand much of it..actually i am newbie when it comes to zipping/unzipping programatically..so might be sounding a bit stupid here ..
By the way , i am using the class in a COM .dll ..it shouldn't make any difference ..?
Thanks
Regards
Kane
"Some guys hack just to get themselves a girlfriend.What a pathetic reason huh ?"
|
|
|
|
|
kanetheterrible1 wrote:
i am using the class in a COM .dll ..it shouldn't make any difference ..?
I don't know, I haven't tried that. I suggest you create a small test MFC app to test your code. If that works, then it must be the COM dll.
|
|
|
|
|
hi !
It was just as suspected.Xzip is working for MFC apps but failing for the COM .dll .However i fail to see why because a)I am using MFC inside the COM .dll and b) Xzip is supposed to be compaitble with any win32 programs.
Now while fishing through i code , i found out the exact place where it goes wrong :
The ZipAdd( ) is actually calling the function Add( ) of class TZIP , which is trying to add the deflated/stored data in the zip file ( as specified in XZip.cpp, line no 2687 ...the snippet is as follows
ZRESULT writeres=ZR_OK;<br />
if (!isdir && method==DEFLATE) <br />
writeres=ideflate(&zfi);<br />
else if (!isdir && method==STORE) <br />
writeres=istore();<br />
else if (isdir) <br />
csize=0;<br />
iclose();<br />
writ += csize;<br />
if (oerr!=ZR_OK) <br />
return oerr;<br />
if (writeres!=ZR_OK) <br />
return ZR_WRITE;<br /> , now here , the program is crashing excatly on the line writeres=ideflate(&zfi); .Checking with MessageBoxes show that when the function ideflate() is being called , the program is crashing instanty * without * the control being transferred to the ideflate( ) function.The debugger is showing a stack overflow error in the statement.
Now it's working fine in MFC , but there is no real reason why it shouldn't work for a COM which uses MFC. Additionally i noted that even though as we can see we already completed writing the header , and the program crashed only while adding the data , the zip file that is being created , is showing up as a corrupt zip file.
Can you give me any hints as to what can possibly crash the app particularly on that line ?Or what kind of exception handling can be possibly done ?Winzip also uses zip through a com .dll , and they have no problem..so it's either i made a mistake in my com programming , or something is making XZip uncompatible to COM. If you have any idea as to what possibly can make ideflate( ) crash , i could have a closer look.
Thanks again for your time
Regards
Kane
"Some guys hack just to get themselves a girlfriend.What a pathetic reason , huh ? "
|
|
|
|
|
Hi,
I too encountered the problem with a stack overflow when used in COM.
A possible solution (seems to work for me) is to create the TState object 'state' on the heap instead of the stack. Replace the 'ideflate(TZipFileInfo *zfi)' function with the following:
ZRESULT TZip::ideflate(TZipFileInfo *zfi)
{
TState* state=new TState();
(*state).readfunc=sread; (*state).flush_outbuf=sflush;
(*state).param=this; (*state).level=8; (*state).seekable=iseekable; (*state).err=NULL;
// the following line will make ct_init realise it has to perform the init
(*state).ts.static_dtree[0].dl.len = 0;
// It would be nicer if I could figure out precisely which data had to
// be initted each time, and which didn't, but that's kind of difficult.
// Maybe for the next version...
//
bi_init(*state,buf, sizeof(buf), TRUE); // it used to be just 1024-size, not 16384 as here
ct_init(*state,&zfi->att);
lm_init(*state,(*state).level, &zfi->flg);
ulg sz = deflate(*state);
csize=sz;
if ((*state).err!=NULL)
{
delete state;
return ZR_FLATE;
}
else
{
delete state;
return ZR_OK;
}
}
Best regards,
Michael
|
|
|
|
|
USE THIS INPLACE OF THE CURRENT IDEFLATE (beginner contribution unknown to errors, checks out ok for me)
ZRESULT TZip::ideflate(TZipFileInfo *zfi)
{
TState *state = new TState();
state->readfunc=sread; state->flush_outbuf=sflush;
state->param=this; state->level=8; state->seekable=iseekable; state->err=NULL;
// the following line will make ct_init realise it has to perform the init
state->ts.static_dtree[0].dl.len = 0;
// It would be nicer if I could figure out precisely which data had to
// be initted each time, and which didn't, but that's kind of difficult.
// Maybe for the next version...
//
bi_init(*state,buf, sizeof(buf), TRUE); // it used to be just 1024-size, not 16384 as here
ct_init(*state,&zfi->att);
lm_init(*state,state->level, &zfi->flg);
ulg sz = deflate(*state);
csize=sz;
if (state->err!=NULL)
{
delete [] state;
return ZR_FLATE;
}
else
{
delete [] state;
return ZR_OK;
}
//return 0;
}
|
|
|
|
|
Hi,
I can't add a file in an existing archive ( not created with CreateZip(...) ).
In XZip.cpp, function OpenZip(...) :
"
TZipHandleData *han = new TZipHandleData;
han->flag = 1;
"
In XZip.cpp, fonction ZipAdd(...) :
"
TZipHandleData *han = (TZipHandleData*)hz;
if (han->flag != 2)
{
lasterrorZ = ZR_ZMODE;
return ZR_ZMODE;
}
"
The flag has the value 2 only when it is created with CreateZip(...).
Thanks.
|
|
|
|
|
how can i use it in eVC????
Thanks ahead
|
|
|
|
|
I tried writing a simple program that would open a zip file and extract all of its files. I started by including XUnzip.h and I got a complaint from Visual C++ 6.0: "error C2065: 'HZIP' : undeclared identifier". I disabled precompiled headers, but I don't understand what's going on.
Help anyone?
|
|
|
|
|
I solved it by including windows.h and remember to do rebuild all when you changed a .h file, or you will get the same error over and over.
|
|
|
|
|
Hello,
I am using your code and it works great when I had files into my zip file.
But now I would like to add a folder and am using
ZRESULT zr = ZipAdd(hZipFile, _T("c:\\TestDir"), 0, 0, ZIP_FOLDER);
It returns zero but the resulting zip file is empty. I traced a bit of the code and it seems the destination becomes "c" only (converted to a char) but even fixing this didn't seem to help.
Any suggestions?
|
|
|
|
|
ZIP_FOLDER adds a folder in the zip. You could use this function
BOOL AddFolderContent(HZIP hZip, CString Path, BOOL Recurse, CString SubDir="")
{
_finddata_t fds ;
long Finder ;
CString Mask,FullPath, File, FileInZip ;
if (SubDir.GetLength())
{
ZipAdd(hZip,(LPCSTR)SubDir,0,0,ZIP_FOLDER);
}
Mask.Format("%s*.*", Path);
fds.attrib = _A_NORMAL ;
Finder = _findfirst(Mask, &fds) ;
if (Finder != -1)
{
while (1)
{
try
{
File = fds.name ;
if (File.CompareNoCase("..") && File.CompareNoCase("."))
{
if ( (fds.attrib & _A_SUBDIR)==0 && (fds.attrib & _A_SYSTEM)==0 )
{
FullPath.Format("%s%s", Path, fds.name);
if (SubDir.GetLength())
{
FileInZip.Format("%s\\%s", SubDir, fds.name);
}
else
{
FileInZip = fds.name ;
}
cout << "Adding file " << fds.name << endl ;
if (ZipAdd(hZip, (LPCSTR)FileInZip, (LPVOID)(LPCSTR)FullPath, 0,ZIP_FILENAME)!=ZR_OK) return FALSE ;
}
else
{
if (fds.attrib & _A_SUBDIR && Recurse)
{
CString TempSubDir ;
CString TempPath ;
if (SubDir.GetLength())
{
TempSubDir.Format("%s\\%s", SubDir, fds.name);
}
else
{
TempSubDir = fds.name;
}
TempPath.Format("%s%s\\", Path, fds.name);
if (AddFolderContent(hZip, TempPath, TRUE, TempSubDir)== FALSE)
{
return FALSE ;
}
}
}
}
}catch(...)
{
}
if (_findnext(Finder, &fds)==-1) break;
}
}
_findclose( Finder );
return TRUE;
}
|
|
|
|
|
Same function but not using MFC
Performance of this algo : 1GB of txt files (unicode) takes 7'35 min to zip. Output file is 53 MB
Performance of WinRAR : 1GB of txt files (unicode) takes 6'25 min to zip. Output file is 35 MB
/**
* Added by Renaud Deysine. This fonctionnality was missing in API
* @brief Add a folder to the zip file. Empty folders will also be added.
* This method add recursively the content of a directory
* @param AbsolutePath like "C:\\Windows" or "C:\\Windows\"
* @param DirToAdd like "System32"
*
*/
BOOL AddFolderContent(HZIP hZip, TCHAR* AbsolutePath, TCHAR* DirToAdd)
{
HANDLE hFind; // file handle
WIN32_FIND_DATA FindFileData;
TCHAR PathToSearchInto [MAX_PATH] = {0};
if (NULL != DirToAdd)
{
ZipAdd(hZip, DirToAdd, 0, 0, ZIP_FOLDER);
}
// Construct the path to search into "C:\\Windows\\System32\\*"
_tcscpy(PathToSearchInto, AbsolutePath);
_tcscat(PathToSearchInto, _T("\\"));
_tcscat(PathToSearchInto, DirToAdd);
_tcscat(PathToSearchInto, _T("\\*"));
hFind = FindFirstFile(PathToSearchInto,&FindFileData); // find the first file
if(hFind == INVALID_HANDLE_VALUE)
{
return FALSE;
}
bool bSearch = true;
while(bSearch) // until we finds an entry
{
if(FindNextFile(hFind,&FindFileData))
{
// Don't care about . and ..
if(IsDots(FindFileData.cFileName))
continue;
// We have found a directory
if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
TCHAR RelativePathNewDirFound[MAX_PATH] = {0};
_tcscat(RelativePathNewDirFound, DirToAdd);
_tcscat(RelativePathNewDirFound, _T("\\"));
_tcscat(RelativePathNewDirFound, FindFileData.cFileName);
// Recursive call with the new directory found
if (AddFolderContent(hZip, AbsolutePath, RelativePathNewDirFound)== FALSE)
{
return FALSE ;
}
}
// We have found a file
else
{
// Add the found file to the zip file
TCHAR RelativePathNewFileFound[MAX_PATH] = {0};
_tcscpy(RelativePathNewFileFound, DirToAdd);
_tcscat(RelativePathNewFileFound, _T("\\"));
_tcscat(RelativePathNewFileFound, FindFileData.cFileName);
if (ZipAdd(hZip, RelativePathNewFileFound, RelativePathNewFileFound, 0, ZIP_FILENAME) != ZR_OK)
{
return FALSE;
}
}
}//FindNextFile
else
{
if(GetLastError() == ERROR_NO_MORE_FILES) // no more files there
bSearch = false;
else {
// some error occured, close the handle and return FALSE
FindClose(hFind);
return FALSE;
}
}
}//while
FindClose(hFind); // closing file handle
return true;
}
Renaud Deysine
|
|
|
|
|
Hi All,
I want to know how can i do compression on the fly? I need to compress data before sending them on the wire between 2 computers and gets uncompressed upon reaching the other computer. Any suggestions, alorithum or functions that i can use? Also is there any way to change XZip/UnZip in .Net(C#)?
I dont want to use the J# functions
thanks
a lot
|
|
|
|
|
A method would be build the stream into packets which can then be compressed individually, before being sent. Any compression algorithm would do, eg. Zip Deflate. It would be best to try different algorithms, and see which one gives you the best compression. It's also worth trying different packet sizes.
It's also worth generating a hash of the packet, to be appended to the packet when sent, enabling
the receiving end to determine if transmission error occurred.
|
|
|
|
|
Hi All,
I want to know how can i do compression on the fly? I need to compress data before sending them on the wire between 2 computers and gets uncompressed upon reaching the other computer. Any suggestions, alorithum or functions that i can use? Also is there any way to change XZip/UnZip in .Net(C#)?
I dont want to use the J# functions
thanks
a lot
|
|
|
|
|
Hi,
Does anyone know where I can find sample code for archiving in the cab format?
Thanks!
|
|
|
|
|
Hi,
I want to add streaming unzip feature to my app i.e. I receive the contents of the zip file as a stream of data, and need to unzip the incoming data without waiting for the complete file to arrive. Is there an easy way to reuse the code in XUnzip to achieve this?
Thanks,
Roshan
|
|
|
|
|
Did anybody used it in UNICODE build ?
It cribs a lot for all function definitions passing TCHAR and all..
Please let me know..
I think will have to port it for UNICODE then
thanks and regards,
Vikram
|
|
|
|
|
Great code, after speindgin two days trying to get unzi32.dll and .lib to work with my c++ project, you code worked in an instant.
I am having a problem unzippin a zip file which contains directories. It unzips the files fine but all dirs are put in an upper level dir and the files within the dirs are not there.
exp:
zip file contents
foo.c
foo.h
temp\foo.h
if foo.zip is in c:\data and its the working dir then here is what I get
c:\data\foo.c
c:\data\foo.h
c:\temp
Any ideas?
Thanks
Vince
|
|
|
|
|
Hi Vince,
I had the same problem, but tracked it down to this:
in XUnzip.cpp, line 4010 reads:
_tcscat(cd,name);
while it should read:
_tcscat(cd,dir);
I made that change in my XUnzip.cpp, and now it works fine.
Hope it works for you also
Craig
|
|
|
|
|
Can I delete a file from the zip?
|
|
|
|
|
I try to add a new file in a existing zip with the following commands:
hz = OpenZip(pszArchive2, 0, ZIP_FILENAME);
if(ZipAdd(hz, pszName3, pszName3, 0, ZIP_FILENAME) == ZR_OK)
{
m_List.Printf(CXListBox::Red, CXListBox::White, 0,
_T(" Am adaugat in arhiva"));
}
else
{
m_List.Printf(CXListBox::Red, CXListBox::White, 0,
_T(" Nu am adaugat in arhiva"));
}
CloseZip(hz);
but this things doesn.t work.
How can I add a new file in a existing zip????
|
|
|
|
|
In TUnzip::Get the evaluation of ufi.external_fa returns invalid results, if the upper half (unix attributes) is not set at all for some reason (=0x0000xxxx). In this case uwritable gets false and later FILE_ATTRIBUTE_READONLY is set.
I think, if the unix attributes are not set at all, you should not evaluate them. Obviously e.g. Winzip or the Windows-XP-Buildt-In-Zip are able to handle missing unix attributes correcltly.
By the way, I have created the zip file with the missing unix attributes with the so called internal zip of "Total Comander 5.51".
Thomas Haase
|
|
|
|
|
Is it possible to create multiple archives. (e.g. 1.44mb)
Thanks,
Marco
|
|
|
|
|