Need another pair of eyes..
I've been racking my brain for a couple days on this one function.
The purpose is to read the file info strings from an executable (or dll, ocx, etc). Not all executables have them, but if you right-click on an executable, select Properties, then click the Version tab (if it's there) you will see the information I am trying to retrieve.
Once fixed, I think it makes a good candidate for a NSIS Example wiki page..
Anyway, I'm messing with the stack and the System plugin and it is wreaking havoc on my program throwing spurious "invalid opcode" and "Access denied" (while reading a memory address). Can someone else take a look at this with me and help me figure it out?
I think the key to fixing the problem is near the "System::Call "*$4(&t$5 .r7)"" line. When I comment that out all my problems seem to disappear. What am I doing wrong? :mad:
Var PROGRAMINFO
; Call like this:
; !insertmacro GetInfoFromExeHeader "ProductName" "c:\programs\myexecutable.exe"
!macro GetInfoFromExeHeader DataType ProgramExe
Push ${DataType}
Push ${ProgramExe}
Call GetInfoFromExeHeader
Pop $PROGRAMINFO
!macroend
Function GetInfoFromExeHeader
; Valid Data Types:
; ProductName
; InternalName
; ProductVersion
; SpecialBuild
; PrivateBuild
; LegalCopyright
; LegalTrademarks
; Comments
; CompanyName
; FileVersion
; FileDescription
Exch $R0 ; path to EXE
IfFileExists $R0 +4 0
MessageBox MB_OK "$R0 doesn't exist! Please correct this."
Exch $R0 ; Put the path back on the stack
Return
Exch
Exch $R1 ; Data type
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
Push $7
StrCpy $1 "0"
StrCpy $3 "0"
StrCpy $7 ""
StrCpy $2 "0"
System::Call "version::GetFileVersionInfoSize(t '$R0', t /NUL) i .r2" ;returns size of version block in header
IntCmp $2 0 Done Done 0 ; $2 needs to be greater than 0
System::Call "version::GetFileVersionInfo(t '$R0', i 0, i r2, *i .r3) i .r1" ; returns 1 or 0 with r3 being the fileinfo struct
IntCmp $1 0 Done 0 0 ; $1 needs to be <> 0
System::Call "version::VerQueryValue(*i r3, t '\StringFileInfo\040904E4\$R1', *i .r4, *i .r5) i .r6"
IntCmp $6 0 Done 0 0 ; $6 needs to be <> 0
IntCmp $5 0 Done Done 0
;IntOp $5 $5 + 1
System::Call "*$4(&t$5 .r7)"
Done:
System::Free $R0
System::Free $R1
System::Free $1
System::Free $2
System::Free $3
System::Free $4
System::Free $5
System::Free $6
;SetPluginUnload "manual"
Push $7
Exch 9 ; put $7 on the bottom
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $R0
Pop $R1
FunctionEnd
Documentation on the three version functions:
GetFileVersionInfoSize: http://msdn2.microsoft.com/en-us/library/ms647005.aspx
GetFileVersionInfo: http://msdn2.microsoft.com/en-us/library/ms647003.aspx
VerQueryValue: http://msdn2.microsoft.com/en-us/library/ms647464.aspx
-Steve.