summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2017-07-10 16:30:28 -0400
committerOz Linden <oz@lindenlab.com>2017-07-10 16:30:28 -0400
commitb0d8f3a1ab671668abb98fe1327f0fd73fca0fc7 (patch)
tree3eb0768772b99db06d5cdd2cbf59d201d5f22cf8 /indra
parent7eb53d4ccbfcb692a2edc7539e651b14c888742e (diff)
MAINT-4532: properly detect Windows 10 in the 64bit build (only - 32bit runs in Windows 8 compatibility mode)
Diffstat (limited to 'indra')
-rw-r--r--indra/CMakeLists.txt4
-rw-r--r--indra/llcommon/llsys.cpp377
-rw-r--r--indra/newview/CMakeLists.txt9
-rw-r--r--indra/newview/windows.manifest20
4 files changed, 143 insertions, 267 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 39f8697e8c..a40b2c0846 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -3,8 +3,8 @@
# cmake_minimum_required should appear before any
# other commands to guarantee full compatibility
# with the version specified
-## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly
-cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
+## prior to 3.4, the Windows manifest handling was missing
+cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index fd1828b1cc..1ef6c538ba 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -61,6 +61,7 @@ using namespace llsd;
#if LL_WINDOWS
# include "llwin32headerslean.h"
# include <psapi.h> // GetPerformanceInfo() et al.
+# include <VersionHelpers.h>
#elif LL_DARWIN
# include <errno.h>
# include <sys/sysctl.h>
@@ -110,78 +111,6 @@ static const F32 MEM_INFO_THROTTLE = 20;
// dropped below the login framerate, we'd have very little additional data.
static const F32 MEM_INFO_WINDOW = 10*60;
-#if LL_WINDOWS
-// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string
-static const U32 WINNT_WINBLUE = 0x0603;
-
-#ifndef DLLVERSIONINFO
-typedef struct _DllVersionInfo
-{
- DWORD cbSize;
- DWORD dwMajorVersion;
- DWORD dwMinorVersion;
- DWORD dwBuildNumber;
- DWORD dwPlatformID;
-}DLLVERSIONINFO;
-#endif
-
-#ifndef DLLGETVERSIONPROC
-typedef int (FAR WINAPI *DLLGETVERSIONPROC) (DLLVERSIONINFO *);
-#endif
-
-bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)
-{
- bool result = false;
- const U32 BUFF_SIZE = 32767;
- WCHAR tempBuf[BUFF_SIZE];
- if(GetSystemDirectory((LPWSTR)&tempBuf, BUFF_SIZE))
- {
-
- std::basic_string<WCHAR> shell32_path(tempBuf);
-
- // Shell32.dll contains the DLLGetVersion function.
- // according to msdn its not part of the API
- // so you have to go in and get it.
- // http://msdn.microsoft.com/en-us/library/bb776404(VS.85).aspx
- shell32_path += TEXT("\\shell32.dll");
-
- HMODULE hDllInst = LoadLibrary(shell32_path.c_str()); //load the DLL
- if(hDllInst)
- { // Could successfully load the DLL
- DLLGETVERSIONPROC pDllGetVersion;
- /*
- You must get this function explicitly because earlier versions of the DLL
- don't implement this function. That makes the lack of implementation of the
- function a version marker in itself.
- */
- pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hDllInst,
- "DllGetVersion");
-
- if(pDllGetVersion)
- {
- // DLL supports version retrieval function
- DLLVERSIONINFO dvi;
-
- ZeroMemory(&dvi, sizeof(dvi));
- dvi.cbSize = sizeof(dvi);
- HRESULT hr = (*pDllGetVersion)(&dvi);
-
- if(SUCCEEDED(hr))
- { // Finally, the version is at our hands
- major = dvi.dwMajorVersion;
- minor = dvi.dwMinorVersion;
- build_number = dvi.dwBuildNumber;
- result = true;
- }
- }
-
- FreeLibrary(hDllInst); // Release DLL
- }
- }
- return result;
-}
-#endif // LL_WINDOWS
-
// Wrap boost::regex_match() with a function that doesn't throw.
template <typename S, typename M, typename R>
static bool regex_match_no_exc(const S& string, M& match, const R& regex)
@@ -214,221 +143,139 @@ static bool regex_search_no_exc(const S& string, M& match, const R& regex)
}
}
-#if LL_WINDOWS
-// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case
-static bool check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
-{
- OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
- DWORDLONG const dwlConditionMask = VerSetConditionMask(
- VerSetConditionMask(
- VerSetConditionMask(
- 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
- VER_MINORVERSION, VER_GREATER_EQUAL),
- VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
-
- osvi.dwMajorVersion = wMajorVersion;
- osvi.dwMinorVersion = wMinorVersion;
- osvi.wServicePackMajor = wServicePackMajor;
-
- return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
-}
-#endif
-
LLOSInfo::LLOSInfo() :
mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")
{
#if LL_WINDOWS
- OSVERSIONINFOEX osvi;
- BOOL bOsVersionInfoEx;
- BOOL bShouldUseShellVersion = false;
- // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi)))
+ if (IsWindowsVersionOrGreater(10, 0, 0))
{
- // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
- osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
- if(!GetVersionEx( (OSVERSIONINFO *) &osvi))
- return;
+ mMajorVer = 10;
+ mMinorVer = 0;
+ mOSStringSimple = "Microsoft Windows 10 ";
}
- mMajorVer = osvi.dwMajorVersion;
- mMinorVer = osvi.dwMinorVersion;
- mBuild = osvi.dwBuildNumber;
-
- DWORD shell32_major, shell32_minor, shell32_build;
- bool got_shell32_version = get_shell32_dll_version(shell32_major,
- shell32_minor,
- shell32_build);
-
- switch(osvi.dwPlatformId)
+ else if (IsWindows8Point1OrGreater())
{
- case VER_PLATFORM_WIN32_NT:
+ mMajorVer = 6;
+ mMinorVer = 3;
+ if (IsWindowsServer())
{
- // Test for the product.
- if(osvi.dwMajorVersion <= 4)
- {
- mOSStringSimple = "Microsoft Windows NT ";
- }
- else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
- {
- mOSStringSimple = "Microsoft Windows 2000 ";
- }
- else if(osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1)
- {
- mOSStringSimple = "Microsoft Windows XP ";
- }
- else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
- {
- if(osvi.wProductType == VER_NT_WORKSTATION)
- mOSStringSimple = "Microsoft Windows XP x64 Edition ";
- else
- mOSStringSimple = "Microsoft Windows Server 2003 ";
- }
- else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 2)
- {
- if(osvi.dwMinorVersion == 0)
- {
- if(osvi.wProductType == VER_NT_WORKSTATION)
- mOSStringSimple = "Microsoft Windows Vista ";
- else
- mOSStringSimple = "Windows Server 2008 ";
- }
- else if(osvi.dwMinorVersion == 1)
- {
- if(osvi.wProductType == VER_NT_WORKSTATION)
- mOSStringSimple = "Microsoft Windows 7 ";
- else
- mOSStringSimple = "Windows Server 2008 R2 ";
- }
- else if(osvi.dwMinorVersion == 2)
- {
- if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0))
- {
- mOSStringSimple = "Microsoft Windows 8.1 ";
- bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version
- }
- else
- {
- if(osvi.wProductType == VER_NT_WORKSTATION)
- mOSStringSimple = "Microsoft Windows 8 ";
- else
- mOSStringSimple = "Windows Server 2012 ";
- }
- }
-
- ///get native system info if available..
- typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo
- SYSTEM_INFO si; //System Info object file contains architecture info
- PGNSI pGNSI; //pointer object
- ZeroMemory(&si, sizeof(SYSTEM_INFO)); //zero out the memory in information
- pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function
- if(NULL != pGNSI) //check if it has failed
- pGNSI(&si); //success
- else
- GetSystemInfo(&si); //if it fails get regular system info
- //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load)
-
- //msdn microsoft finds 32 bit and 64 bit flavors this way..
- //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
- //of windows than this code does (in case it is needed for the future)
- if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) //check for 64 bit
- {
- mOSStringSimple += "64-bit ";
- }
- else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
- {
- mOSStringSimple += "32-bit ";
- }
- }
- else // Use the registry on early versions of Windows NT.
- {
- mOSStringSimple = "Microsoft Windows (unrecognized) ";
-
- HKEY hKey;
- WCHAR szProductType[80];
- DWORD dwBufLen;
- RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
- 0, KEY_QUERY_VALUE, &hKey );
- RegQueryValueEx( hKey, L"ProductType", NULL, NULL,
- (LPBYTE) szProductType, &dwBufLen);
- RegCloseKey( hKey );
- if ( lstrcmpi( L"WINNT", szProductType) == 0 )
- {
- mOSStringSimple += "Professional ";
- }
- else if ( lstrcmpi( L"LANMANNT", szProductType) == 0 )
- {
- mOSStringSimple += "Server ";
- }
- else if ( lstrcmpi( L"SERVERNT", szProductType) == 0 )
- {
- mOSStringSimple += "Advanced Server ";
- }
- }
-
- std::string csdversion = utf16str_to_utf8str(osvi.szCSDVersion);
- // Display version, service pack (if any), and build number.
- std::string tmpstr;
- if(osvi.dwMajorVersion <= 4)
- {
- tmpstr = llformat("version %d.%d %s (Build %d)",
- osvi.dwMajorVersion,
- osvi.dwMinorVersion,
- csdversion.c_str(),
- (osvi.dwBuildNumber & 0xffff));
- }
- else
- {
- tmpstr = !bShouldUseShellVersion ? llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)):
- llformat("%s (Build %d)", csdversion.c_str(), shell32_build);
- }
-
- mOSString = mOSStringSimple + tmpstr;
+ mOSStringSimple = "Windows Server 2012 R2 ";
}
- break;
-
- case VER_PLATFORM_WIN32_WINDOWS:
- // Test for the Windows 95 product family.
- if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
+ else
{
- mOSStringSimple = "Microsoft Windows 95 ";
- if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
- {
- mOSStringSimple += "OSR2 ";
- }
- }
- if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
+ mOSStringSimple = "Microsoft Windows 8.1 ";
+ }
+ }
+ else if (IsWindows8OrGreater())
+ {
+ mMajorVer = 6;
+ mMinorVer = 2;
+ if (IsWindowsServer())
{
- mOSStringSimple = "Microsoft Windows 98 ";
- if ( osvi.szCSDVersion[1] == 'A' )
- {
- mOSStringSimple += "SE ";
- }
- }
- if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
+ mOSStringSimple = "Windows Server 2012 ";
+ }
+ else
{
- mOSStringSimple = "Microsoft Windows Millennium Edition ";
+ mOSStringSimple = "Microsoft Windows 8 ";
+ }
+ }
+ else if (IsWindows7SP1OrGreater())
+ {
+ mMajorVer = 6;
+ mMinorVer = 1;
+ if (IsWindowsServer())
+ {
+ mOSStringSimple = "Windows Server 2008 R2 SP1 ";
+ }
+ else
+ {
+ mOSStringSimple = "Microsoft Windows 7 SP1 ";
+ }
+ }
+ else if (IsWindows7OrGreater())
+ {
+ mMajorVer = 6;
+ mMinorVer = 1;
+ if (IsWindowsServer())
+ {
+ mOSStringSimple = "Windows Server 2008 R2 ";
+ }
+ else
+ {
+ mOSStringSimple = "Microsoft Windows 7 ";
}
- mOSString = mOSStringSimple;
- break;
}
+ else if (IsWindowsVistaSP2OrGreater())
+ {
+ mMajorVer = 6;
+ mMinorVer = 0;
+ if (IsWindowsServer())
+ {
+ mOSStringSimple = "Windows Server 2008 SP2 ";
+ }
+ else
+ {
+ mOSStringSimple = "Microsoft Windows Vista SP2 ";
+ }
+ }
+ else
+ {
+ mOSStringSimple = "Unsupported Windows version ";
+ }
+
+ ///get native system info if available..
+ typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo
+ SYSTEM_INFO si; //System Info object file contains architecture info
+ PGNSI pGNSI; //pointer object
+ ZeroMemory(&si, sizeof(SYSTEM_INFO)); //zero out the memory in information
+ pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function
+ if (NULL != pGNSI) //check if it has failed
+ pGNSI(&si); //success
+ else
+ GetSystemInfo(&si); //if it fails get regular system info
+ //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load)
- std::string compatibility_mode;
- if(got_shell32_version)
+ //msdn microsoft finds 32 bit and 64 bit flavors this way..
+ //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
+ //of windows than this code does (in case it is needed for the future)
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit
{
- if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion)
+ mOSStringSimple += "64-bit ";
+ }
+ else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
+ {
+ mOSStringSimple += "32-bit ";
+ }
+
+ // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
+ OSVERSIONINFOEX osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if (GetVersionEx((OSVERSIONINFO *)&osvi))
+ {
+ mBuild = osvi.dwBuildNumber & 0xffff;
+ }
+ else
+ {
+ // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (GetVersionEx((OSVERSIONINFO *)&osvi))
{
- compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
- shell32_major,
- shell32_minor,
- shell32_build);
+ mBuild = osvi.dwBuildNumber & 0xffff;
}
}
- mOSString += compatibility_mode;
+
+ mOSString = mOSStringSimple;
+ if (mBuild > 0)
+ {
+ mOSString += llformat("(Build %d)", mBuild);
+ }
+
+ LLStringUtil::trim(mOSStringSimple);
+ LLStringUtil::trim(mOSString);
#elif LL_DARWIN
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 266de7277d..f353109deb 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1561,6 +1561,15 @@ if (WINDOWS)
if (INTEL_MEMOPS_LIBRARY)
list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY})
endif (INTEL_MEMOPS_LIBRARY)
+
+ if (ADDRESS_SIZE EQUAL 64)
+ # We deliberately omit this from the 32bit build because it declares that
+ # the viewer is compatible with Windows 10; we need that to properly detect
+ # the Windows version, but doing so causes systems with certain HD video
+ # cards to fail because Windows 10 does not support them. Leaving this out
+ # causes those systems to run in a Windows 8 compatibility mode, which works.
+ LIST(APPEND viewer_SOURCE_FILES windows.manifest)
+ endif (ADDRESS_SIZE EQUAL 64)
endif (WINDOWS)
# Add the xui files. This is handy for searching for xui elements
diff --git a/indra/newview/windows.manifest b/indra/newview/windows.manifest
new file mode 100644
index 0000000000..8321ac5337
--- /dev/null
+++ b/indra/newview/windows.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>True/PM</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 10 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+ </compatibility>
+</assembly>