ReactOS 0.4.16-dev-125-g798ea90
vfdzip.c
Go to the documentation of this file.
1/*
2 vfdzip.c
3
4 Virtual Floppy Drive for Windows
5 Driver control library
6 Zip compressed floppy image handling
7
8 Copyright (C) 2003-2005 Ken Kato
9*/
10
11#ifdef __cplusplus
12#pragma message(__FILE__": Compiled as C++ for testing purpose.")
13#endif // __cplusplus
14
15#define WIN32_LEAN_AND_MEAN
16#include <windows.h>
17
18#include "vfdtypes.h"
19#include "vfdio.h"
20#include "vfdlib.h"
21
22#ifndef __REACTOS__
23#define ZLIB_WINAPI
24#else
25#define Z_SOLO
26#define ZLIB_INTERNAL
27#endif
28#include "zlib.h"
29
30#ifdef VFD_NO_ZLIB
31#pragma message("ZIP image support is disabled.")
32
35 ULONG *pSize)
36{
40}
41
45 PULONG pLength)
46{
51}
52
53#else // VFD_NO_ZLIB
54
55#ifdef _DEBUG
56static const char *ZLIB_ERROR(int err)
57{
58 switch (err) {
59 case Z_OK : return "Z_OK";
60 case Z_STREAM_END : return "Z_STREAM_END";
61 case Z_NEED_DICT : return "Z_NEED_DICT";
62 case Z_ERRNO : return "Z_ERRNO";
63 case Z_STREAM_ERROR : return "Z_STREAM_ERROR";
64 case Z_DATA_ERROR : return "Z_DATA_ERROR";
65 case Z_MEM_ERROR : return "Z_MEM_ERROR";
66 case Z_BUF_ERROR : return "Z_BUF_ERROR";
67 case Z_VERSION_ERROR: return "Z_VERSION_ERROR";
68 default : return "unknown";
69 }
70}
71#endif // _DEBUG
72
73voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size))
74{
76 return LocalAlloc(LPTR, items * size);
77}
78
79void zcfree OF((voidpf opaque, voidpf ptr))
80{
83}
84
85#define ZIP_LOCAL_SIGNATURE 0x04034b50
86
87#define ZIP_FLAG_ENCRYPTED 0x01
88
89#define ZIP_FLAG_DEFLATE_NORMAL 0x00
90#define ZIP_FLAG_DEFLATE_MAX 0x02
91#define ZIP_FLAG_DEFLATE_FAST 0x04
92#define ZIP_FLAG_DEFLATE_SUPER 0x06
93#define ZIP_FLAG_DEFLATE_MASK 0x06
94
95#define ZIP_FLAG_SIZE_IN_DESC 0x08
96
97#define ZIP_METHOD_STORED 0
98#define ZIP_METHOD_SHRUNK 1
99#define ZIP_METHOD_REDUCED1 2
100#define ZIP_METHOD_REDUCED2 3
101#define ZIP_METHOD_REDUCED3 4
102#define ZIP_METHOD_REDUCED4 5
103#define ZIP_METHOD_IMPLODED 6
104#define ZIP_METHOD_TOKENIZED 7
105#define ZIP_METHOD_DEFLATED 8
106#define ZIP_METHOD_DEFLATE64 9
107#define ZIP_METHOD_PKWARE_IMP 10
108#define ZIP_METHOD_RESERVED 11
109#define ZIP_METHOD_BZIP2 12
110
111#pragma pack(1)
112
126 // followed by extra field data, then compressed data
127}
129
130//
131// Check if the file is ZIP compressed
132//
135 ULONG *pSize)
136{
137 ZIP_HEADER zip_hdr;
139 DWORD ret;
140
141 if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
142 ret = GetLastError();
143
144 VFDTRACE(0,
145 ("SetFilePointer() - %s\n",
147
148 return ret;
149 }
150
151 if (!ReadFile(hFile, &zip_hdr, sizeof(zip_hdr), &result, NULL)) {
152 ret = GetLastError();
153
154 VFDTRACE(0,
155 ("ReadFile() - %s\n",
157
158 return ret;
159 }
160
161 if (result != sizeof(zip_hdr) ||
164 (zip_hdr.general_flags & ZIP_FLAG_ENCRYPTED)) {
165
166 VFDTRACE(0,
167 ("[VFD] Invalid ZIP file\n"));
168
169 return ERROR_INVALID_DATA;
170 }
171
172 // correct (and supported) ZIP header detected
173
174 *pSize = zip_hdr.uncompressed_size;
175
176 return ERROR_SUCCESS;
177}
178
179//
180// Extract original data from IMZ file
181//
185 PULONG pLength)
186{
189 DWORD ret;
190
191 PZIP_HEADER zip_hdr;
192 ULONG compressed;
194 PUCHAR file_cache;
196 int zlib_ret;
197
198 VFDTRACE(0,
199 ("[VFD] VfdExtractImz - IN\n"));
200
201 *pBuffer = NULL;
202 *pLength = 0;
203
204 //
205 // Read PKZIP local file header of the first file in the file
206 // -- An IMZ file actually is just a ZIP file with a different
207 // extension, which contains a single floppy image file
208 //
209 if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
210 ret = GetLastError();
211
212 VFDTRACE(0,(
213 "SetFilePointer - %s", SystemMessage(ret)));;
214
215 return ret;
216 }
217
220
221 ret = GetLastError();
222
223 VFDTRACE(0,(
224 "ReadFile - %s", SystemMessage(ret)));;
225
226 return ret;
227 }
228
229 zip_hdr = (PZIP_HEADER)buf;
230
231 // check local file header signature
232
233 if (zip_hdr->header_signature != ZIP_LOCAL_SIGNATURE) {
234
235 VFDTRACE(0,
236 ("[VFD] PKZIP header signature not found.\n"));
237
238 return ERROR_INVALID_DATA;
239 }
240
241 // check compression method
242
243 if (zip_hdr->compression_method != Z_DEFLATED) {
244
245 VFDTRACE(0,
246 ("[VFD] Bad PKZIP compression method.\n"));
247
248 return ERROR_NOT_SUPPORTED;
249 }
250
251 if (zip_hdr->general_flags & 0x01) {
252 // encrypted zip not supported
253
254 VFDTRACE(0,
255 ("[VFD] PKZIP encrypted.\n"));
256
257 return ERROR_NOT_SUPPORTED;
258 }
259
260 // check uncompressed image size
261
262 compressed = zip_hdr->compressed_size;
264
265 switch (uncompressed) {
266 case VFD_SECTOR_TO_BYTE(320):
267 case VFD_SECTOR_TO_BYTE(360):
268 case VFD_SECTOR_TO_BYTE(640):
269 case VFD_SECTOR_TO_BYTE(720):
270 case VFD_SECTOR_TO_BYTE(1280):
271 case VFD_SECTOR_TO_BYTE(1440):
272 case VFD_SECTOR_TO_BYTE(1640):
273 case VFD_SECTOR_TO_BYTE(2400):
274 case VFD_SECTOR_TO_BYTE(2880):
275 case VFD_SECTOR_TO_BYTE(3360):
276 case VFD_SECTOR_TO_BYTE(3444):
277 case VFD_SECTOR_TO_BYTE(5760):
278 break;
279
280 default:
281 VFDTRACE(0,
282 ("[VFD] Unsupported image size %lu.\n",
283 uncompressed));
284
285 return ERROR_NOT_SUPPORTED;
286 }
287
288 // check local file header length
289 // -- Just for simplicity, the compressed data must start in the
290 // first sector in the file: this is not a problem in most cases.
291
293 zip_hdr->file_name_length +
295
296 VFDTRACE(0,
297 ("[VFD] PKZIP header too long.\n"));
298
299 return ERROR_NOT_SUPPORTED;
300 }
301
302 // allocate memory to store uncompressed data
303
304 file_cache = (PUCHAR)LocalAlloc(LPTR, uncompressed);
305
306 if (!file_cache) {
307
308 VFDTRACE(0,
309 ("[VFD] Failed to allocate file cache.\n"));
310
311 return ERROR_OUTOFMEMORY;
312 }
313
314 // initialize the zlib stream
315
316 ZeroMemory(&stream, sizeof(stream));
317
318 // set initial input data information
319
320 stream.next_in = (PUCHAR)zip_hdr->file_name +
321 zip_hdr->file_name_length + zip_hdr->extra_field_length;
322
323 stream.avail_in = VFD_BYTES_PER_SECTOR -
325 zip_hdr->file_name_length - zip_hdr->extra_field_length;
326
327 // set output buffer information
328
329 stream.next_out = file_cache;
330 stream.avail_out = uncompressed;
331
332 zlib_ret = inflateInit2(&stream, -MAX_WBITS);
333
334 // negative MAX_WBITS value passed to the inflateInit2() function
335 // indicates that there is no zlib header.
336 // In this case inflate() function requires an extra "dummy" byte
337 // after the compressed stream in order to complete decompression
338 // and return Z_STREAM_END. However, both compressed and uncompressed
339 // data size are already known from the pkzip header, Z_STREAM_END
340 // is not absolutely necessary to know the completion of the operation.
341
342 if (zlib_ret != Z_OK) {
343 LocalFree(file_cache);
344
345 VFDTRACE(0,
346 ("[VFD] inflateInit2() failed - %s.\n",
347 ZLIB_ERROR(zlib_ret)));
348
350 }
351
352 for (;;) {
353
354 // uncompress current block
355
356 zlib_ret = inflate(&stream, Z_NO_FLUSH);
357
358 if (zlib_ret != Z_OK) {
359 if (zlib_ret == Z_STREAM_END) {
361 }
362 else {
363 VFDTRACE(0,
364 ("[VFD] inflate() failed - %s.\n",
365 ZLIB_ERROR(zlib_ret)));
366
368 }
369 break;
370 }
371
372 if (stream.total_out >= uncompressed) {
373 // uncompress completed - no need to wait for Z_STREAM_END
374 // (inflate() would return Z_STREAM_END on the next call)
376 break;
377 }
378
379 if (stream.total_in >= compressed) {
380 // somehow there is not enought compressed data
382 break;
383 }
384
385 // read next block from file
386
388 result <= 0) {
389
390 ret = GetLastError();
391
392 VFDTRACE(0,
393 ("[VFD] Read compressed data - %s.\n",
395 break;
396 }
397
398 stream.avail_in = result;
399 stream.next_in = buf;
400 }
401
402 // cleanup the zlib stream
403
405
406 // set the return information
407
408 if (ret == ERROR_SUCCESS) {
409 *pBuffer = file_cache;
410 *pLength = uncompressed;
411 }
412 else {
413 LocalFree(file_cache);
414 }
415
416 VFDTRACE(0,
417 ("[VFD] VfdExtractImz - OUT\n"));
418
419 return ret;
420}
421
422#endif // VFD_NO_ZLIB
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FILE_BEGIN
Definition: compat.h:761
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
int inflate(z_streamp strm, int flush)
Definition: inflate.c:1257
int inflateEnd(z_streamp strm)
Definition: inflate.c:1910
#define Z_DEFLATED
Definition: zlib.h:146
#define Z_NEED_DICT
Definition: zlib.h:116
#define Z_ERRNO
Definition: zlib.h:117
#define Z_BUF_ERROR
Definition: zlib.h:121
#define Z_VERSION_ERROR
Definition: zlib.h:122
void FAR * voidpf
Definition: zlib.h:42
#define Z_STREAM_END
Definition: zlib.h:115
#define Z_OK
Definition: zlib.h:114
#define Z_DATA_ERROR
Definition: zlib.h:119
#define Z_STREAM_ERROR
Definition: zlib.h:118
#define MAX_WBITS
Definition: zlib.h:151
#define Z_NO_FLUSH
Definition: zlib.h:105
#define Z_MEM_ERROR
Definition: zlib.h:120
unsigned long DWORD
Definition: ntddk_ex.h:95
void zcfree(voidpf opaque, voidpf ptr)
Definition: zutil.c:173
voidpf zcalloc(voidpf opaque, unsigned items, unsigned size)
Definition: zutil.c:164
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static PVOID ptr
Definition: dispmode.c:27
static const BYTE uncompressed[]
Definition: misc.c:392
static LPCWSTR file_name
Definition: protocol.c:147
_In_ HANDLE hFile
Definition: mswsock.h:90
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
static TCHAR * items[]
Definition: page1.c:45
unsigned short USHORT
Definition: pedump.c:61
PVOID pBuffer
#define err(...)
#define inflateInit2(strm, windowBits)
Definition: zlib.h:1817
USHORT file_name_length
Definition: vfdzip.c:123
USHORT compression_method
Definition: vfdzip.c:117
USHORT extra_field_length
Definition: vfdzip.c:124
USHORT required_version
Definition: vfdzip.c:115
Definition: parse.h:23
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define VFD_BYTES_PER_SECTOR
Definition: vfdio.h:40
#define VFD_SECTOR_TO_BYTE(s)
Definition: vfdio.h:45
PCSTR SystemMessage(DWORD nError)
Definition: vfdlib.c:147
struct _zip_local_file_header * PZIP_HEADER
struct _zip_local_file_header ZIP_HEADER
DWORD ExtractZipImage(HANDLE hFile, PUCHAR *pBuffer, PULONG pLength)
Definition: vfdzip.c:182
#define ZIP_METHOD_DEFLATED
Definition: vfdzip.c:105
DWORD ExtractZipInfo(HANDLE hFile, ULONG *pSize)
Definition: vfdzip.c:133
#define ZIP_LOCAL_SIGNATURE
Definition: vfdzip.c:85
#define ZIP_FLAG_ENCRYPTED
Definition: vfdzip.c:87
int ret
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LPTR
Definition: winbase.h:381
#define ERROR_INVALID_DATA
Definition: winerror.h:116
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175
#define OF(args)
Definition: zconf.h:295