2121package windows
2222
2323import (
24+ "errors"
2425 "fmt"
2526 "unsafe"
2627
27- "github.com/pkg/errors "
28+ "golang.org/x/sys/windows "
2829)
2930
30- // Syscalls
31- //sys _GetFileVersionInfo(filename string, reserved uint32, dataLen uint32, data *byte) (success bool, err error) [!success] = version.GetFileVersionInfoW
32- //sys _GetFileVersionInfoSize(filename string, handle uintptr) (size uint32, err error) = version.GetFileVersionInfoSizeW
33- //sys _VerQueryValueW(data *byte, subBlock string, pBuffer *uintptr, len *uint32) (success bool, err error) [!success] = version.VerQueryValueW
34-
35- // FixedFileInfo contains version information for a file. This information is
36- // language and code page independent. This is an equivalent representation of
37- // VS_FIXEDFILEINFO.
38- // https://msdn.microsoft.com/en-us/library/windows/desktop/ms646997(v=vs.85).aspx
31+ // Deprecated: use x/sys/windows
3932type FixedFileInfo struct {
4033 Signature uint32
4134 StrucVersion uint32
@@ -84,32 +77,27 @@ func (d VersionData) QueryValue(key string) (string, error) {
8477 CodePage uint16
8578 }
8679
80+ var langCodePage * LangAndCodePage
81+ langCodeLen := uint32 (unsafe .Sizeof (* langCodePage ))
82+ if err := windows .VerQueryValue (unsafe .Pointer (& d [0 ]), `\VarFileInfo\Translation` , (unsafe .Pointer )(& langCodePage ), & langCodeLen ); err != nil || langCodeLen == 0 {
83+ return "" , fmt .Errorf ("failed to get list of languages: %w" , err )
84+ }
85+
8786 var dataPtr uintptr
8887 var size uint32
89- if _ , err := _VerQueryValueW (& d [0 ], `\VarFileInfo\Translation` , & dataPtr , & size ); err != nil || size == 0 {
90- return "" , errors .Wrap (err , "failed to get list of languages" )
88+ subBlock := fmt .Sprintf (`\StringFileInfo\%04x%04x\%v` , langCodePage .Language , langCodePage .CodePage , key )
89+ if err := windows .VerQueryValue (unsafe .Pointer (& d [0 ]), subBlock , (unsafe .Pointer )(& dataPtr ), & size ); err != nil || langCodeLen == 0 {
90+ return "" , fmt .Errorf ("failed to query %v: %w" , subBlock , err )
9191 }
9292
9393 offset := int (dataPtr - (uintptr )(unsafe .Pointer (& d [0 ])))
9494 if offset <= 0 || offset > len (d )- 1 {
9595 return "" , errors .New ("invalid address" )
9696 }
9797
98- l := * (* LangAndCodePage )(unsafe .Pointer (& d [offset ]))
99-
100- subBlock := fmt .Sprintf (`\StringFileInfo\%04x%04x\%v` , l .Language , l .CodePage , key )
101- if _ , err := _VerQueryValueW (& d [0 ], subBlock , & dataPtr , & size ); err != nil || size == 0 {
102- return "" , errors .Wrapf (err , "failed to query %v" , subBlock )
103- }
104-
105- offset = int (dataPtr - (uintptr )(unsafe .Pointer (& d [0 ])))
106- if offset <= 0 || offset > len (d )- 1 {
107- return "" , errors .New ("invalid address" )
108- }
109-
11098 str , _ , err := UTF16BytesToString (d [offset : offset + int (size )* 2 ])
11199 if err != nil {
112- return "" , errors . Wrap ( err , "failed to decode UTF16 data" )
100+ return "" , fmt . Errorf ( "failed to decode UTF16 data: %w" , err )
113101 }
114102
115103 return str , nil
@@ -119,40 +107,32 @@ func (d VersionData) QueryValue(key string) (string, error) {
119107// version-information resource. It queries the root block to get the
120108// VS_FIXEDFILEINFO value.
121109// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx
122- func (d VersionData ) FixedFileInfo () (* FixedFileInfo , error ) {
110+ func (d VersionData ) FixedFileInfo () (* windows. VS_FIXEDFILEINFO , error ) {
123111 if len (d ) == 0 {
124112 return nil , errors .New ("use GetFileVersionInfo to initialize VersionData" )
125113 }
126114
127- var dataPtr uintptr
128- var size uint32
129- if _ , err := _VerQueryValueW (& d [0 ], `\` , & dataPtr , & size ); err != nil {
130- return nil , errors .Wrap (err , "VerQueryValue failed for \\ " )
131- }
132-
133- offset := int (dataPtr - (uintptr )(unsafe .Pointer (& d [0 ])))
134- if offset <= 0 || offset > len (d )- 1 {
135- return nil , errors .New ("invalid address" )
115+ var fixedInfo * windows.VS_FIXEDFILEINFO
116+ fixedInfoLen := uint32 (unsafe .Sizeof (* fixedInfo ))
117+ if err := windows .VerQueryValue (unsafe .Pointer (& d [0 ]), `\` , (unsafe .Pointer )(& fixedInfo ), & fixedInfoLen ); err != nil {
118+ return nil , fmt .Errorf ("VerQueryValue failed for \\ : %w" , err )
136119 }
137120
138- // Make a copy of the struct.
139- ffi := * (* FixedFileInfo )(unsafe .Pointer (& d [offset ]))
140-
141- return & ffi , nil
121+ return fixedInfo , nil
142122}
143123
144124// GetFileVersionInfo retrieves version information for the specified file.
145125// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003(v=vs.85).aspx
146126func GetFileVersionInfo (filename string ) (VersionData , error ) {
147- size , err := _GetFileVersionInfoSize (filename , 0 )
127+ size , err := windows . GetFileVersionInfoSize (filename , nil )
148128 if err != nil {
149- return nil , errors . Wrap ( err , "GetFileVersionInfoSize failed" )
129+ return nil , fmt . Errorf ( "GetFileVersionInfoSize failed: %w" , err )
150130 }
151131
152132 data := make (VersionData , size )
153- _ , err = _GetFileVersionInfo (filename , 0 , uint32 (len (data )), & data [0 ])
133+ err = windows . GetFileVersionInfo (filename , 0 , uint32 (len (data )), unsafe . Pointer ( & data [0 ]) )
154134 if err != nil {
155- return nil , errors . Wrap ( err , "GetFileVersionInfo failed" )
135+ return nil , fmt . Errorf ( "GetFileVersionInfo failed: %w" , err )
156136 }
157137
158138 return data , nil
0 commit comments