FFFTPのソースコードです。
修訂 | e6470192110d4890abe9761ed67d0ce7fd6060c9 (tree) |
---|---|
時間 | 2011-10-22 00:05:09 |
作者 | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Add support for encoding multi-byte domain name to Punycode.
@@ -311,6 +311,10 @@ | ||
311 | 311 | > |
312 | 312 | </File> |
313 | 313 | <File |
314 | + RelativePath=".\punycode.c" | |
315 | + > | |
316 | + </File> | |
317 | + <File | |
314 | 318 | RelativePath=".\protectprocess.c" |
315 | 319 | > |
316 | 320 | </File> |
@@ -312,6 +312,10 @@ | ||
312 | 312 | > |
313 | 313 | </File> |
314 | 314 | <File |
315 | + RelativePath=".\punycode.c" | |
316 | + > | |
317 | + </File> | |
318 | + <File | |
315 | 319 | RelativePath=".\protectprocess.c" |
316 | 320 | > |
317 | 321 | </File> |
@@ -311,6 +311,10 @@ | ||
311 | 311 | > |
312 | 312 | </File> |
313 | 313 | <File |
314 | + RelativePath=".\punycode.c" | |
315 | + > | |
316 | + </File> | |
317 | + <File | |
314 | 318 | RelativePath=".\protectprocess.c" |
315 | 319 | > |
316 | 320 | </File> |
@@ -312,6 +312,10 @@ | ||
312 | 312 | > |
313 | 313 | </File> |
314 | 314 | <File |
315 | + RelativePath=".\punycode.c" | |
316 | + > | |
317 | + </File> | |
318 | + <File | |
315 | 319 | RelativePath=".\protectprocess.c" |
316 | 320 | > |
317 | 321 | </File> |
@@ -0,0 +1,346 @@ | ||
1 | +/* | |
2 | +punycode.c from RFC 3492 | |
3 | +http://www.nicemice.net/idn/ | |
4 | +Adam M. Costello | |
5 | +http://www.nicemice.net/amc/ | |
6 | + | |
7 | +This is ANSI C code (C89) implementing Punycode (RFC 3492). | |
8 | + | |
9 | +*/ | |
10 | + | |
11 | + | |
12 | +/************************************************************/ | |
13 | +/* Public interface (would normally go in its own .h file): */ | |
14 | + | |
15 | +#include <limits.h> | |
16 | + | |
17 | +enum punycode_status { | |
18 | + punycode_success, | |
19 | + punycode_bad_input, /* Input is invalid. */ | |
20 | + punycode_big_output, /* Output would exceed the space provided. */ | |
21 | + punycode_overflow /* Input needs wider integers to process. */ | |
22 | +}; | |
23 | + | |
24 | +#if UINT_MAX >= (1 << 26) - 1 | |
25 | +typedef unsigned int punycode_uint; | |
26 | +#else | |
27 | +typedef unsigned long punycode_uint; | |
28 | +#endif | |
29 | + | |
30 | +enum punycode_status punycode_encode( | |
31 | + punycode_uint input_length, | |
32 | + const punycode_uint input[], | |
33 | + const unsigned char case_flags[], | |
34 | + punycode_uint *output_length, | |
35 | + char output[] ); | |
36 | + | |
37 | + /* punycode_encode() converts Unicode to Punycode. The input */ | |
38 | + /* is represented as an array of Unicode code points (not code */ | |
39 | + /* units; surrogate pairs are not allowed), and the output */ | |
40 | + /* will be represented as an array of ASCII code points. The */ | |
41 | + /* output string is *not* null-terminated; it will contain */ | |
42 | + /* zeros if and only if the input contains zeros. (Of course */ | |
43 | + /* the caller can leave room for a terminator and add one if */ | |
44 | + /* needed.) The input_length is the number of code points in */ | |
45 | + /* the input. The output_length is an in/out argument: the */ | |
46 | + /* caller passes in the maximum number of code points that it */ | |
47 | + /* can receive, and on successful return it will contain the */ | |
48 | + /* number of code points actually output. The case_flags array */ | |
49 | + /* holds input_length boolean values, where nonzero suggests that */ | |
50 | + /* the corresponding Unicode character be forced to uppercase */ | |
51 | + /* after being decoded (if possible), and zero suggests that */ | |
52 | + /* it be forced to lowercase (if possible). ASCII code points */ | |
53 | + /* are encoded literally, except that ASCII letters are forced */ | |
54 | + /* to uppercase or lowercase according to the corresponding */ | |
55 | + /* uppercase flags. If case_flags is a null pointer then ASCII */ | |
56 | + /* letters are left as they are, and other code points are */ | |
57 | + /* treated as if their uppercase flags were zero. The return */ | |
58 | + /* value can be any of the punycode_status values defined above */ | |
59 | + /* except punycode_bad_input; if not punycode_success, then */ | |
60 | + /* output_size and output might contain garbage. */ | |
61 | + | |
62 | +enum punycode_status punycode_decode( | |
63 | + punycode_uint input_length, | |
64 | + const char input[], | |
65 | + punycode_uint *output_length, | |
66 | + punycode_uint output[], | |
67 | + unsigned char case_flags[] ); | |
68 | + | |
69 | + /* punycode_decode() converts Punycode to Unicode. The input is */ | |
70 | + /* represented as an array of ASCII code points, and the output */ | |
71 | + /* will be represented as an array of Unicode code points. The */ | |
72 | + /* input_length is the number of code points in the input. The */ | |
73 | + /* output_length is an in/out argument: the caller passes in */ | |
74 | + /* the maximum number of code points that it can receive, and */ | |
75 | + /* on successful return it will contain the actual number of */ | |
76 | + /* code points output. The case_flags array needs room for at */ | |
77 | + /* least output_length values, or it can be a null pointer if the */ | |
78 | + /* case information is not needed. A nonzero flag suggests that */ | |
79 | + /* the corresponding Unicode character be forced to uppercase */ | |
80 | + /* by the caller (if possible), while zero suggests that it be */ | |
81 | + /* forced to lowercase (if possible). ASCII code points are */ | |
82 | + /* output already in the proper case, but their flags will be set */ | |
83 | + /* appropriately so that applying the flags would be harmless. */ | |
84 | + /* The return value can be any of the punycode_status values */ | |
85 | + /* defined above; if not punycode_success, then output_length, */ | |
86 | + /* output, and case_flags might contain garbage. On success, the */ | |
87 | + /* decoder will never need to write an output_length greater than */ | |
88 | + /* input_length, because of how the encoding is defined. */ | |
89 | + | |
90 | +/**********************************************************/ | |
91 | +/* Implementation (would normally go in its own .c file): */ | |
92 | + | |
93 | +#include <string.h> | |
94 | + | |
95 | +/*** Bootstring parameters for Punycode ***/ | |
96 | + | |
97 | +enum { base = 36, tmin = 1, tmax = 26, skew = 38, damp = 700, | |
98 | + initial_bias = 72, initial_n = 0x80, delimiter = 0x2D }; | |
99 | + | |
100 | +/* basic(cp) tests whether cp is a basic code point: */ | |
101 | +#define basic(cp) ((punycode_uint)(cp) < 0x80) | |
102 | + | |
103 | +/* delim(cp) tests whether cp is a delimiter: */ | |
104 | +#define delim(cp) ((cp) == delimiter) | |
105 | + | |
106 | +/* decode_digit(cp) returns the numeric value of a basic code */ | |
107 | +/* point (for use in representing integers) in the range 0 to */ | |
108 | +/* base-1, or base if cp is does not represent a value. */ | |
109 | + | |
110 | +static punycode_uint decode_digit(punycode_uint cp) | |
111 | +{ | |
112 | + return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : | |
113 | + cp - 97 < 26 ? cp - 97 : base; | |
114 | +} | |
115 | + | |
116 | +/* encode_digit(d,flag) returns the basic code point whose value */ | |
117 | +/* (when used for representing integers) is d, which needs to be in */ | |
118 | +/* the range 0 to base-1. The lowercase form is used unless flag is */ | |
119 | +/* nonzero, in which case the uppercase form is used. The behavior */ | |
120 | +/* is undefined if flag is nonzero and digit d has no uppercase form. */ | |
121 | + | |
122 | +static char encode_digit(punycode_uint d, int flag) | |
123 | +{ | |
124 | + return d + 22 + 75 * (d < 26) - ((flag != 0) << 5); | |
125 | + /* 0..25 map to ASCII a..z or A..Z */ | |
126 | + /* 26..35 map to ASCII 0..9 */ | |
127 | +} | |
128 | + | |
129 | +/* flagged(bcp) tests whether a basic code point is flagged */ | |
130 | +/* (uppercase). The behavior is undefined if bcp is not a */ | |
131 | +/* basic code point. */ | |
132 | + | |
133 | +#define flagged(bcp) ((punycode_uint)(bcp) - 65 < 26) | |
134 | + | |
135 | +/* encode_basic(bcp,flag) forces a basic code point to lowercase */ | |
136 | +/* if flag is zero, uppercase if flag is nonzero, and returns */ | |
137 | +/* the resulting code point. The code point is unchanged if it */ | |
138 | +/* is caseless. The behavior is undefined if bcp is not a basic */ | |
139 | +/* code point. */ | |
140 | + | |
141 | +static char encode_basic(punycode_uint bcp, int flag) | |
142 | +{ | |
143 | + bcp -= (bcp - 97 < 26) << 5; | |
144 | + return bcp + ((!flag && (bcp - 65 < 26)) << 5); | |
145 | +} | |
146 | + | |
147 | +/*** Platform-specific constants ***/ | |
148 | + | |
149 | +/* maxint is the maximum value of a punycode_uint variable: */ | |
150 | +static const punycode_uint maxint = -1; | |
151 | +/* Because maxint is unsigned, -1 becomes the maximum value. */ | |
152 | + | |
153 | +/*** Bias adaptation function ***/ | |
154 | + | |
155 | +static punycode_uint adapt( | |
156 | + punycode_uint delta, punycode_uint numpoints, int firsttime ) | |
157 | +{ | |
158 | + punycode_uint k; | |
159 | + | |
160 | + delta = firsttime ? delta / damp : delta >> 1; | |
161 | + /* delta >> 1 is a faster way of doing delta / 2 */ | |
162 | + delta += delta / numpoints; | |
163 | + | |
164 | + for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base) { | |
165 | + delta /= base - tmin; | |
166 | + } | |
167 | + | |
168 | + return k + (base - tmin + 1) * delta / (delta + skew); | |
169 | +} | |
170 | + | |
171 | +/*** Main encode function ***/ | |
172 | + | |
173 | +enum punycode_status punycode_encode( | |
174 | + punycode_uint input_length, | |
175 | + const punycode_uint input[], | |
176 | + const unsigned char case_flags[], | |
177 | + punycode_uint *output_length, | |
178 | + char output[] ) | |
179 | +{ | |
180 | + punycode_uint n, delta, h, b, out, max_out, bias, j, m, q, k, t; | |
181 | + | |
182 | + /* Initialize the state: */ | |
183 | + | |
184 | + n = initial_n; | |
185 | + delta = out = 0; | |
186 | + max_out = *output_length; | |
187 | + bias = initial_bias; | |
188 | + | |
189 | + /* Handle the basic code points: */ | |
190 | + | |
191 | + for (j = 0; j < input_length; ++j) { | |
192 | + if (basic(input[j])) { | |
193 | + if (max_out - out < 2) return punycode_big_output; | |
194 | + output[out++] = | |
195 | + case_flags ? encode_basic(input[j], case_flags[j]) : input[j]; | |
196 | + } | |
197 | + /* else if (input[j] < n) return punycode_bad_input; */ | |
198 | + /* (not needed for Punycode with unsigned code points) */ | |
199 | + } | |
200 | + | |
201 | + h = b = out; | |
202 | + | |
203 | + /* h is the number of code points that have been handled, b is the */ | |
204 | + /* number of basic code points, and out is the number of characters */ | |
205 | + /* that have been output. */ | |
206 | + | |
207 | + if (b > 0) output[out++] = delimiter; | |
208 | + | |
209 | + /* Main encoding loop: */ | |
210 | + | |
211 | + while (h < input_length) { | |
212 | + /* All non-basic code points < n have been */ | |
213 | + /* handled already. Find the next larger one: */ | |
214 | + | |
215 | + for (m = maxint, j = 0; j < input_length; ++j) { | |
216 | + /* if (basic(input[j])) continue; */ | |
217 | + /* (not needed for Punycode) */ | |
218 | + if (input[j] >= n && input[j] < m) m = input[j]; | |
219 | + } | |
220 | + | |
221 | + /* Increase delta enough to advance the decoder's */ | |
222 | + /* <n,i> state to <m,0>, but guard against overflow: */ | |
223 | + | |
224 | + if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow; | |
225 | + delta += (m - n) * (h + 1); | |
226 | + n = m; | |
227 | + | |
228 | + for (j = 0; j < input_length; ++j) { | |
229 | + /* Punycode does not need to check whether input[j] is basic: */ | |
230 | + if (input[j] < n /* || basic(input[j]) */ ) { | |
231 | + if (++delta == 0) return punycode_overflow; | |
232 | + } | |
233 | + | |
234 | + if (input[j] == n) { | |
235 | + /* Represent delta as a generalized variable-length integer: */ | |
236 | + | |
237 | + for (q = delta, k = base; ; k += base) { | |
238 | + if (out >= max_out) return punycode_big_output; | |
239 | + t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */ | |
240 | + k >= bias + tmax ? tmax : k - bias; | |
241 | + if (q < t) break; | |
242 | + output[out++] = encode_digit(t + (q - t) % (base - t), 0); | |
243 | + q = (q - t) / (base - t); | |
244 | + } | |
245 | + | |
246 | + output[out++] = encode_digit(q, case_flags && case_flags[j]); | |
247 | + bias = adapt(delta, h + 1, h == b); | |
248 | + delta = 0; | |
249 | + ++h; | |
250 | + } | |
251 | + } | |
252 | + | |
253 | + ++delta, ++n; | |
254 | + } | |
255 | + | |
256 | + *output_length = out; | |
257 | + return punycode_success; | |
258 | +} | |
259 | + | |
260 | +/*** Main decode function ***/ | |
261 | + | |
262 | +enum punycode_status punycode_decode( | |
263 | + punycode_uint input_length, | |
264 | + const char input[], | |
265 | + punycode_uint *output_length, | |
266 | + punycode_uint output[], | |
267 | + unsigned char case_flags[] ) | |
268 | +{ | |
269 | + punycode_uint n, out, i, max_out, bias, | |
270 | + b, j, in, oldi, w, k, digit, t; | |
271 | + | |
272 | + /* Initialize the state: */ | |
273 | + | |
274 | + n = initial_n; | |
275 | + out = i = 0; | |
276 | + max_out = *output_length; | |
277 | + bias = initial_bias; | |
278 | + | |
279 | + /* Handle the basic code points: Let b be the number of input code */ | |
280 | + /* points before the last delimiter, or 0 if there is none, then */ | |
281 | + /* copy the first b code points to the output. */ | |
282 | + | |
283 | + for (b = j = 0; j < input_length; ++j) if (delim(input[j])) b = j; | |
284 | + if (b > max_out) return punycode_big_output; | |
285 | + | |
286 | + for (j = 0; j < b; ++j) { | |
287 | + if (case_flags) case_flags[out] = flagged(input[j]); | |
288 | + if (!basic(input[j])) return punycode_bad_input; | |
289 | + output[out++] = input[j]; | |
290 | + } | |
291 | + | |
292 | + /* Main decoding loop: Start just after the last delimiter if any */ | |
293 | + /* basic code points were copied; start at the beginning otherwise. */ | |
294 | + | |
295 | + for (in = b > 0 ? b + 1 : 0; in < input_length; ++out) { | |
296 | + | |
297 | + /* in is the index of the next character to be consumed, and */ | |
298 | + /* out is the number of code points in the output array. */ | |
299 | + | |
300 | + /* Decode a generalized variable-length integer into delta, */ | |
301 | + /* which gets added to i. The overflow checking is easier */ | |
302 | + /* if we increase i as we go, then subtract off its starting */ | |
303 | + /* value at the end to obtain delta. */ | |
304 | + | |
305 | + for (oldi = i, w = 1, k = base; ; k += base) { | |
306 | + if (in >= input_length) return punycode_bad_input; | |
307 | + digit = decode_digit(input[in++]); | |
308 | + if (digit >= base) return punycode_bad_input; | |
309 | + if (digit > (maxint - i) / w) return punycode_overflow; | |
310 | + i += digit * w; | |
311 | + t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */ | |
312 | + k >= bias + tmax ? tmax : k - bias; | |
313 | + if (digit < t) break; | |
314 | + if (w > maxint / (base - t)) return punycode_overflow; | |
315 | + w *= (base - t); | |
316 | + } | |
317 | + | |
318 | + bias = adapt(i - oldi, out + 1, oldi == 0); | |
319 | + | |
320 | + /* i was supposed to wrap around from out+1 to 0, */ | |
321 | + /* incrementing n each time, so we'll fix that now: */ | |
322 | + | |
323 | + if (i / (out + 1) > maxint - n) return punycode_overflow; | |
324 | + n += i / (out + 1); | |
325 | + i %= (out + 1); | |
326 | + | |
327 | + /* Insert n at position i of the output: */ | |
328 | + | |
329 | + /* not needed for Punycode: */ | |
330 | + /* if (decode_digit(n) <= base) return punycode_invalid_input; */ | |
331 | + if (out >= max_out) return punycode_big_output; | |
332 | + | |
333 | + if (case_flags) { | |
334 | + memmove(case_flags + i + 1, case_flags + i, out - i); | |
335 | + /* Case of last character determines uppercase flag: */ | |
336 | + case_flags[i] = flagged(input[in - 1]); | |
337 | + } | |
338 | + | |
339 | + memmove(output + i + 1, output + i, (out - i) * sizeof *output); | |
340 | + output[i++] = n; | |
341 | + } | |
342 | + | |
343 | + *output_length = out; | |
344 | + return punycode_success; | |
345 | +} | |
346 | + |
@@ -0,0 +1,89 @@ | ||
1 | +/* | |
2 | +punycode.c from RFC 3492 | |
3 | +http://www.nicemice.net/idn/ | |
4 | +Adam M. Costello | |
5 | +http://www.nicemice.net/amc/ | |
6 | + | |
7 | +This is ANSI C code (C89) implementing Punycode (RFC 3492). | |
8 | + | |
9 | +*/ | |
10 | + | |
11 | + | |
12 | +/************************************************************/ | |
13 | +/* Public interface (would normally go in its own .h file): */ | |
14 | + | |
15 | +#include <limits.h> | |
16 | + | |
17 | +enum punycode_status { | |
18 | + punycode_success, | |
19 | + punycode_bad_input, /* Input is invalid. */ | |
20 | + punycode_big_output, /* Output would exceed the space provided. */ | |
21 | + punycode_overflow /* Input needs wider integers to process. */ | |
22 | +}; | |
23 | + | |
24 | +#if UINT_MAX >= (1 << 26) - 1 | |
25 | +typedef unsigned int punycode_uint; | |
26 | +#else | |
27 | +typedef unsigned long punycode_uint; | |
28 | +#endif | |
29 | + | |
30 | +enum punycode_status punycode_encode( | |
31 | + punycode_uint input_length, | |
32 | + const punycode_uint input[], | |
33 | + const unsigned char case_flags[], | |
34 | + punycode_uint *output_length, | |
35 | + char output[] ); | |
36 | + | |
37 | + /* punycode_encode() converts Unicode to Punycode. The input */ | |
38 | + /* is represented as an array of Unicode code points (not code */ | |
39 | + /* units; surrogate pairs are not allowed), and the output */ | |
40 | + /* will be represented as an array of ASCII code points. The */ | |
41 | + /* output string is *not* null-terminated; it will contain */ | |
42 | + /* zeros if and only if the input contains zeros. (Of course */ | |
43 | + /* the caller can leave room for a terminator and add one if */ | |
44 | + /* needed.) The input_length is the number of code points in */ | |
45 | + /* the input. The output_length is an in/out argument: the */ | |
46 | + /* caller passes in the maximum number of code points that it */ | |
47 | + /* can receive, and on successful return it will contain the */ | |
48 | + /* number of code points actually output. The case_flags array */ | |
49 | + /* holds input_length boolean values, where nonzero suggests that */ | |
50 | + /* the corresponding Unicode character be forced to uppercase */ | |
51 | + /* after being decoded (if possible), and zero suggests that */ | |
52 | + /* it be forced to lowercase (if possible). ASCII code points */ | |
53 | + /* are encoded literally, except that ASCII letters are forced */ | |
54 | + /* to uppercase or lowercase according to the corresponding */ | |
55 | + /* uppercase flags. If case_flags is a null pointer then ASCII */ | |
56 | + /* letters are left as they are, and other code points are */ | |
57 | + /* treated as if their uppercase flags were zero. The return */ | |
58 | + /* value can be any of the punycode_status values defined above */ | |
59 | + /* except punycode_bad_input; if not punycode_success, then */ | |
60 | + /* output_size and output might contain garbage. */ | |
61 | + | |
62 | +enum punycode_status punycode_decode( | |
63 | + punycode_uint input_length, | |
64 | + const char input[], | |
65 | + punycode_uint *output_length, | |
66 | + punycode_uint output[], | |
67 | + unsigned char case_flags[] ); | |
68 | + | |
69 | + /* punycode_decode() converts Punycode to Unicode. The input is */ | |
70 | + /* represented as an array of ASCII code points, and the output */ | |
71 | + /* will be represented as an array of Unicode code points. The */ | |
72 | + /* input_length is the number of code points in the input. The */ | |
73 | + /* output_length is an in/out argument: the caller passes in */ | |
74 | + /* the maximum number of code points that it can receive, and */ | |
75 | + /* on successful return it will contain the actual number of */ | |
76 | + /* code points output. The case_flags array needs room for at */ | |
77 | + /* least output_length values, or it can be a null pointer if the */ | |
78 | + /* case information is not needed. A nonzero flag suggests that */ | |
79 | + /* the corresponding Unicode character be forced to uppercase */ | |
80 | + /* by the caller (if possible), while zero suggests that it be */ | |
81 | + /* forced to lowercase (if possible). ASCII code points are */ | |
82 | + /* output already in the proper case, but their flags will be set */ | |
83 | + /* appropriately so that applying the flags would be harmless. */ | |
84 | + /* The return value can be any of the punycode_status values */ | |
85 | + /* defined above; if not punycode_success, then output_length, */ | |
86 | + /* output, and case_flags might contain garbage. On success, the */ | |
87 | + /* decoder will never need to write an output_length greater than */ | |
88 | + /* input_length, because of how the encoding is defined. */ | |
89 | + |
@@ -38,6 +38,8 @@ | ||
38 | 38 | |
39 | 39 | #include "common.h" |
40 | 40 | #include "resource.h" |
41 | +// UTF-8対応 | |
42 | +#include "punycode.h" | |
41 | 43 | |
42 | 44 | #define USE_THIS 1 |
43 | 45 | #define DBG_MSG 0 |
@@ -92,6 +94,8 @@ static int RegistAsyncTable(SOCKET s); | ||
92 | 94 | static int RegistAsyncTableDbase(HANDLE Async); |
93 | 95 | static int UnRegistAsyncTable(SOCKET s); |
94 | 96 | static int UnRegistAsyncTableDbase(HANDLE Async); |
97 | +// UTF-8対応 | |
98 | +static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen); | |
95 | 99 | |
96 | 100 | |
97 | 101 | /*===== 外部参照 =====*/ |
@@ -655,7 +659,9 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc | ||
655 | 659 | Ret = NULL; |
656 | 660 | *CancelCheckWork = NO; |
657 | 661 | |
658 | - hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); | |
662 | + // UTF-8対応 | |
663 | +// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); | |
664 | + hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); | |
659 | 665 | if(hAsync != NULL) |
660 | 666 | { |
661 | 667 | RegistAsyncTableDbase(hAsync); |
@@ -1159,3 +1165,124 @@ int CheckClosedAndReconnect(void) | ||
1159 | 1165 | |
1160 | 1166 | |
1161 | 1167 | |
1168 | +// UTF-8対応 | |
1169 | + | |
1170 | +static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input) | |
1171 | +{ | |
1172 | + BOOL bResult; | |
1173 | + punycode_uint* pUnicode; | |
1174 | + punycode_uint* p; | |
1175 | + BOOL bNeeded; | |
1176 | + LPCSTR InputString; | |
1177 | + punycode_uint Length; | |
1178 | + punycode_uint OutputLength; | |
1179 | + bResult = FALSE; | |
1180 | + if(pUnicode = malloc(sizeof(punycode_uint) * strlen(Input))) | |
1181 | + { | |
1182 | + p = pUnicode; | |
1183 | + bNeeded = FALSE; | |
1184 | + InputString = Input; | |
1185 | + Length = 0; | |
1186 | + while(*InputString != '\0') | |
1187 | + { | |
1188 | + *p = 0; | |
1189 | + if((*InputString & 0x80) == 0x00) | |
1190 | + *p |= (punycode_uint)*InputString & 0x7f; | |
1191 | + else if((*InputString & 0xe0) == 0xc0) | |
1192 | + *p |= (punycode_uint)*InputString & 0x1f; | |
1193 | + else if((*InputString & 0xf0) == 0xe0) | |
1194 | + *p |= (punycode_uint)*InputString & 0x0f; | |
1195 | + else if((*InputString & 0xf8) == 0xf0) | |
1196 | + *p |= (punycode_uint)*InputString & 0x07; | |
1197 | + else if((*InputString & 0xfc) == 0xf8) | |
1198 | + *p |= (punycode_uint)*InputString & 0x03; | |
1199 | + else if((*InputString & 0xfe) == 0xfc) | |
1200 | + *p |= (punycode_uint)*InputString & 0x01; | |
1201 | + InputString++; | |
1202 | + while((*InputString & 0xc0) == 0x80) | |
1203 | + { | |
1204 | + *p = *p << 6; | |
1205 | + *p |= (punycode_uint)*InputString & 0x3f; | |
1206 | + InputString++; | |
1207 | + } | |
1208 | + if(*p >= 0x80) | |
1209 | + bNeeded = TRUE; | |
1210 | + p++; | |
1211 | + Length++; | |
1212 | + } | |
1213 | + if(bNeeded) | |
1214 | + { | |
1215 | + if(Count >= strlen("xn--") + 1) | |
1216 | + { | |
1217 | + strcpy(Output, "xn--"); | |
1218 | + OutputLength = Count - strlen("xn--"); | |
1219 | + if(punycode_encode(Length, pUnicode, NULL, (punycode_uint*)&OutputLength, Output + strlen("xn--")) == punycode_success) | |
1220 | + { | |
1221 | + Output[strlen("xn--") + OutputLength] = '\0'; | |
1222 | + bResult = TRUE; | |
1223 | + } | |
1224 | + } | |
1225 | + } | |
1226 | + free(pUnicode); | |
1227 | + } | |
1228 | + if(!bResult) | |
1229 | + { | |
1230 | + if(Count >= strlen(Input) + 1) | |
1231 | + { | |
1232 | + strcpy(Output, Input); | |
1233 | + bResult = TRUE; | |
1234 | + } | |
1235 | + } | |
1236 | + return bResult; | |
1237 | +} | |
1238 | + | |
1239 | +static BOOL ConvertNameToPunycode(LPSTR Output, LPCSTR Input) | |
1240 | +{ | |
1241 | + BOOL bResult; | |
1242 | + DWORD Length; | |
1243 | + char* pm0; | |
1244 | + char* pm1; | |
1245 | + char* p; | |
1246 | + char* pNext; | |
1247 | + bResult = FALSE; | |
1248 | + Length = strlen(Input); | |
1249 | + if(pm0 = AllocateStringM(Length + 1)) | |
1250 | + { | |
1251 | + if(pm1 = AllocateStringM(Length * 4 + 1)) | |
1252 | + { | |
1253 | + strcpy(pm0, Input); | |
1254 | + p = pm0; | |
1255 | + while(p) | |
1256 | + { | |
1257 | + if(pNext = strchr(p, '.')) | |
1258 | + { | |
1259 | + *pNext = '\0'; | |
1260 | + pNext++; | |
1261 | + } | |
1262 | + if(ConvertStringToPunycode(pm1, Length * 4, p)) | |
1263 | + strcat(Output, pm1); | |
1264 | + if(pNext) | |
1265 | + strcat(Output, "."); | |
1266 | + p = pNext; | |
1267 | + } | |
1268 | + bResult = TRUE; | |
1269 | + FreeDuplicatedString(pm1); | |
1270 | + } | |
1271 | + FreeDuplicatedString(pm0); | |
1272 | + } | |
1273 | + return bResult; | |
1274 | +} | |
1275 | + | |
1276 | +static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen) | |
1277 | +{ | |
1278 | + HANDLE r = NULL; | |
1279 | + char* pa0 = NULL; | |
1280 | + if(pa0 = AllocateStringA(strlen(name) * 4)) | |
1281 | + { | |
1282 | + if(ConvertNameToPunycode(pa0, name)) | |
1283 | + r = WSAAsyncGetHostByName(hWnd, wMsg, pa0, buf, buflen); | |
1284 | + } | |
1285 | + FreeDuplicatedString(pa0); | |
1286 | + return r; | |
1287 | +} | |
1288 | + |