2 * Unit test suite for ntdll time functions
4 * Copyright 2004 Rein Klazes
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
23 #include "ntdll_test.h"
27 #define TICKSPERSEC 10000000
28 #define TICKSPERMSEC 10000
29 #define SECSPERDAY 86400
31 static VOID (WINAPI
*pRtlTimeToTimeFields
)( const LARGE_INTEGER
*liTime
, PTIME_FIELDS TimeFields
) ;
32 static VOID (WINAPI
*pRtlTimeFieldsToTime
)( PTIME_FIELDS TimeFields
, PLARGE_INTEGER Time
) ;
33 static NTSTATUS (WINAPI
*pNtQueryPerformanceCounter
)( LARGE_INTEGER
*counter
, LARGE_INTEGER
*frequency
);
34 static NTSTATUS (WINAPI
*pNtQuerySystemInformation
)( SYSTEM_INFORMATION_CLASS
class,
35 void *info
, ULONG size
, ULONG
*ret_size
);
36 static NTSTATUS (WINAPI
*pRtlQueryTimeZoneInformation
)( RTL_TIME_ZONE_INFORMATION
*);
37 static NTSTATUS (WINAPI
*pRtlQueryDynamicTimeZoneInformation
)( RTL_DYNAMIC_TIME_ZONE_INFORMATION
*);
38 static BOOL (WINAPI
*pRtlQueryUnbiasedInterruptTime
)( ULONGLONG
*time
);
40 static BOOL (WINAPI
*pRtlQueryPerformanceCounter
)(LARGE_INTEGER
*);
41 static BOOL (WINAPI
*pRtlQueryPerformanceFrequency
)(LARGE_INTEGER
*);
43 static const int MonthLengths
[2][12] =
45 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
46 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
49 static inline BOOL
IsLeapYear(int Year
)
51 return Year
% 4 == 0 && (Year
% 100 != 0 || Year
% 400 == 0);
54 /* start time of the tests */
55 static TIME_FIELDS tftest
= {1889,12,31,23,59,59,0,0};
57 static void test_pRtlTimeToTimeFields(void)
59 LARGE_INTEGER litime
, liresult
;
62 litime
.QuadPart
= ((ULONGLONG
)0x0144017a << 32) | 0xf0b0a980;
63 while( tftest
.Year
< 2110 ) {
64 /* test at the last second of the month */
65 pRtlTimeToTimeFields( &litime
, &tfresult
);
66 ok( tfresult
.Year
== tftest
.Year
&& tfresult
.Month
== tftest
.Month
&&
67 tfresult
.Day
== tftest
.Day
&& tfresult
.Hour
== tftest
.Hour
&&
68 tfresult
.Minute
== tftest
.Minute
&& tfresult
.Second
== tftest
.Second
,
69 "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i
,
70 tftest
.Year
, tftest
.Month
, tftest
.Day
,
71 tftest
.Hour
, tftest
.Minute
,tftest
.Second
,
72 tfresult
.Year
, tfresult
.Month
, tfresult
.Day
,
73 tfresult
.Hour
, tfresult
.Minute
, tfresult
.Second
);
74 /* test the inverse */
75 pRtlTimeFieldsToTime( &tfresult
, &liresult
);
76 ok( liresult
.QuadPart
== litime
.QuadPart
," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n",
77 tfresult
.Year
, tfresult
.Month
, tfresult
.Day
,
78 tfresult
.Hour
, tfresult
.Minute
, tfresult
.Second
,
79 (int) (liresult
.QuadPart
- litime
.QuadPart
) );
80 /* one second later is beginning of next month */
81 litime
.QuadPart
+= TICKSPERSEC
;
82 pRtlTimeToTimeFields( &litime
, &tfresult
);
83 ok( tfresult
.Year
== tftest
.Year
+ (tftest
.Month
==12) &&
84 tfresult
.Month
== tftest
.Month
% 12 + 1 &&
85 tfresult
.Day
== 1 && tfresult
.Hour
== 0 &&
86 tfresult
.Minute
== 0 && tfresult
.Second
== 0,
87 "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i
,
88 tftest
.Year
+ (tftest
.Month
==12),
89 tftest
.Month
% 12 + 1, 1, 0, 0, 0,
90 tfresult
.Year
, tfresult
.Month
, tfresult
.Day
,
91 tfresult
.Hour
, tfresult
.Minute
, tfresult
.Second
);
92 /* test the inverse */
93 pRtlTimeFieldsToTime( &tfresult
, &liresult
);
94 ok( liresult
.QuadPart
== litime
.QuadPart
," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n",
95 tfresult
.Year
, tfresult
.Month
, tfresult
.Day
,
96 tfresult
.Hour
, tfresult
.Minute
, tfresult
.Second
,
97 (int) (liresult
.QuadPart
- litime
.QuadPart
) );
98 /* advance to the end of the month */
99 litime
.QuadPart
-= TICKSPERSEC
;
100 if( tftest
.Month
== 12) {
105 tftest
.Day
= MonthLengths
[IsLeapYear(tftest
.Year
)][tftest
.Month
- 1];
106 litime
.QuadPart
+= (LONGLONG
) tftest
.Day
* TICKSPERSEC
* SECSPERDAY
;
110 static void test_NtQueryPerformanceCounter(void)
112 LARGE_INTEGER counter
, frequency
;
115 status
= pNtQueryPerformanceCounter(NULL
, NULL
);
116 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
117 status
= pNtQueryPerformanceCounter(NULL
, &frequency
);
118 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
119 status
= pNtQueryPerformanceCounter(&counter
, (void *)0xdeadbee0);
120 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
121 status
= pNtQueryPerformanceCounter((void *)0xdeadbee0, &frequency
);
122 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status
);
124 status
= pNtQueryPerformanceCounter(&counter
, NULL
);
125 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
126 status
= pNtQueryPerformanceCounter(&counter
, &frequency
);
127 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
130 #if defined(__i386__) || defined(__x86_64__)
132 struct hypervisor_shared_data
135 UINT64 QpcMultiplier
;
139 /* 128-bit multiply a by b and return the high 64 bits, same as __umulh */
140 static UINT64
multiply_tsc(UINT64 a
, UINT64 b
)
142 UINT64 ah
= a
>> 32, al
= (UINT32
)a
, bh
= b
>> 32, bl
= (UINT32
)b
, m
;
143 m
= (ah
* bl
) + (bh
* al
) + ((al
* bl
) >> 32);
144 return (ah
* bh
) + (m
>> 32);
147 static void test_RtlQueryPerformanceCounter(void)
149 struct hypervisor_shared_data
*hsd
;
150 KSHARED_USER_DATA
*usd
= (void *)0x7ffe0000;
151 LARGE_INTEGER frequency
, counter
;
157 if (!pRtlQueryPerformanceCounter
|| !pRtlQueryPerformanceFrequency
)
159 win_skip( "RtlQueryPerformanceCounter/Frequency not available, skipping tests\n" );
163 if (!(usd
->u3
.s
.QpcBypassEnabled
& SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED
))
165 todo_wine
win_skip("QpcBypassEnabled is not set, skipping tests\n");
169 if ((usd
->u3
.s
.QpcBypassEnabled
& SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE
))
171 ok( usd
->u3
.s
.QpcBypassEnabled
== (SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED
|SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE
|SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP
),
172 "unexpected QpcBypassEnabled %x, expected 0x83\n", usd
->u3
.s
.QpcBypassEnabled
);
173 ok( usd
->QpcFrequency
== 10000000, "unexpected QpcFrequency %I64d, expected 10000000\n", usd
->QpcFrequency
);
174 ok( !usd
->u3
.s
.QpcShift
, "unexpected QpcShift %d, expected 0\n", usd
->u3
.s
.QpcShift
);
177 status
= pNtQuerySystemInformation( SystemHypervisorSharedPageInformation
, &hsd
, sizeof(void *), &len
);
178 ok( !status
, "NtQuerySystemInformation returned %x\n", status
);
179 ok( len
== sizeof(void *), "unexpected SystemHypervisorSharedPageInformation length %u\n", len
);
180 ok( !!hsd
, "unexpected SystemHypervisorSharedPageInformation address %p\n", hsd
);
183 ret
= pRtlQueryPerformanceCounter( &counter
);
185 ok( ret
, "RtlQueryPerformanceCounter failed\n" );
187 tsc0
= multiply_tsc(tsc0
, hsd
->QpcMultiplier
) + hsd
->QpcBias
+ usd
->QpcBias
;
188 tsc1
= multiply_tsc(tsc1
, hsd
->QpcMultiplier
) + hsd
->QpcBias
+ usd
->QpcBias
;
190 ok( tsc0
<= counter
.QuadPart
, "rdtscp %I64d and RtlQueryPerformanceCounter %I64d are out of order\n", tsc0
, counter
.QuadPart
);
191 ok( counter
.QuadPart
<= tsc1
, "RtlQueryPerformanceCounter %I64d and rdtscp %I64d are out of order\n", counter
.QuadPart
, tsc1
);
195 ok( usd
->u3
.s
.QpcShift
== 10, "unexpected QpcShift %d, expected 10\n", usd
->u3
.s
.QpcShift
);
198 ret
= pRtlQueryPerformanceCounter( &counter
);
200 ok( ret
, "RtlQueryPerformanceCounter failed\n" );
202 tsc0
+= usd
->QpcBias
;
203 tsc0
>>= usd
->u3
.s
.QpcShift
;
204 tsc1
+= usd
->QpcBias
;
205 tsc1
>>= usd
->u3
.s
.QpcShift
;
207 ok( tsc0
<= counter
.QuadPart
, "rdtscp %I64d and RtlQueryPerformanceCounter %I64d are out of order\n", tsc0
, counter
.QuadPart
);
208 ok( counter
.QuadPart
<= tsc1
, "RtlQueryPerformanceCounter %I64d and rdtscp %I64d are out of order\n", counter
.QuadPart
, tsc1
);
211 ret
= pRtlQueryPerformanceFrequency( &frequency
);
212 ok( ret
, "RtlQueryPerformanceFrequency failed\n" );
213 ok( frequency
.QuadPart
== usd
->QpcFrequency
,
214 "RtlQueryPerformanceFrequency returned %I64d, expected USD QpcFrequency %I64d\n",
215 frequency
.QuadPart
, usd
->QpcFrequency
);
219 #define CHECK_CURRENT_TIMER(expected) \
221 ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %x\n", status); \
222 ok(cur2 == (expected), "expected new timer resolution %u, got %u\n", (expected), cur2); \
226 status = NtQueryTimerResolution(&min2, &max2, &cur2); \
227 ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %x\n", status); \
228 ok(min2 == min, "NtQueryTimerResolution() expected min=%u, got %u\n", min, min2); \
229 ok(max2 == max, "NtQueryTimerResolution() expected max=%u, got %u\n", max, max2); \
230 ok(cur2 == expected, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", (expected), cur2); \
233 static void test_TimerResolution(void)
235 ULONG min
, max
, cur
, min2
, max2
, cur2
, set
;
238 status
= NtQueryTimerResolution(NULL
, &max
, &cur
);
239 ok(status
== STATUS_ACCESS_VIOLATION
, "NtQueryTimerResolution(NULL,,) success\n");
241 status
= NtQueryTimerResolution(&min
, NULL
, &cur
);
242 ok(status
== STATUS_ACCESS_VIOLATION
, "NtQueryTimerResolution(,NULL,) success\n");
244 status
= NtQueryTimerResolution(&min
, &max
, NULL
);
245 ok(status
== STATUS_ACCESS_VIOLATION
, "NtQueryTimerResolution(,,NULL) success\n");
250 status
= NtQueryTimerResolution(&min
, &max
, &cur
);
251 ok(status
== STATUS_SUCCESS
, "NtQueryTimerResolution() failed (%x)\n", status
);
252 ok(min
== 156250 /* 1/64s HPET */ || min
== 156001 /* RTC */,
253 "unexpected minimum timer resolution %u\n", min
);
254 ok(0 < max
, "invalid maximum timer resolution, should be 0 < %u\n", max
);
255 ok(max
<= cur
&& cur
<= min
, "invalid timer resolutions, should be %u <= %u <= %u\n", max
, cur
, min
);
257 status
= NtSetTimerResolution(0, FALSE
, NULL
);
258 ok(status
== STATUS_ACCESS_VIOLATION
, "NtSetTimerResolution(,,NULL) success\n");
260 /* Nothing happens if that pointer is not good */
261 status
= NtSetTimerResolution(cur
- 1, TRUE
, NULL
);
262 ok(status
== STATUS_ACCESS_VIOLATION
, "NtSetTimerResolution() failed %x\n", status
);
267 status
= NtQueryTimerResolution(&min2
, &max2
, &cur2
);
268 ok(status
== STATUS_SUCCESS
, "NtQueryTimerResolution() failed (%x)\n", status
);
269 ok(min2
== min
, "NtQueryTimerResolution() expected min=%u, got %u\n", min
, min2
);
270 ok(max2
== max
, "NtQueryTimerResolution() expected max=%u, got %u\n", max
, max2
);
271 ok(cur2
== cur
, "NtQueryTimerResolution() expected timer resolution %u, got %u\n", cur
, cur2
);
273 /* 'fails' until the first valid timer resolution request */
275 status
= NtSetTimerResolution(0, FALSE
, &cur2
);
276 ok(status
== STATUS_TIMER_RESOLUTION_NOT_SET
, "NtSetTimerResolution() failed %x\n", status
);
277 /* and returns the current timer resolution */
278 ok(cur2
== cur
, "expected requested timer resolution %u, got %u\n", cur
, cur2
);
282 status
= NtSetTimerResolution(max
- 1, TRUE
, &cur2
);
283 CHECK_CURRENT_TIMER(max
);
285 /* Rescinds our timer resolution request */
287 status
= NtSetTimerResolution(0, FALSE
, &cur2
);
288 ok(status
== STATUS_SUCCESS
, "NtSetTimerResolution() failed %x\n", status
);
289 /* -> the timer resolution was reset to its initial value */
290 ok(cur2
== cur
, "expected requested timer resolution %u, got %u\n", min
, cur2
);
293 status
= NtSetTimerResolution(0, FALSE
, &cur2
);
294 ok(status
== STATUS_TIMER_RESOLUTION_NOT_SET
, "NtSetTimerResolution() failed %x\n", status
);
295 ok(cur2
== cur
, "expected requested timer resolution %u, got %u\n", cur
, cur2
);
298 status
= NtSetTimerResolution(min
+ 1, TRUE
, &cur2
);
299 ok(status
== STATUS_SUCCESS
, "NtSetTimerResolution() failed %x\n", status
);
300 /* This works because:
301 * - Either cur is the minimum (15.6 ms) resolution already, i.e. the
302 * closest valid value 'set' is rounded to.
303 * - Or some other application requested a higher timer resolution, cur,
304 * and any attempt to lower the resolution has no effect until that
305 * request is rescinded (hopefully after this test is done).
307 CHECK_CURRENT_TIMER(cur
);
309 /* The requested resolution may (win7) or may not be rounded */
311 set
= max
< cur
? cur
- 1 : max
;
312 status
= NtSetTimerResolution(set
, TRUE
, &cur2
);
313 ok(status
== STATUS_SUCCESS
, "NtSetTimerResolution() failed %x\n", status
);
314 ok(cur2
<= set
, "expected new timer resolution %u <= %u\n", cur2
, set
);
315 trace("timer resolution: %u(max) <= %u(cur) <= %u(prev) <= %u(min)\n", max
, cur2
, cur
, min
);
318 status
= NtSetTimerResolution(cur
+ 1, TRUE
, &cur2
);
319 CHECK_CURRENT_TIMER(cur
); /* see min + 1 test */
321 /* Cleanup by rescinding the last request */
323 status
= NtSetTimerResolution(0, FALSE
, &cur2
);
324 ok(status
== STATUS_SUCCESS
, "NtSetTimerResolution() failed %x\n", status
);
325 ok(cur2
== cur
, "expected requested timer resolution %u, got %u\n", set
, cur2
);
328 static void test_RtlQueryTimeZoneInformation(void)
330 RTL_DYNAMIC_TIME_ZONE_INFORMATION tzinfo
, tzinfo2
;
334 /* test RtlQueryTimeZoneInformation returns an indirect string,
335 e.g. @tzres.dll,-32 (Vista or later) */
336 if (!pRtlQueryTimeZoneInformation
|| !pRtlQueryDynamicTimeZoneInformation
)
338 win_skip("Time zone name tests require Vista or later\n");
342 memset(&tzinfo
, 0xcc, sizeof(tzinfo
));
343 status
= pRtlQueryDynamicTimeZoneInformation(&tzinfo
);
344 ok(status
== STATUS_SUCCESS
,
345 "RtlQueryDynamicTimeZoneInformation failed, got %08x\n", status
);
346 ok(tzinfo
.StandardName
[0] == '@' ||
347 broken(tzinfo
.StandardName
[0]), /* some win10 2004 */
348 "standard time zone name isn't an indirect string, got %s\n",
349 wine_dbgstr_w(tzinfo
.StandardName
));
350 ok(tzinfo
.DaylightName
[0] == '@' ||
351 broken(tzinfo
.DaylightName
[0]), /* some win10 2004 */
352 "daylight time zone name isn't an indirect string, got %s\n",
353 wine_dbgstr_w(tzinfo
.DaylightName
));
355 memset(&tzinfo2
, 0xcc, sizeof(tzinfo2
));
356 status
= pNtQuerySystemInformation( SystemDynamicTimeZoneInformation
, &tzinfo2
, sizeof(tzinfo2
), &len
);
357 ok( !status
, "NtQuerySystemInformation failed %x\n", status
);
358 ok( len
== sizeof(tzinfo2
), "wrong len %u\n", len
);
359 ok( !memcmp( &tzinfo
, &tzinfo2
, sizeof(tzinfo2
) ), "tz data is different\n" );
361 memset(&tzinfo
, 0xcc, sizeof(tzinfo
));
362 status
= pRtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION
*)&tzinfo
);
363 ok(status
== STATUS_SUCCESS
,
364 "RtlQueryTimeZoneInformation failed, got %08x\n", status
);
365 ok(tzinfo
.StandardName
[0] == '@' ||
366 broken(tzinfo
.StandardName
[0]), /* some win10 2004 */
367 "standard time zone name isn't an indirect string, got %s\n",
368 wine_dbgstr_w(tzinfo
.StandardName
));
369 ok(tzinfo
.DaylightName
[0] == '@' ||
370 broken(tzinfo
.DaylightName
[0]), /* some win10 2004 */
371 "daylight time zone name isn't an indirect string, got %s\n",
372 wine_dbgstr_w(tzinfo
.DaylightName
));
374 memset(&tzinfo
, 0xcc, sizeof(tzinfo
));
375 status
= pRtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION
*)&tzinfo
);
376 ok(status
== STATUS_SUCCESS
,
377 "RtlQueryTimeZoneInformation failed, got %08x\n", status
);
378 ok(tzinfo
.StandardName
[0] == '@' ||
379 broken(tzinfo
.StandardName
[0]), /* some win10 2004 */
380 "standard time zone name isn't an indirect string, got %s\n",
381 wine_dbgstr_w(tzinfo
.StandardName
));
382 ok(tzinfo
.DaylightName
[0] == '@' ||
383 broken(tzinfo
.DaylightName
[0]), /* some win10 2004 */
384 "daylight time zone name isn't an indirect string, got %s\n",
385 wine_dbgstr_w(tzinfo
.DaylightName
));
387 memset(&tzinfo2
, 0xcc, sizeof(tzinfo2
));
388 status
= pNtQuerySystemInformation( SystemCurrentTimeZoneInformation
, &tzinfo2
,
389 sizeof(RTL_TIME_ZONE_INFORMATION
), &len
);
390 ok( !status
, "NtQuerySystemInformation failed %x\n", status
);
391 ok( len
== sizeof(RTL_TIME_ZONE_INFORMATION
), "wrong len %u\n", len
);
392 ok( !memcmp( &tzinfo
, &tzinfo2
, sizeof(RTL_TIME_ZONE_INFORMATION
) ), "tz data is different\n" );
395 static ULONGLONG
read_ksystem_time(volatile KSYSTEM_TIME
*time
)
400 high
= time
->High1Time
;
403 while (high
!= time
->High2Time
);
404 return high
<< 32 | low
;
407 static void test_user_shared_data_time(void)
409 KSHARED_USER_DATA
*user_shared_data
= (void *)0x7ffe0000;
410 ULONGLONG t1
, t2
, t3
;
417 if (user_shared_data
->NtMajorVersion
<= 5 && user_shared_data
->NtMinorVersion
<= 1)
418 t2
= (DWORD
)((*(volatile ULONG
*)&user_shared_data
->TickCountLowDeprecated
* (ULONG64
)user_shared_data
->TickCountMultiplier
) >> 24);
420 t2
= (DWORD
)((read_ksystem_time(&user_shared_data
->u
.TickCount
) * user_shared_data
->TickCountMultiplier
) >> 24);
422 } while(t3
< t1
&& i
++ < 1); /* allow for wrap, but only once */
424 ok(t1
<= t2
, "USD TickCount / GetTickCount are out of order: %s %s\n",
425 wine_dbgstr_longlong(t1
), wine_dbgstr_longlong(t2
));
426 ok(t2
<= t3
, "USD TickCount / GetTickCount are out of order: %s %s\n",
427 wine_dbgstr_longlong(t2
), wine_dbgstr_longlong(t3
));
432 LARGE_INTEGER system_time
;
433 NtQuerySystemTime(&system_time
);
434 t1
= system_time
.QuadPart
;
435 t2
= read_ksystem_time(&user_shared_data
->SystemTime
);
436 NtQuerySystemTime(&system_time
);
437 t3
= system_time
.QuadPart
;
438 } while(t3
< t1
&& i
++ < 1); /* allow for wrap, but only once */
440 /* FIXME: not always in order, but should be close */
441 todo_wine_if(t1
> t2
&& t1
- t2
< 50 * TICKSPERMSEC
)
442 ok(t1
<= t2
, "USD SystemTime / NtQuerySystemTime are out of order %s %s\n",
443 wine_dbgstr_longlong(t1
), wine_dbgstr_longlong(t2
));
444 ok(t2
<= t3
, "USD SystemTime / NtQuerySystemTime are out of order %s %s\n",
445 wine_dbgstr_longlong(t2
), wine_dbgstr_longlong(t3
));
447 if (!pRtlQueryUnbiasedInterruptTime
)
448 win_skip("skipping RtlQueryUnbiasedInterruptTime tests\n");
454 pRtlQueryUnbiasedInterruptTime(&t1
);
455 t2
= read_ksystem_time(&user_shared_data
->InterruptTime
) - user_shared_data
->InterruptTimeBias
;
456 pRtlQueryUnbiasedInterruptTime(&t3
);
457 } while(t3
< t1
&& i
++ < 1); /* allow for wrap, but only once */
459 ok(t1
<= t2
, "USD InterruptTime / RtlQueryUnbiasedInterruptTime are out of order %s %s\n",
460 wine_dbgstr_longlong(t1
), wine_dbgstr_longlong(t2
));
461 ok(t2
<= t3
, "USD InterruptTime / RtlQueryUnbiasedInterruptTime are out of order %s %s\n",
462 wine_dbgstr_longlong(t2
), wine_dbgstr_longlong(t3
));
468 HMODULE mod
= GetModuleHandleA("ntdll.dll");
469 pRtlTimeToTimeFields
= (void *)GetProcAddress(mod
,"RtlTimeToTimeFields");
470 pRtlTimeFieldsToTime
= (void *)GetProcAddress(mod
,"RtlTimeFieldsToTime");
471 pNtQueryPerformanceCounter
= (void *)GetProcAddress(mod
, "NtQueryPerformanceCounter");
472 pNtQuerySystemInformation
= (void *)GetProcAddress(mod
, "NtQuerySystemInformation");
473 pRtlQueryTimeZoneInformation
=
474 (void *)GetProcAddress(mod
, "RtlQueryTimeZoneInformation");
475 pRtlQueryDynamicTimeZoneInformation
=
476 (void *)GetProcAddress(mod
, "RtlQueryDynamicTimeZoneInformation");
477 pRtlQueryUnbiasedInterruptTime
= (void *)GetProcAddress(mod
, "RtlQueryUnbiasedInterruptTime");
478 pRtlQueryPerformanceCounter
= (void *)GetProcAddress(mod
, "RtlQueryPerformanceCounter");
479 pRtlQueryPerformanceFrequency
= (void *)GetProcAddress(mod
, "RtlQueryPerformanceFrequency");
481 if (pRtlTimeToTimeFields
&& pRtlTimeFieldsToTime
)
482 test_pRtlTimeToTimeFields();
484 win_skip("Required time conversion functions are not available\n");
485 test_NtQueryPerformanceCounter();
486 test_RtlQueryTimeZoneInformation();
487 test_user_shared_data_time();
488 #if defined(__i386__) || defined(__x86_64__)
489 test_RtlQueryPerformanceCounter();
491 test_TimerResolution();