ReadACE




Option Explicit

Private Type ACEBlockHead
HEAD_CRC As Integer
HEAD_SIZE As Integer
HEAD_TYPE As Byte
HEAD_FLAGS As Integer
End Type

Public Function InspectACEArchiveFast(sFile As String, _
ByRef lMilliSeconds As Long, _
ByRef lNumFiles As Long, _
ByRef dblUnpackedBytes As Double, _
lblArchive As Label) As Boolean
On Error GoTo ErrExit

Dim F As Long ' file handle
Dim lFileSize As Long ' size of file
Dim tBlockHead As ACEBlockHead ' Block-header
Dim bADDSIZEField As Boolean ' header contains ADDSIZE Field
Dim bMultVolume As Boolean ' indicated multiple volumne
Dim lHeadSize As Long ' size of Block-Header
Dim lADDSIZE As Long ' Value of ADDSIZE-Field
Dim lNextOffset As Long ' Offset of next Block-Header

Dim lVolNum As Long ' Number of current volume
Dim sFilename As String ' name of archive
Dim bReadNextArchive As Boolean ' to control loop

Dim lATTR As Long ' File-Attributes
Dim lUnpackedBytes As Long ' unpacked-bytes of file

' open exe-file

StartTimer

' copy Filename to local-variable cause it's changed

sFilename = sFile

' reset Volume-number

lVolNum = -1&

' loop over all files of multiple archive

Do
' start at file offset 0

lNextOffset = 0&

' get file-handle

F = FreeFile(1)

' open file

Open sFilename For Binary Access Read Shared As #F
' get size of file

lFileSize = LOF(F)

