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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/common/uvectr64.h ('k') | source/config.guess » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/common/wintz.c
diff --git a/source/common/wintz.c b/source/common/wintz.c
index 32e2df8ea162a59a3e06065a7220e8cee56f59eb..1b645ee9be42c4a6129eb2f2a9f4e0a9eec6e78f 100644
--- a/source/common/wintz.c
+++ b/source/common/wintz.c
@@ -1,6 +1,6 @@
/*
********************************************************************************
-* Copyright (C) 2005-2013, International Business Machines
+* Copyright (C) 2005-2014, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************************
*
@@ -17,8 +17,8 @@
#include "cmemory.h"
#include "cstring.h"
-#include "unicode/ustring.h"
#include "unicode/ures.h"
+#include "unicode/ustring.h"
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRALEAN
@@ -193,6 +193,30 @@ static LONG getSTDName(const char *winid, char *regStdName, int32_t length) {
return result;
}
+static LONG getTZKeyName(char* tzKeyName, int32_t length) {
+ HKEY hkey;
+ LONG result = FALSE;
+ DWORD cbData = length;
+
+ if(ERROR_SUCCESS == RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE,
+ CURRENT_ZONE_REGKEY,
+ 0,
+ KEY_QUERY_VALUE,
+ &hkey))
+ {
+ result = RegQueryValueExA(
+ hkey,
+ "TimeZoneKeyName",
+ NULL,
+ NULL,
+ (LPBYTE)tzKeyName,
+ &cbData);
+ }
+
+ return result;
+}
+
/*
This code attempts to detect the Windows time zone, as set in the
Windows Date and Time control panel. It attempts to work on
@@ -250,20 +274,24 @@ uprv_detectWindowsTimeZone() {
UErrorCode status = U_ZERO_ERROR;
UResourceBundle* bundle = NULL;
char* icuid = NULL;
- UChar apiStd[MAX_LENGTH_ID];
char apiStdName[MAX_LENGTH_ID];
char regStdName[MAX_LENGTH_ID];
char tmpid[MAX_LENGTH_ID];
int32_t len;
int id;
int errorCode;
- char ISOcode[3]; /* 2 letter iso code */
+ UChar ISOcodeW[3]; /* 2 letter iso code in UTF-16*/
+ char ISOcodeA[3]; /* 2 letter iso code in ansi */
LONG result;
TZI tziKey;
TZI tziReg;
TIME_ZONE_INFORMATION apiTZI;
+ BOOL isVistaOrHigher;
+ BOOL tryPreVistaFallback;
+ OSVERSIONINFO osVerInfo;
+
/* Obtain TIME_ZONE_INFORMATION from the API, and then convert it
to TZI. We could also interrogate the registry directly; we do
this below if needed. */
@@ -279,39 +307,35 @@ uprv_detectWindowsTimeZone() {
/* Convert the wchar_t* standard name to char* */
uprv_memset(apiStdName, 0, sizeof(apiStdName));
- u_strFromWCS(apiStd, MAX_LENGTH_ID, NULL, apiTZI.StandardName, -1, &status);
- u_austrncpy(apiStdName, apiStd, sizeof(apiStdName) - 1);
+ wcstombs(apiStdName, apiTZI.StandardName, MAX_LENGTH_ID);
tmpid[0] = 0;
id = GetUserGeoID(GEOCLASS_NATION);
- errorCode = GetGeoInfoA(id,GEO_ISO2,ISOcode,3,0);
+ errorCode = GetGeoInfoW(id,GEO_ISO2,ISOcodeW,3,0);
+ u_strToUTF8(ISOcodeA, 3, NULL, ISOcodeW, 3, &status);
bundle = ures_openDirect(NULL, "windowsZones", &status);
ures_getByKey(bundle, "mapTimezones", bundle, &status);
- /* Note: We get the winid not from static tables but from resource bundle. */
- while (U_SUCCESS(status) && ures_hasNext(bundle)) {
- UBool idFound = FALSE;
- const char* winid;
- UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status);
- if (U_FAILURE(status)) {
- break;
- }
- winid = ures_getKey(winTZ);
- result = getTZI(winid, &tziReg);
-
- if (result == ERROR_SUCCESS) {
- /* Windows alters the DaylightBias in some situations.
- Using the bias and the rules suffices, so overwrite
- these unreliable fields. */
- tziKey.standardBias = tziReg.standardBias;
- tziKey.daylightBias = tziReg.daylightBias;
-
- if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
+ /*
+ Windows Vista+ provides us with a "TimeZoneKeyName" that is not localized
+ and can be used to directly map a name in our bundle. Try to use that first
+ if we're on Vista or higher
+ */
+ uprv_memset(&osVerInfo, 0, sizeof(osVerInfo));
+ osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
+ GetVersionEx(&osVerInfo);
+ isVistaOrHigher = osVerInfo.dwMajorVersion >= 6; /* actually includes Windows Server 2008 as well, but don't worry about it */
+ tryPreVistaFallback = TRUE;
+ if(isVistaOrHigher) {
+ result = getTZKeyName(regStdName, sizeof(regStdName));
+ if(ERROR_SUCCESS == result) {
+ UResourceBundle* winTZ = ures_getByKey(bundle, regStdName, NULL, &status);
+ if(U_SUCCESS(status)) {
const UChar* icuTZ = NULL;
if (errorCode != 0) {
- icuTZ = ures_getStringByKey(winTZ, ISOcode, &len, &status);
+ icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status);
}
if (errorCode==0 || icuTZ==NULL) {
/* fallback to default "001" and reset status */
@@ -319,35 +343,79 @@ uprv_detectWindowsTimeZone() {
icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
}
- if (U_SUCCESS(status)) {
- /* Get the standard name from the registry key to compare with
- the one from Windows API call. */
- uprv_memset(regStdName, 0, sizeof(regStdName));
- result = getSTDName(winid, regStdName, sizeof(regStdName));
- if (result == ERROR_SUCCESS) {
- if (uprv_strcmp(apiStdName, regStdName) == 0) {
- idFound = TRUE;
- }
+ if(U_SUCCESS(status)) {
+ int index=0;
+ while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
+ tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */
+ }
+ tmpid[index]='\0';
+ tryPreVistaFallback = FALSE;
+ }
+ }
+ }
+ }
+
+ if(tryPreVistaFallback) {
+
+ /* Note: We get the winid not from static tables but from resource bundle. */
+ while (U_SUCCESS(status) && ures_hasNext(bundle)) {
+ UBool idFound = FALSE;
+ const char* winid;
+ UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status);
+ if (U_FAILURE(status)) {
+ break;
+ }
+ winid = ures_getKey(winTZ);
+ result = getTZI(winid, &tziReg);
+
+ if (result == ERROR_SUCCESS) {
+ /* Windows alters the DaylightBias in some situations.
+ Using the bias and the rules suffices, so overwrite
+ these unreliable fields. */
+ tziKey.standardBias = tziReg.standardBias;
+ tziKey.daylightBias = tziReg.daylightBias;
+
+ if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
+ const UChar* icuTZ = NULL;
+ if (errorCode != 0) {
+ icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status);
}
+ if (errorCode==0 || icuTZ==NULL) {
+ /* fallback to default "001" and reset status */
+ status = U_ZERO_ERROR;
+ icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
+ }
+
+ if (U_SUCCESS(status)) {
+ /* Get the standard name from the registry key to compare with
+ the one from Windows API call. */
+ uprv_memset(regStdName, 0, sizeof(regStdName));
+ result = getSTDName(winid, regStdName, sizeof(regStdName));
+ if (result == ERROR_SUCCESS) {
+ if (uprv_strcmp(apiStdName, regStdName) == 0) {
+ idFound = TRUE;
+ }
+ }
- /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows.
- * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching
- * the current time zone information)
- */
- if (idFound || tmpid[0] == 0) {
- /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */
- int index=0;
- while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
- tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */
+ /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows.
+ * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching
+ * the current time zone information)
+ */
+ if (idFound || tmpid[0] == 0) {
+ /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */
+ int index=0;
+ while (! (*icuTZ == '\0' || *icuTZ ==' ')) {
+ tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */
+ }
+ tmpid[index]='\0';
}
- tmpid[index]='\0';
}
}
}
- }
- ures_close(winTZ);
- if (idFound) {
- break;
+ ures_close(winTZ);
+ if (idFound) {
+ break;
+ }
}
}
« 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