AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Extract from Rar 0.75 + 0.90
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Sat Nov 10, 2007 10:57 pm    Post subject: Extract from Rar 0.75 + 0.90 Reply with quote

I hope this comes in handy for someone, I'm still working on it hopefully more features to come yet. But heres the basic function.

Code:
ExtractRAR(File,ExPath = "",ExPaths = 1,Pass = ""){
  If (ExPath = ""){
    ExPath:=A_workingdir
  }
  varsetcapacity(ArchiveData,32,0)
  Numput(&File,ArchiveData)
  Numput(1,ArchiveData,4)
  hModule := DllCall("LoadLibrary", "str", "unrar.dll")
  if (!hModule) {
    Msgbox,Could not Load Library
    Return
  }
  hArchive:=DLLCall("unrar.dll\RAROpenArchive","Uint",&ArchiveData)
  if (password != ""){
    DLLCall("unrar.dll\RARSetPassword","UInt",hArchive,"uint",&password)
    }
  Varsetcapacity(ArchiveHeader,572,0)
  Loop
  {
    FileResult:=DLLCall("unrar.dll\RARReadHeader","UInt",hArchive,"Uint",&ArchiveHeader)
    If (FileResult = 12){
      MsgBox,File Header Currupt - Incorrect Password????
      Return
    }
    Else If (FileResult = 10){
      Break
    }
    Varsetcapacity(CurFile,260,0)
    DllCall("lstrcpynA", "Str", CurFile, "UInt", &ArchiveHeader+260,   "int", 260)
    If (substr(ExPath,0,1) != "\"){
      Expath.="\"
    }
    If (ExPaths){
      File:=ExPath . CurFile
    }
    Else {
      File:=ExPath . Regexreplace(CurFile,".*\\","")
    }
    ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)
    If (ExResult != 0){
      MsgBox,Error Extracting File
      Return
    }
  }
  DLLCall("unrar.dll\RARCloseArchive","Uint",hArchive)
  DllCall("FreeLibrary ", "UInt", hModule)
  Return
}


It requires Unrar.dll unrar.dll.

Just the DLL or The full package

Usage Is ExtractRAR(RarFile,[ExtractionPath,ExtractPaths,Password])

Define Rarfile as the file you wish to extract.
Extraction Path where you want to extract to. (Leave Blank to default to working Dir)
ExtractPaths - Set to 1 if you wish to extract full paths from the Archive, 0 if not. (Leave Blank to Extract Paths)
Password, Enter a password if the Rar requires it.

The only Required parameter is Filename, but as with all functions if you want to define one of the later two fields, you have to define all fields before it.


