Extended win OS detection to include vista and win7
This commit is contained in:
@@ -76,6 +76,75 @@ extern int errno;
|
|||||||
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
||||||
LLCPUInfo gSysCPU;
|
LLCPUInfo gSysCPU;
|
||||||
|
|
||||||
|
#if LL_WINDOWS
|
||||||
|
#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
|
||||||
|
|
||||||
LLOSInfo::LLOSInfo() :
|
LLOSInfo::LLOSInfo() :
|
||||||
mMajorVer(0), mMinorVer(0), mBuild(0)
|
mMajorVer(0), mMinorVer(0), mBuild(0)
|
||||||
{
|
{
|
||||||
@@ -98,6 +167,11 @@ LLOSInfo::LLOSInfo() :
|
|||||||
mMinorVer = osvi.dwMinorVersion;
|
mMinorVer = osvi.dwMinorVersion;
|
||||||
mBuild = osvi.dwBuildNumber;
|
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)
|
switch(osvi.dwPlatformId)
|
||||||
{
|
{
|
||||||
case VER_PLATFORM_WIN32_NT:
|
case VER_PLATFORM_WIN32_NT:
|
||||||
@@ -122,14 +196,50 @@ LLOSInfo::LLOSInfo() :
|
|||||||
else
|
else
|
||||||
mOSStringSimple = "Microsoft Windows Server 2003 ";
|
mOSStringSimple = "Microsoft Windows Server 2003 ";
|
||||||
}
|
}
|
||||||
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
|
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 1)
|
||||||
{
|
{
|
||||||
if(osvi.wProductType == VER_NT_WORKSTATION)
|
if(osvi.dwMinorVersion == 0)
|
||||||
|
{
|
||||||
mOSStringSimple = "Microsoft Windows Vista ";
|
mOSStringSimple = "Microsoft Windows Vista ";
|
||||||
else mOSStringSimple = "Microsoft Windows Vista Server ";
|
}
|
||||||
|
else if(osvi.dwMinorVersion == 1)
|
||||||
|
{
|
||||||
|
mOSStringSimple = "Microsoft Windows 7 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osvi.wProductType != VER_NT_WORKSTATION)
|
||||||
|
{
|
||||||
|
mOSStringSimple += "Server ";
|
||||||
|
}
|
||||||
|
|
||||||
|
///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.
|
else // Use the registry on early versions of Windows NT.
|
||||||
{
|
{
|
||||||
|
mOSStringSimple = "Microsoft Windows (unrecognized) ";
|
||||||
|
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
WCHAR szProductType[80];
|
WCHAR szProductType[80];
|
||||||
DWORD dwBufLen;
|
DWORD dwBufLen;
|
||||||
@@ -170,6 +280,7 @@ LLOSInfo::LLOSInfo() :
|
|||||||
csdversion.c_str(),
|
csdversion.c_str(),
|
||||||
(osvi.dwBuildNumber & 0xffff));
|
(osvi.dwBuildNumber & 0xffff));
|
||||||
}
|
}
|
||||||
|
|
||||||
mOSString = mOSStringSimple + tmpstr;
|
mOSString = mOSStringSimple + tmpstr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -199,6 +310,21 @@ LLOSInfo::LLOSInfo() :
|
|||||||
mOSString = mOSStringSimple;
|
mOSString = mOSStringSimple;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string compatibility_mode;
|
||||||
|
if(got_shell32_version)
|
||||||
|
{
|
||||||
|
if(osvi.dwMajorVersion != shell32_major
|
||||||
|
|| osvi.dwMinorVersion != shell32_minor)
|
||||||
|
{
|
||||||
|
compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
|
||||||
|
shell32_major,
|
||||||
|
shell32_minor,
|
||||||
|
shell32_build);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mOSString += compatibility_mode;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct utsname un;
|
struct utsname un;
|
||||||
if(uname(&un) != -1)
|
if(uname(&un) != -1)
|
||||||
@@ -226,8 +352,8 @@ LLOSInfo::LLOSInfo() :
|
|||||||
else if (ostype == "Linux")
|
else if (ostype == "Linux")
|
||||||
{
|
{
|
||||||
// Only care about major and minor Linux versions, truncate at second '.'
|
// Only care about major and minor Linux versions, truncate at second '.'
|
||||||
S32 idx1 = mOSStringSimple.find_first_of(".", 0);
|
std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0);
|
||||||
S32 idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos;
|
std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos;
|
||||||
std::string simple = mOSStringSimple.substr(0, idx2);
|
std::string simple = mOSStringSimple.substr(0, idx2);
|
||||||
if (simple.length() > 0)
|
if (simple.length() > 0)
|
||||||
mOSStringSimple = simple;
|
mOSStringSimple = simple;
|
||||||
@@ -393,15 +519,15 @@ LLCPUInfo::LLCPUInfo()
|
|||||||
mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions;
|
mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions;
|
||||||
mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions;
|
mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions;
|
||||||
mHasAltivec = info->_Ext.Altivec_Extensions;
|
mHasAltivec = info->_Ext.Altivec_Extensions;
|
||||||
mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0);
|
mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0);
|
||||||
mFamily.assign( info->strFamily );
|
mFamily.assign( info->strFamily );
|
||||||
mCPUString = "Unknown";
|
mCPUString = "Unknown";
|
||||||
|
|
||||||
#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
|
#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
|
||||||
out << proc.strCPUName;
|
out << proc.strCPUName;
|
||||||
if (200 < mCPUMhz && mCPUMhz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check
|
if (200 < mCPUMHz && mCPUMHz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check
|
||||||
{
|
{
|
||||||
out << " (" << mCPUMhz << " MHz)";
|
out << " (" << mCPUMHz << " MHz)";
|
||||||
}
|
}
|
||||||
mCPUString = out.str();
|
mCPUString = out.str();
|
||||||
|
|
||||||
@@ -446,7 +572,7 @@ LLCPUInfo::LLCPUInfo()
|
|||||||
if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz)
|
if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz)
|
||||||
&& 200.0 < mhz && mhz < 10000.0)
|
&& 200.0 < mhz && mhz < 10000.0)
|
||||||
{
|
{
|
||||||
mCPUMhz = (S32)llrint(mhz);
|
mCPUMHz = (F64)llrint(mhz);
|
||||||
}
|
}
|
||||||
if (!cpuinfo["model name"].empty())
|
if (!cpuinfo["model name"].empty())
|
||||||
mCPUString = cpuinfo["model name"];
|
mCPUString = cpuinfo["model name"];
|
||||||
@@ -469,9 +595,9 @@ bool LLCPUInfo::hasSSE2() const
|
|||||||
return mHasSSE2;
|
return mHasSSE2;
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 LLCPUInfo::getMhz() const
|
F64 LLCPUInfo::getMHz() const
|
||||||
{
|
{
|
||||||
return mCPUMhz;
|
return mCPUMHz;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LLCPUInfo::getCPUString() const
|
std::string LLCPUInfo::getCPUString() const
|
||||||
@@ -518,7 +644,7 @@ void LLCPUInfo::stream(std::ostream& s) const
|
|||||||
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
|
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
|
||||||
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
|
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
|
||||||
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
|
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
|
||||||
s << "->mCPUMhz: " << mCPUMhz << std::endl;
|
s << "->mCPUMHz: " << mCPUMHz << std::endl;
|
||||||
s << "->mCPUString: " << mCPUString << std::endl;
|
s << "->mCPUString: " << mCPUString << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,6 +721,26 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
|
||||||
|
{
|
||||||
|
#if LL_WINDOWS
|
||||||
|
MEMORYSTATUSEX state;
|
||||||
|
state.dwLength = sizeof(state);
|
||||||
|
GlobalMemoryStatusEx(&state);
|
||||||
|
|
||||||
|
avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
|
||||||
|
avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
|
||||||
|
|
||||||
|
#else
|
||||||
|
//do not know how to collect available memory info for other systems.
|
||||||
|
//leave it blank here for now.
|
||||||
|
|
||||||
|
avail_physical_mem_kb = -1 ;
|
||||||
|
avail_virtual_mem_kb = -1 ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void LLMemoryInfo::stream(std::ostream& s) const
|
void LLMemoryInfo::stream(std::ostream& s) const
|
||||||
{
|
{
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
bool hasAltivec() const;
|
bool hasAltivec() const;
|
||||||
bool hasSSE() const;
|
bool hasSSE() const;
|
||||||
bool hasSSE2() const;
|
bool hasSSE2() const;
|
||||||
S32 getMhz() const;
|
F64 getMHz() const;
|
||||||
|
|
||||||
// Family is "AMD Duron" or "Intel Pentium Pro"
|
// Family is "AMD Duron" or "Intel Pentium Pro"
|
||||||
const std::string& getFamily() const { return mFamily; }
|
const std::string& getFamily() const { return mFamily; }
|
||||||
@@ -90,7 +90,7 @@ private:
|
|||||||
bool mHasSSE;
|
bool mHasSSE;
|
||||||
bool mHasSSE2;
|
bool mHasSSE2;
|
||||||
bool mHasAltivec;
|
bool mHasAltivec;
|
||||||
S32 mCPUMhz;
|
F64 mCPUMHz;
|
||||||
std::string mFamily;
|
std::string mFamily;
|
||||||
std::string mCPUString;
|
std::string mCPUString;
|
||||||
};
|
};
|
||||||
@@ -120,6 +120,9 @@ public:
|
|||||||
** be returned.
|
** be returned.
|
||||||
*/
|
*/
|
||||||
U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
|
U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
|
||||||
|
|
||||||
|
//get the available memory infomation in KiloBytes.
|
||||||
|
static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -800,7 +800,7 @@ bool LLAppViewer::init()
|
|||||||
minSpecs += "\n";
|
minSpecs += "\n";
|
||||||
unsupported = true;
|
unsupported = true;
|
||||||
}
|
}
|
||||||
if(gSysCPU.getMhz() < minCPU)
|
if(gSysCPU.getMHz() < minCPU)
|
||||||
{
|
{
|
||||||
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
|
minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
|
||||||
minSpecs += "\n";
|
minSpecs += "\n";
|
||||||
@@ -2358,7 +2358,7 @@ void LLAppViewer::writeSystemInfo()
|
|||||||
//need to put in something to lie about this stuff
|
//need to put in something to lie about this stuff
|
||||||
gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
|
gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
|
||||||
gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
|
gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
|
||||||
gDebugInfo["CPUInfo"]["CPUMhz"] = gSysCPU.getMhz();
|
gDebugInfo["CPUInfo"]["CPUMhz"] = gSysCPU.getMHz();
|
||||||
gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
|
gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
|
||||||
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
|
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
|
||||||
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
|
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
|
||||||
|
|||||||
@@ -627,9 +627,9 @@ void LLFeatureManager::applyBaseMasks()
|
|||||||
|
|
||||||
#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast
|
#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast
|
||||||
#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
|
#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
|
||||||
if (gSysCPU.getMhz() < 800)
|
if (gSysCPU.getMHz() < 800)
|
||||||
#else
|
#else
|
||||||
if (gSysCPU.getMhz() < 1100)
|
if (gSysCPU.getMHz() < 1100)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
maskFeatures("CPUSlow");
|
maskFeatures("CPUSlow");
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ LLViewerJoystick::LLViewerJoystick()
|
|||||||
memset(mBtn, 0, sizeof(mBtn));
|
memset(mBtn, 0, sizeof(mBtn));
|
||||||
|
|
||||||
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
|
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
|
||||||
mPerfScale = 4000.f / gSysCPU.getMhz();
|
mPerfScale = 4000.f / gSysCPU.getMHz();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user