dc570e14ce91ae4945aadd6753ca3094aefcd7b1
[reactos.git] / modules / rostests / winetests / ntdll / time.c
1 /*
2 * Unit test suite for ntdll time functions
3 *
4 * Copyright 2004 Rein Klazes
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #define NONAMELESSUNION
22 #include "ntdll_test.h"
23
24 /* FIXME: Inspect */
25
26 typedef struct _KSYSTEM_TIME {
27 ULONG LowPart;
28 LONG High1Time;
29 LONG High2Time;
30 } KSYSTEM_TIME, *PKSYSTEM_TIME;
31
32 typedef enum _NT_PRODUCT_TYPE {
33 NtProductWinNt = 1,
34 NtProductLanManNt,
35 NtProductServer
36 } NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE;
37
38 #define PROCESSOR_FEATURE_MAX 64
39
40 typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
41 {
42 StandardDesign,
43 NEC98x86,
44 EndAlternatives
45 } ALTERNATIVE_ARCHITECTURE_TYPE;
46
47 #define MAX_WOW64_SHARED_ENTRIES 16
48
49 typedef struct _KUSER_SHARED_DATA {
50 ULONG TickCountLowDeprecated;
51 ULONG TickCountMultiplier;
52 volatile KSYSTEM_TIME InterruptTime;
53 volatile KSYSTEM_TIME SystemTime;
54 volatile KSYSTEM_TIME TimeZoneBias;
55 USHORT ImageNumberLow;
56 USHORT ImageNumberHigh;
57 WCHAR NtSystemRoot[260];
58 ULONG MaxStackTraceDepth;
59 ULONG CryptoExponent;
60 ULONG TimeZoneId;
61 ULONG LargePageMinimum;
62 ULONG Reserved2[7];
63 NT_PRODUCT_TYPE NtProductType;
64 BOOLEAN ProductTypeIsValid;
65 ULONG NtMajorVersion;
66 ULONG NtMinorVersion;
67 BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
68 ULONG Reserved1;
69 ULONG Reserved3;
70 volatile ULONG TimeSlip;
71 ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
72 LARGE_INTEGER SystemExpirationDate;
73 ULONG SuiteMask;
74 BOOLEAN KdDebuggerEnabled;
75 UCHAR NXSupportPolicy;
76 volatile ULONG ActiveConsoleId;
77 volatile ULONG DismountCount;
78 ULONG ComPlusPackage;
79 ULONG LastSystemRITEventTickCount;
80 ULONG NumberOfPhysicalPages;
81 BOOLEAN SafeBootMode;
82 ULONG TraceLogging;
83 ULONGLONG TestRetInstruction;
84 ULONG SystemCall;
85 ULONG SystemCallReturn;
86 ULONGLONG SystemCallPad[3];
87 union {
88 volatile KSYSTEM_TIME TickCount;
89 volatile ULONG64 TickCountQuad;
90 } DUMMYUNIONNAME;
91 ULONG Cookie;
92 ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES];
93 } KSHARED_USER_DATA, *PKSHARED_USER_DATA;
94
95 #define TICKSPERSEC 10000000
96 #define TICKSPERMSEC 10000
97 #define SECSPERDAY 86400
98
99 static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ;
100 static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_INTEGER Time) ;
101 static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency );
102 static ULONG (WINAPI *pNtGetTickCount)(void);
103
104 static const int MonthLengths[2][12] =
105 {
106 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
107 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
108 };
109
110 static inline BOOL IsLeapYear(int Year)
111 {
112 return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0);
113 }
114
115 /* start time of the tests */
116 static TIME_FIELDS tftest = {1889,12,31,23,59,59,0,0};
117
118 static void test_pRtlTimeToTimeFields(void)
119 {
120 LARGE_INTEGER litime , liresult;
121 TIME_FIELDS tfresult;
122 int i=0;
123 litime.QuadPart = ((ULONGLONG)0x0144017a << 32) | 0xf0b0a980;
124 while( tftest.Year < 2110 ) {
125 /* test at the last second of the month */
126 pRtlTimeToTimeFields( &litime, &tfresult);
127 ok( tfresult.Year == tftest.Year && tfresult.Month == tftest.Month &&
128 tfresult.Day == tftest.Day && tfresult.Hour == tftest.Hour &&
129 tfresult.Minute == tftest.Minute && tfresult.Second == tftest.Second,
130 "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i,
131 tftest.Year, tftest.Month, tftest.Day,
132 tftest.Hour, tftest.Minute,tftest.Second,
133 tfresult.Year, tfresult.Month, tfresult.Day,
134 tfresult.Hour, tfresult.Minute, tfresult.Second);
135 /* test the inverse */
136 pRtlTimeFieldsToTime( &tfresult, &liresult);
137 ok( liresult.QuadPart == litime.QuadPart," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n",
138 tfresult.Year, tfresult.Month, tfresult.Day,
139 tfresult.Hour, tfresult.Minute, tfresult.Second,
140 (int) (liresult.QuadPart - litime.QuadPart) );
141 /* one second later is beginning of next month */
142 litime.QuadPart += TICKSPERSEC ;
143 pRtlTimeToTimeFields( &litime, &tfresult);
144 ok( tfresult.Year == tftest.Year + (tftest.Month ==12) &&
145 tfresult.Month == tftest.Month % 12 + 1 &&
146 tfresult.Day == 1 && tfresult.Hour == 0 &&
147 tfresult.Minute == 0 && tfresult.Second == 0,
148 "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i,
149 tftest.Year + (tftest.Month ==12),
150 tftest.Month % 12 + 1, 1, 0, 0, 0,
151 tfresult.Year, tfresult.Month, tfresult.Day,
152 tfresult.Hour, tfresult.Minute, tfresult.Second);
153 /* test the inverse */
154 pRtlTimeFieldsToTime( &tfresult, &liresult);
155 ok( liresult.QuadPart == litime.QuadPart," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n",
156 tfresult.Year, tfresult.Month, tfresult.Day,
157 tfresult.Hour, tfresult.Minute, tfresult.Second,
158 (int) (liresult.QuadPart - litime.QuadPart) );
159 /* advance to the end of the month */
160 litime.QuadPart -= TICKSPERSEC ;
161 if( tftest.Month == 12) {
162 tftest.Month = 1;
163 tftest.Year += 1;
164 } else
165 tftest.Month += 1;
166 tftest.Day = MonthLengths[IsLeapYear(tftest.Year)][tftest.Month - 1];
167 litime.QuadPart += (LONGLONG) tftest.Day * TICKSPERSEC * SECSPERDAY;
168 }
169 }
170
171 static void test_NtQueryPerformanceCounter(void)
172 {
173 LARGE_INTEGER counter, frequency;
174 NTSTATUS status;
175
176 status = pNtQueryPerformanceCounter(NULL, NULL);
177 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
178 status = pNtQueryPerformanceCounter(NULL, &frequency);
179 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
180 status = pNtQueryPerformanceCounter(&counter, (void *)0xdeadbee0);
181 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
182 status = pNtQueryPerformanceCounter((void *)0xdeadbee0, &frequency);
183 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
184
185 status = pNtQueryPerformanceCounter(&counter, NULL);
186 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
187 status = pNtQueryPerformanceCounter(&counter, &frequency);
188 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
189 }
190
191 static void test_NtGetTickCount(void)
192 {
193 #ifndef _WIN64
194 KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000;
195 LONG diff;
196 int i;
197
198 if (!pNtGetTickCount)
199 {
200 win_skip("NtGetTickCount is not available\n");
201 return;
202 }
203
204 for (i = 0; i < 5; ++i)
205 {
206 diff = (user_shared_data->u.TickCountQuad * user_shared_data->TickCountMultiplier) >> 24;
207 diff = pNtGetTickCount() - diff;
208 ok(diff < 32, "NtGetTickCount - TickCountQuad too high, expected < 32 got %d\n", diff);
209 Sleep(50);
210 }
211 #endif
212 }
213
214 START_TEST(time)
215 {
216 HMODULE mod = GetModuleHandleA("ntdll.dll");
217 pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields");
218 pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime");
219 pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter");
220 pNtGetTickCount = (void *)GetProcAddress(mod,"NtGetTickCount");
221 if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime)
222 test_pRtlTimeToTimeFields();
223 else
224 win_skip("Required time conversion functions are not available\n");
225 test_NtQueryPerformanceCounter();
226 test_NtGetTickCount();
227 }