OSDN Git Service

Add support for encoding multi-byte domain name to Punycode.
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 21 Oct 2011 15:05:09 +0000 (00:05 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 21 Oct 2011 15:05:09 +0000 (00:05 +0900)
FFFTP.vc90.vcproj
FFFTP.vcproj
FFFTP_Eng_Release/FFFTP.exe
FFFTP_English.vc90.vcproj
FFFTP_English.vcproj
Release/FFFTP.exe
punycode.c [new file with mode: 0644]
punycode.h [new file with mode: 0644]
socket.c

index f9dee13..53eb2cb 100644 (file)
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\punycode.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
index 7aa2fed..eb47506 100644 (file)
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\punycode.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
index c273a94..5ddc897 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index 0895fd7..9d26882 100644 (file)
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\punycode.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
index 588ee1e..37259ff 100644 (file)
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\punycode.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
                                RelativePath=".\protectprocess.c"\r
                                >\r
                        </File>\r
index d195522..a27e6b4 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
diff --git a/punycode.c b/punycode.c
new file mode 100644 (file)
index 0000000..16a9df7
--- /dev/null
@@ -0,0 +1,346 @@
+/*\r
+punycode.c from RFC 3492\r
+http://www.nicemice.net/idn/\r
+Adam M. Costello\r
+http://www.nicemice.net/amc/\r
+\r
+This is ANSI C code (C89) implementing Punycode (RFC 3492).\r
+\r
+*/\r
+\r
+\r
+/************************************************************/\r
+/* Public interface (would normally go in its own .h file): */\r
+\r
+#include <limits.h>\r
+\r
+enum punycode_status {\r
+  punycode_success,\r
+  punycode_bad_input,   /* Input is invalid.                       */\r
+  punycode_big_output,  /* Output would exceed the space provided. */\r
+  punycode_overflow     /* Input needs wider integers to process.  */\r
+};\r
+\r
+#if UINT_MAX >= (1 << 26) - 1\r
+typedef unsigned int punycode_uint;\r
+#else\r
+typedef unsigned long punycode_uint;\r
+#endif\r
+\r
+enum punycode_status punycode_encode(\r
+  punycode_uint input_length,\r
+  const punycode_uint input[],\r
+  const unsigned char case_flags[],\r
+  punycode_uint *output_length,\r
+  char output[] );\r
+\r
+    /* punycode_encode() converts Unicode to Punycode.  The input     */\r
+    /* is represented as an array of Unicode code points (not code    */\r
+    /* units; surrogate pairs are not allowed), and the output        */\r
+    /* will be represented as an array of ASCII code points.  The     */\r
+    /* output string is *not* null-terminated; it will contain        */\r
+    /* zeros if and only if the input contains zeros.  (Of course     */\r
+    /* the caller can leave room for a terminator and add one if      */\r
+    /* needed.)  The input_length is the number of code points in     */\r
+    /* the input.  The output_length is an in/out argument: the       */\r
+    /* caller passes in the maximum number of code points that it     */\r
+    /* can receive, and on successful return it will contain the      */\r
+    /* number of code points actually output.  The case_flags array   */\r
+    /* holds input_length boolean values, where nonzero suggests that */\r
+    /* the corresponding Unicode character be forced to uppercase     */\r
+    /* after being decoded (if possible), and zero suggests that      */\r
+    /* it be forced to lowercase (if possible).  ASCII code points    */\r
+    /* are encoded literally, except that ASCII letters are forced    */\r
+    /* to uppercase or lowercase according to the corresponding       */\r
+    /* uppercase flags.  If case_flags is a null pointer then ASCII   */\r
+    /* letters are left as they are, and other code points are        */\r
+    /* treated as if their uppercase flags were zero.  The return     */\r
+    /* value can be any of the punycode_status values defined above   */\r
+    /* except punycode_bad_input; if not punycode_success, then       */\r
+    /* output_size and output might contain garbage.                  */\r
+\r
+enum punycode_status punycode_decode(\r
+  punycode_uint input_length,\r
+  const char input[],\r
+  punycode_uint *output_length,\r
+  punycode_uint output[],\r
+  unsigned char case_flags[] );\r
+\r
+    /* punycode_decode() converts Punycode to Unicode.  The input is  */\r
+    /* represented as an array of ASCII code points, and the output   */\r
+    /* will be represented as an array of Unicode code points.  The   */\r
+    /* input_length is the number of code points in the input.  The   */\r
+    /* output_length is an in/out argument: the caller passes in      */\r
+    /* the maximum number of code points that it can receive, and     */\r
+    /* on successful return it will contain the actual number of      */\r
+    /* code points output.  The case_flags array needs room for at    */\r
+    /* least output_length values, or it can be a null pointer if the */\r
+    /* case information is not needed.  A nonzero flag suggests that  */\r
+    /* the corresponding Unicode character be forced to uppercase     */\r
+    /* by the caller (if possible), while zero suggests that it be    */\r
+    /* forced to lowercase (if possible).  ASCII code points are      */\r
+    /* output already in the proper case, but their flags will be set */\r
+    /* appropriately so that applying the flags would be harmless.    */\r
+    /* The return value can be any of the punycode_status values      */\r
+    /* defined above; if not punycode_success, then output_length,    */\r
+    /* output, and case_flags might contain garbage.  On success, the */\r
+    /* decoder will never need to write an output_length greater than */\r
+    /* input_length, because of how the encoding is defined.          */\r
+\r
+/**********************************************************/\r
+/* Implementation (would normally go in its own .c file): */\r
+\r
+#include <string.h>\r
+\r
+/*** Bootstring parameters for Punycode ***/\r
+\r
+enum { base = 36, tmin = 1, tmax = 26, skew = 38, damp = 700,\r
+       initial_bias = 72, initial_n = 0x80, delimiter = 0x2D };\r
+\r
+/* basic(cp) tests whether cp is a basic code point: */\r
+#define basic(cp) ((punycode_uint)(cp) < 0x80)\r
+\r
+/* delim(cp) tests whether cp is a delimiter: */\r
+#define delim(cp) ((cp) == delimiter)\r
+\r
+/* decode_digit(cp) returns the numeric value of a basic code */\r
+/* point (for use in representing integers) in the range 0 to */\r
+/* base-1, or base if cp is does not represent a value.       */\r
+\r
+static punycode_uint decode_digit(punycode_uint cp)\r
+{\r
+  return  cp - 48 < 10 ? cp - 22 :  cp - 65 < 26 ? cp - 65 :\r
+          cp - 97 < 26 ? cp - 97 :  base;\r
+}\r
+\r
+/* encode_digit(d,flag) returns the basic code point whose value      */\r
+/* (when used for representing integers) is d, which needs to be in   */\r
+/* the range 0 to base-1.  The lowercase form is used unless flag is  */\r
+/* nonzero, in which case the uppercase form is used.  The behavior   */\r
+/* is undefined if flag is nonzero and digit d has no uppercase form. */\r
+\r
+static char encode_digit(punycode_uint d, int flag)\r
+{\r
+  return d + 22 + 75 * (d < 26) - ((flag != 0) << 5);\r
+  /*  0..25 map to ASCII a..z or A..Z */\r
+  /* 26..35 map to ASCII 0..9         */\r
+}\r
+\r
+/* flagged(bcp) tests whether a basic code point is flagged */\r
+/* (uppercase).  The behavior is undefined if bcp is not a  */\r
+/* basic code point.                                        */\r
+\r
+#define flagged(bcp) ((punycode_uint)(bcp) - 65 < 26)\r
+\r
+/* encode_basic(bcp,flag) forces a basic code point to lowercase */\r
+/* if flag is zero, uppercase if flag is nonzero, and returns    */\r
+/* the resulting code point.  The code point is unchanged if it  */\r
+/* is caseless.  The behavior is undefined if bcp is not a basic */\r
+/* code point.                                                   */\r
+\r
+static char encode_basic(punycode_uint bcp, int flag)\r
+{\r
+  bcp -= (bcp - 97 < 26) << 5;\r
+  return bcp + ((!flag && (bcp - 65 < 26)) << 5);\r
+}\r
+\r
+/*** Platform-specific constants ***/\r
+\r
+/* maxint is the maximum value of a punycode_uint variable: */\r
+static const punycode_uint maxint = -1;\r
+/* Because maxint is unsigned, -1 becomes the maximum value. */\r
+\r
+/*** Bias adaptation function ***/\r
+\r
+static punycode_uint adapt(\r
+  punycode_uint delta, punycode_uint numpoints, int firsttime )\r
+{\r
+  punycode_uint k;\r
+\r
+  delta = firsttime ? delta / damp : delta >> 1;\r
+  /* delta >> 1 is a faster way of doing delta / 2 */\r
+  delta += delta / numpoints;\r
+\r
+  for (k = 0;  delta > ((base - tmin) * tmax) / 2;  k += base) {\r
+    delta /= base - tmin;\r
+  }\r
+\r
+  return k + (base - tmin + 1) * delta / (delta + skew);\r
+}\r
+\r
+/*** Main encode function ***/\r
+\r
+enum punycode_status punycode_encode(\r
+  punycode_uint input_length,\r
+  const punycode_uint input[],\r
+  const unsigned char case_flags[],\r
+  punycode_uint *output_length,\r
+  char output[] )\r
+{\r
+  punycode_uint n, delta, h, b, out, max_out, bias, j, m, q, k, t;\r
+\r
+  /* Initialize the state: */\r
+\r
+  n = initial_n;\r
+  delta = out = 0;\r
+  max_out = *output_length;\r
+  bias = initial_bias;\r
+\r
+  /* Handle the basic code points: */\r
+\r
+  for (j = 0;  j < input_length;  ++j) {\r
+    if (basic(input[j])) {\r
+      if (max_out - out < 2) return punycode_big_output;\r
+      output[out++] =\r
+        case_flags ?  encode_basic(input[j], case_flags[j]) : input[j];\r
+    }\r
+    /* else if (input[j] < n) return punycode_bad_input; */\r
+    /* (not needed for Punycode with unsigned code points) */\r
+  }\r
+\r
+  h = b = out;\r
+\r
+  /* h is the number of code points that have been handled, b is the  */\r
+  /* number of basic code points, and out is the number of characters */\r
+  /* that have been output.                                           */\r
+\r
+  if (b > 0) output[out++] = delimiter;\r
+\r
+  /* Main encoding loop: */\r
+\r
+  while (h < input_length) {\r
+    /* All non-basic code points < n have been     */\r
+    /* handled already.  Find the next larger one: */\r
+\r
+    for (m = maxint, j = 0;  j < input_length;  ++j) {\r
+      /* if (basic(input[j])) continue; */\r
+      /* (not needed for Punycode) */\r
+      if (input[j] >= n && input[j] < m) m = input[j];\r
+    }\r
+\r
+    /* Increase delta enough to advance the decoder's    */\r
+    /* <n,i> state to <m,0>, but guard against overflow: */\r
+\r
+    if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow;\r
+    delta += (m - n) * (h + 1);\r
+    n = m;\r
+\r
+    for (j = 0;  j < input_length;  ++j) {\r
+      /* Punycode does not need to check whether input[j] is basic: */\r
+      if (input[j] < n /* || basic(input[j]) */ ) {\r
+        if (++delta == 0) return punycode_overflow;\r
+      }\r
+\r
+      if (input[j] == n) {\r
+        /* Represent delta as a generalized variable-length integer: */\r
+\r
+        for (q = delta, k = base;  ;  k += base) {\r
+          if (out >= max_out) return punycode_big_output;\r
+          t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */\r
+              k >= bias + tmax ? tmax : k - bias;\r
+          if (q < t) break;\r
+          output[out++] = encode_digit(t + (q - t) % (base - t), 0);\r
+          q = (q - t) / (base - t);\r
+        }\r
+\r
+        output[out++] = encode_digit(q, case_flags && case_flags[j]);\r
+        bias = adapt(delta, h + 1, h == b);\r
+        delta = 0;\r
+        ++h;\r
+      }\r
+    }\r
+\r
+    ++delta, ++n;\r
+  }\r
+\r
+  *output_length = out;\r
+  return punycode_success;\r
+}\r
+\r
+/*** Main decode function ***/\r
+\r
+enum punycode_status punycode_decode(\r
+  punycode_uint input_length,\r
+  const char input[],\r
+  punycode_uint *output_length,\r
+  punycode_uint output[],\r
+  unsigned char case_flags[] )\r
+{\r
+  punycode_uint n, out, i, max_out, bias,\r
+                 b, j, in, oldi, w, k, digit, t;\r
+\r
+  /* Initialize the state: */\r
+\r
+  n = initial_n;\r
+  out = i = 0;\r
+  max_out = *output_length;\r
+  bias = initial_bias;\r
+\r
+  /* Handle the basic code points:  Let b be the number of input code */\r
+  /* points before the last delimiter, or 0 if there is none, then    */\r
+  /* copy the first b code points to the output.                      */\r
+\r
+  for (b = j = 0;  j < input_length;  ++j) if (delim(input[j])) b = j;\r
+  if (b > max_out) return punycode_big_output;\r
+\r
+  for (j = 0;  j < b;  ++j) {\r
+    if (case_flags) case_flags[out] = flagged(input[j]);\r
+    if (!basic(input[j])) return punycode_bad_input;\r
+    output[out++] = input[j];\r
+  }\r
+\r
+  /* Main decoding loop:  Start just after the last delimiter if any  */\r
+  /* basic code points were copied; start at the beginning otherwise. */\r
+\r
+  for (in = b > 0 ? b + 1 : 0;  in < input_length;  ++out) {\r
+\r
+    /* in is the index of the next character to be consumed, and */\r
+    /* out is the number of code points in the output array.     */\r
+\r
+    /* Decode a generalized variable-length integer into delta,  */\r
+    /* which gets added to i.  The overflow checking is easier   */\r
+    /* if we increase i as we go, then subtract off its starting */\r
+    /* value at the end to obtain delta.                         */\r
+\r
+    for (oldi = i, w = 1, k = base;  ;  k += base) {\r
+      if (in >= input_length) return punycode_bad_input;\r
+      digit = decode_digit(input[in++]);\r
+      if (digit >= base) return punycode_bad_input;\r
+      if (digit > (maxint - i) / w) return punycode_overflow;\r
+      i += digit * w;\r
+      t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */\r
+          k >= bias + tmax ? tmax : k - bias;\r
+      if (digit < t) break;\r
+      if (w > maxint / (base - t)) return punycode_overflow;\r
+      w *= (base - t);\r
+    }\r
+\r
+    bias = adapt(i - oldi, out + 1, oldi == 0);\r
+\r
+    /* i was supposed to wrap around from out+1 to 0,   */\r
+    /* incrementing n each time, so we'll fix that now: */\r
+\r
+    if (i / (out + 1) > maxint - n) return punycode_overflow;\r
+    n += i / (out + 1);\r
+    i %= (out + 1);\r
+\r
+    /* Insert n at position i of the output: */\r
+\r
+    /* not needed for Punycode: */\r
+    /* if (decode_digit(n) <= base) return punycode_invalid_input; */\r
+    if (out >= max_out) return punycode_big_output;\r
+\r
+    if (case_flags) {\r
+      memmove(case_flags + i + 1, case_flags + i, out - i);\r
+      /* Case of last character determines uppercase flag: */\r
+      case_flags[i] = flagged(input[in - 1]);\r
+    }\r
+\r
+    memmove(output + i + 1, output + i, (out - i) * sizeof *output);\r
+    output[i++] = n;\r
+  }\r
+\r
+  *output_length = out;\r
+  return punycode_success;\r
+}\r
+\r
diff --git a/punycode.h b/punycode.h
new file mode 100644 (file)
index 0000000..8343918
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+punycode.c from RFC 3492\r
+http://www.nicemice.net/idn/\r
+Adam M. Costello\r
+http://www.nicemice.net/amc/\r
+\r
+This is ANSI C code (C89) implementing Punycode (RFC 3492).\r
+\r
+*/\r
+\r
+\r
+/************************************************************/\r
+/* Public interface (would normally go in its own .h file): */\r
+\r
+#include <limits.h>\r
+\r
+enum punycode_status {\r
+  punycode_success,\r
+  punycode_bad_input,   /* Input is invalid.                       */\r
+  punycode_big_output,  /* Output would exceed the space provided. */\r
+  punycode_overflow     /* Input needs wider integers to process.  */\r
+};\r
+\r
+#if UINT_MAX >= (1 << 26) - 1\r
+typedef unsigned int punycode_uint;\r
+#else\r
+typedef unsigned long punycode_uint;\r
+#endif\r
+\r
+enum punycode_status punycode_encode(\r
+  punycode_uint input_length,\r
+  const punycode_uint input[],\r
+  const unsigned char case_flags[],\r
+  punycode_uint *output_length,\r
+  char output[] );\r
+\r
+    /* punycode_encode() converts Unicode to Punycode.  The input     */\r
+    /* is represented as an array of Unicode code points (not code    */\r
+    /* units; surrogate pairs are not allowed), and the output        */\r
+    /* will be represented as an array of ASCII code points.  The     */\r
+    /* output string is *not* null-terminated; it will contain        */\r
+    /* zeros if and only if the input contains zeros.  (Of course     */\r
+    /* the caller can leave room for a terminator and add one if      */\r
+    /* needed.)  The input_length is the number of code points in     */\r
+    /* the input.  The output_length is an in/out argument: the       */\r
+    /* caller passes in the maximum number of code points that it     */\r
+    /* can receive, and on successful return it will contain the      */\r
+    /* number of code points actually output.  The case_flags array   */\r
+    /* holds input_length boolean values, where nonzero suggests that */\r
+    /* the corresponding Unicode character be forced to uppercase     */\r
+    /* after being decoded (if possible), and zero suggests that      */\r
+    /* it be forced to lowercase (if possible).  ASCII code points    */\r
+    /* are encoded literally, except that ASCII letters are forced    */\r
+    /* to uppercase or lowercase according to the corresponding       */\r
+    /* uppercase flags.  If case_flags is a null pointer then ASCII   */\r
+    /* letters are left as they are, and other code points are        */\r
+    /* treated as if their uppercase flags were zero.  The return     */\r
+    /* value can be any of the punycode_status values defined above   */\r
+    /* except punycode_bad_input; if not punycode_success, then       */\r
+    /* output_size and output might contain garbage.                  */\r
+\r
+enum punycode_status punycode_decode(\r
+  punycode_uint input_length,\r
+  const char input[],\r
+  punycode_uint *output_length,\r
+  punycode_uint output[],\r
+  unsigned char case_flags[] );\r
+\r
+    /* punycode_decode() converts Punycode to Unicode.  The input is  */\r
+    /* represented as an array of ASCII code points, and the output   */\r
+    /* will be represented as an array of Unicode code points.  The   */\r
+    /* input_length is the number of code points in the input.  The   */\r
+    /* output_length is an in/out argument: the caller passes in      */\r
+    /* the maximum number of code points that it can receive, and     */\r
+    /* on successful return it will contain the actual number of      */\r
+    /* code points output.  The case_flags array needs room for at    */\r
+    /* least output_length values, or it can be a null pointer if the */\r
+    /* case information is not needed.  A nonzero flag suggests that  */\r
+    /* the corresponding Unicode character be forced to uppercase     */\r
+    /* by the caller (if possible), while zero suggests that it be    */\r
+    /* forced to lowercase (if possible).  ASCII code points are      */\r
+    /* output already in the proper case, but their flags will be set */\r
+    /* appropriately so that applying the flags would be harmless.    */\r
+    /* The return value can be any of the punycode_status values      */\r
+    /* defined above; if not punycode_success, then output_length,    */\r
+    /* output, and case_flags might contain garbage.  On success, the */\r
+    /* decoder will never need to write an output_length greater than */\r
+    /* input_length, because of how the encoding is defined.          */\r
+\r
index 8773978..7d76f67 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -38,6 +38,8 @@
 \r
 #include "common.h"\r
 #include "resource.h"\r
 \r
 #include "common.h"\r
 #include "resource.h"\r
+// UTF-8対応\r
+#include "punycode.h"\r
 \r
 #define USE_THIS       1\r
 #define DBG_MSG                0\r
 \r
 #define USE_THIS       1\r
 #define DBG_MSG                0\r
@@ -92,6 +94,8 @@ static int RegistAsyncTable(SOCKET s);
 static int RegistAsyncTableDbase(HANDLE Async);\r
 static int UnRegistAsyncTable(SOCKET s);\r
 static int UnRegistAsyncTableDbase(HANDLE Async);\r
 static int RegistAsyncTableDbase(HANDLE Async);\r
 static int UnRegistAsyncTable(SOCKET s);\r
 static int UnRegistAsyncTableDbase(HANDLE Async);\r
+// UTF-8対応\r
+static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen);\r
 \r
 \r
 /*===== 外部参照 =====*/\r
 \r
 \r
 /*===== 外部参照 =====*/\r
