2024-09-24 12:54:57 +00:00
/*
* mptOS . cpp
* - - - - - - - - -
* Purpose : Operating system version information .
* Notes : ( currently none )
* Authors : OpenMPT Devs
* The OpenMPT source code is released under the BSD license . Read LICENSE for more details .
*/
# include "stdafx.h"
# include "mptOS.h"
# include "mpt/binary/hex.hpp"
# if MPT_OS_WINDOWS
2024-09-29 02:04:03 +00:00
# include <arch.h>
2024-09-24 12:54:57 +00:00
# endif
OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
namespace OS
{
namespace Windows
{
# if MPT_OS_WINDOWS
namespace {
struct WindowsVersionCache
{
2024-09-29 02:04:03 +00:00
mpt : : osinfo : : arch : : Version version ;
2024-09-24 12:54:57 +00:00
WindowsVersionCache ( ) noexcept
2024-09-29 02:04:03 +00:00
: version ( mpt : : osinfo : : arch : : Version : : Current ( ) )
2024-09-24 12:54:57 +00:00
{
}
} ;
}
2024-09-29 02:04:03 +00:00
static mpt : : osinfo : : arch : : Version GatherWindowsVersionFromCache ( ) noexcept
2024-09-24 12:54:57 +00:00
{
static WindowsVersionCache gs_WindowsVersionCache ;
return gs_WindowsVersionCache . version ;
}
# endif // MPT_OS_WINDOWS
2024-09-29 02:04:03 +00:00
mpt : : osinfo : : arch : : Version Version : : Current ( ) noexcept
2024-09-24 12:54:57 +00:00
{
# if MPT_OS_WINDOWS
# ifdef MODPLUG_TRACKER
return GatherWindowsVersionFromCache ( ) ;
# else // !MODPLUG_TRACKER
2024-09-29 02:04:03 +00:00
return mpt : : osinfo : : arch : : Version : : Current ( ) ;
2024-09-24 12:54:57 +00:00
# endif // MODPLUG_TRACKER
# else // !MPT_OS_WINDOWS
2024-09-29 02:04:03 +00:00
return mpt : : osinfo : : arch : : Version : : NoWindows ( ) ;
2024-09-24 12:54:57 +00:00
# endif // MPT_OS_WINDOWS
}
2024-09-29 02:04:03 +00:00
static constexpr struct { mpt : : osinfo : : arch : : Version version ; const mpt : : uchar * name ; bool showDetails ; } versionMap [ ] =
{
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : WinNewer , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 22000 , 0 } , UL_ ( " Windows 11 (or newer) " ) , false } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 22000 , 0 } , UL_ ( " Windows 11 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 19044 , 0 } , UL_ ( " Windows 10 21H2 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 19043 , 0 } , UL_ ( " Windows 10 21H1 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 19042 , 0 } , UL_ ( " Windows 10 20H2 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 19041 , 0 } , UL_ ( " Windows 10 2004 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 18363 , 0 } , UL_ ( " Windows 10 1909 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 18362 , 0 } , UL_ ( " Windows 10 1903 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 17763 , 0 } , UL_ ( " Windows 10 1809 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 17134 , 0 } , UL_ ( " Windows 10 1803 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 16299 , 0 } , UL_ ( " Windows 10 1709 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 15063 , 0 } , UL_ ( " Windows 10 1703 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 14393 , 0 } , UL_ ( " Windows 10 1607 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 10586 , 0 } , UL_ ( " Windows 10 1511 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win10 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 10240 , 0 } , UL_ ( " Windows 10 1507 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win81 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows 8.1 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win8 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows 8 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win7 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows 7 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : WinVista , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows Vista " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : WinXP64 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows XP x64 / Windows Server 2003 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : WinXP , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows XP " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : Win2000 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows 2000 " ) , true } ,
{ mpt : : osinfo : : arch : : Version { mpt : : osinfo : : arch : : Version : : WinNT4 , mpt : : osinfo : : arch : : Version : : ServicePack { 0 , 0 } , 0 , 0 } , UL_ ( " Windows NT4 " ) , true }
2024-09-24 12:54:57 +00:00
} ;
2024-09-29 02:04:03 +00:00
mpt : : ustring Version : : GetName ( mpt : : osinfo : : arch : : Version version )
2024-09-24 12:54:57 +00:00
{
mpt : : ustring name = U_ ( " Generic Windows NT " ) ;
bool showDetails = false ;
for ( const auto & v : versionMap )
{
if ( version . IsAtLeast ( v . version ) )
{
name = v . name ;
showDetails = v . showDetails ;
break ;
}
}
name + = U_ ( " ( " ) ;
name + = MPT_UFORMAT ( " Version {}.{} " ) ( version . GetSystem ( ) . Major , version . GetSystem ( ) . Minor ) ;
if ( showDetails )
{
if ( version . GetServicePack ( ) . HasServicePack ( ) )
{
if ( version . GetServicePack ( ) . Minor )
{
name + = MPT_UFORMAT ( " Service Pack {}.{} " ) ( version . GetServicePack ( ) . Major , version . GetServicePack ( ) . Minor ) ;
} else
{
name + = MPT_UFORMAT ( " Service Pack {} " ) ( version . GetServicePack ( ) . Major ) ;
}
}
if ( version . GetBuild ( ) ! = 0 )
{
name + = MPT_UFORMAT ( " (Build {}) " ) ( version . GetBuild ( ) ) ;
}
}
name + = U_ ( " ) " ) ;
mpt : : ustring result = name ;
# if defined(MODPLUG_TRACKER) && MPT_OS_WINDOWS
if ( mpt : : OS : : Windows : : IsWine ( ) )
{
mpt : : OS : : Wine : : VersionContext v ;
if ( v . Version ( ) . IsValid ( ) )
{
result = MPT_UFORMAT ( " Wine {} ({}) " ) (
v . Version ( ) . AsString ( )
, name
) ;
} else
{
result = MPT_UFORMAT ( " Wine (unknown version: '{}') ({}) " ) (
mpt : : ToUnicode ( mpt : : Charset : : UTF8 , v . RawVersion ( ) )
, name
) ;
}
}
# endif // MODPLUG_TRACKER && MPT_OS_WINDOWS
return result ;
}
2024-09-29 02:04:03 +00:00
mpt : : osinfo : : arch : : Version Version : : GetMinimumKernelLevel ( ) noexcept
2024-09-24 12:54:57 +00:00
{
uint64 minimumKernelVersion = 0 ;
# if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
# if defined(MPT_BUILD_RETRO)
2024-09-29 02:04:03 +00:00
minimumKernelVersion = std : : max ( minimumKernelVersion , static_cast < uint64 > ( mpt : : osinfo : : arch : : Version : : WinXP ) ) ;
2024-09-24 12:54:57 +00:00
# else
2024-09-29 02:04:03 +00:00
minimumKernelVersion = std : : max ( minimumKernelVersion , static_cast < uint64 > ( mpt : : osinfo : : arch : : Version : : WinVista ) ) ;
2024-09-24 12:54:57 +00:00
# endif
# endif
2024-09-29 02:04:03 +00:00
return mpt : : osinfo : : arch : : Version ( mpt : : osinfo : : arch : : Version : : System ( minimumKernelVersion ) , mpt : : osinfo : : arch : : Version : : ServicePack ( 0 , 0 ) , 0 , 0 ) ;
2024-09-24 12:54:57 +00:00
}
2024-09-29 02:04:03 +00:00
mpt : : osinfo : : arch : : Version Version : : GetMinimumAPILevel ( ) noexcept
2024-09-24 12:54:57 +00:00
{
# if MPT_OS_WINDOWS
2024-09-29 02:04:03 +00:00
return mpt : : osinfo : : arch : : Version : : FromSDK ( ) ;
2024-09-24 12:54:57 +00:00
# else // !MPT_OS_WINDOWS
2024-09-29 02:04:03 +00:00
return mpt : : osinfo : : arch : : Version : : NoWindows ( ) ;
2024-09-24 12:54:57 +00:00
# endif // MPT_OS_WINDOWS
}
# if MPT_OS_WINDOWS
# ifndef PROCESSOR_ARCHITECTURE_NEUTRAL
# define PROCESSOR_ARCHITECTURE_NEUTRAL 11
# endif
# ifndef PROCESSOR_ARCHITECTURE_ARM64
# define PROCESSOR_ARCHITECTURE_ARM64 12
# endif
# ifndef PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64
# define PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 13
# endif
# ifndef PROCESSOR_ARCHITECTURE_IA32_ON_ARM64
# define PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 14
# endif
struct OSArchitecture
{
uint16 ProcessorArchitectur ;
Architecture Host ;
Architecture Process ;
} ;
static constexpr OSArchitecture architectures [ ] = {
{ PROCESSOR_ARCHITECTURE_INTEL , Architecture : : x86 , Architecture : : x86 } ,
{ PROCESSOR_ARCHITECTURE_AMD64 , Architecture : : amd64 , Architecture : : amd64 } ,
{ PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 , Architecture : : amd64 , Architecture : : x86 } ,
{ PROCESSOR_ARCHITECTURE_ARM , Architecture : : arm , Architecture : : arm } ,
{ PROCESSOR_ARCHITECTURE_ARM64 , Architecture : : arm64 , Architecture : : arm64 } ,
{ PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 , Architecture : : arm64 , Architecture : : arm } ,
{ PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 , Architecture : : arm64 , Architecture : : x86 } ,
{ PROCESSOR_ARCHITECTURE_MIPS , Architecture : : mips , Architecture : : mips } ,
{ PROCESSOR_ARCHITECTURE_PPC , Architecture : : ppc , Architecture : : ppc } ,
{ PROCESSOR_ARCHITECTURE_SHX , Architecture : : shx , Architecture : : shx } ,
{ PROCESSOR_ARCHITECTURE_ALPHA , Architecture : : alpha , Architecture : : alpha } ,
{ PROCESSOR_ARCHITECTURE_ALPHA64 , Architecture : : alpha64 , Architecture : : alpha64 } ,
{ PROCESSOR_ARCHITECTURE_IA64 , Architecture : : ia64 , Architecture : : ia64 } ,
{ PROCESSOR_ARCHITECTURE_MSIL , Architecture : : unknown , Architecture : : unknown } ,
{ PROCESSOR_ARCHITECTURE_NEUTRAL , Architecture : : unknown , Architecture : : unknown } ,
{ PROCESSOR_ARCHITECTURE_UNKNOWN , Architecture : : unknown , Architecture : : unknown }
} ;
struct HostArchitecture
{
Architecture Host ;
Architecture Process ;
EmulationLevel Emulation ;
} ;
static constexpr HostArchitecture hostArchitectureCanRun [ ] = {
{ Architecture : : x86 , Architecture : : x86 , EmulationLevel : : Native } ,
{ Architecture : : amd64 , Architecture : : amd64 , EmulationLevel : : Native } ,
{ Architecture : : amd64 , Architecture : : x86 , EmulationLevel : : Virtual } ,
{ Architecture : : arm , Architecture : : arm , EmulationLevel : : Native } ,
{ Architecture : : arm64 , Architecture : : arm64 , EmulationLevel : : Native } ,
{ Architecture : : arm64 , Architecture : : arm , EmulationLevel : : Virtual } ,
{ Architecture : : arm64 , Architecture : : x86 , EmulationLevel : : Software } ,
{ Architecture : : arm64 , Architecture : : amd64 , EmulationLevel : : Software } ,
{ Architecture : : mips , Architecture : : mips , EmulationLevel : : Native } ,
{ Architecture : : ppc , Architecture : : ppc , EmulationLevel : : Native } ,
{ Architecture : : shx , Architecture : : shx , EmulationLevel : : Native } ,
{ Architecture : : alpha , Architecture : : alpha , EmulationLevel : : Native } ,
{ Architecture : : alpha64 , Architecture : : alpha64 , EmulationLevel : : Native } ,
{ Architecture : : alpha64 , Architecture : : alpha , EmulationLevel : : Virtual } ,
{ Architecture : : ia64 , Architecture : : ia64 , EmulationLevel : : Native } ,
{ Architecture : : ia64 , Architecture : : x86 , EmulationLevel : : Hardware }
} ;
struct ArchitectureInfo
{
Architecture Arch ;
int Bitness ;
const mpt : : uchar * Name ;
} ;
static constexpr ArchitectureInfo architectureInfo [ ] = {
{ Architecture : : x86 , 32 , UL_ ( " x86 " ) } ,
{ Architecture : : amd64 , 64 , UL_ ( " amd64 " ) } ,
{ Architecture : : arm , 32 , UL_ ( " arm " ) } ,
{ Architecture : : arm64 , 64 , UL_ ( " arm64 " ) } ,
{ Architecture : : mips , 32 , UL_ ( " mips " ) } ,
{ Architecture : : ppc , 32 , UL_ ( " ppc " ) } ,
{ Architecture : : shx , 32 , UL_ ( " shx " ) } ,
{ Architecture : : alpha , 32 , UL_ ( " alpha " ) } ,
{ Architecture : : alpha64 , 64 , UL_ ( " alpha64 " ) } ,
{ Architecture : : ia64 , 64 , UL_ ( " ia64 " ) }
} ;
int Bitness ( Architecture arch ) noexcept
{
for ( const auto & info : architectureInfo )
{
if ( arch = = info . Arch )
{
return info . Bitness ;
}
}
return 0 ;
}
mpt : : ustring Name ( Architecture arch )
{
for ( const auto & info : architectureInfo )
{
if ( arch = = info . Arch )
{
return info . Name ;
}
}
return mpt : : ustring ( ) ;
}
Architecture GetHostArchitecture ( ) noexcept
{
SYSTEM_INFO systemInfo = { } ;
GetNativeSystemInfo ( & systemInfo ) ;
for ( const auto & arch : architectures )
{
if ( systemInfo . wProcessorArchitecture = = arch . ProcessorArchitectur )
{
return arch . Host ;
}
}
return Architecture : : unknown ;
}
Architecture GetProcessArchitecture ( ) noexcept
{
SYSTEM_INFO systemInfo = { } ;
GetSystemInfo ( & systemInfo ) ;
for ( const auto & arch : architectures )
{
if ( systemInfo . wProcessorArchitecture = = arch . ProcessorArchitectur )
{
return arch . Process ;
}
}
return Architecture : : unknown ;
}
EmulationLevel HostCanRun ( Architecture host , Architecture process ) noexcept
{
for ( const auto & can : hostArchitectureCanRun )
{
if ( can . Host = = host & & can . Process = = process )
{
return can . Emulation ;
}
}
return EmulationLevel : : NA ;
}
std : : vector < Architecture > GetSupportedProcessArchitectures ( Architecture host )
{
std : : vector < Architecture > result ;
for ( const auto & entry : hostArchitectureCanRun )
{
if ( entry . Host = = host )
{
result . push_back ( entry . Process ) ;
}
}
return result ;
}
uint64 GetSystemMemorySize ( )
{
MEMORYSTATUSEX memoryStatus = { } ;
memoryStatus . dwLength = sizeof ( MEMORYSTATUSEX ) ;
if ( GlobalMemoryStatusEx ( & memoryStatus ) = = 0 )
{
return 0 ;
}
return memoryStatus . ullTotalPhys ;
}
# endif // MPT_OS_WINDOWS
# if defined(MODPLUG_TRACKER)
# if MPT_OS_WINDOWS
static bool GatherSystemIsWine ( )
{
bool SystemIsWine = false ;
std : : optional < mpt : : library > NTDLL = mpt : : library : : load ( { mpt : : library : : path_search : : system , mpt : : library : : path_prefix : : none , MPT_PATH ( " ntdll.dll " ) , mpt : : library : : path_suffix : : none } ) ;
if ( NTDLL )
{
SystemIsWine = ( NTDLL - > get_address ( " wine_get_version " ) ! = nullptr ) ;
}
return SystemIsWine ;
}
namespace {
struct SystemIsWineCache
{
bool SystemIsWine ;
SystemIsWineCache ( )
: SystemIsWine ( GatherSystemIsWine ( ) )
{
return ;
}
SystemIsWineCache ( bool isWine )
: SystemIsWine ( isWine )
{
return ;
}
} ;
}
# endif // MPT_OS_WINDOWS
static bool SystemIsWine ( bool allowDetection = true )
{
# if MPT_OS_WINDOWS
static SystemIsWineCache gs_SystemIsWineCache = allowDetection ? SystemIsWineCache ( ) : SystemIsWineCache ( false ) ;
if ( ! allowDetection )
{ // catch too late calls of PreventWineDetection
MPT_ASSERT ( ! gs_SystemIsWineCache . SystemIsWine ) ;
}
return gs_SystemIsWineCache . SystemIsWine ;
# else
MPT_UNREFERENCED_PARAMETER ( allowDetection ) ;
return false ;
# endif
}
void PreventWineDetection ( )
{
SystemIsWine ( false ) ;
}
bool IsOriginal ( )
{
return mpt : : OS : : Windows : : Version : : Current ( ) . IsWindows ( ) & & ! SystemIsWine ( ) ;
}
bool IsWine ( )
{
return mpt : : OS : : Windows : : Version : : Current ( ) . IsWindows ( ) & & SystemIsWine ( ) ;
}
# endif // MODPLUG_TRACKER
} // namespace Windows
} // namespace OS
} // namespace mpt
namespace mpt
{
namespace OS
{
namespace Wine
{
Version : : Version ( )
{
return ;
}
Version : : Version ( const mpt : : ustring & rawVersion )
2024-09-29 02:04:03 +00:00
: mpt : : osinfo : : arch : : wine : : version ( )
2024-09-24 12:54:57 +00:00
{
if ( rawVersion . empty ( ) )
{
return ;
}
std : : vector < uint8 > version = mpt : : String : : Split < uint8 > ( rawVersion , U_ ( " . " ) ) ;
if ( version . size ( ) < 2 )
{
return ;
}
mpt : : ustring parsedVersion = mpt : : String : : Combine ( version , U_ ( " . " ) ) ;
std : : size_t len = std : : min ( parsedVersion . length ( ) , rawVersion . length ( ) ) ;
if ( len = = 0 )
{
return ;
}
if ( parsedVersion . substr ( 0 , len ) ! = rawVersion . substr ( 0 , len ) )
{
return ;
}
valid = true ;
vmajor = version [ 0 ] ;
vminor = version [ 1 ] ;
vupdate = ( version . size ( ) > = 3 ) ? version [ 2 ] : 0 ;
}
Version : : Version ( uint8 vmajor , uint8 vminor , uint8 vupdate )
2024-09-29 02:04:03 +00:00
: mpt : : osinfo : : arch : : wine : : version ( vmajor , vminor , vupdate )
2024-09-24 12:54:57 +00:00
{
return ;
}
mpt : : ustring Version : : AsString ( ) const
{
return mpt : : ufmt : : dec ( GetMajor ( ) ) + U_ ( " . " ) + mpt : : ufmt : : dec ( GetMinor ( ) ) + U_ ( " . " ) + mpt : : ufmt : : dec ( GetUpdate ( ) ) ;
}
mpt : : OS : : Wine : : Version GetMinimumWineVersion ( )
{
mpt : : OS : : Wine : : Version minimumWineVersion = mpt : : OS : : Wine : : Version ( 0 , 0 , 0 ) ;
# if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
minimumWineVersion = mpt : : OS : : Wine : : Version ( 1 , 8 , 0 ) ;
# endif
return minimumWineVersion ;
}
VersionContext : : VersionContext ( )
: m_IsWine ( false )
, m_HostClass ( mpt : : osinfo : : osclass : : Unknown )
{
# if MPT_OS_WINDOWS
m_IsWine = mpt : : OS : : Windows : : IsWine ( ) ;
if ( ! m_IsWine )
{
return ;
}
std : : optional < mpt : : library > NTDLL = mpt : : library : : load ( { mpt : : library : : path_search : : system , mpt : : library : : path_prefix : : none , MPT_PATH ( " ntdll.dll " ) , mpt : : library : : path_suffix : : none } ) ;
if ( NTDLL )
{
const char * ( __cdecl * wine_get_version ) ( void ) = nullptr ;
const char * ( __cdecl * wine_get_build_id ) ( void ) = nullptr ;
void ( __cdecl * wine_get_host_version ) ( const char * * , const char * * ) = nullptr ;
NTDLL - > bind ( wine_get_version , " wine_get_version " ) ;
NTDLL - > bind ( wine_get_build_id , " wine_get_build_id " ) ;
NTDLL - > bind ( wine_get_host_version , " wine_get_host_version " ) ;
const char * wine_version = nullptr ;
const char * wine_build_id = nullptr ;
const char * wine_host_sysname = nullptr ;
const char * wine_host_release = nullptr ;
wine_version = wine_get_version ? wine_get_version ( ) : " " ;
wine_build_id = wine_get_build_id ? wine_get_build_id ( ) : " " ;
if ( wine_get_host_version )
{
wine_get_host_version ( & wine_host_sysname , & wine_host_release ) ;
}
m_RawVersion = wine_version ? wine_version : " " ;
m_RawBuildID = wine_build_id ? wine_build_id : " " ;
m_RawHostSysName = wine_host_sysname ? wine_host_sysname : " " ;
m_RawHostRelease = wine_host_release ? wine_host_release : " " ;
}
m_Version = mpt : : OS : : Wine : : Version ( mpt : : ToUnicode ( mpt : : Charset : : UTF8 , m_RawVersion ) ) ;
m_HostClass = mpt : : osinfo : : get_class_from_sysname ( m_RawHostSysName ) ;
# endif // MPT_OS_WINDOWS
}
} // namespace Wine
} // namespace OS
} // namespace mpt
OPENMPT_NAMESPACE_END