1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
diff -ur icu-50.1.orig/source/common/wintz.c icu-50.1/source/common/wintz.c
--- icu-50.1.orig/source/common/wintz.c 2012-11-05 18:14:42.000000000 +0100
+++ icu-50.1/source/common/wintz.c 2012-11-29 09:10:43.000000000 +0100
@@ -265,6 +265,28 @@
TZI tziReg;
TIME_ZONE_INFORMATION apiTZI;
+ OSVERSIONINFO winosversion;
+ static int NewerThanWindows2000 = -1;
+
+ /* If the OS version is older than Windows XP, we use the
+ * code in ICU-49.1.2, since GetGeoInfo() is not available.
+ */
+
+ if (NewerThanWindows2000 == -1) {
+ if (GetVersionEx (&winosversion) == 0) {
+ /* GetVersionEx() failed for some reason. We assume
+ * the Windows OS is newer than Windows 2000.
+ */
+ NewerThanWindows2000 = 1;
+ } else if (winosversion.dwMajorVersion > 5 ||
+ (winosversion.dwMajorVersion == 5 &&
+ winosversion.dwMinorVersion > 0)) {
+ NewerThanWindows2000 = 1;
+ } else {
+ NewerThanWindows2000 = 0;
+ }
+ }
+
/* 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. */
@@ -285,9 +307,31 @@
tmpid[0] = 0;
- id = GetUserGeoID(GEOCLASS_NATION);
- errorCode = GetGeoInfo(id,GEO_ISO2,ISOcode,3,0);
+ if (NewerThanWindows2000 == 1) {
+ HINSTANCE hi;
+ PROC pgetusergeoid, pgetgeoinfo;
+
+ /* if LoadLibrary() and/or GetProcAdress() fail, we again
+ * set NewerThanWindows2000 = 0, and use the code in ICU 49.1.2.
+ */
+
+ hi = LoadLibrary ("kernel32.dll");
+ if (hi == NULL) {
+ NewerThanWindows2000 = 0;
+ } else {
+ pgetusergeoid = GetProcAddress (hi, "GetUserGeoID");
+ pgetgeoinfo = GetProcAddress (hi, "GetGeoInfoA");
+ }
+ if (!pgetusergeoid || !pgetgeoinfo)
+ NewerThanWindows2000 = 0;
+ if (NewerThanWindows2000 == 1) {
+ id = (int)pgetusergeoid (GEOCLASS_NATION);
+ errorCode = (int)pgetgeoinfo (id,GEO_ISO2,ISOcode,3,0);
+ }
+ if (hi)
+ FreeLibrary (hi);
+ }
bundle = ures_openDirect(NULL, "windowsZones", &status);
ures_getByKey(bundle, "mapTimezones", bundle, &status);
@@ -310,14 +354,19 @@
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, ISOcode, &len, &status);
- }
- if (errorCode==0 || icuTZ==NULL) {
- /* fallback to default "001" and reset status */
- status = U_ZERO_ERROR;
+ const UChar* icuTZ;
+ if (NewerThanWindows2000 == 0) {
icuTZ = ures_getStringByKey(winTZ, "001", &len, &status);
+ } else if (NewerThanWindows2000 == 1) {
+ icuTZ = NULL;
+ if (errorCode != 0) {
+ icuTZ = ures_getStringByKey(winTZ, ISOcode, &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)) {
@@ -336,12 +385,17 @@
* 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++]=*icuTZ++;
+ if (NewerThanWindows2000 == 0) {
+ uprv_memset(tmpid, 0, sizeof(tmpid));
+ u_austrncpy(tmpid, icuTZ, len);
+ } else if (NewerThanWindows2000 == 1) {
+ /* 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++]=*icuTZ++;
+ }
+ tmpid[index]='\0';
}
- tmpid[index]='\0';
}
}
}
@@ -364,7 +418,7 @@
}
ures_close(bundle);
-
+
return icuid;
}
|