#include "../osbs.h"
#include <sewer/cassert.h>
#include <sewer/unicode.h>
#if !defined(__WINDOWS__)
#error This file is for Windows
#endif
#include <sewer/nowarn.hxx>
#include <Windows.h>
#undef __VERSION_HELPERS__
#if defined(_MSC_VER)
#if _MSC_VER >= 1800
#define __VERSION_HELPERS__
#endif
#elif defined(__GNUC__)
#define __VERSION_HELPERS__
#endif
#if defined __VERSION_HELPERS__
#include <VersionHelpers.h>
#endif
#include <sewer/warn.hxx>
static win_t i_WIN_VERSION = ENUM_MAX(win_t);
static endian_t i_ENDIANNESS = ENUM_MAX(endian_t);
union i_check_endianness
{
unsigned char bytes[4];
uint32_t value;
};
static const uint32_t i_LITTLE_ENDIAN = 0x03020100;
static const uint32_t i_BIG_ENDIAN = 0x00010203;
platform_t osbs_platform(void)
{
return ekWINDOWS;
}
static win_t i_win_version(void)
{
#if defined(__VERSION_HELPERS__)
#if defined(_WIN32_WINNT_WIN10)
if (IsWindows10OrGreater() == TRUE)
return ekWIN_10;
#endif
if (IsWindows8Point1OrGreater() == TRUE)
return ekWIN_81;
if (IsWindows8OrGreater() == TRUE)
return ekWIN_8;
if (IsWindows7SP1OrGreater() == TRUE)
return ekWIN_71;
if (IsWindows7OrGreater() == TRUE)
return ekWIN_7;
if (IsWindowsVistaSP2OrGreater() == TRUE)
return ekWIN_VI2;
if (IsWindowsVistaSP1OrGreater() == TRUE)
return ekWIN_VI1;
if (IsWindowsVistaOrGreater() == TRUE)
return ekWIN_VI;
if (IsWindowsXPSP3OrGreater() == TRUE)
return ekWIN_XP3;
if (IsWindowsXPSP2OrGreater() == TRUE)
return ekWIN_XP2;
if (IsWindowsXPSP1OrGreater() == TRUE)
return ekWIN_XP1;
if (IsWindowsXPOrGreater() == TRUE)
return ekWIN_XP;
if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN2K), LOBYTE(_WIN32_WINNT_WIN2K), 0))
return ekWIN_2K;
if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_NT4), LOBYTE(_WIN32_WINNT_NT4), 0))
return ekWIN_NT4;
return ekWIN_9x;
#else
BOOL ok;
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
ok = GetVersionEx(&info);
cassert(ok != 0);
if (info.dwMajorVersion < 5)
{
return ekWIN_2K;
}
else if (info.dwMajorVersion == 5)
{
if (info.dwMinorVersion < 1)
return ekWIN_2K;
else
return ekWIN_XP;
}
else if (info.dwMajorVersion == 6)
{
if (info.dwMinorVersion == 0)
return ekWIN_VI;
else if (info.dwMinorVersion == 1)
return ekWIN_7;
else if (info.dwMinorVersion <= 3)
return ekWIN_8;
cassert(FALSE);
return ekWIN_8;
}
else if (info.dwMajorVersion > 6 && info.dwMajorVersion < 10)
{
cassert(FALSE);
return ekWIN_8;
}
else if (info.dwMajorVersion == 10)
{
if (info.dwMinorVersion == 0)
{
return ekWIN_10;
}
else
{
cassert(FALSE);
return ekWIN_10;
}
}
else
{
cassert(FALSE);
return ekWIN_10;
}
#endif
}
win_t osbs_windows(void)
{
if (i_WIN_VERSION == ENUM_MAX(win_t))
i_WIN_VERSION = i_win_version();
return i_WIN_VERSION;
}
endian_t osbs_endian(void)
{
if (i_ENDIANNESS == ENUM_MAX(endian_t))
{
union i_check_endianness i_O32_HOST_ORDER = {{0, 1, 2, 3}};
uint32_t endianness = i_O32_HOST_ORDER.value;
cassert(endianness == i_LITTLE_ENDIAN);
if (endianness == i_LITTLE_ENDIAN)
i_ENDIANNESS = ekLITEND;
else if (endianness == i_BIG_ENDIAN)
i_ENDIANNESS = ekBIGEND;
}
return i_ENDIANNESS;
}