VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "Cls_GZip"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
'This class file can be used to show/extract the contents of an gZip-archive
Private Type GZipType
CompType As Byte 'Compression method
Flags As Byte 'Flags
FDateUnix As Long 'last modified FileDate in UNIX format
ExtFlags As Byte 'Extended Flags
OStype As Byte 'Used OS type
ExtField As String 'Extended fields
FileName As String 'FileName
COMMENT As String 'Comment field
CRC16 As Integer 'least significant 2 bytes from CRC32 from header
Buff(11) As Byte 'hold encryption header
CRC32 As Long 'CRC 32
CSize As Long 'Compressed size
USize As Long 'Uncompressed size
DataStart As Long 'OffSet to start of data
FDate As Integer 'Zip date format
FTime As Integer 'zip time format
End Type
'Flag values for GZip-files
Private Const GzFlgAscII As Byte = 1 'bit 0 set = file is ascii file
Private Const GzFlgCRC16 As Byte = 2 'bit 1 set Included CRC16 ofthe header
Private Const GzFlgExtFld As Byte = 4 'bit 2 set Extra field is set
Private Const GzFlgOrgName As Byte = 8 'bit 3 set original name included
Private Const GzFlgComment As Byte = 16 'bit 4 set comment are included
Private Const GzFlgEncrypt As Byte = 32 'bit 5 set file is encrypted
Private Const GzFlgReserved As Byte = 192 'bit 6,7 reserved
Private GZipData As GZipType
Private CRC As New Cls_CRC32
Private Encrypt As New Cls_Encrypt
Private Const m_Unpack_Supported As Boolean = True
Public Function Get_Contents(ZipName As String) As Integer
Dim NextByte As Byte '1 byte
Dim Byte2 As Integer '2 bytes
Dim FileNum As Long
Dim FileLenght As Long
Dim Header As Integer
Dim LngHeader As Long
Dim LN As Long
Dim X As Long
Dim Temp As String
If ZipName = "" Then
Get_Contents = -1 'file don't exist
Exit Function
End If
PackFileName = ZipName
PackComments = ""
PackFileType = 0
FileNum = FreeFile
Open PackFileName For Binary Access Read As #FileNum
FileLenght = LOF(FileNum)
Get #FileNum, , Header
PackFileType = GZFileType
PackTotFiles = 1 'GZip files contain 1 file
Get #FileNum, , GZipData.CompType
If GZipData.CompType <> 8 Then GZipData.CompType = 99 'only deflate allowed
Get #FileNum, , GZipData.Flags 'get the flags
Get #FileNum, , GZipData.FDateUnix 'get unix date
Get #FileNum, , GZipData.ExtFlags 'get extra flags
Get #FileNum, , GZipData.OStype 'get os type
GZipData.ExtField = ""
If (GZipData.Flags And GzFlgExtFld) > 0 Then 'read extra field
Get #FileNum, , Byte2
LN = Int2Lng(Byte2)
GZipData.ExtField = String(LN, 0)
Get #FileNum, , GZipData.ExtField
End If
GZipData.FileName = ""
If (GZipData.Flags And GzFlgOrgName) > 0 Then 'Read original filename (NULL terminated)
Do
Get #FileNum, , NextByte
If NextByte = 0 Then Exit Do 'filename complete
GZipData.FileName = GZipData.FileName & Chr(NextByte)
Loop
End If
If GZipData.FileName = "" Then GZipData.FileName = GetNameFromFileName
GZipData.COMMENT = ""
If (GZipData.Flags And GzFlgComment) > 0 Then 'read comments (NULL terminated)
Do
Get #FileNum, , NextByte
If NextByte = 0 Then Exit Do 'filename complete
GZipData.COMMENT = GZipData.COMMENT & Chr(NextByte)
Loop
End If
If (GZipData.Flags And GzFlgCRC16) > 0 Then 'get CRC16 of header
Get #FileNum, , Byte2
GZipData.CRC16 = Byte2
End If
If (GZipData.Flags And GzFlgEncrypt) > 0 Then
Get #FileNum, , GZipData.Buff
End If
'here is where the compressed data is
GZipData.CSize = FileLenght - Seek(FileNum) - 8
GZipData.DataStart = Seek(FileNum)
Get #FileNum, FileLenght - 7, GZipData.CRC32
Get #FileNum, , GZipData.USize
Close FileNum
'Translate unix time to zip time
GZipData.FDate = GetIntegerDate(GZipData.FDateUnix)
GZipData.FTime = GetIntegerTime(GZipData.FDateUnix)
End Function
'Unzip as file and return 0 for good decompression or others for error
Public Function UnPack(ZippedFile() As Boolean, ToPath As String) As Integer
Dim X As Long
Dim FileNum As Long
Dim Y As Long
Dim PassWord As String
Dim TotDir As String 'Used for new pathnames
If PackTotFiles = 0 Then UnPack = -10: Exit Function 'nothing to UnPack
Erase PackData
FileNum = FreeFile
Open PackFileName For Binary Access Read As #FileNum
For X = 1 To PackTotFiles
If ZippedFile(X) = True Then
If Encrypted(X) Then
If PassWord = "" Then
PassWord = InputBox("Give Password", "Password requered")
If PassWord = "" Then
UnPack = -1
Close FileNum
MsgBox "Password is incorrect"
Exit Function
End If
End If
Encrypt.ZipPrepareKey PackData, PassWord
If PackData(11) <> (((GZipData.CRC32 And &HFF000000) \ &H1000000) And 255&) Then
UnPack = -1
Close FileNum
MsgBox "Password is incorrect"
Exit Function
End If
'adjust the size of instream to delete the decryption data
For Y = 0 To UBound(PackData) - 12
PackData(Y) = PackData(Y + 12)
Next
ReDim Preserve PackData(UBound(PackData) - 12)
Encrypt.ZipDecryptArray PackData
End If
ReDim PackData(GZipData.CSize)
Get #FileNum, GZipData.DataStart, PackData
Call Inflate(PackData, GZipData.USize - 1)
Call Write_Uncompressed_Data(1, ToPath)
End If
Next
Close FileNum
Erase PackData
End Function
Public Function Pack(ZipName As String, Files() As String, CompType As Integer, CompLevel As Integer, Optional IncludeDir As String = "") As Integer
End Function
Public Property Get CanUnpack() As Boolean
CanUnpack = m_Unpack_Supported
End Property
Public Property Get FileCount() As Long
FileCount = PackTotFiles
End Property
Public Property Get FileName(FileNum As Long) As String
If NotGood(FileNum) Then Exit Property
FileName = GZipData.FileName
End Property
Public Property Get CommentsFile(FileNum As Long) As String
If NotGood(FileNum) Then Exit Property
CommentsFile = GZipData.COMMENT
End Property
Public Property Get CommentsPack() As String
CommentsPack = GZipData.COMMENT
End Property
Public Property Get IsDir(FileNum As Long) As Boolean
IsDir = False 'No dirs allowed in gzip so must be a file
End Property
Public Property Get Method(FileNum As Long) As String
If NotGood(FileNum) Then Exit Property
Method = Methods(CInt(GZipData.CompType))
End Property
Public Property Get CRC32(FileNum As Long) As Long
If NotGood(FileNum) Then Exit Property
CRC32 = GZipData.CRC32
End Property
Public Property Get Compressed_Size(FileNum As Long) As Long
If NotGood(FileNum) Then Exit Property
Compressed_Size = GZipData.CSize
End Property
Public Property Get UnCompressed_Size(FileNum As Long) As Long
If NotGood(FileNum) Then Exit Property
UnCompressed_Size = GZipData.USize
End Property
Public Property Get Encrypted(FileNum As Long) As Boolean
If NotGood(FileNum) Then Exit Property
Encrypted = (GZipData.Flags And GzFlgEncrypt) = 1
End Property
Public Property Get FileDateTime(FileNum As Long) As Date
If NotGood(FileNum) Then Exit Property
FileDateTime = GetZipDate(GZipData.FDate, GZipData.FTime)
End Property
Public Property Get SystemMadeBy(FileNum As Long) As String
SystemMadeBy = SystemName(GZipData.OStype)
End Property
Public Property Get VersionMadeBy(FileNum As Long) As String
VersionMadeBy = "UnKnown"
End Property
Public Property Get SystemNeeded(FileNum As Long) As String
SystemNeeded = "UnKnown"
End Property
Public Property Get VersionNeeded(FileNum As Long) As String
VersionNeeded = "UnKnown"
End Property
Private Function NotGood(FileNum As Long) As Boolean
If FileNum = 0 Then NotGood = True: Exit Function
If FileNum > PackTotFiles Then NotGood = True: Exit Function
If PackFileType = 0 Then NotGood = True: Exit Function
End Function
Private Function Int2Lng(Value As Integer) As Long
If Value < 0 Then Int2Lng = &HFFFF& + Value + 1 Else Int2Lng = Value
End Function
Private Function SystemName(System As Byte) As String
Select Case System
Case 0: SystemName = "MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)"
Case 1: SystemName = "Amiga"
Case 2: SystemName = "2 - OpenVMS"
Case 3: SystemName = "UNIX"
Case 4: SystemName = "VM/CMS"
Case 5: SystemName = "Atari ST"
Case 6: SystemName = "OS/2 H.P.F.S."
Case 7: SystemName = "Macintosh"
Case 8: SystemName = "Z-System"
Case 9: SystemName = "CP/M"
Case 10: SystemName = "Tops-20"
Case 11: SystemName = "NTFS filesystem"
Case 12: SystemName = "QDos"
Case 13: SystemName = "Acorn Risc"
Case Else: SystemName = "UnKnown"
End Select
End Function
Private Sub Write_Uncompressed_Data(FileNum As Long, ToPath As String)
Dim DSize As Long
DSize = DataSize
If DSize > 0 Then
If GZipData.CRC32 <> CRC.CalcCRC32File(PackData) Then
MsgBox "CRC calculation failed"
End If
Else
If GZipData.CRC32 <> 0 Then
MsgBox "CRC error"
End If
End If
If GZipData.USize <> DSize Then
MsgBox "Error in decompressed size"
End If
If Write_File(GZipData.FileName, ToPath, PackData, GZipData.FDate, GZipData.FTime) Then
MsgBox "error writing file"
End If
End Sub
Private Function DataSize() As Long
On Error Resume Next
DataSize = UBound(PackData) + 1
If Err.Number <> 0 Then
Err.Clear
DataSize = 0
End If
End Function
Private Function VersionTo(Version As Byte) As String
VersionTo = Fix(Version / 10) & "." & Version Mod 10
End Function
Private Function Methods(MethodType As Integer) As String
Select Case MethodType
Case 0: Methods = "Stored"
Case 8: Methods = "Deflate"
Case Else: Methods = "Unknown"
End Select
End Function
Private Function GetNameFromFileName()
Dim name As String
name = mbStripFileName(PackFileName, False)
If InStr(UCase(name), ".GZ") Then
GetNameFromFileName = Left(name, InStr(UCase(name), ".GZ") - 1)
Exit Function
End If
If InStr(UCase(name), ".Z") Then
GetNameFromFileName = Left(name, InStr(UCase(name), ".Z") - 1)
Exit Function
End If
If InStr(UCase(name), ".TGZ") Then
GetNameFromFileName = Left(name, InStr(UCase(name), ".TGZ") - 1) & ".tar"
Exit Function
End If
If InStr(UCase(name), ".TAZ") Then
GetNameFromFileName = Left(name, InStr(UCase(name), ".TAZ") - 1) & ".tar"
Exit Function
End If
End Function
'----------------------------------------------------------
'This function is used to extract the filename
'input:
'Stripfile = Filename with or without directory
'StripBaseOnly = Treu if only filename is needed
' False if also the extension is needed
'return:
'StripFileName = filename
'----------------------------------------------------------
Private Function mbStripFileName(Stripfile As String, StripBaseOnly As Boolean) As String
Dim Counter As Integer, Stripped As String
On Local Error Resume Next
If InStr(Stripfile, "\") Then
For Counter = Len(Stripfile) To 1 Step -1
If Mid$(Stripfile, Counter, 1) = "\" Then
Stripped = Mid$(Stripfile, Counter + 1)
Exit For
End If
Next Counter
ElseIf InStr(Stripfile, ":") = 2 Then
Stripped = Mid$(Stripfile, 3)
Else
Stripped = Stripfile
End If
If StripBaseOnly = True Then
If InStr(Stripped, ".") > 0 Then
Stripped = Left$(Stripped, InStr(Stripped, ".") - 1)
End If
End If
mbStripFileName = Stripped
End Function
Private Function StampToData(Stamp) As Date
StampToData = CDate(CDbl(DateSerial(1970, 1, 1)) + CDbl((CLng(Stamp) / 86400)))
End Function
Private Function GetIntegerDate(Stamp As Long) As Integer
Dim Dat As String
Dim FD As Long
Dat = StampToData(Stamp)
FD = (Year(Dat) - 1980) * 2 ^ 9
FD = FD + (Month(Dat) * 2 ^ 5)
FD = FD + Day(Dat)
If FD > 32767 Then GetIntegerDate = FD - &HFFFF& - 1 Else GetIntegerDate = FD
End Function
Private Function GetIntegerTime(Stamp As Long) As Integer
Dim Dat As String
Dim FT As Long
Dat = StampToData(Stamp)
FT = Hour(Dat) * 2 ^ 11
FT = FT + (Minute(Dat) * 2 ^ 5)
FT = FT + Second(Dat)
If FT > 32767 Then GetIntegerTime = FT - &HFFFF& - 1 Else GetIntegerTime = FT
End Function