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, &param, 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