Version 0.90
Code:
ExtractRAR(File,ExPath = "",ExPaths = 1,ShowProg = 0){
  Global Prog,UnpackedFS
  If (ExPath = ""){
    ExPath:=A_workingdir
  }
  Fname:=File
  varsetcapacity(ArchiveData,32,0)
  Numput(&File,ArchiveData)
  Numput(1,ArchiveData,4)
  hModule := DllCall("LoadLibrary", "str", "unrar.dll")
  if (!hModule) {
    MsgBox , 262160 , %A_ScriptName% ,Could not Load Library
    Return
  }
  hArchive:=DLLCall("unrar.dll\RAROpenArchive","Uint",&ArchiveData)
  Result:=Numget(&ArchiveData,8)
  If (Result = 11){
    MsgBox , 262160 , %A_ScriptName% ,Not enough Memory
    Return
  }
  Else if (Result = 12){
    MsgBox , 262160 , %A_ScriptName% ,Archive Header Broken
    Return
  }
  Else If (Result = 13){
    MsgBox , 262160 , %A_ScriptName% ,Invalid Archive Type
    Return
  }
  Else IF (Result = 14){
    MsgBox , 262160 , %A_ScriptName% ,Unknown encryption
    Return
  }
  Else If (Result = 15){
    MsgBox , 262160 , %A_ScriptName% ,Error Opening File
    Return
  }
  If (ShowProg){
    Address:=registercallback("RarCallback","",4,1)
    If (Address = ""){
      Msgbox , 262160 , %A_ScriptName% , Error extracting archive!`n`nReturned adress to machine-code function was empty.
    }
  }
  Else {
    Address:=registercallback("RarCallback","",4,0)
    If (Address = ""){
      Msgbox , 262160 , %A_ScriptName% , Error extracting archive!`n`nReturned adress to machine-code function was empty.
    }
  }
  DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0)
  Varsetcapacity(ArchiveHeader,572,0)
  Loop
  {
    FileResult:=DLLCall("unrar.dll\RARReadHeader","UInt",hArchive,"Uint",&ArchiveHeader)
    If (FileResult = 12){
      MsgBox , 262160 , %A_ScriptName% ,File Header Currupt - Incorrect Password????
      Return
    }
    Else If (FileResult = 10){
      Break
    }
    Varsetcapacity(CurFile,260,0)
    DllCall("lstrcpynA", "Str", CurFile, "UInt", &ArchiveHeader+260,   "int", 260)
    UnpackedFS:=Numget(&ArchiveHeader,528)
    If (ShowProg){
      Progress,A R0-%UnpackedFS% M P0 w500,Current File %CurFile%,Extracting From %Fname%,Extraction in progress...
      Prog:=0
      Sleep,100
    }
    If (substr(ExPath,0,1) != "\"){
      Expath.="\"
    }
    If (ExPaths){
      File:=ExPath . CurFile
    }
    Else {
      File:=ExPath . Regexreplace(CurFile,".*\\","")
    }
    ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)
    If (ExResult != 0){
      MsgBox , 262160 , %A_ScriptName% ,Error Extracting File
      Return
    }
  }
  Progress,Off
  DLLCall("unrar.dll\RARCloseArchive","Uint",hArchive)
  DllCall("FreeLibrary ", "UInt", hModule)
  Return
}

RarCallback(Message,User,P1,P2){
  Global Prog
  If (Message = 1 and a_eventinfo = 1){
    Prog+=P2
    Progress,%Prog%
  }
  If (Message = 2){
    Inputbox,password
    DllCall("lstrcpynA","Uint",P1+0, "STR",Password,"int", P2)
  }
  return,1
}



The updated version 0.85 has a slightly different calling method.

Usage Is ExtractRAR(RarFile,[ExtractionPath,ExtractPaths,Showprogress])

The main difference in calling is password has been replace with the option to show a progress bar. If a password is needed for the file you will be prompted for one.



As usual, Comments, Suggestions, Questions etc, welcome.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle


Last edited by Superfraggle on Mon Mar 31, 2008 7:07 pm; edited 5 times in total
Back to top
View user's profile Send private message MSN Messenger
tic



Joined: 22 Apr 2007
Posts: 1375

PostPosted: Sun Nov 11, 2007 3:53 am    Post subject: Reply with quote

thanks superfraggle. This will come in very handy. Especially when you wish to pack many files in various folders into an exe. I had been working on using lazslos binary read/write and making my own compressed archive, but i guess its not needed now Rolling Eyes

For those interested heres the license (can be used in any application, even if you wish to sell it):

Quote:
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
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Mon Nov 12, 2007 2:18 am    Post subject: Reply with quote

Code Further updated. Call back added and option to use progress bar, comments, questions, bugs etc, let me know.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Mon Mar 31, 2008 12:42 am    Post subject: Reply with quote

to 0.85:

1.) with 0.85 i only got the folder structure extracted without the files inside - what is wrong? 0.75 works perfect for me, but the progress bar would be really cool =)

2.) if i set the archive file to C:\Windows\explorer.exe or whatever i want, i never get an error like
"Invalid Archive Type" , "Archive Header Broken" or "Error Opening File", but everytime i get "Error Extracting File"

3.) change all msgboxes to
MsgBox , 262160 , %A_ScriptName% , Error Extracting File!
or at least add ontop-feature cause they appear under the progress bar.

4.) the progress bar should be wider by default cause in a lot cases you have longer pathes

5.) there is a part:
Code:
Loop
{
   ...
   Progress , R0-%UnpackedFS% P0 w500 , Current File %CurFile% , Extracting From %File% , Extraction in progress...
   ...
   If (ExPaths){
      File:=ExPath . CurFile
   }
   Else {
      File:=ExPath . Regexreplace(CurFile , ".*\\" , "")
   }
   ...
}
so if file := expath . curfile and we are extracting from %file%, then we extract from the output file? or is it my linguistic error in reasoning?

