AutoHotkey Community

It is currently May 25th, 2012, 9:01 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: November 10th, 2007, 11:57 pm 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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 March 31st, 2008, 8:07 pm, edited 5 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 11th, 2007, 4:53 am 
Offline

Joined: April 22nd, 2007, 6:33 pm
Posts: 1832
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 :roll:

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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 12th, 2007, 3:18 am 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2008, 1:42 am 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2008, 8:06 pm 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2008, 10:42 pm 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
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 March 31st, 2008, 11:56 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2008, 11:25 pm 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2008, 11:58 pm 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 1st, 2008, 1:37 am 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 1st, 2008, 10:40 am 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
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) ?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 3rd, 2008, 11:02 am 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 3rd, 2008, 12:19 pm 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 3rd, 2008, 12:47 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 3rd, 2008, 2:09 pm 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
noooooooooooooooooooooooooooooooooooooooooo :|

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 :roll:

BIG BIG thank you both, Lexikos and Superfraggle, for your help :-)

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 :-)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2008, 2:39 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], lblb, RoAltmann and 8 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group