Windows2003-3790/windows/advcore/gdiplus/engine/runtime/osinfo.cpp
2020-09-30 16:53:55 +02:00

203 lines
5.0 KiB
C++

/**************************************************************************\
*
* Copyright (c) 1999 Microsoft Corporation
*
* Module Name:
*
* OS information
*
* Abstract:
*
* Describes the OS that is running
*
* Revision History:
*
* 05/13/1999 davidx
* Created it.
* 09/08/1999 agodfrey
* Moved to Runtime\OSInfo.cpp
*
\**************************************************************************/
#include "precomp.hpp"
namespace GpRuntime {
DWORD OSInfo::VAllocChunk;
DWORD OSInfo::PageSize;
DWORD OSInfo::MajorVersion;
DWORD OSInfo::MinorVersion;
BOOL OSInfo::IsNT;
BOOL OSInfo::HasMMX;
BOOL DetectMMXProcessor();
}
#ifdef _X86_
/**************************************************************************\
*
* Function Description:
*
* Detect whether the processor supports MMX
*
* Arguments:
*
* NONE
*
* Return Value:
*
* TRUE if the processor supports MMX
* FALSE otherwise
*
\**************************************************************************/
BOOL
GpRuntime::DetectMMXProcessor()
{
// NT 4.0 and up provide an API to check for MMX support; this handles
// floating-point emulation as well. We cannot implicitly reference this
// function because it's not exported by Windows 95 or NT < 4.0, so we
// must use GetProcAddress. Windows 98 and up do export the function, but
// it's stubbed, so we must also do an OS version check:
typedef BOOL (WINAPI *ISPROCESSORFEATUREPRESENTFUNCTION)(DWORD);
ISPROCESSORFEATUREPRESENTFUNCTION IsProcessorFeaturePresentFunction = NULL;
if ((OSInfo::IsNT) && (OSInfo::MajorVersion >= 4))
{
// LoadLibrary is not required since we're implicitly dependent on
// kernel32.dll, so just use GetModuleHandle:
HMODULE kernel32Handle = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32Handle != NULL)
{
IsProcessorFeaturePresentFunction =
(ISPROCESSORFEATUREPRESENTFUNCTION) GetProcAddress(
kernel32Handle, "IsProcessorFeaturePresent");
}
}
BOOL hasMMX;
if (IsProcessorFeaturePresentFunction != NULL)
{
hasMMX =
IsProcessorFeaturePresentFunction(PF_MMX_INSTRUCTIONS_AVAILABLE);
}
else
{
hasMMX = FALSE;
// IsProcessorFeaturePresent is unsupported on this OS, so we'll use
// CPUID to check for MMX support.
//
// If CPUID is unsupported on this processor, we'll take the
// exception. This will happen on most processors < Pentium, however
// some 486 processors support CPUID.
WARNING(("Executing processor detection; "
"benign first-change exception possible."));
__try
{
DWORD features;
// Get processor features using CPUID function 1:
__asm
{
push eax
push ebx
push ecx
push edx
mov eax, 1
cpuid
mov features, edx
pop edx
pop ecx
pop ebx
pop eax
}
// If bit 23 is set, MMX technology is supported by this
// processor, otherwise MMX is unsupported:
if (features & (1 << 23))
{
// Try executing an MMX instruction to make sure
// floating-point emulation is not on:
__asm emms
// If we made it this far, then MMX is available:
hasMMX = TRUE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// We should only be here if (1) the processor does not support
// CPUID or (2) CPUID is supported, but floating-point emulation
// is enabled.
}
}
return hasMMX;
}
#else // !_X86_
#define DetectMMXProcessor() FALSE
#endif // !_X86_
/**************************************************************************\
*
* Function Description:
*
* Static initialization function for OSInfo class.
* Called by GpRuntime::Initialize()
*
* Arguments:
*
* NONE
*
* Return Value:
*
* NONE
*
\**************************************************************************/
VOID
GpRuntime::OSInfo::Initialize()
{
// Get VM information
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
VAllocChunk = sysinfo.dwAllocationGranularity;
PageSize = sysinfo.dwPageSize;
// Get operating system version information
OSVERSIONINFOA osver;
osver.dwOSVersionInfoSize = sizeof(osver);
if (GetVersionExA(&osver))
{
IsNT = (osver.dwPlatformId == VER_PLATFORM_WIN32_NT);
MajorVersion = osver.dwMajorVersion;
MinorVersion = osver.dwMinorVersion;
}
// Check to see if MMX is available
HasMMX = DetectMMXProcessor();
}