|
if you define #define _USE_32BIT_TIME_T you wont be able to target 64 bit platforms.
Better solution, substitute all references of time_t by __time32_t, and the call gmtime by _gmtime32. This works on 32/64 bits platforms.
FILETIME timet2filetime(time_t timer)
{
struct tm *tm = _gmtime32(&timer);
SYSTEMTIME st;
st.wYear = (WORD)(tm->tm_year+1900);
st.wMonth = (WORD)(tm->tm_mon+1);
st.wDay = (WORD)(tm->tm_mday);
st.wHour = (WORD)(tm->tm_hour);
st.wMinute = (WORD)(tm->tm_min);
st.wSecond = (WORD)(tm->tm_sec);
st.wMilliseconds=0;
FILETIME ft;
SystemTimeToFileTime(&st,&ft);
return ft;
}
/////////////////////////////////
FILETIME timet2filetime(__time32_t timer)
{
struct tm *tm = _gmtime32(&timer);
SYSTEMTIME st;
st.wYear = (WORD)(tm->tm_year+1900);
st.wMonth = (WORD)(tm->tm_mon+1);
st.wDay = (WORD)(tm->tm_mday);
st.wHour = (WORD)(tm->tm_hour);
st.wMinute = (WORD)(tm->tm_min);
st.wSecond = (WORD)(tm->tm_sec);
st.wMilliseconds=0;
FILETIME ft;
SystemTimeToFileTime(&st,&ft);
return ft;
}KZ
|
|
|
|
|
I'm trying to determine why the files extracted are always extracted read only. If I open up the zip file with another zip program and get the properties, they are not hidden and not read only. But when XUnZip extracts the files it makes them read only.
I have traced this down to the ze.attr field which is 161 for these files. 161 in hex is A1, which are the flags Normal, Archive and Read_Only.
Why is this happening?
-- modified at 8:20 Thursday 27th April, 2006
Found the problem. in XUnzip.cpp
unsigned long a = ufi.external_fa;
bool uisdir = (a&0x40000000)!=0;
//bool uwriteable= (a&0x08000000)!=0;
bool uwriteable= (a&0x00800000)!=0; // ***hd***
//bool ureadable= (a&0x01000000)!=0;
//bool uexecutable=(a&0x00400000)!=0;
bool wreadonly= (a&0x00000001)!=0;
bool whidden= (a&0x00000002)!=0;
bool wsystem= (a&0x00000004)!=0;
bool wisdir= (a&0x00000010)!=0;
bool warchive= (a&0x00000020)!=0;
ze->attr=FILE_ATTRIBUTE_NORMAL;
if (uisdir || wisdir)
ze->attr |= FILE_ATTRIBUTE_DIRECTORY;
if (warchive)
ze->attr|=FILE_ATTRIBUTE_ARCHIVE;
if (whidden)
ze->attr|=FILE_ATTRIBUTE_HIDDEN;
if (!uwriteable||wreadonly)
ze->attr|=FILE_ATTRIBUTE_READONLY;
if (wsystem)
ze->attr|=FILE_ATTRIBUTE_SYSTEM;
for this particular file, the ufi.external_fa is 32. This is hex 00000020 so the only attribute that should be set is the FILE_ATTRIBUTE_ARCHIVE. But, the FILE_ATTRIBUTE_READONLY is being set if either the windows readonly flag is set OR the unix unwritable flag. But it appears the zip utility I am using to create this zip file does not set the unix bytes.
I can kludge this easily to work for me, since I'm only using it on windows machines, by simply changing it to:
if (wreadonly)
ze->attr|=FILE_ATTRIBUTE_READONLY;
Actually, this is a bug with the program creating the zip file. Realistically, PUnzip.cpp should deal with this in some graceful manner.
|
|
|
|
|
Recently I got several archives where my program crashed with an access violation in GetZipEntry(handle, -1, &zipEntry). A little debugging showed that unzOpenInternal returns NULL, but TUnzip::Open still returns ZR_OK.
I changed the last line of TUnzip::Open to
return uf ? ZR_OK : ZR_CORRUPT;
This fix works for me, but I didn't spent too much time in analyzing the code, so perhaps someone with more time (and a better understanding of that code) will check that fix and perhaps find a better solution.
Regards
Heinz
|
|
|
|
|
Heinz,
I independently found the same problem and basically the same solution. I didn't analyze the code either.
Regards
Art
|
|
|
|
|
I had the same problem.
I traced it to using a gzipped file from linux gzip.
xunzip did not find file inforamtions.
The file informations in a .gz file seem to be at the beginning of the file,
the ones of a .zip file at the end.
I would be very interested in having a solution to getting xunzip to decompress
a file which was compressed with gzip on a linux system.
Does anyone have an idea?
|
|
|
|
|
I compiled under visual studio 2005 and created a zip archive. When I call FindZipItem on the archive the program crashes in ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) with an assertion error.
I think the code is failing because the only data in the extra header only contains "UT" only. The code then fails on the timet2filetime conversions.
Any ideas?
Ron
....
while (epos+4<extralen)
{="" char="" etype[3];="" etype[0]="extra[epos+0];" etype[1]="extra[epos+1];" etype[2]="0;
" int="" size="extra[epos+2];
" if="" (strcmp(etype,"ut")!="0)" {epos="" +="4+size;" continue;}
="" flags="extra[epos+4];
" bool="" hasmtime="(flags&1)!=0;
" hasatime="(flags&2)!=0;
" hasctime="(flags&4)!=0;
" epos+="5;
" (hasmtime)
="" time_t="" mtime="*(time_t*)(extra+epos);" ze-="">mtime = timet2filetime(mtime);
}
if (hasatime)
{ time_t atime = *(time_t*)(extra+epos); epos+=4;
ze->atime = timet2filetime(atime);
}
if (hasctime)
{ time_t ctime = *(time_t*)(extra+epos);
ze->ctime = timet2filetime(ctime);
}
break;
}
|
|
|
|
|
the code is failing because XUnzip assumes time_t is a 32bit integer, however by default in VS2005 time_t is a 64bit integer, for a simple fix you can set _USE_32BIT_TIME_T as a preprocessor definition in your project settings, this will force time_t to be 32bit
|
|
|
|
|
void pointers are considered a no no in c++ code, but rather than complain about it, I'm thinking I might do something about it.
I would like to go through all the code and get rid of the void pointers by overloading functions, etc...
Now, I wouldn't want to do this if it means that I would only be doing it for myself, as it will probably be a little bit of work.
Do you, Hans Dietrich, mind if I do this, and then give you back the code?
|
|
|
|
|
No, I don't mind. I would ask that you test all of the functions that are affected by your changes.
|
|
|
|
|
The original (PK)ZIP format does not support Unicode filenames, but I saw that you mentioned porting Create() to Unicode and was wondering if you changed any of the internal structure to accomodate unicode filenames.
I did some testing on a japanese windows xp platform with your demo project. I renamed some of the files in the demo to have german umlaut characters in them - they were automagically replaced by their non-umlaut equivalent. However, using japanese characters worked like a charm, so I am thinking that ANSI filenames are used. Am I terribly mistaken?
Also, if it is not trivial to implement ZIP archives with Unicode filenames, do you know of any other freely available archive/compression library that I could use? I'd appreciate any input.
Thanks!
|
|
|
|
|
I have these lines in my code :
#include"XUnzip.cpp"
using namespace std;
void phase1(){
HZIP hz = OpenZip("c:\test.zip",0, ZIP_FILENAME);
ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
for (int i=0; i
|
|
|
|
|
Wow, that's strange it gives you that error becuase it doesn't give me that error.
But it's fairly simple to fix. Just make your string a non const pointer.
char FileName[_MAX_PATH];
strcpy( FileName, "C:\\test.zip" };
HZIP hz = OpenZip(FileName, 0, ZIP_FILENAME);
Incidently, make sure you use \\ instead of \ because \t is a tab.
|
|
|
|
|
Thanks for your answer.
My problem was that I used "\" instead of the "\\" !!
JJ
|
|
|
|
|
I tried to add new files to zip that was already created with this class. I was able to open the zip but was unable to add anything to it. I also tried adding edited versions of files already in the zip and had the same problem. My only alternative (so far) is to pull all the files out of the zip, add or edit the files and then zip them into a new zip. Anybody else have a better way?
|
|
|
|
|
in function TZip::ideflate()
You allocate the TState object in heap instead of stack, in order to avoid stack overflow. But the TState object only allocate once and its state will not be cleared in second time ideflate() is called.
So, if there are big files added into zip, and the big file was not the first one in zip, error will occur...it is terrible.
|
|
|
|
|
The destination of a file/directory can be specified in UnzipItem, but directories are always extracted to the current directory regardless of destination.
|
|
|
|
|
|
The ugly code makes me a bit sad. Considered rewriting it to be a bit more object oriented? Using void* when it's not nessecary just sucks.
Apart from that, I like it.
|
|
|
|
|
When you try to unzip files from a .ZIP with subdirs the unzipping returns an error 0x200 NO FILE. I have found a bug in Xunzip.cpp here:
void EnsureDirectory(const TCHAR *rootdir, const TCHAR *dir)
....
if (lastslash!=dir)
{
TCHAR tmp[MAX_PATH];
_tcsncpy(tmp, dir, lastslash-dir);
tmp[lastslash-dir] = _T('\0');
EnsureDirectory(rootdir,tmp);
name++;
}
TCHAR cd[MAX_PATH];
_tcscpy(cd,rootdir);
// 20-06-2005 COSMOS
// Here was: _tcscat(cd,name); Which isn't correct
// We have to create the last level directory like this:
_tcscat(cd,dir);
CreateDirectory(cd,NULL);
....
Hope this helps.
|
|
|
|
|
Who know how to delete a file from zip archive with these codes, or how to replace an existing file?
thanks .:->
|
|
|
|
|
hi!
i have created two zip files of same test.png file. when i check both zipped files with windiff.exe, they were different. but files inside the zip are same. whereas i did same with WinRAR and created two zip files of same test.png file. when i compared them with windiff.exe they were identical. could u plz tell me why this happens.
Thanks in advance.
Ahmad Jalil Qarshi
|
|
|
|
|
Hi.
I have the need to open an existing zip file, and add files to it...
Is this possible, since OpenZip(..) then ZipAdd(..) fails.
J
|
|
|
|
|
OK -- My bad!
Needed to include windows.h before the xzip.h file(s)
#include <windows.h>
#include "XZip.h"
#include "XUnzip.h"
Soz,
Joe
|
|
|
|
|
Hi Hans,
Good work. We use your class in our software and it works good. I found however that the files inside the ZIP are stamped with UTC time instead of local time.
GetFileInformationByHandle returns UTC times for a file, so they must be converted to local time before writing to Zip file. BTW, contrary to MSDN, my tests showed that GetFileInformationByHandle returns file time in UTC for both FAT and NTFS file system.
So here's a little code that needs to be added to XZip in order to convert file time from UTC to local time. Add it in GetFileInfo function, after GetFileInformationByHandle call. (Line 2189 in XZip.cpp of May 7th, 2003 release).
Thanks.
Damir Valiulin
BY_HANDLE_FILE_INFORMATION bhi;
BOOL res=GetFileInformationByHandle(hf,&bhi);
if (!res)
return ZR_NOFILE;
{
SYSTEMTIME stUTC, stLocal;
GetSystemTime(&stUTC);
GetLocalTime(&stLocal);
FILETIME ftUTC, ftLocal;
SystemTimeToFileTime(&stUTC, &ftUTC);
SystemTimeToFileTime(&stLocal, &ftLocal);
LONG64 uiUTC, uiLocal;
memcpy (&uiUTC, &ftUTC, min(sizeof(LONG64), sizeof(FILETIME)));
memcpy (&uiLocal, &ftLocal, min(sizeof(LONG64), sizeof(FILETIME)));
LONG64 uiTimeDiff = uiUTC - uiLocal;
FILETIME* pFileTimes[3] = { &bhi.ftLastWriteTime, &bhi.ftLastAccessTime, &bhi.ftCreationTime };
for (int i=0; i<3; i++){
LONG64 uiUTC_file;
memcpy (&uiUTC_file, pFileTimes[i], min(sizeof(LONG64), sizeof(FILETIME)));
LONG64 uiLocal_file = uiUTC_file - uiTimeDiff;
memcpy (pFileTimes[i], &uiLocal_file, min(sizeof(LONG64), sizeof(FILETIME)));
}
}
|
|
|
|
|
This is a very useful module! However:
When I add 50,000 small textfiles to a new zip-file, the resulting zip is about 25MB and contains 50,000 files, everything is fine.
When I add 60,000 small textfiles, the resulting zip file is about 8MB contains only 8,000 files, and no errors where reported from the ZipAdd function...
BR/Karl
|
|
|
|
|