EnableExplicit

Enumeration
  #GetFileVersionField_Comments
  #GetFileVersionField_CompanyName
  #GetFileVersionField_FileDesc
  #GetFileVersionField_FileVersion
  #GetFileVersionField_InternalName
  #GetFileVersionField_LegalCopyright
  #GetFileVersionField_LegalTrademarks
  #GetFileVersionField_OriginalFilename
  #GetFileVersionField_PrivateBuild
  #GetFileVersionField_ProductName
  #GetFileVersionField_ProductVersion
  #GetFileVersionField_SpecialBuild
  EndEnumeration

Procedure.i GetFileVersionInfo(Filename.s)
  Define *hMem
  Define.i xLong1
  Define.i xLong2
  
  xLong1 = GetFileVersionInfoSize_(@Filename, @xLong2)
  If xLong1
    *hMem = LocalAlloc_($40, xLong1)
    If *hMem
      xLong1 = GetFileVersionInfo_(@Filename, xLong2, xLong1, *hMem)
      If xLong1
        ProcedureReturn *hMem
        EndIf
      LocalFree_(*hMem)
      EndIf
    EndIf
  EndProcedure

;Procedure.s VerQueryValueEx(*hMem, FieldStr)
;  Define.i xLong1
;  Define.i xLong2
;  
;  If *hMem
;    If VerQueryValue_(*hMem, @FieldStr, @xLong1, @xLong2)
;      ProcedureReturn PeekS(xLong1, xLong2, #PB_Ascii)
;      EndIf
;    EndIf
;  EndProcedure

Procedure.s VerQueryValue(*hMem, FieldType.i)
  Define.i xLong1
  Define.i xLong2
  Define.s xChar1
  Define.s FieldStr
  Define.s Result
  
  If *hMem
    Select FieldType
      Case #GetFileVersionField_Comments:         FieldStr = "Comments"
      Case #GetFileVersionField_CompanyName:      FieldStr = "CompanyName"
      Case #GetFileVersionField_FileDesc:         FieldStr = "FileDescription"
      Case #GetFileVersionField_FileVersion:      FieldStr = "FileVersion"
      Case #GetFileVersionField_InternalName:     FieldStr = "InternalName"
      Case #GetFileVersionField_LegalCopyright:   FieldStr = "LegalCopyright"
      Case #GetFileVersionField_LegalTrademarks:  FieldStr = "LegalTrademarks"
      Case #GetFileVersionField_OriginalFilename: FieldStr = "OriginalFilename"
      Case #GetFileVersionField_PrivateBuild:     FieldStr = "PrivateBuild"
      Case #GetFileVersionField_ProductName:      FieldStr = "ProductName"
      Case #GetFileVersionField_ProductVersion:   FieldStr = "ProductVersion"
      Case #GetFileVersionField_SpecialBuild:     FieldStr = "SpecialBuild"
      Default: Goto IncompatibleFieldType
      EndSelect
    If VerQueryValue_(*hMem, @"\VarFileInfo\Translation", @xLong1, @xLong2)
      If xLong2
        xLong1 = PeekL(xLong1)
        CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
          EnableASM
          MOV rax, xLong1
          ROR rax, 16
          MOV xLong1, rax
          DisableASM
          CompilerElse
          EnableASM
          MOV eax, xLong1
          ROR eax, 16
          MOV xLong1, eax
          DisableASM
          CompilerEndIf

        FieldStr = "\StringFileInfo\" + Right("00000000"+LCase(Hex(xLong1, #PB_Long)), 8) + "\" + FieldStr + Chr(0)
        If VerQueryValue_(*hMem, @FieldStr, @xLong1, @xLong2)
          ProcedureReturn PeekS(xLong1, xLong2, #PB_Ascii)
          EndIf
IncompatibleFieldType:
        EndIf
      EndIf
    EndIf
  EndProcedure

Procedure FreeFileVersionInfo(*hMem)
  If *hMem
    LocalFree_(*hMem)
    EndIf
  EndProcedure  

; IDE Options = PureBasic 5.21 LTS (Windows - x64)
; CursorPosition = 48
; FirstLine = 45
; Folding = -
; EnableAsm
; EnableXP