Jump to content

UnRAR.au3


rasim
 Share

Recommended Posts

Ok. I searched solution about how to unpack *.rar archive programmaticaly without console Rar.exe utility. And i found the freeware unrar.dll library. Hope this will be useful for you. muttley

UnRAR.au3

Latest unrar.dll library

Also you may download latest unrar.dll and help file from the official site

Common features:

Unicode support

Archive testing

Archive comment getting

Unpacking cancelling

Archive decryption

Next volume changing

Edit:

Fixed some bugs.

License

The unrar.dll library is freeware. This means:

   1. All copyrights to RAR and the unrar.dll are exclusively
      owned by the author - Alexander Roshal.

   2. The unrar.dll library may be used in any software to handle RAR
      archives without limitations free of charge.

   3. THE RAR ARCHIVER AND THE UNRAR.DLL LIBRARY ARE DISTRIBUTED "AS IS".
      NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.  YOU USE AT 
      YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, 
      DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
      OR MISUSING THIS SOFTWARE.

      Thank you for your interest in RAR and unrar.dll.


                                            Alexander L. Roshal

unrar.zip

unrarudf.zip

Edited by rasim
Link to comment
Share on other sites

  • 1 year later...
  • 3 weeks later...
  • 2 months later...
  • 8 months later...