edit:
6.)
i've found the problem:
Code:
If (ShowProg){
   Address:=RegisterCallBack("RarCallback" , "" , 4 , 1)
   If (Adress = "")
      Msgbox , 262160 , %A_ScriptName% , Error extracting archive!`n`nReturned adress to machine-code function was empty.

}
Else {
   Address:=RegisterCallBack("RarCallback" , "" , 4 , 0)
   If (Adress = "")
      Msgbox , 262160 , %A_ScriptName% , Error extracting archive!`n`nReturned adress to machine-code function was empty.

}
DLLCall("unrar.dll\RARSetCallback" , "UInt" , hArchive , "Uint" , Address , "Uint" , 0)

so the ahk_help tells us:
Failure occurs when FunctionName:

1) does not exist;
--> RarCallback(Message,User,P1,P2) exist

2) accepts too many or too few parameters according to ParamCount;
-> RarCallback(Message,User,P1,P2)
RegisterCallBack("RarCallback" , "" , 4 , 1)
seems to be ok

3) accepts any ByRef parameters.
--> RarCallback(Message , User , P1 , P2) has no ByRef parameters

so whats the problem =(
is it a problem with windows vista oO?
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Mon Mar 31, 2008 7:06 pm    Post subject: Reply with quote

Thanks ladiko I have updated it some more. see above.

1) There is a slight bug where if you dont tell it to extract paths, it will extract all the files to the extraction path, but it will also extract all the folders from the archive too. (Ensure you set extractpaths to 1 for now). I will look into this later.

2)I was pulling the wrong number out the structure, This has now been fixed and the correct error is shown.

3) The progress bar, and message boxes have been adjusted to allows easier use.

4) This has been changed too.

5) At the start of the function that variable is the name of the rarfile, however I reused it later and it becomes the current file. This has now been adjusted slightly.

6) I'm not entirely sure what problems you were having with the callback, but I've added the exceptions in there just in case.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Mon Mar 31, 2008 9:42 pm    Post subject: Reply with quote

Code:
ExResult:=DLLCall("unrar.dll\RARProcessFile" , "UInt" , hArchive , "Uint" , 2 , "Uint" , 0 , "Uint" , &File)
If !ExResult {
   MsgBox , 262160 , %A_ScriptName% , Error extracting "%File%" from "%FName%".
   Progress, Off
   Return , 0


to 6) I dont know whats wrong, but my adresses are blank. i'm going to test it tomorrow on an xp machine.


Last edited by ladiko on Mon Mar 31, 2008 10:56 pm; edited 2 times in total
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Mon Mar 31, 2008 10:25 pm    Post subject: Reply with quote

I did notice on the code you posted, I was pulling out address but you were checking adress, Just check your code hasn't got the same mistake.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Mon Mar 31, 2008 10:58 pm    Post subject: Reply with quote

yes i found my bug some minutes ago. in german address = Adresse, thats why forgot a "d" - sorry for that :/

could you please try this:

test:
unrar.dll 3.71.100.350 from http://www.rarlab.com/rar_add.htm
ahk 1.0.47.6
windows vista business sp1
all rar & zip archives from http://www.maximumcompression.com/data/files

test script:
Code:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force ; Run script only one time in memory
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.

LogFile = %A_ScriptDir%\RarExtLog.txt
FileDelete , %LogFile%

Loop , %A_ScriptDir%\*.*
{
   SplitPath, A_LoopFileLongPath , OutFileName , OutDir , OutExtension , OutNameNoExt , OutDrive
   MyFile := A_LoopFileLongPath
   MyPath := OutDir . "\" . OutNameNoExt
   FileAppend , Extract "%MyFile%" to "%MyPath%":%A_Space% , %LogFile%
   ExtractRAR(MyFile,MyPath,1,1)
}

return

; ################################

