1 |
cycrow |
1 |
#ifndef _unzip_H
|
|
|
2 |
#define _unzip_H
|
|
|
3 |
|
|
|
4 |
// UNZIPPING functions -- for unzipping.
|
|
|
5 |
// This file is a repackaged form of extracts from the zlib code available
|
|
|
6 |
// at www.gzip.org/zlib, by Jean-Loup Gailly and Mark Adler. The original
|
|
|
7 |
// copyright notice may be found in unzip.cpp. The repackaging was done
|
|
|
8 |
// by Lucian Wischik to simplify and extend its use in Windows/C++. Also
|
|
|
9 |
// encryption and unicode filenames have been added.
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
#ifndef _zip_H
|
|
|
13 |
DECLARE_HANDLE(HZIP);
|
|
|
14 |
#endif
|
|
|
15 |
// An HZIP identifies a zip file that has been opened
|
|
|
16 |
|
|
|
17 |
typedef DWORD ZRESULT;
|
|
|
18 |
// return codes from any of the zip functions. Listed later.
|
|
|
19 |
|
|
|
20 |
typedef struct
|
|
|
21 |
{ int index; // index of this file within the zip
|
|
|
22 |
TCHAR name[MAX_PATH]; // filename within the zip
|
|
|
23 |
DWORD attr; // attributes, as in GetFileAttributes.
|
|
|
24 |
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
|
|
25 |
long comp_size; // sizes of item, compressed and uncompressed. These
|
|
|
26 |
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
|
|
27 |
} ZIPENTRY;
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
HZIP OpenZip(const TCHAR *fn, const char *password);
|
|
|
31 |
HZIP OpenZip(void *z,unsigned int len, const char *password);
|
|
|
32 |
HZIP OpenZipHandle(HANDLE h, const char *password);
|
|
|
33 |
// OpenZip - opens a zip file and returns a handle with which you can
|
|
|
34 |
// subsequently examine its contents. You can open a zip file from:
|
|
|
35 |
// from a pipe: OpenZipHandle(hpipe_read,0);
|
|
|
36 |
// from a file (by handle): OpenZipHandle(hfile,0);
|
|
|
37 |
// from a file (by name): OpenZip("c:\\test.zip","password");
|
|
|
38 |
// from a memory block: OpenZip(bufstart, buflen,0);
|
|
|
39 |
// If the file is opened through a pipe, then items may only be
|
|
|
40 |
// accessed in increasing order, and an item may only be unzipped once,
|
|
|
41 |
// although GetZipItem can be called immediately before and after unzipping
|
|
|
42 |
// it. If it's opened in any other way, then full random access is possible.
|
|
|
43 |
// Note: pipe input is not yet implemented.
|
|
|
44 |
// Note: zip passwords are ascii, not unicode.
|
|
|
45 |
// Note: for windows-ce, you cannot close the handle until after CloseZip.
|
|
|
46 |
// but for real windows, the zip makes its own copy of your handle, so you
|
|
|
47 |
// can close yours anytime.
|
|
|
48 |
|
|
|
49 |
ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
|
|
|
50 |
// GetZipItem - call this to get information about an item in the zip.
|
|
|
51 |
// If index is -1 and the file wasn't opened through a pipe,
|
|
|
52 |
// then it returns information about the whole zipfile
|
|
|
53 |
// (and in particular ze.index returns the number of index items).
|
|
|
54 |
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
55 |
// See below for notes on what happens when you unzip such an item.
|
|
|
56 |
// Note: if you are opening the zip through a pipe, then random access
|
|
|
57 |
// is not possible and GetZipItem(-1) fails and you can't discover the number
|
|
|
58 |
// of items except by calling GetZipItem on each one of them in turn,
|
|
|
59 |
// starting at 0, until eventually the call fails. Also, in the event that
|
|
|
60 |
// you are opening through a pipe and the zip was itself created into a pipe,
|
|
|
61 |
// then then comp_size and sometimes unc_size as well may not be known until
|
|
|
62 |
// after the item has been unzipped.
|
|
|
63 |
|
|
|
64 |
ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
|
|
|
65 |
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
|
|
66 |
// It returns the index of the item, and returns information about it.
|
|
|
67 |
// If nothing was found, then index is set to -1 and the function returns
|
|
|
68 |
// an error code.
|
|
|
69 |
|
|
|
70 |
ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn);
|
|
|
71 |
ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len);
|
|
|
72 |
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
|
|
|
73 |
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
|
|
74 |
// to a pipe: UnzipItemHandle(hz,i, hpipe_write);
|
|
|
75 |
// to a file (by handle): UnzipItemHandle(hz,i, hfile);
|
|
|
76 |
// to a file (by name): UnzipItem(hz,i, ze.name);
|
|
|
77 |
// to a memory block: UnzipItem(hz,i, buf,buflen);
|
|
|
78 |
// In the final case, if the buffer isn't large enough to hold it all,
|
|
|
79 |
// then the return code indicates that more is yet to come. If it was
|
|
|
80 |
// large enough, and you want to know precisely how big, GetZipItem.
|
|
|
81 |
// Note: zip files are normally stored with relative pathnames. If you
|
|
|
82 |
// unzip with ZIP_FILENAME a relative pathname then the item gets created
|
|
|
83 |
// relative to the current directory - it first ensures that all necessary
|
|
|
84 |
// subdirectories have been created. Also, the item may itself be a directory.
|
|
|
85 |
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
|
|
86 |
// If you unzip it to a handle or a memory block, then nothing gets created
|
|
|
87 |
// and it emits 0 bytes.
|
|
|
88 |
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir);
|
|
|
89 |
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
|
|
|
90 |
// (defaults to current-directory).
|
|
|
91 |
|
|
|
92 |
|
|
|
93 |
ZRESULT CloseZip(HZIP hz);
|
|
|
94 |
// CloseZip - the zip handle must be closed with this function.
|
|
|
95 |
|
|
|
96 |
unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
|
|
|
97 |
// FormatZipMessage - given an error code, formats it as a string.
|
|
|
98 |
// It returns the length of the error message. If buf/len points
|
|
|
99 |
// to a real buffer, then it also writes as much as possible into there.
|
|
|
100 |
|
|
|
101 |
|
|
|
102 |
// These are the result codes:
|
|
|
103 |
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
|
|
104 |
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
|
|
105 |
// The following come from general system stuff (e.g. files not openable)
|
|
|
106 |
#define ZR_GENMASK 0x0000FF00
|
|
|
107 |
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
|
|
108 |
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
|
|
109 |
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
|
|
110 |
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
|
|
111 |
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
|
|
112 |
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
|
|
113 |
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
|
|
114 |
#define ZR_READ 0x00000800 // a general error reading the file
|
|
|
115 |
#define ZR_PASSWORD 0x00001000 // we didn't get the right password to unzip the file
|
|
|
116 |
// The following come from mistakes on the part of the caller
|
|
|
117 |
#define ZR_CALLERMASK 0x00FF0000
|
|
|
118 |
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
|
|
119 |
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
|
|
120 |
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
|
|
121 |
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
|
|
122 |
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
|
|
123 |
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
|
|
124 |
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
|
|
125 |
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
|
|
126 |
// The following come from bugs within the zip library itself
|
|
|
127 |
#define ZR_BUGMASK 0xFF000000
|
|
|
128 |
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
|
|
129 |
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
|
|
130 |
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
|
|
131 |
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
|
|
132 |
|
|
|
133 |
|
|
|
134 |
|
|
|
135 |
|
|
|
136 |
|
|
|
137 |
// e.g.
|
|
|
138 |
//
|
|
|
139 |
// SetCurrentDirectory("c:\\docs\\stuff");
|
|
|
140 |
// HZIP hz = OpenZip("c:\\stuff.zip",0);
|
|
|
141 |
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
|
|
|
142 |
// for (int i=0; i<numitems; i++)
|
|
|
143 |
// { GetZipItem(hz,i,&ze);
|
|
|
144 |
// UnzipItem(hz,i,ze.name);
|
|
|
145 |
// }
|
|
|
146 |
// CloseZip(hz);
|
|
|
147 |
//
|
|
|
148 |
//
|
|
|
149 |
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
|
|
|
150 |
// HANDLE hglob = LoadResource(hInstance,hrsrc);
|
|
|
151 |
// void *zipbuf=LockResource(hglob);
|
|
|
152 |
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
|
|
|
153 |
// HZIP hz = OpenZip(zipbuf, ziplen, 0);
|
|
|
154 |
// - unzip to a membuffer -
|
|
|
155 |
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
|
|
|
156 |
// char *ibuf = new char[ze.unc_size];
|
|
|
157 |
// UnzipItem(hz,i, ibuf, ze.unc_size);
|
|
|
158 |
// delete[] ibuf;
|
|
|
159 |
// - unzip to a fixed membuff -
|
|
|
160 |
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
|
|
|
161 |
// char ibuf[1024]; ZRESULT zr=ZR_MORE; unsigned long totsize=0;
|
|
|
162 |
// while (zr==ZR_MORE)
|
|
|
163 |
// { zr = UnzipItem(hz,i, ibuf,1024);
|
|
|
164 |
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
|
|
|
165 |
// totsize+=bufsize;
|
|
|
166 |
// }
|
|
|
167 |
// - unzip to a pipe -
|
|
|
168 |
// HANDLE hwrite; HANDLE hthread=CreateWavReaderThread(&hwrite);
|
|
|
169 |
// int i; ZIPENTRY ze; FindZipItem(hz,"sound.wav",true,&i,&ze);
|
|
|
170 |
// UnzipItemHandle(hz,i, hwrite);
|
|
|
171 |
// CloseHandle(hwrite);
|
|
|
172 |
// WaitForSingleObject(hthread,INFINITE);
|
|
|
173 |
// CloseHandle(hwrite); CloseHandle(hthread);
|
|
|
174 |
// - finished -
|
|
|
175 |
// CloseZip(hz);
|
|
|
176 |
// // note: no need to free resources obtained through Find/Load/LockResource
|
|
|
177 |
//
|
|
|
178 |
//
|
|
|
179 |
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
|
|
|
180 |
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,0,0);
|
|
|
181 |
// CreateZipWriterThread(hwrite);
|
|
|
182 |
// HZIP hz = OpenZipHandle(hread,0);
|
|
|
183 |
// for (int i=0; ; i++)
|
|
|
184 |
// { ZIPENTRY ze;
|
|
|
185 |
// ZRESULT zr=GetZipItem(hz,i,&ze); if (zr!=ZR_OK) break; // no more
|
|
|
186 |
// UnzipItem(hz,i, ze.name);
|
|
|
187 |
// }
|
|
|
188 |
// CloseZip(hz);
|
|
|
189 |
//
|
|
|
190 |
//
|
|
|
191 |
|
|
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
|
195 |
// Now we indulge in a little skullduggery so that the code works whether
|
|
|
196 |
// the user has included just zip or both zip and unzip.
|
|
|
197 |
// Idea: if header files for both zip and unzip are present, then presumably
|
|
|
198 |
// the cpp files for zip and unzip are both present, so we will call
|
|
|
199 |
// one or the other of them based on a dynamic choice. If the header file
|
|
|
200 |
// for only one is present, then we will bind to that particular one.
|
|
|
201 |
ZRESULT CloseZipU(HZIP hz);
|
|
|
202 |
unsigned int FormatZipMessageU(ZRESULT code, TCHAR *buf,unsigned int len);
|
|
|
203 |
bool IsZipHandleU(HZIP hz);
|
|
|
204 |
#ifdef _zip_H
|
|
|
205 |
#undef CloseZip
|
|
|
206 |
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
|
|
|
207 |
#else
|
|
|
208 |
#define CloseZip CloseZipU
|
|
|
209 |
#define FormatZipMessage FormatZipMessageU
|
|
|
210 |
#endif
|
|
|
211 |
|
|
|
212 |
|
|
|
213 |
|
|
|
214 |
#endif // _unzip_H
|