aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/system_win32.c2
-rw-r--r--lib/timeval.c1
-rw-r--r--src/tool_doswin.c26
-rw-r--r--src/tool_doswin.h1
-rw-r--r--src/tool_main.c33
-rw-r--r--src/tool_util.c42
6 files changed, 72 insertions, 33 deletions
diff --git a/lib/system_win32.c b/lib/system_win32.c
index 52a5fd951..7e287064e 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -109,11 +109,11 @@ CURLcode Curl_win32_init(long flags)
if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
Curl_isVistaOrGreater = TRUE;
- QueryPerformanceFrequency(&Curl_freq);
}
else
Curl_isVistaOrGreater = FALSE;
+ QueryPerformanceFrequency(&Curl_freq);
return CURLE_OK;
}
diff --git a/lib/timeval.c b/lib/timeval.c
index 9b05cf051..04d0ff3ee 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -28,6 +28,7 @@
extern LARGE_INTEGER Curl_freq;
extern bool Curl_isVistaOrGreater;
+/* In case of bug fix this function has a counterpart in tool_util.c */
struct curltime Curl_now(void)
{
struct curltime now;
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index a64a81633..0743c7183 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -697,6 +697,32 @@ cleanup:
return slist;
}
+LARGE_INTEGER Curl_freq;
+bool Curl_isVistaOrGreater;
+
+CURLcode win32_init(void)
+{
+ OSVERSIONINFOEXA osvi;
+ unsigned __int64 mask = 0;
+ unsigned char op = VER_GREATER_EQUAL;
+
+ memset(&osvi, 0, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ osvi.dwMajorVersion = 6;
+ VER_SET_CONDITION(mask, VER_MAJORVERSION, op);
+ VER_SET_CONDITION(mask, VER_MINORVERSION, op);
+
+ if(VerifyVersionInfoA(&osvi, (VER_MAJORVERSION | VER_MINORVERSION), mask))
+ Curl_isVistaOrGreater = true;
+ else if(GetLastError() == ERROR_OLD_WIN_VERSION)
+ Curl_isVistaOrGreater = false;
+ else
+ return CURLE_FAILED_INIT;
+
+ QueryPerformanceFrequency(&Curl_freq);
+ return CURLE_OK;
+}
+
#endif /* WIN32 */
#endif /* MSDOS || WIN32 */
diff --git a/src/tool_doswin.h b/src/tool_doswin.h
index 457637665..aba31b0bd 100644
--- a/src/tool_doswin.h
+++ b/src/tool_doswin.h
@@ -61,6 +61,7 @@ CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file);
struct curl_slist *GetLoadedModulePaths(void);
+CURLcode win32_init(void);
#endif /* WIN32 */
diff --git a/src/tool_main.c b/src/tool_main.c
index 06923c332..047796b6c 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -279,6 +279,24 @@ int main(int argc, char *argv[])
struct GlobalConfig global;
memset(&global, 0, sizeof(global));
+#ifdef WIN32
+ /* Undocumented diagnostic option to list the full paths of all loaded
+ modules. This is purposely pre-init. */
+ if(argc == 2 && !strcmp(argv[1], "--dump-module-paths")) {
+ struct curl_slist *item, *head = GetLoadedModulePaths();
+ for(item = head; item; item = item->next)
+ printf("%s\n", item->data);
+ curl_slist_free_all(head);
+ return head ? 0 : 1;
+ }
+ /* win32_init must be called before other init routines. */
+ result = win32_init();
+ if(result) {
+ fprintf(stderr, "curl: (%d) Windows-specific init failed.\n", result);
+ return result;
+ }
+#endif
+
/* Perform any platform-specific terminal configuration */
configure_terminal();
@@ -294,21 +312,6 @@ int main(int argc, char *argv[])
/* Initialize the curl library - do not call any libcurl functions before
this point */
result = main_init(&global);
-
-#ifdef WIN32
- /* Undocumented diagnostic option to list the full paths of all loaded
- modules, regardless of whether or not initialization succeeded. */
- if(argc == 2 && !strcmp(argv[1], "--dump-module-paths")) {
- struct curl_slist *item, *head = GetLoadedModulePaths();
- for(item = head; item; item = item->next) {
- printf("%s\n", item->data);
- }
- curl_slist_free_all(head);
- if(!result)
- main_free(&global);
- }
- else
-#endif /* WIN32 */
if(!result) {
/* Start our curl operation */
result = operate(&global, argc, argv);
diff --git a/src/tool_util.c b/src/tool_util.c
index 04d73e4e3..ec99bf3f6 100644
--- a/src/tool_util.c
+++ b/src/tool_util.c
@@ -27,27 +27,35 @@
#if defined(WIN32) && !defined(MSDOS)
+/* set in win32_init() */
+extern LARGE_INTEGER Curl_freq;
+extern bool Curl_isVistaOrGreater;
+
+/* In case of bug fix this function has a counterpart in timeval.c */
struct timeval tvnow(void)
{
- /*
- ** GetTickCount() is available on _all_ Windows versions from W95 up
- ** to nowadays. Returns milliseconds elapsed since last system boot,
- ** increases monotonically and wraps once 49.7 days have elapsed.
- **
- ** GetTickCount64() is available on Windows version from Windows Vista
- ** and Windows Server 2008 up to nowadays. The resolution of the
- ** function is limited to the resolution of the system timer, which
- ** is typically in the range of 10 milliseconds to 16 milliseconds.
- */
struct timeval now;
-#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) && \
- (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
- ULONGLONG milliseconds = GetTickCount64();
-#else
- DWORD milliseconds = GetTickCount();
+ if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
+ LARGE_INTEGER count;
+ QueryPerformanceCounter(&count);
+ now.tv_sec = (long)(count.QuadPart / Curl_freq.QuadPart);
+ now.tv_usec = (long)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
+ Curl_freq.QuadPart);
+ }
+ else {
+ /* Disable /analyze warning that GetTickCount64 is preferred */
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:28159)
+#endif
+ DWORD milliseconds = GetTickCount();
+#if defined(_MSC_VER)
+#pragma warning(pop)
#endif
- now.tv_sec = (long)(milliseconds / 1000);
- now.tv_usec = (long)((milliseconds % 1000) * 1000);
+
+ now.tv_sec = (long)(milliseconds / 1000);
+ now.tv_usec = (long)((milliseconds % 1000) * 1000);
+ }
return now;
}