_ERROR_EXIT(sMSG)
{
   Global LogFile
   ; MsgBox , 262160 , %A_ScriptName% , %sMSG%
   ; ExitApp
   FileAppend ,  %sMSG%`n , %LogFile%
   return
}

ExtractRAR(File,ExPath = "",ExPaths = 1,ShowProg = 0){
  Global Prog,UnpackedFS
  If (ExPath = ""){
    ExPath:=A_workingdir
  }
  Fname:=File
  varsetcapacity(ArchiveData,32,0)
  Numput(&File,ArchiveData)
  Numput(1,ArchiveData,4)
  hModule := DllCall("LoadLibrary", "str", "unrar.dll")
  if (!hModule) {
    _ERROR_EXIT("Could not Load Library")
    Return
  }
  hArchive:=DLLCall("unrar.dll\RAROpenArchive","Uint",&ArchiveData)
  Result:=Numget(&ArchiveData,8)
  If (Result = 11){
    _ERROR_EXIT("Not enough Memory")
    Return
  }
  Else if (Result = 12){
    _ERROR_EXIT("Archive Header Broken")
    Return
  }
  Else If (Result = 13){
    _ERROR_EXIT("Invalid Archive Type")
    Return
  }
  Else IF (Result = 14){
    _ERROR_EXIT("Unknown encryption")
    Return
  }
  Else If (Result = 15){
    _ERROR_EXIT("%A_ScriptName% ,Error Opening File")
    Return
  }
  If (ShowProg){
    Address:=registercallback("RarCallback","",4,1)
    If (Address = ""){
      _ERROR_EXIT("Error extracting archive!`n`nReturned adress to machine-code function was empty.")
    }
  }
  Else {
    Address:=registercallback("RarCallback","",4,0)
    If (Address = ""){
      _ERROR_EXIT("Error extracting archive!`n`nReturned adress to machine-code function was empty.")
    }
  }
  DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0)
  Varsetcapacity(ArchiveHeader,572,0)
  Loop
  {
    FileResult:=DLLCall("unrar.dll\RARReadHeader","UInt",hArchive,"Uint",&ArchiveHeader)
    If (FileResult = 12){
      _ERROR_EXIT("File Header Currupt - Incorrect Password????")
      Return
    }
    Else If (FileResult = 10){
      Break
    }
    Varsetcapacity(CurFile,260,0)
    DllCall("lstrcpynA", "Str", CurFile, "UInt", &ArchiveHeader+260,   "int", 260)
    UnpackedFS:=Numget(&ArchiveHeader,528)
    If (ShowProg){
      Progress,A R0-%UnpackedFS% M P0 w500,Current File %CurFile%,Extracting From %Fname%,Extraction in progress...
      Prog:=0
      Sleep,100
    }
    If (substr(ExPath,0,1) != "\"){
      Expath.="\"
    }
    If (ExPaths){
      File:=ExPath . CurFile
    }
    Else {
      File:=ExPath . Regexreplace(CurFile,".*\\","")
    }
    ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)
    If (ExResult != 0){
      _ERROR_EXIT("Error Extracting """ . File . """ from """ . FName . """.")
      Return
    }
  }
  Progress,Off
  DLLCall("unrar.dll\RARCloseArchive","Uint",hArchive)
  DllCall("FreeLibrary ", "UInt", hModule)
  _ERROR_EXIT("OK!")
  Return
}

RarCallback(Message,User,P1,P2){
  Global Prog
  If (Message = 1 and a_eventinfo = 1){
    Prog+=P2
    Progress,%Prog%
  }

  If (Message = 2){
    Inputbox,password
    DllCall("lstrcpynA","Uint",P1+0, "STR",Password,"int", P2)
  }
  return,1
}


RarExtLog.txt:
Code:
Extract "D:\test\bmp-test.rar" to "D:\test\bmp-test": Error Extracting "D:\test\bmp-test\rafale.bmp" from "D:\test\bmp-test.rar".
Extract "D:\test\dll-test.rar" to "D:\test\dll-test": Error Extracting "D:\test\dll-test\mso97.dll" from "D:\test\dll-test.rar".
Extract "D:\test\doc-test.rar" to "D:\test\doc-test": Error Extracting "D:\test\doc-test\ohs.doc" from "D:\test\doc-test.rar".
Extract "D:\test\exe-test.rar" to "D:\test\exe-test": Error Extracting "D:\test\exe-test\acrord32.exe" from "D:\test\exe-test.rar".
Extract "D:\test\hlp-test.rar" to "D:\test\hlp-test": Error Extracting "D:\test\hlp-test\vcfiu.hlp" from "D:\test\hlp-test.rar".
Extract "D:\test\jpg-test.zip" to "D:\test\jpg-test": Invalid Archive Type
Extract "D:\test\log-test.rar" to "D:\test\log-test": Error Extracting "D:\test\log-test\fp.log" from "D:\test\log-test.rar".
Extract "D:\test\pdf-test.zip" to "D:\test\pdf-test": Invalid Archive Type
Extract "D:\test\sorted-test.zip" to "D:\test\sorted-test": Invalid Archive Type
Extract "D:\test\text-test.rar" to "D:\test\text-test": Error Extracting "D:\test\text-test\world95.txt" from "D:\test\text-test.rar".
Extract "D:\test\unrar.dll" to "D:\test\unrar": Invalid Archive Type
Extract "D:\test\unrar_test.ahk" to "D:\test\unrar_test": Invalid Archive Type


i will try this tomorrow on the xp system.
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Tue Apr 01, 2008 12:37 am    Post subject: Reply with quote

Heres my Log file, using only a few rar files.

Code:
Extract "D:\Temp\test\bmp-test.rar" to "D:\Temp\test\bmp-test": OK!
Extract "D:\Temp\test\dll-test.rar" to "D:\Temp\test\dll-test": OK!
Extract "D:\Temp\test\New AutoHotkey Script.ahk" to "D:\Temp\test\New AutoHotkey Script": Invalid Archive Type
Extract "D:\Temp\test\unrar.dll" to "D:\Temp\test\unrar": Invalid Archive Type


Works fine for me. I'm using XP, and I downloaded the same Dll Version.

EDIT:

I did have a different AHK version, but it still works fine with the latest.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Tue Apr 01, 2008 9:40 am    Post subject: Reply with quote

ok i copied the test-folder to a usb-stick and tested it on a xp sp2 machine and the result is:
Code:
Extract "W:\test\bmp-test.rar" to "W:\test\bmp-test": OK!
Extract "W:\test\dll-test.rar" to "W:\test\dll-test": OK!
Extract "W:\test\doc-test.rar" to "W:\test\doc-test": OK!
Extract "W:\test\exe-test.rar" to "W:\test\exe-test": OK!
Extract "W:\test\hlp-test.rar" to "W:\test\hlp-test": OK!
Extract "W:\test\jpg-test.zip" to "W:\test\jpg-test": Invalid Archive Type
Extract "W:\test\log-test.rar" to "W:\test\log-test": OK!
Extract "W:\test\pdf-test.zip" to "W:\test\pdf-test": Invalid Archive Type
Extract "W:\test\sorted-test.zip" to "W:\test\sorted-test": Invalid Archive Type
Extract "W:\test\text-test.rar" to "W:\test\text-test": OK!
Extract "W:\test\unrar.dll" to "W:\test\unrar": Invalid Archive Type
Extract "W:\test\unrar_test.ahk" to "W:\test\unrar_test": Invalid Archive Type
Extract "W:\test\RarExtLog.txt" to "W:\test\RarExtLog": Invalid Archive Type

seems like your script works perfect, but something goes wrong on vista - i would guess it's a problem with the unrar.dll cause
DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File) fails. could somebody else test it on windows vista?

edit:
DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File) only fails if DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0) is called and succeed.

is it right that the returned value of DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0) is the same address as hArchive gets from DLLCall("unrar.dll\RAROpenArchive","Uint",&ArchiveData) ?
Back to top
View user's profile Send private message
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Thu Apr 03, 2008 10:02 am    Post subject: Reply with quote

i replaced the line
Code:
ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)

with:
Code:
OldErrorLevel = %ErrorLevel%
OldLastError = %A_LastError%
ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)
ErrMsg = . FName = "%FName%"`n
      . ExPath = "%ExPath%"`n
      . File = "%File%"`n
      . hArchive = "%hArchive%"`n
      . ExResult = "%ExResult%"`n
      . OldErrorLevel = "%OldErrorLevel%"`n
      . ErrorLevel = "%ErrorLevel%"`n
      . OldLastError = "%OldLastError%"`n
      . LastError = "%A_LastError%"`n

and get this LogFile:
Code:
Extract "X:\test\bmp-test.rar" to "X:\test\bmp-test":
. FName = "X:\test\bmp-test.rar"
 . ExPath = "X:\test\bmp-test\"
 . File = "X:\test\bmp-test\rafale.bmp"
 . hArchive = "42410660"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\dll-test.rar" to "X:\test\dll-test":
. FName = "X:\test\dll-test.rar"
 . ExPath = "X:\test\dll-test\"
 . File = "X:\test\dll-test\mso97.dll"
 . hArchive = "73288572"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\doc-test.rar" to "X:\test\doc-test":
. FName = "X:\test\doc-test.rar"
 . ExPath = "X:\test\doc-test\"
 . File = "X:\test\doc-test\ohs.doc"
 . hArchive = "104261780"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\exe-test.rar" to "X:\test\exe-test":
. FName = "X:\test\exe-test.rar"
 . ExPath = "X:\test\exe-test\"
 . File = "X:\test\exe-test\acrord32.exe"
 . hArchive = "135237360"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\hlp-test.rar" to "X:\test\hlp-test":
. FName = "X:\test\hlp-test.rar"
 . ExPath = "X:\test\hlp-test\"
 . File = "X:\test\hlp-test\vcfiu.hlp"
 . hArchive = "166044988"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\jpg-test.zip" to "X:\test\jpg-test":
. %A_ScriptName% ,Invalid Archive Type
Extract "X:\test\log-test.rar" to "X:\test\log-test":
. FName = "X:\test\log-test.rar"
 . ExPath = "X:\test\log-test\"
 . File = "X:\test\log-test\fp.log"
 . hArchive = "196852616"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\pdf-test.zip" to "X:\test\pdf-test":
. %A_ScriptName% ,Invalid Archive Type
Extract "X:\test\sorted-test.zip" to "X:\test\sorted-test":
. %A_ScriptName% ,Invalid Archive Type
Extract "X:\test\text-test.rar" to "X:\test\text-test":
. FName = "X:\test\text-test.rar"
 . ExPath = "X:\test\text-test\"
 . File = "X:\test\text-test\world95.txt"
 . hArchive = "227398092"
 . ExResult = ""
 . OldErrorLevel = "0"
 . ErrorLevel = "0xc0000005"
 . OldLastError = "0"
 . LastError = "0"
. unrar.dll = ok
. Error Extracting File
Extract "X:\test\unrar.dll" to "X:\test\unrar":
. %A_ScriptName% ,Invalid Archive Type
Extract "X:\test\unrar_test.ahk" to "X:\test\unrar_test":
. %A_ScriptName% ,Invalid Archive Type

what could the errorlevel mean? i found a thread with the same error code and something about dependencies. is unrar.dll using a library that is missing on vista? oO
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 971
Location: London, UK

PostPosted: Thu Apr 03, 2008 11:19 am    Post subject: Reply with quote

I'm at work so cannot have a look at the moment, but

Quote:
N (any positive number): The function was called but it aborted with fatal exception number N (for example, 0xC0000005 means "access violation"). In such cases, the function returns a blank value (empty string), but any asterisk variables are still updated. An example of a fatal exception is dereferencing an invalid pointer such as NULL. Since a Cdecl function never produces the "An" error in the next paragraph, it may generate an exception when too few arguments are passed to it.



Edit: Try this
Code:
ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Char",0,"Char",File)

or
ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Char",0,"Char",&File)
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Thu Apr 03, 2008 11:47 am    Post subject: Reply with quote

ladiko wrote:
DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File) only fails if DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0) is called and succeed.
Sounds like your Vista machine really doesn't like callbacks. (Related thread.) The script works on my 32-bit Vista Business system. Are you on 32-bit or 64-bit Vista? Do you have DEP enabled?

