Attribute VB_Name = "MTKUnrar" Option Explicit Const RAR_DLL_VERSION As Integer = 2 Const RAR_CONTINUE As Integer = 1 Const RAR_ABORT As Integer = -1 Public Enum ERAR ERAR_END_ARCHIVE = 10 ERAR_NO_MEMORY ERAR_BAD_DATA ERAR_BAD_ARCHIVE ERAR_UNKNOWN_FORMAT ERAR_EOPEN ERAR_ECREATE ERAR_ECLOSE ERAR_EREAD ERAR_EWRITE ERAR_SMALL_BUF ' Private error definitions ERAR_DEST_ARR_TO_SMALL = 5000 ERAR_UNKNOWN_DESTINATION ERAR_UNKNOWN_ERROR End Enum Public Enum RAR_OM RAR_OM_LIST = 0 RAR_OM_EXTRACT End Enum Public Enum RAR RAR_SKIP = 0 RAR_TEST RAR_EXTRACT End Enum Public Enum UCM UCM_CHANGEVOLUME = 0 UCM_PROCESSDATA UCM_NEEDPASSWORD End Enum Public Enum RAR_VOL RAR_VOL_ASK = 0 RAR_VOL_NOTIFY End Enum Public Enum RarOperations OP_EXTRACT = 0 OP_TEST OP_LIST End Enum Public Type RARHeaderData ArcName As String * 260 FileName As String * 260 flags As Long PackSize As Long UnpSize As Long HostOS As Long FileCRC As Long FileTime As Long UnpVer As Long Method As Long FileAttr As Long CmtBuf As String CmtBufSize As Long CmtSize As Long CmtState As Long End Type Public Type RARHeaderDataEx ArcName As String * 1024 ArcNameW As String * 2048 FileName As String * 1024 FileNameW As String * 2048 flags As Long PackSize As Long PackSizeHigh As Long UnpSize As Long UnpSizeHigh As Long HostOS As Long FileCRC As Long FileTime As Long UnpVer As Long Method As Long FileAttr As Long CmtBuf As String CmtBufSize As Long CmtSize As Long CmtState As Long Reserved(1024) As Integer End Type Public Type RAROpenArchiveData ArcName As String OpenMode As Long OpenResult As Long CmtBuf As String CmtBufSize As Long CmtSize As Long CmtState As Long End Type Public Declare Function RAROpenArchive Lib "unrar.dll" (ByRef ArchiveData As RAROpenArchiveData) As Long Public Declare Function RARCloseArchive Lib "unrar.dll" (ByVal hArcData As Long) As Long Public Declare Function RARReadHeader Lib "unrar.dll" (ByVal hArcData As Long, ByRef HeaderData As RARHeaderData) As Long Public Declare Function RARReadHeaderEx Lib "unrar.dll" (ByVal hArcData As Long, ByRef HeaderData As RARHeaderDataEx) As Long Public Declare Function RARProcessFile Lib "unrar.dll" (ByVal hArcData As Long, ByVal Operation As Long, ByVal DestPath As String, ByVal DestName As String) As Long Public Declare Sub RARSetCallback Lib "unrar.dll" (ByVal hArcData As Long, ByVal CallbackProc As Long, ByVal UserData As Long) Public Declare Sub RARSetPassword Lib "unrar.dll" (ByVal hArcData As Long, ByVal Password As String) Public Declare Function RARGetDllVersion Lib "unrar.dll" () As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long) Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long ' Public Function MakeDouble(ByVal HiWord As Long, ByVal LoWord As Long) As Double MakeDouble = CDbl(LoWord) + CDbl(HiWord) * 4294967296# End Function Public Function MyCallBack(ByVal msg As Long, ByVal UserData As Long, ByVal P1 As Long, ByVal P2 As Long) As Integer Dim strPassword As String Dim strNewVolume As String If msg = UCM_CHANGEVOLUME Then If P2 = RAR_VOL_ASK Then strNewVolume = CallFunctionFromUserdata(UserData).FindMissingFile(PointerToStringA(P1)) & Chr(0) If Len(strNewVolume) > 1 Then CopyMemory ByVal P1, ByVal StrPtr(StrConv(strNewVolume, vbFromUnicode)), Len(strNewVolume) MyCallBack = RAR_CONTINUE Else MyCallBack = RAR_ABORT End If ElseIf P2 = RAR_VOL_NOTIFY Then If CallFunctionFromUserdata(UserData).NextVolume(PointerToStringA(P1)) Then MyCallBack = RAR_CONTINUE Else MyCallBack = RAR_ABORT End If End If ElseIf msg = UCM_PROCESSDATA Then Call CallFunctionFromUserdata(UserData).ProcessingLength(P2) ' Debug.Print "Size of data = " & P2 ' Debug.Print HexDump(P1, P2) MyCallBack = RAR_CONTINUE ElseIf msg = UCM_NEEDPASSWORD Then strPassword = CallFunctionFromUserdata(UserData).MissingPassword() & Chr(0) If Len(strPassword) = 1 Then ' If the user supplies an empty password, we have to generate a fake one, else we ' won't receieve a CRC error message from RARProcessFile. Bug? strPassword = "CTKUnrar" & Now() & Chr(0) End If CopyMemory ByVal P1, ByVal StrPtr(StrConv(strPassword, vbFromUnicode)), IIf(Len(strPassword) > P2, P2, Len(strPassword)) Else Debug.Print "Unknown msg" End If End Function ' resolve the passed object pointer into an object reference. ' DO NOT PRESS THE "STOP" BUTTON WHILE IN THIS PROCEDURE! Private Function CallFunctionFromUserdata(ByVal UserData As Long) As CTKUnrar Dim CwdEx As CTKUnrar CopyMemory CwdEx, UserData, 4& Set CallFunctionFromUserdata = CwdEx CopyMemory CwdEx, 0&, 4& End Function Public Function PointerToStringW(ByVal lpString As Long) As String Dim sText As String Dim lLength As Long If lpString Then lLength = lstrlenW(lpString) If lLength Then sText = Space$(lLength) CopyMemory ByVal StrPtr(sText), ByVal lpString, lLength * 2 End If End If PointerToStringW = sText End Function Public Function IsUnicode(s As String) As Boolean IsUnicode = Not (Len(s) = LenB(s)) End Function Public Function PointerToStringA(lpStringA As Long) As String Dim Buffer() As Byte Dim nLen As Long If lpStringA Then nLen = lstrlenA(ByVal lpStringA) If nLen Then ReDim Buffer(0 To (nLen - 1)) As Byte CopyMemory Buffer(0), ByVal lpStringA, nLen PointerToStringA = StrConv(Buffer, vbUnicode) End If End If End Function Public Function PointerToDWord(ByVal lpDWord As Long) As Long Dim nRet As Long If lpDWord Then CopyMemory nRet, ByVal lpDWord, 4 PointerToDWord = nRet End If End Function Private Function HexDump(ByVal lpBuffer As Long, ByVal nBytes As Long) As String Dim i As Long, j As Long Dim ba() As Byte Dim sRet As String Dim dBytes As Long ' Size recieving buffer as requested, ' then sling memory block to buffer. ReDim ba(0 To nBytes - 1) As Byte Call CopyMemory(ba(0), ByVal lpBuffer, nBytes) sRet = String(81, "=") & vbCrLf & _ "lpBuffer = &h" & Hex$(lpBuffer) & _ " nBytes = " & nBytes ' Buffer may well not be even multiple of 16. ' If not, we need to round up. If nBytes Mod 16 = 0 Then dBytes = nBytes Else dBytes = ((nBytes \ 16) + 1) * 16 End If ' Loop through buffer, displaying 16 bytes per ' row. Preface with offset, trail with ASCII. For i = 0 To (dBytes - 1) ' Add address and offset from beginning ' if at the start of new row. If (i Mod 16) = 0 Then sRet = sRet & vbCrLf & Right$("00000000" _ & Hex$(lpBuffer + i), 8) & " " & _ Right$("0000" & Hex$(i), 4) & " " End If ' Append this byte. If i < nBytes Then sRet = sRet & Right$("0" & Hex(ba(i)), 2) Else sRet = sRet & " " End If ' Special handling... If (i Mod 16) = 15 Then ' Display last 16 characters in ' ASCII if at end of row. sRet = sRet & " " For j = (i - 15) To i If j < nBytes Then If ba(j) >= 32 And ba(j) <= 126 Then sRet = sRet & Chr$(ba(j)) Else sRet = sRet & "." End If End If Next j ElseIf (i Mod 8) = 7 Then ' Insert hyphen between 8th and ' 9th bytes of hex display. sRet = sRet & "-" Else ' Insert space between other bytes. sRet = sRet & " " End If Next i HexDump = sRet & vbCrLf & String(81, "=") & vbCrLf End Function