@@ -655,7 +659,9 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc
        Ret = NULL;\r
        *CancelCheckWork = NO;\r
 \r
        Ret = NULL;\r
        *CancelCheckWork = NO;\r
 \r
-       hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       // UTF-8対応\r
+//     hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+       hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
        if(hAsync != NULL)\r
        {\r
                RegistAsyncTableDbase(hAsync);\r
        if(hAsync != NULL)\r
        {\r
                RegistAsyncTableDbase(hAsync);\r
@@ -1159,3 +1165,124 @@ int CheckClosedAndReconnect(void)
 \r
 \r
 \r
 \r
 \r
 \r
+// UTF-8対応\r
+\r
+static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)\r
+{\r
+       BOOL bResult;\r
+       punycode_uint* pUnicode;\r
+       punycode_uint* p;\r
+       BOOL bNeeded;\r
+       LPCSTR InputString;\r
+       punycode_uint Length;\r
+       punycode_uint OutputLength;\r
+       bResult = FALSE;\r
+       if(pUnicode = malloc(sizeof(punycode_uint) * strlen(Input)))\r
+       {\r
+               p = pUnicode;\r
+               bNeeded = FALSE;\r
+               InputString = Input;\r
+               Length = 0;\r
+               while(*InputString != '\0')\r
+               {\r
+                       *p = 0;\r
+                       if((*InputString & 0x80) == 0x00)\r
+                               *p |= (punycode_uint)*InputString & 0x7f;\r
+                       else if((*InputString & 0xe0) == 0xc0)\r
+                               *p |= (punycode_uint)*InputString & 0x1f;\r
+                       else if((*InputString & 0xf0) == 0xe0)\r
+                               *p |= (punycode_uint)*InputString & 0x0f;\r
+                       else if((*InputString & 0xf8) == 0xf0)\r
+                               *p |= (punycode_uint)*InputString & 0x07;\r
+                       else if((*InputString & 0xfc) == 0xf8)\r
+                               *p |= (punycode_uint)*InputString & 0x03;\r
+                       else if((*InputString & 0xfe) == 0xfc)\r
+                               *p |= (punycode_uint)*InputString & 0x01;\r
+                       InputString++;\r
+                       while((*InputString & 0xc0) == 0x80)\r
+                       {\r
+                               *p = *p << 6;\r
+                               *p |= (punycode_uint)*InputString & 0x3f;\r
+                               InputString++;\r
+                       }\r
+                       if(*p >= 0x80)\r
+                               bNeeded = TRUE;\r
+                       p++;\r
+                       Length++;\r
+               }\r
+               if(bNeeded)\r
+               {\r
+                       if(Count >= strlen("xn--") + 1)\r
+                       {\r
+                               strcpy(Output, "xn--");\r
+                               OutputLength = Count - strlen("xn--");\r
+                               if(punycode_encode(Length, pUnicode, NULL, (punycode_uint*)&OutputLength, Output + strlen("xn--")) == punycode_success)\r
+                               {\r
+                                       Output[strlen("xn--") + OutputLength] = '\0';\r
+                                       bResult = TRUE;\r
+                               }\r
+                       }\r
+               }\r
+               free(pUnicode);\r
+       }\r
+       if(!bResult)\r
+       {\r
+               if(Count >= strlen(Input) + 1)\r
+               {\r
+                       strcpy(Output, Input);\r
+                       bResult = TRUE;\r
+               }\r
+       }\r
+       return bResult;\r
+}\r
+\r
+static BOOL ConvertNameToPunycode(LPSTR Output, LPCSTR Input)\r
+{\r
+       BOOL bResult;\r
+       DWORD Length;\r
+       char* pm0;\r
+       char* pm1;\r
+       char* p;\r
+       char* pNext;\r
+       bResult = FALSE;\r
+       Length = strlen(Input);\r
+       if(pm0 = AllocateStringM(Length + 1))\r
+       {\r
+               if(pm1 = AllocateStringM(Length * 4 + 1))\r
+               {\r
+                       strcpy(pm0, Input);\r
+                       p = pm0;\r
+                       while(p)\r
+                       {\r
+                               if(pNext = strchr(p, '.'))\r
+                               {\r
+                                       *pNext = '\0';\r
+                                       pNext++;\r
+                               }\r
+                               if(ConvertStringToPunycode(pm1, Length * 4, p))\r
+                                       strcat(Output, pm1);\r
+                               if(pNext)\r
+                                       strcat(Output, ".");\r
+                               p = pNext;\r
+                       }\r
+                       bResult = TRUE;\r
+                       FreeDuplicatedString(pm1);\r
+               }\r
+               FreeDuplicatedString(pm0);\r
+       }\r
+       return bResult;\r
+}\r
+\r
+static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen)\r
+{\r
+       HANDLE r = NULL;\r
+       char* pa0 = NULL;\r
+       if(pa0 = AllocateStringA(strlen(name) * 4))\r
+       {\r
+               if(ConvertNameToPunycode(pa0, name))\r
+                       r = WSAAsyncGetHostByName(hWnd, wMsg, pa0, buf, buflen);\r
+       }\r
+       FreeDuplicatedString(pa0);\r
+       return r;\r
+}\r
+\r