⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liteunzip.c

📁 是一个C语言的压缩和解压缩的DLL源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include "../LiteUnzip.h"
#define IDS_OK        20
#define IDS_UNKNOWN   21


// =========================== Defines ======================
// Basic data types
typedef unsigned int	uInt;		// 16 bits or more
typedef unsigned char	UCH;
typedef unsigned long	ULG;
typedef unsigned long	lutime_t;	// define it ourselves since we don't include time.h

#define ZIP_MEMORY		0x01
#define ZIP_FILENAME	0x02
#define ZIP_HANDLE		0x04
#define ZIP_ALREADYINIT	0x40000000
#define ZIP_UNICODE		0x80000000

// Allowed flush values; see deflate() for details
#define Z_NO_FLUSH		0
#define Z_SYNC_FLUSH	2
#define Z_FULL_FLUSH	3
#define Z_FINISH		4

// The deflate compression method (the only one supported in this version)
#define Z_DEFLATED		8

// Return codes for the DEFLATE low-level functions. Negative
// values are errors, positive values are used for special but normal events.
#define Z_OK			0
#define Z_STREAM_END	1
#define Z_NEED_DICT		2
#define Z_STREAM_ERROR	(-2)
#define Z_DATA_ERROR	(-3)
#define Z_MEM_ERROR		(-4)
#define Z_BUF_ERROR		(-5)

// preset dictionary flag in zlib header 
#define PRESET_DICT		0x20

// Maximum size of dynamic tree. The maximum found in a long but non-
// exhaustive search was 1004 huft structures (850 for length/literals
// and 154 for distances, the latter actually the result of an
// exhaustive search). The actual maximum is not known, but the
// value below is more than safe.
#define MANY		1440





// =========================== Structs ======================

typedef struct
{
	unsigned int tm_sec;	// seconds after the minute - [0,59]
	unsigned int tm_min;	// minutes after the hour - [0,59]
	unsigned int tm_hour;	// hours since midnight - [0,23]
	unsigned int tm_mday;	// day of the month - [1,31]
	unsigned int tm_mon;	// months since January - [0,11]
	unsigned int tm_year;	// years - [1980..2044]
} TM_UNZ;

// ZIPENTRYINFO holds information about one entry in the zip archive.
// This header appears in the ZIP archive.

#define UNZ_BUFSIZE (16384)
#define UNZ_MAXFILENAMEINZIP (256)
#define SIZECENTRALDIRITEM (0x2e)
#define SIZEZIPLOCALHEADER (0x1e)

#define ZIP_FIELDS_REFORMAT 0x000060F0
#define NUM_FIELDS_REFORMAT 15

#pragma pack(1)
typedef struct
{
	unsigned short	version;			// version made by					2 bytes
	unsigned short	version_needed;		// version needed to extract		2 bytes
	unsigned short	flag;				// general purpose bit flag			2 bytes
	unsigned short	compression_method;	// compression method				2 bytes
	unsigned long	dosDate;			// last mod file date in Dos fmt	4 bytes
	unsigned long	crc;				// crc-32							4 bytes
	unsigned long	compressed_size;	// compressed size					4 bytes
	unsigned long	uncompressed_size;	// uncompressed size				4 bytes
	unsigned short	size_filename;		// filename length					2 bytes
	unsigned short	size_file_extra;	// extra field length				2 bytes
	unsigned short	size_file_comment;	// file comment length				2 bytes
	unsigned short	disk_num_start;		// disk number start				2 bytes
	unsigned short	internal_fa;		// internal file attributes			2 bytes
	unsigned long	external_fa;		// external file attributes			4 bytes
	unsigned long	offset;				// Byte offset of local header		4 bytes
} ZIPENTRYINFO;
#pragma pack()


// Used for DEFLATE decompression
typedef struct {
	union {
		struct {
			UCH Exop;		// number of extra bits or operation
			UCH Bits;		// number of bits in this code or subcode
		} what;
		uInt pad;			// pad structure to a power of 2 (4 bytes for
	} word;					//  16-bit, 8 bytes for 32-bit int's)
	uInt base;				// literal, length base, distance base, or table offset
} INFLATE_HUFT;


