Reactos
at master 1266 lines 51 kB view raw
1/* 2 * Unit test suite for time functions 3 * 4 * Copyright 2004 Uwe Bonnes 5 * Copyright 2007 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22#include "wine/test.h" 23#include "winbase.h" 24#include "winnls.h" 25#include "winternl.h" 26 27static BOOL (WINAPI *pTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); 28static BOOL (WINAPI *pSystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); 29static BOOL (WINAPI *pGetSystemTimes)(LPFILETIME, LPFILETIME, LPFILETIME); 30static int (WINAPI *pGetCalendarInfoA)(LCID,CALID,CALTYPE,LPSTR,int,LPDWORD); 31static int (WINAPI *pGetCalendarInfoW)(LCID,CALID,CALTYPE,LPWSTR,int,LPDWORD); 32static DWORD (WINAPI *pGetDynamicTimeZoneInformation)(DYNAMIC_TIME_ZONE_INFORMATION*); 33static void (WINAPI *pGetSystemTimePreciseAsFileTime)(LPFILETIME); 34static BOOL (WINAPI *pGetTimeZoneInformationForYear)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION); 35static ULONG (WINAPI *pNtGetTickCount)(void); 36 37#define SECSPERMIN 60 38#define SECSPERDAY 86400 39/* 1601 to 1970 is 369 years plus 89 leap days */ 40#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) 41#define TICKSPERSEC 10000000 42#define TICKSPERMSEC 10000 43#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) 44 45 46#define NEWYEAR_1980_HI 0x01a8e79f 47#define NEWYEAR_1980_LO 0xe1d58000 48 49#define MAYDAY_2002_HI 0x01c1f107 50#define MAYDAY_2002_LO 0xb82b6000 51 52#define ATIME_HI 0x1c2349b 53#define ATIME_LOW 0x580716b0 54 55#define LOCAL_ATIME_HI 0x01c23471 56#define LOCAL_ATIME_LOW 0x6f310eb0 57 58#define DOS_DATE(y,m,d) ( (((y)-1980)<<9) | ((m)<<5) | (d) ) 59#define DOS_TIME(h,m,s) ( ((h)<<11) | ((m)<<5) | ((s)>>1) ) 60 61 62#define SETUP_1980(st) \ 63 (st).wYear = 1980; \ 64 (st).wMonth = 1; \ 65 (st).wDay = 1; \ 66 (st).wHour = 0; \ 67 (st).wMinute = 0; \ 68 (st).wSecond = 0; \ 69 (st).wMilliseconds = 0; 70 71#define SETUP_2002(st) \ 72 (st).wYear = 2002; \ 73 (st).wMonth = 5; \ 74 (st).wDay = 1; \ 75 (st).wHour = 12; \ 76 (st).wMinute = 0; \ 77 (st).wSecond = 0; \ 78 (st).wMilliseconds = 0; 79 80#define SETUP_ATIME(st) \ 81 (st).wYear = 2002; \ 82 (st).wMonth = 7; \ 83 (st).wDay = 26; \ 84 (st).wHour = 11; \ 85 (st).wMinute = 55; \ 86 (st).wSecond = 32; \ 87 (st).wMilliseconds = 123; 88 89#define SETUP_ZEROTIME(st) \ 90 (st).wYear = 1601; \ 91 (st).wMonth = 1; \ 92 (st).wDay = 1; \ 93 (st).wHour = 0; \ 94 (st).wMinute = 0; \ 95 (st).wSecond = 0; \ 96 (st).wMilliseconds = 0; 97 98#define SETUP_EARLY(st) \ 99 (st).wYear = 1600; \ 100 (st).wMonth = 12; \ 101 (st).wDay = 31; \ 102 (st).wHour = 23; \ 103 (st).wMinute = 59; \ 104 (st).wSecond = 59; \ 105 (st).wMilliseconds = 999; 106 107 108static void test_conversions(void) 109{ 110 FILETIME ft; 111 SYSTEMTIME st; 112 113 memset(&ft,0,sizeof ft); 114 115 SetLastError(0xdeadbeef); 116 SETUP_EARLY(st) 117 ok (!SystemTimeToFileTime(&st, &ft), "Conversion succeeded EARLY\n"); 118 ok (GetLastError() == ERROR_INVALID_PARAMETER || 119 GetLastError() == 0xdeadbeef, /* win9x */ 120 "EARLY should be INVALID\n"); 121 122 SETUP_ZEROTIME(st) 123 ok (SystemTimeToFileTime(&st, &ft), "Conversion failed ZERO_TIME\n"); 124 ok( (!((ft.dwHighDateTime != 0) || (ft.dwLowDateTime != 0))), 125 "Wrong time for ATIME: %08lx %08lx (correct %08x %08x)\n", 126 ft.dwLowDateTime, ft.dwHighDateTime, 0, 0); 127 128 129 SETUP_ATIME(st) 130 ok (SystemTimeToFileTime(&st,&ft), "Conversion Failed ATIME\n"); 131 ok( (!((ft.dwHighDateTime != ATIME_HI) || (ft.dwLowDateTime!=ATIME_LOW))), 132 "Wrong time for ATIME: %08lx %08lx (correct %08x %08x)\n", 133 ft.dwLowDateTime, ft.dwHighDateTime, ATIME_LOW, ATIME_HI); 134 135 136 SETUP_2002(st) 137 ok (SystemTimeToFileTime(&st, &ft), "Conversion failed 2002\n"); 138 139 ok( (!((ft.dwHighDateTime != MAYDAY_2002_HI) || 140 (ft.dwLowDateTime!=MAYDAY_2002_LO))), 141 "Wrong time for 2002 %08lx %08lx (correct %08x %08x)\n", ft.dwLowDateTime, 142 ft.dwHighDateTime, MAYDAY_2002_LO, MAYDAY_2002_HI); 143 144 145 SETUP_1980(st) 146 ok((SystemTimeToFileTime(&st, &ft)), "Conversion failed 1980\n"); 147 148 ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) || 149 (ft.dwLowDateTime!=NEWYEAR_1980_LO))) , 150 "Wrong time for 1980 %08lx %08lx (correct %08x %08x)\n", ft.dwLowDateTime, 151 ft.dwHighDateTime, NEWYEAR_1980_LO,NEWYEAR_1980_HI ); 152 153 ok(DosDateTimeToFileTime(DOS_DATE(1980,1,1),DOS_TIME(0,0,0),&ft), 154 "DosDateTimeToFileTime() failed\n"); 155 156 ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) || 157 (ft.dwLowDateTime!=NEWYEAR_1980_LO))), 158 "Wrong time DosDateTimeToFileTime %08lx %08lx (correct %08x %08x)\n", 159 ft.dwHighDateTime, ft.dwLowDateTime, NEWYEAR_1980_HI, NEWYEAR_1980_LO); 160 161} 162 163static void test_invalid_arg(void) 164{ 165 FILETIME ft; 166 SYSTEMTIME st; 167 168 169 /* Invalid argument checks */ 170 171 memset(&ft,0,sizeof ft); 172 ok( DosDateTimeToFileTime(DOS_DATE(1980,1,1),DOS_TIME(0,0,0),&ft), /* this is 1 Jan 1980 00:00:00 */ 173 "DosDateTimeToFileTime() failed\n"); 174 175 ok( (ft.dwHighDateTime==NEWYEAR_1980_HI) && (ft.dwLowDateTime==NEWYEAR_1980_LO), 176 "filetime for 1/1/80 00:00:00 was %08lx %08lx\n", ft.dwHighDateTime, ft.dwLowDateTime); 177 178 /* now check SystemTimeToFileTime */ 179 memset(&ft,0,sizeof ft); 180 181 182 /* try with a bad month */ 183 SETUP_1980(st) 184 st.wMonth = 0; 185 186 ok( !SystemTimeToFileTime(&st, &ft), "bad month\n"); 187 188 /* with a bad hour */ 189 SETUP_1980(st) 190 st.wHour = 24; 191 192 ok( !SystemTimeToFileTime(&st, &ft), "bad hour\n"); 193 194 /* with a bad minute */ 195 SETUP_1980(st) 196 st.wMinute = 60; 197 198 ok( !SystemTimeToFileTime(&st, &ft), "bad minute\n"); 199} 200 201static LONGLONG system_time_to_minutes(const SYSTEMTIME *st) 202{ 203 BOOL ret; 204 FILETIME ft; 205 LONGLONG minutes; 206 207 SetLastError(0xdeadbeef); 208 ret = SystemTimeToFileTime(st, &ft); 209 ok(ret, "SystemTimeToFileTime error %lu\n", GetLastError()); 210 211 minutes = ((LONGLONG)ft.dwHighDateTime << 32) + ft.dwLowDateTime; 212 minutes /= (LONGLONG)600000000; /* convert to minutes */ 213 return minutes; 214} 215 216static LONG get_tz_bias(const TIME_ZONE_INFORMATION *tzinfo, DWORD tz_id) 217{ 218 switch (tz_id) 219 { 220 case TIME_ZONE_ID_DAYLIGHT: 221 if (memcmp(&tzinfo->StandardDate, &tzinfo->DaylightDate, sizeof(tzinfo->DaylightDate)) != 0) 222 return tzinfo->DaylightBias; 223 /* fall through */ 224 225 case TIME_ZONE_ID_STANDARD: 226 return tzinfo->StandardBias; 227 228 default: 229 trace("unknown time zone id %ld\n", tz_id); 230 /* fall through */ 231 case TIME_ZONE_ID_UNKNOWN: 232 return 0; 233 } 234} 235 236static void test_GetTimeZoneInformation(void) 237{ 238 char std_name[32], dlt_name[32]; 239 TIME_ZONE_INFORMATION tzinfo, tzinfo1; 240 BOOL res; 241 DWORD tz_id; 242 SYSTEMTIME st, current, utc, local; 243 FILETIME l_ft, s_ft; 244 LONGLONG l_time, s_time; 245 LONG diff; 246 247 GetSystemTime(&st); 248 s_time = system_time_to_minutes(&st); 249 250 SetLastError(0xdeadbeef); 251 res = SystemTimeToFileTime(&st, &s_ft); 252 ok(res, "SystemTimeToFileTime error %lu\n", GetLastError()); 253 SetLastError(0xdeadbeef); 254 res = FileTimeToLocalFileTime(&s_ft, &l_ft); 255 ok(res, "FileTimeToLocalFileTime error %lu\n", GetLastError()); 256 SetLastError(0xdeadbeef); 257 res = FileTimeToSystemTime(&l_ft, &local); 258 ok(res, "FileTimeToSystemTime error %lu\n", GetLastError()); 259 l_time = system_time_to_minutes(&local); 260 261 tz_id = GetTimeZoneInformation(&tzinfo); 262 ok(tz_id != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 263 264 trace("tz_id %lu (%s)\n", tz_id, 265 tz_id == TIME_ZONE_ID_DAYLIGHT ? "TIME_ZONE_ID_DAYLIGHT" : 266 (tz_id == TIME_ZONE_ID_STANDARD ? "TIME_ZONE_ID_STANDARD" : 267 (tz_id == TIME_ZONE_ID_UNKNOWN ? "TIME_ZONE_ID_UNKNOWN" : 268 "TIME_ZONE_ID_INVALID"))); 269 270 WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1, std_name, sizeof(std_name), NULL, NULL); 271 WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1, dlt_name, sizeof(dlt_name), NULL, NULL); 272 trace("bias %ld, %s - %s\n", tzinfo.Bias, std_name, dlt_name); 273 trace("standard (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %ld\n", 274 tzinfo.StandardDate.wDay, tzinfo.StandardDate.wMonth, 275 tzinfo.StandardDate.wYear, tzinfo.StandardDate.wDayOfWeek, 276 tzinfo.StandardDate.wHour, tzinfo.StandardDate.wMinute, 277 tzinfo.StandardDate.wSecond, tzinfo.StandardDate.wMilliseconds, 278 tzinfo.StandardBias); 279 trace("daylight (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %ld\n", 280 tzinfo.DaylightDate.wDay, tzinfo.DaylightDate.wMonth, 281 tzinfo.DaylightDate.wYear, tzinfo.DaylightDate.wDayOfWeek, 282 tzinfo.DaylightDate.wHour, tzinfo.DaylightDate.wMinute, 283 tzinfo.DaylightDate.wSecond, tzinfo.DaylightDate.wMilliseconds, 284 tzinfo.DaylightBias); 285 286 diff = (LONG)(s_time - l_time); 287 ok(diff == tzinfo.Bias + get_tz_bias(&tzinfo, tz_id), 288 "system/local diff %ld != tz bias %ld\n", 289 diff, tzinfo.Bias + get_tz_bias(&tzinfo, tz_id)); 290 291 ok(SetEnvironmentVariableA("TZ","GMT0") != 0, 292 "SetEnvironmentVariableA failed\n"); 293 res = GetTimeZoneInformation(&tzinfo1); 294 ok(res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 295 296 ok(((tzinfo.Bias == tzinfo1.Bias) && 297 (tzinfo.StandardBias == tzinfo1.StandardBias) && 298 (tzinfo.DaylightBias == tzinfo1.DaylightBias)), 299 "Bias influenced by TZ variable\n"); 300 ok(SetEnvironmentVariableA("TZ",NULL) != 0, 301 "SetEnvironmentVariableA failed\n"); 302 303 if (!pSystemTimeToTzSpecificLocalTime) 304 { 305 win_skip("SystemTimeToTzSpecificLocalTime not available\n"); 306 return; 307 } 308 309 diff = get_tz_bias(&tzinfo, tz_id); 310 311 utc = st; 312 SetLastError(0xdeadbeef); 313 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &current); 314 if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 315 { 316 win_skip("SystemTimeToTzSpecificLocalTime is not implemented\n"); 317 return; 318 } 319 320 ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError()); 321 s_time = system_time_to_minutes(&current); 322 323 tzinfo.StandardBias -= 123; 324 tzinfo.DaylightBias += 456; 325 326 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 327 ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError()); 328 l_time = system_time_to_minutes(&local); 329 ok(l_time - s_time == diff - get_tz_bias(&tzinfo, tz_id), "got %ld, expected %ld\n", 330 (LONG)(l_time - s_time), diff - get_tz_bias(&tzinfo, tz_id)); 331 332 /* pretend that there is no transition dates */ 333 tzinfo.DaylightDate.wDay = 0; 334 tzinfo.DaylightDate.wMonth = 0; 335 tzinfo.DaylightDate.wYear = 0; 336 tzinfo.StandardDate.wDay = 0; 337 tzinfo.StandardDate.wMonth = 0; 338 tzinfo.StandardDate.wYear = 0; 339 340 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 341 ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError()); 342 l_time = system_time_to_minutes(&local); 343 ok(l_time - s_time == diff, "got %ld, expected %ld\n", 344 (LONG)(l_time - s_time), diff); 345 346 /* test 23:01, 31st of December date */ 347 memset(&tzinfo, 0, sizeof(tzinfo)); 348 tzinfo.StandardDate.wMonth = 10; 349 tzinfo.StandardDate.wDay = 5; 350 tzinfo.StandardDate.wHour = 2; 351 tzinfo.StandardDate.wMinute = 0; 352 tzinfo.DaylightDate.wMonth = 4; 353 tzinfo.DaylightDate.wDay = 1; 354 tzinfo.DaylightDate.wHour = 2; 355 tzinfo.Bias = 0; 356 tzinfo.StandardBias = 0; 357 tzinfo.DaylightBias = -60; 358 utc.wYear = 2012; 359 utc.wMonth = 12; 360 utc.wDay = 31; 361 utc.wHour = 23; 362 utc.wMinute = 1; 363 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 364 ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError()); 365 ok(local.wYear==2012 && local.wMonth==12 && local.wDay==31 && local.wHour==23 && local.wMinute==1, 366 "got (%d-%d-%d %02d:%02d), expected (2012-12-31 23:01)\n", 367 local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute); 368} 369 370static void test_FileTimeToSystemTime(void) 371{ 372 FILETIME ft; 373 SYSTEMTIME st; 374 ULONGLONG time = (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; 375 BOOL ret; 376 377 ft.dwHighDateTime = 0; 378 ft.dwLowDateTime = 0; 379 ret = FileTimeToSystemTime(&ft, &st); 380 ok( ret, 381 "FileTimeToSystemTime() failed with Error %ld\n",GetLastError()); 382 ok(((st.wYear == 1601) && (st.wMonth == 1) && (st.wDay == 1) && 383 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 0) && 384 (st.wMilliseconds == 0)), 385 "Got Year %4d Month %2d Day %2d\n", st.wYear, st.wMonth, st.wDay); 386 387 ft.dwHighDateTime = (UINT)(time >> 32); 388 ft.dwLowDateTime = (UINT)time; 389 ret = FileTimeToSystemTime(&ft, &st); 390 ok( ret, 391 "FileTimeToSystemTime() failed with Error %ld\n",GetLastError()); 392 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 393 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 394 (st.wMilliseconds == 0)), 395 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 396 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 397 st.wMilliseconds); 398 399 ft.dwHighDateTime = -1; 400 ft.dwLowDateTime = -1; 401 SetLastError(0xdeadbeef); 402 ret = FileTimeToSystemTime(&ft, &st); 403 ok(!ret, "expected failure\n"); 404 ok(GetLastError() == ERROR_INVALID_PARAMETER, 405 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 406} 407 408static void test_FileTimeToLocalFileTime(void) 409{ 410 FILETIME ft, lft; 411 SYSTEMTIME st; 412 TIME_ZONE_INFORMATION tzinfo; 413 DWORD res = GetTimeZoneInformation(&tzinfo); 414 ULONGLONG time = (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970 + 415 (LONGLONG)(tzinfo.Bias + 416 ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias : 417 ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * 418 SECSPERMIN *TICKSPERSEC; 419 BOOL ret; 420 421 ok( res != TIME_ZONE_ID_INVALID , "GetTimeZoneInformation failed\n"); 422 ft.dwHighDateTime = (UINT)(time >> 32); 423 ft.dwLowDateTime = (UINT)time; 424 ret = FileTimeToLocalFileTime(&ft, &lft); 425 ok( ret, 426 "FileTimeToLocalFileTime() failed with Error %ld\n",GetLastError()); 427 FileTimeToSystemTime(&lft, &st); 428 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 429 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 430 (st.wMilliseconds == 0)), 431 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 432 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 433 st.wMilliseconds); 434 435 ok(SetEnvironmentVariableA("TZ","GMT") != 0, 436 "SetEnvironmentVariableA failed\n"); 437 ok(res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 438 ret = FileTimeToLocalFileTime(&ft, &lft); 439 ok( ret, 440 "FileTimeToLocalFileTime() failed with Error %ld\n",GetLastError()); 441 FileTimeToSystemTime(&lft, &st); 442 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 443 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 444 (st.wMilliseconds == 0)), 445 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 446 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 447 st.wMilliseconds); 448 ok(SetEnvironmentVariableA("TZ",NULL) != 0, 449 "SetEnvironmentVariableA failed\n"); 450} 451 452typedef struct { 453 int nr; /* test case number for easier lookup */ 454 TIME_ZONE_INFORMATION *ptz; /* ptr to timezone */ 455 SYSTEMTIME slt; /* system/local time to convert */ 456 WORD ehour; /* expected hour */ 457} TZLT2ST_case; 458 459static void test_TzSpecificLocalTimeToSystemTime(void) 460{ 461 TIME_ZONE_INFORMATION tzE, tzW, tzS; 462 SYSTEMTIME result; 463 int i, j, year; 464 465 if (!pTzSpecificLocalTimeToSystemTime || !pSystemTimeToTzSpecificLocalTime) 466 { 467 win_skip("TzSpecificLocalTimeToSystemTime or SystemTimeToTzSpecificLocalTime not available\n"); 468 return; 469 } 470 471 ZeroMemory( &tzE, sizeof(tzE)); 472 ZeroMemory( &tzW, sizeof(tzW)); 473 ZeroMemory( &tzS, sizeof(tzS)); 474 /* timezone Eastern hemisphere */ 475 tzE.Bias=-600; 476 tzE.StandardBias=0; 477 tzE.DaylightBias=-60; 478 tzE.StandardDate.wMonth=10; 479 tzE.StandardDate.wDayOfWeek=0; /* Sunday */ 480 tzE.StandardDate.wDay=5; /* last (Sunday) of the month */ 481 tzE.StandardDate.wHour=3; 482 tzE.DaylightDate.wMonth=3; 483 tzE.DaylightDate.wDay=5; 484 tzE.DaylightDate.wHour=2; 485 /* timezone Western hemisphere */ 486 tzW.Bias=240; 487 tzW.StandardBias=0; 488 tzW.DaylightBias=-60; 489 tzW.StandardDate.wMonth=10; 490 tzW.StandardDate.wDayOfWeek=0; /* Sunday */ 491 tzW.StandardDate.wDay=4; /* 4th (Sunday) of the month */ 492 tzW.StandardDate.wHour=2; 493 tzW.DaylightDate.wMonth=4; 494 tzW.DaylightDate.wDay=1; 495 tzW.DaylightDate.wHour=2; 496 /* timezone Southern hemisphere */ 497 tzS.Bias=240; 498 tzS.StandardBias=0; 499 tzS.DaylightBias=-60; 500 tzS.StandardDate.wMonth=4; 501 tzS.StandardDate.wDayOfWeek=0; /*Sunday */ 502 tzS.StandardDate.wDay=1; /* 1st (Sunday) of the month */ 503 tzS.StandardDate.wHour=2; 504 tzS.DaylightDate.wMonth=10; 505 tzS.DaylightDate.wDay=4; 506 tzS.DaylightDate.wHour=2; 507 /*tests*/ 508 /* TzSpecificLocalTimeToSystemTime */ 509 { TZLT2ST_case cases[] = { 510 /* standard->daylight transition */ 511 { 1, &tzE, {2004,3,-1,28,1,0,0,0}, 15 }, 512 { 2, &tzE, {2004,3,-1,28,1,59,59,999}, 15}, 513 { 3, &tzE, {2004,3,-1,28,2,0,0,0}, 15}, 514 /* daylight->standard transition */ 515 { 4, &tzE, {2004,10,-1,31,2,0,0,0} , 15 }, 516 { 5, &tzE, {2004,10,-1,31,2,59,59,999}, 15 }, 517 { 6, &tzE, {2004,10,-1,31,3,0,0,0}, 17 }, 518 /* West and with fixed weekday of the month */ 519 { 7, &tzW, {2004,4,-1,4,1,0,0,0}, 5}, 520 { 8, &tzW, {2004,4,-1,4,1,59,59,999}, 5}, 521 { 9, &tzW, {2004,4,-1,4,2,0,0,0}, 5}, 522 { 10, &tzW, {2004,10,-1,24,1,0,0,0}, 4}, 523 { 11, &tzW, {2004,10,-1,24,1,59,59,999}, 4}, 524 { 12, &tzW, {2004,10,-1,24,2,0,0,0 }, 6}, 525 /* and now South */ 526 { 13, &tzS, {2004,4,-1,4,1,0,0,0}, 4}, 527 { 14, &tzS, {2004,4,-1,4,1,59,59,999}, 4}, 528 { 15, &tzS, {2004,4,-1,4,2,0,0,0}, 6}, 529 { 16, &tzS, {2004,10,-1,24,1,0,0,0}, 5}, 530 { 17, &tzS, {2004,10,-1,24,1,59,59,999}, 5}, 531 { 18, &tzS, {2004,10,-1,24,2,0,0,0}, 5}, 532 {0} 533 }; 534 /* days of transitions to put into the cases array */ 535 int yeardays[][6]= 536 { 537 {28,31,4,24,4,24} /* 1999 */ 538 , {26,29,2,22,2,22} /* 2000 */ 539 , {25,28,1,28,1,28} /* 2001 */ 540 , {31,27,7,27,7,27} /* 2002 */ 541 , {30,26,6,26,6,26} /* 2003 */ 542 , {28,31,4,24,4,24} /* 2004 */ 543 , {27,30,3,23,3,23} /* 2005 */ 544 , {26,29,2,22,2,22} /* 2006 */ 545 , {25,28,1,28,1,28} /* 2007 */ 546 , {30,26,6,26,6,26} /* 2008 */ 547 , {29,25,5,25,5,25} /* 2009 */ 548 , {28,31,4,24,4,24} /* 2010 */ 549 , {27,30,3,23,3,23} /* 2011 */ 550 , {25,28,1,28,1,28} /* 2012 */ 551 , {31,27,7,27,7,27} /* 2013 */ 552 , {30,26,6,26,6,26} /* 2014 */ 553 , {29,25,5,25,5,25} /* 2015 */ 554 , {27,30,3,23,3,23} /* 2016 */ 555 , {26,29,2,22,2,22} /* 2017 */ 556 , {25,28,1,28,1,28} /* 2018 */ 557 , {31,27,7,27,7,27} /* 2019 */ 558 ,{0} 559 }; 560 for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) { 561 for (i=0; cases[i].nr; i++) { 562 if(i) cases[i].nr += 18; 563 cases[i].slt.wYear = year; 564 cases[i].slt.wDay = yeardays[j][i/3]; 565 pTzSpecificLocalTimeToSystemTime( cases[i].ptz, &(cases[i].slt), &result); 566 ok( result.wHour == cases[i].ehour, 567 "Test TzSpecificLocalTimeToSystemTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n", 568 cases[i].nr, result.wYear, result.wMonth, result.wDay, 569 result.wHour, result.wMinute, cases[i].ehour); 570 } 571 } 572 } 573 /* SystemTimeToTzSpecificLocalTime */ 574 { TZLT2ST_case cases[] = { 575 /* standard->daylight transition */ 576 { 1, &tzE, {2004,3,-1,27,15,0,0,0}, 1 }, 577 { 2, &tzE, {2004,3,-1,27,15,59,59,999}, 1}, 578 { 3, &tzE, {2004,3,-1,27,16,0,0,0}, 3}, 579 /* daylight->standard transition */ 580 { 4, &tzE, {2004,10,-1,30,15,0,0,0}, 2 }, 581 { 5, &tzE, {2004,10,-1,30,15,59,59,999}, 2 }, 582 { 6, &tzE, {2004,10,-1,30,16,0,0,0}, 2 }, 583 /* West and with fixed weekday of the month */ 584 { 7, &tzW, {2004,4,-1,4,5,0,0,0}, 1}, 585 { 8, &tzW, {2004,4,-1,4,5,59,59,999}, 1}, 586 { 9, &tzW, {2004,4,-1,4,6,0,0,0}, 3}, 587 { 10, &tzW, {2004,10,-1,24,4,0,0,0}, 1}, 588 { 11, &tzW, {2004,10,-1,24,4,59,59,999}, 1}, 589 { 12, &tzW, {2004,10,-1,24,5,0,0,0 }, 1}, 590 /* and now South */ 591 { 13, &tzS, {2004,4,-1,4,4,0,0,0}, 1}, 592 { 14, &tzS, {2004,4,-1,4,4,59,59,999}, 1}, 593 { 15, &tzS, {2004,4,-1,4,5,0,0,0}, 1}, 594 { 16, &tzS, {2004,10,-1,24,5,0,0,0}, 1}, 595 { 17, &tzS, {2004,10,-1,24,5,59,59,999}, 1}, 596 { 18, &tzS, {2004,10,-1,24,6,0,0,0}, 3}, 597 598 {0} 599 }; 600 /* days of transitions to put into the cases array */ 601 int yeardays[][6]= 602 { 603 {27,30,4,24,4,24} /* 1999 */ 604 , {25,28,2,22,2,22} /* 2000 */ 605 , {24,27,1,28,1,28} /* 2001 */ 606 , {30,26,7,27,7,27} /* 2002 */ 607 , {29,25,6,26,6,26} /* 2003 */ 608 , {27,30,4,24,4,24} /* 2004 */ 609 , {26,29,3,23,3,23} /* 2005 */ 610 , {25,28,2,22,2,22} /* 2006 */ 611 , {24,27,1,28,1,28} /* 2007 */ 612 , {29,25,6,26,6,26} /* 2008 */ 613 , {28,24,5,25,5,25} /* 2009 */ 614 , {27,30,4,24,4,24} /* 2010 */ 615 , {26,29,3,23,3,23} /* 2011 */ 616 , {24,27,1,28,1,28} /* 2012 */ 617 , {30,26,7,27,7,27} /* 2013 */ 618 , {29,25,6,26,6,26} /* 2014 */ 619 , {28,24,5,25,5,25} /* 2015 */ 620 , {26,29,3,23,3,23} /* 2016 */ 621 , {25,28,2,22,2,22} /* 2017 */ 622 , {24,27,1,28,1,28} /* 2018 */ 623 , {30,26,7,27,7,27} /* 2019 */ 624 , {0} 625 }; 626 for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) { 627 for (i=0; cases[i].nr; i++) { 628 if(i) cases[i].nr += 18; 629 cases[i].slt.wYear = year; 630 cases[i].slt.wDay = yeardays[j][i/3]; 631 pSystemTimeToTzSpecificLocalTime( cases[i].ptz, &(cases[i].slt), &result); 632 ok( result.wHour == cases[i].ehour, 633 "Test SystemTimeToTzSpecificLocalTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n", 634 cases[i].nr, result.wYear, result.wMonth, result.wDay, 635 result.wHour, result.wMinute, cases[i].ehour); 636 } 637 } 638 639 } 640} 641 642static void test_FileTimeToDosDateTime(void) 643{ 644 FILETIME ft = { 0 }; 645 WORD fatdate, fattime; 646 BOOL ret; 647 648 if (0) 649 { 650 /* Crashes */ 651 FileTimeToDosDateTime(NULL, NULL, NULL); 652 } 653 /* Parameter checking */ 654 SetLastError(0xdeadbeef); 655 ret = FileTimeToDosDateTime(&ft, NULL, NULL); 656 ok(!ret, "expected failure\n"); 657 ok(GetLastError() == ERROR_INVALID_PARAMETER, 658 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 659 660 SetLastError(0xdeadbeef); 661 ret = FileTimeToDosDateTime(&ft, &fatdate, NULL); 662 ok(!ret, "expected failure\n"); 663 ok(GetLastError() == ERROR_INVALID_PARAMETER, 664 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 665 666 SetLastError(0xdeadbeef); 667 ret = FileTimeToDosDateTime(&ft, NULL, &fattime); 668 ok(!ret, "expected failure\n"); 669 ok(GetLastError() == ERROR_INVALID_PARAMETER, 670 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 671 672 SetLastError(0xdeadbeef); 673 ret = FileTimeToDosDateTime(&ft, &fatdate, &fattime); 674 ok(!ret, "expected failure\n"); 675 ok(GetLastError() == ERROR_INVALID_PARAMETER, 676 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 677} 678 679static void test_GetCalendarInfo(void) 680{ 681 char bufferA[20]; 682 WCHAR bufferW[20]; 683 DWORD val1, val2; 684 int i, j, ret, ret2; 685 686 if (!pGetCalendarInfoA || !pGetCalendarInfoW) 687 { 688 trace( "GetCalendarInfo missing\n" ); 689 return; 690 } 691 692 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 693 NULL, 0, &val1 ); 694 ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() ); 695 ok( ret == sizeof(val1), "wrong size %u\n", ret ); 696 ok( val1 >= 2000 && val1 < 2100, "wrong value %lu\n", val1 ); 697 698 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 699 NULL, 0, &val2 ); 700 ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() ); 701 ok( ret == sizeof(val2)/sizeof(WCHAR), "wrong size %u\n", ret ); 702 ok( val1 == val2, "A/W mismatch %lu/%lu\n", val1, val2 ); 703 704 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferA, sizeof(bufferA), NULL ); 705 ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() ); 706 ok( ret == 5, "wrong size %u\n", ret ); 707 ok( atoi( bufferA ) == val1, "wrong value %s/%lu\n", bufferA, val1 ); 708 709 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, ARRAY_SIZE(bufferW), NULL ); 710 ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() ); 711 ok( ret == 5, "wrong size %u\n", ret ); 712 memset( bufferA, 0x55, sizeof(bufferA) ); 713 WideCharToMultiByte( CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL ); 714 ok( atoi( bufferA ) == val1, "wrong value %s/%lu\n", bufferA, val1 ); 715 716 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 717 NULL, 0, NULL ); 718 ok( !ret, "GetCalendarInfoA succeeded\n" ); 719 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 720 721 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL ); 722 ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() ); 723 ok( ret == 5, "wrong size %u\n", ret ); 724 725 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 726 NULL, 0, NULL ); 727 ok( !ret, "GetCalendarInfoW succeeded\n" ); 728 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 729 730 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL ); 731 ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() ); 732 ok( ret == 5, "wrong size %u\n", ret ); 733 734 ret = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 735 bufferA, sizeof(bufferA), NULL); 736 ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() ); 737 ret2 = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 738 bufferA, 0, NULL); 739 ok( ret2, "GetCalendarInfoA failed err %lu\n", GetLastError() ); 740 ok( ret == ret2, "got %d, expected %d\n", ret2, ret ); 741 742 ret2 = pGetCalendarInfoW( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 743 bufferW, ARRAY_SIZE(bufferW), NULL); 744 ok( ret2, "GetCalendarInfoW failed err %lu\n", GetLastError() ); 745 ret2 = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); 746 ok( ret == ret2, "got %d, expected %d\n", ret, ret2 ); 747 748#ifdef __REACTOS__ 749 if (GetNTVersion() >= _WIN32_WINNT_VISTA) { 750#endif 751 for (i = CAL_GREGORIAN; i <= CAL_UMALQURA; i++) 752 { 753 WCHAR name[80]; 754 ret = pGetCalendarInfoW( 0x0409, i, CAL_SCALNAME, name, ARRAY_SIZE(name), NULL); 755 for (j = CAL_ICALINTVALUE; j <= CAL_SRELATIVELONGDATE; j++) 756 { 757 ret2 = pGetCalendarInfoW( 0x0409, i, j, bufferW, ARRAY_SIZE(bufferW), NULL); 758 if (ret || j == CAL_ITWODIGITYEARMAX) 759#ifdef __REACTOS__ 760 ok( ret2 || broken(j == CAL_SRELATIVELONGDATE) /* Win7 */ || broken(j == CAL_SMONTHDAY || j == CAL_SABBREVERASTRING), /* Vista */ 761#else 762 ok( ret2 || broken(j == CAL_SRELATIVELONGDATE), /* win7 doesn't have this */ 763#endif 764 "calendar %u %s value %02x failed\n", i, wine_dbgstr_w(name), j ); 765 else 766 ok( !ret2, "calendar %u %s value %02x succeeded %s\n", 767 i, wine_dbgstr_w(name), j, wine_dbgstr_w(bufferW) ); 768 } 769 } 770#ifdef __REACTOS__ 771 } 772#endif 773} 774 775static void test_GetDynamicTimeZoneInformation(void) 776{ 777 DYNAMIC_TIME_ZONE_INFORMATION dyninfo; 778 TIME_ZONE_INFORMATION tzinfo; 779 DWORD ret, ret2; 780 781#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 782 /* FIXME: GetDynamicTimeZoneInformation is a STUB on ReactOS */ 783 if (is_reactos() || !pGetDynamicTimeZoneInformation) 784#else 785 if (!pGetDynamicTimeZoneInformation) 786#endif 787 { 788 win_skip("GetDynamicTimeZoneInformation() is not supported.\n"); 789 return; 790 } 791 792 ret = pGetDynamicTimeZoneInformation(&dyninfo); 793 ret2 = GetTimeZoneInformation(&tzinfo); 794 ok(ret == ret2, "got %ld, %ld\n", ret, ret2); 795 796 ok(dyninfo.Bias == tzinfo.Bias, "got %ld, %ld\n", dyninfo.Bias, tzinfo.Bias); 797 ok(!lstrcmpW(dyninfo.StandardName, tzinfo.StandardName), "got std name %s, %s\n", 798 wine_dbgstr_w(dyninfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 799 ok(!memcmp(&dyninfo.StandardDate, &tzinfo.StandardDate, sizeof(dyninfo.StandardDate)), "got different StandardDate\n"); 800 ok(dyninfo.StandardBias == tzinfo.StandardBias, "got %ld, %ld\n", dyninfo.StandardBias, tzinfo.StandardBias); 801 ok(!lstrcmpW(dyninfo.DaylightName, tzinfo.DaylightName), "got daylight name %s, %s\n", 802 wine_dbgstr_w(dyninfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 803 ok(!memcmp(&dyninfo.DaylightDate, &tzinfo.DaylightDate, sizeof(dyninfo.DaylightDate)), "got different DaylightDate\n"); 804 ok(dyninfo.TimeZoneKeyName[0] != 0, "got empty tz keyname\n"); 805 trace("Dyn TimeZoneKeyName %s\n", wine_dbgstr_w(dyninfo.TimeZoneKeyName)); 806} 807 808static ULONGLONG get_longlong_time(FILETIME *time) 809{ 810 ULARGE_INTEGER uli; 811 uli.u.LowPart = time->dwLowDateTime; 812 uli.u.HighPart = time->dwHighDateTime; 813 return uli.QuadPart; 814} 815 816static void test_GetSystemTimeAsFileTime(void) 817{ 818 LARGE_INTEGER t1, t2, t3; 819 FILETIME ft; 820 821 NtQuerySystemTime( &t1 ); 822 GetSystemTimeAsFileTime( &ft ); 823 NtQuerySystemTime( &t3 ); 824 t2.QuadPart = get_longlong_time( &ft ); 825 826 ok(t1.QuadPart <= t2.QuadPart, "out of order %s %s\n", wine_dbgstr_longlong(t1.QuadPart), wine_dbgstr_longlong(t2.QuadPart)); 827 ok(t2.QuadPart <= t3.QuadPart, "out of order %s %s\n", wine_dbgstr_longlong(t2.QuadPart), wine_dbgstr_longlong(t3.QuadPart)); 828} 829 830static void test_GetSystemTimePreciseAsFileTime(void) 831{ 832 FILETIME ft; 833 ULONGLONG time1, time2; 834 LONGLONG diff; 835 836 if (!pGetSystemTimePreciseAsFileTime) 837 { 838 win_skip("GetSystemTimePreciseAsFileTime() is not supported.\n"); 839 return; 840 } 841 842 GetSystemTimeAsFileTime(&ft); 843 time1 = get_longlong_time(&ft); 844 pGetSystemTimePreciseAsFileTime(&ft); 845 time2 = get_longlong_time(&ft); 846 diff = time2 - time1; 847 if (diff < 0) 848 diff = -diff; 849 ok(diff < 1000000, "Difference between GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime more than 100 ms\n"); 850 851 pGetSystemTimePreciseAsFileTime(&ft); 852 time1 = get_longlong_time(&ft); 853 do { 854 pGetSystemTimePreciseAsFileTime(&ft); 855 time2 = get_longlong_time(&ft); 856 } while (time2 == time1); 857 diff = time2 - time1; 858 ok(diff < 10000 && diff > 0, "GetSystemTimePreciseAsFileTime incremented by more than 1 ms\n"); 859} 860 861static void test_GetSystemTimes(void) 862{ 863 864 FILETIME idletime, kerneltime, usertime; 865 int i; 866 ULARGE_INTEGER ul1, ul2, ul3; 867 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi; 868 SYSTEM_BASIC_INFORMATION sbi; 869 ULONG ReturnLength; 870 ULARGE_INTEGER total_usertime, total_kerneltime, total_idletime; 871 872 if (!pGetSystemTimes) 873 { 874 win_skip("GetSystemTimes not available\n"); 875 return; 876 } 877 878 ok( pGetSystemTimes(NULL, NULL, NULL), "GetSystemTimes failed unexpectedly\n" ); 879 880 total_usertime.QuadPart = 0; 881 total_kerneltime.QuadPart = 0; 882 total_idletime.QuadPart = 0; 883 memset( &idletime, 0x11, sizeof(idletime) ); 884 memset( &kerneltime, 0x11, sizeof(kerneltime) ); 885 memset( &usertime, 0x11, sizeof(usertime) ); 886 ok( pGetSystemTimes(&idletime, &kerneltime , &usertime), 887 "GetSystemTimes failed unexpectedly\n" ); 888 889 ul1.LowPart = idletime.dwLowDateTime; 890 ul1.HighPart = idletime.dwHighDateTime; 891 ul2.LowPart = kerneltime.dwLowDateTime; 892 ul2.HighPart = kerneltime.dwHighDateTime; 893 ul3.LowPart = usertime.dwLowDateTime; 894 ul3.HighPart = usertime.dwHighDateTime; 895 896 ok( !NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength), 897 "NtQuerySystemInformation failed\n" ); 898 ok( sizeof(sbi) == ReturnLength, "Inconsistent length %ld\n", ReturnLength ); 899 900 /* Check if we have some return values */ 901 trace( "Number of Processors : %d\n", sbi.NumberOfProcessors ); 902 ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", 903 sbi.NumberOfProcessors ); 904 905 sppi = HeapAlloc( GetProcessHeap(), 0, 906 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * sbi.NumberOfProcessors); 907 908 ok( !NtQuerySystemInformation( SystemProcessorPerformanceInformation, sppi, 909 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * sbi.NumberOfProcessors, 910 &ReturnLength), 911 "NtQuerySystemInformation failed\n" ); 912 913 for (i = 0; i < sbi.NumberOfProcessors; i++) 914 { 915 total_usertime.QuadPart += sppi[i].UserTime.QuadPart; 916 total_kerneltime.QuadPart += sppi[i].KernelTime.QuadPart; 917 total_idletime.QuadPart += sppi[i].IdleTime.QuadPart; 918 } 919 920 ok( total_idletime.QuadPart - ul1.QuadPart < 10000000, "test idletime failed\n" ); 921 ok( total_kerneltime.QuadPart - ul2.QuadPart < 10000000, "test kerneltime failed\n" ); 922 ok( total_usertime.QuadPart - ul3.QuadPart < 10000000, "test usertime failed\n" ); 923 924 HeapFree(GetProcessHeap(), 0, sppi); 925} 926 927static WORD day_of_month(const SYSTEMTIME* systemtime, WORD year) 928{ 929 SYSTEMTIME first_of_month = {0}; 930 FILETIME filetime; 931 WORD result; 932 933 if (systemtime->wYear != 0) 934 return systemtime->wDay; 935 936 if (systemtime->wMonth == 0) 937 return 0; 938 939 first_of_month.wYear = year; 940 first_of_month.wMonth = systemtime->wMonth; 941 first_of_month.wDay = 1; 942 943 /* round-trip conversion sets day of week field */ 944 SystemTimeToFileTime(&first_of_month, &filetime); 945 FileTimeToSystemTime(&filetime, &first_of_month); 946 947 result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + 948 (7 * (systemtime->wDay - 1)); 949 950 if (systemtime->wDay == 5) 951 { 952 /* make sure this isn't in the next month */ 953 SYSTEMTIME result_date; 954 955 result_date = first_of_month; 956 result_date.wDay = result; 957 958 SystemTimeToFileTime(&result_date, &filetime); 959 FileTimeToSystemTime(&filetime, &result_date); 960 961 if (result_date.wDay != result) 962 result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + 963 (7 * (4 - 1)); 964 } 965 966 return result; 967} 968 969static void test_GetTimeZoneInformationForYear(void) 970{ 971 BOOL ret, broken_test = FALSE; 972 SYSTEMTIME systemtime; 973 TIME_ZONE_INFORMATION local_tzinfo, tzinfo, tzinfo2; 974 DYNAMIC_TIME_ZONE_INFORMATION dyn_tzinfo; 975 WORD std_day, dlt_day; 976 unsigned i; 977 static const struct 978 { 979 const WCHAR *tzname; 980 USHORT year; 981 LONG bias, std_bias, dlt_bias; 982 WORD std_month, std_day, dlt_month, dlt_day; 983 } 984 test_data[] = 985 { 986 { L"Greenland Standard Time", 2015, 180, 0, -60, 10, 24, 3, 28 }, 987 { L"Greenland Standard Time", 2016, 180, 0, -60, 10, 29, 3, 26 }, 988 { L"Greenland Standard Time", 2017, 180, 0, -60, 10, 28, 3, 25 }, 989 { L"Easter Island Standard Time", 2014, 360, 0, -60, 4, 26, 9, 6 }, 990 { L"Easter Island Standard Time", 2015, 300, 0, -60, 0, 0, 0, 0 }, 991 { L"Easter Island Standard Time", 2016, 360, 0, -60, 5, 14, 8, 13 }, 992 { L"Egypt Standard Time", 2013, -120, 0, -60, 0, 0, 0, 0 }, 993 { L"Egypt Standard Time", 2014, -120, 0, -60, 9, 25, 5, 15 }, 994 { L"Egypt Standard Time", 2015, -120, 0, -60, 0, 0, 0, 0 }, 995 { L"Egypt Standard Time", 2016, -120, 0, -60, 0, 0, 0, 0 }, 996 { L"Altai Standard Time", 2016, -420, 0, 60, 3, 27, 1, 1 }, 997 { L"Altai Standard Time", 2017, -420, 0, -60, 0, 0, 0, 0 }, 998 { L"Altai Standard Time", 2018, -420, 0, -60, 0, 0, 0, 0 }, 999 }; 1000 1001#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 1002 /* FIXME: GetTimeZoneInformationForYear and GetDynamicTimeZoneInformation are STUBS on ReactOS */ 1003 if (is_reactos() || !pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation) 1004#else 1005 if (!pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation) 1006#endif 1007 { 1008 win_skip("GetTimeZoneInformationForYear not available\n"); 1009 return; 1010 } 1011 1012 GetLocalTime(&systemtime); 1013 1014 GetTimeZoneInformation(&local_tzinfo); 1015 1016 ret = pGetTimeZoneInformationForYear(systemtime.wYear, NULL, &tzinfo); 1017 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu\n", GetLastError()); 1018 ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %ld, got %ld\n", local_tzinfo.Bias, tzinfo.Bias); 1019 ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), 1020 "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 1021 ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); 1022 ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %ld, got %ld\n", local_tzinfo.StandardBias, tzinfo.StandardBias); 1023 ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), 1024 "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 1025 ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); 1026 ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %ld, got %ld\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); 1027 1028 pGetDynamicTimeZoneInformation(&dyn_tzinfo); 1029 1030 ret = pGetTimeZoneInformationForYear(systemtime.wYear, &dyn_tzinfo, &tzinfo); 1031 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu\n", GetLastError()); 1032 ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %ld, got %ld\n", local_tzinfo.Bias, tzinfo.Bias); 1033 ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), 1034 "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 1035 ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); 1036 ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %ld, got %ld\n", local_tzinfo.StandardBias, tzinfo.StandardBias); 1037 ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), 1038 "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 1039 ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); 1040 ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %ld, got %ld\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); 1041 1042 memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); 1043 lstrcpyW(dyn_tzinfo.TimeZoneKeyName, L"Greenland Daylight Time"); 1044 SetLastError(0xdeadbeef); 1045 ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); 1046 if (ret) 1047 broken_test = TRUE; 1048 ok((ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND) || 1049 broken(broken_test) /* vista,7 */, 1050 "GetTimeZoneInformationForYear err %lu\n", GetLastError()); 1051 1052 memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); 1053 lstrcpyW(dyn_tzinfo.TimeZoneKeyName, L"Altai Standard Time"); 1054 SetLastError(0xdeadbeef); 1055 ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); 1056 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 1057 broken_test = TRUE; 1058 ok(ret == TRUE || broken(broken_test) /* before 10 1809 */, 1059 "GetTimeZoneInformationForYear err %lu\n", GetLastError()); 1060 1061 if (broken(broken_test)) 1062 { 1063 win_skip("Old Windows version\n"); 1064 return; 1065 } 1066 1067 for (i = 0; i < ARRAY_SIZE(test_data); i++) 1068 { 1069 memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); 1070 memset(&tzinfo, 0xbb, sizeof(tzinfo)); 1071 lstrcpyW(dyn_tzinfo.TimeZoneKeyName, test_data[i].tzname); 1072 dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE; 1073 1074 ret = pGetTimeZoneInformationForYear(test_data[i].year, &dyn_tzinfo, &tzinfo); 1075 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu, for %s\n", GetLastError(), wine_dbgstr_w(test_data[i].tzname)); 1076 if (!ret) 1077 continue; 1078 ok(tzinfo.Bias == test_data[i].bias, "Expected bias %ld, got %ld, for %s\n", 1079 test_data[i].bias, tzinfo.Bias, wine_dbgstr_w(test_data[i].tzname)); 1080 ok(tzinfo.StandardDate.wMonth == test_data[i].std_month, "Expected standard month %d, got %d, for %s\n", 1081 test_data[i].std_month, tzinfo.StandardDate.wMonth, wine_dbgstr_w(test_data[i].tzname)); 1082 std_day = day_of_month(&tzinfo.StandardDate, test_data[i].year); 1083 ok(std_day == test_data[i].std_day, "Expected standard day %d, got %d, for %s\n", 1084 test_data[i].std_day, std_day, wine_dbgstr_w(test_data[i].tzname)); 1085 ok(tzinfo.StandardBias == test_data[i].std_bias, "Expected standard bias %ld, got %ld, for %s\n", 1086 test_data[i].std_bias, tzinfo.StandardBias, wine_dbgstr_w(test_data[i].tzname)); 1087 ok(tzinfo.DaylightDate.wMonth == test_data[i].dlt_month, "Expected daylight month %d, got %d, for %s\n", 1088 test_data[i].dlt_month, tzinfo.DaylightDate.wMonth, wine_dbgstr_w(test_data[i].tzname)); 1089 dlt_day = day_of_month(&tzinfo.DaylightDate, test_data[i].year); 1090 ok(dlt_day == test_data[i].dlt_day, "Expected daylight day %d, got %d, for %s\n", 1091 test_data[i].dlt_day, dlt_day, wine_dbgstr_w(test_data[i].tzname)); 1092 ok(tzinfo.DaylightBias == test_data[i].dlt_bias, "Expected daylight bias %ld, got %ld, for %s\n", 1093 test_data[i].dlt_bias, tzinfo.DaylightBias, wine_dbgstr_w(test_data[i].tzname)); 1094 1095 if (i > 0 && test_data[i-1].tzname == test_data[i].tzname) 1096 { 1097 ok(!lstrcmpW(tzinfo.StandardName, tzinfo2.StandardName), 1098 "Got differing StandardName values %s and %s\n", 1099 wine_dbgstr_w(tzinfo.StandardName), wine_dbgstr_w(tzinfo2.StandardName)); 1100 ok(!lstrcmpW(tzinfo.DaylightName, tzinfo2.DaylightName), 1101 "Got differing DaylightName values %s and %s\n", 1102 wine_dbgstr_w(tzinfo.DaylightName), wine_dbgstr_w(tzinfo2.DaylightName)); 1103 } 1104 1105 memcpy(&tzinfo2, &tzinfo, sizeof(tzinfo2)); 1106 } 1107} 1108 1109static void test_GetTickCount(void) 1110{ 1111 DWORD t1, t2, t3; 1112 int i = 0; 1113 1114 if (!pNtGetTickCount) 1115 { 1116 win_skip("NtGetTickCount not implemented\n"); 1117 return; 1118 } 1119 1120 do 1121 { 1122 t1 = pNtGetTickCount(); 1123 t2 = GetTickCount(); 1124 t3 = pNtGetTickCount(); 1125 } while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */ 1126 1127 ok(t1 <= t2, "out of order %ld %ld\n", t1, t2); 1128 ok(t2 <= t3, "out of order %ld %ld\n", t2, t3); 1129} 1130 1131BOOL (WINAPI *pQueryUnbiasedInterruptTime)(ULONGLONG *time); 1132BOOL (WINAPI *pRtlQueryUnbiasedInterruptTime)(ULONGLONG *time); 1133 1134static void test_QueryUnbiasedInterruptTime(void) 1135{ 1136 ULONGLONG time; 1137 BOOL ret; 1138 1139 if (pQueryUnbiasedInterruptTime) 1140 { 1141 SetLastError( 0xdeadbeef ); 1142 ret = pQueryUnbiasedInterruptTime( &time ); 1143 ok( ret, "QueryUnbiasedInterruptTime failed err %lu\n", GetLastError() ); 1144 SetLastError( 0xdeadbeef ); 1145 ret = pQueryUnbiasedInterruptTime( NULL ); 1146 ok( !ret, "QueryUnbiasedInterruptTime succeeded\n" ); 1147 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1148 } 1149 else win_skip( "QueryUnbiasedInterruptTime not supported\n" ); 1150 if (pRtlQueryUnbiasedInterruptTime) 1151 { 1152 SetLastError( 0xdeadbeef ); 1153 ret = pRtlQueryUnbiasedInterruptTime( &time ); 1154 ok( ret, "RtlQueryUnbiasedInterruptTime failed err %lu\n", GetLastError() ); 1155 SetLastError( 0xdeadbeef ); 1156 ret = pRtlQueryUnbiasedInterruptTime( NULL ); 1157 ok( !ret, "RtlQueryUnbiasedInterruptTime succeeded\n" ); 1158 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() ); 1159 } 1160 else win_skip( "RtlQueryUnbiasedInterruptTime not supported\n" ); 1161} 1162 1163static void test_processor_idle_cycle_time(void) 1164{ 1165#ifdef __REACTOS__ 1166 skip("Cannot build test_processor_idle_cycle_time() until kernelbase is synced.\n"); 1167#else 1168 unsigned int cpu_count = NtCurrentTeb()->Peb->NumberOfProcessors; 1169 ULONG64 buffer[64]; 1170 ULONG size; 1171 DWORD err; 1172 BOOL bret; 1173 1174 SetLastError( 0xdeadbeef ); 1175 size = 0; 1176 bret = QueryIdleProcessorCycleTime( &size, NULL ); 1177 err = GetLastError(); 1178 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1179 ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); 1180 1181 size = 4; 1182 memset( buffer, 0xcc, sizeof(buffer) ); 1183 SetLastError( 0xdeadbeef ); 1184 bret = QueryIdleProcessorCycleTime( &size, NULL ); 1185 err = GetLastError(); 1186 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1187 ok( size == 4, "got %lu.\n", size ); 1188 ok( buffer[0] == 0xcccccccccccccccc, "got %#I64x.\n", buffer[0] ); 1189 1190 size = sizeof(buffer); 1191 SetLastError( 0xdeadbeef ); 1192 bret = QueryIdleProcessorCycleTime( &size, NULL ); 1193 err = GetLastError(); 1194 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1195 ok( size == sizeof(buffer), "got %lu.\n", size ); 1196 1197 size = sizeof(buffer); 1198 SetLastError( 0xdeadbeef ); 1199 bret = QueryIdleProcessorCycleTime( &size, buffer ); 1200 err = GetLastError(); 1201 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1202 ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); 1203 1204 SetLastError( 0xdeadbeef ); 1205 size = 0; 1206 bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); 1207 err = GetLastError(); 1208 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1209 ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); 1210 1211 size = 4; 1212 SetLastError( 0xdeadbeef ); 1213 bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); 1214 err = GetLastError(); 1215 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1216 ok( size == 4, "got %lu.\n", size ); 1217 1218 size = sizeof(buffer); 1219 SetLastError( 0xdeadbeef ); 1220 bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL ); 1221 err = GetLastError(); 1222 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1223 ok( size == sizeof(buffer), "got %lu.\n", size ); 1224 1225 size = sizeof(buffer); 1226 SetLastError( 0xdeadbeef ); 1227 bret = QueryIdleProcessorCycleTimeEx( 0, &size, buffer ); 1228 err = GetLastError(); 1229 ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err ); 1230 ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size ); 1231#endif 1232} 1233 1234START_TEST(time) 1235{ 1236 HMODULE hKernel = GetModuleHandleA("kernel32"); 1237 HMODULE hntdll = GetModuleHandleA("ntdll"); 1238 pTzSpecificLocalTimeToSystemTime = (void *)GetProcAddress(hKernel, "TzSpecificLocalTimeToSystemTime"); 1239 pSystemTimeToTzSpecificLocalTime = (void *)GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime"); 1240 pGetSystemTimes = (void *)GetProcAddress( hKernel, "GetSystemTimes"); 1241 pGetCalendarInfoA = (void *)GetProcAddress(hKernel, "GetCalendarInfoA"); 1242 pGetCalendarInfoW = (void *)GetProcAddress(hKernel, "GetCalendarInfoW"); 1243 pGetDynamicTimeZoneInformation = (void *)GetProcAddress(hKernel, "GetDynamicTimeZoneInformation"); 1244 pGetSystemTimePreciseAsFileTime = (void *)GetProcAddress(hKernel, "GetSystemTimePreciseAsFileTime"); 1245 pGetTimeZoneInformationForYear = (void *)GetProcAddress(hKernel, "GetTimeZoneInformationForYear"); 1246 pQueryUnbiasedInterruptTime = (void *)GetProcAddress(hKernel, "QueryUnbiasedInterruptTime"); 1247 pNtGetTickCount = (void *)GetProcAddress(hntdll, "NtGetTickCount"); 1248 pRtlQueryUnbiasedInterruptTime = (void *)GetProcAddress(hntdll, "RtlQueryUnbiasedInterruptTime"); 1249 1250 test_conversions(); 1251 test_invalid_arg(); 1252 test_GetTimeZoneInformation(); 1253 test_FileTimeToSystemTime(); 1254 test_FileTimeToLocalFileTime(); 1255 test_TzSpecificLocalTimeToSystemTime(); 1256 test_GetSystemTimes(); 1257 test_FileTimeToDosDateTime(); 1258 test_GetCalendarInfo(); 1259 test_GetDynamicTimeZoneInformation(); 1260 test_GetSystemTimeAsFileTime(); 1261 test_GetSystemTimePreciseAsFileTime(); 1262 test_GetTimeZoneInformationForYear(); 1263 test_GetTickCount(); 1264 test_QueryUnbiasedInterruptTime(); 1265 test_processor_idle_cycle_time(); 1266}