Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: source/common/wintz.c

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/common/uvectr64.h ('k') | source/config.guess » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************** 2 ********************************************************************************
3 * Copyright (C) 2005-2013, International Business Machines 3 * Copyright (C) 2005-2014, International Business Machines
4 * Corporation and others. All Rights Reserved. 4 * Corporation and others. All Rights Reserved.
5 ******************************************************************************** 5 ********************************************************************************
6 * 6 *
7 * File WINTZ.CPP 7 * File WINTZ.CPP
8 * 8 *
9 ******************************************************************************** 9 ********************************************************************************
10 */ 10 */
11 11
12 #include "unicode/utypes.h" 12 #include "unicode/utypes.h"
13 13
14 #if U_PLATFORM_HAS_WIN32_API 14 #if U_PLATFORM_HAS_WIN32_API
15 15
16 #include "wintz.h" 16 #include "wintz.h"
17 #include "cmemory.h" 17 #include "cmemory.h"
18 #include "cstring.h" 18 #include "cstring.h"
19 19
20 #include "unicode/ures.h"
20 #include "unicode/ustring.h" 21 #include "unicode/ustring.h"
21 #include "unicode/ures.h"
22 22
23 # define WIN32_LEAN_AND_MEAN 23 # define WIN32_LEAN_AND_MEAN
24 # define VC_EXTRALEAN 24 # define VC_EXTRALEAN
25 # define NOUSER 25 # define NOUSER
26 # define NOSERVICE 26 # define NOSERVICE
27 # define NOIME 27 # define NOIME
28 # define NOMCX 28 # define NOMCX
29 #include <windows.h> 29 #include <windows.h>
30 30
31 #define MAX_LENGTH_ID 40 31 #define MAX_LENGTH_ID 40
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 (LPBYTE)regStdName, 186 (LPBYTE)regStdName,
187 &cbData); 187 &cbData);
188 188
189 } 189 }
190 190
191 RegCloseKey(hkey); 191 RegCloseKey(hkey);
192 192
193 return result; 193 return result;
194 } 194 }
195 195
196 static LONG getTZKeyName(char* tzKeyName, int32_t length) {
197 HKEY hkey;
198 LONG result = FALSE;
199 DWORD cbData = length;
200
201 if(ERROR_SUCCESS == RegOpenKeyExA(
202 HKEY_LOCAL_MACHINE,
203 CURRENT_ZONE_REGKEY,
204 0,
205 KEY_QUERY_VALUE,
206 &hkey))
207 {
208 result = RegQueryValueExA(
209 hkey,
210 "TimeZoneKeyName",
211 NULL,
212 NULL,
213 (LPBYTE)tzKeyName,
214 &cbData);
215 }
216
217 return result;
218 }
219
196 /* 220 /*
197 This code attempts to detect the Windows time zone, as set in the 221 This code attempts to detect the Windows time zone, as set in the
198 Windows Date and Time control panel. It attempts to work on 222 Windows Date and Time control panel. It attempts to work on
199 multiple flavors of Windows (9x, Me, NT, 2000, XP) and on localized 223 multiple flavors of Windows (9x, Me, NT, 2000, XP) and on localized
200 installs. It works by directly interrogating the registry and 224 installs. It works by directly interrogating the registry and
201 comparing the data there with the data returned by the 225 comparing the data there with the data returned by the
202 GetTimeZoneInformation API, along with some other strategies. The 226 GetTimeZoneInformation API, along with some other strategies. The
203 registry contains time zone data under one of two keys (depending on 227 registry contains time zone data under one of two keys (depending on
204 the flavor of Windows): 228 the flavor of Windows):
205 229
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 267
244 /** 268 /**
245 * Main Windows time zone detection function. Returns the Windows 269 * Main Windows time zone detection function. Returns the Windows
246 * time zone, translated to an ICU time zone, or NULL upon failure. 270 * time zone, translated to an ICU time zone, or NULL upon failure.
247 */ 271 */
248 U_CFUNC const char* U_EXPORT2 272 U_CFUNC const char* U_EXPORT2
249 uprv_detectWindowsTimeZone() { 273 uprv_detectWindowsTimeZone() {
250 UErrorCode status = U_ZERO_ERROR; 274 UErrorCode status = U_ZERO_ERROR;
251 UResourceBundle* bundle = NULL; 275 UResourceBundle* bundle = NULL;
252 char* icuid = NULL; 276 char* icuid = NULL;
253 UChar apiStd[MAX_LENGTH_ID];
254 char apiStdName[MAX_LENGTH_ID]; 277 char apiStdName[MAX_LENGTH_ID];
255 char regStdName[MAX_LENGTH_ID]; 278 char regStdName[MAX_LENGTH_ID];
256 char tmpid[MAX_LENGTH_ID]; 279 char tmpid[MAX_LENGTH_ID];
257 int32_t len; 280 int32_t len;
258 int id; 281 int id;
259 int errorCode; 282 int errorCode;
260 char ISOcode[3]; /* 2 letter iso code */ 283 UChar ISOcodeW[3]; /* 2 letter iso code in UTF-16*/
284 char ISOcodeA[3]; /* 2 letter iso code in ansi */
261 285
262 LONG result; 286 LONG result;
263 TZI tziKey; 287 TZI tziKey;
264 TZI tziReg; 288 TZI tziReg;
265 TIME_ZONE_INFORMATION apiTZI; 289 TIME_ZONE_INFORMATION apiTZI;
266 290
291 BOOL isVistaOrHigher;
292 BOOL tryPreVistaFallback;
293 OSVERSIONINFO osVerInfo;
294
267 /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it 295 /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it
268 to TZI. We could also interrogate the registry directly; we do 296 to TZI. We could also interrogate the registry directly; we do
269 this below if needed. */ 297 this below if needed. */
270 uprv_memset(&apiTZI, 0, sizeof(apiTZI)); 298 uprv_memset(&apiTZI, 0, sizeof(apiTZI));
271 uprv_memset(&tziKey, 0, sizeof(tziKey)); 299 uprv_memset(&tziKey, 0, sizeof(tziKey));
272 uprv_memset(&tziReg, 0, sizeof(tziReg)); 300 uprv_memset(&tziReg, 0, sizeof(tziReg));
273 GetTimeZoneInformation(&apiTZI); 301 GetTimeZoneInformation(&apiTZI);
274 tziKey.bias = apiTZI.Bias; 302 tziKey.bias = apiTZI.Bias;
275 uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate, 303 uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate,
276 sizeof(apiTZI.StandardDate)); 304 sizeof(apiTZI.StandardDate));
277 uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate, 305 uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate,
278 sizeof(apiTZI.DaylightDate)); 306 sizeof(apiTZI.DaylightDate));
279 307
280 /* Convert the wchar_t* standard name to char* */ 308 /* Convert the wchar_t* standard name to char* */
281 uprv_memset(apiStdName, 0, sizeof(apiStdName)); 309 uprv_memset(apiStdName, 0, sizeof(apiStdName));
282 u_strFromWCS(apiStd, MAX_LENGTH_ID, NULL, apiTZI.StandardName, -1, &status); 310 wcstombs(apiStdName, apiTZI.StandardName, MAX_LENGTH_ID);
283 u_austrncpy(apiStdName, apiStd, sizeof(apiStdName) - 1);
284 311
285 tmpid[0] = 0; 312 tmpid[0] = 0;
286 313
287 id = GetUserGeoID(GEOCLASS_NATION); 314 id = GetUserGeoID(GEOCLASS_NATION);
288 errorCode = GetGeoInfoA(id,GEO_ISO2,ISOcode,3,0); 315 errorCode = GetGeoInfoW(id,GEO_ISO2,ISOcodeW,3,0);
316 u_strToUTF8(ISOcodeA, 3, NULL, ISOcodeW, 3, &status);
289 317
290 bundle = ures_openDirect(NULL, "windowsZones", &status); 318 bundle = ures_openDirect(NULL, "windowsZones", &status);
291 ures_getByKey(bundle, "mapTimezones", bundle, &status); 319 ures_getByKey(bundle, "mapTimezones", bundle, &status);
292 320
293 /* Note: We get the winid not from static tables but from resource bundle. * / 321 /*
294 while (U_SUCCESS(status) && ures_hasNext(bundle)) { 322 Windows Vista+ provides us with a "TimeZoneKeyName" that is not localize d
295 UBool idFound = FALSE; 323 and can be used to directly map a name in our bundle. Try to use that fi rst
296 const char* winid; 324 if we're on Vista or higher
297 UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status); 325 */
298 if (U_FAILURE(status)) { 326 uprv_memset(&osVerInfo, 0, sizeof(osVerInfo));
299 break; 327 osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
300 } 328 GetVersionEx(&osVerInfo);
301 winid = ures_getKey(winTZ); 329 isVistaOrHigher = osVerInfo.dwMajorVersion >= 6;» /* actually includes Win dows Server 2008 as well, but don't worry about it */
302 result = getTZI(winid, &tziReg); 330 tryPreVistaFallback = TRUE;
303 331 if(isVistaOrHigher) {
304 if (result == ERROR_SUCCESS) { 332 result = getTZKeyName(regStdName, sizeof(regStdName));
305 /* Windows alters the DaylightBias in some situations. 333 if(ERROR_SUCCESS == result) {
306 Using the bias and the rules suffices, so overwrite 334 UResourceBundle* winTZ = ures_getByKey(bundle, regStdName, NULL, &st atus);
307 these unreliable fields. */ 335 if(U_SUCCESS(status)) {
308 tziKey.standardBias = tziReg.standardBias;
309 tziKey.daylightBias = tziReg.daylightBias;
310
311 if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
312 const UChar* icuTZ = NULL; 336 const UChar* icuTZ = NULL;
313 if (errorCode != 0) { 337 if (errorCode != 0) {
314 icuTZ = ures_getStringByKey(winTZ, ISOcode, &len, &status); 338 icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status);
315 } 339 }
316 if (errorCode==0 || icuTZ==NULL) { 340 if (errorCode==0 || icuTZ==NULL) {
317 /* fallback to default "001" and reset status */ 341 /* fallback to default "001" and reset status */
318 status = U_ZERO_ERROR; 342 status = U_ZERO_ERROR;
319 icuTZ = ures_getStringByKey(winTZ, "001", &len, &status); 343 icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
320 } 344 }
321 345
322 if (U_SUCCESS(status)) { 346 if(U_SUCCESS(status)) {
323 /* Get the standard name from the registry key to compare wi th 347 int index=0;
324 the one from Windows API call. */ 348 while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
325 uprv_memset(regStdName, 0, sizeof(regStdName)); 349 tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'cha r' is ASCII compatible on windows */
326 result = getSTDName(winid, regStdName, sizeof(regStdName)); 350 }
327 if (result == ERROR_SUCCESS) { 351 tmpid[index]='\0';
328 if (uprv_strcmp(apiStdName, regStdName) == 0) { 352 tryPreVistaFallback = FALSE;
329 idFound = TRUE; 353 }
330 } 354 }
355 }
356 }
357
358 if(tryPreVistaFallback) {
359
360 /* Note: We get the winid not from static tables but from resource bundl e. */
361 while (U_SUCCESS(status) && ures_hasNext(bundle)) {
362 UBool idFound = FALSE;
363 const char* winid;
364 UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status) ;
365 if (U_FAILURE(status)) {
366 break;
367 }
368 winid = ures_getKey(winTZ);
369 result = getTZI(winid, &tziReg);
370
371 if (result == ERROR_SUCCESS) {
372 /* Windows alters the DaylightBias in some situations.
373 Using the bias and the rules suffices, so overwrite
374 these unreliable fields. */
375 tziKey.standardBias = tziReg.standardBias;
376 tziKey.daylightBias = tziReg.daylightBias;
377
378 if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
379 const UChar* icuTZ = NULL;
380 if (errorCode != 0) {
381 icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &stat us);
382 }
383 if (errorCode==0 || icuTZ==NULL) {
384 /* fallback to default "001" and reset status */
385 status = U_ZERO_ERROR;
386 icuTZ = ures_getStringByKey(winTZ, "001", &len, &status) ;
331 } 387 }
332 388
333 /* tmpid buffer holds the ICU timezone ID corresponding to t he timezone ID from Windows. 389 if (U_SUCCESS(status)) {
334 * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching 390 /* Get the standard name from the registry key to compar e with
335 * the current time zone information) 391 the one from Windows API call. */
336 */ 392 uprv_memset(regStdName, 0, sizeof(regStdName));
337 if (idFound || tmpid[0] == 0) { 393 result = getSTDName(winid, regStdName, sizeof(regStdName ));
338 /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */ 394 if (result == ERROR_SUCCESS) {
339 int index=0; 395 if (uprv_strcmp(apiStdName, regStdName) == 0) {
340 while (! (*icuTZ == '\0' || *icuTZ ==' ')) { 396 idFound = TRUE;
341 tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */ 397 }
342 } 398 }
343 tmpid[index]='\0'; 399
400 /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows.
401 * If none is found, tmpid buffer will contain a fallbac k ID (i.e. the time zone ID matching
402 * the current time zone information)
403 */
404 if (idFound || tmpid[0] == 0) {
405 /* if icuTZ has more than one city, take only the fi rst (i.e. terminate icuTZ at first space) */
406 int index=0;
407 while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
408 tmpid[index++]=(char)(*icuTZ++); /* safe to ass ume 'char' is ASCII compatible on windows */
409 }
410 tmpid[index]='\0';
411 }
344 } 412 }
345 } 413 }
346 } 414 }
347 } 415 ures_close(winTZ);
348 ures_close(winTZ); 416 if (idFound) {
349 if (idFound) { 417 break;
350 break; 418 }
351 } 419 }
352 } 420 }
353 421
354 /* 422 /*
355 * Copy the timezone ID to icuid to be returned. 423 * Copy the timezone ID to icuid to be returned.
356 */ 424 */
357 if (tmpid[0] != 0) { 425 if (tmpid[0] != 0) {
358 len = uprv_strlen(tmpid); 426 len = uprv_strlen(tmpid);
359 icuid = (char*)uprv_calloc(len + 1, sizeof(char)); 427 icuid = (char*)uprv_calloc(len + 1, sizeof(char));
360 if (icuid != NULL) { 428 if (icuid != NULL) {
361 uprv_strcpy(icuid, tmpid); 429 uprv_strcpy(icuid, tmpid);
362 } 430 }
363 } 431 }
364 432
365 ures_close(bundle); 433 ures_close(bundle);
366 434
367 return icuid; 435 return icuid;
368 } 436 }
369 437
370 #endif /* U_PLATFORM_HAS_WIN32_API */ 438 #endif /* U_PLATFORM_HAS_WIN32_API */
OLDNEW
« no previous file with comments | « source/common/uvectr64.h ('k') | source/config.guess » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698