Reactos
at master 188 lines 5.0 kB view raw
1// 2// timeset.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// The time zone values for the default time zone, and other global time data. 7// 8#include <corecrt_internal_time.h> 9 10#undef _daylight 11#undef _dstbias 12#undef _timezone 13#undef _tzname 14 15 16 17__crt_state_management::dual_state_global<long> _timezone; // Pacific Time Zone 18__crt_state_management::dual_state_global<int> _daylight; // Daylight Saving Time (DST) in timezone 19__crt_state_management::dual_state_global<long> _dstbias; // DST offset in seconds 20 21// Note that NT POSIX's TZNAME_MAX is only 10. 22 23#define _PST_STRING "PST" 24#define _PDT_STRING "PDT" 25 26#define L_PST_STRING L"PST" 27#define L_PDT_STRING L"PDT" 28 29static char tzstd_program[_TZ_STRINGS_SIZE] = { _PST_STRING }; 30static char tzdst_program[_TZ_STRINGS_SIZE] = { _PDT_STRING }; 31 32static wchar_t w_tzstd_program[_TZ_STRINGS_SIZE] = { L_PST_STRING }; 33static wchar_t w_tzdst_program[_TZ_STRINGS_SIZE] = { L_PDT_STRING }; 34 35#ifdef _CRT_GLOBAL_STATE_ISOLATION 36 static char tzstd_os[_TZ_STRINGS_SIZE] = { _PST_STRING }; 37 static char tzdst_os[_TZ_STRINGS_SIZE] = { _PDT_STRING }; 38 39 static wchar_t w_tzstd_os[_TZ_STRINGS_SIZE] = { L_PST_STRING }; 40 static wchar_t w_tzdst_os[_TZ_STRINGS_SIZE] = { L_PDT_STRING }; 41#endif 42 43static char* tzname_states[__crt_state_management::state_index_count][2] = 44{ 45 { tzstd_program, tzdst_program }, 46 #ifdef _CRT_GLOBAL_STATE_ISOLATION 47 { tzstd_os, tzdst_os } 48 #endif 49}; 50 51static wchar_t* w_tzname_states[__crt_state_management::state_index_count][2] = 52{ 53 { w_tzstd_program, w_tzdst_program }, 54 #ifdef _CRT_GLOBAL_STATE_ISOLATION 55 { w_tzstd_os, w_tzdst_os } 56 #endif 57}; 58 59static __crt_state_management::dual_state_global<char **> _tzname; 60static __crt_state_management::dual_state_global<wchar_t **> w_tzname; 61 62// Initializer for the timeset globals: 63_CRT_LINKER_FORCE_INCLUDE(__acrt_timeset_initializer); 64 65extern "C" int __cdecl __acrt_initialize_timeset() 66{ 67 _timezone.initialize(8 * 3600L); 68 _daylight.initialize(1); 69 _dstbias.initialize (-3600); 70 71 char*** const first_state = _tzname.dangerous_get_state_array(); 72 for (unsigned i = 0; i != __crt_state_management::state_index_count; ++i) 73 { 74 first_state[i] = tzname_states[i]; 75 } 76 77 wchar_t*** const w_first_state = w_tzname.dangerous_get_state_array(); 78 for (unsigned i = 0; i != __crt_state_management::state_index_count; ++i) 79 { 80 w_first_state[i] = w_tzname_states[i]; 81 } 82 83 return 0; 84} 85 86extern "C" errno_t __cdecl _get_daylight(int* const result) 87{ 88 _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL); 89 90 // This variable is correctly inited at startup, so no need to check if 91 // CRT init finished. 92 *result = _daylight.value(); 93 return 0; 94} 95 96extern "C" errno_t __cdecl _get_dstbias(long* result) 97{ 98 _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL); 99 100 // This variable is correctly inited at startup, so no need to check if 101 // CRT init finished. 102 *result = _dstbias.value(); 103 return 0; 104} 105 106extern "C" errno_t __cdecl _get_timezone(long* result) 107{ 108 _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL); 109 110 // This variable is correctly inited at startup, so no need to check if 111 // CRT init finished. 112 *result = _timezone.value(); 113 return 0; 114} 115 116extern "C" errno_t __cdecl _get_tzname( 117 size_t* const length, 118 char* const buffer, 119 size_t const size_in_bytes, 120 int const index) 121{ 122 _VALIDATE_RETURN_ERRCODE( 123 (buffer != nullptr && size_in_bytes > 0) || 124 (buffer == nullptr && size_in_bytes == 0), 125 EINVAL); 126 127 if (buffer != nullptr) 128 buffer[0] = '\0'; 129 130 _VALIDATE_RETURN_ERRCODE(length != nullptr, EINVAL); 131 _VALIDATE_RETURN_ERRCODE(index == 0 || index == 1, EINVAL); 132 133 // _tzname is correctly inited at startup, so no need to check if 134 // CRT init finished. 135 *length = strlen(_tzname.value()[index]) + 1; 136 137 // If the buffer pointer is null, the caller is interested only in the size 138 // of the string, not in the actual value of the string: 139 if (buffer == nullptr) 140 return 0; 141 142 if (*length > size_in_bytes) 143 return ERANGE; 144 145 return strcpy_s(buffer, size_in_bytes, _tzname.value()[index]); 146} 147 148 149 150// Day names must be three character abbreviations strung together 151extern "C" const char __dnames[] = 152{ 153 "SunMonTueWedThuFriSat" 154}; 155 156// Month names must be three character abbreviations strung together 157extern "C" const char __mnames[] = 158{ 159 "JanFebMarAprMayJunJulAugSepOctNovDec" 160}; 161 162 163 164// Accessors for the global time data 165extern "C" int* __cdecl __daylight() 166{ 167 return &_daylight.value(); 168} 169 170extern "C" long* __cdecl __dstbias() 171{ 172 return &_dstbias.value(); 173} 174 175extern "C" long* __cdecl __timezone() 176{ 177 return &_timezone.value(); 178} 179 180extern "C" char** __cdecl __tzname() 181{ 182 return _tzname.value(); 183} 184 185extern "C" wchar_t** __cdecl __wide_tzname() 186{ 187 return w_tzname.value(); 188}