// INFLATE_CODES_STATE->mode
// waiting for "i:"=input, "o:"=output, "x:"=nothing 
#define START	0	// x: set up for LEN 
#define LEN		1	// i: get length/literal/eob next 
#define LENEXT	2	// i: getting length extra (have base) 
#define DIST	3	// i: get distance next 
#define DISTEXT	4	// i: getting distance extra 
#define COPY	5	// o: copying bytes in window, waiting for space
#define LIT		6	// o: got literal, waiting for output space 
#define WASH	7	// o: got eob, possibly still output waiting 
#define END		8	// x: got eob and all data flushed 
#define BADCODE	9	// x: got error 

// inflate codes private state
typedef struct {
  uInt						len;

  // mode dependent information 
  union {
    struct {
      const INFLATE_HUFT	*tree;	// pointer into tree 
      uInt					need;	// bits needed 
    } code;							// if LEN or DIST, where in tree 
    uInt					lit;	// if LIT, literal 
    struct {
      uInt					get;	// bits to get for extra 
      uInt					dist;	// distance back to copy from 
    } copy;							// if EXT or COPY, where and how much 
  } sub;							// submode

  // mode independent information 
  const INFLATE_HUFT		*ltree;	// literal/length/eob tree
  const INFLATE_HUFT		*dtree;	// distance tree
  UCH						lbits;	// ltree bits decoded per branch 
  UCH						dbits;	// dtree bits decoder per branch 
  unsigned char				mode;	// current inflate_codes mode 
} INFLATE_CODES_STATE;

// INFLATE_BLOCKS_STATE->mode
#define IBM_TYPE	0	// get type bits (3, including end bit)
#define IBM_LENS	1	// get lengths for stored
#define IBM_STORED	2	// processing stored block
#define IBM_TABLE	3	// get table lengths
#define IBM_BTREE	4	// get bit lengths tree for a dynamic block
#define IBM_DTREE	5	// get length, distance trees for a dynamic block
#define IBM_CODES	6	// processing fixed or dynamic block
#define IBM_DRY		7	// output remaining window bytes
#define IBM_DONE	8	// finished last block, done 
#define IBM_BAD		9	// got a data error--stuck here 

// inflate blocks semi-private state 
typedef struct {
	// mode dependent information 
	union {
		uInt			 left;		// if STORED, bytes left to copy 
		struct {
			uInt		 table;		// table lengths (14 bits) 
			uInt		 index;		// index into blens (or border)
			uInt		 *blens;	// bit lengths of codes
			uInt		 bb;		// bit length tree depth 
			INFLATE_HUFT *tb;		// bit length decoding tree 
		} trees;					// if DTREE, decoding info for trees 

		struct {
			INFLATE_CODES_STATE *codes;
		} decode;				// if CODES, current state 
	} sub;						// submode

	// mode independent information 
	uInt			last;		// TRUE if this block is the last block 
	uInt			bitk;		// bits in bit buffer 
	ULG				bitb;		// bit buffer 
	INFLATE_HUFT	*hufts;		// single malloc for tree space 
	UCH				*window;	// sliding window 
	UCH				*end;		// one byte after sliding window 
	UCH				*read;		// window read pointer 
	UCH				*write;		// window write pointer 
	ULG				check;		// check on output 
	unsigned char	 mode;		// current inflate_block mode 
} INFLATE_BLOCKS_STATE;

// INTERNAL_STATE->mode
#define IM_METHOD	0	// waiting for method byte
#define IM_FLAG		1	// waiting for flag byte
#define IM_DICT4	2	// four dictionary check bytes to go
#define IM_DICT3	3	// three dictionary check bytes to go
#define IM_DICT2	4	// two dictionary check bytes to go
#define IM_DICT1	5	// one dictionary check byte to go
#define IM_DICT0	6	// waiting for inflateSetDictionary
#define IM_BLOCKS	7	// decompressing blocks
#define IM_CHECK4	8	// four check bytes to go
#define IM_CHECK3	9	// three check bytes to go
#define IM_CHECK2	10	// two check bytes to go
#define IM_CHECK1	11	// one check byte to go
#define IM_DONE		12	// finished check, done
#define IM_BAD		13	// got an error--stay here