Sry, but something is wrong with the example - using an password protected archive I get "unpack successfull", no mather what password I use (Of course it is NOT beeing unpacked.....

Im also interested in this, how can u tell if entered pass was good or bad?

Edit: Okey you cant really restore passwords if u happen to lost yours, cuz its speed is around 5 passwords in 1 sec. from password list. But to use it for files U already have passwords, it will do the job just fine. to check for wrong pass u can compare dir size before & after unpacking.

I made a small gui to easily drag & drop all files into it & they will be extracted in the same folder.

Usage: Define a file that contains all your passwords. it will loop until it finds the right pass & then extracts files.

Info :Does not perform the file integrity check. you can add it yourself if u want. in case someone gets confused by the pass file thing: imagine you have load of files in 1 folder all compressed say with 2 , 3 different passwords. Now imagine the pain extracting it. so we take all passwords, put them into 1 file & let gui search for the correct pass.

Posted Image

#cs ----------------------------------------------------------------------------
 AutoIt Version: 3.3.6.1
 GUI Author:         goldenix
 
 http://www.autoitscript.com/forum/index.php?showtopic=76176&view=findpost&p=835654

 Script Function: Drag & drop files into gui , they will be extracted, 
 does not capture part 2, part,3 etc..so u can safely drop all selected files into gui
#ce ----------------------------------------------------------------------------
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <StaticConstants.au3>
#include <StatusBarConstants.au3>
#include <WindowsConstants.au3>
#include <UnRAR.au3>
#include <file.au3>

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode

Global $StatusBar1, $GUI = 'UnRAR Gui 1.0'
Global $_PAsswords = @ScriptDir & '\Passwords.txt'
Global $Cancel = False
Global $passwords[1]

;~ HotKeySet("{Esc}", "_CancelUnpack")
HotKeySet("{Esc}", "_exit")


#Region ### START Koda GUI section ### Form=E:\temp_\unrar\UnRAR.kxf
$Form1_1 = GUICreate($GUI, 210, 166, 193, 115, -1,$WS_EX_ACCEPTFILES)
$Group1 = GUICtrlCreateGroup("Drop Files Hire:", 8, 56, 193, 81)
GUICtrlCreateGroup("", -99, -99, 1, 1)
$StatusBar1 = _GUICtrlStatusBar_Create($Form1_1)
$Button1 = GUICtrlCreateButton("Edit Passwordlist", 8, 8, 192, 25, 0)
WinSetOnTop($GUI,'',1)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; events
GUIRegisterMsg(0x233, "On_WM_DROPFILES")
GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")

GUICtrlSetOnEvent($Button1, "Button1")

;~ =========================================================================================
;## REad passwords to array
    If Not _FileReadToArray($_PAsswords ,$passwords) Then
        MsgBox(4096,"Error", " Error reading passwords to Array     error:" & @error)
        Exit
    EndIf
;~ =========================================================================================
Func _uncompress($ze_File)

    $split = StringSplit($ze_File,'\')

    $filepath = StringReplace($ze_File,$split[$split[0]],'')    ; Filepath
    $Filename = $split[$split[0]]                           ; Filename

    If StringInStr($Filename,'.part1.rar') Or Not StringInStr($Filename,'.part') Then

        ConsoleWrite($Filename & @CRLF)

        _GUICtrlStatusBar_SetText ($StatusBar1, "working.." & StringRight($Filename,30))

        $ArchiveFile = $ze_File
        $OutputFolder = $filepath

        For $xxx = 1 to $passwords[0]

            $begin = TimerInit()

            $size_0 = DirGetSize($OutputFolder)
            $size_0 = Round($size_0 / 1024 / 1024) ; MB
            ConsoleWrite($size_0 & ' MB' & @CRLF)

            ;Creates a user-defined DLL Callback function to process Unrar events
            $hUnRAR_CallBack = DllCallbackRegister("_UnRARProc", "int", "uint;int;int;int")

            $hArchive = _RAR_OpenArchive($ArchiveFile)
            If @error Then
                MsgBox(16, "UnRAR", "Archive open error")
                Exit
            EndIf

            ;Set a password to decrypt files
            _RAR_SetPassword($hArchive, $passwords[$xxx])
            ConsoleWrite($passwords[$xxx] & '   ')

            ;Set a user-defined callback function to process Unrar events
            _RAR_SetCallback($hArchive, $hUnRAR_CallBack)

            ;Read header of file in archive, performs action and moves the current position in the archive to the next file
            ;Also extract or test the current file from the archive
            $_Rar_UnpackArchive = _Rar_UnpackArchive($hArchive, $OutputFolder)
            If @error Then
                MsgBox(16, "UnRAR", "Archive unpacking error")
                Exit
            EndIf

            If $Cancel = True Then
                MsgBox(64, "UnRAR", "Unpacking cancelled")
            Else
        ;~      MsgBox(64, "Done", "Archive unpacked")
            EndIf

            DllCallbackFree($hUnRAR_CallBack)

            $dif = TimerDiff($begin)
            ConsoleWrite($dif/1000 & '  sec.' & @CRLF) ; in seconds

            $size_1 = DirGetSize($OutputFolder)
            $size_1 = Round($size_1 / 1024 / 1024) ; MB
            ConsoleWrite($size_1 & ' MB' & @CRLF)

            If $size_1 <> $size_0 then ExitLoop
        Next

        _GUICtrlStatusBar_SetText ($StatusBar1, "Done!")

    EndIf
EndFunc
;~ =================================================================================
Func _CancelUnpack()
    $Cancel = True
EndFunc
;~ =================================================================================
Func _UnRARProc($Msg, $UserData, $P1, $P2)
    Switch $Msg
        Case $UCM_PROCESSDATA ;Return a positive value to continue process or -1 to cancel the archive operation
            If $Cancel = True Then Return -1
        Case $UCM_NEEDPASSWORD ;DLL needs a password to process archive
            Local $iPassGet = InputBox("Password required", "Please type a password", "", "*", 300, 120)
            If $iPassGet = "" Then Return -1 ;If user cancelled password entering
            Local $PassBuffer = DllStructCreate("char[256]", $P1)
            DllStructSetData($PassBuffer, 1, $iPassGet)
            Return 1
        Case $UCM_CHANGEVOLUME ;Process volume change
            If $P2 = $RAR_VOL_ASK Then ;Required volume is absent
                Local $iVolGet = InputBox("Next volume required", "Please type a path to the next volume", "", "", 300, 120)
                If $iVolGet = "" Then Return -1 ;If user cancelled path entering
                Local $VolBuffer = DllStructCreate("char[256]", $P1)
                DllStructSetData($VolBuffer, 1, $iVolGet)
                Return 1
            EndIf
    EndSwitch
EndFunc
;~ =================================================================================
Func On_WM_DROPFILES($hWnd, $Msg, $wParam, $lParam)
    Local $tDrop, $aRet, $iCount
    ;string buffer for file path
    $tDrop = DllStructCreate("char[260]")
    ;get file count
    $aRet = DllCall("shell32.dll", "int", "DragQueryFile", _
                                            "hwnd", $wParam, _
                                            "uint", -1, _
                                            "ptr", DllStructGetPtr($tDrop), _
                                            "int", DllStructGetSize($tDrop) _
                                            )
    $iCount = $aRet[0]
    ;get file paths
    For $i = 0 To $iCount-1
        $aRet = DllCall("shell32.dll", "int", "DragQueryFile", _
                                                "hwnd", $wParam, _
                                                "uint", $i, _
                                                "ptr", DllStructGetPtr($tDrop), _
                                                "int", DllStructGetSize($tDrop) _
                                                )

        $ze_File = DllStructGetData($tDrop, 1)
        _uncompress($ze_File)
    Next
    ;finalize
    DllCall("shell32.dll", "int", "DragFinish", "hwnd", $wParam)
    Return
EndFunc
;~ =================================================================================
Func Button1()
    ShellExecute($_PAsswords)
EndFunc
;~ =================================================================================
Func _exit()
    _CancelUnpack()
  Exit
EndFunc
;~ =================================================================================

While 1
  Sleep(100)  ; Idle around
WEnd
Edited by goldenix
My Projects:[list][*]Guide - ytube step by step tut for reading memory with autoitscript + samples[*]WinHide - tool to show hide windows, Skinned With GDI+[*]Virtualdub batch job list maker - Batch Process all files with same settings[*]Exp calc - Exp calculator for online games[*]Automated Microsoft SQL Server 2000 installer[*]Image sorter helper for IrfanView - 1 click opens img & move ur mouse to close opened img[/list]
Link to comment
Share on other sites

  • 4 weeks later...

Hi,

thanks for sharing this little UDF, it's just what i was looking for.

But i wonder how this UDF can work flawlessly on all of your machines, because there is a fatal bug in UnRAR.au3 !

The symptoms are that when unpacking, testing or just listing the files inside an archive ONLY the first file of the archive is listed and it will neither be tested nor extracted (depending on operation mode).

I've spent some time to debug that issue and the solution is amazing easy:

- for opening the archive you use the unicode version RAROpenArchiveEx of the 2 available dll functions which is OK

- for reading the contents of the archive you use the standard function RARReadHeader instead of the unicode version RARReadHeaderEx

- even this would be OK if you had then also used the standard version of RARProcessFile instead of RARProcessFileW (in Func _RAR_ProcessFile)

I don't know if this is only an issue with the latest unrar.dll I'm using or actually a very small (just one "W") but annoying mistake in UnRAR.au3 but I wanted to share my debugging results just in case others also have this problem.

I am including a modified (and working) version of your Example.au3 with direct dll calls and some debug msgs, just add the "W" after RARProcessFile in line 57 to see the difference (files will always be extracted to current dir).

#include <UnRAR.au3>

Global $Cancel = False
Local $RARHeaderData, $sFileOper, $aRet
Const $ERAR_END_ARCHIVE = 10

HotKeySet("{Esc}", "_CancelUnpack")

$ArchiveFile = FileOpenDialog("Select the archive file", @MyDocumentsDir, "Archive files (*.rar)")

;Set a password to decrypt files
;_RAR_SetPassword($hArchive, "MyPassword")

;Returns an integer value denoting UnRAR.dll API version
;_RAR_GetDllVersion()

;Creates a user-defined DLL Callback function to process Unrar events
$hUnRAR_CallBack = DllCallbackRegister("_UnRARProc", "int", "uint;int;int;int")

;Open RAR archive and allocate memory structures
$hArchive = _OpenArchive($ArchiveFile, 0, $RAR_OM_EXTRACT)
If @error Then
    MsgBox(16, "UnRAR", "Archive open error")
    Exit
EndIf

;Read header of file in archive, performs action and moves the current position in the archive to the next file
;Also extract or test the current file from the archive

$sFileOper = $RAR_EXTRACT

$RARHeaderData = DllStructCreate("char ArcName[260];char FileName[260];uint Flags;uint PackSize;uint UnpSize;uint HostOS;" & _
        "uint FileCRC;uint FileTime;uint UnpVer;uint Method;uint FileAttr;char CmtBuf;" & _
        "uint CmtBufSize;uint CmtSize;uint CmtState")

;Set a user-defined callback function to process Unrar events
_RAR_SetCallback($hArchive, $hUnRAR_CallBack)

Do
    $aRet = DllCall($hDll, "int", "RARReadHeader", "hwnd", $hArchive, "ptr", DllStructGetPtr($RARHeaderData))

    If DllStructGetData($RARHeaderData, "CmtState") > 1 Then
        DllCall($hDll, "int", "RARCloseArchive", "hwnd", $hArchive)
        MsgBox(16, "RARReadHeader", "Reading archive header FAILED !")
        Exit
    EndIf

    If $aRet[0] = 0 Then
        $ArcName = DllStructGetData($RARHeaderData, "ArcName")
        $FileName = DllStructGetData($RARHeaderData, "FileName")
        $PackSize = DllStructGetData($RARHeaderData, "PackSize")
        $UnpSize = DllStructGetData($RARHeaderData, "UnpSize")
        $UnpVer = DllStructGetData($RARHeaderData, "UnpVer")

        MsgBox(64, "RARReadHeader result:", $aRet[0] & " | " & $sFileOper & " | " & $ArcName & " | " & $FileName & " | " & $PackSize & " | " & $UnpSize & " | " & $UnpVer)

        $res = DllCall($hDll, "int", "RARProcessFile", "hwnd", $hArchive, "int", $sFileOper, "ptr", 0, "ptr", 0)
        MsgBox(64, "RARProcessFile:", $res[0] & ": must be 0 for success !")
    EndIf

Until $aRet[0] <> 0

If $aRet[0] = $ERAR_END_ARCHIVE Then MsgBox(64, "RARReadHeader:", $aRet[0] & ": normally terminated due to end of archive !")

If @error Then
    MsgBox(16, "UnRAR", "Archive unpacking error code " & @error)
    Exit
EndIf

If $Cancel = True Then
    MsgBox(64, "UnRAR", "Unpacking cancelled")
Else
    MsgBox(64, "Done", "Archive unpacked")
EndIf

DllCallbackFree($hUnRAR_CallBack)

;Close RAR archive and release allocated memory
_RAR_CloseArchive($hArchive)

Func _CancelUnpack()
    $Cancel = True
EndFunc   ;==>_CancelUnpack

Func _UnRARProc($Msg, $UserData, $P1, $P2)
    Switch $Msg
        Case $UCM_PROCESSDATA ;Return a positive value to continue process or -1 to cancel the archive operation
            If $Cancel = True Then Return -1
        Case $UCM_NEEDPASSWORD ;DLL needs a password to process archive
            Local $iPassGet = InputBox("Password required", "Please type a password", "", "*", 300, 120)
            If $iPassGet = "" Then Return -1 ;If user cancelled password entering
            Local $PassBuffer = DllStructCreate("char[256]", $P1)
            DllStructSetData($PassBuffer, 1, $iPassGet)
            Return 1
        Case $UCM_CHANGEVOLUME ;Process volume change
            If $P2 = $RAR_VOL_ASK Then ;Required volume is absent
                Local $iVolGet = InputBox("Next volume required", "Please type a path to the next volume", "", "", 300, 120)
                If $iVolGet = "" Then Return -1 ;If user cancelled path entering
                Local $VolBuffer = DllStructCreate("char[256]", $P1)
                DllStructSetData($VolBuffer, 1, $iVolGet)
                Return 1
            EndIf
    EndSwitch
EndFunc   ;==>_UnRARProc

For those who want to process unicode files only: you have to use RARReadHeaderEx and you must also create an RARHeaderDataEx structure which is neither included in UnRAR.au3 nor in my Example.au3.

Hope this is helpful for somebody, greetings,

MasterOaC

Link to comment
Share on other sites

  • 7 months later...

Scuse me MasterOaC but in your example what I must modify to choose the output folder instead the current folder ?

PS : Sorry for my english I'm French.

The DLL-Call in line 57 must be modified like this:

$res = DllCall($hDll, "int", "RARProcessFile", "hwnd", $hArchive, "int", $sFileOper, "ptr", DllStructGetPtr($sDestPath), "ptr", DllStructGetPtr($sDestName))

; Parameter....: $sDestPath - 
; This parameter should point to a zero terminated string containing the 
; destination directory to which to extract files to. If DestPath is equal 
; to NULL, it means extract to the current directory. This parameter has 
; meaning only if DestName is NULL. 

; $sDestName
;  This parameter should point to a string containing the full path and name
;  to assign to extracted file or it can be NULL to use the default name.
;  If DestName is defined (not NULL), it overrides both the original file
;  name saved in the archive and path specified in DestPath setting. 

;  Both DestPath and DestName must be in OEM encoding. If necessary,
;  use CharToOem to convert text to OEM before passing to this function.
Link to comment
Share on other sites

  • 2 years later...

I needed to use this script.
I would like to say

Thank you

It works even on the current version of AutoIt 3.3.12.0

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...