Access violation (0xC0000005) basically means the DllCall tried to read/write memory at an invalid address.
Back to top
View user's profile Send private message
ladiko



Joined: 13 Jul 2006
Posts: 188
Location: Berlin

PostPosted: Thu Apr 03, 2008 1:09 pm    Post subject: Reply with quote

noooooooooooooooooooooooooooooooooooooooooo Neutral

now it is disabled and the unrar callback works. the IconToResourceID thing will be tested later.

i thought DEP would be usefull and i never had such big problems with it. doesnt also other applications use callbacks? or why do i get this problems right now when i use these ahk-functions? i thought it is recommended to enable DEP, like it is recommended by microsoft that the bios setup option PnP OS is disabled Rolling Eyes

BIG BIG thank you both, Lexikos and Superfraggle, for your help Smile

edit
so here is a version with an advanced gui:

Code:
ExtractRAR(File,ExPath = "",ExPaths = 1,ShowProg = 0){
   Global FileProg,UnpackedFS,GuiFileProgress,GuiOverallProgress , GuiExtractFrom, GuiCurFile , GuiProgressText
   ErrMsg = Error extracting archive!`n`n
   
   Loop , %File%
      SplitPath, A_LoopFileLongPath , ArchiveFileName , ArchiveDir , , ArchiveNameNoExt
   
   If (ExPath = ""){
      ExPath := ArchiveDir . "\" . AchiveNameNoExt
      ; ExPath:=A_WorkingDir
   }
   ArchiveFileFullPath:=File
   
   varsetcapacity(ArchiveData,32,0)
   Numput(&File,ArchiveData)
   Numput(1,ArchiveData,4)
   hModule := DllCall("LoadLibrary", "str", "unrar.dll")
   if (!hModule) {
      _ERROR(ErrMsg . "Could not Load Library")
      Return
   }
   hArchive:=DLLCall("unrar.dll\RAROpenArchive","Uint",&ArchiveData)
   Result:=Numget(&ArchiveData,8)
   If (Result = 11){
      _ERROR(ErrMsg . "%A_ScriptName% ,Not enough Memory.")
      Return
   }
   Else if (Result = 12){
      _ERROR(ErrMsg . "%A_ScriptName% ,Archive Header Broken.")
      Return
   }
   Else If (Result = 13){
      _ERROR(ErrMsg . "Invalid Archive Type.")
      Return
   }
   Else IF (Result = 14){
      _ERROR(ErrMsg . "Unknown encryption.")
      Return
   }
   Else If (Result = 15){
      _ERROR(ErrMsg . "Error Opening File")
      Return
   }
   If (ShowProg){
      Address:=registercallback("RarCallback","",4,1)
      If (Address = ""){
         _ERROR(ErrMsg . "Returned adress to machine-code function was empty.")
      }
   }
   Else {
      Address:=registercallback("RarCallback","",4,0)
      If (Address = ""){
         _ERROR(ErrMsg . "Returned adress to machine-code function was empty.")
      }
   }
   DLLCall("unrar.dll\RARSetCallback","UInt",hArchive,"Uint",Address,"Uint",0)
   Varsetcapacity(ArchiveHeader,572,0)
   
   If ShowProg
   {
      FileGetSize , ArchiveSize , %ArchiveFileFullPath%
      
      If ArchiveSize > 10737418240
      {
         SizeDiv = 1073741824.0
         SizeExt = GByte
      }
      Else If ArchiveSize > 10486760
      {
         SizeDiv = 1048676.0
         SizeExt = MByte
      }
      Else If ArchiveSize > 10240
      {
         SizeDiv = 1024.0
         SizeExt = KByte
      }
      Else
      {
         SizeDiv = 1.0
         SizeExt = Byte
      }
      GuiArchiveSize := Round(ArchiveSize / SizeDiv , 2)
      
      Gui +OwnDialogs -SysMenu ; +ToolWindow
      
      Gui , Add , Text , w500 Center vGuiExtractFrom, Extracting from: %ArchiveFileName%
      Gui , Add , Progress , w500 -Smooth Range0-500 vGuiOverallProgress
      Gui , Add , Text , w500 Center vGuiCurFile , Current File:
      Gui , Add , Progress , w500 -Smooth Range0-500 vGuiFileProgress
      Gui , Add , Text , w500 Center vGuiProgressText , Remaining: 00h00m00s`t`tProgress: 0 / %GuiArchiveSize% %SizeExt%
      
      Gui , Show , AutoSize Center, Extraction in progress...
      
      StartTime := A_TickCount
   }
   
   Loop
   {
      FileResult:=DLLCall("unrar.dll\RARReadHeader","UInt",hArchive,"Uint",&ArchiveHeader)
      If (FileResult = 12){
         _ERROR(ErrMsg . "File Header Currupt - Incorrect Password????")
         Return
      }
      Else If (FileResult = 10){
         Break
      }
      Varsetcapacity(CurFile,260,0)
      DllCall("lstrcpynA", "Str", CurFile, "UInt", &ArchiveHeader+260, "int", 260)
      
      ExtractedSize += Numget(&ArchiveHeader,524)
      UnpackedFS := Numget(&ArchiveHeader,528)
      If (ShowProg){
         
         OverallProgress := 500 / (ArchiveSize / ExtractedSize)
         ProgSize := Round(ExtractedSize / SizeDiv , 2)
         FileProg:=0
         
         EstimatedTime := (A_TickCount - StartTime) * ((ArchiveSize / ExtractedSize) - 1)
         ss := Round(EstimatedTime/1000)
         mm := Round(ss/60)
         ss := Round(Mod(ss,60))
         hh := Floor(mm/60)
         mm := Floor(Mod(mm,60))
         If hh > 0
            EstimatedTime = %hh%h%mm%m%ss%s
         Else If mm > 0
            EstimatedTime = %mm%m%ss%s
         Else
            EstimatedTime = %ss%s
         
         GuiControl,, GuiFileProgress, %FileProg%
         GuiControl,, GuiOverallProgress, %OverallProgress%
         GuiControl,, GuiCurFile , Current File: %CurFile%
         GuiControl,, GuiProgressText , Remaining: %EstimatedTime%`t`tProgress: %ProgSize% / %GuiArchiveSize% %SizeExt%
         Sleep,100
      }
      If (substr(ExPath,0,1) != "\"){
         Expath.="\"
      }
      If (ExPaths){
         File:=ExPath . CurFile
      }
      Else {
         File:=ExPath . Regexreplace(CurFile,".*\\","")
      }
      ExResult:=DLLCall("unrar.dll\RARProcessFile","UInt",hArchive,"Uint",2,"Uint",0,"Uint",&File)
      If (ExResult != 0){
         _ERROR(ErrMsg . "Error Extracting """ . File . """.")
         Return , -1
      }
   }
   
   DLLCall("unrar.dll\RARCloseArchive","Uint",hArchive)
   DllCall("FreeLibrary ", "UInt", hModule)
   Gui , Destroy
   Return , 1
}

RarCallback(Message,User,P1,P2){
   Global FileProg
   If (Message = 1 and a_eventinfo = 1){
      FileProg += 5 * P2
      GuiControl,, GuiFileProgress, %FileProg%
   }
   If (Message = 2){
      Inputbox,password
      DllCall("lstrcpynA","Uint",P1+0, "STR",Password,"int", P2)
   }
   return,1
}

_ERROR(sMSG)
{
   Msgbox , 262160 , %A_ScriptName% , %sMSG%
   return
}


i hope you like it and maybe update your first post Smile
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Fri Apr 04, 2008 1:39 am    Post subject: Reply with quote

AutoHotkey uses GlobalAlloc to allocate memory for the callback. Presumably because Microsoft recommends against it, AutoHotkey doesn't change the memory protection to include PAGE_EXECUTE, so DEP will prevent callbacks from executing.

Try re-enabling DEP and using this for each callback:
Code:
; PAGE_EXECUTE_READWRITE = 0x40
DllCall("VirtualProtect", "uint", Address, "uint", 22, "uint", 0x40, "uint*", OldProtect)
This should change the protection of the page containing the callback (i.e. it will affect all memory blocks on that page, which is why Microsoft recommends against it.)

TBH, callbacks are rather useless if you can't call them. Perhaps it would be better if AutoHotkey did this, despite Microsoft's recommendation.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group