Commit 1ff3a094156baba11240f48924dd5e0c1d983d8e

Edward Thomson 2013-08-27T19:41:44

Improve win32 version check, no ipv6 tests on XP

diff --git a/src/hash/hash_win32.c b/src/hash/hash_win32.c
index 43d54ca..362712e 100644
--- a/src/hash/hash_win32.c
+++ b/src/hash/hash_win32.c
@@ -20,29 +20,11 @@ static struct git_hash_prov hash_prov = {0};
 /* Initialize CNG, if available */
 GIT_INLINE(int) hash_cng_prov_init(void)
 {
-	OSVERSIONINFOEX version_test = {0};
-	DWORD version_test_mask;
-	DWORDLONG version_condition_mask = 0;
 	char dll_path[MAX_PATH];
 	DWORD dll_path_len, size_len;
 
-	return -1;
-
 	/* Only use CNG on Windows 2008 / Vista SP1  or better (Windows 6.0 SP1) */
-	version_test.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-	version_test.dwMajorVersion = 6;
-	version_test.dwMinorVersion = 0;
-	version_test.wServicePackMajor = 1;
-	version_test.wServicePackMinor = 0;
-
-	version_test_mask = (VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR);
-
-	VER_SET_CONDITION(version_condition_mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
-	VER_SET_CONDITION(version_condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
-	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
-	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
-
-	if (!VerifyVersionInfo(&version_test, version_test_mask, version_condition_mask))
+	if (!git_has_win32_version(6, 0, 1))
 		return -1;
 
 	/* Load bcrypt.dll explicitly from the system directory */
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 8decd8d..29d4ba6 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -511,7 +511,7 @@ replay:
 
 			/* Check for Windows 7. This workaround is only necessary on
 			 * Windows Vista and earlier. Windows 7 is version 6.1. */
-			if (!git_has_win32_version(6, 1)) {
+			if (!git_has_win32_version(6, 1, 0)) {
 				wchar_t *location;
 				DWORD location_length;
 				int redirect_cmp;
@@ -989,7 +989,7 @@ static int winhttp_receivepack(
 {
 	/* WinHTTP only supports Transfer-Encoding: chunked
 	 * on Windows Vista (NT 6.0) and higher. */
-	s->chunked = git_has_win32_version(6, 0);
+	s->chunked = git_has_win32_version(6, 0, 0);
 
 	if (s->chunked)
 		s->parent.write = winhttp_stream_write_chunked;
diff --git a/src/win32/error.c b/src/win32/error.c
index a62a07e..bc598ae 100644
--- a/src/win32/error.c
+++ b/src/win32/error.c
@@ -47,7 +47,7 @@ char *git_win32_get_error_message(DWORD error_code)
 		(LPWSTR)&lpMsgBuf, 0, NULL)) {
 
 		/* Invalid code point check supported on Vista+ only */
-		if (git_has_win32_version(6, 0))
+		if (git_has_win32_version(6, 0, 0))
 			dwFlags = WC_ERR_INVALID_CHARS;
 		else
 			dwFlags = 0;
diff --git a/src/win32/version.h b/src/win32/version.h
index 483962b..518b0a3 100644
--- a/src/win32/version.h
+++ b/src/win32/version.h
@@ -9,12 +9,29 @@
 
 #include <windows.h>
 
-GIT_INLINE(int) git_has_win32_version(int major, int minor)
+GIT_INLINE(int) git_has_win32_version(int major, int minor, int service_pack)
 {
-	WORD wVersion = LOWORD(GetVersion());
+	OSVERSIONINFOEX version_test = {0};
+	DWORD version_test_mask;
+	DWORDLONG version_condition_mask = 0;
+	
+	version_test.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	version_test.dwMajorVersion = major;
+	version_test.dwMinorVersion = minor;
+	version_test.wServicePackMajor = service_pack;
+	version_test.wServicePackMinor = 0;
 
-	return LOBYTE(wVersion) > major ||
-		(LOBYTE(wVersion) == major && HIBYTE(wVersion) >= minor);
+	version_test_mask = (VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR);
+
+	VER_SET_CONDITION(version_condition_mask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+	VER_SET_CONDITION(version_condition_mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+	if (!VerifyVersionInfo(&version_test, version_test_mask, version_condition_mask))
+		return 0;
+
+	return 1;
 }
 
 #endif
diff --git a/tests-clar/core/posix.c b/tests-clar/core/posix.c
index 890e25d..1cef937 100644
--- a/tests-clar/core/posix.c
+++ b/tests-clar/core/posix.c
@@ -24,6 +24,16 @@ void test_core_posix__initialize(void)
 #endif
 }
 
+static bool supports_ipv6(void)
+{
+#ifdef GIT_WIN32
+	/* IPv6 is supported on Vista and newer */
+	return git_has_win32_version(6, 0, 0);
+#else
+	return 1;
+#endif
+}
+
 void test_core_posix__inet_pton(void)
 {
 	struct in_addr addr;
@@ -65,9 +75,12 @@ void test_core_posix__inet_pton(void)
 	}
 
 	/* Test some ipv6 addresses */
-	for (i = 0; i < 6; i++) {
-		cl_assert(p_inet_pton(AF_INET6, in6_addr_data[i].p, &addr6) == 1);
-		cl_assert(memcmp(&addr6, in6_addr_data[i].n, sizeof(struct in6_addr)) == 0);
+	if (supports_ipv6())
+	{
+		for (i = 0; i < 6; i++) {
+			cl_assert(p_inet_pton(AF_INET6, in6_addr_data[i].p, &addr6) == 1);
+			cl_assert(memcmp(&addr6, in6_addr_data[i].n, sizeof(struct in6_addr)) == 0);
+		}
 	}
 
 	/* Test some invalid strings */