Skip to content

Commit

Permalink
Merge pull request #562 from mlfreeman2/versionutils
Browse files Browse the repository at this point in the history
added VersionUtil class and utility method for obtaining file version information
  • Loading branch information
dblock committed Dec 14, 2015
2 parents b71170a + f6405e0 commit 4e0388c
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -26,6 +26,7 @@ Features
* [#554](https://github.com/java-native-access/jna/pull/554): Initial code for a few Unix 'libc' API(s) [@lgoldstein](https://github.com/lgoldstein)
* [#552](https://github.com/java-native-access/jna/pull/552): Added `Module32FirstW` and `Module32NextW` to `com.sun.jna.platform.win32.Kernel32` (and helper to `com.sun.jna.platform.win32.Kernel32Util`) and `MODULEENTRY32W` structure to `com.sun.jna.platform.win32.Tlhelp32` - [@mlfreeman2](https://github.com/mlfreeman2).
* [#564](https://github.com/java-native-access/jna/pull/564): Use generic definition of Native#loadLibrary [@lgoldstein](https://github.com/lgoldstein)
* [#562](https://github.com/java-native-access/jna/pull/562): Added `com.sun.jna.platform.win32.VersionUtil` with `getFileVersionInfo` utility method to get file major, minor, revision, and build version parts - [@mlfreeman2](https://github.com/mlfreeman2).

Bug Fixes
---------
Expand Down
32 changes: 32 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/VerRsrc.java
Expand Up @@ -116,6 +116,38 @@ public VS_FIXEDFILEINFO(Pointer memory) {
*/
public WinDef.DWORD dwFileDateLS;

public int getFileVersionMajor() {
return dwFileVersionMS.intValue() >>> 16;
}

public int getFileVersionMinor() {
return dwFileVersionMS.intValue() & 0xffff;
}

public int getFileVersionRevision() {
return dwFileVersionLS.intValue() >>> 16;
}

public int getFileVersionBuild() {
return dwFileVersionLS.intValue() & 0xffff;
}

public int getProductVersionMajor() {
return dwProductVersionMS.intValue() >>> 16;
}

public int getProductVersionMinor() {
return dwProductVersionMS.intValue() & 0xffff;
}

public int getProductVersionRevision() {
return dwProductVersionLS.intValue() >>> 16;
}

public int getProductVersionBuild() {
return dwProductVersionLS.intValue() & 0xffff;
}

protected List getFieldOrder() {
return Arrays.asList(new String[] { "dwSignature", "dwStrucVersion", "dwFileVersionMS", "dwFileVersionLS", "dwProductVersionMS", "dwProductVersionLS", "dwFileFlagsMask", "dwFileFlags", "dwFileOS", "dwFileType", "dwFileSubtype", "dwFileDateMS", "dwFileDateLS" });
}
Expand Down
77 changes: 77 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/VersionUtil.java
@@ -0,0 +1,77 @@
/* Copyright (c) 2015 Michael Freeman, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO;
import com.sun.jna.platform.win32.Version;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

/**
* Reads Windows Version info from files (the version details you can see by
* right-clicking and choosing properties)
*
* @author mlfreeman[at]gmail.com
*/
public class VersionUtil {

/**
* Gets the file's version number info
*
* @param filePath
* The path to the file
* @return The VS_FIXEDFILEINFO structure read from the file.<br>
* Use the getFileVersionMajor(), getFileVersionMinor(),
* getFileVersionRevision(), and getFileVersionBuild()
* @throws UnsupportedOperationException
* if VerQueryValue fails to get version info from the file.
*/
public static VS_FIXEDFILEINFO getFileVersionInfo(String filePath) {
IntByReference dwDummy = new IntByReference();

int versionLength = Version.INSTANCE.GetFileVersionInfoSize(filePath, dwDummy);

// Reading version info failed.
// throw a Win32Exception with GetLastError()
if (versionLength == 0) {
throw new Win32Exception(Native.getLastError());
}

// buffer to hold version info
Pointer lpData = new Memory(versionLength);

// pointer to pointer to location in aforementioned buffer
PointerByReference lplpBuffer = new PointerByReference();

if (!Version.INSTANCE.GetFileVersionInfo(filePath, 0, versionLength, lpData)) {
throw new Win32Exception(Native.getLastError());
}

// here to make VerQueryValue happy.
IntByReference puLen = new IntByReference();

// this does not set GetLastError, so no need to throw a Win32Exception
if (!Version.INSTANCE.VerQueryValue(lpData, "\\", lplpBuffer, puLen)) {
throw new UnsupportedOperationException("Unable to extract version info from the file: \"" + filePath + "\"");
}

VS_FIXEDFILEINFO fileInfo = new VS_FIXEDFILEINFO(lplpBuffer.getValue());
fileInfo.read();
return fileInfo;
}

}
@@ -0,0 +1,43 @@
/* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32;

import java.io.File;

import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO;

import junit.framework.TestCase;

public class VersionUtilTest extends TestCase {

public static void main(String[] args) {
junit.textui.TestRunner.run(VersionUtilTest.class);
}

public void testGetFileVersionNumbers() {
String testFileName = "regedit.exe";
File file = new File(System.getenv("SystemRoot"), testFileName);
assertTrue("Test file with version info in it should exist.", file.exists());

VS_FIXEDFILEINFO version = VersionUtil.getFileVersionInfo(file.getAbsolutePath());
assertNotNull("Version info should have been returned.", version);

assertTrue("The major file version number should be greater than 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionMajor() > 0);
assertTrue("The minor file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionMinor() >= 0);
assertTrue("The revision file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionRevision() >= 0);
assertTrue("The build file version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getFileVersionBuild() > 0);

assertTrue("The major product version number should be greater than 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionMajor() > 0);
assertTrue("The minor product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionMinor() >= 0);
assertTrue("The revision product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionRevision() >= 0);
assertTrue("The build product version number should be greater than or equal to 0 when pulling version from \"" + testFileName + "\"", version.getProductVersionBuild() > 0);
}
}

0 comments on commit 4e0388c

Please sign in to comment.