-- a simple demo of a .dll/.exe version probe
include win32lib.ew -- at least version 0.55.1

constant
  ver=registerw32Library("version.dll"),

  zGetFileVersionInfoSize=registerw32Function(
    ver,"GetFileVersionInfoSizeA",
    {C_POINTER,C_POINTER},C_INT),

  zGetFileVersionInfo=registerw32Function(
    ver,"GetFileVersionInfoA",
    {C_POINTER,C_INT,C_INT,C_POINTER},C_INT),

  zVerQueryValue=registerw32Function(
    ver,"VerQueryValueA",
    {C_POINTER,C_POINTER,C_POINTER,C_POINTER},C_INT)


atom
  lptstrFilename,
  lpdwHandle,
  dwLen,
  lpData,
  lplpBuffer,
  puLen,

  jk,
  index

function probe_version(sequence x_name)
  atom dat1,dat2,dat3,dat4

  lptstrFilename=acquire_mem(0,x_name)
  lpdwHandle=acquire_mem(0,4)
  lplpBuffer=acquire_mem(0,4)
  puLen=acquire_mem(0,4)

  -- does this file have a version resource?
  dwLen=w32Func(zGetFileVersionInfoSize,{lptstrFilename,lpdwHandle})
  if dwLen>0 then

    -- if so, then get the data into a block of memory
    lpData=acquire_mem(0,dwLen)
    jk=w32Func(zGetFileVersionInfo,{lptstrFilename,NULL,dwLen,lpData})

    -- get the 'binary' version value from the VS_FIXEDFILEINFO structure
    jk=acquire_mem(0,"\\")
    jk=w32Func(zVerQueryValue,{lpData,jk,lplpBuffer,puLen})
    index=peek4u(lplpBuffer)
    dat1=hi_word(peek4u(index+8))
    dat2=lo_word(peek4u(index+8))
    dat3=hi_word(peek4u(index+12))
    dat4=lo_word(peek4u(index+12))
    -- return as a sequence
    return {dat1,dat2,dat3,dat4}
  else
    return {}
  end if
end function

-- test stub --
procedure check(sequence x_name)
  sequence returned
    returned=probe_version(x_name)
  if length(returned) > 0 then
    jk=message_box(sprintf("%s",{x_name & " version "}) & " " &
                   sprintf("%d.%d.%d.%d",{returned[1],returned[2],
                   returned[3],returned[4]}),"DLL / EXE Version, " &
                   sprintf(" using Win32Lib version %d.%d.%d ",
                    {Win32LibVersion[1],
                     Win32LibVersion[2],
                     Win32LibVersion[3]
                    }) ,MB_OK)

  else
    jk=message_box("Error in finding " &
                   sprintf("%s",{x_name}),"... oops",
                   {MB_ICONERROR,MB_OK})

  end if
end procedure

-- call test stub --
check("Comctl32.dll")
check("Riched20.dll")
check("NotePad.exe")
