From 8545d4b8b69da5aa88ab899a705b2c62b176509d Mon Sep 17 00:00:00 2001 From: Aleksander Czajczynski Date: Sun, 11 Feb 2018 23:40:11 +0100 Subject: [PATCH] 2018-02-11 23:40 UTC+0100 Aleksander Czajczynski (hb fki.pl) * include/hbapi.h * src/common/hbver.c * src/harbour.def * contrib/hbwin/win_osc.c * synced Windows version detection code with Viktor's work in 3.4 * src/main/Makefile + src/main/harbour.rc * include Windows manifest in standalone compiler - "harbour.exe /build" should now correctly report Windows 10. "yourapp.exe //build" plus in-app results still depend on manual manifest inclusion within .rc --- ChangeLog.txt | 13 + contrib/hbwin/win_osc.c | 188 ++++++----- include/hbapi.h | 9 +- src/common/hbver.c | 675 +++++++++++++++++++++++----------------- src/harbour.def | 3 + src/main/Makefile | 2 + src/main/harbour.rc | 2 + 7 files changed, 511 insertions(+), 381 deletions(-) create mode 100644 src/main/harbour.rc diff --git a/ChangeLog.txt b/ChangeLog.txt index 319d34a3cb..8f1919c1b4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,19 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2018-02-11 23:40 UTC+0100 Aleksander Czajczynski (hb fki.pl) + * include/hbapi.h + * src/common/hbver.c + * src/harbour.def + * contrib/hbwin/win_osc.c + * synced Windows version detection code with Viktor's work in 3.4 + + * src/main/Makefile + + src/main/harbour.rc + * include Windows manifest in standalone compiler - "harbour.exe /build" + should now correctly report Windows 10. "yourapp.exe //build" plus + in-app results still depend on manual manifest inclusion within .rc + 2018-02-11 12:55 UTC+0100 Aleksander Czajczynski (hb fki.pl) * package/harbour.mft + added version manifest to Harbour compiler binaries, which is more diff --git a/contrib/hbwin/win_osc.c b/contrib/hbwin/win_osc.c index 7c932d7321..bafd76eedd 100644 --- a/contrib/hbwin/win_osc.c +++ b/contrib/hbwin/win_osc.c @@ -1,6 +1,7 @@ /* * Windows OS version information * + * Copyright 2014 Viktor Szakats (vszakats.net/harbour) * Copyright 2004 Peter Rees Rees Software and Systems Ltd * * This program is free software; you can redistribute it and/or modify @@ -47,174 +48,165 @@ #include "hbwin.h" #include "hbapiitm.h" -static void getwinver( OSVERSIONINFO * pOSvi ) -{ - pOSvi->dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); - GetVersionEx( pOSvi ); -} - HB_FUNC( WIN_OSISNT ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ); + hb_retl( hb_iswinnt() != 0 ); } HB_FUNC( WIN_OSISNT351 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && - osvi.dwMajorVersion == 3 && osvi.dwMinorVersion == 51 ); + hb_retl( hb_iswinnt() == 3 ); } HB_FUNC( WIN_OSISNT4 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && - osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0 ); + hb_retl( hb_iswinnt() == 4 ); } -HB_FUNC( WIN_OSIS2000ORUPPER ) +HB_FUNC( WIN_OSIS2000 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion >= 5 ); + hb_retl( hb_iswinver( 5, 0, 0, HB_FALSE ) ); } -HB_FUNC( WIN_OSIS2000 ) +HB_FUNC( WIN_OSIS2000ORUPPER ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ); + hb_retl( hb_iswin2k() ); } HB_FUNC( WIN_OSISXP ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ); + hb_retl( hb_iswinver( 5, 1, 0, HB_FALSE ) ); } HB_FUNC( WIN_OSISWINXPORUPPER ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion > 5 || ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1 ) ); + hb_retl( hb_iswinver( 5, 1, 0, HB_TRUE ) ); } HB_FUNC( WIN_OSIS2003 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ); + hb_retl( hb_iswinver( 5, 2, 0, HB_FALSE ) ); } HB_FUNC( WIN_OSISVISTA ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 ); + hb_retl( hb_iswinver( 6, 0, 0, HB_FALSE ) ); } HB_FUNC( WIN_OSISVISTAORUPPER ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion >= 6 ); + hb_retl( hb_iswinvista() ); } HB_FUNC( WIN_OSIS7 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 ); + hb_retl( hb_iswinver( 6, 1, 0, HB_FALSE ) ); } HB_FUNC( WIN_OSIS8 ) { - OSVERSIONINFO osvi; + hb_retl( hb_iswinver( 6, 2, 0, HB_FALSE ) ); +} + +HB_FUNC( WIN_OSIS81 ) +{ + hb_retl( hb_iswinver( 6, 3, 0, HB_FALSE ) ); +} - getwinver( &osvi ); - hb_retl( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2 ); +HB_FUNC( WIN_OSIS10 ) +{ + hb_retl( hb_iswinver( 10, 0, 0, HB_FALSE ) ); } HB_FUNC( WIN_OSIS9X ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ); + hb_retl( hb_iswin9x() ); } HB_FUNC( WIN_OSIS95 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0 ); + hb_retl( hb_iswin9x() == 5 ); } HB_FUNC( WIN_OSIS98 ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10 ); + hb_retl( hb_iswin9x() == 8 ); } HB_FUNC( WIN_OSISME ) { - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_retl( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && - osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90 ); + hb_retl( hb_iswin9x() == 9 ); } HB_FUNC( WIN_OSISTSCLIENT ) { - HB_BOOL bResult = HB_FALSE; - OSVERSIONINFO osvi; + /* Only supported on NT 4.0 SP3 & higher */ + #ifndef SM_REMOTESESSION + #define SM_REMOTESESSION 0x1000 + #endif - getwinver( &osvi ); - if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion >= 4 ) - { - /* Only supported on NT 4.0 SP3 & higher */ - #ifndef SM_REMOTESESSION - #define SM_REMOTESESSION 0x1000 - #endif - bResult = ( GetSystemMetrics( SM_REMOTESESSION ) != 0 ); - } - hb_retl( bResult ); + hb_retl( GetSystemMetrics( SM_REMOTESESSION ) != 0 ); } HB_FUNC( WIN_OSVERSIONINFO ) { PHB_ITEM pArray = hb_itemArrayNew( 5 ); - OSVERSIONINFO osvi; - - getwinver( &osvi ); - hb_arraySetNL( pArray, 1, osvi.dwMajorVersion ); - hb_arraySetNL( pArray, 2, osvi.dwMinorVersion ); - if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) - osvi.dwBuildNumber = LOWORD( osvi.dwBuildNumber ); - hb_arraySetNL( pArray, 3, osvi.dwBuildNumber ); - hb_arraySetNL( pArray, 4, osvi.dwPlatformId ); - HB_ARRAYSETSTR( pArray, 5, osvi.szCSDVersion ); + + int iMajor = 4; + int iMinor = 0; + int pos; + + typedef struct + { + int iMajor; + int iMinor; + } HB_ISWINVER; + + static const HB_ISWINVER s_vers[] = { + { 10, 0 }, + { 6, 3 }, + { 6, 2 }, + { 6, 1 }, + { 6, 0 }, + { 5, 2 }, + { 5, 1 }, + { 5, 0 } }; + + for( pos = 0; pos < ( int ) HB_SIZEOFARRAY( s_vers ); ++pos ) + { + if( hb_iswinver( s_vers[ pos ].iMajor, s_vers[ pos ].iMinor, 0, ( pos == 0 ) ) ) + { + iMajor = s_vers[ pos ].iMajor; + iMinor = s_vers[ pos ].iMinor; + break; + } + } + + hb_arraySetNL( pArray, 1, iMajor ); + hb_arraySetNL( pArray, 2, iMinor ); + hb_arraySetNL( pArray, 3, 0 ); +#if defined( HB_OS_WIN_CE ) + hb_arraySetNL( pArray, 4, VER_PLATFORM_WIN32_CE ); +#else + hb_arraySetNL( pArray, 4, hb_iswinnt() ? VER_PLATFORM_WIN32_NT : VER_PLATFORM_WIN32_WINDOWS ); +#endif + hb_arraySetC( pArray, 5, NULL ); + + if( hb_iswin2k() ) + { + int tmp; + + for( tmp = 5; tmp > 0; --tmp ) + { + if( hb_iswinsp( tmp, HB_TRUE ) ) + { + char szServicePack[ 8 ]; + hb_snprintf( szServicePack, sizeof( szServicePack ), "SP%u", tmp ); + hb_arraySetC( pArray, 5, szServicePack ); + break; + } + } + } + hb_itemReturnRelease( pArray ); } diff --git a/include/hbapi.h b/include/hbapi.h index 17ffdf0baf..e2974fed58 100644 --- a/include/hbapi.h +++ b/include/hbapi.h @@ -1203,16 +1203,19 @@ extern HB_EXPORT const char * hb_verFlagsPRG( void ); /* retrieves a stat extern HB_EXPORT const char * hb_verHB_PLAT( void ); /* retrieves a static buffer containing build time HB_PLATFORM setting */ extern HB_EXPORT const char * hb_verHB_COMP( void ); /* retrieves a static buffer containing build time HB_COMPILER setting */ -extern HB_EXPORT HB_BOOL hb_iswin9x( void ); /* return HB_TRUE if OS == Windows 9x, ME */ -extern HB_EXPORT HB_BOOL hb_iswinnt( void ); /* return HB_TRUE if OS == Windows NT or newer */ +extern HB_EXPORT int hb_iswine( void ); /* return non-zero if OS == Wine */ +extern HB_EXPORT int hb_iswin9x( void ); /* return non-zero if OS == Windows 9x, ME */ +extern HB_EXPORT int hb_iswinnt( void ); /* return non-zero if OS == Windows NT or newer */ extern HB_EXPORT HB_BOOL hb_iswin2k( void ); /* return HB_TRUE if OS == Windows 2000 or newer */ extern HB_EXPORT HB_BOOL hb_iswin2k3( void ); /* return HB_TRUE if OS == Windows 2003 Server or newer */ extern HB_EXPORT HB_BOOL hb_iswinvista( void ); /* return HB_TRUE if OS == Windows Vista or newer */ +extern HB_EXPORT HB_BOOL hb_iswin7( void ); /* return HB_TRUE if OS == Windows 7 or newer */ extern HB_EXPORT HB_BOOL hb_iswin8( void ); /* return HB_TRUE if OS == Windows 8 or newer */ extern HB_EXPORT HB_BOOL hb_iswin81( void ); /* return HB_TRUE if OS == Windows 8.1 or newer */ extern HB_EXPORT HB_BOOL hb_iswin10( void ); /* return HB_TRUE if OS == Windows 10 or newer */ extern HB_EXPORT HB_BOOL hb_iswince( void ); /* return HB_TRUE if OS is Windows CE or Windows Mobile */ -extern HB_EXPORT HB_BOOL hb_iswinver( int iMajorVersion, int iMinorVersion, int iType, HB_BOOL fOrUpper ); +extern HB_EXPORT HB_BOOL hb_iswinver( int iMajor, int iMinor, int iType, HB_BOOL fOrUpper ); +extern HB_EXPORT HB_BOOL hb_iswinsp( int iServicePackMajor, HB_BOOL fOrUpper ); extern HB_EXPORT HB_BOOL hb_printerIsReady( const char * pszPrinterName ); diff --git a/src/common/hbver.c b/src/common/hbver.c index 938395af0e..ce58898694 100644 --- a/src/common/hbver.c +++ b/src/common/hbver.c @@ -8,7 +8,7 @@ * hb_verPlatform() (support for determining many Windows flavours) * hb_verCompiler() (support for determining some compiler version/revision) * Copyright 2000-2014 Viktor Szakats (vszakats.net/harbour) - * hb_verCPU(), hb_verHostBitWidth(), hb_iswinver() + * hb_verCPU(), hb_verHostBitWidth(), hb_iswinver(), hb_iswinsp() * hb_verPlatform() (support for detecting Windows NT on DOS, Wine, post-Windows 8, cleanups) * * This program is free software; you can redistribute it and/or modify @@ -86,6 +86,13 @@ #ifndef VER_MAJORVERSION #define VER_MAJORVERSION 0x0000002 #endif + #ifndef VER_SERVICEPACKMINOR + #define VER_SERVICEPACKMINOR 0x0000010 + #endif + #ifndef VER_SERVICEPACKMAJOR + #define VER_SERVICEPACKMAJOR 0x0000020 + #endif + #ifndef VER_PRODUCT_TYPE #define VER_PRODUCT_TYPE 0x0000080 #endif @@ -96,6 +103,10 @@ #define VER_GREATER_EQUAL 3 #endif + #ifndef SM_SERVERR2 + #define SM_SERVERR2 89 + #endif + #elif defined( HB_OS_OS2 ) #define INCL_DOSMISC #include @@ -146,7 +157,7 @@ const char * hb_verCPU( void ) #elif defined( HB_CPU_SYS390 ) return "System/390"; #else - return "(unknown)"; + return "(unrecognized)"; #endif } @@ -264,6 +275,177 @@ const char * hb_verPlatformMacro( void ) #endif } +#if defined( HB_OS_WIN ) + +static HB_BOOL s_fWinVerInit = HB_FALSE; + +static HB_BOOL s_fWin10 = HB_FALSE; +static HB_BOOL s_fWin81 = HB_FALSE; +static HB_BOOL s_fWin8 = HB_FALSE; +static HB_BOOL s_fWin7 = HB_FALSE; +static HB_BOOL s_fWinVista = HB_FALSE; +static HB_BOOL s_fWin2K3 = HB_FALSE; +static HB_BOOL s_fWin2K = HB_FALSE; +static int s_iWinNT = 0; +static int s_iWin9x = 0; +static int s_iWine = 0; + +#if ! defined( HB_OS_WIN_CE ) + +#if ( defined( _MSC_VER ) && _MSC_VER < 1300 ) && ! defined( __POCC__ ) + + typedef struct _OSVERSIONINFOEXW + { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[ 128 ]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; + } OSVERSIONINFOEXW, * LPOSVERSIONINFOEXW; +#endif + +typedef BOOL ( WINAPI * _HB_VERIFYVERSIONINFO )( LPOSVERSIONINFOEXW, DWORD, DWORDLONG ); +typedef ULONGLONG ( WINAPI * _HB_VERSETCONDITIONMASK )( ULONGLONG, DWORD, BYTE ); + +static HB_BOOL s_fVerInfoInit = HB_TRUE; +static _HB_VERIFYVERSIONINFO s_pVerifyVersionInfo = NULL; +static _HB_VERSETCONDITIONMASK s_pVerSetConditionMask = NULL; + +static HB_BOOL s_hb_winVerifyVersionInit( void ) +{ + if( s_fVerInfoInit ) + { + HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); + if( hModule ) + { + s_pVerifyVersionInfo = ( _HB_VERIFYVERSIONINFO ) HB_WINAPI_GETPROCADDRESS( hModule, "VerifyVersionInfoW" ); + s_pVerSetConditionMask = ( _HB_VERSETCONDITIONMASK ) HB_WINAPI_GETPROCADDRESS( hModule, "VerSetConditionMask" ); + } + s_fVerInfoInit = HB_FALSE; + } + + return s_pVerifyVersionInfo && + s_pVerSetConditionMask; +} + +#endif + +static void s_hb_winVerInit( void ) +{ +#if ! defined( HB_OS_WIN_CE ) + s_fWin10 = hb_iswinver( 10, 0, 0, HB_TRUE ); + s_fWin81 = hb_iswinver( 6, 3, 0, HB_TRUE ); + s_fWin8 = hb_iswinver( 6, 2, 0, HB_TRUE ); + s_fWin7 = hb_iswinver( 6, 1, 0, HB_TRUE ); + s_fWinVista = hb_iswinver( 6, 0, 0, HB_TRUE ); + s_fWin2K3 = hb_iswinver( 5, 2, VER_NT_SERVER, HB_TRUE ) || hb_iswinver( 5, 2, VER_NT_DOMAIN_CONTROLLER, HB_TRUE ); + s_fWin2K = hb_iswinver( 5, 0, 0, HB_TRUE ); + +#if !( defined( HB_OS_WIN_64 ) || ( defined( _MSC_VER ) && _MSC_VER > 1310 ) ) + { + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof( osvi ); + if( GetVersionEx( &osvi ) ) + { + /* NOTE: Value is VER_PLATFORM_WIN32_CE on WinCE */ + if( osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) + s_iWin9x = 0; + else if( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion < 10 ) + s_iWin9x = 5; /* 95 */ + else if( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10 ) + s_iWin9x = 8; /* 98 */ + else + s_iWin9x = 9; /* ME */ + + if( osvi.dwPlatformId != VER_PLATFORM_WIN32_NT ) + s_iWinNT = 0; + else if( osvi.dwMajorVersion == 3 && osvi.dwMinorVersion == 51 ) + s_iWinNT = 3; /* 3.51 */ + else if( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0 ) + s_iWinNT = 4; /* 4.0 */ + else + s_iWinNT = 5; /* newer */ + } + } +#endif + + { + /* NOTE: Unofficial Wine detection. + https://www.mail-archive.com/wine-devel@winehq.org/msg48659.html */ + HMODULE hntdll = GetModuleHandle( TEXT( "ntdll.dll" ) ); + if( hntdll && HB_WINAPI_GETPROCADDRESS( hntdll, "wine_get_version" ) ) + s_iWine = 1; + } + + if( s_fWin2K ) + s_iWinNT = 5; +#endif + + s_fWinVerInit = HB_TRUE; +} + +#elif defined( HB_OS_DOS ) + +static HB_BOOL s_fWinVerInit = HB_FALSE; + +static HB_BOOL s_fWin10 = HB_FALSE; +static HB_BOOL s_fWin81 = HB_FALSE; +static HB_BOOL s_fWin8 = HB_FALSE; +static HB_BOOL s_fWin7 = HB_FALSE; +static HB_BOOL s_fWinVista = HB_FALSE; +static HB_BOOL s_fWin2K3 = HB_FALSE; +static HB_BOOL s_fWin2K = HB_FALSE; +static int s_iWinNT = 0; +static int s_iWin9x = 0; +static int s_iWine = 0; + +static void s_hb_winVerInit( void ) +{ + union REGS regs; + + /* TODO */ + s_fWin10 = HB_FALSE; + s_fWin81 = HB_FALSE; + s_fWin8 = HB_FALSE; + s_fWin7 = HB_FALSE; + s_fWinVista = HB_FALSE; + s_fWin2K3 = s_fWinVista; + s_fWin2K = HB_FALSE; + + /* Host OS detection: Windows NT family */ + + { + regs.HB_XREGS.ax = 0x3306; + HB_DOS_INT86( 0x21, ®s, ®s ); + + if( regs.HB_XREGS.bx == 0x3205 ) + s_iWinNT = 5; + } + + /* Host OS detection: 95/98 */ + + if( s_iWinNT == 0 ) + { + regs.HB_XREGS.ax = 0x1600; + HB_DOS_INT86( 0x2F, ®s, ®s ); + + if( regs.h.al != 0x80 && + regs.h.al != 0xFF && + regs.h.al >= 4 ) + s_iWin9x = 5; + } + + s_fWinVerInit = HB_TRUE; +} + +#endif + /* NOTE: Must be larger than 128, which is the maximum size of osvi.szCSDVersion (Windows). [vszakats] */ #define PLATFORM_BUF_SIZE 255 @@ -359,163 +541,156 @@ char * hb_verPlatform( void ) #elif defined( HB_OS_WIN ) { - OSVERSIONINFO osVer; + const char * pszName = ""; - osVer.dwOSVersionInfoSize = sizeof( osVer ); + OSVERSIONINFO osvi; - if( GetVersionEx( &osVer ) ) - { - /* NOTE: Unofficial Wine detection. - http://www.mail-archive.com/wine-devel@winehq.org/msg48659.html */ - HMODULE hntdll = GetModuleHandle( TEXT( "ntdll.dll" ) ); - const char * pszWine = ""; - const char * pszName = ""; + memset( &osvi, 0, sizeof( osvi ) ); - if( hntdll && HB_WINAPI_GETPROCADDRESS( hntdll, "wine_get_version" ) ) - pszWine = " (Wine)"; +#if defined( HB_OS_WIN_CE ) + pszName = " CE"; + osvi.dwOSVersionInfoSize = sizeof( osvi ); + GetVersionEx( &osvi ); +#else + /* Detection of legacy Windows versions */ + switch( hb_iswin9x() ) + { + case 5: + osvi.dwMajorVersion = 4; + osvi.dwMinorVersion = 0; + pszName = " 95"; + break; + case 8: + osvi.dwMajorVersion = 4; + osvi.dwMinorVersion = 10; + pszName = " 98"; + break; + case 9: + osvi.dwMajorVersion = 4; + osvi.dwMinorVersion = 90; + pszName = " ME"; + break; + } +#endif - switch( osVer.dwPlatformId ) + if( pszName[ 0 ] == '\0' ) + { +#if defined( HB_OS_WIN_CE ) + pszName = " CE"; +#else + if( hb_iswinver( 11, 0, 0, HB_TRUE ) ) { - case VER_PLATFORM_WIN32_WINDOWS: - - if( osVer.dwMajorVersion == 4 && osVer.dwMinorVersion < 10 ) - pszName = " 95"; - else if( osVer.dwMajorVersion == 4 && osVer.dwMinorVersion == 10 ) - pszName = " 98"; + osvi.dwMajorVersion = 11; + osvi.dwMinorVersion = 0; + pszName = " 11 or newer"; + } + else if( hb_iswin10() ) + { + osvi.dwMajorVersion = 10; + osvi.dwMinorVersion = 0; + if( hb_iswinver( 10, 0, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " 10"; + else + pszName = " Server 2016"; + } + else if( hb_iswin81() ) + { + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 3; + if( hb_iswinver( 6, 3, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " 8.1"; + else + pszName = " Server 2012 R2"; + } + else if( hb_iswinvista() ) + { + if( hb_iswin8() ) + { + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 2; + if( hb_iswinver( 6, 2, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " 8"; else - pszName = " ME"; - - break; - - case VER_PLATFORM_WIN32_NT: - - if( osVer.dwMajorVersion == 6 ) - { -#if ! defined( HB_OS_WIN_CE ) && ! defined( __DMC__ ) && \ - ( ! defined( _MSC_VER ) || _MSC_VER >= 1400 ) - OSVERSIONINFOEX osVerEx; - - osVerEx.dwOSVersionInfoSize = sizeof( osVerEx ); - - if( GetVersionEx( ( OSVERSIONINFO * ) &osVerEx ) ) - { - if( osVer.dwMinorVersion == 2 ) - { - if( osVerEx.wProductType == VER_NT_WORKSTATION ) - pszName = " 8"; - else - pszName = " Server 2012"; - } - else if( osVer.dwMinorVersion == 1 ) - { - if( osVerEx.wProductType == VER_NT_WORKSTATION ) - pszName = " 7"; - else - pszName = " Server 2008 R2"; - } - else if( osVer.dwMinorVersion == 0 ) - { - if( osVerEx.wProductType == VER_NT_WORKSTATION ) - pszName = " Vista"; - else - pszName = " Server 2008"; - } - else - pszName = ""; - } - else -#endif - pszName = ""; - } - else if( osVer.dwMajorVersion == 5 && osVer.dwMinorVersion >= 2 ) - { -#if ! defined( HB_OS_WIN_CE ) && ! defined( __DMC__ ) && \ - ( ! defined( _MSC_VER ) || _MSC_VER >= 1400 ) - OSVERSIONINFOEX osVerEx; - - osVerEx.dwOSVersionInfoSize = sizeof( osVerEx ); - - if( GetVersionEx( ( OSVERSIONINFO * ) &osVerEx ) ) - { - if( osVerEx.wProductType == VER_NT_WORKSTATION ) - pszName = " XP x64"; - else - { - #ifndef SM_SERVERR2 - #define SM_SERVERR2 89 - #endif - - if( GetSystemMetrics( SM_SERVERR2 ) != 0 ) - pszName = " Server 2003 R2"; - else - pszName = " Server 2003"; - } - } - else - pszName = ""; -#else - pszName = " Server 2003 / XP x64"; -#endif - } - else if( osVer.dwMajorVersion == 5 && osVer.dwMinorVersion == 1 ) - pszName = " XP"; - else if( osVer.dwMajorVersion == 5 ) - pszName = " 2000"; + pszName = " Server 2012"; + } + else if( hb_iswinver( 6, 1, 0, HB_FALSE ) ) + { + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 1; + if( hb_iswinver( 6, 1, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " 7"; else - pszName = " NT"; - - break; - - case VER_PLATFORM_WIN32s: - pszName = " 32s"; - break; - - case VER_PLATFORM_WIN32_CE: - pszName = " CE"; - break; + pszName = " Server 2008 R2"; + } + else + { + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 0; + if( hb_iswinver( 6, 0, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " Vista"; + else + pszName = " Server 2008"; + } } - - if( hb_iswinver( 6, 4, 0, HB_FALSE ) ) + else if( hb_iswinver( 5, 2, 0, HB_FALSE ) ) { - pszName = " 10"; - osVer.dwMajorVersion = 6; - osVer.dwMinorVersion = 4; - osVer.dwBuildNumber = 0; + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 2; + if( hb_iswinver( 5, 2, VER_NT_WORKSTATION, HB_FALSE ) ) + pszName = " XP x64"; + else if( GetSystemMetrics( SM_SERVERR2 ) != 0 ) + pszName = " Server 2003 R2"; + else + pszName = " Server 2003"; } - else if( hb_iswinver( 6, 3, VER_NT_WORKSTATION, HB_FALSE ) ) + else if( hb_iswinver( 5, 1, 0, HB_FALSE ) ) { - pszName = " 8.1"; - osVer.dwMajorVersion = 6; - osVer.dwMinorVersion = 3; - osVer.dwBuildNumber = 0; + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 1; + pszName = " XP"; } - else if( hb_iswinver( 6, 3, 0, HB_FALSE ) ) /* this must come after 6.3 workstation check */ + else if( hb_iswin2k() ) { - pszName = " 2012 R2"; - osVer.dwMajorVersion = 6; - osVer.dwMinorVersion = 3; - osVer.dwBuildNumber = 0; + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 0; + pszName = " 2000"; } - - if( osVer.dwBuildNumber ) - hb_snprintf( pszPlatform, PLATFORM_BUF_SIZE + 1, "Windows%s%s %lu.%lu.%04u", - pszName, - pszWine, - osVer.dwMajorVersion, - osVer.dwMinorVersion, - LOWORD( osVer.dwBuildNumber ) ); else - hb_snprintf( pszPlatform, PLATFORM_BUF_SIZE + 1, "Windows%s%s %lu.%lu", - pszName, - pszWine, - osVer.dwMajorVersion, - osVer.dwMinorVersion ); + pszName = " NT"; +#endif + } - /* Add service pack/other info */ + hb_snprintf( pszPlatform, PLATFORM_BUF_SIZE + 1, "Windows%s%s %lu.%lu", + pszName, + s_iWine ? " (Wine)" : "", + osvi.dwMajorVersion, + osvi.dwMinorVersion ); - if( osVer.szCSDVersion[ 0 ] != TEXT( '\0' ) ) + /* Add service pack/other info */ + + if( hb_iswin2k() ) + { + int tmp; + + for( tmp = 5; tmp > 0; --tmp ) + { + if( hb_iswinsp( tmp, HB_TRUE ) ) + { + char szServicePack[ 8 ]; + hb_snprintf( szServicePack, sizeof( szServicePack ), " SP%u", tmp ); + hb_strncat( pszPlatform, szServicePack, PLATFORM_BUF_SIZE ); + break; + } + } + } +#if defined( HB_OS_WIN_CE ) + else + { + /* Also for Win9x and NT, but GetVersionEx() is deprecated + so we avoid it. */ + if( osvi.szCSDVersion[ 0 ] != TEXT( '\0' ) ) { - char * pszCSDVersion = HB_OSSTRDUP( osVer.szCSDVersion ); + char * pszCSDVersion = HB_OSSTRDUP( osvi.szCSDVersion ); int i; /* Skip the leading spaces (Win95B, Win98) */ @@ -530,8 +705,7 @@ char * hb_verPlatform( void ) hb_xfree( pszCSDVersion ); } } - else - hb_snprintf( pszPlatform, PLATFORM_BUF_SIZE + 1, "Windows" ); +#endif } #elif defined( __CEGCC__ ) @@ -555,7 +729,7 @@ char * hb_verPlatform( void ) #else { - hb_strncpy( pszPlatform, "(unknown)", PLATFORM_BUF_SIZE ); + hb_strncpy( pszPlatform, "(unrecognized)", PLATFORM_BUF_SIZE ); } #endif @@ -563,146 +737,42 @@ char * hb_verPlatform( void ) return pszPlatform; } -#if defined( HB_OS_WIN ) - -static HB_BOOL s_fWinVerInit = HB_FALSE; - -static HB_BOOL s_fWin10 = HB_FALSE; -static HB_BOOL s_fWin81 = HB_FALSE; -static HB_BOOL s_fWin8 = HB_FALSE; -static HB_BOOL s_fWinVista = HB_FALSE; -static HB_BOOL s_fWin2K3 = HB_FALSE; -static HB_BOOL s_fWin2K = HB_FALSE; -static HB_BOOL s_fWinNT = HB_FALSE; -static HB_BOOL s_fWin9x = HB_FALSE; - -static void s_hb_winVerInit( void ) -{ - OSVERSIONINFO osvi; - - s_fWin10 = hb_iswinver( 6, 4, 0, HB_TRUE ); - s_fWin81 = hb_iswinver( 6, 3, 0, HB_TRUE ); - s_fWin8 = hb_iswinver( 6, 2, 0, HB_TRUE ); - s_fWinVista = hb_iswinver( 6, 0, 0, HB_TRUE ); - s_fWin2K3 = hb_iswinver( 5, 2, VER_NT_SERVER, HB_TRUE ) || hb_iswinver( 5, 2, VER_NT_DOMAIN_CONTROLLER, HB_TRUE ); - s_fWin2K = hb_iswinver( 5, 0, 0, HB_TRUE ); - - osvi.dwOSVersionInfoSize = sizeof( osvi ); - if( GetVersionEx( &osvi ) ) - { - s_fWin9x = osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS; - s_fWinNT = osvi.dwPlatformId == VER_PLATFORM_WIN32_NT; /* && osvi.dwMajorVersion >= 4 ); */ - } - - s_fWinVerInit = HB_TRUE; -} - -#elif defined( HB_OS_DOS ) - -static HB_BOOL s_fWinVerInit = HB_FALSE; - -static HB_BOOL s_fWin10 = HB_FALSE; -static HB_BOOL s_fWin81 = HB_FALSE; -static HB_BOOL s_fWin8 = HB_FALSE; -static HB_BOOL s_fWinVista = HB_FALSE; -static HB_BOOL s_fWin2K3 = HB_FALSE; -static HB_BOOL s_fWin2K = HB_FALSE; -static HB_BOOL s_fWinNT = HB_FALSE; -static HB_BOOL s_fWin9x = HB_FALSE; - -static void s_hb_winVerInit( void ) -{ - union REGS regs; - - /* TODO */ - s_fWin10 = HB_FALSE; - s_fWin81 = HB_FALSE; - s_fWin8 = HB_FALSE; - s_fWinVista = HB_FALSE; - s_fWin2K3 = s_fWinVista; - s_fWin2K = HB_FALSE; - - /* Host OS detection: Windows NT family */ - - { - regs.HB_XREGS.ax = 0x3306; - HB_DOS_INT86( 0x21, ®s, ®s ); - - s_fWinNT = ( regs.HB_XREGS.bx == 0x3205 ); - } - - /* Host OS detection: 95/98 */ - - if( ! s_fWinNT ) - { - regs.HB_XREGS.ax = 0x1600; - HB_DOS_INT86( 0x2F, ®s, ®s ); - - s_fWin9x = ( regs.h.al != 0x80 && - regs.h.al != 0xFF && - regs.h.al >= 4 ); - } - else - s_fWin9x = HB_FALSE; - - s_fWinVerInit = HB_TRUE; -} - -#endif - -HB_BOOL hb_iswinver( int iMajorVersion, int iMinorVersion, int iType, HB_BOOL fOrUpper ) +HB_BOOL hb_iswinver( int iMajor, int iMinor, int iType, HB_BOOL fOrUpper ) { #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) - - #if defined( __DMC__ ) || ( defined( _MSC_VER ) && _MSC_VER < 1400 ) - typedef struct _OSVERSIONINFOEXW - { - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformId; - WCHAR szCSDVersion[ 128 ]; - WORD wServicePackMajor; - WORD wServicePackMinor; - WORD wSuiteMask; - BYTE wProductType; - BYTE wReserved; - } OSVERSIONINFOEXW, * LPOSVERSIONINFOEXW; - #endif - - typedef BOOL ( WINAPI * _HB_VERIFYVERSIONINFO )( LPOSVERSIONINFOEXW, DWORD, DWORDLONG ); - typedef ULONGLONG ( WINAPI * _HB_VERSETCONDITIONMASK )( ULONGLONG, DWORD, BYTE ); - - static _HB_VERIFYVERSIONINFO s_pVerifyVersionInfo = NULL; - static _HB_VERSETCONDITIONMASK s_pVerSetConditionMask = NULL; - - if( ! s_pVerifyVersionInfo || - ! s_pVerSetConditionMask ) - { - HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); - if( hModule ) - { - s_pVerifyVersionInfo = ( _HB_VERIFYVERSIONINFO ) HB_WINAPI_GETPROCADDRESS( hModule, "VerifyVersionInfoW" ); - s_pVerSetConditionMask = ( _HB_VERSETCONDITIONMASK ) HB_WINAPI_GETPROCADDRESS( hModule, "VerSetConditionMask" ); - } - } - - if( s_pVerifyVersionInfo && - s_pVerSetConditionMask ) + if( s_hb_winVerifyVersionInit() ) { OSVERSIONINFOEXW ver; DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION; DWORDLONG dwlConditionMask = 0; - ZeroMemory( &ver, sizeof( ver ) ); + memset( &ver, 0, sizeof( ver ) ); ver.dwOSVersionInfoSize = sizeof( ver ); - ver.dwMajorVersion = ( DWORD ) iMajorVersion; - ver.dwMinorVersion = ( DWORD ) iMinorVersion; + ver.dwMajorVersion = ( DWORD ) iMajor; + ver.dwMinorVersion = ( DWORD ) iMinor; dwlConditionMask = s_pVerSetConditionMask( dwlConditionMask, VER_MAJORVERSION, fOrUpper ? VER_GREATER_EQUAL : VER_EQUAL ); dwlConditionMask = s_pVerSetConditionMask( dwlConditionMask, VER_MINORVERSION, fOrUpper ? VER_GREATER_EQUAL : VER_EQUAL ); + /* MSDN says in https://msdn.microsoft.com/library/ms725492 + "If you are testing the major version, you must also test the + minor version and the service pack major and minor versions." + However, Wine (as of 1.7.53) breaks on this. Since native Windows + apparently doesn't care, we're not doing it for now. + Wine (emulating Windows 7) will erroneously return HB_FALSE from + these calls: + hb_iswinver( 6, 1, 0, HB_FALSE ); + hb_iswinver( 6, 1, VER_NT_WORKSTATION, HB_FALSE ); + Removing the Service Pack check, or changing HB_FALSE to HB_TRUE + in above calls, both fixes the problem. [vszakats] */ +#if defined( __HB_DISABLE_WINE_VERIFYVERSIONINFO_BUG_WORKAROUND ) + ver.wServicePackMajor = + ver.wServicePackMinor = ( WORD ) 0; + dwTypeMask |= VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; + dwlConditionMask = s_pVerSetConditionMask( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL ); + dwlConditionMask = s_pVerSetConditionMask( dwlConditionMask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL ); +#endif + if( iType ) { dwTypeMask |= VER_PRODUCT_TYPE; @@ -713,14 +783,48 @@ HB_BOOL hb_iswinver( int iMajorVersion, int iMinorVersion, int iType, HB_BOOL fO return ( HB_BOOL ) s_pVerifyVersionInfo( &ver, dwTypeMask, dwlConditionMask ); } #else - HB_SYMBOL_UNUSED( iMajorVersion ); - HB_SYMBOL_UNUSED( iMinorVersion ); + HB_SYMBOL_UNUSED( iMajor ); + HB_SYMBOL_UNUSED( iMinor ); HB_SYMBOL_UNUSED( iType ); HB_SYMBOL_UNUSED( fOrUpper ); #endif return HB_FALSE; } +HB_BOOL hb_iswinsp( int iServicePackMajor, HB_BOOL fOrUpper ) +{ +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + if( s_hb_winVerifyVersionInit() ) + { + OSVERSIONINFOEXW ver; + DWORDLONG dwlConditionMask = 0; + + memset( &ver, 0, sizeof( ver ) ); + ver.dwOSVersionInfoSize = sizeof( ver ); + ver.wServicePackMajor = ( WORD ) iServicePackMajor; + + dwlConditionMask = s_pVerSetConditionMask( dwlConditionMask, VER_SERVICEPACKMAJOR, fOrUpper ? VER_GREATER_EQUAL : VER_EQUAL ); + + return ( HB_BOOL ) s_pVerifyVersionInfo( &ver, VER_SERVICEPACKMAJOR, dwlConditionMask ); + } +#else + HB_SYMBOL_UNUSED( iServicePackMajor ); + HB_SYMBOL_UNUSED( fOrUpper ); +#endif + return HB_FALSE; +} + +int hb_iswine( void ) +{ +#if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) + if( ! s_fWinVerInit ) + s_hb_winVerInit(); + return s_iWine; +#else + return 0; +#endif +} + HB_BOOL hb_iswin10( void ) { #if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) @@ -754,6 +858,17 @@ HB_BOOL hb_iswin8( void ) #endif } +HB_BOOL hb_iswin7( void ) +{ +#if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) + if( ! s_fWinVerInit ) + s_hb_winVerInit(); + return s_fWin7; +#else + return HB_FALSE; +#endif +} + HB_BOOL hb_iswinvista( void ) { #if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) @@ -787,25 +902,25 @@ HB_BOOL hb_iswin2k( void ) #endif } -HB_BOOL hb_iswinnt( void ) +int hb_iswinnt( void ) { #if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) if( ! s_fWinVerInit ) s_hb_winVerInit(); - return s_fWinNT; + return s_iWinNT; #else - return HB_FALSE; + return 0; #endif } -HB_BOOL hb_iswin9x( void ) +int hb_iswin9x( void ) { #if defined( HB_OS_WIN ) || defined( HB_OS_DOS ) if( ! s_fWinVerInit ) s_hb_winVerInit(); - return s_fWin9x; + return s_iWin9x; #else - return HB_FALSE; + return 0; #endif } diff --git a/src/harbour.def b/src/harbour.def index b72fec5edd..e75685af5f 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -2743,11 +2743,14 @@ hb_inkeySetText hb_iswin10 hb_iswin2k hb_iswin2k3 +hb_iswin7 hb_iswin8 hb_iswin81 hb_iswin9x hb_iswince +hb_iswine hb_iswinnt +hb_iswinsp hb_iswinver hb_iswinvista hb_itemArrayGet diff --git a/src/main/Makefile b/src/main/Makefile index c0d6b59557..7cc7a79405 100644 --- a/src/main/Makefile +++ b/src/main/Makefile @@ -4,6 +4,8 @@ C_SOURCES := \ C_MAIN := harbour.c +RC_SOURCES := harbour.rc + LIBS := \ hbcplr \ hbpp \ diff --git a/src/main/harbour.rc b/src/main/harbour.rc new file mode 100644 index 0000000000..ff78dddb8b --- /dev/null +++ b/src/main/harbour.rc @@ -0,0 +1,2 @@ +#include "../../package/harbour.rc" +__HB_CREATEPROCESS_MANIFEST_RESOURCE_ID __HB_RT_MANIFEST "../../package/harbour.mft"