// inflate private state
typedef struct {

	// mode dependent information
	union {
		uInt method;		// if IM_FLAGS, method byte
		struct {
			ULG	was;		// computed check value
			ULG	need;		// stream check value
		} check;			// if CHECK, check values to compare
		uInt marker;		// if IM_BAD, inflateSync's marker bytes count
	} sub;					// submode

	// mode independent information
	uInt					wbits;		// log2(window size)  (8..15, defaults to 15)
	INFLATE_BLOCKS_STATE	blocks;		// current inflate_blocks state
	unsigned char			mode;		// current inflate mode
//	unsigned char			nowrap;		// flag for no wrapper
} INTERNAL_STATE;


// readEntry() updates next_in and avail_in when avail_in has
// dropped to zero. It updates next_out and avail_out when avail_out
// has dropped to zero. All other fields are set by low level
// DEFLATE routines and must not be updated by the higher level.
//
// The fields total_in and total_out can be used for statistics or
// progress reports. After compression, total_in holds the total size of
// the uncompressed data and may be saved for use in the decompressor
// (particularly if the decompressor wants to decompress everything in
// a single step)
typedef struct {
	UCH	*		next_in;	// next input byte
	DWORD		avail_in;	// # of bytes available at next_in
	DWORD		total_in;	// total # of input bytes read so far
	UCH	*		next_out;	// next output byte should be put there
	DWORD		avail_out;	// remaining free space at next_out
	DWORD		total_out;	// total # of bytes output so far
#ifndef NDEBUG
	char *		msg;		// last error message, NULL if no error
#endif
	INTERNAL_STATE *state;
//	int			data_type;	// best guess about the data type: ascii or binary
//	ULG			adler;		// adler32 value of the uncompressed data
} Z_STREAM;


// ENTRYREADVARS holds tables/variables used when reading and decompressing an entry
typedef struct
{
	UCH			*InputBuffer;				// Buffer for reading in compressed data of the current entry
	Z_STREAM	stream;						// structure for inflate()
//	DWORD		PosInArchive;				// Current "file position" within the archive
	ULG			RunningCrc;					// crc32 of all data uncompressed
	DWORD		RemainingCompressed;		// Remaining number of bytes to be decompressed
	DWORD		RemainingUncompressed;		// Remaining number of bytes to be obtained after decomp
	unsigned long Keys[3];					// Decryption keys, initialized by initEntry()
	DWORD		RemainingEncrypt;			// The first call(s) to readEntry will read this many encryption-header bytes first
	char		CrcEncTest;					// If encrypted, we'll check the encryption buffer against this
} ENTRYREADVARS;

// For TUNZIP->flags
#define TZIP_ARCMEMORY			0x0000001	// Set if TZIP->archive is memory, instead of a file, handle.
#define TZIP_ARCCLOSEFH			0x0000002	// Set if we open the file handle in archiveOpen() and must close it later.
#define TZIP_GZIP				0x0000004	// Set if a GZIP archive.

