From: Piotr Caban <piotr@codeweavers.com>
Subject: [PATCH v2] ucrtbase: Add _timespec{32,64}_get implementation
Message-Id: <9ed16b7c-6eec-6193-4566-30723c4decc7@codeweavers.com>
Date: Wed, 18 Apr 2018 20:38:18 +0200

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
---
  .../api-ms-win-crt-time-l1-1-0.spec                |  4 +-
  dlls/msvcrt/time.c                                 | 53 
++++++++++++++++++++++
  dlls/ucrtbase/ucrtbase.spec                        |  4 +-
  3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec b/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec
index db36c29a07..e21e07ec2f 100644
--- a/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec
@@ -47,8 +47,8 @@
 @ cdecl _strtime_s(ptr long) ucrtbase._strtime_s
 @ cdecl _time32(ptr) ucrtbase._time32
 @ cdecl _time64(ptr) ucrtbase._time64
-@ stub _timespec32_get
-@ stub _timespec64_get
+@ cdecl _timespec32_get(ptr long) ucrtbase._timespec32_get
+@ cdecl _timespec64_get(ptr long) ucrtbase._timespec64_get
 @ cdecl _tzset() ucrtbase._tzset
 @ cdecl _utime32(str ptr) ucrtbase._utime32
 @ cdecl _utime64(str ptr) ucrtbase._utime64
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index a2500c4878..861b2eddb5 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -1620,3 +1620,56 @@ int CDECL _get_daylight(int *hours)
 }
 
 #endif /* _MSVCR_VER >= 80 */
+
+#if _MSVCR_VER >= 140
+
+#define TIME_UTC 1
+
+struct _timespec32
+{
+    MSVCRT___time32_t tv_sec;
+    LONG tv_nsec;
+};
+
+struct _timespec64
+{
+    MSVCRT___time64_t tv_sec;
+    LONG tv_nsec;
+};
+
+/*********************************************************************
+ * _timespec64_get (UCRTBASE.@)
+ */
+int CDECL _timespec64_get(struct _timespec64 *ts, int base)
+{
+    ULONGLONG time;
+    FILETIME ft;
+
+    if(!MSVCRT_CHECK_PMT(ts != NULL)) return 0;
+    if(base != TIME_UTC) return 0;
+
+    GetSystemTimePreciseAsFileTime(&ft);
+    time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+
+    ts->tv_sec = time / TICKSPERSEC - SECS_1601_TO_1970;
+    ts->tv_nsec = time % TICKSPERSEC * 100;
+    return base;
+}
+
+/*********************************************************************
+ * _timespec32_get (UCRTBASE.@)
+ */
+int CDECL _timespec32_get(struct _timespec32 *ts, int base)
+{
+    struct _timespec64 ts64;
+
+    if(_timespec64_get(&ts64, base) != base)
+        return 0;
+    if(ts64.tv_sec != (MSVCRT___time32_t)ts64.tv_sec)
+        return 0;
+
+    ts->tv_sec = ts64.tv_sec;
+    ts->tv_nsec = ts64.tv_nsec;
+    return base;
+}
+#endif /* _MSVCR_VER >= 140 */
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index b12a1b134d..ce226fe536 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -1972,8 +1972,8 @@
 @ cdecl _tempnam(str str) MSVCRT__tempnam
 @ cdecl _time32(ptr) MSVCRT__time32
 @ cdecl _time64(ptr) MSVCRT__time64
-@ stub _timespec32_get
-@ stub _timespec64_get
+@ cdecl _timespec32_get(ptr long)
+@ cdecl _timespec64_get(ptr long)
 @ cdecl _tolower(long) MSVCRT__tolower
 @ cdecl _tolower_l(long ptr) MSVCRT__tolower_l
 @ cdecl _toupper(long) MSVCRT__toupper