Seit 20.06.2011 kann man auch zip-Dateien entpacken.
Es gibt viele Dinge wie pureZIP von gnozal oder die minizip von ts-soft,
aber ich wollte etwas, das auch bei allen OS funktioniert (und keine library ist).
Update (29.12.2012)
Dateinamen werden korrekt GEzippt (Danke an ts-soft)
Update (30.04.2012)
Dateinamen mit Umlauten werden korrekt entzippt.
(Da ist das zib-Format ein wenig altbacken, ich fürchte die Zip-Routine produziert beim zippen von Umlautdateinamen auch falsche Namen.
Muss ich mal bei Gelegenheit abändern)
Update (29.04.2012)
Zip-Dateien mit Extrafields werden nun auch unterstützt (Fehler von DROOPY gemeldet).
Neu (20.06.2011)
Entzippen-Funktion hinzugefügt.
Herausgekommen ist das hier:
Code: Alles auswählen
;/--------------
;| Pipifax Zip
;| Last modified: 29.12.2012
;|
;| Mini-Include to
;| create a zip file with just ONE file in it.
;| Extract zip files
;|
;| Should work with Win, Linux and MacOS
;|
;| (c)HeX0R 2012
;|
;/--------------
Structure z_stream
*next_in; /* next input byte */
avail_in.l; /* number of bytes available at next_in */
total_in.l; /* total nb of input bytes read so far */
*next_out; /* next output byte should be put there */
avail_out.l; /* remaining free space at next_out */
total_out.l; /* total nb of bytes output so far */
*msg; /* last error message, NULL if no error */
*state; /* not visible by applications */
*zalloc; /* used to allocate the internal state */
*zfree; /* used to free the internal state */
*opaque; /* private data object passed to zalloc and zfree */
data_type.l; /* best guess about the data type: binary or text */
adler.l; /* adler32 value of the uncompressed data */
reserved.l; /* reserved for future use */
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Dummy.l
CompilerEndIf
EndStructure
;All-OS compatible Import
;from jamirokwai [http://www.purebasic.fr/german/viewtopic.php?p=288981#p288981]
;{
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
ImportC "zlib.lib"
CompilerCase #PB_OS_Linux
ImportC #PB_Compiler_Home + "purelibraries/linux/libraries/zlib.a"
CompilerCase #PB_OS_MacOS
ImportC "/usr/lib/libz.dylib"
CompilerEndSelect
compress2(*dest, *destLen, *source, sourceLen, level)
uncompress(*a, *b, *c, d)
inflateInit2_(*strm.z_stream, windowBits, *version, stream_size)
inflate(*strm.z_stream, flush)
inflateEnd(*strm.z_stream)
EndImport
;}
#Z_DEFAULT_COMPRESSION = -1
#Z_OK = 0
#Z_STREAM_END = 1
#Z_FINISH = 4
Structure _ZIP_Local_File_Header_
signature.l ;0x04034b50
VersionNeeded.w
Generalflag.w
Compressionmethod.w
Last_modification.l
CRC32.l
Compressed_size.l
Uncompressed_size.l
Filename_length.w
Extrafield_length.w
*Filename
EndStructure
Structure _ZIP_Unicode_Path_Extra_Field_
signature.w ;0x7075
Size.w
Version.b
CRC32.l
*FileName
EndStructure
Structure _ZIP_Data_Descriptor_
signature.l ;0x08074b50
CRC32.l
Compressed_size.l
Uncompressed_size.l
EndStructure
Structure _ZIP_Central_Directory_File_Header_
signature.l ;0x02014b50
madeby.w
VersionNeeded.w
Generalflag.w
Compressionmethod.w
Last_modification.l
CRC32.l
Compressed_size.l
Uncompressed_size.l
Filename_length.w
Extrafield_length.w
comment_length.w
Disk_number_start.w
Internal_file_attributes.w
External_file_attributes.l
offset_of_local_file_header.l
*Filename
EndStructure
Structure _ZIP_End_of_central_directory_record_
signature.l ;0x06054b50
Number_of_this_disk.w
Disk_Start.w
Number_of_central_directory_records_on_disk.w
Total_number_of_central_directory_records.w
Size_of_central_directory.l
Offset_of_start_of_central_directory.l
filecomment_length.w
*filecomment
EndStructure
Procedure UnixToMSDosDate(UnixDate)
Protected Result, m
m = Year(UnixDate) - 1980
Result | (m << 25)
m = Month(UnixDate)
Result | (m << 21)
m = Day(UnixDate)
Result | (m << 16)
m = Hour(UnixDate)
Result | (m << 11)
m = Minute(UnixDate)
Result | (m << 5)
m = Second(UnixDate) / 2
Result | m
ProcedureReturn Result
EndProcedure
Procedure MSDosDateToUnix(MSDos_Date)
Protected Result, Y, M, D, H, Min, S
Y = 1980 + (MSDos_Date >> 25) & $7F
M = (MSDos_Date >> 21) & $0F
D = (MSDos_Date >> 16) & $1F
H = (MSDos_Date >> 11) & $1F
Min = (MSDos_Date >> 5) & $3F
S = (MSDos_Date & $1F) * 2
Result = Date(Y, M, D, H, Min, S)
ProcedureReturn Result
EndProcedure
Procedure CreateZipFile(FileToAdd.s, ZipFile.s)
Protected i, j, k, l, Offset, Result, FID_Zip, FID_Orig, *B1, *B2
Protected MSDos_Date
Protected *ZLFH._ZIP_Local_File_Header_
Protected *ZDD._ZIP_Data_Descriptor_ ;not used
Protected *ZCDFH._ZIP_Central_Directory_File_Header_
Protected *ZECDR._ZIP_End_of_central_directory_record_
If FileSize(FileToAdd) > 0
*ZLFH = ?__ZIP_Local_File_Header_
*ZDD = ?__ZIP_Data_Descriptor_
*ZCDFH = ?__ZIP_Central_Directory_File_Header_
*ZECDR = ?__ZIP_End_of_central_directory_record_
k = CRC32FileFingerprint(FileToAdd)
FID_Orig = ReadFile(#PB_Any, FileToAdd)
If FID_Orig
*B1 = AllocateMemory(Lof(FID_Orig))
If *B1
ReadData(FID_Orig, *B1, Lof(FID_Orig))
i = MemorySize(*B1)
j = i
*B2 = AllocateMemory(i)
If *B2
If compress2(*B2, @i, *B1, j, #Z_DEFAULT_COMPRESSION) = #Z_OK
FID_Zip = CreateFile(#PB_Any, ZipFile)
If FID_Zip
l = StringByteLength(GetFilePart(FileToAdd), #PB_UTF8)
MSDos_Date = UnixToMSDosDate(GetFileDate(FileToAdd, #PB_Date_Modified))
*ZLFH\Last_modification = MSDos_Date
*ZLFH\CRC32 = k
*ZLFH\Compressed_size = i - 6
*ZLFH\Uncompressed_size = j
*ZLFH\Filename_length = l
*ZLFH\Generalflag = $800
WriteData(FID_Zip, *ZLFH, OffsetOf(_ZIP_Local_File_Header_\Filename))
WriteString(FID_Zip, GetFilePart(FileToAdd), #PB_UTF8)
WriteData(FID_Zip, *B2 + 2, i - 6)
Offset = Loc(FID_Zip)
*ZCDFH\External_file_attributes = GetFileAttributes(FileToAdd)
*ZCDFH\CRC32 = k
*ZCDFH\Compressed_size = i - 6
*ZCDFH\Uncompressed_size = j
*ZCDFH\Generalflag = $800
*ZCDFH\Filename_length = l
*ZCDFH\Last_modification = MSDos_Date
WriteData(FID_Zip, *ZCDFH, OffsetOf(_ZIP_Central_Directory_File_Header_\Filename))
WriteString(FID_Zip, GetFilePart(FileToAdd), #PB_UTF8)
*ZECDR\Size_of_central_directory = OffsetOf(_ZIP_Central_Directory_File_Header_\Filename) + l
*ZECDR\Offset_of_start_of_central_directory = Offset
WriteData(FID_Zip, *ZECDR, OffsetOf(_ZIP_End_of_central_directory_record_\filecomment))
CloseFile(FID_Zip)
Result = #True
EndIf
EndIf
FreeMemory(*B2)
EndIf
FreeMemory(*B1)
EndIf
CloseFile(FID_Orig)
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure ExtractZipFile(ZipFile.s, DestinationFolder.s)
Protected i, j, Result, R, FID_Zip, FID_Orig, *B1, *B2, *B3._ZIP_Unicode_Path_Extra_Field_
Protected FileName.s, PathAdd.s, Version.s, FileCount, FilesOK, *FileNameBuffer
Protected ZLFH._ZIP_Local_File_Header_
Protected STREAM.z_stream
If FileSize(ZipFile) > OffsetOf(_ZIP_Local_File_Header_\Filename) And FileSize(DestinationFolder) = -2
FID_Zip = ReadFile(#PB_Any, ZipFile)
If FID_Zip
Repeat
R = 0
ReadData(FID_Zip, @ZLFH, OffsetOf(_ZIP_Local_File_Header_\Filename))
If ZLFH\signature = $04034b50
FileName = ""
*FileNameBuffer = AllocateMemory(ZLFH\Filename_length + 2)
ReadData(FID_Zip, *FileNameBuffer, ZLFH\Filename_length)
If ZLFH\Generalflag & $800
FileName = PeekS(*FileNameBuffer, ZLFH\Filename_length, #PB_UTF8)
Else
FileName = PeekS(*FileNameBuffer, ZLFH\Filename_length, #PB_Ascii)
EndIf
FreeMemory(*FileNameBuffer)
If ZLFH\Extrafield_length
If *B3 = 0 Or MemorySize(*B3) < ZLFH\Extrafield_length
*B3 = ReAllocateMemory(*B3, ZLFH\Extrafield_length)
EndIf
ReadData(FID_Zip, *B3, ZLFH\Extrafield_length)
If *B3\signature = $7075
;This filename is also in utf8 available
FileName = PeekS(*B3 + OffsetOf(_ZIP_Unicode_Path_Extra_Field_\FileName), (*B3\Size & $FFFF) - 5, #PB_UTF8)
EndIf
EndIf
Debug FileName
PathAdd = ""
For i = 1 To CountString(FileName, "/")
PathAdd + StringField(FileName, i, "/") + "/"
If FileSize(DestinationFolder + PathAdd) <> -2
CreateDirectory(DestinationFolder + PathAdd)
EndIf
Next i
If Right(FileName, 1) <> "/"
FileCount + 1
FID_Orig = CreateFile(#PB_Any, DestinationFolder + FileName)
If FID_Orig
If ZLFH\Uncompressed_size = 0
R = #True
ElseIf *B2 = 0 Or MemorySize(*B2) < ZLFH\Uncompressed_size
*B2 = ReAllocateMemory(*B2, ZLFH\Uncompressed_size)
EndIf
If *B2
If ZLFH\Uncompressed_size = ZLFH\Compressed_size
;Not compressed!
R = #True
ReadData(FID_Zip, *B2, ZLFH\Uncompressed_size)
WriteData(FID_Orig, *B2, ZLFH\Uncompressed_size)
Else
If *B1 = 0 Or MemorySize(*B1) < ZLFH\Compressed_size
*B1 = ReAllocateMemory(*B1, ZLFH\Compressed_size)
EndIf
If *B1
Version = "1.2.5"
If inflateInit2_(@STREAM, -10, @Version, SizeOf(z_stream)) = #Z_OK
STREAM\adler = ZLFH\CRC32
STREAM\next_in = *B1
STREAM\next_out = *B2
STREAM\avail_out = ZLFH\Uncompressed_size
STREAM\avail_in = ReadData(FID_Zip, *B1, ZLFH\Compressed_size)
If inflate(@STREAM, #Z_FINISH) = #Z_STREAM_END
If CRC32Fingerprint(*B2, ZLFH\UnCompressed_size) = ZLFH\CRC32 & $FFFFFFFF
R = #True
WriteData(FID_Orig, *B2, ZLFH\Uncompressed_size)
EndIf
EndIf
inflateEnd(@STREAM)
EndIf
EndIf
EndIf
EndIf
CloseFile(FID_Orig)
EndIf
If R
SetFileDate(DestinationFolder + FileName, #PB_Date_Modified, MSDosDateToUnix(ZLFH\Last_modification))
FilesOK + 1
EndIf
EndIf
Else
Break
EndIf
Until Eof(FID_Zip)
CloseFile(FID_Zip)
EndIf
EndIf
If *B1
FreeMemory(*B1)
EndIf
If *B2
FreeMemory(*B2)
EndIf
If *B3
FreeMemory(*B3)
EndIf
If FileCount = FilesOK
Result = #True
EndIf
ProcedureReturn Result
EndProcedure
DataSection
__ZIP_Local_File_Header_:
Data.l $04034b50
Data.w $14, 0, 8
Data.l 0, 0, 0, 0
Data.w 0, 0
__ZIP_Data_Descriptor_:
Data.l $08074b50, 0, 0, 0
__ZIP_Central_Directory_File_Header_:
Data.l $02014b50
Data.w $14, $14, 0, 8
Data.l 0, 0, 0, 0
Data.w 0, 0, 0, 0, 0
Data.l 0, 0
__ZIP_End_of_central_directory_record_:
Data.l $06054b50
Data.w 0, 0, 1, 1
Data.l 0, 0
Data.w 0
EndDataSection
Gruß