// TUNZIP holds information about the ZIP archive itself.
typedef struct
{
	DWORD			Flags;
	HANDLE			ArchivePtr;					// Points to a handle, or a buffer if TZIP_ARCMEMORY
	DWORD			LastErr;					// Holds the last TUNZIP error code
	DWORD			InitialArchiveOffset;		// Initial offset within a file where the ZIP archive begins. This allows reading a ZIP archive contained within another file
	DWORD			ArchiveBufLen;				// Size of memory buffer
	DWORD			ArchiveBufPos;				// Current position within "ArchivePtr" if TZIP_ARCMEMORY
	DWORD			TotalEntries;				// Total number of entries in the current disk of this archive
	DWORD			CommentSize;				// Size of the global comment of the archive
	DWORD			ByteBeforeZipArchive;		// Byte before the archive, (>0 for sfx)
	DWORD			CurrentEntryNum;			// Number of the entry (in the archive) that is currently selected for
												// unzipping. -1 if none.
	DWORD			CurrEntryPosInCentralDir;	// Position of the current entry's header within the central dir
//	DWORD			CentralDirPos;				// Byte offset to the beginning of the central dir
	DWORD			CentralDirOffset;			// Offset of start of central directory with respect to the starting disk number
	unsigned char	*Password;					// Password, or 0 if none.
	unsigned char	*OutBuffer;					// Output buffer (where we decompress the current entry when unzipping it).
	ZIPENTRYINFO	CurrentEntryInfo;			// Info about the currently selected entry (gotten from the Central Dir)
	ENTRYREADVARS	EntryReadVars;				// Variables/buffers for decompressing the current entry
	unsigned char	Rootdir[MAX_PATH];			// Root dir for unzipping entries. Includes a trailing slash. Must be the last field!!!
} TUNZIP;

































// ======================== Function Declarations ======================

// Diagnostic functions
#ifndef NDEBUG
#define LuAssert(cond,msg)
#define LuTrace(x)
#define LuTracev(x)
#define LuTracevv(x)
#define LuTracec(c,x)
#define LuTracecv(c,x)
#endif
static int inflate_trees_bits (uInt *, uInt *, INFLATE_HUFT **, INFLATE_HUFT *, Z_STREAM *);
static int inflate_trees_dynamic(uInt, uInt, uInt *, uInt *, uInt *, INFLATE_HUFT **, INFLATE_HUFT **, INFLATE_HUFT *, Z_STREAM *);
static INFLATE_BLOCKS_STATE * inflate_blocks_new(Z_STREAM * z, uInt w);
static INFLATE_CODES_STATE *inflate_codes_new(uInt, uInt, const INFLATE_HUFT *, const INFLATE_HUFT *, Z_STREAM *);
static int inflate_codes(INFLATE_BLOCKS_STATE *, Z_STREAM *, int);
static int inflate_flush(INFLATE_BLOCKS_STATE *, Z_STREAM *, int);
static int inflate_fast(uInt, uInt, const INFLATE_HUFT *, const INFLATE_HUFT *, INFLATE_BLOCKS_STATE *, Z_STREAM *);
//static ULG adler32(ULG, const UCH *, DWORD);
static DWORD setCurrentEntry(TUNZIP *, ZIPENTRY *, DWORD);


// simplify the use of the INFLATE_HUFT type with some defines
// defines for inflate input/output
//   update pointers and return 
#define UPDBITS {s->bitb = b; s->bitk = k;}
#define UPDIN {z->avail_in = n; z->total_in += (ULG)(p-z->next_in); z->next_in = p;}
#define UPDOUT {s->write = q;}
#define UPDATE {UPDBITS UPDIN UPDOUT}
#define LEAVE {UPDATE return(inflate_flush(s,z,r));}
//   get bytes and bits 
#define LOADIN {p = z->next_in; n = z->avail_in; b = s->bitb; k = s->bitk;}
#define NEEDBYTE {if (n) r = Z_OK; else LEAVE}
#define NEXTBYTE (n--, *p++)
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((ULG)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(j) {b >>= (j); k -= (j);}
//   output bytes 
#define WAVAIL (uInt)(q < s->read ? s->read - q - 1: s->end - q)
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;m;}
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
#define OUTBYTE(a) {*q++=(UCH)(a);m--;}
//   load local pointers 
#define LOAD {LOADIN LOADOUT}







// NOTE: I specify this data section to be Shared (ie, each running rexx
// script shares these variables, rather than getting its own copies of these
// variables). This is because, since I have only globals that are read-only
// or whose value is the same for all processes, I don't need a separate copy
// of these for each process that uses this DLL. In Visual C++'s Linker
// settings, I add "/section:Shared,rws"

#pragma data_seg("shared")

static HINSTANCE	ThisInstance;

// Table of CRC-32's of all single-byte values (made by make_Crc_table)
static const ULG Crc_table[256] = {
  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -