diff --git a/bin/named/win32/os.c b/bin/named/win32/os.c index 71652d6d7e..1a0efb0b24 100644 --- a/bin/named/win32/os.c +++ b/bin/named/win32/os.c @@ -81,9 +81,10 @@ ns_paths_init(void) { static void version_check(const char *progname) { - if(isc_win32os_majorversion() < 5) + if ((isc_win32os_versioncheck(4, 0, 0, 0) >= 0) && + (isc_win32os_versioncheck(5, 0, 0, 0) < 0)) return; /* No problem with Version 4.0 */ - if(isc_win32os_versioncheck(5, 0, 2, 0) < 0) + if (isc_win32os_versioncheck(5, 0, 2, 0) < 0) if (ntservice_isservice()) NTReportError(progname, version_error); else diff --git a/lib/isc/win32/include/isc/win32os.h b/lib/isc/win32/include/isc/win32os.h index bd40393619..34978fd414 100644 --- a/lib/isc/win32/include/isc/win32os.h +++ b/lib/isc/win32/include/isc/win32os.h @@ -29,30 +29,6 @@ ISC_LANG_BEGINDECLS * be determined. */ -unsigned int -isc_win32os_majorversion(void); -/* - * Major Version of the O/S. - */ - -unsigned int -isc_win32os_minorversion(void); -/* - * Minor Version of the O/S. - */ - -unsigned int -isc_win32os_servicepackmajor(void); -/* - * Major Version of the Service Pack for O/S. - */ - -unsigned int -isc_win32os_servicepackminor(void); -/* - * Minor Version of the Service Pack for O/S. - */ - int isc_win32os_versioncheck(unsigned int major, unsigned int minor, unsigned int updatemajor, unsigned int updateminor); diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index e59373f545..ade7a6e6a2 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -733,10 +733,6 @@ isc_timermgr_destroy isc_timermgr_poke isc_tm_timegm isc_tm_strptime -isc_win32os_majorversion -isc_win32os_minorversion -isc_win32os_servicepackmajor -isc_win32os_servicepackminor isc_win32os_versioncheck openlog @IF PKCS11 diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index e50c0a0607..1e078fb67a 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -927,7 +927,7 @@ connection_reset_fix(SOCKET fd) { BOOL bNewBehavior = FALSE; DWORD status; - if (isc_win32os_majorversion() < 5) + if (isc_win32os_versioncheck(5, 0, 0, 0) < 0) return (ISC_R_SUCCESS); /* NT 4.0 has no problem */ /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */ diff --git a/lib/isc/win32/win32os.c b/lib/isc/win32/win32os.c index 74c6ea4186..c02dfc6016 100644 --- a/lib/isc/win32/win32os.c +++ b/lib/isc/win32/win32os.c @@ -15,88 +15,106 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: win32os.c,v 1.5 2007/06/19 23:47:19 tbox Exp $ */ - #include +#ifndef TESTVERSION #include - -static BOOL bInit = FALSE; -static OSVERSIONINFOEX osVer; - -static void -initialize_action(void) { - BOOL bSuccess; - - if (bInit) - return; - /* - * NOTE: VC++ 6.0 gets this function declaration wrong - * so we compensate by casting the argument - * NOTE: GetVersionEx() deprecated in Windows 8.1 - */ - osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - bSuccess = GetVersionEx((OSVERSIONINFO *) &osVer); - - /* - * Versions of NT before NT4.0 SP6 did not return the - * extra info that the EX structure provides and returns - * a failure so we need to retry with the old structure. - */ - if(!bSuccess) { - osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - (void)GetVersionEx((OSVERSIONINFO *) &osVer); - } - bInit = TRUE; -} - -unsigned int -isc_win32os_majorversion(void) { - initialize_action(); - return ((unsigned int)osVer.dwMajorVersion); -} - -unsigned int -isc_win32os_minorversion(void) { - initialize_action(); - return ((unsigned int)osVer.dwMinorVersion); -} - -unsigned int -isc_win32os_servicepackmajor(void) { - initialize_action(); - return ((unsigned int)osVer.wServicePackMajor); -} - -unsigned int -isc_win32os_servicepackminor(void) { - initialize_action(); - return ((unsigned int)osVer.wServicePackMinor); -} +#else +#include +#endif int isc_win32os_versioncheck(unsigned int major, unsigned int minor, - unsigned int spmajor, unsigned int spminor) { + unsigned int spmajor, unsigned int spminor) +{ + OSVERSIONINFOEX osVer; + DWORD typeMask; + ULONGLONG conditionMask; - initialize_action(); + memset(&osVer, 0, sizeof(OSVERSIONINFOEX)); + osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + typeMask = 0; + conditionMask = 0; - if (major < isc_win32os_majorversion()) + /* Optimistic: likely greater */ + osVer.dwMajorVersion = major; + typeMask |= VER_MAJORVERSION; + conditionMask = VerSetConditionMask(conditionMask, + VER_MAJORVERSION, + VER_GREATER); + osVer.dwMinorVersion = minor; + typeMask |= VER_MINORVERSION; + conditionMask = VerSetConditionMask(conditionMask, + VER_MINORVERSION, + VER_GREATER); + osVer.wServicePackMajor = spmajor; + typeMask |= VER_SERVICEPACKMAJOR; + conditionMask = VerSetConditionMask(conditionMask, + VER_SERVICEPACKMAJOR, + VER_GREATER); + osVer.wServicePackMinor = spminor; + typeMask |= VER_SERVICEPACKMINOR; + conditionMask = VerSetConditionMask(conditionMask, + VER_SERVICEPACKMINOR, + VER_GREATER); + if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) return (1); - if (major > isc_win32os_majorversion()) - return (-1); - if (minor < isc_win32os_minorversion()) - return (1); - if (minor > isc_win32os_minorversion()) - return (-1); - if (spmajor < isc_win32os_servicepackmajor()) - return (1); - if (spmajor > isc_win32os_servicepackmajor()) - return (-1); - if (spminor < isc_win32os_servicepackminor()) - return (1); - if (spminor > isc_win32os_servicepackminor()) - return (-1); - /* Exact */ - return (0); + /* Failed: retry with equal */ + conditionMask = 0; + conditionMask = VerSetConditionMask(conditionMask, + VER_MAJORVERSION, + VER_EQUAL); + conditionMask = VerSetConditionMask(conditionMask, + VER_MINORVERSION, + VER_EQUAL); + conditionMask = VerSetConditionMask(conditionMask, + VER_SERVICEPACKMAJOR, + VER_EQUAL); + conditionMask = VerSetConditionMask(conditionMask, + VER_SERVICEPACKMINOR, + VER_EQUAL); + if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) + return (0); + else + return (-1); } + +#ifdef TESTVERSION +int +main(int argc, char **argv) { + unsigned int major = 0; + unsigned int minor = 0; + unsigned int spmajor = 0; + unsigned int spminor = 0; + int ret; + + if (argc > 1) { + --argc; + ++argv; + major = (unsigned int) atoi(argv[0]); + } + if (argc > 1) { + --argc; + ++argv; + minor = (unsigned int) atoi(argv[0]); + } + if (argc > 1) { + --argc; + ++argv; + spmajor = (unsigned int) atoi(argv[0]); + } + if (argc > 1) { + --argc; + ++argv; + spminor = (unsigned int) atoi(argv[0]); + } + + ret = isc_win32os_versioncheck(major, minor, spmajor, spminor); + + printf("%s major %u minor %u SP major %u SP minor %u\n", + ret > 0 ? "greater" : (ret == 0 ? "equal" : "less"), + major, minor, spmajor, spminor); + return (ret); +} +#endif