Reactos
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}