If lFileSize > 0 Then
If Not lblArchive Is Nothing Then
lblArchive.Caption = Mid$(sFilename, modIni.RInstr(sFilename, "\") + 1)
lblArchive.Refresh
End If
End If

' read all block-headers

Do While lNextOffset < lFileSize
If Not ReadBlockHead(F, tBlockHead, _
bADDSIZEField, _
bMultVolume) Then GoTo ErrExit

' convert header-size from unsigned integer to long

' if the 16-bit value HEAD_SIZE is greater than 32767

' VB interprets this a negative number

' Therefore the negative number is first converted into

' a Long via the CLng function. This results in a long

' negative number. The value is then masked to remove the

' high 16 bits. The result is a positive 16-bit number in

' a long variable

lHeadSize = (CLng(tBlockHead.HEAD_SIZE) And &HFFFF&)
If bADDSIZEField Then
' if ADDSIZE-Field is present read it

Get #F, , lADDSIZE

' and calculate the next header-offset

' HEAD_SIZE contains the total size of the header

' starting with the HEAD_TYPE field.

' Because we've already read the HEAD_TYPE and

' HEAD_FLAGS fields (3 bytes) and we also read

' the ADDSIZE field (4 bytes) we have the subtract

' 7 bytes from the total header size.

lNextOffset = Seek(F) + lHeadSize - 7& + lADDSIZE
Else
' Calculate the next header-offset

' HEAD_SIZE contains the total size of the header

' starting with the HEAD_TYPE field.

' Because we've already read the HEAD_TYPE and

' HEAD_FLAGS fields (3 bytes) we have the subtract

' 3 bytes from the total header size.

lNextOffset = Seek(F) + lHeadSize - 3&
End If

' do different things according to the block-type

Select Case tBlockHead.HEAD_TYPE
Case 0 ' Archive header
' set flag whether we have to read another volume-file

bReadNextArchive = bMultVolume

Case 1 ' file block
' ignore all files which are continued from a

' previous volume

If (tBlockHead.HEAD_FLAGS And &H1000) = 0 Then
' file continued flag not set

' read the file-header to get attributes and unpacked-sized

If Not ReadFileHead(F, tBlockHead, _
lATTR, _
lUnpackedBytes) Then GoTo ErrExit

' ignore directories

If lATTR <> vbDirectory Then
' count number of files and

' count unpacked bytes into a double variable

' A long may be to small to keep the value

dblUnpackedBytes = dblUnpackedBytes + CDbl(lUnpackedBytes)
lNumFiles = lNumFiles + 1
End If
End If

Case 2 ' recovery record
' ignore recovery record

' this is assumed to be at the end of the archive

' stop reading

lNextOffset = lFileSize
End Select

' set next read position to calculated offset

Seek #F, lNextOffset
Loop

' close this archive file

Close #F

If bReadNextArchive Then
' if this is a multiple volume build next volume name

' Cut off the extension and replace it with the next volume-number

lVolNum = lVolNum + 1
sFilename = Left$(sFilename, modIni.RInstr(sFilename, ".")) & _
"C" & Format(lVolNum, "00")
End If

' if the filename built above does not exist

' lFileSize will be 0

Loop While bReadNextArchive And lFileSize > 0

InspectACEArchiveFast = True

lMilliSeconds = MeasureTime
Exit Function

ErrExit:
ShowError

On Error Resume Next
Close #F
Exit Function
End Function

Private Function ReadBlockHead(F As Long, _
ByRef tBlockHead As ACEBlockHead, _
ByRef bADDSIZEField As Boolean, _
ByRef bMultVolume As Boolean) As Boolean
On Error GoTo ErrExit

Get #F, , tBlockHead

bADDSIZEField = CBool(tBlockHead.HEAD_FLAGS And &H1)
bMultVolume = CBool(tBlockHead.HEAD_FLAGS And &H800)

ReadBlockHead = True
Exit Function

ErrExit:
ShowError
Exit Function
End Function

Private Function ReadFileHead(F As Long, _
ByRef tBlockHead As ACEBlockHead, _
ByRef lATTR As Long, _
ByRef lUnpackedBytes As Long) As Boolean
On Error GoTo ErrExit

Dim sFNAME As String

Get #F, , lUnpackedBytes

' read the FTIME-Field into the lATTR variable

Get #F, , lATTR

' read the ATTR-Field into the lATTR variable

Get #F, , lATTR

ReadFileHead = True
Exit Function

ErrExit:
ShowError
Exit Function
End Function

' -------------------------------------------------------

' DLL- Version

' -------------------------------------------------------


Public Function InspectACEArchiveDLL(sFile As String, _
ByRef lMilliSeconds As Long, _
ByRef lNumFiles As Long, _
ByRef dblUnpackedBytes As Double, _
lblArchiv As Label) As Boolean
On Error GoTo ErrExit

Dim hArchive As Long
Dim tHeaderdata As ACEHEADERDATA
Dim lVolNum As Long
Dim sFilename As String
Dim bMultVolume As Boolean

StartTimer

sFilename = sFile
lVolNum = -1&

Do
hArchive = modAce.OpenACEArchive(sFilename, ACEOPEN_LIST, bMultVolume)
If hArchive = 0 Then Exit Do

While ACEReadHeader(hArchive, tHeaderdata) = 0
If Not lblArchiv Is Nothing Then
lblArchiv.Caption = modIni.LiesArchiv(tHeaderdata.Arcname)
lblArchiv.Refresh
End If

ACEProcessFile hArchive, ACECMD_SKIP, vbNull
If (tHeaderdata.flags And &H1000) = 0 Then
' file continued flag not set

If tHeaderdata.FileAttr <> vbDirectory Then
lNumFiles = lNumFiles + 1&
dblUnpackedBytes = dblUnpackedBytes + tHeaderdata.UnpSize
End If
End If
Wend

ACECloseArchive hArchive

If bMultVolume Then
lVolNum = lVolNum + 1
sFilename = Left$(sFilename, modIni.RInstr(sFilename, ".")) & _
"C" & Format(lVolNum, "00")
End If
Loop While bMultVolume

InspectACEArchiveDLL = True

lMilliSeconds = MeasureTime

Exit Function

ErrExit:
ShowError

On Error Resume Next
ACECloseArchive hArchive
Exit Function
End Function




##################################################################
EntPacker für Ace, Rar, Zip
Copyright Emil Weiss
für Testzwecke freigestellt
emil.weiss@koeln.netsurf.de
http://koeln.netsurf.de/~emil.weiss (Only IE4 or later)
##################################################################











( readace.html )- by Paolo Puglisi - Modifica del 17/12/2023