1 /* Copyright (c) 2015 Michael Freeman, All Rights Reserved
2  *
3  * The contents of this file is dual-licensed under 2
4  * alternative Open Source/Free licenses: LGPL 2.1 or later and
5  * Apache License 2.0. (starting with JNA version 4.0.0).
6  *
7  * You can freely decide which license you want to apply to
8  * the project.
9  *
10  * You may obtain a copy of the LGPL License at:
11  *
12  * http://www.gnu.org/licenses/licenses.html
13  *
14  * A copy is also included in the downloadable source code package
15  * containing JNA, in file "LGPL2.1".
16  *
17  * You may obtain a copy of the Apache License at:
18  *
19  * http://www.apache.org/licenses/
20  *
21  * A copy is also included in the downloadable source code package
22  * containing JNA, in file "AL2.0".
23  */
24 package com.sun.jna.platform.win32;
25 
26 import com.sun.jna.Memory;
27 import com.sun.jna.Native;
28 import com.sun.jna.Pointer;
29 import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO;
30 import com.sun.jna.platform.win32.Version;
31 import com.sun.jna.platform.win32.Win32Exception;
32 import com.sun.jna.ptr.IntByReference;
33 import com.sun.jna.ptr.PointerByReference;
34 
35 /**
36  * Reads Windows Version info from files (the version details you can see by
37  * right-clicking and choosing properties)
38  *
39  * @author mlfreeman[at]gmail.com
40  */
41 public class VersionUtil {
42 
43     /**
44      * Gets the file's version number info
45      *
46      * @param filePath
47      *            The path to the file
48      * @return The VS_FIXEDFILEINFO structure read from the file.<br>
49      *         Use the getFileVersionMajor(), getFileVersionMinor(),
50      *         getFileVersionRevision(), and getFileVersionBuild()
51      * @throws UnsupportedOperationException
52      *             if VerQueryValue fails to get version info from the file.
53      */
getFileVersionInfo(String filePath)54     public static VS_FIXEDFILEINFO getFileVersionInfo(String filePath) {
55         IntByReference dwDummy = new IntByReference();
56 
57         int versionLength = Version.INSTANCE.GetFileVersionInfoSize(filePath, dwDummy);
58 
59         // Reading version info failed.
60         // throw a Win32Exception with GetLastError()
61         if (versionLength == 0) {
62             throw new Win32Exception(Native.getLastError());
63         }
64 
65         // buffer to hold version info
66         Pointer lpData = new Memory(versionLength);
67 
68         // pointer to pointer to location in aforementioned buffer
69         PointerByReference lplpBuffer = new PointerByReference();
70 
71         if (!Version.INSTANCE.GetFileVersionInfo(filePath, 0, versionLength, lpData)) {
72             throw new Win32Exception(Native.getLastError());
73         }
74 
75         // here to make VerQueryValue happy.
76         IntByReference puLen = new IntByReference();
77 
78         // this does not set GetLastError, so no need to throw a Win32Exception
79         if (!Version.INSTANCE.VerQueryValue(lpData, "\\", lplpBuffer, puLen)) {
80             throw new UnsupportedOperationException("Unable to extract version info from the file: \"" + filePath + "\"");
81         }
82 
83         VS_FIXEDFILEINFO fileInfo = new VS_FIXEDFILEINFO(lplpBuffer.getValue());
84         fileInfo.read();
85         return fileInfo;
86     }
87 
88 }
89