reFX
June 18, 2017, 9:35pm
21
No, they don’t output the same. First, for the JUCE file class, the name needs to be an absolute path. This is not necessary in this case. Second, the version numbers returned are different. My function returns
10.0.15063.296
With File::getVersion () it returns
6.2.15063.296
No idea why this is, but for that alone I prefer to continue to use my old, years old function.
Also, there are no permission problems. I’ve used this function for years and every support file we’ve been sent has this correct information in it.
jules
June 20, 2017, 9:34am
22
OK - can you do me a favour and sanity-check this cleaned up version:
struct WindowsVersion
{
WindowsVersion()
{
auto name = _T("kernel32.dll");
DWORD handle = 0;
if (auto size = GetFileVersionInfoSize (filename, &handle))
{
HeapBlock<char> data (size);
if (GetFileVersionInfo (filename, handle, size, data))
{
VS_FIXEDFILEINFO* info = nullptr;
if (VerQueryValue (data, (LPCTSTR) _T("\\"), (void**) &info, &size))
{
if (size > 0 && info != nullptr && info->dwSignature == 0xfeef04bd)
{
major = HIWORD (info->dwFileVersionMS);
minor = LOWORD (info->dwFileVersionMS);
point1 = HIWORD (info->dwFileVersionLS);
point2 = LOWORD (info->dwFileVersionLS);
}
}
}
}
}
WORD major = 0, minor = 0, point1 = 0, point2 = 0;
};
Looks like name
should have been filename
but anyways, VerQueryValue
's fourth parameter is of type PUINT
and not DWORD*
.
Try this - works fine for me:
struct WindowsVersion
{
WindowsVersion()
{
auto filename = _T ("kernel32.dll");
DWORD handle = 0;
if (auto size = GetFileVersionInfoSize (filename, &handle))
{
HeapBlock<char> data (size);
if (GetFileVersionInfo (filename, handle, size, data) != FALSE)
{
VS_FIXEDFILEINFO* info = nullptr;
UINT length = 0;
if (VerQueryValue (data, (LPCTSTR) _T ("\\"), (void**) &info, &length) != FALSE)
{
if (length > 0 && info != nullptr && info->dwSignature == 0xfeef04bd)
{
major = HIWORD (info->dwFileVersionMS);
minor = LOWORD (info->dwFileVersionMS);
point1 = HIWORD (info->dwFileVersionLS);
point2 = LOWORD (info->dwFileVersionLS);
}
}
}
}
}
WORD major = 0, minor = 0, point1 = 0, point2 = 0;
};
jules
June 21, 2017, 7:41am
24
It’s OK - I actually already implemented this on develop (slightly differently)
Oh my… This keep rearing its head. This function still returns incorrectly when called from an AAX plugin! Any ideas?
Guessing ProTools must deliberately load a different version of kernel32.dll, or something
FWIW I’m using this now which appears to work:
#include <lmerr.h>
#include <lm.h>
#pragma comment(lib, "netapi32.lib")
static bool GetWindowsVersion(DWORD& major, DWORD& minor)
{
LPBYTE pinfoRawData;
if (NERR_Success == NetWkstaGetInfo(NULL, 100, &pinfoRawData))
{
WKSTA_INFO_100 * pworkstationInfo = (WKSTA_INFO_100 *)pinfoRawData;
major = pworkstationInfo->wki100_ver_major;
minor = pworkstationInfo->wki100_ver_minor;
::NetApiBufferFree(pinfoRawData);
return true;
}
return false;
}
static bool isWindows10OrGreater()
{
DWORD major, minor;
if (GetWindowsVersion(major, minor))
return major >= 10;
return false;
}
Anyone see any issue with that on Windows 7+ ?
t0m
October 23, 2018, 3:49pm
28
Here’s a different approach I’ve used on Windows 10 to find out the build number:
auto getWindowsVersionInfo = []
{
RTL_OSVERSIONINFOW versionInfo = { 0 };
if (auto* mod = ::GetModuleHandleW (L"ntdll.dll"))
{
using RtlGetVersion = LONG (WINAPI*)(PRTL_OSVERSIONINFOW);
if (auto* rtlGetVersion = (RtlGetVersion) ::GetProcAddress (mod, "RtlGetVersion"))
{
versionInfo.dwOSVersionInfoSize = sizeof (versionInfo);
constexpr LONG STATUS_SUCCESS = 0;
if (rtlGetVersion (&versionInfo) != STATUS_SUCCESS)
versionInfo = { 0 };
}
}
return versionInfo;
};
auto versionInfo = getWindowsVersionInfo();
DBG (versionInfo.dwMajorVersion); // 10
DBG (versionInfo.dwMinorVersion); // 0
DBG (versionInfo.dwBuildNumber); // 17763
but like Martin I’ve not yet investigated if this will work on Windows 7.
2 Likes
Actually, my thinking in terms of not using GetModuleHandleW()
or JUCE’s own DLL loading stuff (etc) is that my plugin will just fail to load if the dll is missing. Which in some ways is preferable to silently returning the wrong result in my case
reFX
October 23, 2018, 8:48pm
31
Do you mean if the ntdll.dll is missing?
Well my example was using netapi32, but I get your point!