1 /*
2 * encoding.c - get DNS/Local encodings
3 *
4 * Software\JPNIC\IDN\Where
5 * \LogFile
6 * \LogLevel
7 * \InstallDir
8 * \PerProg\<name>\Where
9 * \PerProg\<name>\Encoding
10 */
11
12 /*
13 * Copyright (c) 2000,2001,2002 Japan Network Information Center.
14 * All rights reserved.
15 *
16 * By using this file, you agree to the terms and conditions set forth bellow.
17 *
18 * LICENSE TERMS AND CONDITIONS
19 *
20 * The following License Terms and Conditions apply, unless a different
21 * license is obtained from Japan Network Information Center ("JPNIC"),
22 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
23 * Chiyoda-ku, Tokyo 101-0047, Japan.
24 *
25 * 1. Use, Modification and Redistribution (including distribution of any
26 * modified or derived work) in source and/or binary forms is permitted
27 * under this License Terms and Conditions.
28 *
29 * 2. Redistribution of source code must retain the copyright notices as they
30 * appear in each source code file, this License Terms and Conditions.
31 *
32 * 3. Redistribution in binary form must reproduce the Copyright Notice,
33 * this License Terms and Conditions, in the documentation and/or other
34 * materials provided with the distribution. For the purposes of binary
35 * distribution the "Copyright Notice" refers to the following language:
36 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
37 *
38 * 4. The name of JPNIC may not be used to endorse or promote products
39 * derived from this Software without specific prior written approval of
40 * JPNIC.
41 *
42 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
45 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
47 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
48 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
49 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
50 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
51 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
52 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
53 */
54
55 #include <windows.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <ctype.h>
60
61 #include "wrapcommon.h"
62
63 #define IDN_GLOBAL 1
64 #define IDN_PERPROG 2
65 #define IDN_CURUSER 4
66
67 /*
68 * Registry of Encodings
69 */
70
71 #define IDNKEY_WRAPPER "Software\\JPNIC\\IDN"
72 #define IDNKEY_PERPROG "Software\\JPNIC\\IDN\\PerProg"
73 #define IDNVAL_WHERE "Where"
74 #define IDNVAL_ENCODE "Encoding"
75 #define IDNVAL_LOGLVL "LogLevel"
76 #define IDNVAL_LOGFILE "LogFile"
77 #define IDNVAL_INSDIR "InstallDir"
78
79 static int GetRegistry(HKEY top, const char *key, const char *name,
80 DWORD type, void *param, DWORD length);
81 static char *GetPerProgKey(char *buf, size_t len);
82 static int GetFromRegistry(const char *name, int where, DWORD type,
83 void *param, DWORD length);
84 static int GetIntFromRegistry(const char *name, int defvalue, int where);
85 static BOOL GetStringFromRegistry(const char *name, char *result,
86 size_t length, int where);
87
88 static int
GetRegistry(HKEY top,const char * key,const char * name,DWORD type,void * param,DWORD length)89 GetRegistry(HKEY top, const char *key, const char *name, DWORD type,
90 void *param, DWORD length)
91 {
92 LONG stat;
93 HKEY hk;
94 DWORD realtype;
95
96 stat = RegOpenKeyEx(top, key, 0, KEY_READ, &hk);
97 if (stat != ERROR_SUCCESS) {
98 return 0;
99 }
100
101 stat = RegQueryValueEx(hk, (LPCTSTR)name, NULL,
102 &realtype, (LPBYTE)param, &length);
103
104 RegCloseKey(hk);
105
106 if (stat != ERROR_SUCCESS || realtype != type)
107 return 0;
108
109 return 1;
110 }
111
112 static char *
GetPerProgKey(char * buf,size_t len)113 GetPerProgKey(char *buf, size_t len)
114 {
115 char exename[256];
116 char prgname[256];
117 char *p, *last;
118
119 GetModuleFileName(NULL, exename, 256);
120
121 for (p = exename, last = NULL; *p != '\0'; p++) {
122 if (*p == '/' || *p == '\\') {
123 last = p;
124 }
125 }
126 strcpy(prgname, (last == NULL) ? exename : (last + 1));
127 if ((p = strrchr(prgname, '.')) != NULL) {
128 *p = '\0';
129 }
130
131 if (strlen(IDNKEY_PERPROG) + 1 + strlen(prgname) >= len) {
132 return (NULL);
133 }
134 sprintf(buf, "%s\\%s", IDNKEY_PERPROG, prgname);
135 return buf;
136 }
137
138 static int
GetFromRegistry(const char * name,int where,DWORD type,void * param,DWORD length)139 GetFromRegistry(const char *name, int where, DWORD type,
140 void *param, DWORD length)
141 {
142 if (where & IDN_PERPROG) {
143 /*
144 * First, try program specific setting.
145 */
146 char keyname[256];
147
148 /*
149 * Try HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE.
150 */
151 if (GetPerProgKey(keyname, sizeof(keyname)) != NULL) {
152 if (((where & IDN_CURUSER) &&
153 GetRegistry(HKEY_CURRENT_USER, keyname, name,
154 type, param, length)) ||
155 GetRegistry(HKEY_LOCAL_MACHINE, keyname, name,
156 type, param, length)) {
157 return (1);
158 }
159 }
160 }
161
162 if (where & IDN_GLOBAL) {
163 /*
164 * Try global setting.
165 */
166 if (((where & IDN_CURUSER) &&
167 GetRegistry(HKEY_CURRENT_USER, IDNKEY_WRAPPER, name,
168 type, param, length)) ||
169 GetRegistry(HKEY_LOCAL_MACHINE, IDNKEY_WRAPPER, name,
170 type, param, length)) {
171 return (1);
172 }
173 }
174
175 /*
176 * Not found.
177 */
178 return (0);
179 }
180
181 static int
GetIntFromRegistry(const char * name,int defvalue,int where)182 GetIntFromRegistry(const char *name, int defvalue, int where)
183 {
184 DWORD param;
185
186 if (GetFromRegistry(name, where, REG_DWORD, ¶m, sizeof(param))) {
187 return ((int)param);
188 }
189 return (defvalue);
190 }
191
192 static BOOL
GetStringFromRegistry(const char * name,char * result,size_t length,int where)193 GetStringFromRegistry(const char *name, char *result, size_t length, int where)
194 {
195 if (GetFromRegistry(name, where, REG_SZ, result, (DWORD)length)) {
196 return (TRUE);
197 }
198 return (FALSE);
199 }
200
201 /*
202 * idnEncodeWhere - which module should convert domain name
203 */
204 int
idnEncodeWhere(void)205 idnEncodeWhere(void)
206 {
207 int v = GetIntFromRegistry(IDNVAL_WHERE, IDN_ENCODE_ALWAYS,
208 IDN_GLOBAL|IDN_PERPROG|IDN_CURUSER);
209
210 idnLogPrintf(idn_log_level_trace, "idnEncodeWhere: %d\n", v);
211 return (v);
212 }
213
214 /*
215 * idnGetLogFile - refer to log file
216 */
217 BOOL
idnGetLogFile(char * file,size_t len)218 idnGetLogFile(char *file, size_t len)
219 {
220 BOOL v = GetStringFromRegistry(IDNVAL_LOGFILE, file, len,
221 IDN_GLOBAL|IDN_CURUSER);
222
223 idnLogPrintf(idn_log_level_trace, "idnGetLogFile: %-.100s\n",
224 (v == TRUE) ? file : "<none>");
225 return (v);
226 }
227
228 /*
229 * idnGetPrgEncoding - refer to Program's Local Encoding
230 *
231 * use program name as registry key
232 */
233 BOOL
idnGetPrgEncoding(char * enc,size_t len)234 idnGetPrgEncoding(char *enc, size_t len)
235 {
236 if (GetStringFromRegistry(IDNVAL_ENCODE, enc, len,
237 IDN_PERPROG|IDN_CURUSER) != TRUE ||
238 enc[0] == '\0') {
239 sprintf(enc, "CP%d", GetACP());
240 }
241 idnLogPrintf(idn_log_level_trace,
242 "idnGetPrgEncoding: %-.30s\n", enc);
243 return (TRUE);
244 }
245
246 /*
247 * idnGetLogLevel
248 */
249 int
idnGetLogLevel(void)250 idnGetLogLevel(void)
251 {
252 int v = GetIntFromRegistry(IDNVAL_LOGLVL, 0,
253 IDN_GLOBAL|IDN_CURUSER);
254
255 idnLogPrintf(idn_log_level_trace, "idnGetLogLevel: %d\n", v);
256 return (v);
257 }
258
259 /*
260 * idnGetInstallDir - get idn wrapper install directory
261 */
262 BOOL
idnGetInstallDir(char * dir,size_t len)263 idnGetInstallDir(char *dir, size_t len)
264 {
265 /* No need to look at HKEY_CURRENT_USER */
266 BOOL v = GetStringFromRegistry(IDNVAL_INSDIR, dir, len, IDN_GLOBAL);
267
268 idnLogPrintf(idn_log_level_trace, "idnGetInstallDir: %-.100s\n",
269 (v == TRUE) ? dir : "<none>");
270 return (v);
271 }
272