Jeff пре 5 година
родитељ
комит
1f7db7dd20
100 измењених фајлова са 26296 додато и 0 уклоњено
  1. 39 0
      TCL Copy Tool/Include/curl/Makefile.am
  2. 694 0
      TCL Copy Tool/Include/curl/Makefile.in
  3. 2864 0
      TCL Copy Tool/Include/curl/curl.h
  4. 77 0
      TCL Copy Tool/Include/curl/curlver.h
  5. 112 0
      TCL Copy Tool/Include/curl/easy.h
  6. 50 0
      TCL Copy Tool/Include/curl/mprintf.h
  7. 441 0
      TCL Copy Tool/Include/curl/multi.h
  8. 33 0
      TCL Copy Tool/Include/curl/stdcheaders.h
  9. 493 0
      TCL Copy Tool/Include/curl/system.h
  10. 700 0
      TCL Copy Tool/Include/curl/typecheck-gcc.h
  11. 122 0
      TCL Copy Tool/Include/curl/urlapi.h
  12. 1 0
      TCL Copy Tool/Licence.txt
  13. 376 0
      TCL Copy Tool/Log4C/GlobalMacro.h
  14. 479 0
      TCL Copy Tool/Log4C/Log4C.vcproj
  15. 3 0
      TCL Copy Tool/Log4C/log4c.def
  16. 27 0
      TCL Copy Tool/Log4C/log4c.h
  17. 251 0
      TCL Copy Tool/Log4C/log4c/appender.h
  18. 71 0
      TCL Copy Tool/Log4C/log4c/appender_typ_stream.h
  19. 58 0
      TCL Copy Tool/Log4C/log4c/appender_type_mmap.h
  20. 120 0
      TCL Copy Tool/Log4C/log4c/appender_type_rollingfile.h
  21. 67 0
      TCL Copy Tool/Log4C/log4c/appender_type_stream.h
  22. 130 0
      TCL Copy Tool/Log4C/log4c/appender_type_stream2.h
  23. 56 0
      TCL Copy Tool/Log4C/log4c/appender_type_syslog.h
  24. 46 0
      TCL Copy Tool/Log4C/log4c/buffer.h
  25. 651 0
      TCL Copy Tool/Log4C/log4c/category.h
  26. 41 0
      TCL Copy Tool/Log4C/log4c/config-win32.h
  27. 26 0
      TCL Copy Tool/Log4C/log4c/config.h
  28. 46 0
      TCL Copy Tool/Log4C/log4c/defs.h
  29. 65 0
      TCL Copy Tool/Log4C/log4c/init.h
  30. 204 0
      TCL Copy Tool/Log4C/log4c/layout.h
  31. 38 0
      TCL Copy Tool/Log4C/log4c/layout_type_basic.h
  32. 42 0
      TCL Copy Tool/Log4C/log4c/layout_type_basic_r.h
  33. 43 0
      TCL Copy Tool/Log4C/log4c/layout_type_dated.h
  34. 45 0
      TCL Copy Tool/Log4C/log4c/layout_type_dated_r.h
  35. 45 0
      TCL Copy Tool/Log4C/log4c/layout_type_dated_threadid.h
  36. 73 0
      TCL Copy Tool/Log4C/log4c/location_info.h
  37. 553 0
      TCL Copy Tool/Log4C/log4c/log.h
  38. 89 0
      TCL Copy Tool/Log4C/log4c/logging_event.h
  39. 56 0
      TCL Copy Tool/Log4C/log4c/priority.h
  40. 70 0
      TCL Copy Tool/Log4C/log4c/rc.h
  41. 215 0
      TCL Copy Tool/Log4C/log4c/rollingpolicy.h
  42. 86 0
      TCL Copy Tool/Log4C/log4c/rollingpolicy_type_sizewin.h
  43. 40 0
      TCL Copy Tool/Log4C/log4c/sharedmemory.h
  44. 57 0
      TCL Copy Tool/Log4C/log4c/version.h
  45. 676 0
      TCL Copy Tool/Log4C/log4c/vos.h
  46. 238 0
      TCL Copy Tool/Log4C/log4c/voscfg.h
  47. 19 0
      TCL Copy Tool/Log4C/sd/defs.h
  48. 21 0
      TCL Copy Tool/Log4C/sd/domnode-xml-parser.h
  49. 882 0
      TCL Copy Tool/Log4C/sd/domnode-xml-scanner.h
  50. 33 0
      TCL Copy Tool/Log4C/sd/domnode-xml.h
  51. 65 0
      TCL Copy Tool/Log4C/sd/domnode.h
  52. 16 0
      TCL Copy Tool/Log4C/sd/error.h
  53. 1014 0
      TCL Copy Tool/Log4C/sd/expat.h
  54. 115 0
      TCL Copy Tool/Log4C/sd/expat_external.h
  55. 43 0
      TCL Copy Tool/Log4C/sd/factory.h
  56. 166 0
      TCL Copy Tool/Log4C/sd/hash.h
  57. 190 0
      TCL Copy Tool/Log4C/sd/list.h
  58. 43 0
      TCL Copy Tool/Log4C/sd/malloc.h
  59. 137 0
      TCL Copy Tool/Log4C/sd/sd_xplatform.h
  60. 59 0
      TCL Copy Tool/Log4C/sd/sprintf.h
  61. 41 0
      TCL Copy Tool/Log4C/sd/stack.h
  62. 139 0
      TCL Copy Tool/Setup.nsi
  63. 43 0
      TCL Copy Tool/TCL Copy Tool.sln
  64. 130 0
      TCL Copy Tool/TCL Copy Tool/Base64.cpp
  65. 70 0
      TCL Copy Tool/TCL Copy Tool/Base64.h
  66. 235 0
      TCL Copy Tool/TCL Copy Tool/CharConvert.cpp
  67. 22 0
      TCL Copy Tool/TCL Copy Tool/CharConvert.h
  68. 739 0
      TCL Copy Tool/TCL Copy Tool/CharEncoding.cpp
  69. 97 0
      TCL Copy Tool/TCL Copy Tool/CharEncoding.h
  70. 306 0
      TCL Copy Tool/TCL Copy Tool/ChassisConfigDlg.cpp
  71. 48 0
      TCL Copy Tool/TCL Copy Tool/ChassisConfigDlg.h
  72. 202 0
      TCL Copy Tool/TCL Copy Tool/Config.json
  73. 84 0
      TCL Copy Tool/TCL Copy Tool/CritSection.h
  74. 555 0
      TCL Copy Tool/TCL Copy Tool/CurlClient.cpp
  75. 88 0
      TCL Copy Tool/TCL Copy Tool/CurlClient.h
  76. 836 0
      TCL Copy Tool/TCL Copy Tool/Global.cpp
  77. 300 0
      TCL Copy Tool/TCL Copy Tool/Global.h
  78. 1999 0
      TCL Copy Tool/TCL Copy Tool/OTA.cpp
  79. 244 0
      TCL Copy Tool/TCL Copy Tool/OTA.h
  80. 990 0
      TCL Copy Tool/TCL Copy Tool/SerialPort.cpp
  81. 168 0
      TCL Copy Tool/TCL Copy Tool/SerialPort.h
  82. 156 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.cpp
  83. 32 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.h
  84. 478 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.vcxproj
  85. 217 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.vcxproj.filters
  86. 3611 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy ToolDlg.cpp
  87. 344 0
      TCL Copy Tool/TCL Copy Tool/TCL Copy ToolDlg.h
  88. BIN
      TCL Copy Tool/TCL Copy Tool/TCLCopyTool.rc
  89. 34 0
      TCL Copy Tool/TCL Copy Tool/VerificationCodeDlg.cpp
  90. 23 0
      TCL Copy Tool/TCL Copy Tool/VerificationCodeDlg.h
  91. 49 0
      TCL Copy Tool/TCL Copy Tool/framework.h
  92. 27 0
      TCL Copy Tool/TCL Copy Tool/log4c.h
  93. 8 0
      TCL Copy Tool/TCL Copy Tool/pch.cpp
  94. 44 0
      TCL Copy Tool/TCL Copy Tool/pch.h
  95. BIN
      TCL Copy Tool/TCL Copy Tool/res/TCL Copy Tool.ico
  96. BIN
      TCL Copy Tool/TCL Copy Tool/res/TCL Copy Tool2.ico
  97. BIN
      TCL Copy Tool/TCL Copy Tool/res/TCLCopyTool.rc2
  98. 158 0
      TCL Copy Tool/TCL Copy Tool/resource.h
  99. 259 0
      TCL Copy Tool/TCL Copy Tool/stdint.h
  100. 8 0
      TCL Copy Tool/TCL Copy Tool/targetver.h

+ 39 - 0
TCL Copy Tool/Include/curl/Makefile.am

@@ -0,0 +1,39 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+pkginclude_HEADERS = \
+  curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
+  typecheck-gcc.h system.h urlapi.h
+
+pkgincludedir= $(includedir)/curl
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo "  RUN     " $@;
+CS_1 =
+CS_ = $(CS_0)
+
+checksrc:
+	$(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
+
+if CURLDEBUG
+# for debug builds, we scan the sources on all regular make invokes
+all-local: checksrc
+endif

+ 694 - 0
TCL Copy Tool/Include/curl/Makefile.in

@@ -0,0 +1,694 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include/curl
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \
+	$(top_srcdir)/m4/curl-compilers.m4 \
+	$(top_srcdir)/m4/curl-confopts.m4 \
+	$(top_srcdir)/m4/curl-functions.m4 \
+	$(top_srcdir)/m4/curl-openssl.m4 \
+	$(top_srcdir)/m4/curl-override.m4 \
+	$(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/xc-am-iface.m4 \
+	$(top_srcdir)/m4/xc-cc-check.m4 \
+	$(top_srcdir)/m4/xc-lt-iface.m4 \
+	$(top_srcdir)/m4/xc-translit.m4 \
+	$(top_srcdir)/m4/xc-val-flgs.m4 \
+	$(top_srcdir)/m4/zz40-xc-ovr.m4 \
+	$(top_srcdir)/m4/zz50-xc-ovr.m4 \
+	$(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
+	$(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/lib/curl_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgincludedir)"
+HEADERS = $(pkginclude_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgincludedir = $(includedir)/curl
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AR_FLAGS = @AR_FLAGS@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
+CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@
+CURLVERSION = @CURLVERSION@
+CURL_CA_BUNDLE = @CURL_CA_BUNDLE@
+CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@
+CURL_DISABLE_DICT = @CURL_DISABLE_DICT@
+CURL_DISABLE_FILE = @CURL_DISABLE_FILE@
+CURL_DISABLE_FTP = @CURL_DISABLE_FTP@
+CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@
+CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@
+CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@
+CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@
+CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@
+CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@
+CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@
+CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@
+CURL_DISABLE_SMB = @CURL_DISABLE_SMB@
+CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@
+CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@
+CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@
+CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@
+CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@
+CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@
+CURL_WITH_MULTI_SSL = @CURL_WITH_MULTI_SSL@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_SSL_BACKEND = @DEFAULT_SSL_BACKEND@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_SHARED = @ENABLE_SHARED@
+ENABLE_STATIC = @ENABLE_STATIC@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@
+GCOV = @GCOV@
+GREP = @GREP@
+HAVE_BROTLI = @HAVE_BROTLI@
+HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@
+HAVE_LDAP_SSL = @HAVE_LDAP_SSL@
+HAVE_LIBZ = @HAVE_LIBZ@
+HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@
+HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@
+IDN_ENABLED = @IDN_ENABLED@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPV6_ENABLED = @IPV6_ENABLED@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@
+LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@
+LIBMETALINK_LIBS = @LIBMETALINK_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MANOPT = @MANOPT@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NROFF = @NROFF@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKGADD_NAME = @PKGADD_NAME@
+PKGADD_PKG = @PKGADD_PKG@
+PKGADD_VENDOR = @PKGADD_VENDOR@
+PKGCONFIG = @PKGCONFIG@
+RANDOM_FILE = @RANDOM_FILE@
+RANLIB = @RANLIB@
+REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SSL_BACKENDS = @SSL_BACKENDS@
+SSL_ENABLED = @SSL_ENABLED@
+SSL_LIBS = @SSL_LIBS@
+STRIP = @STRIP@
+SUPPORT_FEATURES = @SUPPORT_FEATURES@
+SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@
+USE_ARES = @USE_ARES@
+USE_CYASSL = @USE_CYASSL@
+USE_GNUTLS = @USE_GNUTLS@
+USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@
+USE_LIBRTMP = @USE_LIBRTMP@
+USE_LIBSSH = @USE_LIBSSH@
+USE_LIBSSH2 = @USE_LIBSSH2@
+USE_MBEDTLS = @USE_MBEDTLS@
+USE_MESALINK = @USE_MESALINK@
+USE_NGHTTP2 = @USE_NGHTTP2@
+USE_NSS = @USE_NSS@
+USE_OPENLDAP = @USE_OPENLDAP@
+USE_POLARSSL = @USE_POLARSSL@
+USE_SCHANNEL = @USE_SCHANNEL@
+USE_SECTRANSP = @USE_SECTRANSP@
+USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
+USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
+VERSION = @VERSION@
+VERSIONNUM = @VERSIONNUM@
+ZLIB_LIBS = @ZLIB_LIBS@
+ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libext = @libext@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+pkginclude_HEADERS = \
+  curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
+  typecheck-gcc.h system.h urlapi.h
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo "  RUN     " $@;
+CS_1 = 
+CS_ = $(CS_0)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/curl/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu include/curl/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+@CURLDEBUG_FALSE@all-local:
+all-am: Makefile $(HEADERS) all-local
+installdirs:
+	for dir in "$(DESTDIR)$(pkgincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkgincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \
+	clean-generic clean-libtool cscopelist-am ctags ctags-am \
+	distclean distclean-generic distclean-libtool distclean-tags \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-pkgincludeHEADERS \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pkgincludeHEADERS
+
+.PRECIOUS: Makefile
+
+
+checksrc:
+	$(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS)
+
+# for debug builds, we scan the sources on all regular make invokes
+@CURLDEBUG_TRUE@all-local: checksrc
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

+ 2864 - 0
TCL Copy Tool/Include/curl/curl.h

@@ -0,0 +1,2864 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ *   https://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ *   https://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#ifdef CURL_NO_OLDIES
+#define CURL_STRICTER
+#endif
+
+#include "curlver.h"         /* libcurl version defines   */
+#include "system.h"          /* determine things run-time */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+     !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
+      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+   included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on systems that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+    defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+    defined(__CYGWIN__) || \
+   (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+#include <sys/socket.h>
+#endif
+
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+/* Compatibility for non-Clang compilers */
+#ifndef __has_declspec_attribute
+#  define __has_declspec_attribute(x) 0
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_easy CURL;
+typedef struct Curl_share CURLSH;
+#else
+typedef void CURL;
+typedef void CURLSH;
+#endif
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+#  define CURL_EXTERN
+#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) || \
+     (__has_declspec_attribute(dllexport) && \
+      __has_declspec_attribute(dllimport))
+#  if defined(BUILDING_LIBCURL)
+#    define CURL_EXTERN  __declspec(dllexport)
+#  else
+#    define CURL_EXTERN  __declspec(dllimport)
+#  endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+#  define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#  define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+/* enum for the different supported SSL backends */
+typedef enum {
+  CURLSSLBACKEND_NONE = 0,
+  CURLSSLBACKEND_OPENSSL = 1,
+  CURLSSLBACKEND_GNUTLS = 2,
+  CURLSSLBACKEND_NSS = 3,
+  CURLSSLBACKEND_OBSOLETE4 = 4,  /* Was QSOSSL. */
+  CURLSSLBACKEND_GSKIT = 5,
+  CURLSSLBACKEND_POLARSSL = 6,
+  CURLSSLBACKEND_WOLFSSL = 7,
+  CURLSSLBACKEND_SCHANNEL = 8,
+  CURLSSLBACKEND_SECURETRANSPORT = 9,
+  CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
+  CURLSSLBACKEND_MBEDTLS = 11,
+  CURLSSLBACKEND_MESALINK = 12
+} curl_sslbackend;
+
+/* aliases for library clones and renames */
+#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
+
+/* deprecated names: */
+#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
+#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
+
+struct curl_httppost {
+  struct curl_httppost *next;       /* next entry in the list */
+  char *name;                       /* pointer to allocated name */
+  long namelength;                  /* length of name length */
+  char *contents;                   /* pointer to allocated data contents */
+  long contentslength;              /* length of contents field, see also
+                                       CURL_HTTPPOST_LARGE */
+  char *buffer;                     /* pointer to allocated buffer contents */
+  long bufferlength;                /* length of buffer field */
+  char *contenttype;                /* Content-Type */
+  struct curl_slist *contentheader; /* list of extra headers for this form */
+  struct curl_httppost *more;       /* if one field name has more than one
+                                       file, this link should link to following
+                                       files */
+  long flags;                       /* as defined below */
+
+/* specified content is a file name */
+#define CURL_HTTPPOST_FILENAME (1<<0)
+/* specified content is a file name */
+#define CURL_HTTPPOST_READFILE (1<<1)
+/* name is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRNAME (1<<2)
+/* contents is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
+/* upload file from buffer */
+#define CURL_HTTPPOST_BUFFER (1<<4)
+/* upload file from pointer contents */
+#define CURL_HTTPPOST_PTRBUFFER (1<<5)
+/* upload file contents by using the regular read callback to get the data and
+   pass the given pointer as custom pointer */
+#define CURL_HTTPPOST_CALLBACK (1<<6)
+/* use size in 'contentlen', added in 7.46.0 */
+#define CURL_HTTPPOST_LARGE (1<<7)
+
+  char *showfilename;               /* The file name to show. If not set, the
+                                       actual file name will be used (if this
+                                       is a file part) */
+  void *userp;                      /* custom pointer used for
+                                       HTTPPOST_CALLBACK posts */
+  curl_off_t contentlen;            /* alternative length of contents
+                                       field. Used if CURL_HTTPPOST_LARGE is
+                                       set. Added in 7.46.0 */
+};
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
+   deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+                                      double dltotal,
+                                      double dlnow,
+                                      double ultotal,
+                                      double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
+   7.32.0, it avoids floating point and provides more detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+                                      curl_off_t dltotal,
+                                      curl_off_t dlnow,
+                                      curl_off_t ultotal,
+                                      curl_off_t ulnow);
+
+#ifndef CURL_MAX_READ_SIZE
+  /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE 524288
+#endif
+
+#ifndef CURL_MAX_WRITE_SIZE
+  /* Tests have proven that 20K is a very bad buffer size for uploads on
+     Windows, while 16K for some odd reason performed a lot better.
+     We do the ifndef check to allow this value to easier be changed at build
+     time for those who feel adventurous. The practical minimum is about
+     400 bytes since libcurl uses a buffer of this size as a scratch area
+     (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+   server feeding libcurl with a never-ending header that will cause reallocs
+   infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+   will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *outstream);
+
+/* This callback will be called when a new resolver request is made */
+typedef int (*curl_resolver_start_callback)(void *resolver_state,
+                                            void *reserved, void *userdata);
+
+/* enumeration of file types */
+typedef enum {
+  CURLFILETYPE_FILE = 0,
+  CURLFILETYPE_DIRECTORY,
+  CURLFILETYPE_SYMLINK,
+  CURLFILETYPE_DEVICE_BLOCK,
+  CURLFILETYPE_DEVICE_CHAR,
+  CURLFILETYPE_NAMEDPIPE,
+  CURLFILETYPE_SOCKET,
+  CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+  CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME    (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE    (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME        (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM        (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID         (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID         (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
+
+/* Content of this structure depends on information which is known and is
+   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+   page for callbacks returning this structure -- some fields are mandatory,
+   some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+  char *filename;
+  curlfiletype filetype;
+  time_t time;
+  unsigned int perm;
+  int uid;
+  int gid;
+  curl_off_t size;
+  long int hardlinks;
+
+  struct {
+    /* If some of these fields is not NULL, it is a pointer to b_data. */
+    char *time;
+    char *perm;
+    char *user;
+    char *group;
+    char *target; /* pointer to the target filename of a symlink */
+  } strings;
+
+  unsigned int flags;
+
+  /* used internally */
+  char *b_data;
+  size_t b_size;
+  size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK      0
+#define CURL_CHUNK_BGN_FUNC_FAIL    1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP    2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+   download of an individual chunk started. Note that parameter "remains" works
+   only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+                                        void *ptr,
+                                        int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK      0
+#define CURL_CHUNK_END_FUNC_FAIL    1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+   download of an individual chunk finished.
+   Note! After this callback was set then it have to be called FOR ALL chunks.
+   Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+   This is the reason why we don't need "transfer_info" parameter in this
+   callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH    0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH  1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL     2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+   string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+                                     const char *pattern,
+                                     const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK       0
+#define CURL_SEEKFUNC_FAIL     1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+                                    libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+                                  curl_off_t offset,
+                                  int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+/* Return code for when the trailing headers' callback has terminated
+   without any errors*/
+#define CURL_TRAILERFUNC_OK 0
+/* Return code for when was an error in the trailing header's list and we
+  want to abort the request */
+#define CURL_TRAILERFUNC_ABORT 1
+
+typedef size_t (*curl_read_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *instream);
+
+typedef int (*curl_trailer_callback)(struct curl_slist **list,
+                                      void *userdata);
+
+typedef enum {
+  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
+  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+  CURLSOCKTYPE_LAST    /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+   to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+                                CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+                                     curl_socket_t curlfd,
+                                     curlsocktype purpose);
+
+struct curl_sockaddr {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+                           turned really ugly and painful on the systems that
+                           lack this type */
+  struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+                            curlsocktype purpose,
+                            struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+  CURLIOE_OK,            /* I/O operation successful */
+  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
+  CURLIOE_FAILRESTART,   /* failed to restart the read */
+  CURLIOE_LAST           /* never use */
+} curlioerr;
+
+typedef enum {
+  CURLIOCMD_NOP,         /* no operation */
+  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+  CURLIOCMD_LAST         /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+                                         int cmd,
+                                         void *clientp);
+
+#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively.  Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+#define CURL_DID_MEMORY_FUNC_TYPEDEFS
+#endif
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+  CURLINFO_TEXT = 0,
+  CURLINFO_HEADER_IN,    /* 1 */
+  CURLINFO_HEADER_OUT,   /* 2 */
+  CURLINFO_DATA_IN,      /* 3 */
+  CURLINFO_DATA_OUT,     /* 4 */
+  CURLINFO_SSL_DATA_IN,  /* 5 */
+  CURLINFO_SSL_DATA_OUT, /* 6 */
+  CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+       (CURL *handle,      /* the handle/transfer this concerns */
+        curl_infotype type, /* what kind of data */
+        char *data,        /* points to the data */
+        size_t size,       /* size of the data pointed to */
+        void *userptr);    /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+   may return other values, stay prepared.
+
+   Always add new return codes last. Never *EVER* remove any. The return
+   codes must remain the same!
+ */
+
+typedef enum {
+  CURLE_OK = 0,
+  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
+  CURLE_FAILED_INIT,             /* 2 */
+  CURLE_URL_MALFORMAT,           /* 3 */
+  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
+                                    7.17.0, reused in April 2011 for 7.21.5] */
+  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
+  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
+  CURLE_COULDNT_CONNECT,         /* 7 */
+  CURLE_WEIRD_SERVER_REPLY,      /* 8 */
+  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
+                                    due to lack of access - when login fails
+                                    this is not returned. */
+  CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
+                                    7.15.4, reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
+  CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
+  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
+  CURLE_FTP_CANT_GET_HOST,       /* 15 */
+  CURLE_HTTP2,                   /* 16 - A problem in the http2 framing layer.
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in July 2014 for 7.38.0] */
+  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
+  CURLE_PARTIAL_FILE,            /* 18 */
+  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
+  CURLE_OBSOLETE20,              /* 20 - NOT USED */
+  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
+  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
+  CURLE_WRITE_ERROR,             /* 23 */
+  CURLE_OBSOLETE24,              /* 24 - NOT USED */
+  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
+  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
+  CURLE_OUT_OF_MEMORY,           /* 27 */
+  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+           instead of a memory allocation error if CURL_DOES_CONVERSIONS
+           is defined
+  */
+  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
+  CURLE_OBSOLETE29,              /* 29 - NOT USED */
+  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
+  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
+  CURLE_OBSOLETE32,              /* 32 - NOT USED */
+  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
+  CURLE_HTTP_POST_ERROR,         /* 34 */
+  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
+  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
+  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
+  CURLE_LDAP_CANNOT_BIND,        /* 38 */
+  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
+  CURLE_OBSOLETE40,              /* 40 - NOT USED */
+  CURLE_FUNCTION_NOT_FOUND,      /* 41 - NOT USED starting with 7.53.0 */
+  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
+  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
+  CURLE_OBSOLETE44,              /* 44 - NOT USED */
+  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
+  CURLE_OBSOLETE46,              /* 46 - NOT USED */
+  CURLE_TOO_MANY_REDIRECTS,      /* 47 - catch endless re-direct loops */
+  CURLE_UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
+  CURLE_TELNET_OPTION_SYNTAX,    /* 49 - Malformed telnet option */
+  CURLE_OBSOLETE50,              /* 50 - NOT USED */
+  CURLE_OBSOLETE51,              /* 51 - NOT USED */
+  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
+  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
+  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
+                                    default */
+  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
+  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
+  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
+  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
+  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
+  CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint
+                                     wasn't verified fine */
+  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
+  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
+  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
+  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
+  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
+                                    that failed */
+  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
+  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
+                                    accepted and we failed to login */
+  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
+  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
+  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
+  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
+  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
+  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
+  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
+  CURLE_CONV_FAILED,             /* 75 - conversion failed */
+  CURLE_CONV_REQD,               /* 76 - caller must register conversion
+                                    callbacks using curl_easy_setopt options
+                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
+  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
+                                    or wrong format */
+  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
+  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
+                                    generic so the error message will be of
+                                    interest when this has happened */
+
+  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
+                                    connection */
+  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
+                                    wait till it's ready and try again (Added
+                                    in 7.18.2) */
+  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
+                                    wrong format (Added in 7.19.0) */
+  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
+                                    7.19.0) */
+  CURLE_FTP_PRET_FAILED,         /* 84 - a PRET command failed */
+  CURLE_RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
+  CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
+  CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
+  CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
+  CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+                                    session will be queued */
+  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+                                     match */
+  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
+  CURLE_HTTP2_STREAM,            /* 92 - stream error in HTTP/2 framing layer
+                                    */
+  CURLE_RECURSIVE_API_CALL,      /* 93 - an api function was called from
+                                    inside a callback */
+  CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Previously obsolete error code re-used in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes re-used in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/*  compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
+
+/* The following were added in 7.62.0 */
+#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+   is no longer used by libcurl but is instead #defined here only to not
+   make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+   with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
+                                          void *ssl_ctx, /* actually an
+                                                            OpenSSL SSL_CTX */
+                                          void *userptr);
+
+typedef enum {
+  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
+                           CONNECT HTTP/1.1 */
+  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
+                               HTTP/1.0  */
+  CURLPROXY_HTTPS = 2, /* added in 7.52.0 */
+  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+                           in 7.10 */
+  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+                                   host name rather than the IP address. added
+                                   in 7.18.0 */
+} curl_proxytype;  /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE         - No HTTP authentication
+ * CURLAUTH_BASIC        - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST       - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE    - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM         - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_BEARER       - HTTP Bearer token authentication
+ * CURLAUTH_ONLY         - Use together with a single other type to force no
+ *                         authentication or just that single type
+ * CURLAUTH_ANY          - All fine types set
+ * CURLAUTH_ANYSAFE      - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE         ((unsigned long)0)
+#define CURLAUTH_BASIC        (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST       (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE    (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
+#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM         (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
+#define CURLAUTH_BEARER       (((unsigned long)1)<<6)
+#define CURLAUTH_ONLY         (((unsigned long)1)<<31)
+#define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
+#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
+#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT     (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_GSSAPI    (1<<5) /* gssapi (kerberos, ...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+  CURLKHTYPE_UNKNOWN,
+  CURLKHTYPE_RSA1,
+  CURLKHTYPE_RSA,
+  CURLKHTYPE_DSS,
+  CURLKHTYPE_ECDSA,
+  CURLKHTYPE_ED25519
+};
+
+struct curl_khkey {
+  const char *key; /* points to a zero-terminated string encoded with base64
+                      if len is zero, otherwise to the "raw" data */
+  size_t len;
+  enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+   callback */
+enum curl_khstat {
+  CURLKHSTAT_FINE_ADD_TO_FILE,
+  CURLKHSTAT_FINE,
+  CURLKHSTAT_REJECT, /* reject the connection, return an error */
+  CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
+                        this causes a CURLE_DEFER error but otherwise the
+                        connection will be left intact etc */
+  CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+  CURLKHMATCH_OK,       /* match */
+  CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+  CURLKHMATCH_MISSING,  /* no matching host/key found */
+  CURLKHMATCH_LAST      /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+  (*curl_sshkeycallback) (CURL *easy,     /* easy handle */
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch, /* libcurl's view on the keys */
+                          void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+  CURLUSESSL_NONE,    /* do not attempt to use SSL */
+  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
+  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+  CURLUSESSL_ALL,     /* SSL for all communication or fail */
+  CURLUSESSL_LAST     /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+   name of improving interoperability with older servers. Some SSL libraries
+   have introduced work-arounds for this flaw but those work-arounds sometimes
+   make the SSL communication fail. To regain functionality with those broken
+   servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+   SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+/* The default connection attempt delay in milliseconds for happy eyeballs.
+   CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
+   this value, keep them in sync. */
+#define CURL_HET_DEFAULT 200L
+
+/* The default connection upkeep interval in milliseconds. */
+#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
+  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
+  CURLFTPSSL_CCC_LAST     /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
+  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
+  CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
+  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+                               again if MKD succeeded, for SFTP this does
+                               similar magic */
+  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+                               again even if MKD failed! */
+  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
+  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
+  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
+  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+  CURLFTPMETHOD_LAST       /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED  0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
+#define CURLALTSVC_IMMEDIATELY  (1<<0)
+#define CURLALTSVC_ALTUSED      (1<<1)
+#define CURLALTSVC_READONLYFILE (1<<2)
+#define CURLALTSVC_H1           (1<<3)
+#define CURLALTSVC_H2           (1<<4)
+#define CURLALTSVC_H3           (1<<5)
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP   (1<<0)
+#define CURLPROTO_HTTPS  (1<<1)
+#define CURLPROTO_FTP    (1<<2)
+#define CURLPROTO_FTPS   (1<<3)
+#define CURLPROTO_SCP    (1<<4)
+#define CURLPROTO_SFTP   (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP   (1<<7)
+#define CURLPROTO_LDAPS  (1<<8)
+#define CURLPROTO_DICT   (1<<9)
+#define CURLPROTO_FILE   (1<<10)
+#define CURLPROTO_TFTP   (1<<11)
+#define CURLPROTO_IMAP   (1<<12)
+#define CURLPROTO_IMAPS  (1<<13)
+#define CURLPROTO_POP3   (1<<14)
+#define CURLPROTO_POP3S  (1<<15)
+#define CURLPROTO_SMTP   (1<<16)
+#define CURLPROTO_SMTPS  (1<<17)
+#define CURLPROTO_RTSP   (1<<18)
+#define CURLPROTO_RTMP   (1<<19)
+#define CURLPROTO_RTMPT  (1<<20)
+#define CURLPROTO_RTMPE  (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS  (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB    (1<<26)
+#define CURLPROTO_SMBS   (1<<27)
+#define CURLPROTO_ALL    (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+   but 32 */
+#define CURLOPTTYPE_LONG          0
+#define CURLOPTTYPE_OBJECTPOINT   10000
+#define CURLOPTTYPE_STRINGPOINT   10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T         30000
+
+/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
+   string options from the header file */
+
+/* name is uppercase CURLOPT_<name>,
+   type is one of the defined CURLOPTTYPE_<type>
+   number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define STRINGPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+  /* This is the FILE * or void * the regular output should be written to. */
+  CINIT(WRITEDATA, OBJECTPOINT, 1),
+
+  /* The full URL to get/put */
+  CINIT(URL, STRINGPOINT, 2),
+
+  /* Port number to connect to, if other than default. */
+  CINIT(PORT, LONG, 3),
+
+  /* Name of proxy to use. */
+  CINIT(PROXY, STRINGPOINT, 4),
+
+  /* "user:password;options" to use when fetching. */
+  CINIT(USERPWD, STRINGPOINT, 5),
+
+  /* "user:password" to use with proxy. */
+  CINIT(PROXYUSERPWD, STRINGPOINT, 6),
+
+  /* Range to get, specified as an ASCII string. */
+  CINIT(RANGE, STRINGPOINT, 7),
+
+  /* not used */
+
+  /* Specified file stream to upload from (use as input): */
+  CINIT(READDATA, OBJECTPOINT, 9),
+
+  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+   * bytes big. */
+  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+  /* Function that will be called to store the output (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+  /* Function that will be called to read the input (instead of fread). The
+   * parameters will use fread() syntax, make sure to follow them. */
+  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+  /* Time-out the read operation after this amount of seconds */
+  CINIT(TIMEOUT, LONG, 13),
+
+  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+   * how large the file being sent really is. That allows better error
+   * checking and better verifies that the upload was successful. -1 means
+   * unknown size.
+   *
+   * For large file support, there is also a _LARGE version of the key
+   * which takes an off_t type, allowing platforms with larger off_t
+   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
+   */
+  CINIT(INFILESIZE, LONG, 14),
+
+  /* POST static input fields. */
+  CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+  /* Set the referrer page (needed by some CGIs) */
+  CINIT(REFERER, STRINGPOINT, 16),
+
+  /* Set the FTP PORT string (interface name, named or numerical IP address)
+     Use i.e '-' to use default address. */
+  CINIT(FTPPORT, STRINGPOINT, 17),
+
+  /* Set the User-Agent string (examined by some CGIs) */
+  CINIT(USERAGENT, STRINGPOINT, 18),
+
+  /* If the download receives less than "low speed limit" bytes/second
+   * during "low speed time" seconds, the operations is aborted.
+   * You could i.e if you have a pretty high speed connection, abort if
+   * it is less than 2000 bytes/sec during 20 seconds.
+   */
+
+  /* Set the "low speed limit" */
+  CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+  /* Set the "low speed time" */
+  CINIT(LOW_SPEED_TIME, LONG, 20),
+
+  /* Set the continuation offset.
+   *
+   * Note there is also a _LARGE version of this key which uses
+   * off_t types, allowing for large file offsets on platforms which
+   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
+   */
+  CINIT(RESUME_FROM, LONG, 21),
+
+  /* Set cookie in request: */
+  CINIT(COOKIE, STRINGPOINT, 22),
+
+  /* This points to a linked list of headers, struct curl_slist kind. This
+     list is also used for RTSP (in spite of its name) */
+  CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+  /* This points to a linked list of post entries, struct curl_httppost */
+  CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+  /* name of the file keeping your private SSL-certificate */
+  CINIT(SSLCERT, STRINGPOINT, 25),
+
+  /* password for the SSL or SSH private key */
+  CINIT(KEYPASSWD, STRINGPOINT, 26),
+
+  /* send TYPE parameter? */
+  CINIT(CRLF, LONG, 27),
+
+  /* send linked-list of QUOTE commands */
+  CINIT(QUOTE, OBJECTPOINT, 28),
+
+  /* send FILE * or void * to store headers to, if you use a callback it
+     is simply passed to the callback unmodified */
+  CINIT(HEADERDATA, OBJECTPOINT, 29),
+
+  /* point to a file to read the initial cookies from, also enables
+     "cookie awareness" */
+  CINIT(COOKIEFILE, STRINGPOINT, 31),
+
+  /* What version to specifically try to use.
+     See CURL_SSLVERSION defines below. */
+  CINIT(SSLVERSION, LONG, 32),
+
+  /* What kind of HTTP time condition to use, see defines */
+  CINIT(TIMECONDITION, LONG, 33),
+
+  /* Time to use with the above condition. Specified in number of seconds
+     since 1 Jan 1970 */
+  CINIT(TIMEVALUE, LONG, 34),
+
+  /* 35 = OBSOLETE */
+
+  /* Custom request, for customizing the get command like
+     HTTP: DELETE, TRACE and others
+     FTP: to use a different list command
+     */
+  CINIT(CUSTOMREQUEST, STRINGPOINT, 36),
+
+  /* FILE handle to use instead of stderr */
+  CINIT(STDERR, OBJECTPOINT, 37),
+
+  /* 38 is not used */
+
+  /* send linked-list of post-transfer QUOTE commands */
+  CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
+
+  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
+  CINIT(HEADER, LONG, 42),       /* throw the header out too */
+  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
+  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
+  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
+  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
+  CINIT(POST, LONG, 47),         /* HTTP POST method */
+  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
+
+  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
+
+  /* Specify whether to read the user+password from the .netrc or the URL.
+   * This must be one of the CURL_NETRC_* enums below. */
+  CINIT(NETRC, LONG, 51),
+
+  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
+
+  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+  CINIT(PUT, LONG, 54),          /* HTTP PUT */
+
+  /* 55 = OBSOLETE */
+
+  /* DEPRECATED
+   * Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_progress_callback
+   * prototype defines. */
+  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+  /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+     callbacks */
+  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+
+  /* We want the referrer field set automatically when following locations */
+  CINIT(AUTOREFERER, LONG, 58),
+
+  /* Port of the proxy, can be set in the proxy string as well with:
+     "[host]:[port]" */
+  CINIT(PROXYPORT, LONG, 59),
+
+  /* size of the POST input data, if strlen() is not good to use */
+  CINIT(POSTFIELDSIZE, LONG, 60),
+
+  /* tunnel non-http operations through a HTTP proxy */
+  CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+  /* Set the interface string to use as outgoing network interface */
+  CINIT(INTERFACE, STRINGPOINT, 62),
+
+  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
+   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
+   * is set but doesn't match one of these, 'private' will be used.  */
+  CINIT(KRBLEVEL, STRINGPOINT, 63),
+
+  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+  CINIT(SSL_VERIFYPEER, LONG, 64),
+
+  /* The CApath or CAfile used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAINFO, STRINGPOINT, 65),
+
+  /* 66 = OBSOLETE */
+  /* 67 = OBSOLETE */
+
+  /* Maximum number of http redirects to follow */
+  CINIT(MAXREDIRS, LONG, 68),
+
+  /* Pass a long set to 1 to get the date of the requested document (if
+     possible)! Pass a zero to shut it off. */
+  CINIT(FILETIME, LONG, 69),
+
+  /* This points to a linked list of telnet options */
+  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+  /* Max amount of cached alive connections */
+  CINIT(MAXCONNECTS, LONG, 71),
+
+  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
+
+  /* 73 = OBSOLETE */
+
+  /* Set to explicitly use a new connection for the upcoming transfer.
+     Do not use this unless you're absolutely sure of this, as it makes the
+     operation slower and is less friendly for the network. */
+  CINIT(FRESH_CONNECT, LONG, 74),
+
+  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+     when done. Do not use this unless you're absolutely sure of this, as it
+     makes the operation slower and is less friendly for the network. */
+  CINIT(FORBID_REUSE, LONG, 75),
+
+  /* Set to a file name that contains random data for libcurl to use to
+     seed the random engine when doing SSL connects. */
+  CINIT(RANDOM_FILE, STRINGPOINT, 76),
+
+  /* Set to the Entropy Gathering Daemon socket pathname */
+  CINIT(EGDSOCKET, STRINGPOINT, 77),
+
+  /* Time-out connect operations after this amount of seconds, if connects are
+     OK within this time, then fine... This only aborts the connect phase. */
+  CINIT(CONNECTTIMEOUT, LONG, 78),
+
+  /* Function that will be called to store headers (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+  /* Set this to force the HTTP request to get back to GET. Only really usable
+     if POST, PUT or a custom request have been used first.
+   */
+  CINIT(HTTPGET, LONG, 80),
+
+  /* Set if we should verify the Common name from the peer certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches the
+   * provided hostname. */
+  CINIT(SSL_VERIFYHOST, LONG, 81),
+
+  /* Specify which file name to write all known cookies in after completed
+     operation. Set file name to "-" (dash) to make it go to stdout. */
+  CINIT(COOKIEJAR, STRINGPOINT, 82),
+
+  /* Specify which SSL ciphers to use */
+  CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83),
+
+  /* Specify which HTTP version to use! This must be set to one of the
+     CURL_HTTP_VERSION* enums set below. */
+  CINIT(HTTP_VERSION, LONG, 84),
+
+  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+     default, that one will always be attempted before the more traditional
+     PASV command. */
+  CINIT(FTP_USE_EPSV, LONG, 85),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+  CINIT(SSLCERTTYPE, STRINGPOINT, 86),
+
+  /* name of the file keeping your private SSL-key */
+  CINIT(SSLKEY, STRINGPOINT, 87),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+  CINIT(SSLKEYTYPE, STRINGPOINT, 88),
+
+  /* crypto engine for the SSL-sub system */
+  CINIT(SSLENGINE, STRINGPOINT, 89),
+
+  /* set the crypto engine for the SSL-sub system as default
+     the param has no meaning...
+   */
+  CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+  /* Non-zero value means to use the global dns cache */
+  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+
+  /* DNS cache timeout */
+  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+  /* send linked-list of pre-transfer QUOTE commands */
+  CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+  /* set the debug function */
+  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+  /* set the data for the debug function */
+  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+  /* mark this as start of a cookie session */
+  CINIT(COOKIESESSION, LONG, 96),
+
+  /* The CApath directory used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAPATH, STRINGPOINT, 97),
+
+  /* Instruct libcurl to use a smaller receive buffer */
+  CINIT(BUFFERSIZE, LONG, 98),
+
+  /* Instruct libcurl to not use any signal/alarm handlers, even when using
+     timeouts. This option is useful for multi-threaded applications.
+     See libcurl-the-guide for more background information. */
+  CINIT(NOSIGNAL, LONG, 99),
+
+  /* Provide a CURLShare for mutexing non-ts data */
+  CINIT(SHARE, OBJECTPOINT, 100),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+     CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
+     CURLPROXY_SOCKS5. */
+  CINIT(PROXYTYPE, LONG, 101),
+
+  /* Set the Accept-Encoding string. Use this to tell a server you would like
+     the response to be compressed. Before 7.21.6, this was known as
+     CURLOPT_ENCODING */
+  CINIT(ACCEPT_ENCODING, STRINGPOINT, 102),
+
+  /* Set pointer to private data */
+  CINIT(PRIVATE, OBJECTPOINT, 103),
+
+  /* Set aliases for HTTP 200 in the HTTP Response header */
+  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+  /* Continue to send authentication (user+password) when following locations,
+     even when hostname changed. This can potentially send off the name
+     and password to whatever host the server decides. */
+  CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+  /* Specifically switch on or off the FTP engine's use of the EPRT command (
+     it also disables the LPRT attempt). By default, those ones will always be
+     attempted before the good old traditional PORT command. */
+  CINIT(FTP_USE_EPRT, LONG, 106),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_USERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(HTTPAUTH, LONG, 107),
+
+  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+     in second argument. The function must be matching the
+     curl_ssl_ctx_callback proto. */
+  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+  /* Set the userdata for the ssl context callback function's third
+     argument */
+  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+  /* FTP Option that causes missing dirs to be created on the remote server.
+     In 7.19.4 we introduced the convenience enums for this option using the
+     CURLFTP_CREATE_DIR prefix.
+  */
+  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(PROXYAUTH, LONG, 111),
+
+  /* FTP option that changes the timeout, in seconds, associated with
+     getting a response.  This is different from transfer timeout time and
+     essentially places a demand on the FTP server to acknowledge commands
+     in a timely manner. */
+  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+     tell libcurl to resolve names to those IP versions only. This only has
+     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+  CINIT(IPRESOLVE, LONG, 113),
+
+  /* Set this option to limit the size of a file that will be downloaded from
+     an HTTP or FTP server.
+
+     Note there is also _LARGE version which adds large file support for
+     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
+  CINIT(MAXFILESIZE, LONG, 114),
+
+  /* See the comment for INFILESIZE above, but in short, specifies
+   * the size of the file being uploaded.  -1 means unknown.
+   */
+  CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+  /* Sets the continuation offset.  There is also a LONG version of this;
+   * look above for RESUME_FROM.
+   */
+  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+  /* Sets the maximum size of data that will be downloaded from
+   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
+   */
+  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+  /* Set this option to the file name of your .netrc file you want libcurl
+     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+     a poor attempt to find the user's home directory and check for a .netrc
+     file in there. */
+  CINIT(NETRC_FILE, STRINGPOINT, 118),
+
+  /* Enable SSL/TLS for FTP, pick one of:
+     CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
+     CURLUSESSL_CONTROL - SSL for the control connection or fail
+     CURLUSESSL_ALL     - SSL for all communication or fail
+  */
+  CINIT(USE_SSL, LONG, 119),
+
+  /* The _LARGE version of the standard POSTFIELDSIZE option */
+  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+  /* Enable/disable the TCP Nagle algorithm */
+  CINIT(TCP_NODELAY, LONG, 121),
+
+  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 123 OBSOLETE. Gone in 7.16.0 */
+  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 127 OBSOLETE. Gone in 7.16.0 */
+  /* 128 OBSOLETE. Gone in 7.16.0 */
+
+  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+     can be used to change libcurl's default action which is to first try
+     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+     response has been received.
+
+     Available parameters are:
+     CURLFTPAUTH_DEFAULT - let libcurl decide
+     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
+     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
+  */
+  CINIT(FTPSSLAUTH, LONG, 129),
+
+  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+  CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+  /* 132 OBSOLETE. Gone in 7.16.0 */
+  /* 133 OBSOLETE. Gone in 7.16.0 */
+
+  /* zero terminated string for pass on to the FTP server when asked for
+     "account" info */
+  CINIT(FTP_ACCOUNT, STRINGPOINT, 134),
+
+  /* feed cookie into cookie engine */
+  CINIT(COOKIELIST, STRINGPOINT, 135),
+
+  /* ignore Content-Length */
+  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+     response. Typically used for FTP-SSL purposes but is not restricted to
+     that. libcurl will then instead use the same IP address it used for the
+     control connection. */
+  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+     above. */
+  CINIT(FTP_FILEMETHOD, LONG, 138),
+
+  /* Local port number to bind the socket to */
+  CINIT(LOCALPORT, LONG, 139),
+
+  /* Number of ports to try, including the first one set with LOCALPORT.
+     Thus, setting it to 1 will make no additional attempts but the first.
+  */
+  CINIT(LOCALPORTRANGE, LONG, 140),
+
+  /* no transfer, set up connection and let application use the socket by
+     extracting it with CURLINFO_LASTSOCKET */
+  CINIT(CONNECT_ONLY, LONG, 141),
+
+  /* Function that will be called to convert from the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+  /* Function that will be called to convert to the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+  /* Function that will be called to convert from UTF8
+     (instead of using the iconv calls in libcurl)
+     Note that this is used only for SSL certificate processing */
+  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+  /* if the connection proceeds too quickly then need to slow it down */
+  /* limit-rate: maximum number of bytes per second to send or receive */
+  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+  /* Pointer to command string to send if USER/PASS fails. */
+  CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147),
+
+  /* callback function for setting socket options */
+  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+  /* set to 0 to disable session ID re-use for this transfer, default is
+     enabled (== 1) */
+  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+  /* allowed SSH authentication methods */
+  CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+  /* Used by scp/sftp to do public/private key authentication */
+  CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152),
+  CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153),
+
+  /* Send CCC (Clear Command Channel) after authentication */
+  CINIT(FTP_SSL_CCC, LONG, 154),
+
+  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+  CINIT(TIMEOUT_MS, LONG, 155),
+  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+  /* set to zero to disable the libcurl's decoding and thus pass the raw body
+     data to the application even when it is encoded/compressed */
+  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+  /* Permission used when creating new files and directories on the remote
+     server for protocols that support it, SFTP/SCP/FILE */
+  CINIT(NEW_FILE_PERMS, LONG, 159),
+  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+  /* Set the behaviour of POST when redirecting. Values must be set to one
+     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+  CINIT(POSTREDIR, LONG, 161),
+
+  /* used by scp/sftp to verify the host's public key */
+  CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162),
+
+  /* Callback function for opening socket (instead of socket(2)). Optionally,
+     callback is able change the address or refuse to connect returning
+     CURL_SOCKET_BAD.  The callback should have type
+     curl_opensocket_callback */
+  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+  /* POST volatile input fields. */
+  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+  /* Callback function for seeking in the input stream */
+  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+  CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+  /* CRL file */
+  CINIT(CRLFILE, STRINGPOINT, 169),
+
+  /* Issuer certificate */
+  CINIT(ISSUERCERT, STRINGPOINT, 170),
+
+  /* (IPv6) Address scope */
+  CINIT(ADDRESS_SCOPE, LONG, 171),
+
+  /* Collect certificate chain info and allow it to get retrievable with
+     CURLINFO_CERTINFO after the transfer is complete. */
+  CINIT(CERTINFO, LONG, 172),
+
+  /* "name" and "pwd" to use when fetching. */
+  CINIT(USERNAME, STRINGPOINT, 173),
+  CINIT(PASSWORD, STRINGPOINT, 174),
+
+    /* "name" and "pwd" to use with Proxy when fetching. */
+  CINIT(PROXYUSERNAME, STRINGPOINT, 175),
+  CINIT(PROXYPASSWORD, STRINGPOINT, 176),
+
+  /* Comma separated list of hostnames defining no-proxy zones. These should
+     match both hostnames directly, and hostnames within a domain. For
+     example, local.com will match local.com and www.local.com, but NOT
+     notlocal.com or www.notlocal.com. For compatibility with other
+     implementations of this, .local.com will be considered to be the same as
+     local.com. A single * is the only valid wildcard, and effectively
+     disables the use of proxy. */
+  CINIT(NOPROXY, STRINGPOINT, 177),
+
+  /* block size for TFTP transfers */
+  CINIT(TFTP_BLKSIZE, LONG, 178),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+  /* set the bitmask for the protocols that are allowed to be used for the
+     transfer, which thus helps the app which takes URLs from users or other
+     external inputs and want to restrict what protocol(s) to deal
+     with. Defaults to CURLPROTO_ALL. */
+  CINIT(PROTOCOLS, LONG, 181),
+
+  /* set the bitmask for the protocols that libcurl is allowed to follow to,
+     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+     to be set in both bitmasks to be allowed to get redirected to. Defaults
+     to all protocols except FILE and SCP. */
+  CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+  /* set the SSH knownhost file name to use */
+  CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183),
+
+  /* set the SSH host key callback, must point to a curl_sshkeycallback
+     function */
+  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+  /* set the SSH host key callback custom pointer */
+  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+  /* set the SMTP mail originator */
+  CINIT(MAIL_FROM, STRINGPOINT, 186),
+
+  /* set the list of SMTP mail receiver(s) */
+  CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+  /* FTP: send PRET before PASV */
+  CINIT(FTP_USE_PRET, LONG, 188),
+
+  /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+  CINIT(RTSP_REQUEST, LONG, 189),
+
+  /* The RTSP session identifier */
+  CINIT(RTSP_SESSION_ID, STRINGPOINT, 190),
+
+  /* The RTSP stream URI */
+  CINIT(RTSP_STREAM_URI, STRINGPOINT, 191),
+
+  /* The Transport: header to use in RTSP requests */
+  CINIT(RTSP_TRANSPORT, STRINGPOINT, 192),
+
+  /* Manually initialize the client RTSP CSeq for this handle */
+  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+  /* Manually initialize the server RTSP CSeq for this handle */
+  CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+  /* The stream to pass to INTERLEAVEFUNCTION. */
+  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+  /* Let the application define a custom write method for RTP data */
+  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+  /* Turn on wildcard matching */
+  CINIT(WILDCARDMATCH, LONG, 197),
+
+  /* Directory matching callback called before downloading of an
+     individual file (chunk) started */
+  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+  /* Directory matching callback called after the file (chunk)
+     was downloaded, or skipped */
+  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+  /* Change match (fnmatch-like) callback for wildcard matching */
+  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+  /* Let the application define custom chunk data pointer */
+  CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+  /* FNMATCH_FUNCTION user pointer */
+  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+  /* send linked-list of name:port:address sets */
+  CINIT(RESOLVE, OBJECTPOINT, 203),
+
+  /* Set a username for authenticated TLS */
+  CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204),
+
+  /* Set a password for authenticated TLS */
+  CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205),
+
+  /* Set authentication type for authenticated TLS */
+  CINIT(TLSAUTH_TYPE, STRINGPOINT, 206),
+
+  /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+     compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+     in outgoing requests. The current default is 0, but it might change in a
+     future libcurl release.
+
+     libcurl will ask for the compressed methods it knows of, and if that
+     isn't any, it will not ask for transfer-encoding at all even if this
+     option is set to 1.
+
+  */
+  CINIT(TRANSFER_ENCODING, LONG, 207),
+
+  /* Callback function for closing socket (instead of close(2)). The callback
+     should have type curl_closesocket_callback */
+  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
+  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+
+  /* allow GSSAPI credential delegation */
+  CINIT(GSSAPI_DELEGATION, LONG, 210),
+
+  /* Set the name servers to use for DNS resolution */
+  CINIT(DNS_SERVERS, STRINGPOINT, 211),
+
+  /* Time-out accept operations (currently for FTP only) after this amount
+     of milliseconds. */
+  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
+
+  /* Set TCP keepalive */
+  CINIT(TCP_KEEPALIVE, LONG, 213),
+
+  /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+  CINIT(TCP_KEEPIDLE, LONG, 214),
+  CINIT(TCP_KEEPINTVL, LONG, 215),
+
+  /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+  CINIT(SSL_OPTIONS, LONG, 216),
+
+  /* Set the SMTP auth originator */
+  CINIT(MAIL_AUTH, STRINGPOINT, 217),
+
+  /* Enable/disable SASL initial response */
+  CINIT(SASL_IR, LONG, 218),
+
+  /* Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_xferinfo_callback
+   * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
+
+  /* The XOAUTH2 bearer token */
+  CINIT(XOAUTH2_BEARER, STRINGPOINT, 220),
+
+  /* Set the interface string to use as outgoing network
+   * interface for DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_INTERFACE, STRINGPOINT, 221),
+
+  /* Set the local IPv4 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222),
+
+  /* Set the local IPv6 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223),
+
+  /* Set authentication options directly */
+  CINIT(LOGIN_OPTIONS, STRINGPOINT, 224),
+
+  /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_NPN, LONG, 225),
+
+  /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_ALPN, LONG, 226),
+
+  /* Time to wait for a response to a HTTP request containing an
+   * Expect: 100-continue header before sending the data anyway. */
+  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
+
+  /* This points to a linked list of headers used for proxy requests only,
+     struct curl_slist kind */
+  CINIT(PROXYHEADER, OBJECTPOINT, 228),
+
+  /* Pass in a bitmask of "header options" */
+  CINIT(HEADEROPT, LONG, 229),
+
+  /* The public key in DER form used to validate the peer public key
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230),
+
+  /* Path to Unix domain socket */
+  CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231),
+
+  /* Set if we should verify the certificate status. */
+  CINIT(SSL_VERIFYSTATUS, LONG, 232),
+
+  /* Set if we should enable TLS false start. */
+  CINIT(SSL_FALSESTART, LONG, 233),
+
+  /* Do not squash dot-dot sequences */
+  CINIT(PATH_AS_IS, LONG, 234),
+
+  /* Proxy Service Name */
+  CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235),
+
+  /* Service Name */
+  CINIT(SERVICE_NAME, STRINGPOINT, 236),
+
+  /* Wait/don't wait for pipe/mutex to clarify */
+  CINIT(PIPEWAIT, LONG, 237),
+
+  /* Set the protocol used when curl is given a URL without a protocol */
+  CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238),
+
+  /* Set stream weight, 1 - 256 (default is 16) */
+  CINIT(STREAM_WEIGHT, LONG, 239),
+
+  /* Set stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS, OBJECTPOINT, 240),
+
+  /* Set E-xclusive stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
+
+  /* Do not send any tftp option requests to the server */
+  CINIT(TFTP_NO_OPTIONS, LONG, 242),
+
+  /* Linked-list of host:port:connect-to-host:connect-to-port,
+     overrides the URL's host:port (only for the network layer) */
+  CINIT(CONNECT_TO, OBJECTPOINT, 243),
+
+  /* Set TCP Fast Open */
+  CINIT(TCP_FASTOPEN, LONG, 244),
+
+  /* Continue to send data if the server responds early with an
+   * HTTP status code >= 300 */
+  CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
+
+  /* The CApath or CAfile used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAINFO, STRINGPOINT, 246),
+
+  /* The CApath directory used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAPATH, STRINGPOINT, 247),
+
+  /* Set if we should verify the proxy in ssl handshake,
+     set 1 to verify. */
+  CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
+
+  /* Set if we should verify the Common name from the proxy certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches
+   * the provided hostname. */
+  CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
+
+  /* What version to specifically try to use for proxy.
+     See CURL_SSLVERSION defines below. */
+  CINIT(PROXY_SSLVERSION, LONG, 250),
+
+  /* Set a username for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
+
+  /* Set a password for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
+
+  /* Set authentication type for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
+
+  /* name of the file keeping your private SSL-certificate for proxy */
+  CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
+
+  /* name of the file keeping your private SSL-key for proxy */
+  CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
+
+  /* password for the SSL private key for proxy */
+  CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
+
+  /* Specify which SSL ciphers to use for proxy */
+  CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
+
+  /* CRL file for proxy */
+  CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
+
+  /* Enable/disable specific SSL features with a bitmask for proxy, see
+     CURLSSLOPT_* */
+  CINIT(PROXY_SSL_OPTIONS, LONG, 261),
+
+  /* Name of pre proxy to use. */
+  CINIT(PRE_PROXY, STRINGPOINT, 262),
+
+  /* The public key in DER form used to validate the proxy public key
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
+
+  /* Path to an abstract Unix domain socket */
+  CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+
+  /* Suppress proxy CONNECT response headers from user callbacks */
+  CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
+
+  /* The request target, instead of extracted from the URL */
+  CINIT(REQUEST_TARGET, STRINGPOINT, 266),
+
+  /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
+  CINIT(SOCKS5_AUTH, LONG, 267),
+
+  /* Enable/disable SSH compression */
+  CINIT(SSH_COMPRESSION, LONG, 268),
+
+  /* Post MIME data. */
+  CINIT(MIMEPOST, OBJECTPOINT, 269),
+
+  /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of
+     seconds since 1 Jan 1970. */
+  CINIT(TIMEVALUE_LARGE, OFF_T, 270),
+
+  /* Head start in milliseconds to give happy eyeballs. */
+  CINIT(HAPPY_EYEBALLS_TIMEOUT_MS, LONG, 271),
+
+  /* Function that will be called before a resolver request is made */
+  CINIT(RESOLVER_START_FUNCTION, FUNCTIONPOINT, 272),
+
+  /* User data to pass to the resolver start callback. */
+  CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273),
+
+  /* send HAProxy PROXY protocol header? */
+  CINIT(HAPROXYPROTOCOL, LONG, 274),
+
+  /* shuffle addresses before use when DNS returns multiple */
+  CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275),
+
+  /* Specify which TLS 1.3 ciphers suites to use */
+  CINIT(TLS13_CIPHERS, STRINGPOINT, 276),
+  CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277),
+
+  /* Disallow specifying username/login in URL. */
+  CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278),
+
+  /* DNS-over-HTTPS URL */
+  CINIT(DOH_URL, STRINGPOINT, 279),
+
+  /* Preferred buffer size to use for uploads */
+  CINIT(UPLOAD_BUFFERSIZE, LONG, 280),
+
+  /* Time in ms between connection upkeep calls for long-lived connections. */
+  CINIT(UPKEEP_INTERVAL_MS, LONG, 281),
+
+  /* Specify URL using CURL URL API. */
+  CINIT(CURLU, OBJECTPOINT, 282),
+
+  /* add trailing data just after no more data is available */
+  CINIT(TRAILERFUNCTION, FUNCTIONPOINT, 283),
+
+  /* pointer to be passed to HTTP_TRAILER_FUNCTION */
+  CINIT(TRAILERDATA, OBJECTPOINT, 284),
+
+  /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
+  CINIT(HTTP09_ALLOWED, LONG, 285),
+
+  /* alt-svc control bitmask */
+  CINIT(ALTSVC_CTRL, LONG, 286),
+
+  /* alt-svc cache file name to possibly read from/write to */
+  CINIT(ALTSVC, STRINGPOINT, 287),
+
+  CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+     name resolves addresses using more than one IP protocol version, this
+     option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+                                     versions that your system allows */
+#define CURL_IPRESOLVE_V4       1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6       2 /* resolve to IPv6 addresses */
+
+  /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+                             like the library to choose the best possible
+                             for us! */
+  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
+  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
+  CURL_HTTP_VERSION_2_0,  /* please use HTTP 2 in the request */
+  CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
+  CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE,  /* please use HTTP 2 without HTTP/1.1
+                                           Upgrade */
+
+  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+   not 2.0. The 2_0 version of the enum name was set while the version was
+   still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+    CURL_RTSPREQ_NONE, /* first in list */
+    CURL_RTSPREQ_OPTIONS,
+    CURL_RTSPREQ_DESCRIBE,
+    CURL_RTSPREQ_ANNOUNCE,
+    CURL_RTSPREQ_SETUP,
+    CURL_RTSPREQ_PLAY,
+    CURL_RTSPREQ_PAUSE,
+    CURL_RTSPREQ_TEARDOWN,
+    CURL_RTSPREQ_GET_PARAMETER,
+    CURL_RTSPREQ_SET_PARAMETER,
+    CURL_RTSPREQ_RECORD,
+    CURL_RTSPREQ_RECEIVE,
+    CURL_RTSPREQ_LAST /* last in list */
+};
+
+  /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
+                           * This is the default. */
+  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
+                           * to one in the .netrc. */
+  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
+                           * Unless one is set programmatically, the .netrc
+                           * will be queried. */
+  CURL_NETRC_LAST
+};
+
+enum {
+  CURL_SSLVERSION_DEFAULT,
+  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+  CURL_SSLVERSION_SSLv2,
+  CURL_SSLVERSION_SSLv3,
+  CURL_SSLVERSION_TLSv1_0,
+  CURL_SSLVERSION_TLSv1_1,
+  CURL_SSLVERSION_TLSv1_2,
+  CURL_SSLVERSION_TLSv1_3,
+
+  CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum {
+  CURL_SSLVERSION_MAX_NONE =     0,
+  CURL_SSLVERSION_MAX_DEFAULT =  (CURL_SSLVERSION_TLSv1   << 16),
+  CURL_SSLVERSION_MAX_TLSv1_0 =  (CURL_SSLVERSION_TLSv1_0 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_1 =  (CURL_SSLVERSION_TLSv1_1 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_2 =  (CURL_SSLVERSION_TLSv1_2 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_3 =  (CURL_SSLVERSION_TLSv1_3 << 16),
+
+  /* never use, keep last */
+  CURL_SSLVERSION_MAX_LAST =     (CURL_SSLVERSION_LAST    << 16)
+};
+
+enum CURL_TLSAUTH {
+  CURL_TLSAUTH_NONE,
+  CURL_TLSAUTH_SRP,
+  CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+   CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+   can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+   | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL  0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+    (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+  CURL_TIMECOND_NONE,
+
+  CURL_TIMECOND_IFMODSINCE,
+  CURL_TIMECOND_IFUNMODSINCE,
+  CURL_TIMECOND_LASTMOD,
+
+  CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+/* Special size_t value signaling a zero-terminated string. */
+#define CURL_ZERO_TERMINATED ((size_t) -1)
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+   release */
+CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
+CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
+
+/* Mime/form handling support. */
+typedef struct curl_mime_s      curl_mime;      /* Mime context. */
+typedef struct curl_mimepart_s  curl_mimepart;  /* Mime part context. */
+
+/*
+ * NAME curl_mime_init()
+ *
+ * DESCRIPTION
+ *
+ * Create a mime context and return its handle. The easy parameter is the
+ * target handle.
+ */
+CURL_EXTERN curl_mime *curl_mime_init(CURL *easy);
+
+/*
+ * NAME curl_mime_free()
+ *
+ * DESCRIPTION
+ *
+ * release a mime handle and its substructures.
+ */
+CURL_EXTERN void curl_mime_free(curl_mime *mime);
+
+/*
+ * NAME curl_mime_addpart()
+ *
+ * DESCRIPTION
+ *
+ * Append a new empty part to the given mime context and return a handle to
+ * the created part.
+ */
+CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime);
+
+/*
+ * NAME curl_mime_name()
+ *
+ * DESCRIPTION
+ *
+ * Set mime/form part name.
+ */
+CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name);
+
+/*
+ * NAME curl_mime_filename()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part remote file name.
+ */
+CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part,
+                                        const char *filename);
+
+/*
+ * NAME curl_mime_type()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part type.
+ */
+CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype);
+
+/*
+ * NAME curl_mime_encoder()
+ *
+ * DESCRIPTION
+ *
+ * Set mime data transfer encoder.
+ */
+CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part,
+                                       const char *encoding);
+
+/*
+ * NAME curl_mime_data()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from memory data,
+ */
+CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part,
+                                    const char *data, size_t datasize);
+
+/*
+ * NAME curl_mime_filedata()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from named file.
+ */
+CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part,
+                                        const char *filename);
+
+/*
+ * NAME curl_mime_data_cb()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from callback function.
+ */
+CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part,
+                                       curl_off_t datasize,
+                                       curl_read_callback readfunc,
+                                       curl_seek_callback seekfunc,
+                                       curl_free_callback freefunc,
+                                       void *arg);
+
+/*
+ * NAME curl_mime_subparts()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from subparts.
+ */
+CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part,
+                                        curl_mime *subparts);
+/*
+ * NAME curl_mime_headers()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part headers.
+ */
+CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part,
+                                       struct curl_slist *headers,
+                                       int take_ownership);
+
+/* Old form API. */
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+  CFINIT(NOTHING),        /********* the first one is unused ************/
+
+  /*  */
+  CFINIT(COPYNAME),
+  CFINIT(PTRNAME),
+  CFINIT(NAMELENGTH),
+  CFINIT(COPYCONTENTS),
+  CFINIT(PTRCONTENTS),
+  CFINIT(CONTENTSLENGTH),
+  CFINIT(FILECONTENT),
+  CFINIT(ARRAY),
+  CFINIT(OBSOLETE),
+  CFINIT(FILE),
+
+  CFINIT(BUFFER),
+  CFINIT(BUFFERPTR),
+  CFINIT(BUFFERLENGTH),
+
+  CFINIT(CONTENTTYPE),
+  CFINIT(CONTENTHEADER),
+  CFINIT(FILENAME),
+  CFINIT(END),
+  CFINIT(OBSOLETE2),
+
+  CFINIT(STREAM),
+  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
+
+  CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+  CURLformoption option;
+  const char     *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+  CURL_FORMADD_OK, /* first, no error */
+
+  CURL_FORMADD_MEMORY,
+  CURL_FORMADD_OPTION_TWICE,
+  CURL_FORMADD_NULL,
+  CURL_FORMADD_UNKNOWN_OPTION,
+  CURL_FORMADD_INCOMPLETE,
+  CURL_FORMADD_ILLEGAL_ARRAY,
+  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+  CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                                      struct curl_httppost **last_post,
+                                      ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ *   curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ *   success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+                                        size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+                             curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+                                   const char *string,
+                                   int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+                              int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+                                     const char *string,
+                                     int length,
+                                     int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+                                int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl.  This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions.  Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc.  User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+                                          curl_malloc_callback m,
+                                          curl_free_callback f,
+                                          curl_realloc_callback r,
+                                          curl_strdup_callback s,
+                                          curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+  char *data;
+  struct curl_slist *next;
+};
+
+/*
+ * NAME curl_global_sslset()
+ *
+ * DESCRIPTION
+ *
+ * When built with multiple SSL backends, curl_global_sslset() allows to
+ * choose one. This function can only be called once, and it must be called
+ * *before* curl_global_init().
+ *
+ * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The
+ * backend can also be specified via the name parameter (passing -1 as id).
+ * If both id and name are specified, the name will be ignored. If neither id
+ * nor name are specified, the function will fail with
+ * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the
+ * NULL-terminated list of available backends.
+ *
+ * Upon success, the function returns CURLSSLSET_OK.
+ *
+ * If the specified SSL backend is not available, the function returns
+ * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated
+ * list of available SSL backends.
+ *
+ * The SSL backend can be set only once. If it has already been set, a
+ * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
+ */
+
+typedef struct {
+  curl_sslbackend id;
+  const char *name;
+} curl_ssl_backend;
+
+typedef enum {
+  CURLSSLSET_OK = 0,
+  CURLSSLSET_UNKNOWN_BACKEND,
+  CURLSSLSET_TOO_LATE,
+  CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */
+} CURLsslset;
+
+CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+                                          const curl_ssl_backend ***avail);
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+                                                 const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+  int num_of_certs;             /* number of certificates with information */
+  struct curl_slist **certinfo; /* for each index in this array, there's a
+                                   linked list with textual information in the
+                                   format "name: value" */
+};
+
+/* Information about the SSL library used and the respective internal SSL
+   handle, which can be used to obtain further information regarding the
+   connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+  curl_sslbackend backend;
+  void *internals;
+};
+
+#define CURLINFO_STRING   0x100000
+#define CURLINFO_LONG     0x200000
+#define CURLINFO_DOUBLE   0x300000
+#define CURLINFO_SLIST    0x400000
+#define CURLINFO_PTR      0x400000 /* same as SLIST */
+#define CURLINFO_SOCKET   0x500000
+#define CURLINFO_OFF_T    0x600000
+#define CURLINFO_MASK     0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+  CURLINFO_NONE, /* first, never use this */
+  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
+  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
+  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
+  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
+  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
+  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
+  CURLINFO_SIZE_UPLOAD_T    = CURLINFO_OFF_T  + 7,
+  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
+  CURLINFO_SIZE_DOWNLOAD_T  = CURLINFO_OFF_T  + 8,
+  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
+  CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T  + 9,
+  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
+  CURLINFO_SPEED_UPLOAD_T   = CURLINFO_OFF_T  + 10,
+  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
+  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
+  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
+  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
+  CURLINFO_FILETIME_T       = CURLINFO_OFF_T  + 14,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T  + 15,
+  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
+  CURLINFO_CONTENT_LENGTH_UPLOAD_T   = CURLINFO_OFF_T  + 16,
+  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
+  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
+  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
+  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
+  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
+  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
+  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
+  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
+  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
+  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
+  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
+  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
+  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
+  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
+  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
+  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
+  CURLINFO_CERTINFO         = CURLINFO_PTR    + 34,
+  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
+  CURLINFO_RTSP_SESSION_ID  = CURLINFO_STRING + 36,
+  CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG   + 37,
+  CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG   + 38,
+  CURLINFO_RTSP_CSEQ_RECV   = CURLINFO_LONG   + 39,
+  CURLINFO_PRIMARY_PORT     = CURLINFO_LONG   + 40,
+  CURLINFO_LOCAL_IP         = CURLINFO_STRING + 41,
+  CURLINFO_LOCAL_PORT       = CURLINFO_LONG   + 42,
+  CURLINFO_TLS_SESSION      = CURLINFO_PTR    + 43,
+  CURLINFO_ACTIVESOCKET     = CURLINFO_SOCKET + 44,
+  CURLINFO_TLS_SSL_PTR      = CURLINFO_PTR    + 45,
+  CURLINFO_HTTP_VERSION     = CURLINFO_LONG   + 46,
+  CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
+  CURLINFO_PROTOCOL         = CURLINFO_LONG   + 48,
+  CURLINFO_SCHEME           = CURLINFO_STRING + 49,
+  /* Fill in new entries below here! */
+
+  /* Preferably these would be defined conditionally based on the
+     sizeof curl_off_t being 64-bits */
+  CURLINFO_TOTAL_TIME_T     = CURLINFO_OFF_T + 50,
+  CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
+  CURLINFO_CONNECT_TIME_T   = CURLINFO_OFF_T + 52,
+  CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53,
+  CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
+  CURLINFO_REDIRECT_TIME_T  = CURLINFO_OFF_T + 55,
+  CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+
+  CURLINFO_LASTONE          = 56
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+   CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+  CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+  CURLCLOSEPOLICY_OLDEST,
+  CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+  CURLCLOSEPOLICY_LEAST_TRAFFIC,
+  CURLCLOSEPOLICY_SLOWEST,
+  CURLCLOSEPOLICY_CALLBACK,
+
+  CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+  CURL_LOCK_DATA_NONE = 0,
+  /*  CURL_LOCK_DATA_SHARE is used internally to say that
+   *  the locking is just made to change the internal state of the share
+   *  itself.
+   */
+  CURL_LOCK_DATA_SHARE,
+  CURL_LOCK_DATA_COOKIE,
+  CURL_LOCK_DATA_DNS,
+  CURL_LOCK_DATA_SSL_SESSION,
+  CURL_LOCK_DATA_CONNECT,
+  CURL_LOCK_DATA_PSL,
+  CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+  CURL_LOCK_ACCESS_NONE = 0,   /* unspecified action */
+  CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+  CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+  CURL_LOCK_ACCESS_LAST        /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+                                   curl_lock_data data,
+                                   curl_lock_access locktype,
+                                   void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+                                     curl_lock_data data,
+                                     void *userptr);
+
+
+typedef enum {
+  CURLSHE_OK,  /* all is fine */
+  CURLSHE_BAD_OPTION, /* 1 */
+  CURLSHE_IN_USE,     /* 2 */
+  CURLSHE_INVALID,    /* 3 */
+  CURLSHE_NOMEM,      /* 4 out of memory */
+  CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+  CURLSHE_LAST        /* never use */
+} CURLSHcode;
+
+typedef enum {
+  CURLSHOPT_NONE,  /* don't use */
+  CURLSHOPT_SHARE,   /* specify a data type to share */
+  CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+  CURLSHOPT_LOCKFUNC,   /* pass in a 'curl_lock_function' pointer */
+  CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+  CURLSHOPT_USERDATA,   /* pass in a user data pointer used in the lock/unlock
+                           callback functions */
+  CURLSHOPT_LAST  /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+  CURLVERSION_FIRST,
+  CURLVERSION_SECOND,
+  CURLVERSION_THIRD,
+  CURLVERSION_FOURTH,
+  CURLVERSION_FIFTH,
+  CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+   basically all programs ever that want to get version information. It is
+   meant to be a built-in version number for what kind of struct the caller
+   expects. If the struct ever changes, we redefine the NOW to another enum
+   from above. */
+#define CURLVERSION_NOW CURLVERSION_FIFTH
+
+typedef struct {
+  CURLversion age;          /* age of the returned struct */
+  const char *version;      /* LIBCURL_VERSION */
+  unsigned int version_num; /* LIBCURL_VERSION_NUM */
+  const char *host;         /* OS/host/cpu/machine when configured */
+  int features;             /* bitmask, see defines below */
+  const char *ssl_version;  /* human readable string */
+  long ssl_version_num;     /* not used anymore, always 0 */
+  const char *libz_version; /* human readable string */
+  /* protocols is terminated by an entry with a NULL protoname */
+  const char * const *protocols;
+
+  /* The fields below this were added in CURLVERSION_SECOND */
+  const char *ares;
+  int ares_num;
+
+  /* This field was added in CURLVERSION_THIRD */
+  const char *libidn;
+
+  /* These field were added in CURLVERSION_FOURTH */
+
+  /* Same as '_libiconv_version' if built with HAVE_ICONV */
+  int iconv_ver_num;
+
+  const char *libssh_version; /* human readable string */
+
+  /* These fields were added in CURLVERSION_FIFTH */
+
+  unsigned int brotli_ver_num; /* Numeric Brotli version
+                                  (MAJOR << 24) | (MINOR << 12) | PATCH */
+  const char *brotli_version; /* human readable string. */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_SSL          (1<<2)  /* SSL options are present */
+#define CURL_VERSION_LIBZ         (1<<3)  /* libz features are present */
+#define CURL_VERSION_NTLM         (1<<4)  /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5)  /* Negotiate auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_DEBUG        (1<<6)  /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS    (1<<7)  /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO       (1<<8)  /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE    (1<<9)  /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN          (1<<10) /* Internationized Domain Names are
+                                             supported */
+#define CURL_VERSION_SSPI         (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV         (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
+                                             is supported */
+#define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+#define CURL_VERSION_PSL          (1<<20) /* Mozilla's Public Suffix List, used
+                                             for cookie domain verification */
+#define CURL_VERSION_HTTPS_PROXY  (1<<21) /* HTTPS-proxy support built-in */
+#define CURL_VERSION_MULTI_SSL    (1<<22) /* Multiple SSL backends available */
+#define CURL_VERSION_BROTLI       (1<<23) /* Brotli features are present. */
+#define CURL_VERSION_ALTSVC       (1<<24) /* Alt-Svc handling built-in */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV      (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND      (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+  stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+#include "urlapi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+   only done to make sure application authors pass exactly three arguments
+   to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */

+ 77 - 0
TCL Copy Tool/Include/curl/curlver.h

@@ -0,0 +1,77 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+   a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+   file origins: */
+#define LIBCURL_VERSION "7.64.1"
+
+/* The numeric version number is also available "in parts" by using these
+   defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 64
+#define LIBCURL_VERSION_PATCH 1
+
+/* This is the numeric version of the libcurl version number, meant for easier
+   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+   always follow this syntax:
+
+         0xXXYYZZ
+
+   Where XX, YY and ZZ are the main version, release and patch numbers in
+   hexadecimal (using 8 bits each). All three numbers are always represented
+   using two digits.  1.2 would appear as "0x010200" while version 9.11.7
+   appears as "0x090b07".
+
+   This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+   and it is always a greater number in a more recent release. It makes
+   comparisons with greater than and less than work.
+
+   Note: This define is the full hex number and _does not_ use the
+   CURL_VERSION_BITS() macro since curl's own configure script greps for it
+   and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x074001
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date follows this template:
+ *
+ * "2007-11-23"
+ */
+#define LIBCURL_TIMESTAMP "2019-03-27"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+  (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* __CURL_CURLVER_H */

+ 112 - 0
TCL Copy Tool/Include/curl/easy.h

@@ -0,0 +1,112 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function.  The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere).  The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK.  This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+                                    size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+                                    size_t buflen, size_t *n);
+
+
+/*
+ * NAME curl_easy_upkeep()
+ *
+ * DESCRIPTION
+ *
+ * Performs connection upkeep for the given session handle.
+ */
+CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif

+ 50 - 0
TCL Copy Tool/Include/curl/mprintf.h

@@ -0,0 +1,50 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+#include "curl.h"  /* for CURL_EXTERN */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+                               const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+                                const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */

+ 441 - 0
TCL Copy Tool/Include/curl/multi.h

@@ -0,0 +1,441 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+  This is an "external" header file. Don't give away any internals here!
+
+  GOALS
+
+  o Enable a "pull" interface. The application that uses libcurl decides where
+    and when to ask libcurl to get/send data.
+
+  o Enable multiple simultaneous transfers in the same thread without making it
+    complicated for the application.
+
+  o Enable the application to select() on its own file descriptors and curl's
+    file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_multi CURLM;
+#else
+typedef void CURLM;
+#endif
+
+typedef enum {
+  CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+                                    curl_multi_socket*() soon */
+  CURLM_OK,
+  CURLM_BAD_HANDLE,      /* the passed-in handle is not a valid CURLM handle */
+  CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+  CURLM_OUT_OF_MEMORY,   /* if you ever get this, you're in deep sh*t */
+  CURLM_INTERNAL_ERROR,  /* this is a libcurl bug */
+  CURLM_BAD_SOCKET,      /* the passed in socket argument did not match */
+  CURLM_UNKNOWN_OPTION,  /* curl_multi_setopt() with unsupported option */
+  CURLM_ADDED_ALREADY,   /* an easy handle already added to a multi handle was
+                            attempted to get added - again */
+  CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
+                               callback */
+  CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+   for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+   curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING   0L
+#define CURLPIPE_HTTP1     1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+  CURLMSG_NONE, /* first, not used */
+  CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+                   the CURLcode of the transfer */
+  CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+  CURLMSG msg;       /* what this message means */
+  CURL *easy_handle; /* the handle it concerns */
+  union {
+    void *whatever;    /* message-specific data */
+    CURLcode result;   /* return code for transfer */
+  } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN    0x0001
+#define CURL_WAIT_POLLPRI   0x0002
+#define CURL_WAIT_POLLOUT   0x0004
+
+struct curl_waitfd {
+  curl_socket_t fd;
+  short events;
+  short revents; /* not supported yet */
+};
+
+/*
+ * Name:    curl_multi_init()
+ *
+ * Desc:    inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name:    curl_multi_add_handle()
+ *
+ * Desc:    add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+                                            CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_remove_handle()
+  *
+  * Desc:    removes a curl handle from the multi stack again
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+                                               CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_fdset()
+  *
+  * Desc:    Ask curl for its fd_set sets. The app can use these to select() or
+  *          poll() on. We want curl_multi_perform() called as soon as one of
+  *          them are ready.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+                                       fd_set *read_fd_set,
+                                       fd_set *write_fd_set,
+                                       fd_set *exc_fd_set,
+                                       int *max_fd);
+
+/*
+ * Name:     curl_multi_wait()
+ *
+ * Desc:     Poll on all fds within a CURLM set as well as any
+ *           additional fds passed to the function.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+                                      struct curl_waitfd extra_fds[],
+                                      unsigned int extra_nfds,
+                                      int timeout_ms,
+                                      int *ret);
+
+ /*
+  * Name:    curl_multi_perform()
+  *
+  * Desc:    When the app thinks there's data available for curl it calls this
+  *          function to read/write whatever there is right now. This returns
+  *          as soon as the reads and writes are done. This function does not
+  *          require that there actually is data available for reading or that
+  *          data can be written, it can be called just in case. It returns
+  *          the number of handles that still transfer data in the second
+  *          argument's integer-pointer.
+  *
+  * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+  *          returns errors etc regarding the whole multi stack. There might
+  *          still have occurred problems on individual transfers even when
+  *          this returns OK.
+  */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+                                         int *running_handles);
+
+ /*
+  * Name:    curl_multi_cleanup()
+  *
+  * Desc:    Cleans up and removes a whole multi stack. It does not free or
+  *          touch any individual easy handles in any way. We need to define
+  *          in what state those handles will be if this function is called
+  *          in the middle of a transfer.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name:    curl_multi_info_read()
+ *
+ * Desc:    Ask the multi handle if there's any messages/informationals from
+ *          the individual transfers. Messages include informationals such as
+ *          error code from the transfer or just the fact that a transfer is
+ *          completed. More details on these should be written down as well.
+ *
+ *          Repeated calls to this function will return a new struct each
+ *          time, until a special "end of msgs" struct is returned as a signal
+ *          that there is no more to get at this point.
+ *
+ *          The data the returned pointer points to will not survive calling
+ *          curl_multi_cleanup().
+ *
+ *          The 'CURLMsg' struct is meant to be very simple and only contain
+ *          very basic information. If more involved information is wanted,
+ *          we will provide the particular "transfer handle" in that struct
+ *          and that should/could/would be used in subsequent
+ *          curl_easy_getinfo() calls (or similar). The point being that we
+ *          must never expose complex structs to applications, as then we'll
+ *          undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ *          of structs. It also writes the number of messages left in the
+ *          queue (after this read) in the integer the second argument points
+ *          to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+                                          int *msgs_in_queue);
+
+/*
+ * Name:    curl_multi_strerror()
+ *
+ * Desc:    The curl_multi_strerror function may be used to turn a CURLMcode
+ *          value into the equivalent human readable error string.  This is
+ *          useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name:    curl_multi_socket() and
+ *          curl_multi_socket_all()
+ *
+ * Desc:    An alternative version of curl_multi_perform() that allows the
+ *          application to pass in one of the file descriptors that have been
+ *          detected to have "action" on them and let libcurl perform.
+ *          See man page for details.
+ */
+#define CURL_POLL_NONE   0
+#define CURL_POLL_IN     1
+#define CURL_POLL_OUT    2
+#define CURL_POLL_INOUT  3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN   0x01
+#define CURL_CSELECT_OUT  0x02
+#define CURL_CSELECT_ERR  0x04
+
+typedef int (*curl_socket_callback)(CURL *easy,      /* easy handle */
+                                    curl_socket_t s, /* socket */
+                                    int what,        /* see above */
+                                    void *userp,     /* private callback
+                                                        pointer */
+                                    void *socketp);  /* private socket
+                                                        pointer */
+/*
+ * Name:    curl_multi_timer_callback
+ *
+ * Desc:    Called by libcurl whenever the library detects a change in the
+ *          maximum number of milliseconds the app is allowed to wait before
+ *          curl_multi_socket() or curl_multi_perform() must be called
+ *          (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi,    /* multi handle */
+                                         long timeout_ms, /* see above */
+                                         void *userp);    /* private callback
+                                                             pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+                                        int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+                                               curl_socket_t s,
+                                               int ev_bitmask,
+                                               int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+                                            int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+   the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name:    curl_multi_timeout()
+ *
+ * Desc:    Returns the maximum number of milliseconds the app is allowed to
+ *          wait before curl_multi_socket() or curl_multi_perform() must be
+ *          called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+                                         long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+  /* This is the socket callback function pointer */
+  CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+  /* This is the argument passed to the socket callback */
+  CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+    /* set to 1 to enable pipelining for this multi handle */
+  CINIT(PIPELINING, LONG, 3),
+
+   /* This is the timer callback function pointer */
+  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+  /* This is the argument passed to the timer callback */
+  CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+  /* maximum number of entries in the connection cache */
+  CINIT(MAXCONNECTS, LONG, 6),
+
+  /* maximum number of (pipelining) connections to one host */
+  CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
+
+  /* maximum number of requests in a pipeline */
+  CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
+
+  /* a connection with a content-length longer than this
+     will not be considered for pipelining */
+  CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+
+  /* a connection with a chunk length longer than this
+     will not be considered for pipelining */
+  CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+
+  /* a list of site names(+port) that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
+
+  /* a list of server types that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+
+  /* maximum number of open connections in total */
+  CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
+
+   /* This is the server push callback function pointer */
+  CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+
+  /* This is the argument passed to the server push callback */
+  CINIT(PUSHDATA, OBJECTPOINT, 15),
+
+  CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name:    curl_multi_setopt()
+ *
+ * Desc:    Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+                                        CURLMoption option, ...);
+
+
+/*
+ * Name:    curl_multi_assign()
+ *
+ * Desc:    This function sets an association in the multi handle between the
+ *          given socket and a private pointer of the application. This is
+ *          (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+                                        curl_socket_t sockfd, void *sockp);
+
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ *       server. It approves or denies the new stream.
+ *
+ * Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
+ */
+#define CURL_PUSH_OK   0
+#define CURL_PUSH_DENY 1
+
+struct curl_pushheaders;  /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+                                        size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+                                         const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+                                  CURL *easy,
+                                  size_t num_headers,
+                                  struct curl_pushheaders *headers,
+                                  void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif

+ 33 - 0
TCL Copy Tool/Include/curl/stdcheaders.h

@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */

+ 493 - 0
TCL Copy Tool/Include/curl/system.h

@@ -0,0 +1,493 @@
+#ifndef __CURL_SYSTEM_H
+#define __CURL_SYSTEM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Try to keep one section per platform, compiler and architecture, otherwise,
+ * if an existing section is reused for a different one and later on the
+ * original is adjusted, probably the piggybacking one can be adversely
+ * changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures use
+ * only compiler built in predefined preprocessor symbols.
+ *
+ * curl_off_t
+ * ----------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
+ * wide signed integral data type. The width of this data type must remain
+ * constant and independent of any possible large file support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
+ * wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
+ * only be violated if off_t is the only 64-bit data type available and the
+ * size of off_t is independent of large file support settings. Keep your
+ * build on the safe side avoiding an off_t gating.  If you have a 64-bit
+ * off_t then take for sure that another 64-bit data type exists, dig deeper
+ * and you will find it.
+ *
+ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+#  if defined(__DJGPP__) && (__DJGPP__ > 1)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SALFORDC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__BORLANDC__)
+#  if (__BORLANDC__ < 0x520)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TURBOC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__WATCOMC__)
+#  if defined(__386__)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__POCC__)
+#  if (__POCC__ < 280)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  elif defined(_MSC_VER)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__LCC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SYMBIAN32__)
+#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__CW32__)
+#    pragma longlong on
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__VC32__)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__MWERKS__)
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "lld"
+#  define CURL_FORMAT_CURL_OFF_TU    "llu"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(_WIN32_WCE)
+#  define CURL_TYPEOF_CURL_OFF_T     __int64
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_SUFFIX_CURL_OFF_T     i64
+#  define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__MINGW32__)
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_WS2TCPIP_H       1
+
+#elif defined(__VMS)
+#  if defined(__VAX)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#    elif defined(_LP64)
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#    elif defined(_LP64)
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TINYC__) /* also known as tcc */
+
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "lld"
+#  define CURL_FORMAT_CURL_OFF_TU    "llu"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
+#  if !defined(__LP64) && (defined(__ILP32) ||                          \
+                           defined(__i386) ||                           \
+                           defined(__sparcv8) ||                        \
+                           defined(__sparcv8plus))
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64) || \
+        defined(__amd64) || defined(__sparcv9)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#elif defined(__xlc__) /* IBM xlc compiler */
+#  if !defined(_LP64)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__) && !defined(_SCO_DS)
+#  if !defined(__LP64__) &&                                             \
+  (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) ||      \
+   defined(__ppc__) || defined(__powerpc__) || defined(__arm__) ||      \
+   defined(__sparc__) || defined(__mips__) || defined(__sh__) ||        \
+   defined(__XTENSA__) ||                                               \
+   (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4)  ||               \
+   (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64__) || \
+        defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+        (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
+        (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#else
+/* generic "safe guess" on old 32 bit style */
+# define CURL_TYPEOF_CURL_OFF_T     long
+# define CURL_FORMAT_CURL_OFF_T     "ld"
+# define CURL_FORMAT_CURL_OFF_TU    "lu"
+# define CURL_SUFFIX_CURL_OFF_T     L
+# define CURL_SUFFIX_CURL_OFF_TU    UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+#endif
+
+#ifdef _AIX
+/* AIX needs <sys/poll.h> */
+#define CURL_PULL_SYS_POLL_H
+#endif
+
+
+/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file  */
+/* ws2tcpip.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_WS2TCPIP_H
+#  include <winsock2.h>
+#  include <windows.h>
+#  include <ws2tcpip.h>
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file  */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file  */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file    */
+/* sys/poll.h is required here to properly make type definitions below.   */
+#ifdef CURL_PULL_SYS_POLL_H
+#  include <sys/poll.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+  typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+  typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or  __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+  defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+  defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+  defined(__ILEC400__)
+  /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+  /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+#  define __CURL_OFF_T_C_HLPR2(x) x
+#  define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+#  ifdef CURL_ISOCPP
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+#  else
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+#  endif
+#  define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+#endif /* __CURL_SYSTEM_H */

+ 700 - 0
TCL Copy Tool/Include/curl/typecheck-gcc.h

@@ -0,0 +1,700 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ *   if(_curl_is_sometype_option(_curl_opt))
+ *     if(!_curl_is_sometype(value))
+ *       _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ *       order to work around gcc bug #32061.  It affects only gcc 4.3.x/4.4.x
+ *       when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value)                               \
+__extension__ ({                                                              \
+  __typeof__(option) _curl_opt = option;                                     \
+  if(__builtin_constant_p(_curl_opt)) {                                       \
+    if(_curl_is_long_option(_curl_opt))                                       \
+      if(!_curl_is_long(value))                                               \
+        _curl_easy_setopt_err_long();                                         \
+    if(_curl_is_off_t_option(_curl_opt))                                      \
+      if(!_curl_is_off_t(value))                                              \
+        _curl_easy_setopt_err_curl_off_t();                                   \
+    if(_curl_is_string_option(_curl_opt))                                     \
+      if(!_curl_is_string(value))                                             \
+        _curl_easy_setopt_err_string();                                       \
+    if(_curl_is_write_cb_option(_curl_opt))                                   \
+      if(!_curl_is_write_cb(value))                                           \
+        _curl_easy_setopt_err_write_callback();                               \
+    if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)                        \
+      if(!_curl_is_resolver_start_callback(value))                            \
+        _curl_easy_setopt_err_resolver_start_callback();                      \
+    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
+      if(!_curl_is_read_cb(value))                                            \
+        _curl_easy_setopt_err_read_cb();                                      \
+    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
+      if(!_curl_is_ioctl_cb(value))                                           \
+        _curl_easy_setopt_err_ioctl_cb();                                     \
+    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
+      if(!_curl_is_sockopt_cb(value))                                         \
+        _curl_easy_setopt_err_sockopt_cb();                                   \
+    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
+      if(!_curl_is_opensocket_cb(value))                                      \
+        _curl_easy_setopt_err_opensocket_cb();                                \
+    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
+      if(!_curl_is_progress_cb(value))                                        \
+        _curl_easy_setopt_err_progress_cb();                                  \
+    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
+      if(!_curl_is_debug_cb(value))                                           \
+        _curl_easy_setopt_err_debug_cb();                                     \
+    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
+      if(!_curl_is_ssl_ctx_cb(value))                                         \
+        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
+    if(_curl_is_conv_cb_option(_curl_opt))                                    \
+      if(!_curl_is_conv_cb(value))                                            \
+        _curl_easy_setopt_err_conv_cb();                                      \
+    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
+      if(!_curl_is_seek_cb(value))                                            \
+        _curl_easy_setopt_err_seek_cb();                                      \
+    if(_curl_is_cb_data_option(_curl_opt))                                    \
+      if(!_curl_is_cb_data(value))                                            \
+        _curl_easy_setopt_err_cb_data();                                      \
+    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
+      if(!_curl_is_error_buffer(value))                                       \
+        _curl_easy_setopt_err_error_buffer();                                 \
+    if((_curl_opt) == CURLOPT_STDERR)                                         \
+      if(!_curl_is_FILE(value))                                               \
+        _curl_easy_setopt_err_FILE();                                         \
+    if(_curl_is_postfields_option(_curl_opt))                                 \
+      if(!_curl_is_postfields(value))                                         \
+        _curl_easy_setopt_err_postfields();                                   \
+    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
+      if(!_curl_is_arr((value), struct curl_httppost))                        \
+        _curl_easy_setopt_err_curl_httpost();                                 \
+    if((_curl_opt) == CURLOPT_MIMEPOST)                                       \
+      if(!_curl_is_ptr((value), curl_mime))                                   \
+        _curl_easy_setopt_err_curl_mimepost();                                \
+    if(_curl_is_slist_option(_curl_opt))                                      \
+      if(!_curl_is_arr((value), struct curl_slist))                           \
+        _curl_easy_setopt_err_curl_slist();                                   \
+    if((_curl_opt) == CURLOPT_SHARE)                                          \
+      if(!_curl_is_ptr((value), CURLSH))                                      \
+        _curl_easy_setopt_err_CURLSH();                                       \
+  }                                                                           \
+  curl_easy_setopt(handle, _curl_opt, value);                                 \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg)                                  \
+__extension__ ({                                                              \
+  __typeof__(info) _curl_info = info;                                         \
+  if(__builtin_constant_p(_curl_info)) {                                      \
+    if(_curl_is_string_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), char *))                                        \
+        _curl_easy_getinfo_err_string();                                      \
+    if(_curl_is_long_info(_curl_info))                                        \
+      if(!_curl_is_arr((arg), long))                                          \
+        _curl_easy_getinfo_err_long();                                        \
+    if(_curl_is_double_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), double))                                        \
+        _curl_easy_getinfo_err_double();                                      \
+    if(_curl_is_slist_info(_curl_info))                                       \
+      if(!_curl_is_arr((arg), struct curl_slist *))                           \
+        _curl_easy_getinfo_err_curl_slist();                                  \
+    if(_curl_is_tlssessioninfo_info(_curl_info))                              \
+      if(!_curl_is_arr((arg), struct curl_tlssessioninfo *))                  \
+        _curl_easy_getinfo_err_curl_tlssesssioninfo();                        \
+    if(_curl_is_certinfo_info(_curl_info))                                    \
+      if(!_curl_is_arr((arg), struct curl_certinfo *))                        \
+        _curl_easy_getinfo_err_curl_certinfo();                               \
+    if(_curl_is_socket_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), curl_socket_t))                                 \
+        _curl_easy_getinfo_err_curl_socket();                                 \
+    if(_curl_is_off_t_info(_curl_info))                                       \
+      if(!_curl_is_arr((arg), curl_off_t))                                    \
+        _curl_easy_getinfo_err_curl_off_t();                                  \
+  }                                                                           \
+  curl_easy_getinfo(handle, _curl_info, arg);                                 \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message)                                            \
+  static void __attribute__((__warning__(message)))                           \
+  __attribute__((__unused__)) __attribute__((__noinline__))                   \
+  id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+  "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+  "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+              "curl_easy_setopt expects a "
+              "string ('char *' or char[]) argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+  "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback,
+              "curl_easy_setopt expects a "
+              "curl_resolver_start_callback argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+  "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+              "curl_easy_setopt expects a "
+              "curl_opensocket_callback argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+  "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+  "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+  "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+  "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+              "curl_easy_setopt expects a "
+              "private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+              "curl_easy_setopt expects a "
+              "char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+  "curl_easy_setopt expects a 'FILE *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+  "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+              "curl_easy_setopt expects a 'struct curl_httppost *' "
+              "argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost,
+              "curl_easy_setopt expects a 'curl_mime *' "
+              "argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+  "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+  "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+  "curl_easy_getinfo expects a pointer to 'char *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+  "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+  "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+  "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+              "curl_easy_getinfo expects a pointer to "
+              "'struct curl_tlssessioninfo *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo,
+              "curl_easy_getinfo expects a pointer to "
+              "'struct curl_certinfo *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_socket,
+  "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
+  "curl_easy_getinfo expects a pointer to curl_off_t for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ *   (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option)                                          \
+  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option)                                         \
+  ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option)                                        \
+  ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
+   (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
+   (option) == CURLOPT_ALTSVC ||                                              \
+   (option) == CURLOPT_CAINFO ||                                              \
+   (option) == CURLOPT_CAPATH ||                                              \
+   (option) == CURLOPT_COOKIE ||                                              \
+   (option) == CURLOPT_COOKIEFILE ||                                          \
+   (option) == CURLOPT_COOKIEJAR ||                                           \
+   (option) == CURLOPT_COOKIELIST ||                                          \
+   (option) == CURLOPT_CRLFILE ||                                             \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
+   (option) == CURLOPT_DEFAULT_PROTOCOL ||                                    \
+   (option) == CURLOPT_DNS_INTERFACE ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
+   (option) == CURLOPT_DNS_SERVERS ||                                         \
+   (option) == CURLOPT_DOH_URL ||                                             \
+   (option) == CURLOPT_EGDSOCKET ||                                           \
+   (option) == CURLOPT_FTPPORT ||                                             \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_INTERFACE ||                                           \
+   (option) == CURLOPT_ISSUERCERT ||                                          \
+   (option) == CURLOPT_KEYPASSWD ||                                           \
+   (option) == CURLOPT_KRBLEVEL ||                                            \
+   (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
+   (option) == CURLOPT_MAIL_AUTH ||                                           \
+   (option) == CURLOPT_MAIL_FROM ||                                           \
+   (option) == CURLOPT_NETRC_FILE ||                                          \
+   (option) == CURLOPT_NOPROXY ||                                             \
+   (option) == CURLOPT_PASSWORD ||                                            \
+   (option) == CURLOPT_PINNEDPUBLICKEY ||                                     \
+   (option) == CURLOPT_PRE_PROXY ||                                           \
+   (option) == CURLOPT_PROXY ||                                               \
+   (option) == CURLOPT_PROXYPASSWORD ||                                       \
+   (option) == CURLOPT_PROXYUSERNAME ||                                       \
+   (option) == CURLOPT_PROXYUSERPWD ||                                        \
+   (option) == CURLOPT_PROXY_CAINFO ||                                        \
+   (option) == CURLOPT_PROXY_CAPATH ||                                        \
+   (option) == CURLOPT_PROXY_CRLFILE ||                                       \
+   (option) == CURLOPT_PROXY_KEYPASSWD ||                                     \
+   (option) == CURLOPT_PROXY_PINNEDPUBLICKEY ||                               \
+   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
+   (option) == CURLOPT_PROXY_SSLCERT ||                                       \
+   (option) == CURLOPT_PROXY_SSLCERTTYPE ||                                   \
+   (option) == CURLOPT_PROXY_SSLKEY ||                                        \
+   (option) == CURLOPT_PROXY_SSLKEYTYPE ||                                    \
+   (option) == CURLOPT_PROXY_SSL_CIPHER_LIST ||                               \
+   (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD ||                              \
+   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                              \
+   (option) == CURLOPT_PROXY_TLSAUTH_TYPE ||                                  \
+   (option) == CURLOPT_RANDOM_FILE ||                                         \
+   (option) == CURLOPT_RANGE ||                                               \
+   (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
+   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
+   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SERVICE_NAME ||                                        \
+   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
+   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
+   (option) == CURLOPT_SSLCERT ||                                             \
+   (option) == CURLOPT_SSLCERTTYPE ||                                         \
+   (option) == CURLOPT_SSLENGINE ||                                           \
+   (option) == CURLOPT_SSLKEY ||                                              \
+   (option) == CURLOPT_SSLKEYTYPE ||                                          \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_TLSAUTH_PASSWORD ||                                    \
+   (option) == CURLOPT_TLSAUTH_TYPE ||                                        \
+   (option) == CURLOPT_TLSAUTH_USERNAME ||                                    \
+   (option) == CURLOPT_UNIX_SOCKET_PATH ||                                    \
+   (option) == CURLOPT_URL ||                                                 \
+   (option) == CURLOPT_USERAGENT ||                                           \
+   (option) == CURLOPT_USERNAME ||                                            \
+   (option) == CURLOPT_USERPWD ||                                             \
+   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
+   0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option)                                      \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+   (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option)                                       \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option)                                       \
+  ((option) == CURLOPT_CHUNK_DATA ||                                          \
+   (option) == CURLOPT_CLOSESOCKETDATA ||                                     \
+   (option) == CURLOPT_DEBUGDATA ||                                           \
+   (option) == CURLOPT_FNMATCH_DATA ||                                        \
+   (option) == CURLOPT_HEADERDATA ||                                          \
+   (option) == CURLOPT_INTERLEAVEDATA ||                                      \
+   (option) == CURLOPT_IOCTLDATA ||                                           \
+   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
+   (option) == CURLOPT_PRIVATE ||                                             \
+   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_READDATA ||                                            \
+   (option) == CURLOPT_SEEKDATA ||                                            \
+   (option) == CURLOPT_SOCKOPTDATA ||                                         \
+   (option) == CURLOPT_SSH_KEYDATA ||                                         \
+   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
+   (option) == CURLOPT_WRITEDATA ||                                           \
+   (option) == CURLOPT_RESOLVER_START_DATA ||                                 \
+   (option) == CURLOPT_CURLU ||                                               \
+   0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option)                                    \
+  ((option) == CURLOPT_POSTFIELDS ||                                          \
+   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
+   0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option)                                         \
+  ((option) == CURLOPT_HTTP200ALIASES ||                                      \
+   (option) == CURLOPT_HTTPHEADER ||                                          \
+   (option) == CURLOPT_MAIL_RCPT ||                                           \
+   (option) == CURLOPT_POSTQUOTE ||                                           \
+   (option) == CURLOPT_PREQUOTE ||                                            \
+   (option) == CURLOPT_PROXYHEADER ||                                         \
+   (option) == CURLOPT_QUOTE ||                                               \
+   (option) == CURLOPT_RESOLVE ||                                             \
+   (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info)                                            \
+  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info)                                              \
+  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info)                                            \
+  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info)                                       \
+  (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
+
+/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
+#define _curl_is_tlssessioninfo_info(info)                              \
+  (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
+
+/* true if info expects a pointer to struct curl_certinfo * argument */
+#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+
+/* true if info expects a pointer to struct curl_socket_t argument */
+#define _curl_is_socket_info(info)                                            \
+  (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
+
+/* true if info expects a pointer to curl_off_t argument */
+#define _curl_is_off_t_info(info)                                             \
+  (CURLINFO_OFF_T < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true if expr is a pointer */
+#define _curl_is_any_ptr(expr)                                                \
+  (sizeof(expr) == sizeof(void *))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type)                                              \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type)                                              \
+  (_curl_is_ptr((expr), type) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr)                                                 \
+  (_curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), signed char) ||                                       \
+   _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
+   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
+   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
+   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
+   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr)                                                  \
+  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr)                                           \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr)                                                \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr)                                                \
+  _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr)                                             \
+  (_curl_is_NULL(expr) ||                                              \
+   (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr)                                             \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), unsigned char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type)                                 \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+   __builtin_types_compatible_p(__typeof__(func) *, type))
+
+/* evaluates to true if expr is of type curl_resolver_start_callback */
+#define _curl_is_resolver_start_callback(expr)       \
+  (_curl_is_NULL(expr) || \
+   _curl_callback_compatible((expr), curl_resolver_start_callback))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), __typeof__(fread) *) ||                  \
+   _curl_callback_compatible((expr), curl_read_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr)                                               \
+  (_curl_is_read_cb(expr) ||                                            \
+   _curl_callback_compatible((expr), __typeof__(fwrite) *) ||                 \
+   _curl_callback_compatible((expr), curl_write_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
+                                       const void *);
+typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
+                                       const void *);
+typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_ioctl_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
+typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
+typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
+typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_sockopt_callback) ||                \
+   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
+                                      curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+   "similar" */
+#define _curl_is_opensocket_cb(expr)                                    \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_opensocket_callback) ||             \
+   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (*_curl_opensocket_callback1)
+  (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback2)
+  (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback3)
+  (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback4)
+  (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr)                                      \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_progress_callback) ||               \
+   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
+   _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (*_curl_progress_callback1)(void *,
+    double, double, double, double);
+typedef int (*_curl_progress_callback2)(const void *,
+    double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_debug_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback8))
+typedef int (*_curl_debug_callback1) (CURL *,
+    curl_infotype, char *, size_t, void *);
+typedef int (*_curl_debug_callback2) (CURL *,
+    curl_infotype, char *, size_t, const void *);
+typedef int (*_curl_debug_callback3) (CURL *,
+    curl_infotype, const char *, size_t, void *);
+typedef int (*_curl_debug_callback4) (CURL *,
+    curl_infotype, const char *, size_t, const void *);
+typedef int (*_curl_debug_callback5) (CURL *,
+    curl_infotype, unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback6) (CURL *,
+    curl_infotype, unsigned char *, size_t, const void *);
+typedef int (*_curl_debug_callback7) (CURL *,
+    curl_infotype, const unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback8) (CURL *,
+    curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_ssl_ctx_callback) ||                \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
+                                            const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+                                           const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_conv_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_seek_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */

+ 122 - 0
TCL Copy Tool/Include/curl/urlapi.h

@@ -0,0 +1,122 @@
+#ifndef __CURL_URLAPI_H
+#define __CURL_URLAPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* the error codes for the URL API */
+typedef enum {
+  CURLUE_OK,
+  CURLUE_BAD_HANDLE,          /* 1 */
+  CURLUE_BAD_PARTPOINTER,     /* 2 */
+  CURLUE_MALFORMED_INPUT,     /* 3 */
+  CURLUE_BAD_PORT_NUMBER,     /* 4 */
+  CURLUE_UNSUPPORTED_SCHEME,  /* 5 */
+  CURLUE_URLDECODE,           /* 6 */
+  CURLUE_OUT_OF_MEMORY,       /* 7 */
+  CURLUE_USER_NOT_ALLOWED,    /* 8 */
+  CURLUE_UNKNOWN_PART,        /* 9 */
+  CURLUE_NO_SCHEME,           /* 10 */
+  CURLUE_NO_USER,             /* 11 */
+  CURLUE_NO_PASSWORD,         /* 12 */
+  CURLUE_NO_OPTIONS,          /* 13 */
+  CURLUE_NO_HOST,             /* 14 */
+  CURLUE_NO_PORT,             /* 15 */
+  CURLUE_NO_QUERY,            /* 16 */
+  CURLUE_NO_FRAGMENT          /* 17 */
+} CURLUcode;
+
+typedef enum {
+  CURLUPART_URL,
+  CURLUPART_SCHEME,
+  CURLUPART_USER,
+  CURLUPART_PASSWORD,
+  CURLUPART_OPTIONS,
+  CURLUPART_HOST,
+  CURLUPART_PORT,
+  CURLUPART_PATH,
+  CURLUPART_QUERY,
+  CURLUPART_FRAGMENT
+} CURLUPart;
+
+#define CURLU_DEFAULT_PORT (1<<0)       /* return default port number */
+#define CURLU_NO_DEFAULT_PORT (1<<1)    /* act as if no port number was set,
+                                           if the port number matches the
+                                           default for the scheme */
+#define CURLU_DEFAULT_SCHEME (1<<2)     /* return default scheme if
+                                           missing */
+#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
+#define CURLU_PATH_AS_IS (1<<4)         /* leave dot sequences */
+#define CURLU_DISALLOW_USER (1<<5)      /* no user+password allowed */
+#define CURLU_URLDECODE (1<<6)          /* URL decode on get */
+#define CURLU_URLENCODE (1<<7)          /* URL encode on set */
+#define CURLU_APPENDQUERY (1<<8)        /* append a form style part */
+#define CURLU_GUESS_SCHEME (1<<9)       /* legacy curl-style guessing */
+
+typedef struct Curl_URL CURLU;
+
+/*
+ * curl_url() creates a new CURLU handle and returns a pointer to it.
+ * Must be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url(void);
+
+/*
+ * curl_url_cleanup() frees the CURLU handle and related resources used for
+ * the URL parsing. It will not free strings previously returned with the URL
+ * API.
+ */
+CURL_EXTERN void curl_url_cleanup(CURLU *handle);
+
+/*
+ * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
+ * handle must also be freed with curl_url_cleanup().
+ */
+CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
+
+/*
+ * curl_url_get() extracts a specific part of the URL from a CURLU
+ * handle. Returns error code. The returned pointer MUST be freed with
+ * curl_free() afterwards.
+ */
+CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
+                                   char **part, unsigned int flags);
+
+/*
+ * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
+ * error code. The passed in string will be copied. Passing a NULL instead of
+ * a part string, clears that part.
+ */
+CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
+                                   const char *part, unsigned int flags);
+
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif

+ 1 - 0
TCL Copy Tool/Licence.txt

@@ -0,0 +1 @@
+scbc tools

+ 376 - 0
TCL Copy Tool/Log4C/GlobalMacro.h

@@ -0,0 +1,376 @@
+/************** Begin of GlobalMacro.h *******************************************/
+/**********************************************************
+* 版权所有 (C)2008, 51.com
+*
+* 文件名称:GlobalMacro.h
+* 内容摘要:全局宏定义的头文件
+*			本文件包含了所有要用到的全局宏的定义
+* 其它说明:
+* 当前版本:
+* 作    者:温辉敏
+* 完成日期:2009-1-02
+*
+* 修改记录1:
+*    修改日期:
+*    版 本 号:
+*    修 改 人:
+*    修改内容:
+**********************************************************/
+#if !defined(AFX_GLOBALMACRO_H__DD58A78D_C125_410F_B4C8_F0067B797121__INCLUDED_)
+#define AFX_GLOBALMACRO_H__DD58A78D_C125_410F_B4C8_F0067B797121__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// 获取数组的维数 [7/1/2008 温辉敏]
+#define PARRAYSIZE(array) ((sizeof(array)/sizeof(array[0])))
+
+/** Declare all the standard PWlib class information.
+This macro is used to provide the basic run-time typing capability needed
+by the library. All descendent classes from the #PObject# class require
+these functions for correct operation. Either use ptrThis macro or the
+#PDECLARE_CLASS# macro.
+
+The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
+of compatibility with documentation systems.
+*/
+#define CLASSINFO(cls, par) \
+  public: \
+	static const char * Class() \
+	{ return #cls; } \
+	virtual const char * GetClass(unsigned ancestor = 0) const \
+	{ return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
+	virtual BOOL IsClass(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0; } \
+	virtual BOOL IsDescendant(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0 || \
+	  par::IsDescendant(clsName); } 
+
+
+/** Declare all the standard PWlib class information.
+This macro is used to provide the basic run-time typing capability needed
+by the library. All descendent classes from the #PObject# class require
+these functions for correct operation. Either use ptrThis macro or the
+#PDECLARE_CLASS# macro.
+
+The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
+of compatibility with documentation systems.
+*/
+#define CLASSINFO_BASE(cls) \
+  public: \
+	static const char * Class() \
+	{ return #cls; } \
+	virtual const char * GetClass(unsigned ancestor = 0) const \
+	{ return cls::Class(); } \
+	virtual BOOL IsClass(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0; } \
+	virtual BOOL IsDescendant(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0; } 
+
+
+/* 函数返回基本状态信息  */
+#ifdef OK
+#undef OK
+#endif /* #ifdef OK */
+#ifndef OK
+#define OK               (0)    /* 成功返回	*/
+#endif /* #ifndef OK */
+
+/* 函数返回基本状态信息  */
+#ifdef FAILURE
+#undef FAILURE
+#endif /* #ifdef FAILURE */
+#ifndef FAILURE
+#define FAILURE           (-1)    /* 失败返回	*/
+#endif /* #ifndef FAILURE */
+
+//////////////////////////////////////////////////////////////////////////
+///一些宏定义
+
+///删除一个数组指针的宏定义
+//lint -emacro(774, DELETEA)
+#ifndef DELETEA
+#define DELETEA(ptr) \
+	if(NULL != ptr) \
+	{ \
+		delete[] ptr; \
+		ptr = NULL; \
+	}
+#endif
+
+///删除一个指针的宏定义
+#ifndef FREEP
+#define FREEP(ptr)		\
+	if(NULL != ptr)		\
+	{					\
+		free(ptr) ;		\
+		ptr = NULL;		\
+	}
+#endif
+
+///删除一个指针的宏定义
+//lint -emacro(774, DELETEP)
+#define DELETEP(ptr)	\
+	if(NULL != (ptr))		\
+	{					\
+		delete (ptr);		\
+		(ptr) = NULL;		\
+	}
+
+///删除一个GDI对象的宏定义
+//lint -emacro(774, DELETEOBJECT)
+#define DELETEOBJECT(ptr)	\
+	if(NULL != (ptr))		\
+	{					\
+		::DeleteObject (ptr);		\
+		(ptr) = NULL;		\
+	}
+
+///Destroy一个Window
+//lint -emacro(774, DESTROYWINDOW)
+#define DESTROYWINDOW(hWnd)	\
+	if (IsWindow(hWnd)) \
+	{ \
+		DestroyWindow(hWnd); \
+	}
+
+///删除一个指针的宏定义
+//lint -emacro(774, FREEP)
+#undef  FREEP
+#define FREEP(ptr)		\
+	if(NULL != ptr)		\
+	{					\
+		free(ptr) ;		\
+		ptr = NULL;		\
+	}
+
+
+/** 定义的根据输入类型来删除不同类型的指针的宏定义
+*/
+#define DELETE_TYPE_P(Type, ptrEvent) \
+	{\
+		Type *ptrEventLocal = (Type *)ptrEvent; \
+		DELETEP(ptrEventLocal); \
+		ptrEvent = NULL; \
+	}
+
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行statement语句,然后以return_value值return
+*/
+#define PAssert_ReturnWithValue(condition, return_value) \
+	{  \
+		if (!(condition)) \
+		{ \
+			return (return_value); \
+		} \
+	}
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行statement语句,然后return
+*/
+#define PAssert_Return(condition) \
+	{  \
+		if (!(condition)) \
+		{ \
+			return ; \
+		} \
+	}
+
+#ifndef VOS_DELETE_SEM
+#define VOS_DELETE_SEM(semId)	\
+	if (NULL != semId)			\
+	{							\
+		VOS_DeleteSem(semId);	\
+		semId = NULL;			\
+	}
+#endif
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行statement语句,然后以return_value值return
+*/
+#define PAssert_Statement_ReturnWithValue(condition, statement, return_value) \
+	{  \
+		if (!(condition)) \
+		{ \
+			statement; \
+			return (return_value); \
+		} \
+	}
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行statement语句,然后return
+*/
+#define PAssert_Statement_Return(condition, statement) \
+	{  \
+		if (!(condition)) \
+		{ \
+			statement; \
+			return ; \
+		} \
+	}
+
+/** This macro is used to assert that a pointer must be non-null.
+若指针ptr为NULL则执行statement语句,然后以return_value值return
+*/
+#define PAssertNotNull_Statement_ReturnWithValue(ptr, statement, return_value) \
+	{ \
+		if( (ptr) == NULL) \
+		{ \
+			statement; \
+			return (return_value); \
+		} \
+	}
+
+
+/** This macro is used to assert that a pointer must be non-null.
+若指针ptr为NULL则执行statement语句,然后return
+*/
+#define PAssertNotNull_Statement_Return(ptr, statement) \
+	{ \
+		if( (ptr) == NULL) \
+		{ \
+			statement; \
+			return ; \
+		} \
+	}
+
+/** This macro is used to assert that a pointer must be non-null.
+若指针ptr为NULL则执行statement语句,然后以return_value值return
+*/
+#define PAssertNotNull_ReturnWithValue(ptr, return_value) \
+	{ \
+		if( (ptr) == NULL) \
+		{ \
+			return (return_value); \
+		} \
+	}
+
+
+/** This macro is used to assert that a pointer must be non-null.
+若指针ptr为NULL则执行statement语句,然后return
+*/
+#define PAssertNotNull_Return(ptr) \
+	{ \
+		if( (ptr) == NULL) \
+		{ \
+			return ; \
+		} \
+	}
+
+/** This macro is used to do something and return 
+执行一个语句statement,然后return return_value
+*/
+#define PStatement_Return(statement, return_value) \
+{ \
+	statement; \
+	return return_value; \
+}
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行break语句
+*/
+#define PAssert_Break(condition) \
+{  \
+	if (!(condition)) \
+	{ \
+		break ; \
+	} \
+}
+
+/** This macro is used to do something and break 
+执行一个语句statement,然后break
+*/
+#define PStatement_Break(statement) \
+{ \
+	statement; \
+	break; \
+}
+
+/** This macro is used to assert that a condition must be TRUE.
+若condition条件不成立则执行statement语句,然后执行break语句
+*/
+#define PAssert_Statement_Break(condition, statement) \
+{  \
+	if (!(condition)) \
+	{ \
+		statement; \
+		break ; \
+	} \
+}
+
+/** 空操作
+*/
+#define NULL_OPERATION
+
+// 获取数组的维数 
+#define PARRAYSIZE(array) ((sizeof(array)/sizeof(array[0])))
+
+/** Declare all the standard RTTI class information.
+This macro is used to provide the basic run-time typing capability needed
+by the library. All descendent classes from the #PObject# class require
+these functions for correct operation. Either use ptrThis macro or the
+#PDECLARE_CLASS# macro.
+
+The use of the #PDECLARE_CLASS# macro is no longer recommended for reasons
+of compatibility with documentation systems.
+*/
+#define CLASSINFO(cls, par) \
+  public: \
+	static const char * Class() \
+	{ return #cls; } \
+	virtual const char * GetClass(unsigned ancestor = 0) const \
+	{ return ancestor > 0 ? par::GetClass(ancestor-1) : cls::Class(); } \
+	virtual BOOL IsClass(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0; } \
+	virtual BOOL IsDescendant(const char * clsName) const \
+	{ return strcmp(clsName, cls::Class()) == 0 || \
+	par::IsDescendant(clsName); } 
+
+
+///memset缺省构造函数
+#ifndef MEMSET_CONSTRUCTOR
+#define MEMSET_CONSTRUCTOR(ClassType) \
+	ClassType() \
+	{ \
+		memset(this, 0, sizeof(ClassType)); \
+	}
+#endif
+
+#if 0
+#ifdef __cplusplus
+/** 
+按照特定数据类型删除该数据类型的数组指针
+*/
+#ifndef DELETE_ARRAY_TEMPLATE
+#define DELETE_ARRAY_TEMPLATE
+template <class classType>
+void DeleteArray(void *&ptr)
+{
+	classType *ptrClassType = (classType *)ptr;
+	DELETEA(ptrClassType);
+	ptr = NULL;
+}
+#endif
+
+/** 
+按照特定数据类型删除该数据类型的指针
+*/
+#ifndef DELETE_TEMPLATE
+#define DELETE_TEMPLATE
+template <class classType>
+void Delete(void *&ptr)
+{
+	classType *ptrClassType = (classType *)ptr;
+	DELETEP(ptrClassType);
+	ptr = NULL;
+}
+#endif
+#endif
+#endif
+
+
+#endif // !defined(AFX_GLOBALMACRO_H__DD58A78D_C125_410F_B4C8_F0067B797121__INCLUDED_)
+
+/************** End of GlobalMacro.h *******************************************/

+ 479 - 0
TCL Copy Tool/Log4C/Log4C.vcproj

@@ -0,0 +1,479 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Log4C"
+	ProjectGUID="{2CE4A92D-3CF6-4BFA-975A-C72EE8536141}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\Log4C"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LOG4C_EXPORTS;XML_STATIC;LOG4C_ENABLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				ModuleDefinitionFile="log4c.def"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/Log4C.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="lib/Log4C.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\Log4C"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LOG4C_EXPORTS;XML_STATIC;LOG4C_ENABLE"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="lib/Log4C.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\appender.c"
+				>
+			</File>
+			<File
+				RelativePath=".\appender_type_rollingfile.c"
+				>
+			</File>
+			<File
+				RelativePath=".\appender_type_stream.c"
+				>
+			</File>
+			<File
+				RelativePath=".\appender_type_stream2.c"
+				>
+			</File>
+			<File
+				RelativePath=".\category.c"
+				>
+			</File>
+			<File
+				RelativePath=".\init.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout_type_basic.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout_type_basic_r.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout_type_dated.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout_type_dated_r.c"
+				>
+			</File>
+			<File
+				RelativePath=".\layout_type_dated_threadid.c"
+				>
+			</File>
+			<File
+				RelativePath=".\log.c"
+				>
+			</File>
+			<File
+				RelativePath=".\log4c.def"
+				>
+			</File>
+			<File
+				RelativePath=".\logging_event.c"
+				>
+			</File>
+			<File
+				RelativePath=".\priority.c"
+				>
+			</File>
+			<File
+				RelativePath=".\rc.c"
+				>
+			</File>
+			<File
+				RelativePath=".\rollingpolicy.c"
+				>
+			</File>
+			<File
+				RelativePath=".\rollingpolicy_type_sizewin.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sharedmemory.c"
+				>
+			</File>
+			<File
+				RelativePath=".\version.c"
+				>
+			</File>
+			<File
+				RelativePath=".\vosnt.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="sd"
+			>
+			<File
+				RelativePath=".\sd\defs.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml-parser.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml-parser.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml-scanner.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml-scanner.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode-xml.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\domnode.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\error.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\error.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\expat.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\expat_external.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\factory.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\factory.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\hash.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\hash.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\list.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\list.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\malloc.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\malloc.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\sd_xplatform.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\sd_xplatform.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\sprintf.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\sprintf.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\stack.c"
+				>
+			</File>
+			<File
+				RelativePath=".\sd\stack.h"
+				>
+			</File>
+			<Filter
+				Name="include"
+				>
+				<File
+					RelativePath=".\log4c\appender.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\appender_type_rollingfile.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\appender_type_stream.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\appender_type_stream2.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\buffer.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\category.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\config-win32.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\defs.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\init.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\layout.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\layout_type_basic.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\layout_type_dated.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\location_info.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\logging_event.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\priority.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\rc.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\rollingpolicy.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\rollingpolicy_type_sizewin.h"
+					>
+				</File>
+				<File
+					RelativePath=".\log4c\version.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 3 - 0
TCL Copy Tool/Log4C/log4c.def

@@ -0,0 +1,3 @@
+EXPORTS
+	log4c_init
+	log4c_fini

+ 27 - 0
TCL Copy Tool/Log4C/log4c.h

@@ -0,0 +1,27 @@
+/* $Id$
+ *
+ * log4c.h
+ *
+ * Copyright 2001-2002, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_log4c_h
+#define log4c_log4c_h
+
+#define IMPLEMENT_LOG4C
+
+#include <log4c/version.h>
+#include <log4c/init.h>
+#include <log4c/rc.h>
+#include <log4c/appender.h>
+#include <log4c/rollingpolicy.h>
+#include <log4c/category.h>
+#include <log4c/layout.h>
+#include <log4c/logging_event.h>
+#include <log4c/priority.h>
+#include <log4c/log.h>
+
+#endif
+

+ 251 - 0
TCL Copy Tool/Log4C/log4c/appender.h

@@ -0,0 +1,251 @@
+/* $Id$
+ *
+ * appender.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_appender_h
+#define log4c_appender_h
+
+/**
+ * @file appender.h
+ *
+ * @brief Implement this interface for your own strategies for printing log
+ * statements.
+ *
+ * @todo the appender interface needs a better configuration system
+ * depending on the layout type. The udata field is a just a trick.
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+#include <stdio.h>
+
+__LOG4C_BEGIN_DECLS
+
+struct __log4c_appender;
+
+/**
+ * log4c appender class 
+ **/
+typedef struct __log4c_appender log4c_appender_t;
+
+/**
+ * @brief log4c appender type class
+ *
+ * Attributes description:
+ * 
+ * @li @c name appender type name 
+ * @li @c open
+ * @li @c append
+ * @li @c close
+ **/
+typedef struct log4c_appender_type {
+    const char*	  name;
+    int (*open)	  (log4c_appender_t*);
+    int (*append) (log4c_appender_t*, const log4c_logging_event_t*);
+    int (*close)  (log4c_appender_t*);
+} log4c_appender_type_t;
+
+/**
+ * Get a pointer to an existing appender type.
+ *
+ * @param a_name the name of the appender type to return.  
+ * @returns a pointer to an existing appender type, or NULL if no appender
+ * type with the specified name exists.
+ **/
+LOG4C_API const log4c_appender_type_t* log4c_appender_type_get(const char* a_name);
+
+/**
+ * Use this function to register an appender type with log4c.
+ * Once this is done you may refer to this type by name both 
+ * programmatically and in the log4c
+ * configuration file.
+ *
+ * @param a_type a pointer to the new appender type to set.
+ * @returns a pointer to the previous appender type of same name.
+ * 
+ * Example code fragment: 
+ * @code
+ * 
+ * const log4c_appender_type_t log4c_appender_type_s13_file = {
+ *   "s13_file",
+ *   s13_file_open,
+ *   s13_file_append,
+ *   s13_file_close,
+ * };
+ *  
+ *  log4c_appender_type_set(&log4c_appender_type_s13_file);
+ * @endcode
+ **/
+LOG4C_API const log4c_appender_type_t* log4c_appender_type_set(
+    const log4c_appender_type_t* a_type);
+
+/**
+ * Get a pointer to an existing appender.
+ *
+ * @param a_name the name of the appender to return.
+ * @returns a pointer to an existing appender, or NULL if no appender
+ * with the specfied name exists.
+ **/
+LOG4C_API log4c_appender_t* log4c_appender_get(const char* a_name);
+
+/**
+ * Constructor for log4c_appender_t. 
+ **/
+LOG4C_API log4c_appender_t* log4c_appender_new(const char* a_name);
+
+/**
+ * Destructor for log4c_appender_t.
+ **/
+LOG4C_API void log4c_appender_delete(log4c_appender_t* a_appender);
+
+/**
+ * @param a_appender the log4c_appender_t object
+ * @return the appender name
+ **/
+LOG4C_API const char* log4c_appender_get_name(const log4c_appender_t* a_appender);
+
+/**
+ * @param a_appender the log4c_appender_t object
+ * @return the appender operations
+ **/
+LOG4C_API const log4c_appender_type_t* log4c_appender_get_type(
+    const log4c_appender_t* a_appender);
+
+/**
+ * @param a_appender the log4c_appender_t object
+ * @return the appender layout
+ **/
+LOG4C_API const log4c_layout_t* log4c_appender_get_layout(
+    const log4c_appender_t* a_appender);
+
+/**
+ * @param a_appender the log4c_appender_t object
+ * @return the appender user data
+ **/
+LOG4C_API void* log4c_appender_get_udata(const log4c_appender_t* a_appender);
+
+/**
+ * sets the appender type
+ *
+ * @param a_appender the log4c_appender_t object
+ * @param a_type the new appender type
+ * @return the previous appender type
+ **/
+LOG4C_API const log4c_appender_type_t* log4c_appender_set_type(
+    log4c_appender_t* a_appender,
+    const log4c_appender_type_t* a_type);
+
+/**
+ * sets the appender user data
+ *
+ * @param a_appender the log4c_appender_t object
+ * @param a_udata the new appender user data
+ * @return the previous appender user data
+ **/
+LOG4C_API void* log4c_appender_set_udata(log4c_appender_t*	a_appender, 
+				      void* a_udata);
+
+/**
+ * sets the appender layout
+ *
+ * @param a_appender the log4c_appender_t object
+ * @param a_layout the new appender layout
+ * @return the previous appender layout
+ **/
+LOG4C_API const log4c_layout_t* log4c_appender_set_layout(
+    log4c_appender_t* a_appender,
+    const log4c_layout_t* a_layout);
+
+/**
+ * opens the appender.
+ *
+ * @param a_appender the log4c_appender_t object
+ **/
+LOG4C_API int log4c_appender_open(log4c_appender_t* a_appender);
+
+/**
+ * log in appender specific way.
+ *
+ * @param a_appender the log4c_appender object
+ * @param a_event the log4c_logging_event_t object to log.
+ **/
+LOG4C_API int log4c_appender_append(
+    log4c_appender_t* a_appender,
+    log4c_logging_event_t* a_event);
+
+/**
+* log in appender specific way.
+*
+* @param a_appender the log4c_appender object
+* @param a_event the log4c_logging_event_t object to log.
+**/
+LOG4C_API int log4c_appender_append_no_file_num_no_layout(
+	log4c_appender_t* a_appender,
+	log4c_logging_event_t* a_event);
+
+/**
+ * closes the appender
+ *
+ * @param a_appender the log4c_appender_t object
+ * @return zero if successful, -1 otherwise
+ **/
+LOG4C_API int log4c_appender_close(log4c_appender_t* a_appender);
+
+/**
+ * prints the appender on a stream
+ *
+ * @param a_appender the log4c_appender_t object
+ * @param a_stream the stream
+ **/
+LOG4C_API void log4c_appender_print(const log4c_appender_t* a_appender, 
+				 FILE* a_stream);
+     
+/**
+ * prints all the current registered appender types on a stream
+ *
+ * @param fp the stream
+ **/                            
+LOG4C_API void log4c_appender_types_print(FILE *fp);
+
+/** 删除本appender.c文件中定义的全局和静态的指针指向的内存,防止内存泄漏
+如:
+1.gs_types.
+2.
+@return void.
+作者:jesse 日期:2008.09.08
+*/
+LOG4C_API void log4c_appender_delete_global();
+
+/**
+ * Helper macro to define static appender types.
+ *
+ * @param a_type the log4c_appender_type_t object to define
+ * @warning needs GCC support: otherwise this macro does nothing
+ * @deprecated This macro, and the static initialialization
+ * of appenders in general, is deprecated. Use rather
+ * the log4c_appender_type_set() function to initialize your appenders
+ * before calling log4c_init() 
+ *
+ **/
+#ifdef __GNUC__
+#   define log4c_appender_type_define(a_type) \
+    typedef int log4c_appender_type_define_##a_type __attribute__((deprecated)); \
+    static log4c_appender_type_define_##a_type __unsused_var __attribute__ ((unused));
+#else
+#   define log4c_appender_type_define(a_type)
+#endif
+
+/**
+ * @internal
+ **/
+struct __sd_factory;
+LOG4C_API struct __sd_factory* log4c_appender_factory;
+
+__LOG4C_END_DECLS
+
+#endif

+ 71 - 0
TCL Copy Tool/Log4C/log4c/appender_typ_stream.h

@@ -0,0 +1,71 @@
+/************** Begin of log4c/appender_type_stream.h *******************************************/
+/* $Id$
+*
+* appender_type_stream.h
+* 
+* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_appender_type_stream_h
+#define log4c_appender_type_stream_h
+
+/**
+* @file appender_type_stream.h
+*
+* @brief Log4c stream appender interface.
+*
+* The stream appender uses a file handle @c FILE* for logging. The
+* appender's name is used as the file name which will be opened at first
+* log. An appender can also be associated to an opened file handle using
+* the log4c_appender_set_udata() method to update the appender user data
+* field. In ptrThis last case, the appender name has no meaning. 2 default
+* stream appenders are defined: @c "stdout" and @c "stderr".
+*
+* The following examples shows how to define and use stream appenders.
+* 
+* @li the simple way
+* @code
+*
+* log4c_appender_t* myappender;
+*
+* myappender = log4c_appender_get("myfile.log");
+* log4c_appender_set_type(myappender, &log4c_appender_type_stream);
+* 
+* @endcode
+*
+* @li the sophisticated way
+* @code
+*
+* log4c_appender_t* myappender;
+*
+* myappender = log4c_appender_get("myappender");
+*    
+* log4c_appender_set_type(myappender, &log4c_appender_type_stream);
+* log4c_appender_set_udata(myappender, fopen("myfile.log", "w"));
+*
+* @endcode
+*
+**/
+
+///#include <log4c/defs.h>
+///#include <log4c/appender.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+* Stream appender type definition.
+*
+* This should be used as a parameter to the log4c_appender_set_type()
+* routine to set the type of the appender.
+*
+**/
+extern const log4c_appender_type_t log4c_appender_type_stream;
+
+__LOG4C_END_DECLS
+
+#endif
+
+
+/************** End of log4c/appender_type_stream.h *******************************************/

+ 58 - 0
TCL Copy Tool/Log4C/log4c/appender_type_mmap.h

@@ -0,0 +1,58 @@
+/************** Begin of appender_type_mmap.h *******************************************/
+/* $Id$
+*
+* appender_type_mmap.h
+* 
+* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_appender_type_mmap_h
+#define log4c_appender_type_mmap_h
+
+/**
+* @file appender_type_mmap.h
+*
+* @brief Log4c mmap(2) appender interface.
+*
+* The mmap appender uses a fixed length memory mapped file for
+* logging. The appender's name is used as the file name which will be
+* opened and mapped to memory at first use. The memory mapped file is then
+* used as a rotating buffer in which logging events are written.
+*
+* The following examples shows how to define and use mmap appenders.
+* 
+* @code
+*
+* log4c_appender_t* myappender;
+*
+* myappender = log4c_appender_get("myfile.log");
+* log4c_appender_set_type(myappender, &log4c_appender_type_mmap);
+* 
+* @endcode
+*
+* @warning the file is not created at first use. It should already exist
+* and have a reasonable size, a mutilple of a page size.
+*
+**/
+///#include <log4c/defs.h>
+///#include <log4c/appender.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+* Mmap appender type definition.
+*
+* This should be used as a parameter to the log4c_appender_set_type()
+* routine to set the type of the appender.
+*
+**/
+extern const log4c_appender_type_t log4c_appender_type_mmap;
+
+__LOG4C_END_DECLS
+
+#endif
+
+
+/************** End of appender_type_mmap.h *******************************************/

+ 120 - 0
TCL Copy Tool/Log4C/log4c/appender_type_rollingfile.h

@@ -0,0 +1,120 @@
+/* $Id: appender_type_rollingfile.h
+ *
+ * appender_type_rollingfile.h
+ * 
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_appender_type_rollingfile_h
+#define log4c_appender_type_rollingfile_h
+
+/**
+ * @file appender_type_rollingfile.h
+ *
+ * @brief Log4c rolling file appender interface.
+ *
+ * The rolling file appender implements a logging mechanism of
+ * a list of files up to a maximum number.
+ *
+ * The files are written by default to the current directory with logging
+ * names folowing the pattern log.1, log.2 etc.  These parameters may
+ * be changed using the appropriate setter functions.
+ *
+ * If the appender fails to open logfiles for writing then the
+ * messages are logged to stderr--it will continue to try to open
+ * the zero-th file for writing at rollover events so if it succeeds
+ * at some point to open that file the messages will start to appear therein
+ * and will no longer be sent to stderr.
+ *
+ * Switching from logging from one file
+ * to the next is referred to as a 'rollover event'.
+ *
+ * The policy that determines when a rollover event should happen is
+ * called a 'rolling policy'.
+ *
+ * A mechanism is provided to allow different rolling policies to be defined.
+ *
+ * Log4c ships with (and defaults to) the classic size-window rollover policy:
+ * this triggers rollover when files reach a maximum size.  The first file in
+ * the list is
+ * always the current file; when a rollover event occurs files are shifted up
+ * by one position in the list--if the number of files in the list has already
+ * reached the max then the oldest file is rotated out of the window.
+ *
+ * See the documentation in the rollingpolicy_type_sizewin.h file for
+ * more details on the size-win rollover policy.
+ *
+*/
+
+#include <log4c/defs.h>
+#include <log4c/appender.h>
+#include <log4c/rollingpolicy.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * rollingfile appender type definition.
+ *
+ * This should be used as a parameter to the log4c_appender_set_type()
+ * routine to set the type of the appender.
+ *
+ **/
+LOG4C_API const log4c_appender_type_t log4c_appender_type_rollingfile;
+
+/**
+ * Get a new rolling file appender configuration object.
+ * @return a new rolling file appender configuration object, otherwise NULL.
+*/
+LOG4C_API rollingfile_udata_t *rollingfile_make_udata(void);
+
+/**
+ * Set the logging directory in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @param logdir the logging directory to set.
+ * @return zero if successful, non-zero otherwise.
+ */
+LOG4C_API int rollingfile_udata_set_logdir(rollingfile_udata_t *rfudatap,char* logdir);
+/**
+ * Set the prefix string in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @param prefix the logging files prfix to use.
+ * @return zero if successful, non-zero otherwise.
+ */                            
+LOG4C_API int rollingfile_udata_set_files_prefix(rollingfile_udata_t *rfudatap, char * prefix);
+
+LOG4C_API int rollingfile_udata_set_files_ext(rollingfile_udata_t *rfudatap, char * ext);
+/**
+ * Set the rolling policy in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @param policyp the logging files prfix to use.
+ * @return zero if successful, non-zero otherwise.
+ */                          
+LOG4C_API int rollingfile_udata_set_policy(rollingfile_udata_t* rfudatap,log4c_rollingpolicy_t* policyp);                       
+/**
+ * Get the logging directory in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @return the logging directory.
+ */                              
+LOG4C_API const char* rollingfile_udata_get_logdir(rollingfile_udata_t* rfudatap);
+              
+/**
+ * Get the prefix string in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @return the prefix.
+ */ 
+LOG4C_API const char* rollingfile_udata_get_files_prefix(rollingfile_udata_t* rfudatap);
+
+
+LOG4C_API const char* rollingfile_udata_get_files_ext(rollingfile_udata_t* rfudatap);
+
+/**
+ * Get the prefix string in this rolling file appender configuration.
+ * @param rfudatap the rolling file appender configuration object.
+ * @return the current size of the file being logged to.
+ */ 
+LOG4C_API long  rollingfile_get_current_file_size( rollingfile_udata_t* rfudatap);
+
+__LOG4C_END_DECLS
+
+#endif

+ 67 - 0
TCL Copy Tool/Log4C/log4c/appender_type_stream.h

@@ -0,0 +1,67 @@
+/* $Id$
+ *
+ * appender_type_stream.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_appender_type_stream_h
+#define log4c_appender_type_stream_h
+
+/**
+ * @file appender_type_stream.h
+ *
+ * @brief Log4c stream appender interface.
+ *
+ * The stream appender uses a file handle @c FILE* for logging. The
+ * appender's name is used as the file name which will be opened at first
+ * log. An appender can also be associated to an opened file handle using
+ * the log4c_appender_set_udata() method to update the appender user data
+ * field. In this last case, the appender name has no meaning. 2 default
+ * stream appenders are defined: @c "stdout" and @c "stderr".
+ *
+ * The following examples shows how to define and use stream appenders.
+ * 
+ * @li the simple way
+ * @code
+ *
+ * log4c_appender_t* myappender;
+ *
+ * myappender = log4c_appender_get("myfile.log");
+ * log4c_appender_set_type(myappender, &log4c_appender_type_stream);
+ * 
+ * @endcode
+ *
+ * @li the sophisticated way
+ * @code
+ *
+ * log4c_appender_t* myappender;
+ *
+ * myappender = log4c_appender_get("myappender");
+ *    
+ * log4c_appender_set_type(myappender, &log4c_appender_type_stream);
+ * log4c_appender_set_udata(myappender, fopen("myfile.log", "w"));
+ *
+ * @endcode
+ *
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/appender.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * Stream appender type definition.
+ *
+ * This should be used as a parameter to the log4c_appender_set_type()
+ * routine to set the type of the appender.
+ *
+ **/
+extern const log4c_appender_type_t log4c_appender_type_stream;
+
+__LOG4C_END_DECLS
+
+#endif

+ 130 - 0
TCL Copy Tool/Log4C/log4c/appender_type_stream2.h

@@ -0,0 +1,130 @@
+/* 
+ *
+ * appender_type_stream.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_appender_type_stream2_h
+#define log4c_appender_type_stream2_h
+
+/**
+ * @file appender_type_stream2.h
+ *
+ * @brief Log4c stream2 appender interface.
+ *
+ * The stream2 appender uses a file handle @c FILE* for logging.
+ * It can be used with @c stdout, @c stderr or a normal file.
+ * It is pretty primitive as it does not do file rotation, or have a maximum
+ * configurable file size etc. It improves on the stream appender in a few
+ * ways that make it a better starting point for new stream based appenders.
+ *
+ * It enhances the stream appender by allowing
+ * the default file pointer to be used in buffered or unbuffered mode.
+ * Also when you set the file pointer stream2 will not attempt to close
+ * it on exit which avoids it fighting with the owner of the file pointer.
+ * stream2 is configured via setter functions--the udata is
+ * not exposed directly.  This means that new options (eg. configure the open
+ * mode ) could be added to stream2 while maintaining backward compatability.
+ *
+ * The appender can be used with default values, for example as follows:
+ *
+ * @code
+ * log4c_appender_t* myappender;
+ *
+ * myappender = log4c_appender_get("/var/logs/mylog.log");
+ * log4c_appender_set_type(myappender,log4c_appender_type_get("stream2"));
+ *
+ * @endcode
+ *
+ * In this case the appender will  be configured automatically with default 
+ * values: 
+ * @li the filename is the same as the name of the appender,
+ * @c "/var/logs/mymlog.log"
+ * @li the file is opened in "w+" mode
+ * @li the default system buffer is used (cf; @c setbuf() ) in buffered mode
+ *
+ * The stream2 appender can be configured by passing it a file pointer
+ * to use.  In this case you manage the file pointer yourself--open,
+ * option setting, closing.  If you set the file pointer log4c will
+ * not close the file on exiting--you must do this:
+ * 
+ * @code
+ * log4c_appender_t* myappender;
+ * FILE * fp = fopen("myfile.log", "w");
+ *
+ * myappender = log4c_appender_get("myappender");
+ * log4c_appender_set_type(myappender, log4c_appender_type_get("stream2"));
+ * log4c_stream2_set_fp(stream2_appender,myfp);
+ *
+ * @endcode
+ *
+ * The default file pointer can be configured to use unbuffered mode.
+ * Buffered mode is typically 25%-50% faster than unbuffered mode but
+ * unbuffered mode is useful if your preference is for a more synchronized 
+ * log file:
+ *
+ * @code log4c_appender_t* myappender;
+ *
+ * myappender = log4c_appender_get("/var/logs/mylog.log");
+ * log4c_appender_set_type(myappender,log4c_appender_type_get("stream2"));
+ * log4c_stream2_set_flags(myappender, LOG4C_STREAM2_UNBUFFERED);
+ *
+ * @endcode
+ *
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/appender.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * Stream2 appender type definition.
+ *
+ * This should be used as a parameter to the log4c_appender_set_type()
+ * routine to set the type of the appender.
+ *
+ **/
+LOG4C_API const log4c_appender_type_t log4c_appender_type_stream2;
+
+/**
+ * Set the file pointer for this appender.
+ * @param this a pointer to the appender
+ * @param fp the file pointer this appender will use.  The caller is
+ * responsible for managing the file pointer (open, option setting, closing).
+ */      
+LOG4C_API void log4c_stream2_set_fp(log4c_appender_t* a_this, FILE *fp);
+
+/**
+ * Get the file pointer for this appender.
+ * @param this a pointer to the appender
+ * @return the file pointer for this appender.  If there's a problem
+ * returns NULL.
+ * 
+ */ 
+LOG4C_API FILE * log4c_stream2_get_fp(log4c_appender_t* a_this);
+
+
+/**
+ * Set the flags for this appender.
+ * @param this a pointer to the appender
+ * @param flags ar teh flags to set. These will overwrite the existing flags.
+ * Currently supported flags:  LOG4C_STREAM2_UNBUFFERED
+ * 
+ */
+LOG4C_API void log4c_stream2_set_flags(log4c_appender_t* a_this, int flags);
+#define LOG4C_STREAM2_UNBUFFERED 0x01
+
+/**
+ * Get the flags for this appender.
+ * @param this a pointer to the appender
+ * @return the flags for this appender. returns -1 if there was a problem.
+ */
+LOG4C_API int log4c_stream2_get_flags(log4c_appender_t* a_this);
+
+__LOG4C_END_DECLS
+
+#endif

+ 56 - 0
TCL Copy Tool/Log4C/log4c/appender_type_syslog.h

@@ -0,0 +1,56 @@
+/************** Begin of appender_type_syslog.h *******************************************/
+/* $Id$
+*
+* appender_type_syslog.h
+* 
+* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_appender_type_syslog_h
+#define log4c_appender_type_syslog_h
+
+/**
+* @file appender_type_syslog.h
+*
+* @brief Log4c syslog(3) appender interface.
+*
+* The syslog appender uses the syslog(3) interface for logging. The log4c
+* priorities are mapped to the syslog priorities and the appender name is
+* used as a syslog identifier. 1 default syslog appender is defined: @c
+* "syslog".
+*
+* The following examples shows how to define and use syslog appenders.
+* 
+* @code
+*
+* log4c_appender_t* myappender;
+*
+* myappender = log4c_appender_get("myappender");
+* log4c_appender_set_type(myappender, &log4c_appender_type_syslog);
+* 
+* @endcode
+*
+**/
+
+///#include <log4c/defs.h>
+///#include <log4c/appender.h>
+
+__LOG4C_BEGIN_DECLS
+
+	/**
+	* Syslog appender type definition.
+	*
+	* This should be used as a parameter to the log4c_appender_set_type()
+	* routine to set the type of the appender.
+	*
+	**/
+	extern const log4c_appender_type_t log4c_appender_type_syslog;
+
+__LOG4C_END_DECLS
+
+#endif
+
+
+	/************** End of appender_type_syslog.h *******************************************/

+ 46 - 0
TCL Copy Tool/Log4C/log4c/buffer.h

@@ -0,0 +1,46 @@
+/* $Id$
+ *
+ * buffer.h
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __log4c_buffer_h
+#define __log4c_buffer_h
+
+/**
+ * @file buffer.h
+ *
+ * @brief log4c buffer
+ *
+ **/
+
+#include <log4c/defs.h>
+#include <stddef.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * @brief buffer object
+ *
+ * Attributes description:
+ *
+ * @li @c size current size of the buffer
+ * @li @c maxsize maximum size of the buffer. 0 means no limitation.
+ * @li @c data raw data
+ **/
+typedef struct
+{
+    size_t buf_size;
+    size_t buf_maxsize;
+    char*  buf_data;
+
+} log4c_buffer_t;
+
+#define LOG4C_BUFFER_SIZE_DEFAULT  1024
+
+#define LOG4C_BUFFER_SIZE_MAX 1024*10
+
+__LOG4C_END_DECLS
+
+#endif

+ 651 - 0
TCL Copy Tool/Log4C/log4c/category.h

@@ -0,0 +1,651 @@
+/* $Id$
+ *
+ * category.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_category_h
+#define log4c_category_h
+
+/**
+ * @file category.h
+ *
+ * @brief central class in the log4c package. 
+ * 
+ * One of the distintive features of log4j (and hence log4c) are
+ * hierarchical categories and their evaluation.
+ *
+ **/   
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <log4c/defs.h>
+#include <log4c/priority.h>
+#include <log4c/location_info.h>
+
+__LOG4C_BEGIN_DECLS
+
+struct __log4c_appender;
+struct __log4c_category;
+
+/**
+ * log4c category class 
+ **/
+typedef struct __log4c_category	log4c_category_t;
+
+/**
+ * Instantiate a log4c_category_t with name @a name. This method
+ * does not set priority of the category which is by default @c
+ * LOG4C_PRIORITY_NOTSET.
+ * 
+ * @param a_name The name of the category to retrieve.
+ **/
+LOG4C_API log4c_category_t* log4c_category_get(const char* a_name);
+
+/**
+ * Fill in an array with the log4c categories.
+ *
+ * @param a_cats array of categories that will be filled
+ * @param a_ncats number of categories in the array
+ *
+ * @returns -1 if it fails or the number of available categories in
+ * log4c.
+ **/
+LOG4C_API int log4c_category_list(log4c_category_t** a_cats, int a_ncats);
+
+/**
+ * Constructor for a log4c_category_t.
+ *
+ * @param a_name the category name
+ * @returns a log4c_category object
+ * @warning this method should not be called directly. You should use the
+ * log4c_category_get() method in order to preserve the categories
+ * hierarchy.
+ **/
+LOG4C_API log4c_category_t* log4c_category_new(const char* a_name);
+
+/**
+ * Destructor for a log4c_category_t.
+ *
+ * @param a_category the log4c_category_t object
+ **/
+LOG4C_API void log4c_category_delete(log4c_category_t* a_category);
+
+/**
+ * Return the category name.
+ * @param a_category the log4c_category_t object
+ * @returns the category name.
+ */       
+LOG4C_API const char* log4c_category_get_name(const log4c_category_t* a_category);
+
+/**
+ * Returns the Appender for this log4c_category_t, or NULL if no Appender has
+ * been set.
+ * @param a_category the log4c_category_t object
+ * @returns The Appender.
+ **/
+LOG4C_API const struct __log4c_appender* log4c_category_get_appender(
+    const log4c_category_t* a_category);
+
+/**
+ * Get the additivity flag for this log4c_category_t..
+ *
+ * @param a_category the log4c_category_t object
+ * @return the category additivity
+ **/
+LOG4C_API int log4c_category_get_additivity(const log4c_category_t* a_category);
+
+/**
+ * Returns the assigned Priority, if any, for this log4c_category_t.
+ * @param a_category the log4c_category_t object
+ * @return Priority - the assigned Priority, can be LOG4C_PRIORITY_NOTSET
+ **/
+LOG4C_API int log4c_category_get_priority(const log4c_category_t* a_category);
+
+/**
+ * Starting from this category, search the category hierarchy for a set
+ * priority and return it. Otherwise, return the priority of the root
+ * category.
+ *
+ * @param a_category the log4c_category_t object
+ *
+ * @todo the log4c_category_t is designed so that this method executes as
+ * quickly as possible. It could even be faster if the set priority was
+ * propagated through the children hierarchy of a category.
+ **/
+LOG4C_API int log4c_category_get_chainedpriority(const log4c_category_t* a_category);
+
+/**
+ * Sets a new appender for this category.
+ *
+ * @param a_category the log4c_category_t object
+ * @param a_appender the new category appender
+ * @return the previous category appender
+ **/
+LOG4C_API const struct __log4c_appender* log4c_category_set_appender(
+    log4c_category_t* a_category,
+    struct __log4c_appender* a_appender);
+/**
+ * Sets a new priority of this category.
+ *
+ * @param a_category the log4c_category_t object
+ * @param a_priority the new priority to set. Use LOG4C_PRIORITY_NOTSET to
+ * let the category use its parents priority as effective priority.
+ * @return the previous category priority
+ **/
+LOG4C_API int log4c_category_set_priority(log4c_category_t* a_category,
+                                       int a_priority);
+
+/**
+ * Sets a new additivity flag for this category.
+ *
+ * @param a_category the log4c_category_t object
+ * @param a_additivity the new category additivity
+ * @return the previous category additivity
+ **/
+LOG4C_API int log4c_category_set_additivity(log4c_category_t* a_category,
+                                         int a_additivity);
+/**
+ * prints the log4c_category_t object on a stream
+ *
+ * @param a_category the log4c_category_t object
+ * @param a_stream The stream
+ **/ 
+LOG4C_API void log4c_category_print(const log4c_category_t* a_category, FILE* a_stream); 
+
+/** 
+ * Returns true if the chained priority of the log4c_category_t is equal to
+ * or higher than given priority.
+ * @param a_category the log4c_category_t object
+ * @param a_priority The priority to compare with.
+ * @returns whether logging is enable for this priority.
+ **/
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_priority_enabled(const log4c_category_t* a_category,
+						     int a_priority)
+{
+    return log4c_category_get_chainedpriority(a_category) >= a_priority;
+}
+#else
+#define log4c_category_is_priority_enabled(a,b) \
+  (log4c_category_get_chainedpriority(a) >= b)
+#endif
+
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_FATAL.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_fatal_enabled(const log4c_category_t* a_category)
+{	
+  return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_FATAL);
+}
+#else
+#define log4c_category_is_fatal_enabled(a)  \
+  (log4c_category_is_priority_enabled(a,LOG4C_PRIORITY_FATAL))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_ALERT.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_alert_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ALERT); 
+}
+#else
+#define log4c_category_is_alert_enabled(a) \
+  (log4c_category_is_priority_enabled(a,LOG4C_PRIORITY_ALERT))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_CRIT.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_crit_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_CRIT); 
+}
+#else
+#define log4c_category_is_crit_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_CRIT))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_ERROR.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_error_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ERROR); 
+}
+#else
+#define log4c_category_is_error_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_ERROR))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_WARN.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_warn_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_WARN); 
+}
+#else
+#define log4c_category_is_warn_enabled(a) \
+  log4c_category_is_warn_enabled(a) \
+    (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_WARN))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_NOTICE.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_notice_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_NOTICE); 
+}
+#else 
+#define log4c_category_is_notice_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_NOTICE))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_INFO.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_info_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_INFO); 
+}
+#else
+#define log4c_category_is_info_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_INFO))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_DEBUG.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_debug_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_DEBUG); 
+}
+#else
+#define log4c_category_is_debug_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_DEBUG))
+#endif
+ 
+/**
+ * Return true if the category will log messages with priority @c
+ * LOG4C_PRIORITY_TRACE.
+ *
+ * @param a_category the log4c_category_t object
+ * @returns Whether the category will log.
+ **/ 
+#if !defined(_WIN32) && !defined(__HP_cc)
+static inline int log4c_category_is_trace_enabled(const log4c_category_t* a_category) 
+{	
+    return log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_TRACE); 
+}
+#else
+#define log4c_category_is_trace_enabled(a) \
+  (log4c_category_is_priority_enabled(a, LOG4C_PRIORITY_TRACE))
+#endif
+ 
+/**
+ * @internal
+ **/
+LOG4C_API void __log4c_category_vlog(const log4c_category_t* a_category, 
+				  const log4c_location_info_t* a_locinfo, 
+				  int a_priority,
+				  const char* a_format, 
+				  va_list a_args);
+
+/**
+ * @internal
+**/
+LOG4C_API void __log4c_category_vlog_no_file_num_no_layout(
+	const log4c_category_t* a_category, 
+	const log4c_location_info_t* a_locinfo, 
+	int a_priority,
+	const char* a_format, 
+	va_list a_args);
+
+
+/**
+ * @internal
+ *
+ * @bug the log4c_location_info_t object is not set correctly. A macro is
+ * needed.
+ **/
+
+/* msvc doesn't allow "inline" nor variable args in a macro
+ * so cannot #define these ones.
+ */
+
+static LOG4C_INLINE void log4c_category_vlog(const log4c_category_t* a_category, 
+				       int a_priority,
+				       const char* a_format, 
+				       va_list a_args)
+{
+    const log4c_location_info_t locinfo = LOG4C_LOCATION_INFO_INITIALIZER(NULL);
+
+    __log4c_category_vlog(a_category, &locinfo, a_priority, a_format, a_args);
+}
+
+/** 
+* @internal
+*
+* @bug the log4c_location_info_t object is not set correctly. A macro is
+* needed.
+**/
+
+/* msvc doesn't allow "inline" nor variable args in a macro
+* so cannot #define these ones.
+*/
+
+static LOG4C_INLINE void log4c_category_vlog_no_file_num_no_layout(const log4c_category_t* a_category, 
+																   int a_priority,
+																   const char* a_format, 
+																   va_list a_args)
+{
+	const log4c_location_info_t locinfo = LOG4C_LOCATION_INFO_INITIALIZER(NULL);
+
+	__log4c_category_vlog_no_file_num_no_layout(a_category, &locinfo, a_priority, a_format, a_args);
+}
+
+
+/** 
+ * Log a message with the specified priority.
+ * @param a_category the log4c_category_t object
+ * @param a_priority The priority of this log message.
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_log(const log4c_category_t* a_category,
+				      int a_priority,
+				      const char* a_format,
+				      ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, a_priority)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, a_priority, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with the specified priority and a user location info.
+ * @param a_category the log4c_category_t object
+ * @param a_locinfo a user  location info
+ * @param a_priority The priority of this log message.
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_log_locinfo(
+	const log4c_category_t* a_category,
+	const log4c_location_info_t* a_locinfo, 
+	int a_priority,
+	const char* a_format,
+	...)
+{
+	if (log4c_category_is_priority_enabled(a_category, a_priority)) {
+		va_list va;
+		va_start(va, a_format);
+		__log4c_category_vlog(a_category, a_locinfo, a_priority, a_format, va);
+		va_end(va);
+	}
+}
+
+/** 
+ * Log a message with fatal priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_fatal(const log4c_category_t* a_category,
+					const char* a_format,
+					...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_FATAL)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_FATAL, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with alert priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_alert(const log4c_category_t* a_category,
+					const char* a_format,
+					...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ALERT)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_ALERT, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with crit priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_crit(const log4c_category_t* a_category,
+				       const char* a_format,
+				       ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_CRIT)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_CRIT, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with error priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_error(const log4c_category_t* a_category,
+					const char* a_format,
+					...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_ERROR)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_ERROR, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with warn priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_warn(const log4c_category_t* a_category,
+				       const char* a_format,
+				       ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_WARN)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_WARN, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with notice priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_notice(const log4c_category_t* a_category,
+					 const char* a_format,
+					 ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_NOTICE)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_NOTICE, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with info priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_info(const log4c_category_t* a_category,
+				       const char* a_format,
+				       ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_INFO)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_INFO, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with debug priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void log4c_category_debug(const log4c_category_t* a_category,
+					const char* a_format,
+					...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_DEBUG)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_DEBUG, a_format, va);
+	va_end(va);
+    }
+}
+
+/** 
+ * Log a message with trace priority.
+ * @param a_category the log4c_category_t object
+ * @param a_format Format specifier for the string to write 
+ * in the log file.
+ * @param ... The arguments for a_format 
+ **/  
+static LOG4C_INLINE void __log4c_category_trace(const log4c_category_t* a_category,
+					  const char* a_format,
+					  ...)
+{
+    if (log4c_category_is_priority_enabled(a_category, LOG4C_PRIORITY_TRACE)) {
+	va_list va;
+	va_start(va, a_format);
+	log4c_category_vlog(a_category, LOG4C_PRIORITY_TRACE, a_format, va);
+	va_end(va);
+    }
+}
+
+#ifdef __GNUC__
+
+#ifdef OLD_VARIADIC_MACRO
+
+#  define log4c_category_trace(a_category, a_format, args...) \
+    __log4c_category_trace(a_category, log4c_location "\n" a_format, ##args )
+
+#else
+
+#  define log4c_category_trace(a_category, a_format, ...) \
+    __log4c_category_trace(a_category, log4c_location "\n" a_format, ##__VA_ARGS__ )
+
+#endif /* OLD_VARIADIC_MACRO */
+
+
+#else
+#  define log4c_category_trace __log4c_category_trace
+#endif  /* __GNUC__ */
+
+/**
+ * Helper macro to define static categories.
+ *
+ * @param a_category the log4c_category_t pointer name
+ * @param a_name the category name
+ **/
+#ifdef __GNUC__
+#   define log4c_category_define(a_category, a_name) \
+    typedef log4c_category_t log4c_category_define_##a_category __attribute__((deprecated)); \
+    static log4c_category_define_##a_category* a_category  __attribute__ ((unused)) = NULL;
+#else
+#   define log4c_category_define(a_category, a_name)
+#endif
+
+/**
+ * @internal
+ **/
+struct __sd_factory;
+LOG4C_API struct __sd_factory* log4c_category_factory;
+
+__LOG4C_END_DECLS
+
+#endif

+ 41 - 0
TCL Copy Tool/Log4C/log4c/config-win32.h

@@ -0,0 +1,41 @@
+/* $Id$
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+/* This file defines some labels as required for
+   compiling with Microsoft Visual C++ 6
+*/
+
+#ifndef __log4c_config_win32_h
+#define __log4c_config_win32_h
+
+#include <time.h>
+#include <winsock2.h>
+
+#undef LOG4C_API
+#ifdef LOG4C_EXPORTS
+#    define LOG4C_API         __declspec(dllexport)
+#else
+#    define LOG4C_API       extern __declspec(dllimport)
+#endif
+
+#undef LOG4C_DATA
+#ifdef LOG4C_EXPORTS
+#    define LOG4C_DATA        __declspec(dllexport)
+#else
+#    define LOG4C_DATA       extern __declspec(dllimport)
+#endif
+
+
+/* This is defined to be 'inline' by default,
+   but with msvc6 undef it so that inlined
+   functions are just normal functions.
+*/
+#undef LOG4C_INLINE
+#define LOG4C_INLINE
+
+#define WITH_ROLLINGFILE 1
+
+
+#endif /* __log4c_config_win32_h */

+ 26 - 0
TCL Copy Tool/Log4C/log4c/config.h

@@ -0,0 +1,26 @@
+/************** Begin of config.h *******************************************/
+
+/* $Id$
+*
+* config.h created by wenhm in 2006-11-9
+*
+* Copyright 2001-2002, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_config_h
+#define log4c_config_h
+
+
+///#ifdef _WIN32
+#define LOG4C_RCPATH	"."
+#define VERSION			"1.2.1"
+///#endif
+
+#define WITH_ROLLINGFILE 1
+#endif
+
+
+
+/************** End of config.h *******************************************/

+ 46 - 0
TCL Copy Tool/Log4C/log4c/defs.h

@@ -0,0 +1,46 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __log4c_defs_h
+#define __log4c_defs_h
+
+/**
+ * @file defs.h
+ *
+ * @brief types and declarations enclosures for C++.
+ *
+ **/   
+
+#ifdef  __cplusplus
+# define __LOG4C_BEGIN_DECLS  extern "C" {
+# define __LOG4C_END_DECLS    }
+#else
+# define __LOG4C_BEGIN_DECLS
+# define __LOG4C_END_DECLS
+#endif
+
+#define LOG4C_INLINE inline
+#define LOG4C_API    extern
+#define LOG4C_DATA    extern
+
+#ifdef __HP_cc
+#define inline __inline
+#endif
+
+#ifdef _WIN32
+# include <log4c/config-win32.h>
+#endif
+
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif /* GCC_VERSION */
+
+#if GCC_VERSION < 2009
+#define OLD_VARIADIC_MACRO 1
+#endif
+
+#endif /* __log4c_defs_h */

+ 65 - 0
TCL Copy Tool/Log4C/log4c/init.h

@@ -0,0 +1,65 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __log4c_init_h
+#define __log4c_init_h
+
+#include <log4c/defs.h>
+#include <stdio.h>
+
+/**
+ * @file init.h
+ *
+ * @brief log4c constructors and destructors
+ *
+ **/   
+
+/**
+ * constructor
+ * 
+ * @returns 0 for success 
+ **/
+LOG4C_API int log4c_init(void);
+
+/**
+* another constructor
+* 
+* 带有配置文件名的初始化函数
+* 完成功能和log4c_init完全一致,只是这里的配置文件名以参数形式传入的
+* @returns 0 for success .
+* 作者:jesse 日期:2008-9-6
+*/
+LOG4C_API int log4c_init_with_cfg_file(const char *strCfgFileName);
+
+/**
+ * destructor
+ *
+ * @returns 0 for success 
+ **/
+LOG4C_API int log4c_fini(void);
+
+/*
+ * Dumps all the current appender, layout and rollingpolicy types
+ * known by log4c.
+ * @param stream to write to
+ */
+LOG4C_API void log4c_dump_all_types(FILE *fp);
+
+/*
+ * Dumps all the current instances of categories, appenders, layouts
+ * and rollingpolicy objects.
+ * An instances of a type consists of the base
+ * type information (name plus function table) and an instance name and
+ * configuration.  For example one can have an instance of the rollingfile
+ * appender which logs to /var/tmp and another instance which logs to 
+ * /usr/tmp.  They are both of type rollingfile, but are distinct instances of
+ * it
+ * @param stream to write t
+ */
+LOG4C_API void log4c_dump_all_instances(FILE *fp);
+
+#endif

+ 204 - 0
TCL Copy Tool/Log4C/log4c/layout.h

@@ -0,0 +1,204 @@
+/* $Id$
+ *
+ * layout.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_layout_h
+#define log4c_layout_h
+
+/**
+ * @file layout.h
+ *
+ * @brief Interface for user specific layout format of log4c_logging_event
+ * events. 
+ *
+ * @todo the layout interface needs a better configuration system
+ * depending on the layout type. The udata field is a just a trick.
+ *
+ * @todo a pattern layout would be welcomed !!
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/logging_event.h>
+#include <stdio.h>
+
+__LOG4C_BEGIN_DECLS
+
+struct __log4c_layout;
+
+/**
+ * log4c layout class 
+ **/
+typedef struct __log4c_layout log4c_layout_t;
+
+/**
+ * @brief log4c layout type class
+ *
+ * Attributes description:
+ * 
+ * @li @c name layout type name 
+ * @li @c format 
+ **/
+typedef struct log4c_layout_type {
+    const char* name;
+    const char* (*format) (const log4c_layout_t*, const log4c_logging_event_t*);
+} log4c_layout_type_t;
+
+/**
+ * Get a pointer to an existing layout type.
+ *
+ * @param a_name the name of the layout type to return.  
+ * @returns a pointer to an existing layout type, or NULL if no layout
+ * type with the specified name exists.
+ **/
+LOG4C_API const log4c_layout_type_t* log4c_layout_type_get(const char* a_name);
+
+/**
+ * Use this function to register a layout type with log4c.
+ * Once this is done you may refer to this type by name both 
+ * programatically and in the log4c configuration file.
+ *
+ * @param a_type a pointer to the new layout type to set.
+ * @returns a pointer to the previous layout type of same name.
+ *
+ * Example code fragment: 
+ * @code
+ * 
+ * const log4c_layout_type_t log4c_layout_type_xml = {
+ *    "s13_xml",
+ *    xml_format,
+ * };
+ *  
+ * log4c_layout_type_set(&log4c_layout_type_xml);
+ *
+ * @endcode
+ **/
+LOG4C_API const log4c_layout_type_t* log4c_layout_type_set(
+    const log4c_layout_type_t* a_type);
+
+/**
+ * Get a pointer to an existing layout.
+ *
+ * @param a_name the name of the layout to return.
+ * @returns a pointer to an existing layout, or NULL if no layout
+ * with the specfied name exists.
+ **/
+LOG4C_API log4c_layout_t* log4c_layout_get(const char* a_name);
+
+/**
+ * Constructor for layout. 
+ **/
+LOG4C_API log4c_layout_t* log4c_layout_new(const char* a_name);
+
+/**
+ * Destructor for layout.
+ **/
+LOG4C_API void log4c_layout_delete(log4c_layout_t* a_layout);
+
+/**
+ * @param a_layout the log4c_layout_t object
+ * @return the layout name
+ **/
+LOG4C_API const char* log4c_layout_get_name(const log4c_layout_t* a_layout);
+
+/**
+ * @param a_layout the log4c_layout_t object
+ * @return a log4c_layout_type_t object
+ **/
+LOG4C_API const log4c_layout_type_t* log4c_layout_get_type(
+    const log4c_layout_t* a_layout);
+
+/**
+ * sets the layout type
+ *
+ * @param a_layout the log4c_layout_t object
+ * @param a_type the new layout type
+ * @return the previous layout type
+ *
+ **/
+LOG4C_API const log4c_layout_type_t* log4c_layout_set_type(
+    log4c_layout_t* a_layout,
+    const log4c_layout_type_t* a_type);
+
+/**
+ * @param a_layout the log4c_layout_t object
+ * @return the layout user data
+ **/
+LOG4C_API void* log4c_layout_get_udata(const log4c_layout_t* a_layout);
+
+/**
+ * sets the layout user data
+ *
+ * @param a_layout the log4c_layout_t object
+ * @param a_udata the new layout user data
+ * @return the previous layout user data
+ **/
+LOG4C_API void* log4c_layout_set_udata(log4c_layout_t*	a_layout, 
+				    void*		a_udata);
+/**
+ * format a log4c_logging_event events to a string.
+ *
+ * @param a_layout the log4c_layout_t object
+ * @param a_event a logging_event_t object
+ * @returns an appendable string.
+ **/
+LOG4C_API const char* log4c_layout_format(
+    const log4c_layout_t*		a_layout,
+    const log4c_logging_event_t*	a_event);
+
+/**
+ * prints the layout on a stream
+ * @param a_layout the log4c_layout_t object
+ * @param a_stream the stream
+ **/
+LOG4C_API void log4c_layout_print(
+    const log4c_layout_t* a_layout, FILE* a_stream);
+
+/**
+ * prints all the current registered layout types on a stream
+ *
+ * @param fp the stream
+ **/                            
+LOG4C_API void log4c_layout_types_print(FILE *fp);
+
+/** 删除本layout.c文件中定义的全局和静态的指针指向的内存,防止内存泄漏
+如:
+1.gs_types.
+2.
+@return void.
+作者:jesse 日期:2008.09.08
+*/
+LOG4C_API void log4c_layout_delete_global();
+
+
+/**
+ * Helper macro to define static layout types.
+ *
+ * @param a_type the log4c_layout_type_t object to define
+ * @warning needs GCC support: otherwise this macro does nothing
+ * @deprecated This macro, and the static initialialization
+ * of layouts in general, is deprecated. Use rather
+ * the log4c_layout_type_set() function to initialize your appenders
+ * before calling log4c_init() 
+ **/
+#ifdef __GNUC__
+#   define log4c_layout_type_define(a_type) \
+    typedef int log4c_layout_type_define_##a_type __attribute__((deprecated)); \
+    static log4c_layout_type_define_##a_type __unsused_var __attribute__((unused));
+#else
+#   define log4c_layout_type_define(a_type)
+#endif
+
+/**
+ * @internal
+ **/
+struct __sd_factory;
+LOG4C_API struct __sd_factory* log4c_layout_factory;
+
+__LOG4C_END_DECLS
+
+#endif

+ 38 - 0
TCL Copy Tool/Log4C/log4c/layout_type_basic.h

@@ -0,0 +1,38 @@
+/* $Id$
+ *
+ * layout_type_basic.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_layout_type_basic_h
+#define log4c_layout_type_basic_h
+
+/**
+ * @file layout_type_basic.h
+ *
+ * @brief Implement a basic layout.
+ *
+ * In @c log4j.PatternLayout conventions, the basic layout has the following
+ * conversion pattern: @c "%P %c - %m\n".
+ *
+ * Where 
+ * @li @c "%P" is the priority of the logging event
+ * @li @c "%c" is the category of the logging event
+ * @li @c "%m" is the application supplied message associated with the
+ * logging event
+ * 
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+__LOG4C_BEGIN_DECLS
+
+extern const log4c_layout_type_t log4c_layout_type_basic;
+
+__LOG4C_END_DECLS
+
+#endif

+ 42 - 0
TCL Copy Tool/Log4C/log4c/layout_type_basic_r.h

@@ -0,0 +1,42 @@
+		/************** Begin of layout_type_basic_r.h *******************************************/
+		/* $Id$
+		*
+		* layout_type_basic_r.h
+		*
+		* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+		*
+		* See the COPYING file for the terms of usage and distribution.
+		*/
+
+#ifndef log4c_layout_type_basic_r_h
+#define log4c_layout_type_basic_r_h
+
+		/**
+		* @file layout_type_basic_r.h
+		*
+		* @brief Implement a basic_r layout.
+		*
+		* In @c log4j.PatternLayout conventions, the basic_r layout has the following
+		* conversion pattern: @c "%P %c - %m\n".
+		*
+		* Where
+		* @li @c "%P" is the priority of the logging event
+		* @li @c "%c" is the category of the logging event
+		* @li @c "%m" is the application supplied message associated with the
+		* logging event
+		*
+		**/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+		__LOG4C_BEGIN_DECLS
+
+		extern const log4c_layout_type_t log4c_layout_type_basic_r;
+
+	__LOG4C_END_DECLS
+
+#endif
+
+
+		/************** End of layout_type_basic_r.h *******************************************/

+ 43 - 0
TCL Copy Tool/Log4C/log4c/layout_type_dated.h

@@ -0,0 +1,43 @@
+/* $Id$
+ *
+ * layout_type_dated.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_layout_type_dated_h
+#define log4c_layout_type_dated_h
+
+/**
+ * @file layout_type_dated.h
+ *
+ * @brief Implement a dated layout.
+ *
+ * In @c log4j.PatternLayout conventions, the dated layout has the following
+ * conversion pattern: @c "%d %P %c - %m\n".
+ *
+ * Where 
+ * @li @c "%d" is the date of the logging event
+ * @li @c "%P" is the priority of the logging event
+ * @li @c "%c" is the category of the logging event
+ * @li @c "%m" is the application supplied message associated with the
+ * logging event
+ *
+ * 
+ * 
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+__LOG4C_BEGIN_DECLS
+
+extern const log4c_layout_type_t log4c_layout_type_dated;
+extern const log4c_layout_type_t log4c_layout_type_dated_r;
+extern const log4c_layout_type_t log4c_layout_type_dated_threadid;
+
+__LOG4C_END_DECLS
+
+#endif

+ 45 - 0
TCL Copy Tool/Log4C/log4c/layout_type_dated_r.h

@@ -0,0 +1,45 @@
+/************** Begin of log4c/layout_type_dated_r.h *******************************************/
+/* $Id$
+*
+* layout_type_dated_r.h
+*
+* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_layout_type_dated_r_h
+#define log4c_layout_type_dated_r_h
+
+/**
+* @file layout_type_dated_r.h
+*
+* @brief Implement a dated_r layout.
+*
+* In @c log4j.PatternLayout conventions, the dated_r layout has the following
+* conversion pattern: @c "%d %P %c - %m\n".
+*
+* Where
+* @li @c "%d" is the date of the logging event
+* @li @c "%P" is the priority of the logging event
+* @li @c "%c" is the category of the logging event
+* @li @c "%m" is the application supplied message associated with the
+* logging event
+*
+*
+*
+**/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+__LOG4C_BEGIN_DECLS
+
+extern const log4c_layout_type_t log4c_layout_type_dated_r;
+
+__LOG4C_END_DECLS
+
+#endif
+
+
+/************** End of log4c/layout_type_dated_r.h *******************************************/

+ 45 - 0
TCL Copy Tool/Log4C/log4c/layout_type_dated_threadid.h

@@ -0,0 +1,45 @@
+/************** Begin of log4c/layout_type_dated_threadid.h *******************************************/
+/* $Id$
+*
+* layout_type_dated_threadid.h
+* 
+* Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+*
+* See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_layout_type_dated_threadid_h
+#define log4c_layout_type_dated_threadid_h
+
+/**
+* @file layout_type_dated_threadid.h
+*
+* @brief Implement a dated layout.
+*
+* In @c log4j.PatternLayout conventions, the dated layout has the following
+* conversion pattern: @c "%d %P %c - %m\n".
+*
+* Where 
+* @li @c "%d" is the date of the logging event
+* @li @c "%P" is the priority of the logging event
+* @li @c "%c" is the category of the logging event
+* @li @c "%m" is the application supplied message associated with the
+* logging event
+*
+* 
+* 
+**/
+
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+__LOG4C_BEGIN_DECLS
+
+extern const log4c_layout_type_t log4c_layout_type_dated_threadid;
+
+__LOG4C_END_DECLS
+
+#endif
+
+
+/************** End of log4c/layout_type_dated_threadid.h *******************************************/

+ 73 - 0
TCL Copy Tool/Log4C/log4c/location_info.h

@@ -0,0 +1,73 @@
+/* $Id$
+ *
+ * location_info.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+
+
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_location_info_h
+#define log4c_location_info_h
+
+/**
+ * @file location_info.h
+ *
+ * @brief The internal representation of caller location information.
+ * 
+ * When a affirmative logging decision is made a log4c_location_info_t is
+ * created and is passed around the different log4c components.
+ **/
+
+///#include <log4c/defs.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * @brief logging location information
+ *
+ * Attributes description:
+ * 
+ * @li @c loc_file file name
+ * @li @c loc_line file line
+ * @li @c loc_function function name
+ * @li @c loc_data user data
+ *
+ * @todo this is not used
+ **/
+typedef struct 
+{
+    const char* loc_file;
+    int loc_line;
+    const char* loc_function;
+    void* loc_data;
+
+} log4c_location_info_t;
+
+/**
+ * log4c_location_info_t initializer 
+ **/
+#ifdef __GNUC__
+#   define LOG4C_LOCATION_INFO_INITIALIZER(user_data) { __FILE__, __LINE__, __FUNCTION__, user_data }
+#else
+#   define LOG4C_LOCATION_INFO_INITIALIZER(user_data) { __FILE__, __LINE__, "(nil)", user_data }
+#endif
+
+#define __log4c_str(n) #n
+
+#ifdef __GNUC__
+#   define __log4c_location(n)	__FUNCTION__ "() at " __FILE__ ":" __log4c_str(n)
+#else
+#   define __log4c_location(n)	__FILE__ ":" __log4c_str(n)
+#endif
+
+/**
+ * This macro returns the literal representation of a logging event
+ * location
+ **/
+#define log4c_location __log4c_location(__LINE__)
+
+__LOG4C_END_DECLS
+
+#endif

+ 553 - 0
TCL Copy Tool/Log4C/log4c/log.h

@@ -0,0 +1,553 @@
+/************** Begin of Log.h *******************************************/
+/************************************************************************
+ * Log.h
+ *
+ * edit by jesse in 2010-07-22
+ * 日志相关代码的头文件
+ ************************************************************************/
+#if !defined(LOG_H_INCLUDED_)
+#define LOG_H_INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+///用户不需要使用日志,不要定义LOG_USELOG4CXX和LOG4C_ENABLE宏命令就可以了
+#if !defined(LOG_USELOG4CXX) && !defined(LOG4C_ENABLE)
+
+#define LOG4C(X) 
+#define LOG4C_INIT()
+
+#define LOG4C_PARAM_CFG_FILE_NAME(strCfgFileName) 
+#define LOG4C_PARAM_LOG_LEVEL(strLogLevel) 
+#define LOG4C_PARAM_LOG_FILE_NAME(strLogFileName) 
+#define LOG4C_PARAM_LOG_FILE_SIZE(iFileSize) 
+#define LOG4C_PARAM_LOG_FILE_NUM(iFileNum)
+#define LOG4C_PARAM_REREAD_LOG_CFG_FILE(bReReadLogCfgFile)
+#define LOG4C_INIT_WITH_PARAM()
+#define LOG4C_INIT_WITH_PARAM_MULTI_PROCESS()
+
+#define LOG4C_FINI()
+#define LOG4C_INIT_DEFAULT()
+
+#define LOG4C_NO_FILENUM(X) 
+#define LOG4C_NO_FILENUM_NO_LAYOUT(X)
+#define LOG4C_ORIGIN LOG4C_NO_FILENUM_NO_LAYOUT
+#define LOG4C_BLOCK_BEGIN(X)
+#define LOG4C_BLOCK_END(X) 
+#define LOG4C_FUN(X) 
+#define LOG4C_IF(X)
+#define LOG4C_LINE()
+#define LOG4C_HEX_DUMP(X)
+#define LOG4C_RETURN(X)
+#define LOG4C_RETURN_WITH_VALUE(X, reurnValue)
+
+#else
+
+#include <stdlib.h>
+
+/**日志记录模块初始化宏定义
+注意事项: 必须初始化日志模块后才能正确记录日志
+本初始化不要求应用程序所在目录有日志配置文件log4crc,会自动生成一个缺省的log4crc文件
+使用例子: LOG4C_INIT_DEFAULT();
+作者:Jesse  日期:2010-07-22
+*/
+#define LOG4C_INIT_DEFAULT() \
+	log_init_with_string("", "")
+
+/**日志记录模块初始化宏定义
+注意事项: 必须初始化日志模块后才能正确记录日志
+本初始化要求应用程序所在目录有日志配置文件log4crc才行
+使用例子: LOG4C_INIT();
+作者:Jesse  日期:2010-07-22
+*/
+#define LOG4C_INIT() \
+	log_init()
+
+/************************************************************************
+下面的为通过设置参数设置日志模块参数的宏定义(功能和LOG4C_INIT和LOG4C_INIT_DEFAULT类似):
+1.必须先调用LOG_PARAM_XXXX系列宏定义设置参数,
+1.1.如设置日志记录级别、生成日志文件名等。
+1.2.若不LOG_PARAM_XXXX系列宏定义则将使用默认设置参数。
+2.然后调用LOG_INIT_WITH_PARAM宏定义来初始化日志模块。
+3.此时就可以记录日志了。
+*/
+#define LOG4C_PARAM_CFG_FILE_NAME(strCfgFileName) \
+	log_set_log_cfg_file_name(strCfgFileName)
+
+#define LOG4C_PARAM_LOG_LEVEL(strLogLevel) \
+	log_set_log_level(strLogLevel)
+
+#define LOG4C_PARAM_LOG_FILE_NAME(strLogFileName) \
+	log_set_log_file_name(strLogFileName)
+
+#define LOG4C_PARAM_LOG_FILE_SIZE(iFileSize) \
+	log_set_log_file_size(iFileSize)
+
+#define LOG4C_PARAM_LOG_FILE_NUM(iFileNum) \
+	log_set_log_file_num(iFileNum)
+
+#define LOG4C_PARAM_REREAD_LOG_CFG_FILE(bReReadLogCfgFile) \
+	log_set_reread_log_cfg_file(bReReadLogCfgFile)
+
+#define LOG4C_INIT_WITH_PARAM() \
+	log_init_with_param()
+
+#define LOG4C_INIT_WITH_PARAM_MULTI_PROCESS() \
+	log_init_with_param_multi_process()
+
+/************************************************************************/
+
+/**日志记录模块结束宏定义
+注意事项: 必须正确结束日志模块后才不会造成内存、资源泄漏
+使用例子: LOG4C_FINI();
+作者:Jesse  日期:2010-07-22
+*/
+#define LOG4C_FINI() \
+	log_fini()
+
+///进行LOG宏定义参数获取的结果
+typedef struct __LOG_PARAM
+{
+	char strMsg[LOG4C_BUFFER_SIZE_DEFAULT];
+	int iPriority;
+
+	///LOG4C_IF时的条件参数
+	int iCondition;
+
+	///LOG4C_HEX_DUMP时的参数
+	char *strHexBuf;
+	int iHexBufLen;
+}LOG_PARAM;
+
+#define LOG4C(X) \
+{ \
+	const LOG_PARAM log_param = log_vsprintf_wrapper X; \
+	log_msg( __FILE__, __LINE__, DEFAULT_LOG_CATEGORY_NAME, log_param.iPriority, log_param.strMsg ); \
+}
+
+#define LOG4C_NO_FILENUM(X) \
+{ \
+	const LOG_PARAM log_param = log_vsprintf_wrapper X; \
+	log_msg_no_file_num( DEFAULT_LOG_CATEGORY_NAME, log_param.iPriority, log_param.strMsg );  \
+}
+
+#define LOG4C_NO_FILENUM_NO_LAYOUT(X) \
+{ \
+	const LOG_PARAM log_param = log_vsprintf_wrapper X; \
+	log_msg_no_file_num_no_layout( DEFAULT_LOG_CATEGORY_NAME, log_param.iPriority, log_param.strMsg ); \
+}
+
+#define LOG4C_ORIGIN LOG4C_NO_FILENUM_NO_LAYOUT
+
+#define LOG4C_BLOCK_BEGIN(X) \
+{ \
+	const LOG_PARAM log_param = log_vsnprintf_wrapper_msg X; \
+	log4c_block_begin(__FILE__, __LINE__, log_param.strMsg); \
+}
+
+#define LOG4C_BLOCK_END(X) \
+{	\
+	const LOG_PARAM log_param = log_vsnprintf_wrapper_msg X; \
+	log4c_block_end(__FILE__, __LINE__, log_param.strMsg); \
+}
+
+#define LOG4C_FUN(X) \
+{ \
+	const LOG_PARAM log_param = log_vsnprintf_wrapper_msg X; \
+	log_msg_func(__FILE__, __FUNCTION__, __LINE__, DEFAULT_LOG_CATEGORY_NAME, LOG4C_PRIORITY_TRACE, log_param.strMsg ); \
+}
+
+/** Output trace on condition.
+This macro outputs a trace of any information needed, using standard stream
+output operators. The output is only made if the conditional is TRUE. 
+example: LOG4C_IF((4>3, LOG4C_PRIORITY_TRACE, "HELLO"));
+*/
+#define LOG4C_IF(X) \
+{ \
+	const LOG_PARAM log_param = log_condition_vsnprintf_wrapper X; \
+	if( log_param.iCondition ) {\
+		log_msg( \
+			__FILE__, \
+			__LINE__, \
+			DEFAULT_LOG_CATEGORY_NAME, \
+			log_param.iPriority, \
+			log_param.strMsg\
+		); 	\
+	}\
+}
+
+/** Trace the execution of a line.
+This macro outputs a trace of a source file line execution.
+*/
+#define LOG4C_LINE() \
+{ \
+	char strBuffer[128] = {0}; \
+	snprintf(strBuffer, sizeof(strBuffer), "line:%d", __LINE__); \
+	log_msg( \
+		__FILE__, \
+		__LINE__, \
+		DEFAULT_LOG_CATEGORY_NAME, \
+		LOG4C_PRIORITY_TRACE, \
+		strBuffer \
+		); \
+}
+
+/**将内存中数据以十六进制方式打印出来的一个宏定义
+example:LOG4C_HEX_DUMP((LOG4C_PRIORITY_TRACE, strHexBuf, iHexBufLen));
+作者:Jesse 日期:2010-07-22
+*/
+#define LOG4C_HEX_DUMP(X)	\
+{	\
+	log_hex_dump_vsnprintf_wrapper X; \
+}
+
+/** 输出文件名和行号的日志输出宏,记录完日志直接return
+然后再输入到LOG宏定义中
+作者:Jesse 日期:2010-07-22
+*/ 
+#define LOG4C_RETURN(X) \
+{ \
+	LOG4C(X); \
+	return; \
+}
+
+/** 输出文件名和行号的日志输出宏,记录完日志直接return returnValue;
+然后再输入到LOG宏定义中
+example:LOG4C_RETURN_WITH_VALUE(( LOG4C_PRIORITY_TRACE, "message%d", 1), returnValue);
+作者:Jesse 日期:2010-07-22
+*/ 
+#define LOG4C_RETURN_WITH_VALUE(X, returnValue) \
+{ \
+	LOG4C(X); \
+	return returnValue; \
+}
+
+#endif ///!defined(LOG_USELOG4CXX) 	&& 	!defined(LOG4C_ENABLE)
+
+#if ((defined(LOG_USELOG4CXX) && defined(__cplusplus)) || defined(LOG4C_ENABLE)) 
+
+#ifdef _WIN32
+///log4c正确使用必须的一些宏定义
+#define snprintf _snprintf
+
+#ifndef HAVE_CONFIG_H
+	#define HAVE_CONFIG_H
+#endif
+///#define LOG4C_EXPORTS
+#endif
+
+///定义linux下使用到而不存在的类型
+#ifdef linux
+	///typedef int BOOL;
+#ifndef BOOL 
+	#define BOOL int
+	#define FALSE 0
+	#define TRUE 1
+#endif
+	#define sprintf_s snprintf
+	///#define strcpy_s strncpy
+#endif
+
+
+/// 日志输出缺省category
+#ifndef DEFAULT_LOG_CATEGORY_NAME
+	#define DEFAULT_LOG_CATEGORY_NAME "root"
+#endif
+
+/** 日志记录级别
+*/
+/** fatal */	#define LOG_FATAL		LOG4C_PRIORITY_FATAL	
+/** alert */	#define LOG_ALERT		LOG4C_PRIORITY_ALERT	
+/** crit */	    #define LOG_CRIT		LOG4C_PRIORITY_CRIT		
+/** error */	#define LOG_ERROR		LOG4C_PRIORITY_ERROR	
+/** warn */	    #define LOG_WARN		LOG4C_PRIORITY_WARN		
+/** notice */	#define LOG_NOTICE		LOG4C_PRIORITY_NOTICE	
+/** info */	    #define LOG_INFO		LOG4C_PRIORITY_INFO		
+/** debug */	#define LOG_DEBUG		LOG4C_PRIORITY_DEBUG	
+/** trace */	#define LOG_TRACE		LOG4C_PRIORITY_TRACE	
+/** notset */	#define LOG_NOTSET		LOG4C_PRIORITY_NOTSET	
+/** unknown */	#define LOG_UNKNOWN		LOG4C_PRIORITY_UNKNOWN
+
+#include <log4c/defs.h>
+
+__LOG4C_BEGIN_DECLS
+
+/** 日志模块初始化
+@return int:return 0 for success 
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init();
+
+/** 日志模块初始化,指定配置文件名称
+@return int:return 0 for success 
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init_with_cfg_file(const char *strCfgFileName);
+
+/** 日志模块清理
+@return int:return 0 for success 
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_fini();
+
+/**宏参数抽取priority函数
+本函数接受LOG_DEBUG(X)的参数,并从该宏定义的参数中返回priority的值
+@return const int : iPriority.
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API const int log_get_priority_wrapper(
+	const int iPriority,	///日志记录级别
+	const char* strFormat,	///日志内容格式
+	...						///日志内容
+	);
+
+/**
+将大小为count的缓冲区中内容按字节以16进制字符串打印出来,
+返回值即为指向相应的字符串,
+该返回指向的存储区域要调用本函数的用户显示的进行删除
+*/
+LOG4C_API void log4c_sprintf_data(char *buff, int count, char *dest_buffer);
+
+/**日志记录宏定义
+注意事项: 使用时参数必须使用两个括号括起来,LOG4C((X));见下面例子
+使用例子: LOG4C((LOG_ERROR, "Hello World! My Name is %s, and my age is %d ", "Jess", "28" ));
+作者:Jesse  日期:2010-07-22
+*/
+
+LOG4C_API const LOG_PARAM  log_vsprintf_wrapper(
+	const int iPriority,	///日志记录级别
+	const char* strFormat,	///日志内容格式
+	...						///日志内容
+	);
+
+LOG4C_API const LOG_PARAM  log_condition_vsnprintf_wrapper(
+	const int iCondition,	///条件
+	const int iPriority,	///日志记录级别
+	const char* strFormat,	///日志内容格式
+	...						///日志内容
+	);
+
+LOG4C_API void log_hex_dump_vsnprintf_wrapper(
+	const int iPriority,	///日志记录级别
+	const char* strFormat,  ///日志内容格式
+	const char* strHexBuf,	///缓冲区首地址
+	const int iHexBufLen,	///缓冲区长度
+	...						///日志内容
+	);
+
+LOG4C_API const LOG_PARAM log_vsnprintf_wrapper_msg(
+	const char* strFormat,	///日志内容格式
+	...						///日志内容
+);
+
+/** 日志记录
+日志记录为一个字符串指针指向的内容
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_msg(
+			const char *strFile,	///文件名
+			const int iLineNum,		///行号
+			const char *strCatName,	///category名
+			const int iPriority,	///日志记录级别
+			const char *strFormat,	///日志内容格式
+			...						///日志内容
+			);
+
+LOG4C_API void log_msg_func(
+	const char *strFile,	///文件名
+	const char *strFuncName,///函数名
+	const int iLineNum,		///行号
+	const char *strCatName,	///category名
+	const int iPriority,	///日志记录级别
+	const char *strFormat,	///日志内容格式
+	...						///日志内容
+	);
+
+/** 日志记录,不记录文件名和行号
+日志记录为一个字符串指针指向的内容
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_msg_no_file_num(
+			const char *strCatName,	///category名
+			const int iPriority,	///日志记录级别
+			const char *strFormat,	///日志内容格式
+			...						///日志内容
+			);
+
+/** 日志记录,不记录文件名和行号,没有任何layout转换,直接输出相应的字符文本到日志中
+此条记录没有行号,也没有线程号,也没有回车等
+日志记录为一个字符串指针指向的内容
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_msg_no_file_num_no_layout(
+		   const char *strCatName,	///category名
+		   const int iPriority,		///日志记录级别
+		   const char *strFormat,		///日志内容格式
+		   ...						///日志内容
+		   );
+
+
+/** 日志模块初始化
+以日志配置文件字符串内容和日志配置文件命作为参数
+若相应配置文件存在则使用,否则按照给定内容和文件名创建日志配置文件并使用之
+@return int,0 表成功
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init_with_string(
+			const char *strFileContent,
+			const char *strFileName 
+			);
+
+/** 日志模块初始化
+以日志配置文件命作为参数
+@return int,0 表成功
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init_with_cfg_file_wrapper(
+			const char * strConfigFile
+			);
+
+/** 日志模块初始化-日志配置文件的文件名设置
+以日志配置文件命作为参数
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_log_cfg_file_name(const char *strFileName);
+
+/** 日志模块初始化-生成的日志文件的文件名设置
+以日志文件命作为参数
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_log_file_name(const char *strFileName);
+
+/** 日志模块初始化-日志记录级别设置
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_log_level(const char *strLogLevel);
+
+/** 日志模块初始化-日志记录文件的大设置
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_log_file_size(const int iFileSize);
+
+/** 日志模块初始化-日志记录文件的个数设置
+记录到最大个数后将回滚重复覆盖第一个日志文件,依次类推
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_log_file_num(const int iFileNum);
+
+/** 日志模块初始化-是否实时读取日志配置文件
+设置是否每次记录时都读取日志配置文件
+@param:const BOOL m_bReReadLogCfgFile
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log_set_reread_log_cfg_file(const BOOL bReReadLogCfgFile);
+
+/** 日志模块初始化-带参数进行日志模块初始化
+这里的参数则为上面的几个API设置的参数,
+所以本函数一定要在日志配置参数设置好之后调用设置的参数才能生效的
+@return int,OK,成功;FAILURE,失败
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init_with_param();
+
+/** 日志模块初始化-带参数进行日志模块初始化,程序的多个运行实例产生的日志不互相冲突
+这里的参数则为上面的几个API设置的参数,
+所以本函数一定要在日志配置参数设置好之后调用设置的参数才能生效的
+@return int,OK,成功;FAILURE,失败
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API int log_init_with_param_multi_process();
+
+/** 日志记录Block方式能清楚的表明调用层次
+类似下面这种B-Entry类型日志:
+main.cpp(87) B-Entry	==> main
+main.cpp(90) B-Entry	====> main_01
+main.cpp(92) B-Entry	======> main_02
+main.cpp(92) B-Exit	<====== main_02 
+main.cpp(90) B-Exit	<==== main_01
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log4c_block_begin(const char * fileName, int lineNum, const char * traceName);
+
+/** 日志记录Block方式能清楚的表明调用层次
+类似下面这种B-Exit类型日志:
+main.cpp(87) B-Entry	==> main
+main.cpp(90) B-Entry	====> main_01
+main.cpp(92) B-Entry	======> main_02
+main.cpp(92) B-Exit	<====== main_02 
+main.cpp(90) B-Exit	<==== main_01
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+LOG4C_API void log4c_block_end(const char * fileName, int lineNum, const char * traceName);
+
+/**检测配置文件是否存在
+@return const int : iPriority.
+作者:Jesse  日期:2010-07-22
+*/
+extern const int log_check(void);
+
+/**检测配置文件是否存在,只检测传入的配置文件名
+@return const int : iPriority.
+作者:Jesse  日期:2010-07-22
+*/
+extern const int log_check_with_cfg_file(const char *strCfgFileName);
+
+/**宏参数抽取format函数
+本函数接受LOG_DEBUG(X)的参数,并从该宏定义的参数中返回format的值
+@return const char* : strFormat
+作者:Jesse  日期:2010-07-22
+*/
+extern const char* log_get_format_wrapper(
+	const int iPriority,	///日志记录级别
+	const char* strFormat,	///日志内容格式
+	...						///日志内容
+	);
+
+
+/** 设置appender
+@return int:
+作者:Jesse  日期:2010-07-22
+*/
+extern int log_setappender(
+			const char *strCatName,		///category名
+			const char *strAppenderName ///appender名
+			);
+
+/** 日志记录
+支持类似printf函数的带格式输出
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+extern void log_log(
+			const char *strCatName,	///category名
+			const int iPriority,	///日志记录级别
+			const char *strFormat,	///日志内容格式
+			...						///日志内容
+			);
+
+/** 日志模块初始化-日志模块使用实例个数自增
+@return void
+作者:Jesse  日期:2010-07-22
+*/
+extern void IncreaseLogModuleUsage();
+
+__LOG4C_END_DECLS
+
+///#include "log4c.h"
+#endif ///((defined(LOG_USELOG4CXX) && defined(__cplusplus)) || defined(LOG4C_ENABLE))
+
+#endif // !defined(LOG_H_INCLUDED_)
+/************** End of Log.h *******************************************/

+ 89 - 0
TCL Copy Tool/Log4C/log4c/logging_event.h

@@ -0,0 +1,89 @@
+/* $Id$
+ *
+ * logging_event.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_logging_event_h
+#define log4c_logging_event_h
+
+/**
+ * @file logging_event.h
+ *
+ * @brief the internal representation of logging events. 
+ * 
+ * When a affirmative logging decision is made a log4c_logging_event
+ * instance is created. This instance is passed around the different log4c
+ * components.
+ **/
+
+#include <log4c/defs.h>
+#include <log4c/buffer.h>
+#include <log4c/location_info.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+
+__LOG4C_BEGIN_DECLS
+
+struct __log4c_category;
+
+/**
+ * @brief logging event object
+ * 
+ * Attributes description:
+ * 
+ * @li @c evt_category category name. 
+ * @li @c evt_priority priority of logging event.
+ * @li @c evt_msg The application supplied message of logging event.
+ * @li @c evt_buffer a pre allocated buffer to be used by layouts to
+ *        format in a multi-thread environment.
+ * @li @c evt_rendered_msg The application supplied message after layout format.
+ * @li @c evt_timestamp The number of seconds elapsed since the epoch
+ * (1/1/1970 00:00:00 UTC) until logging event was created.
+ * @li @c evt_loc The event's location information 
+ **/
+typedef struct 
+{
+    const char* evt_category;
+    int	evt_priority;
+    const char* evt_msg;
+    const char* evt_rendered_msg;
+    log4c_buffer_t evt_buffer;
+/* ok, this is probably not a good way to do it--should define a common type here
+and have the base acessor function do the mapping
+*/
+#ifndef _WIN32
+    struct timeval evt_timestamp;
+#else
+    FILETIME evt_timestamp;
+#endif
+    const log4c_location_info_t* evt_loc;
+
+} log4c_logging_event_t;
+
+/**
+ * Constructor for a logging event.
+ *
+ * @param a_category the category name
+ * @param a_priority the category initial priority
+ * @param a_message the message of this event
+ *
+ * @todo need to handle multi-threading (NDC)
+ **/
+LOG4C_API log4c_logging_event_t* log4c_logging_event_new(
+    const char* a_category,
+    int		a_priority,
+    const char*	a_message);
+/**
+ * Destructor for a logging event.
+ * @param a_event the logging event object
+ **/
+LOG4C_API void log4c_logging_event_delete(log4c_logging_event_t* a_event);
+
+__LOG4C_END_DECLS
+
+#endif

+ 56 - 0
TCL Copy Tool/Log4C/log4c/priority.h

@@ -0,0 +1,56 @@
+/* $Id$
+ *
+ * priority.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_priority_h
+#define log4c_priority_h
+
+/**
+ * @file priority.h
+ *
+ * @brief The priority class provides importance levels with which one can
+ * categorize log messages.
+ **/
+
+#include <log4c/defs.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * Predefined Levels of priorities. These correspond to the priority levels
+ * used by syslog(3).
+ **/
+ typedef enum {
+    /** fatal */	LOG4C_PRIORITY_FATAL	= 000, 
+    /** alert */	LOG4C_PRIORITY_ALERT	= 100, 
+    /** crit */	      	LOG4C_PRIORITY_CRIT	= 200, 
+    /** error */	LOG4C_PRIORITY_ERROR	= 300, 
+    /** warn */	      	LOG4C_PRIORITY_WARN	= 400, 
+    /** notice */	LOG4C_PRIORITY_NOTICE	= 500, 
+    /** info */	      	LOG4C_PRIORITY_INFO	= 600, 
+    /** debug */	LOG4C_PRIORITY_DEBUG	= 700,
+    /** trace */	LOG4C_PRIORITY_TRACE	= 800,
+    /** notset */	LOG4C_PRIORITY_NOTSET	= 900,
+    /** unknown */	LOG4C_PRIORITY_UNKNOWN	= 1000
+} log4c_priority_level_t;
+
+/**
+ * @param a_priority a numeric value of the priority.
+ * @returns the given priority string name.
+ **/
+LOG4C_API const char* log4c_priority_to_string(int a_priority);
+
+/**
+ * @param a_priority_name a priority string name.
+ * @returns the given numeric value of the priority.
+ **/
+LOG4C_API int log4c_priority_to_int(const char* a_priority_name);
+
+__LOG4C_END_DECLS
+
+#endif

+ 70 - 0
TCL Copy Tool/Log4C/log4c/rc.h

@@ -0,0 +1,70 @@
+/* $Id$
+ *
+ * rc.h
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __log4c_rc_h
+#define __log4c_rc_h
+
+/**
+ * @file rc.h
+ *
+ * @brief log4c resource configuration
+ *
+ **/
+
+#include <log4c/defs.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * @brief resource configuration object
+ *
+ * Attributes description:
+ * 
+ * @li @c nocleanup don't perform memory cleanup in log4c library 
+ *        destructor or in log4c_fini()
+ * @li @c bufsize maximum logging buffer size. 0 for no limits
+ * @li @c debug activate log4c debugging
+ **/
+typedef struct 
+{
+    struct 
+    {
+	int nocleanup;
+	int bufsize;
+	int debug;
+	int reread;
+    } config;
+
+} log4c_rc_t;
+
+/**
+ * default log4c resource configuration object
+ **/
+LOG4C_API log4c_rc_t * const	log4c_rc;
+
+/**
+ * load log4c resource configuration file
+ *
+ * @param a_filename name of file to load
+ **/
+LOG4C_API int		log4c_load(const char* a_filename);
+
+/**
+ * @internal
+ **/
+LOG4C_API int		log4c_rc_load(log4c_rc_t* a_rc, const char* a_filename);
+
+/*
+ * Rereads any log4crc files that have changed
+ */
+LOG4C_API void log4c_reread(void);
+
+__LOG4C_END_DECLS
+
+#endif

+ 215 - 0
TCL Copy Tool/Log4C/log4c/rollingpolicy.h

@@ -0,0 +1,215 @@
+
+/*
+ * rollingpolicy.h
+ *
+ * See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_rollingpolicy_h
+#define log4c_rollingpolicy_h
+
+/**
+ * @file rollingpolicy.h
+ *
+ * @brief Log4c rolling policy interface. Defines the interface for
+ * managing and providing rolling policies.
+ *
+ * A rolling policy is used to confogure a rollingfile appender to tell
+ * it when to trigger a rolover event.
+*/ 
+
+#include <stdio.h>
+#include <log4c/defs.h>
+#include <log4c/layout.h>
+
+__LOG4C_BEGIN_DECLS
+
+struct __log4c_rollingpolicy;
+
+/**
+ * log4c rollingpolicy type 
+ */
+typedef struct __log4c_rollingpolicy log4c_rollingpolicy_t;
+
+
+#define ROLLINGFILE_DEFAULT_LOG_DIR "."
+#define ROLLINGFILE_DEFAULT_LOG_PREFIX "log"
+#define ROLLINGFILE_DEFAULT_LOG_EXT "txt"
+
+typedef struct __rollingfile_udata rollingfile_udata_t; /* opaque */
+
+
+/**
+ * @brief log4c rollingpolicy type.  Defines the interface a specific policy
+ * must provide to the rollingfile appender.
+ *
+ * Attributes description:
+ * 
+ * @li @c name rollingpolicy type name 
+ * @li @c init() init the rollingpolicy
+ * @li @c is_triggering_event()
+ * @li @c rollover()
+ *
+ **/
+typedef struct log4c_rollingpolicy_type {
+  const char*	name;
+  int (*init)(log4c_rollingpolicy_t *a_this, rollingfile_udata_t* rfudatap );
+  int (*is_triggering_event)( log4c_rollingpolicy_t* a_policy,
+			      const log4c_logging_event_t*,
+			      long current_file_size );
+  int (*rollover)(log4c_rollingpolicy_t* a_policy, FILE **);  
+  int (*fini)(log4c_rollingpolicy_t *a_this);
+} log4c_rollingpolicy_type_t;
+
+/**
+ * Get a new rolling policy
+ * @param policy_name a name for the policy
+ * @return a new rolling policy, otherwise NULL.
+ */ 
+LOG4C_API log4c_rollingpolicy_t* log4c_rollingpolicy_get(
+                                  const char* policy_name);
+
+/**
+ * Use this function to register a rollingpolicy type with log4c.
+ * Once this is done you may refer to this type by name both 
+ * programmatically and in the log4c configuration file.
+ *
+ * @param a_type a pointer to the new rollingpolicy type to register.
+ * @returns a pointer to the previous rollingpolicy type of same name.
+ *
+ * Example code fragment: 
+ * @code
+ * 
+ * const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_sizewin = {
+ *   "sizewin",
+ *   sizewin_init,
+ *   sizewin_is_triggering_event,
+ *   sizewin_rollover
+ * };
+ *
+ * log4c_rollingpolicy_type_set(&log4c_rollingpolicy_type_sizewin);
+ * @endcode
+ * 
+ */
+LOG4C_API const log4c_rollingpolicy_type_t* log4c_rollingpolicy_type_set(
+                                    const log4c_rollingpolicy_type_t* a_type);
+                                  
+/**
+ * Configure a rolling policy with a specific policy.
+ * @param policyp pointer to the rolling policy
+ * @param udatap a specific policy type, for example sizewin.
+ * @return zero if successful, non-zero otherwise.
+ */                                  
+LOG4C_API void log4c_rollingpolicy_set_udata(log4c_rollingpolicy_t* policyp,
+					  void *udatap);
+/**
+ * Call the initialization code of a rolling policy.
+ * @param policyp pointer to the rolling policy
+ * @param app the rolling appender this policy is used with
+ * @return zero if successful, non-zero otherwise.
+*/
+LOG4C_API int log4c_rollingpolicy_init(log4c_rollingpolicy_t *policyp,
+                                       rollingfile_udata_t* rfup );
+
+/**
+ * Call the un initialization code of a rolling policy.
+ * This will call the fini routine of the particular rollingpolicy type
+ * to allow it to free up resources.  If the call to fini in the 
+ * rollingpolicy type fails then the rollingpolicy is not uninitialized.
+ * Try again later model...
+ * @param policyp pointer to the rolling policy
+ * @return zero if successful, non-zero otherwise.
+*/
+LOG4C_API int log4c_rollingpolicy_fini(log4c_rollingpolicy_t *a_this);
+
+/**
+ * Determine if a logging event should trigger a rollover according to
+ * the given policy.
+ * @param policyp pointer to the rolling policy
+ * @param evtp the logging event pointer.
+ * @param current_file_size the size of the current file being logged to.
+ * @return non-zero if rollover required, zero otherwise.
+ */ 
+LOG4C_API int log4c_rollingpolicy_is_triggering_event(
+		     log4c_rollingpolicy_t* policyp,
+                     const log4c_logging_event_t* evtp,
+		     long current_file_size );
+/**
+ * Effect a rollover according to policyp on the given file stream.
+ * @param policyp pointer to the rolling policy
+ * @param fp filestream to rollover.
+ * @return zero if successful, non-zero otherwise.
+ * The policy can return an indication that something went wrong but
+ * that the rollingfile appender can stull go ahead and log by returning an
+ * error code <= ROLLINGPOLICY_ROLLOVER_ERR_CAN_LOG.  Anything greater than
+ * means that the rolling file appender will not try to log it's message.
+ */        
+
+#define  ROLLINGPOLICY_ROLLOVER_ERR_CAN_LOG 0x05
+LOG4C_API int log4c_rollingpolicy_rollover(log4c_rollingpolicy_t* policyp,
+                                            FILE ** fp);
+
+/**
+ * sets the rolling policy type
+ *
+ * @param a_rollingpolicy the log4c_rollingpolicy_t object
+ * @param a_type the new rollingpolicy type
+ * @return the previous appender type
+ **/
+LOG4C_API const log4c_rollingpolicy_type_t* log4c_rollingpolicy_set_type(
+    log4c_rollingpolicy_t* a_rollingpolicy,
+    const log4c_rollingpolicy_type_t* a_type);
+    
+/**
+ * Get a pointer to an existing rollingpolicy type.
+ *
+ * @param a_name the name of the rollingpolicy type to return.  
+ * @returns a pointer to an existing rollingpolicy type, or NULL if no 
+ * rollingpolicy type with the specified name exists.
+ */
+LOG4C_API const log4c_rollingpolicy_type_t* log4c_rollingpolicy_type_get(
+    const char* a_name);
+                                            
+/**
+ * Get the rolling policy configuration.
+ * @param policyp pointer to the rolling policy
+ * @return pointer to the rolling policy configuration.
+*/                                             
+LOG4C_API void* log4c_rollingpolicy_get_udata(
+                        const log4c_rollingpolicy_t* policyp);
+                        
+/**
+ * Get the rollingfile appender associated with this policy.
+ * @param policyp pointer to the rolling policy
+ * @return pointer to the rolling file appender associated with this policy
+*/                          
+LOG4C_API rollingfile_udata_t* log4c_rollingpolicy_get_rfudata(
+                        const log4c_rollingpolicy_t* policyp);
+                        
+LOG4C_API void* log4c_rollingpolicy_get_name(const log4c_rollingpolicy_t* a_this);                        
+
+LOG4C_API log4c_rollingpolicy_t* log4c_rollingpolicy_new(const char* a_name);
+LOG4C_API void log4c_rollingpolicy_delete(log4c_rollingpolicy_t* a_this);
+LOG4C_API void log4c_rollingpolicy_print(const log4c_rollingpolicy_t* a_this,
+FILE* a_stream);
+
+LOG4C_API int log4c_rollingpolicy_is_initialized(log4c_rollingpolicy_t* a_this);
+LOG4C_API void log4c_rollingpolicy_types_print(FILE *fp);
+
+/** 删除本rollingpolicy.c文件中定义的全局和静态的指针指向的内存,防止内存泄漏
+如:
+1.gs_types.
+2.
+@return void.
+作者:jesse 日期:2008.09.08
+*/
+LOG4C_API void log4c_rollingpolicy_delete_global();
+
+/**
+ * @internal
+ **/
+struct __sd_factory;
+LOG4C_API struct __sd_factory* log4c_rollingpolicy_factory;
+
+__LOG4C_END_DECLS
+#endif

+ 86 - 0
TCL Copy Tool/Log4C/log4c/rollingpolicy_type_sizewin.h

@@ -0,0 +1,86 @@
+
+/*
+ * rollingpolicy_type_sizewin.h
+ *
+ * See the COPYING file for the terms of usage and distribution.
+*/
+
+#ifndef log4c_policy_type_sizewin_h
+#define log4c_policy_type_sizewin_h
+
+/**
+ * @file rollingpolicy_type_sizewin.h
+ *
+ * @brief Log4c rolling file size-win interface.
+ * Log4c ships with (and defaults to) the classic size-window rollover policy:
+ * this triggers rollover when files reach a maximum size.  The first file in
+ * the list is
+ * always the current file; when a rollover event occurs files are shifted up
+ * by one position in the list--if the number of files in the list has already
+ * reached the max then the oldest file is rotated out of the window.
+ *
+ * If the max file size is set to zero, this means 'no-limit'.
+ *
+ * The default parameters for the size-win policy are 5 files of maximum
+ * size of 20kilobytes each.  These parameters may be changed using the
+ * appropriate setter functions.
+ */
+ 
+#include <log4c/defs.h>
+#include <log4c/rollingpolicy.h>
+
+__LOG4C_BEGIN_DECLS
+
+LOG4C_API const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_sizewin;
+
+/**
+ * log4c size-win rolling policy type 
+*/
+typedef struct __sizewin_udata rollingpolicy_sizewin_udata_t;
+
+#define ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE 1024*20
+#define ROLLINGPOLICY_SIZE_DEFAULT_MAX_NUM_FILES 5
+
+/**
+ * Get a new size-win rolling policy
+ * @return a new size-win rolling policy, otherwise NULL.
+ */
+LOG4C_API rollingpolicy_sizewin_udata_t *sizewin_make_udata(void);
+
+/**
+ * Set the maximum file size in this rolling policy configuration.
+ * @param swup the size-win configuration object.
+ * @param max_size the approximate maximum size any logging file will
+ * attain.
+ * If you set zero then it means 'no-limit' and so only one file
+ * of unlimited size will be used for logging.
+ * @return zero if successful, non-zero otherwise.
+ */
+LOG4C_API int sizewin_udata_set_file_maxsize(
+                              rollingpolicy_sizewin_udata_t * swup,
+			      long max_size);
+                                                            
+/**
+ * Set the maximum number of filesin this rolling policy configuration.
+ * @param swup the size-win configuration object.
+ * @param max_num the maximum number of files in the list.
+ * @return zero if successful, non-zero otherwise.
+ */                                                         
+LOG4C_API int sizewin_udata_set_max_num_files(
+                              rollingpolicy_sizewin_udata_t * swup,
+	                      long max_num);
+
+/**
+ * Set the rolling file appender in this rolling policy configuration.
+ * @param swup the size-win configuration object.
+ * @param app the rolling file appender to set.
+ * @return zero if successful, non-zero otherwise.
+*/                                                            
+LOG4C_API int sizewin_udata_set_appender(
+                              rollingpolicy_sizewin_udata_t * swup,
+			      log4c_appender_t* app);
+
+__LOG4C_END_DECLS
+
+
+#endif

+ 40 - 0
TCL Copy Tool/Log4C/log4c/sharedmemory.h

@@ -0,0 +1,40 @@
+/************** Begin of sharedmemory.h *******************************************/
+#if defined(linux)  && defined(HAVE_SHM)
+	/***************************************************************************
+	|sharedmemory.h|  -  sharedmemory类的头文件-声明sharedmemory类
+	-------------------
+	begin                : |03-6-20|
+	modify               : |03-6-20|
+	copyright            : (C) |YEAR| by |wenhm(温辉敏)|
+	email                : |EMAIL|
+	***************************************************************************/
+
+#ifndef SHAREDMEMORY_H
+#define SHAREDMEMORY_H
+
+#include <sys/types.h>
+
+	//创建或关键字为Key的含有大小为size的共享内存对象,并将共享内存对象id放于shmid中返回。
+	//若共享内存对象已存在则取得该对象
+	extern int create_sharedmemory(key_t key, int size);
+
+	//创建关键字Key为IPC_PRIVATE(即关键字由系统选定)的含有大小为size的共享内存对象,并将共享内存对象id放于shmid中返回。
+	//因使用IPC_PRIVATE创建的共享内存的key都一样,所以key就不要了。
+	extern int create_sharedmemory_private(int size);
+
+	//将共享内存attach到进程自己得空间内,函数返回指向映射内存的指针。
+	extern void *attach_sharedmemory(int shmid );
+
+	//将共享内存disattach,唯一的参数是共享内存映射的指针
+	//返回值: -1 on error: errno = EINVAL (Invalid attach address passed)
+	extern int disattach_sharedmemory(void* shm);
+
+	//获取共享内存对象shmid的大小
+	extern int getsize_sharedmemory(int shmid);
+
+	//删除共享内存对象
+	extern int del_sharedmemory(int shmid);
+#endif	/* SHAREDMEMORY_H */  
+
+#endif
+/************** Begin of sharedmemory.h *******************************************/

+ 57 - 0
TCL Copy Tool/Log4C/log4c/version.h

@@ -0,0 +1,57 @@
+/* $Id$
+ *
+ * version.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_version_h
+#define log4c_version_h
+
+/**
+ * @file version.h
+ *
+ * @brief log4c version information
+ **/
+
+#include <log4c/defs.h>
+
+__LOG4C_BEGIN_DECLS
+
+/**
+ * constant macro holding the major version of log4c
+ **/
+#define LOG4C_MAJOR_VERSION 1
+/**
+ * constant macro holding the minor version of log4c
+ **/
+#define LOG4C_MINOR_VERSION 2
+/**
+ * constant macro holding the micro version of log4c
+ **/
+#define LOG4C_MICRO_VERSION 1
+
+/**
+ * constant variable holding the major version of log4c
+ **/
+extern const int log4c_major_version;
+/**
+ * constant variable holding the minor version of log4c
+ **/
+extern const int log4c_minor_version;
+/**
+ * constant variable holding the micro version of log4c
+ **/
+extern const int log4c_micro_version;
+
+/**
+ * @return a string containing the full log4c version
+ **/
+extern const char* log4c_version(void);
+
+__LOG4C_END_DECLS
+
+#endif
+

+ 676 - 0
TCL Copy Tool/Log4C/log4c/vos.h

@@ -0,0 +1,676 @@
+/************** Begin of vos.h *******************************************/
+/**********************************************************
+* 版权所有 (C)2002, 深圳市中兴通讯股份有限公司。
+*
+* 文件名称: vos.h
+* 文件标识:
+* 内容摘要: 操作系统封装层头文件(主要是所包含头文件、数据结构、接口等)
+* 其它说明: 无
+* 当前版本: V1.0
+* 作    者: 王泽民
+* 完成日期: 2003/08/10
+*
+* 修改记录1:
+*    修改日期:
+*    版 本 号:
+*    修 改 人:
+*    修改内容:
+**********************************************************/
+#ifndef _VOS_H_
+#define _VOS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "voscfg.h"
+	/**********************************************************
+	*                          宏定义                         *
+	**********************************************************/
+
+#define    VOS_NULL                      0x0
+
+#define    VOS_TRUE                      1
+#define    VOS_FALSE                     0
+
+#define    VOS_SUCCESS                   0     /* PSOS返回值                    */
+#define    VOS_PCBINDEXNO                0     /* 保存pcbindex的便条寄存器号    */
+#define    VOS_TASKPRINO                 1     /* 保存任务优先级的便条寄存器号  */
+#define    VOS_TICKNUM                   1     /* 中断的tick数                  */
+#define    TIMER_SCAN_EVENT              (WORD32)(1<<15)
+#define    MEMLEAK_SCAN_EVENT            (WORD32)(1<<16)
+#define    MAX_LENGTH_BUF                512
+
+#define    VOS_NO_WAIT                   0x0
+#define    VOS_WAIT_FOREVER              -1
+
+#define    VOS_SEM_DELETE_SAFE           0x04
+#define    VOS_SEM_INVERSION_SAFE        0x08
+
+#define    VOS_VM_STATE_MASK_VALID       0x03
+#define    VOS_VM_STATE_MASK_WRITABLE    0x0c
+#define    VOS_VM_STATE_MASK_CACHEABLE   0x30
+#define    VOS_VM_STATE_MASK_WBACK       0x40
+#define    VOS_VM_STATE_MASK_GLOBAL      0x80
+#define    VOS_VM_STATE_MASK_GUARDED     0x80
+
+#define    VOS_VM_STATE_VALID            0x01
+#define    VOS_VM_STATE_VALID_NOT        0x00
+#define    VOS_VM_STATE_WRITABLE         0x04
+#define    VOS_VM_STATE_WRITABLE_NOT     0x00
+#define    VOS_VM_STATE_CACHEABLE        0x10
+#define    VOS_VM_STATE_CACHEABLE_NOT    0x00
+#define    VOS_VM_STATE_WBACK			 0x40
+#define    VOS_VM_STATE_WBACK_NOT		 0x00
+#define    VOS_VM_STATE_GLOBAL			 0x80
+#define    VOS_VM_STATE_GLOBAL_NOT		 0x00
+#define    VOS_VM_STATE_GUARDED			 0x80
+#define    VOS_VM_STATE_GUARDED_NOT		 0x00
+
+#define    MAXCOUNTSEM                   10000
+#define    VOS_MAX_PATH_LEN              50
+#define    VOS_MAX_FILENAME_LEN          60
+#define    VOS_MAX_EXP_FILENAME_LEN      8
+
+#if OS_TYPE == OS_VXWORKS
+#define    NULL_TASKID               ERROR
+#define    NULL_SEMID                NULL
+#define    NULL_MSGQID               NULL
+#define    NULL_MSGGET               0
+#define    DIR_CODE                  0x2f    /* 定义符号 "/" */
+#define    DIR_CONCATE_CODE            "/"
+#endif
+
+#if OS_TYPE == OS_WINNT
+#define    NULL_TASKID               NULL
+#define    NULL_SEMID                NULL
+#define    NULL_MSGQID               NULL
+#define    NULL_MSGGET               0
+#define    DIR_CODE                  0x5c    /* 定义符号" \" */
+#define    DIR_CONCATE_CODE            "\\"
+#define    RDONLY                    0
+#define    WRONLY                    1
+#define    RDWR                      2
+#define    WINNT_ERROR               -1    
+#endif
+
+#if OS_TYPE == OS_PSOS
+#define    NULL_TASKID               0xffffffff
+#define    NULL_SEMID                0xffffffff
+#define    NULL_MSGQID               0xffffffff
+#define    NULL_MSGGET               0xffffffff
+#define    MSG_Q_FIFO                0x00
+#define    MSG_Q_PRIORITY            0x01
+#define    MSG_PRI_NORMAL            0x00
+#define    MSG_PRI_URGENT            0x01
+#define    RAM_BLOCKS                2*360  /* RAM disk块大小 */
+#define    RAM_PATH_LENGTH           80
+#define    MIN_EXPAN_BLOCKS          10
+#endif
+
+#if OS_TYPE == OS_LINUX
+#ifdef VXWORKS_TO_LINUX
+#define    NULL_TASKID               ERROR
+#define    NULL_SEMID                NULL
+#define    NULL_MSGQID               NULL
+#else
+#define    NULL_TASKID               0xffffffff
+#define    NULL_SEMID                0xffffffff
+#define    NULL_MSGQID               0xffffffff
+#endif
+#define    NULL_MSGGET               0
+#define    DIR_CODE                  0x2f  /* 定义符号 "/" */
+
+#endif
+
+#if OS_TYPE == OS_KLINUX
+#define    NULL_TASKID               ERROR
+#define    NULL_SEMID                 NULL
+#define    NULL_MSGQID              NULL
+#define    TRUE   1
+#define    FALSE 0
+#define    DIR_CONCATE_CODE        "/"
+#define    DIR_CODE                0x2f
+#define    VOS_ISDIR(mode)    ((mode & S_IFMT) == S_IFDIR)    /* 判断是否是目录 */
+	// #define    malloc(size) __vmalloc(size,GFP_KERNEL |__GFP_HIGHMEM, PAGE_KERNEL)
+	//#define    free(buf)      vfree(buf)
+#define    printf  printk
+#endif
+
+
+	/************** SOCKET & TCP ***************/
+#define NELEMENTS(array)  (sizeof (array) / sizeof ((array) [0]))
+
+#ifndef HASMAX
+#ifndef max
+#define max(a,b) ((a)>(b)?(a):(b))
+#endif
+#endif
+
+#ifndef HASMIN
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+#endif 
+
+
+#if (OS_TYPE == OS_VXWORKS)
+#define SOCKET_ERROR     ERROR
+#define SOMAXCONN        5
+#define VOS_EWOULDBLOCK  EWOULDBLOCK
+#define VOS_ECONNRESET   ECONNRESET
+#endif
+
+#if (OS_TYPE == OS_WINNT)
+	/* 数组中元素个数 */
+	///(pclint检测注释掉该行)#define NELEMENTS(array)  (sizeof (array) / sizeof ((array) [0]))
+#define CloseSocket closesocket
+#define bcopy(src,dst,size) memcpy(dst,src,size)
+#define errnoGet         WSAGetLastError
+	typedef long int STATUS ;
+#define VOS_EWOULDBLOCK WSAEWOULDBLOCK
+#define VOS_ECONNRESET WSAECONNRESET
+#endif
+
+
+#if ((OS_TYPE == OS_LINUX) ||(OS_TYPE == OS_KLINUX))
+	typedef unsigned long ULONG;
+#define errnoGet() errno
+#define SOCKET_ERROR     ERROR
+#define SOMAXCONN	128
+#define VOS_EWOULDBLOCK  EWOULDBLOCK
+#define VOS_ECONNRESET ECONNRESET
+
+#endif
+
+#if ((OS_TYPE == OS_VXWORKS) || (OS_TYPE == OS_LINUX)||(OS_TYPE == OS_KLINUX))
+	typedef int SOCKET;
+#endif
+
+	/**************** VOS TIMER *******************/
+
+	/* 时钟中断精度10ms */
+#define  TIMER_RESOLUTION    10 
+
+
+#if (OS_TYPE == OS_WINNT)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <mmsystem.h>
+#define  VOS_TIMERCALLBACK     LPTIMECALLBACK  
+#define  VOS_TIMER_ID          WORD32 
+#define  INVALID_VOS_TIMERID   0
+#endif
+
+#if (OS_TYPE == OS_VXWORKS)
+#define  VOS_TIMERCALLBACK     FUNCPTR  
+#define  VOS_TIMER_ID          WDOG_ID 
+#define  INVALID_VOS_TIMERID   NULL
+
+#define  TIMER_ONESHOT         0
+#define  TIMER_PERIODIC        1
+#endif
+
+#if (OS_TYPE == OS_PSOS)
+#define  VOS_TIMERCALLBACK     LPVOID  
+#define  VOS_TIMER_ID          WORD32 
+#define  INVALID_VOS_TIMERID   0xffffffff
+#endif
+
+#if (OS_TYPE == OS_LINUX)
+	typedef  void(*VOS_TIMERCALLBACK)(int);
+#define  VOS_TIMER_ID          WORD32 
+#define  INVALID_VOS_TIMERID   0
+#endif
+
+#if (OS_TYPE == OS_KLINUX)
+#ifndef HZ
+#define HZ 100
+#endif     
+	extern unsigned long volatile jiffies;
+
+	typedef  void(*VOS_TIMERCALLBACK)(WORD32);
+	typedef  struct timer_list    *VOS_TIMER_ID;
+#define  INVALID_VOS_TIMERID   NULL    
+#endif
+
+	/**************** VOS VOLUME *******************/
+#define        VOLNAME_LENGTH            10
+
+
+	/**********************************************************
+	*                          类型定义                       *
+	**********************************************************/
+
+#if    OS_TYPE == OS_VXWORKS
+#define    VOS_ISDIR(mode)    ((mode & S_IFMT) == S_IFDIR)    /* 判断是否是目录 */
+#define    VOS_ISCHR(mode)    ((mode & S_IFMT) == S_IFCHR)    /* 是否 是特殊字符 */
+#define    VOS_ISBLK(mode)    ((mode & S_IFMT) == S_IFBLK)    /* 判断是否是特殊块 */
+#define    VOS_ISREG(mode)    ((mode & S_IFMT) == S_IFREG)    /* 判断是否正规块 */
+#define    VOS_ISFIFO(mode)   ((mode & S_IFMT) == S_IFIFO)    /* 判断是否fifo  */
+#elif OS_TYPE== OS_WINNT
+#define    VOS_ISDIR(mode)    ((mode & _S_IFMT) == _S_IFDIR)    /* 判断是否是目录 */
+#define    VOS_ISCHR(mode)    ((mode & _S_IFMT) == _S_IFCHR)    /* 是否 是特殊字符 */
+#define    VOS_ISBLK(mode)    ((mode & _S_IFMT) == _S_IFBLK)    /* 判断是否是特殊块 */
+#define    VOS_ISREG(mode)    ((mode & _S_IFMT) == _S_IFREG)      /* 判断是否正规块 */
+#define    VOS_ISFIFO(mode)   ((mode & _S_IFMT) == _S_IFIFO)    /* 判断是否fifo  */
+#endif
+
+
+	/* ID类型定义 */
+#if OS_TYPE == OS_VXWORKS
+	typedef SWORD32  TASK_ID;
+	typedef PART_ID  MEMPART_ID;
+	typedef FUNCPTR  VOS_FUNCPTR;
+	typedef WIND_TCB TASK_TCB;	
+#endif
+
+#if OS_TYPE == OS_PSOS
+	typedef WORD32  TASK_ID;
+	typedef VOS_VOIDFUNCPTR  VOS_FUNCPTR;
+	typedef WORD32  SEM_ID;
+	typedef WORD32  MSG_Q_ID;
+	typedef WORD32  MEMPART_ID;	
+#endif
+
+#if OS_TYPE == OS_WINNT
+	typedef HANDLE   TASK_ID;
+	typedef HANDLE   SEM_ID;
+	typedef HANDLE   MEMPART_ID;
+	typedef HANDLE   MSG_Q_ID;
+	typedef LPTHREAD_START_ROUTINE VOS_FUNCPTR;	
+#endif
+
+#if OS_TYPE == OS_LINUX
+	typedef void        VOID;
+	typedef pthread_t	TASK_ID;
+	typedef sem_t *		SEM_ID; 
+#ifndef PART_ID
+#define PART_ID int
+#endif /*wenhm,050826*/
+	typedef PART_ID     MEMPART_ID;
+	typedef void*       VOS_FUNCPTR; 
+	///typedef void (*AutoRunHandler)(void);
+	typedef WORD32      MSG_RECEIVE;/*yangyp*/    
+	typedef WORD32      MSG_Q_ID;
+
+	///typedef FUNCPTR     VOS_FUNCPTR; 
+	///typedef WIND_TCB    TASK_TCB;
+	///typedef WORD16      VOS_TIMER_ID;/*yangyp*/
+	///typedef WORD32		SEM_ID;
+	///typedef SWORD32     TASK_ID;
+#endif
+#if OS_TYPE == OS_KLINUX
+	typedef void        VOID;
+	typedef pthread_t	TASK_ID;
+	typedef sem_t*		SEM_ID; 
+	/*typedef PART_ID     MEMPART_ID;
+	typedef FUNCPTR     VOS_FUNCPTR;
+	typedef WIND_TCB    TASK_TCB;*/
+	typedef WORD32      MEMPART_ID;
+	typedef void*       VOS_FUNCPTR;
+	typedef WORD32      MSG_RECEIVE;/*yangyp*/
+	typedef WORD16      VOS_TIMER_ID;/*yangyp*/
+	typedef WORD32      MSG_Q_ID;
+#endif
+
+
+	/* VOS_STATUS: VOS层函数返回值 */
+	typedef enum
+	{
+		VOS_ERROR = -1,
+		VOS_OK = 0,
+	}VOS_STATUS;
+
+	/* VOS_SEM_STATE  二进制信号量初始状态 */
+	typedef enum
+	{
+		VOS_SEM_EMPTY,
+		VOS_SEM_FULL
+	}VOS_SEM_STATE;
+
+	/* 信号量队列类型:先进先出或优先级 */
+	typedef enum
+	{
+		VOS_SEM_Q_FIFO,
+		VOS_SEM_Q_PRIORITY
+	}VOS_SEM_QUEUE_TYPE;
+
+	/* 消息优先级 */
+	typedef enum
+	{
+		VOS_MSG_PRI_NORMAL,
+		VOS_MSG_PRI_URGENT
+	}VOS_MSG_TYPE;
+
+	/* 消息排队类型:先进先出或优先级 */
+	typedef enum
+	{
+		VOS_MSG_Q_FIFO,
+		VOS_MSG_Q_PRIORITY
+	}VOS_MSGQUE_TYPE;
+
+	/* 任务状态 */
+	typedef enum
+	{
+		VOS_TASK_STATUS_NULL,
+		VOS_TASK_STATUS_RUNNING,
+		VOS_TASK_STATUS_READY,
+		VOS_TASK_STATUS_PEND,
+		VOS_TASK_STATUS_SUSPEND,
+		VOS_TASK_STATUS_DEBUG,
+		VOS_TASK_STATUS_DEAD
+	}VOS_TASK_STATUS;
+
+	/* 参数和返回值为VOID的函数定义 */
+	typedef   VOID(*VOS_VOIDFUNCPTR)(VOID);
+
+	/**********************************************************
+	*                          数据结构定义                   *
+	**********************************************************/
+
+	/* 系统时钟 */
+	typedef struct tagSYS_CLOCK
+	{
+		WORD16             wSysYear;
+		WORD16             wSysMon;
+		WORD16             wSysDay;
+		WORD16             wSysHour;
+		WORD16             wSysMin;
+		WORD16             wSysSec;
+		WORD16             wSysWeek;
+		WORD16             wMilliSec;
+	}T_SYS_CLOCK;
+
+#undef st_atime
+#undef st_mtime
+#undef st_ctime
+	/* 文件状态描述 */
+	typedef struct tagFileStat
+	{
+		WORD32  st_dev;
+		WORD32  st_ino;
+		WORD16  st_mode;
+		SWORD16 st_nlink;
+		SWORD16 st_uid;
+		SWORD16 st_gid;
+		WORD32  st_rdev;
+		SWORD32 st_size;
+		SWORD32 st_atime;
+		SWORD32 st_mtime;
+		SWORD32 st_ctime;
+	}T_FileStat;
+
+
+	/* added by 温辉敏,文件的访问属性*/
+	enum Permissions {
+		/// File has world execute permission
+		WorldExecute = 1,   
+		/// File has world write permission
+		WorldWrite = 2,     
+		/// File has world read permission
+		WorldRead = 4,      
+		/// File has group execute permission
+		GroupExecute = 8,   
+		/// File has group write permission
+		GroupWrite = 16,    
+		/// File has group read permission
+		GroupRead = 32,     
+		/// File has owner execute permission
+		UserExecute = 64,   
+		/// File has owner write permission
+		UserWrite = 128,    
+		/// File has owner read permission
+		UserRead = 256,     
+		/// All possible permissions.
+		AllPermissions = 0x1ff,   
+		/// Owner read & write plus group and world read permissions.
+		DefaultPerms = UserRead|UserWrite|GroupRead|WorldRead,
+		/// Owner read & write & execute plus group and world read & exectute permissions.
+		DefaultDirPerms = DefaultPerms|UserExecute|GroupExecute|WorldExecute		
+	};
+
+#if OS_TYPE == OS_WINNT
+	/**
+	下面结构当和MINIAce一起使用时,
+	os_dirent.h中相应的结构产生的冲突,而os_dirent.h结构中采用了ACE_LACKS_STRUCT_DIR才会生效,
+	因此可以设定vos.h中不采用ACE_LACKS_STRUCT_DIR宏定义时它的结构dirent才生效. 
+	added by wenhm in 2007.05.16
+	*/
+#ifndef ACE_LACKS_STRUCT_DIR
+	/* 路径入口 */
+	struct  dirent
+	{
+		unsigned short d_ino;
+		unsigned short d_off;
+		unsigned short d_reclen;
+		CHAR     d_name [VOS_MAX_FILENAME_LEN + 1];
+	};
+#endif
+
+
+	/* 目录项的定义 */
+	typedef struct
+	{
+		SWORD32       dd_fd;        /* 打开目录的文件描述 */
+		SWORD32       dd_cookie;    /* 目录中的文件特定标示filesys-specific marker within dir */
+		struct dirent dd_dirent;    /* 路径入口 */
+	}DIR;
+
+
+#endif
+
+
+
+	/**********************************************************
+	*                          函数原型                       *
+	**********************************************************/
+
+	/******************  任务管理模块 ************************/
+	TASK_ID       VOS_CreateTask(CHAR *pTaskName, SWORD32 priority,
+		SWORD32 options, SWORD32 stackSize,
+		VOS_FUNCPTR pTaskEntry, SWORD32 arg1,
+		SWORD32 arg2, SWORD32 arg3, SWORD32 arg4,
+		SWORD32 arg5, SWORD32 arg6, SWORD32 arg7,
+		SWORD32 arg8, SWORD32 arg9, SWORD32 arg10);
+
+	VOS_STATUS    VOS_DeleteTask(TASK_ID taskId);
+	VOS_STATUS    VOS_SuspendTask(TASK_ID taskId);
+	VOS_STATUS    VOS_ResumeTask(TASK_ID  taskId);
+	VOS_STATUS    VOS_SetPriority(TASK_ID TaskId, SWORD32 newPriority);
+	SWORD32       VOS_GetPriority(TASK_ID TaskId);
+
+	VOS_STATUS    VOS_DelayTask(SWORD32 delayTime);
+	TASK_ID       VOS_GetSelfTaskID(VOID);
+	VOS_STATUS    VOS_SuspendSelf(VOID);
+
+	VOS_TASK_STATUS VOS_GetTaskStatus(TASK_ID taskId);
+	VOID          VOS_CheckStack(TASK_ID taskId);
+
+
+	/************** 二进制信号量与计数信号量 *****************/
+	SEM_ID        VOS_CreateBSem(SWORD32 options, VOS_SEM_STATE initialState);
+	SEM_ID        VOS_CreateCSem(SWORD32 options, SWORD32 initialState);
+	SEM_ID        VOS_CreateMSem(SWORD32 options);
+	VOS_STATUS    VOS_DeleteSem(SEM_ID semId);
+	VOS_STATUS    VOS_TakeSem(SEM_ID semId, SWORD32 timeout);
+	VOS_STATUS    VOS_GiveSem(SEM_ID semId);
+
+
+	/**************** 内存管理模块 ***************************/
+	MEMPART_ID    VOS_CreateMemPart(CHAR *pPool, WORD32 poolSize);
+	VOID         *VOS_AllocMemPart(MEMPART_ID memPartId, WORD32 size);
+	VOS_STATUS    VOS_FreeMemPart(MEMPART_ID memPartId, CHAR *pBlock);
+
+	CHAR         *VOS_GetPhysMemTop(VOID);
+	WORD32        VOS_GetRnFreeInfo(WORD32 dwRnId);
+
+	/********************* 中断处理 ******* ******************/
+	SWORD32       VOS_LockInt();
+	VOID          VOS_UnlockInt(SWORD32 dwLevel);
+
+
+	/********************* 消息队列 **************************/
+	MSG_Q_ID      VOS_CreateMsgQue(WORD32 dwMaxMsgNum,
+		WORD32 dwMaxMsgLength,
+		BYTE ucOptions);
+	VOS_STATUS    VOS_DeleteMsgQue(MSG_Q_ID wMsgId);
+	VOS_STATUS    VOS_SendMsg(MSG_Q_ID wMsgId,
+		CHAR *pcMsgData,
+		WORD32 dwlen,
+		SWORD32 dwtimeout,
+		BYTE ucPrior);
+	WORD32        VOS_ReceiveMsg(MSG_Q_ID wMsgId,
+		CHAR  *pcMsgDataBuffer,
+		WORD32 dwlen,
+		SWORD32 iTimeout);
+	WORD32        VOS_GetCurMsgs(MSG_Q_ID wMsgId);
+
+
+	/********************* 时钟模块 **************************/
+	VOS_STATUS    VOS_ConnectClk(VOS_VOIDFUNCPTR clkIntEntry);
+	SWORD32       VOS_GetSysClkRate(VOID);
+	WORD32        VOS_GetTick();
+	VOS_STATUS    VOS_IniSysClk(T_SYS_CLOCK *pSysSoftClk);
+	VOS_STATUS    VOS_SetSysClkRate(SWORD32 sdTicPerSend);
+
+	VOS_STATUS    VOS_TimeSet(T_SYS_CLOCK *pSysSoftClk);
+	VOS_STATUS    VOS_TimeGet(T_SYS_CLOCK *pSysSoftClk);
+
+	VOS_TIMER_ID VOS_RelTimer(
+		WORD32 dwTimeLength, 
+		VOS_TIMERCALLBACK lpTimeProc,
+		WORD32 dwUser,
+		WORD32 dwEvents			 
+		);
+
+	VOS_TIMER_ID VOS_AbsTimer(
+		T_SYS_CLOCK tRelTimerSet, 
+		VOS_TIMERCALLBACK lpTimeProc,
+		WORD32 dwUser,
+		WORD32 dwEvents			 
+		);
+
+	VOS_TIMER_ID VOS_PerTimer(
+		WORD32 dwTimeLength, 			 
+		VOS_TIMERCALLBACK lpTimeProc,
+		WORD32 dwUser,
+		WORD32 dwEvents			 
+		);
+
+	VOS_STATUS   VOS_TimerKill(VOS_TIMER_ID TimerId);
+
+
+	/********************* 错误异常 **************************/
+	SWORD32       VOS_GetErrno(VOID);
+	VOID          VOS_AddExcHook(VOS_FUNCPTR excHookEntry);
+
+	/********************* 初始化VOS *************************/
+	VOS_STATUS    VOS_InitVOS(VOID);
+
+
+	/****************** 当前进程PCB操作 **********************/
+	VOS_STATUS    VOS_SetCurPCBIndex(WORD16  wIndex);
+	WORD16        VOS_GetCurPCBIndex(VOID);
+	VOS_STATUS    VOS_FreeTlsData(VOID);
+
+	/******************      事件模块   **********************/
+	VOS_STATUS    VOS_SendEvent(TASK_ID taskId, WORD32 dwEvents);
+	VOS_STATUS    VOS_ReceiveEvent(WORD32 dwEvents, WORD32 dwTimeout,
+		WORD32 *ptEventsR);
+
+
+	/******************  调试打印函数  **********************/
+	VOID          VOS_Display(const CHAR *fmt, ... );
+
+
+	/********************文件系统模块**********************/
+	SWORD32       VOS_Create(CHAR *pcFileName);
+	VOS_STATUS    VOS_Delete(CHAR *pcFileName);
+	SWORD32       VOS_Open(CHAR *pcFileName,SWORD32 sdwFlag,SWORD32 sdwMode);
+	VOS_STATUS    VOS_Close(SWORD32 sdwFileHandle);
+	VOS_STATUS    VOS_Rename(CHAR *pcOldFileName,CHAR *pcNewFileName);
+	SWORD32       VOS_Read(SWORD32 sdFileHandle,VOID *pBuffer,SWORD32 sdCount);
+	SWORD32       VOS_Write(SWORD32 sdFileHandle,VOID *pBuffer,SWORD32 sdCount);
+	SWORD32       VOS_FileLength(CHAR *pcFileName);
+	SWORD32       VOS_Lseek(SWORD32 sdFileHandle,SWORD32 sdOffset,SWORD32 sdOrigin);
+	VOS_STATUS    VOS_CreateDir(CHAR *pcDirName);
+	VOS_STATUS    VOS_DeleteDir(CHAR *pcDirName);
+	VOS_STATUS    VOS_RenameDir(CHAR *pcOldDirName,CHAR *pcNewDirName);
+	DIR           *VOS_OpenDir(CHAR *pcDirName);
+	struct dirent *VOS_ReadDir(DIR *pDir);
+	VOS_STATUS    VOS_CloseDir(DIR *pDir);
+	VOS_STATUS    VOS_Stat(CHAR *pcFileName, T_FileStat *pStat);
+	VOS_STATUS    VOS_CreateMemDev(CHAR      *pcRamDiskName,
+		CHAR      *pcRamAddr,
+		SWORD32   sdwCHARsPerBlk,
+		SWORD32   sdwBlksPerTrack,
+		SWORD32   sdwNBlocks,
+		SWORD32   sdwBlkOffset);
+	VOS_STATUS    VOS_StartFtpServer(LPVOID   pLoginRtn,
+		SWORD32  sdwStackSize);
+
+	VOS_STATUS    VOS_StopFtpServer(VOID);
+
+#if OS_TYPE == OS_PSOS
+	VOS_STATUS    VOS_FileSystemInit(VOID);
+#endif
+
+	/****************** SOCKET **********************/
+	VOS_STATUS  VOS_InitSocketLib(VOID);
+	SOCKET      VOS_Socket(SWORD32 family, SWORD32 type,SWORD32 protocol );
+	VOS_STATUS  VOS_Bind(SWORD32 s, const struct sockaddr * name,  SWORD32 namelen);
+	VOS_STATUS  VOS_Accept(SOCKET s ,struct sockaddr * addr,SWORD32* addrlen );
+	VOS_STATUS  VOS_Listen(SOCKET s ,SWORD32 backlog );
+	SWORD32     VOS_Send(SOCKET s,const char * buffer,SWORD32 len, SWORD32 flags);
+	SWORD32     VOS_Recv(SOCKET s,const char * buffer,SWORD32 len,SWORD32 flags);
+	VOS_STATUS  VOS_CloseSocket(SOCKET s);
+	VOS_STATUS  VOS_CleanUp(void);
+	VOS_STATUS  VOS_ConnectWithTimeout(SOCKET s,  struct sockaddr * adrs,  int adrsLen,
+	struct timeval *  timeVal );
+	SWORD32     VOS_SendTo(SOCKET s,const char *buffer,SWORD32 len, SWORD32 flags,
+	struct sockaddr *to, int tolen );
+	SWORD32     VOS_SendSocketMsg(SOCKET s,  struct msghdr  *mp, SWORD32 flags);
+	SWORD32     VOS_RecvFrom(SOCKET s,const char *buffer,SWORD32 len, SWORD32 flags,
+	struct sockaddr *from, int  * pFromLen);
+	SWORD32     VOS_RecvSocketMsg(SOCKET s,  struct msghdr  *mp, SWORD32 flags);
+	VOS_STATUS  VOS_Shutdown(SOCKET s, int how);
+	VOS_STATUS  VOS_SetSockOpt (SOCKET s,  int level,  int  optname, char * optval, int optlen );
+	VOS_STATUS  VOS_GetSockOpt (SOCKET s,  int level,  int  optname, char * optval, int *optlen );
+	VOS_STATUS  VOS_GetSockName(SOCKET s,   struct sockaddr * name,   int * namelen);
+	VOS_STATUS  VOS_GetPeerName (SOCKET s, struct sockaddr * name, int * namelen);
+	SWORD32     VOS_Select(int width, fd_set  *pReadFds, fd_set  * pWriteFds,
+		fd_set * pExceptFds, struct timeval * pTimeOut);
+	SWORD32     VOS_Ioctl(int fd, int function,int arg);
+
+	/****************** Exec **********************/
+	VOS_STATUS VOS_Exec(
+		const CHAR * strFile,		///要执行的程序名称
+		const CHAR * strArgs		///要传入的命令行参数
+		);
+
+	VOS_STATUS VOS_ExecByFork(
+		const CHAR * strFile,	///要执行的程序名称
+		const CHAR * strArgs	///要传入的命令行参数
+		);
+
+	VOS_STATUS VOS_ForceDelete(CHAR *pcFileName);
+
+	SWORD32 VOS_Chmod(
+		const CHAR * pcFileName, ///文件名
+		int iPermissions         ///要进行设置的文件属性
+		);
+
+	VOS_STATUS VOS_SetRLimit(const int iCoreFileSize);
+
+	VOS_STATUS VOS_GetTimeOfDay(struct timeval *tv, struct timezone *tz);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+/************** End of vos.h *******************************************/

+ 238 - 0
TCL Copy Tool/Log4C/log4c/voscfg.h

@@ -0,0 +1,238 @@
+/************** Begin of voscfg.h *******************************************/
+/**********************************************************
+* 版权所有 (C)2002, 深圳市中兴通讯股份有限公司。
+*
+* 文件名称: voscfg.h
+* 文件标识:
+* 内容摘要: VOS的系统配置文件
+* 其它说明: 无
+* 当前版本: v1.0
+* 作    者: 谢鑫
+* 完成日期: 2004.02.27
+*
+* 修改记录1:
+*    修改日期:
+*    版 本 号:
+*    修 改 人:
+*    修改内容:
+**********************************************************/
+
+#ifndef _VOSCFG_H
+#define _VOSCFG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	/*******************************************************
+	*                       基本配置
+	*******************************************************/
+
+	/* CPU类型 */
+#define   CPU_X86             0x1
+#define   CPU_PPC             0x2
+#define   CPU_ARM             0x3
+#define   CPU_TYPE            CPU_X86
+
+#undef	OS_LINUX	
+#undef  OS_WINNT
+	/* 操作系统OS类型 */
+#define   OS_VXWORKS          0x1
+#define   OS_WINNT            0x2
+#define   OS_PSOS             0x3
+#define   OS_LINUX            0x4
+#define   OS_KLINUX           0x5
+
+	///added by wenhm in 2005.08.25
+#ifdef _WIN32
+#define   OS_TYPE             OS_WINNT
+#else #ifdef   linux
+#define   OS_TYPE			  OS_LINUX
+#endif
+
+
+	/* linux适配 */
+#define    VXWORKS_TO_LINUX
+#ifndef    VXWORKS_TO_LINUX
+#define    PSOS_TO_LINUX
+#endif
+#if ( OS_TYPE == OS_KLINUX)
+#define  _USE_TIMER_IRQ
+#endif
+
+	/*********************************************************
+	基本包含文件                        
+	**********************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#if OS_TYPE == OS_PSOS
+#include <psos.h>
+#include <phile.h>
+#include <pna.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <sys_conf.h>
+#include <types.h>
+#include <socket.h>
+#endif
+
+#if  OS_TYPE == OS_VXWORKS
+#include <vxWorks.h>
+#include <sysLib.h>
+#include <taskLib.h>    
+#include <msgQLib.h>
+#include <semLib.h>
+#include <vmLib.h>
+#include <dosfslib.h>
+#include <iolib.h>
+#include <dirent.h>
+#include <stat.h>
+#include <errnoLib.h>
+#include <types.h>
+#include <socket.h>
+#include <socklib.h>
+#include <logLib.h>
+#include <assert.h>
+#include <symlib.h>
+#include <sysSymTbl.h>
+#include <excLib.h>
+#include <esf.h>
+#include <memLib.h>
+#include <tickLib.h>
+#include <private\memPartLibP.h>
+#include <in.h>
+#include <ramDrv.h>
+#include <ftpdLib.h>
+#include <cachelib.h>
+#include <signal.h>
+#include <sigLib.h>
+#include <time.h>
+#include <wdLib.h>
+#include <intLib.h>
+#include <timers.h>
+#include "inetLib.h"
+#include "netinet\tcp.h"
+#include "fcntl.h"
+#include "netinet/in.h"
+#include "end.h"
+#include "zbufSockLib.h"
+#include <routeLib.h>
+#include <usrLib.h>
+#endif
+
+#if OS_TYPE == OS_WINNT
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <process.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+#include <imagehlp.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <direct.h>
+#include <Winsock.h>
+#include <time.h>
+	///#include <Winsock2.h>
+#pragma comment(lib, "imagehlp.lib")
+#pragma comment(lib,"Winmm.lib")
+#endif
+
+#if OS_TYPE == OS_LINUX
+#ifdef VXWORKS_TO_LINUX
+	///#include "vxw_hdrs.h"
+#else
+	///#include "psos_hdrs.h"
+#endif
+#include <time.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <asm/ioctls.h>
+#include <netinet/tcp.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <asm/errno.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h> 
+#include <unistd.h>
+#include <netinet/in.h>    
+#include <signal.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <semaphore.h>    
+#endif
+
+#if OS_TYPE == OS_KLINUX
+#include "kth.h"
+	/*	#include "ksocket.h"*/
+#include <stdio.h>
+#include "ktm.h"
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+	/*	#include "kfile.h"*/
+	/*	#include <linux/vmalloc.h>*/
+#endif
+
+
+	/*********************************************************
+	基本数据类型                        
+	**********************************************************/
+#if OS_TYPE != OS_WINNT
+	typedef  unsigned char    BYTE;
+#endif
+
+	typedef  unsigned char    BOOLEAN;
+	typedef  char             CHAR;
+	typedef  void            *LPVOID;
+	typedef  unsigned short   WORD16;
+	typedef  unsigned long    WORD32;
+	typedef  signed short     SWORD16;
+	///typedef  signed long      SWORD32;
+
+#ifndef SWORD32
+#ifdef  WIN32
+	typedef long                SWORD32; 
+#else
+#define SWORD32            long
+#endif		
+#endif
+
+#define  INVALID_BYTE     (unsigned char)0xff
+#define  INVALID_WORD     (unsigned short)0xffff
+#define  INVALID_DWORD    (unsigned long)0xffffffff 
+
+	typedef  long             OSS_STATUS;
+#define  OSS_OK           0
+#define  OSS_ERROR        -1
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+/************** End of voscfg.h *******************************************/

+ 19 - 0
TCL Copy Tool/Log4C/sd/defs.h

@@ -0,0 +1,19 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_defs_h
+#define __sd_defs_h
+
+#ifdef  __cplusplus
+# define __SD_BEGIN_DECLS  extern "C" {
+# define __SD_END_DECLS    }
+#else
+# define __SD_BEGIN_DECLS
+# define __SD_END_DECLS
+#endif
+
+#endif

+ 21 - 0
TCL Copy Tool/Log4C/sd/domnode-xml-parser.h

@@ -0,0 +1,21 @@
+#ifndef BISON_DOMNODE_XML_PARSER_H
+# define BISON_DOMNODE_XML_PARSER_H
+
+#ifndef YYSTYPE
+typedef union { char *s; } yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define	ENDDEF	257
+# define	EQ	258
+# define	SLASH	259
+# define	CLOSE	260
+# define	END	261
+# define	NAME	262
+# define	VALUE	263
+# define	DATA	264
+# define	COMMENT	265
+# define	START	266
+
+
+#endif /* not BISON_DOMNODE_XML_PARSER_H */

+ 882 - 0
TCL Copy Tool/Log4C/sd/domnode-xml-scanner.h

@@ -0,0 +1,882 @@
+#ifndef __sd_domnode_xml_HEADER_H
+#define __sd_domnode_xml_HEADER_H 1
+#define __sd_domnode_xml_IN_HEADER 1
+
+#define YY_REENTRANT 1
+#define YY_BISON_BRIDGE 1
+#ifndef YY_REENTRANT
+#define yytext __sd_domnode_xml_text
+#define yyleng __sd_domnode_xml_leng
+#define yyin __sd_domnode_xml_in
+#define yyout __sd_domnode_xml_out
+#define yy_flex_debug __sd_domnode_xml__flex_debug
+#endif
+#define yy_create_buffer __sd_domnode_xml__create_buffer
+#define yy_delete_buffer __sd_domnode_xml__delete_buffer
+#define yy_scan_buffer __sd_domnode_xml__scan_buffer
+#define yy_scan_string __sd_domnode_xml__scan_string
+#define yy_scan_bytes __sd_domnode_xml__scan_bytes
+#define yy_init_buffer __sd_domnode_xml__init_buffer
+#define yy_flush_buffer __sd_domnode_xml__flush_buffer
+#define yy_load_buffer_state __sd_domnode_xml__load_buffer_state
+#define yy_switch_to_buffer __sd_domnode_xml__switch_to_buffer
+#define yylex __sd_domnode_xml_lex
+#define yyrestart __sd_domnode_xml_restart
+#define yylex_init __sd_domnode_xml_lex_init
+#define yylex_destroy __sd_domnode_xml_lex_destroy
+#define yyget_debug __sd_domnode_xml_get_debug
+#define yyset_debug __sd_domnode_xml_set_debug
+#define yyget_extra __sd_domnode_xml_get_extra
+#define yyset_extra __sd_domnode_xml_set_extra
+#define yyget_in __sd_domnode_xml_get_in
+#define yyset_in __sd_domnode_xml_set_in
+#define yyget_out __sd_domnode_xml_get_out
+#define yyset_out __sd_domnode_xml_set_out
+#define yyget_leng __sd_domnode_xml_get_leng
+#define yyget_text __sd_domnode_xml_get_text
+#define yyget_lineno __sd_domnode_xml_get_lineno
+#define yyset_lineno __sd_domnode_xml_set_lineno
+#ifdef YY_BISON_BRIDGE
+#define yyget_lval __sd_domnode_xml_get_lval
+#define yyset_lval __sd_domnode_xml_set_lval
+#define yyget_lloc __sd_domnode_xml_get_lloc
+#define yyset_lloc __sd_domnode_xml_set_lloc
+#endif
+#define yyalloc __sd_domnode_xml_alloc
+#define yyrealloc __sd_domnode_xml_realloc
+#define yyfree __sd_domnode_xml_free
+
+#line 50 "domnode-xml-scanner.h"
+#define  YY_INT_ALIGNED short int
+
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 27
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+#include <sd/sd_xplatform.h>
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+
+#endif /* ! FLEXINT_H */
+
+
+
+#ifdef __cplusplus
+
+/* C++ compilers don't understand traditional function definitions. */
+#ifdef YY_TRADITIONAL_FUNC_DEFS
+#undef YY_TRADITIONAL_FUNC_DEFS
+#endif
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* We're not in a C++ compiler, so by default,
+   we generate C99 function defs, unless you explicitly ask
+   for traditional defs by defining YY_TRADITIONAL_FUNC_DEFS */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* For compilers that can't handle prototypes.
+ * e.g.,
+ * The function prototype
+ *    int foo(int x, char* y);
+ *
+ * ...should be written as
+ *    int foo YY_PARAMS((int x, char* y));
+ *
+ * ...which could possibly generate
+ *    int foo ();
+ */
+#ifdef YY_NO_PROTOS
+#define YY_PARAMS(proto) ()
+#else
+#define YY_PARAMS(proto) proto
+#endif
+
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For use wherever a Global is accessed or assigned. */
+#define YY_G(var) (((struct yyguts_t*)yyscanner)->var)
+
+/* For use in function prototypes to append the additional argument. */
+#define YY_PROTO_LAST_ARG , yyscan_t yyscanner
+#define YY_PROTO_ONLY_ARG    yyscan_t yyscanner
+
+/* For use in function definitions to append the additional argument. */
+#ifdef YY_TRADITIONAL_FUNC_DEFS
+#define YY_DEF_LAST_ARG , yyscanner
+#define YY_DEF_ONLY_ARG    yyscanner
+#else
+#define YY_DEF_LAST_ARG , yyscan_t yyscanner
+#define YY_DEF_ONLY_ARG   yyscan_t yyscanner
+#endif
+#define YY_DECL_LAST_ARG yyscan_t yyscanner;
+
+/* For use in function calls to pass the additional argument. */
+#define YY_CALL_LAST_ARG  , yyscanner
+#define YY_CALL_ONLY_ARG   yyscanner
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin YY_G(yyin_r)
+#define yyout YY_G(yyout_r)
+#define yyextra YY_G(yyextra_r)
+#define yyleng YY_G(yyleng_r)
+#define yytext YY_G(yytext_r)
+#define yylineno YY_G(yylineno_r)
+#define yy_flex_debug YY_G(yy_flex_debug_r)
+
+int yylex_init YY_PARAMS((yyscan_t* scanner));
+
+
+
+/* For compilers that need traditional function definitions.
+ * e.g.,
+ * The function prototype taking 2 arguments
+ *    int foo (int x, char* y)
+ *
+ * ...should be written as
+ *    int foo YYFARGS2(int,x, char*,y)
+ *
+ * ...which could possibly generate
+ *    int foo (x,y,yyscanner)
+ *        int x;
+ *        char * y;
+ *        yyscan_t yyscanner;
+ */
+#ifdef YY_TRADITIONAL_FUNC_DEFS
+/* Generate traditional function defs */
+#define YYFARGS0(v) (YY_DEF_ONLY_ARG) YY_DECL_LAST_ARG
+#define YYFARGS1(t1,n1) (n1 YY_DEF_LAST_ARG) t1 n1; YY_DECL_LAST_ARG
+#define YYFARGS2(t1,n1,t2,n2) (n1,n2 YY_DEF_LAST_ARG) t1 n1; t2 n2; YY_DECL_LAST_ARG
+#define YYFARGS3(t1,n1,t2,n2,t3,n3) (n1,n2,n3 YY_DEF_LAST_ARG) t1 n1; t2 n2; t3 n3; YY_DECL_LAST_ARG
+#else
+/* Generate C99 function defs. */
+#define YYFARGS0(v) (YY_DEF_ONLY_ARG)
+#define YYFARGS1(t1,n1) (t1 n1 YY_DEF_LAST_ARG)
+#define YYFARGS2(t1,n1,t2,n2) (t1 n1,t2 n2 YY_DEF_LAST_ARG)
+#define YYFARGS3(t1,n1,t2,n2,t3,n3) (t1 n1,t2 n2,t3 n3 YY_DEF_LAST_ARG)
+#endif
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN YY_G(yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((YY_G(yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin YY_CALL_LAST_ARG )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+#ifdef YY_USE_LINENO
+/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ *       access to the local variable yy_act. Since yyless() is a macro, it would break
+ *       existing scanners that call yyless() from OUTSIDE yylex. 
+ *       One obvious solution it to make yy_act a global. I tried that, and saw
+ *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+ *       normally declared as a register variable-- so it's not worth it.
+ */
+#define  YY_LESS_LINENO(n) \
+        do { \
+			int yyl;\
+			for ( yyl = n; yyl < yyleng; ++yyl )\
+				if ( yytext[yyl] == '\n' )\
+					--yylineno;\
+        }while(0)
+#else
+#define YY_LESS_LINENO(n)
+#endif
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = YY_G(yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		YY_G(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, YY_G(yytext_ptr) YY_CALL_LAST_ARG )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+
+void yyrestart YY_PARAMS(( FILE *input_file YY_PROTO_LAST_ARG ));
+
+
+void yy_switch_to_buffer YY_PARAMS(( YY_BUFFER_STATE new_buffer YY_PROTO_LAST_ARG ));
+void yy_load_buffer_state YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+YY_BUFFER_STATE yy_create_buffer YY_PARAMS(( FILE *file, int size YY_PROTO_LAST_ARG ));
+void yy_delete_buffer YY_PARAMS(( YY_BUFFER_STATE b YY_PROTO_LAST_ARG ));
+void yy_init_buffer YY_PARAMS(( YY_BUFFER_STATE b, FILE *file YY_PROTO_LAST_ARG ));
+void yy_flush_buffer YY_PARAMS(( YY_BUFFER_STATE b YY_PROTO_LAST_ARG ));
+
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_G(yy_current_buffer) YY_CALL_LAST_ARG)
+
+YY_BUFFER_STATE yy_scan_buffer YY_PARAMS(( char *base, yy_size_t size YY_PROTO_LAST_ARG ));
+YY_BUFFER_STATE yy_scan_string YY_PARAMS(( yyconst char *yy_str YY_PROTO_LAST_ARG ));
+YY_BUFFER_STATE yy_scan_bytes YY_PARAMS(( yyconst char *bytes, int len YY_PROTO_LAST_ARG ));
+
+
+void *yyalloc YY_PARAMS(( yy_size_t YY_PROTO_LAST_ARG ));
+void *yyrealloc YY_PARAMS(( void *, yy_size_t YY_PROTO_LAST_ARG ));
+void yyfree YY_PARAMS(( void * YY_PROTO_LAST_ARG ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_G(yy_current_buffer) ) \
+		YY_G(yy_current_buffer) =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); \
+	YY_G(yy_current_buffer)->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_G(yy_current_buffer) ) \
+		YY_G(yy_current_buffer) =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); \
+	YY_G(yy_current_buffer)->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_G(yy_current_buffer)->yy_at_bol)
+
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+#define yytext_ptr yytext_r
+
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	YY_G(yytext_ptr) = yy_bp; \
+	yyleng = (size_t) (yy_cp - yy_bp); \
+	YY_G(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	YY_G(yy_c_buf_p) = yy_cp;
+
+
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#ifndef YY_NO_UNISTD_H
+#include <unistd.h>
+#endif /* !YY_NO_UNISTD_H */
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+
+
+
+
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+#ifndef YY_NO_DESTROY
+int yylex_destroy YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_GET_DEBUG
+int yyget_debug YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_SET_DEBUG
+void yyset_debug YY_PARAMS(( int debug_flag YY_PROTO_LAST_ARG ));
+#endif
+
+#ifndef YY_NO_GET_EXTRA
+YY_EXTRA_TYPE yyget_extra YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_SET_EXTRA
+void yyset_extra YY_PARAMS(( YY_EXTRA_TYPE user_defined YY_PROTO_LAST_ARG ));
+#endif
+
+#ifndef YY_NO_GET_IN
+FILE *yyget_in YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_SET_IN
+void yyset_in  YY_PARAMS(( FILE * in_str YY_PROTO_LAST_ARG ));
+#endif
+
+#ifndef YY_NO_GET_OUT
+FILE *yyget_out YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_SET_OUT
+void yyset_out  YY_PARAMS(( FILE * out_str YY_PROTO_LAST_ARG ));
+#endif
+
+#ifndef YY_NO_GET_LENG
+int yyget_leng YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_GET_TEXT
+char *yyget_text YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_GET_LINENO
+int yyget_lineno YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#ifndef YY_NO_SET_LINENO
+void yyset_lineno YY_PARAMS(( int line_number YY_PROTO_LAST_ARG ));
+#endif
+
+#ifndef YY_NO_GET_LVAL
+YYSTYPE * yyget_lval YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+void yyset_lval YY_PARAMS(( YYSTYPE * yylvalp YY_PROTO_LAST_ARG ));
+#if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+#ifndef YY_NO_GET_LLOC
+   YYLTYPE *yyget_lloc YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+#ifndef YY_NO_SET_LLOC
+    void yyset_lloc YY_PARAMS(( YYLTYPE * yyllocp YY_PROTO_LAST_ARG ));
+#endif
+#endif /* YYLTYPE */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#else
+extern int yywrap YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+#endif
+
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PARAMS(( char *, yyconst char *, int YY_PROTO_LAST_ARG));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PARAMS(( yyconst char * YY_PROTO_LAST_ARG));
+#endif
+
+#ifndef YY_NO_INPUT
+#endif
+
+
+#if YY_STACK_USED
+
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PARAMS(( int new_state YY_PROTO_LAST_ARG));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PARAMS(( YY_PROTO_ONLY_ARG ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	errno=0; \
+	while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+	{ \
+		if( errno != EINTR) \
+		{ \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+			break; \
+		} \
+		errno=0; \
+		clearerr(yyin); \
+	}
+\
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg YY_CALL_LAST_ARG)
+#endif
+
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+
+/* If the bison pure parser is used, then bison will provide
+   one or two additional arguments. */
+
+#  if defined(YYLTYPE) || defined(YYLTYPE_IS_DECLARED)
+#        define YY_LEX_PROTO YY_PARAMS((YYSTYPE * yylvalp, YYLTYPE * yyllocp YY_PROTO_LAST_ARG))
+#        define YY_LEX_DECLARATION YYFARGS2(YYSTYPE *,yylvalp, YYLTYPE *,yyllocp)
+#  else
+#        define YY_LEX_PROTO YY_PARAMS((YYSTYPE * yylvalp YY_PROTO_LAST_ARG))
+#        define YY_LEX_DECLARATION YYFARGS1(YYSTYPE *,yylvalp)
+#  endif
+
+
+
+extern int yylex YY_LEX_PROTO;
+
+#define YY_DECL int yylex YY_LEX_DECLARATION
+#endif
+
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#line 135 "../../../src/sd/domnode-xml-scanner.l"
+#line 719 "domnode-xml-scanner.h"
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+/* Beware! Start conditions are not prefixed. */
+#undef INITIAL
+#define INITIAL 0
+#define CONTENT 1
+#endif /* YY_HEADER_EXPORT_START_CONDITIONS */
+
+#ifndef YY_HEADER_NO_UNDEFS
+/* Undefine all internal macros, etc., that do no belong in the header. */
+
+#undef BEGIN
+#undef ECHO
+#undef EOB_ACT_CONTINUE_SCAN
+#undef EOB_ACT_END_OF_FILE
+#undef EOB_ACT_LAST_MATCH
+#undef FLEX_SCANNER
+#undef FLEX_STD
+#undef REJECT
+#undef YYLMAX
+#undef YYSTATE
+#undef YY_AT_BOL
+#undef YY_BREAK
+#undef YY_BUFFER_EOF_PENDING
+#undef YY_BUFFER_NEW
+#undef YY_BUFFER_NORMAL
+#undef YY_BUF_SIZE
+#undef YY_CALL_LAST_ARG
+#undef YY_CALL_ONLY_ARG
+#undef YY_CURRENT_BUFFER
+#undef YY_DECL
+#undef YY_DECL_LAST_ARG
+#undef YY_DO_BEFORE_ACTION
+#undef YY_END_OF_BUFFER
+#undef YY_END_OF_BUFFER_CHAR
+#undef YY_EXIT_FAILURE
+#undef YY_EXTRA_TYPE
+#undef YY_FATAL_ERROR
+#undef YY_FLEX_DEFINED_ECHO
+#undef YY_FLEX_LEX_COMPAT
+#undef YY_FLEX_MAJOR_VERSION
+#undef YY_FLEX_MINOR_VERSION
+#undef YY_FLUSH_BUFFER
+#undef YY_G
+#undef YY_INPUT
+#undef YY_INT_ALIGNED
+#undef YY_INTERACTIVE
+#undef YY_LAST_ARG
+#undef YY_LEX_ARGS
+#undef YY_MAIN
+#undef YY_MORE_ADJ
+#undef YY_NEED_STRLEN
+#undef YY_NEW_FILE
+#undef YY_NO_FLEX_ALLOC
+#undef YY_NO_FLEX_REALLOC
+#undef YY_NO_FLEX_FREE
+#undef YY_NO_GET_DEBUG
+#undef YY_NO_GET_EXTRA
+#undef YY_NO_GET_IN
+#undef YY_NO_GET_LENG
+#undef YY_NO_GET_LINENO
+#undef YY_NO_GET_LLOC
+#undef YY_NO_GET_LVAL
+#undef YY_NO_GET_OUT
+#undef YY_NO_GET_TEXT
+#undef YY_NO_INPUT
+#undef YY_NO_POP_STATE
+#undef YY_NO_PUSH_STATE
+#undef YY_NO_SCAN_BUFFER
+#undef YY_NO_SCAN_BYTES
+#undef YY_NO_SCAN_STRING
+#undef YY_NO_SET_DEBUG
+#undef YY_NO_SET_EXTRA
+#undef YY_NO_SET_IN
+#undef YY_NO_SET_LINENO
+#undef YY_NO_SET_LLOC
+#undef YY_NO_SET_LVAL
+#undef YY_NO_SET_OUT
+#undef YY_NO_TOP_STATE
+#undef YY_NO_UNISTD_H
+#undef YY_NO_UNPUT
+#undef YY_NULL
+#undef YY_NUM_RULES
+#undef YY_ONLY_ARG
+#undef YY_PROTO
+#undef YY_READ_BUF_SIZE
+#undef YY_REENTRANT
+#undef YY_BISON_BRIDGE
+#undef YY_RESTORE_YY_MORE_OFFSET
+#undef YY_RULE_SETUP
+#undef YY_SC_TO_UI
+#undef YY_SKIP_YYWRAP
+#undef YY_STACK_USED
+#undef YY_START
+#undef YY_START_STACK_INCR
+#undef YY_STATE_EOF
+#undef YY_STDINIT
+#undef YY_TEXT_IS_ARRAY
+#undef YY_TRAILING_HEAD_MASK
+#undef YY_TRAILING_MASK
+#undef YY_USER_ACTION
+#undef YY_USES_REJECT
+#undef YY_USE_CONST
+#undef YY_USE_LINENO
+#undef YY_USE_PROTOS
+#undef unput
+#undef yy_create_buffer
+#undef yy_delete_buffer
+#undef yy_flex_debug
+#undef yy_flush_buffer
+#undef yy_init_buffer
+#undef yy_load_buffer_state
+#undef yy_new_buffer
+#undef yy_scan_buffer
+#undef yy_scan_bytes
+#undef yy_scan_string
+#undef yy_set_bol
+#undef yy_set_interactive
+#undef yy_switch_to_buffer
+#undef yyconst
+#undef yyextra
+#undef yyget_debug
+#undef yyset_debug
+#undef yyget_extra
+#undef yyget_in
+#undef yyget_leng
+#undef yyget_lineno
+#undef yyget_lloc
+#undef yyget_lval
+#undef yyget_out
+#undef yyget_text
+#undef yyin
+#undef yyleng
+#undef yyless
+#undef yylex
+#undef yylex_destroy
+#undef yylex_init
+#undef yylineno
+#undef yylloc
+#undef yylval
+#undef yymore
+#undef yyout
+#undef yyrestart
+#undef yyset_extra
+#undef yyset_in
+#undef yyset_lineno
+#undef yyset_lloc
+#undef yyset_lval
+#undef yyset_out
+#undef yyterminate
+#undef yytext
+#undef yytext_ptr
+#undef yywrap
+#undef yyalloc
+#undef yyrealloc
+#undef yyfree
+#undef YY_NEVER_INTERACTIVE
+#undef YY_NO_UNPUT
+#undef YY_TABLES_VERIFY
+#endif /* !YY_HEADER_NO_UNDEFS */
+
+#undef __sd_domnode_xml_IN_HEADER
+#endif /* __sd_domnode_xml_HEADER_H */

+ 33 - 0
TCL Copy Tool/Log4C/sd/domnode-xml.h

@@ -0,0 +1,33 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_domnode_xml_h
+#define __sd_domnode_xml_h
+
+/**
+ * @file domnode-xml.h @ingroup sd
+ *
+ * @brief Private API for XML parsing.
+ */
+
+#include "domnode.h"
+#include "stack.h"
+
+struct __sd_domnode_xml_maker {
+    void*		scanner;
+    sd_stack_t*		elements;
+    sd_domnode_t*	root;
+};
+
+extern int __sd_domnode_xml_fread(sd_domnode_t** a_node, FILE* a_stream);
+extern int __sd_domnode_xml_fwrite(const sd_domnode_t* a_node, FILE* a_stream);
+
+extern int __sd_domnode_xml_read(sd_domnode_t** a_node, const char* a_buffer,
+				 size_t a_size);
+extern int __sd_domnode_xml_write(const sd_domnode_t* a_node, char** a_buffer,
+				  size_t* a_size);
+
+#endif

+ 65 - 0
TCL Copy Tool/Log4C/sd/domnode.h

@@ -0,0 +1,65 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_domnode_h
+#define __sd_domnode_h
+
+/**
+ * @file domnode.h @ingroup sd
+ *
+ * @brief Generic DOM object.
+ */
+
+#include <stdio.h>
+#include <sd/list.h>
+
+__SD_BEGIN_DECLS
+
+typedef struct {
+    const char*	name;
+    const char*	value;
+    sd_list_t*	children;
+    sd_list_t*	attrs;
+} sd_domnode_t;
+
+extern sd_domnode_t*	sd_domnode_new(const char* a_name,
+				       const char* a_value);
+
+extern void		sd_domnode_delete(sd_domnode_t* ptrThis);
+
+extern int		sd_domnode_read(sd_domnode_t* ptrThis,
+					const char* a_buffer, size_t asize);
+extern int		sd_domnode_write(sd_domnode_t* ptrThis, char** a_buffer,
+					 size_t* asize);
+
+extern int		sd_domnode_fread(sd_domnode_t* ptrThis, FILE* a_stream);
+extern int		sd_domnode_fwrite(const sd_domnode_t* ptrThis,
+					  FILE* a_stream);
+
+extern int		sd_domnode_load(sd_domnode_t* ptrThis,
+					const char* a_filename);
+
+extern int		sd_domnode_store(const sd_domnode_t* ptrThis, 
+					 const char* a_filename);
+
+extern sd_domnode_t*	sd_domnode_search(const sd_domnode_t* ptrThis,
+					  const char* a_name);
+
+extern sd_domnode_t* 	sd_domnode_attrs_put(sd_domnode_t* ptrThis,
+					     sd_domnode_t* a_attr);
+extern sd_domnode_t*	sd_domnode_attrs_get(const sd_domnode_t* ptrThis,
+					     const char* a_name);
+extern sd_domnode_t*	sd_domnode_attrs_remove(sd_domnode_t* ptrThis,
+						const char* a_name);
+
+/** Creates a new node. */
+extern sd_domnode_t* __sd_domnode_new(const char* name, const char* a_value,
+				      int is_elem);
+
+__SD_END_DECLS
+
+#endif
+

+ 16 - 0
TCL Copy Tool/Log4C/sd/error.h

@@ -0,0 +1,16 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_error_h
+#define __sd_error_h
+
+#include <stdarg.h>
+
+extern int sd_debug(const char *fmt, ...);
+extern int sd_error(const char *fmt, ...);
+
+#endif /* __sd_error_h */

+ 1014 - 0
TCL Copy Tool/Log4C/sd/expat.h

@@ -0,0 +1,1014 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_INCLUDED
+#define Expat_INCLUDED 1
+
+#ifdef __VMS
+/*      0        1         2         3      0        1         2         3
+        1234567890123456789012345678901     1234567890123456789012345678901 */
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
+#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler
+#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler
+#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg
+#endif
+
+#include <stdlib.h>
+#include "expat_external.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+/* Should this be defined using stdbool.h when C99 is available? */
+typedef unsigned char XML_Bool;
+#define XML_TRUE   ((XML_Bool) 1)
+#define XML_FALSE  ((XML_Bool) 0)
+
+/* The XML_Status enum gives the possible return values for several
+   API functions.  The preprocessor #defines are included so this
+   stanza can be added to code that still needs to support older
+   versions of Expat 1.95.x:
+
+   #ifndef XML_STATUS_OK
+   #define XML_STATUS_OK    1
+   #define XML_STATUS_ERROR 0
+   #endif
+
+   Otherwise, the #define hackery is quite ugly and would have been
+   dropped.
+*/
+enum XML_Status {
+  XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+  XML_STATUS_OK = 1,
+#define XML_STATUS_OK XML_STATUS_OK
+  XML_STATUS_SUSPENDED = 2
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+};
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE,
+  XML_ERROR_UNEXPECTED_STATE,
+  XML_ERROR_ENTITY_DECLARED_IN_PE,
+  XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+  /* Added in 1.95.7. */
+  XML_ERROR_UNBOUND_PREFIX,
+  /* Added in 1.95.8. */
+  XML_ERROR_UNDECLARING_PREFIX,
+  XML_ERROR_INCOMPLETE_PE,
+  XML_ERROR_XML_DECL,
+  XML_ERROR_TEXT_DECL,
+  XML_ERROR_PUBLICID,
+  XML_ERROR_SUSPENDED,
+  XML_ERROR_NOT_SUSPENDED,
+  XML_ERROR_ABORTED,
+  XML_ERROR_FINISHED,
+  XML_ERROR_SUSPEND_PE,
+  /* Added in 2.0. */
+  XML_ERROR_RESERVED_PREFIX_XML,
+  XML_ERROR_RESERVED_PREFIX_XMLNS,
+  XML_ERROR_RESERVED_NAMESPACE_URI
+};
+
+enum XML_Content_Type {
+  XML_CTYPE_EMPTY = 1,
+  XML_CTYPE_ANY,
+  XML_CTYPE_MIXED,
+  XML_CTYPE_NAME,
+  XML_CTYPE_CHOICE,
+  XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+  XML_CQUANT_NONE,
+  XML_CQUANT_OPT,
+  XML_CQUANT_REP,
+  XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+   XML_CQUANT_NONE, and the other fields will be zero or NULL.
+   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+   numchildren will contain number of elements that may be mixed in
+   and children point to an array of XML_Content cells that will be
+   all of XML_CTYPE_NAME type with no quantification.
+
+   If type == XML_CTYPE_NAME, then the name points to the name, and
+   the numchildren field will be zero and children will be NULL. The
+   quant fields indicates any quantifiers placed on the name.
+
+   CHOICE and SEQ will have name NULL, the number of children in
+   numchildren and children will point, recursively, to an array
+   of XML_Content cells.
+
+   The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  XML_Char *                    name;
+  unsigned int                  numchildren;
+  XML_Content *                 children;
+};
+
+
+/* This is called for an element declaration. See above for
+   description of the model argument. It's the caller's responsibility
+   to free model when finished with it.
+*/
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
+                                                const XML_Char *name,
+                                                XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+   a single Attlist declaration with multiple attributes declared will
+   generate multiple calls to this handler. The "default" parameter
+   may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+   keyword. The "isrequired" parameter will be true and the default
+   value will be NULL in the case of "#REQUIRED". If "isrequired" is
+   true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void (XMLCALL *XML_AttlistDeclHandler) (
+                                    void            *userData,
+                                    const XML_Char  *elname,
+                                    const XML_Char  *attname,
+                                    const XML_Char  *att_type,
+                                    const XML_Char  *dflt,
+                                    int              isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+   and text declarations. The way to distinguish is that the version
+   parameter will be NULL for text declarations. The encoding
+   parameter may be NULL for XML declarations. The standalone
+   parameter will be -1, 0, or 1 indicating respectively that there
+   was no standalone parameter in the declaration, that it was given
+   as no, or that it was given as yes.
+*/
+typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,
+                                            const XML_Char *version,
+                                            const XML_Char *encoding,
+                                            int             standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+  void *(*malloc_fcn)(size_t size);
+  void *(*realloc_fcn)(void *ptr, size_t size);
+  void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+   external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type
+   names and attribute names that belong to a namespace will be
+   expanded; unprefixed attribute names are never expanded; unprefixed
+   element type names are expanded only if there is a default
+   namespace. The expanded name is the concatenation of the namespace
+   URI, the namespace separator character, and the local part of the
+   name.  If the namespace separator is '\0' then the namespace URI
+   and the local part will be concatenated without any separator.
+   It is a programming error to use the separator '\0' with namespace
+   triplets (see XML_SetReturnNSTriplet).
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suite referred to
+   by memsuite. If memsuite is NULL, then use the standard library memory
+   suite. If namespaceSeparator is non-NULL it creates a parser with
+   namespace processing as described above. The character pointed at
+   will serve as the namespace separator.
+
+   All further memory operations used for the created parser will come from
+   the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used.  This is particularly
+   valuable when memory allocation overhead is disproportionatly high,
+   such as when a large number of small documnents need to be parsed.
+   All handlers are cleared from the parser, except for the
+   unknownEncodingHandler. The parser's external state is re-initialized
+   except for the values of ns and ns_triplets.
+
+   Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated.
+*/
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
+                                                 const XML_Char *name,
+                                                 const XML_Char **atts);
+
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
+                                               const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
+                                                  const XML_Char *s,
+                                                  int len);
+
+/* target and data are 0 terminated */
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
+                                                void *userData,
+                                                const XML_Char *target,
+                                                const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,
+                                            const XML_Char *data);
+
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+
+/* This is called for any characters in the XML document for which
+   there is no applicable handler.  This includes both characters that
+   are part of markup which is of a kind that is not reported
+   (comments, markup declarations), or characters that are part of a
+   construct which could be reported but for which no handler has been
+   supplied. The characters are passed exactly as they were in the XML
+   document except that they will be encoded in UTF-8 or UTF-16.
+   Line boundaries are not normalized. Note that a byte order mark
+   character is not passed to the default handler. There are no
+   guarantees about how characters are divided between calls to the
+   default handler: for example, a comment might be split between
+   multiple calls.
+*/
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
+                                            const XML_Char *s,
+                                            int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+   any DTD or internal subset is parsed.
+*/
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
+                                            void *userData,
+                                            const XML_Char *doctypeName,
+                                            const XML_Char *sysid,
+                                            const XML_Char *pubid,
+                                            int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+   closing > is encountered, but after processing any external
+   subset.
+*/
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+   argument will be non-zero if the entity is a parameter entity, zero
+   otherwise.
+
+   For internal entities (<!ENTITY foo "bar">), value will
+   be non-NULL and systemId, publicID, and notationName will be NULL.
+   The value string is NOT nul-terminated; the length is provided in
+   the value_length argument. Since it is legal to have zero-length
+   values, do not use this argument to test for internal entities.
+
+   For external entities, value will be NULL and systemId will be
+   non-NULL. The publicId argument will be NULL unless a public
+   identifier was provided. The notationName argument will have a
+   non-NULL value only for unparsed entity declarations.
+
+   Note that is_parameter_entity can't be changed to XML_Bool, since
+   that would break binary compatibility.
+*/
+typedef void (XMLCALL *XML_EntityDeclHandler) (
+                              void *userData,
+                              const XML_Char *entityName,
+                              int is_parameter_entity,
+                              const XML_Char *value,
+                              int value_length,
+                              const XML_Char *base,
+                              const XML_Char *systemId,
+                              const XML_Char *publicId,
+                              const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+   This handler has been superceded by the EntityDeclHandler above.
+   It is provided here for backward compatibility.
+
+   This is called for a declaration of an unparsed (NDATA) entity.
+   The base argument is whatever was set by XML_SetBase. The
+   entityName, systemId and notationName arguments will never be
+   NULL. The other arguments may be.
+*/
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId,
+                                    const XML_Char *notationName);
+
+/* This is called for a declaration of notation.  The base argument is
+   whatever was set by XML_SetBase. The notationName will never be
+   NULL.  The other arguments can be.
+*/
+typedef void (XMLCALL *XML_NotationDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *notationName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+   each namespace declaration. The call to the start and end element
+   handlers occur between the calls to the start and end namespace
+   declaration handlers. For an xmlns attribute, prefix will be
+   NULL.  For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix,
+                                    const XML_Char *uri);
+
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+   external subset or a reference to a parameter entity, but does not
+   have standalone="yes". If this handler returns XML_STATUS_ERROR,
+   then processing will not continue, and the parser will return a
+   XML_ERROR_NOT_STANDALONE error.
+   If parameter entity parsing is enabled, then in addition to the
+   conditions above this handler will only be called if the referenced
+   entity was actually read.
+*/
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+
+/* This is called for a reference to an external parsed general
+   entity.  The referenced entity is not automatically parsed.  The
+   application can parse it immediately or later using
+   XML_ExternalEntityParserCreate.
+
+   The parser argument is the parser parsing the entity containing the
+   reference; it can be passed as the parser argument to
+   XML_ExternalEntityParserCreate.  The systemId argument is the
+   system identifier as specified in the entity declaration; it will
+   not be NULL.
+
+   The base argument is the system identifier that should be used as
+   the base for resolving systemId if systemId was relative; this is
+   set by XML_SetBase; it may be NULL.
+
+   The publicId argument is the public identifier as specified in the
+   entity declaration, or NULL if none was specified; the whitespace
+   in the public identifier will have been normalized as required by
+   the XML spec.
+
+   The context argument specifies the parsing context in the format
+   expected by the context argument to XML_ExternalEntityParserCreate;
+   context is valid only until the handler returns, so if the
+   referenced entity is to be parsed later, it must be copied.
+   context is NULL only when the entity is a parameter entity.
+
+   The handler should return XML_STATUS_ERROR if processing should not
+   continue because of a fatal error in the handling of the external
+   entity.  In this case the calling parser will return an
+   XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+   Note that unlike other handlers the first argument is the parser,
+   not userData.
+*/
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
+                                    XML_Parser parser,
+                                    const XML_Char *context,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* This is called in two situations:
+   1) An entity reference is encountered for which no declaration
+      has been read *and* this is not an error.
+   2) An internal entity reference is read, but not expanded, because
+      XML_SetDefaultHandler has been called.
+   Note: skipped parameter entities in declarations and skipped general
+         entities in attribute values cannot be reported, because
+         the event would be out of sync with the reporting of the
+         declarations or attribute values
+*/
+typedef void (XMLCALL *XML_SkippedEntityHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+   provide information to the parser about encodings that are unknown
+   to the parser.
+
+   The map[b] member gives information about byte sequences whose
+   first byte is b.
+
+   If map[b] is c where c is >= 0, then b by itself encodes the
+   Unicode scalar value c.
+
+   If map[b] is -1, then the byte sequence is malformed.
+
+   If map[b] is -n, where n >= 2, then b is the first byte of an
+   n-byte sequence that encodes a single Unicode scalar value.
+
+   The data member will be passed as the first argument to the convert
+   function.
+
+   The convert function is used to convert multibyte sequences; s will
+   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The
+   convert function must return the Unicode scalar value represented
+   by this byte sequence or -1 if the byte sequence is malformed.
+
+   The convert function may be NULL if the encoding is a single-byte
+   encoding, that is if map[b] >= -1 for all bytes b.
+
+   When the parser is finished with the encoding, then if release is
+   not NULL, it will call release passing it the data member; once
+   release has been called, the convert function will not be called
+   again.
+
+   Expat places certain restrictions on the encodings that are supported
+   using this mechanism.
+
+   1. Every ASCII character that can appear in a well-formed XML document,
+      other than the characters
+
+      $@\^`{}~
+
+      must be represented by a single byte, and that byte must be the
+      same byte that represents that character in ASCII.
+
+   2. No character may require more than 4 bytes to encode.
+
+   3. All characters encoded must have Unicode scalar values <=
+      0xFFFF, (i.e., characters that would be encoded by surrogates in
+      UTF-16 are  not allowed).  Note that this restriction doesn't
+      apply to the built-in support for UTF-8 and UTF-16.
+
+   4. No Unicode character may be encoded by more than one distinct
+      sequence of bytes.
+*/
+typedef struct {
+  int map[256];
+  void *data;
+  int (XMLCALL *convert)(void *data, const char *s);
+  void (XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+   The encodingHandlerData argument is that which was passed as the
+   second argument to XML_SetUnknownEncodingHandler.
+
+   The name argument gives the name of the encoding as specified in
+   the encoding declaration.
+
+   If the callback can provide information about the encoding, it must
+   fill in the XML_Encoding structure, and return XML_STATUS_OK.
+   Otherwise it must return XML_STATUS_ERROR.
+
+   If info does not describe a suitable encoding, then the parser will
+   return an XML_UNKNOWN_ENCODING error.
+*/
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (
+                                    void *encodingHandlerData,
+                                    const XML_Char *name,
+                                    XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser parser,
+                           XML_StartElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser parser,
+                         XML_EndElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+   internal entities. These entity references will be passed to the
+   default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+   internal entities.  The entity reference will not be passed to the
+   default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+   passed as the first argument to the external entity ref handler
+   instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
+                                   void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+   element, processing instruction or character data.  It causes the
+   corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+   a name has a prefix (i.e. an explicit namespace qualifier) then
+   that name is returned as a triplet in a single string separated by
+   the separator character specified when the parser was created: URI
+   + sep + local_name + sep + prefix.
+
+   If do_nst is zero, then namespace information is returned in the
+   default manner (URI + sep + local_name) whether or not the name
+   has a prefix.
+
+   Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+     XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+   XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+   zero otherwise.
+   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+     has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+   first argument to callbacks instead of userData.  The userData will
+   still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+   will assume that there is an external subset, even if none is
+   specified in the document. In such a case the parser will call the
+   externalEntityRefHandler with a value of NULL for the systemId
+   argument (the publicId and context arguments will be NULL as well).
+   Note: For the purpose of checking WFC: Entity Declared, passing
+     useDTD == XML_TRUE will make the parser behave as if the document
+     had a DTD with an external subset.
+   Note: If this function is called, then this must be done before
+     the first call to XML_Parse or XML_ParseBuffer, since it will
+     have no effect after that.  Returns
+     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+   Note: If the document does not have a DOCTYPE declaration at all,
+     then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+     be called, despite an external subset being parsed.
+   Note: If XML_DTD is not defined when Expat is compiled, returns
+     XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+
+/* Sets the base to be used for resolving relative URIs in system
+   identifiers in declarations.  Resolving relative identifiers is
+   left to the application: this value will be passed through as the
+   base argument to the XML_ExternalEntityRefHandler,
+   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+   argument will be copied.  Returns XML_STATUS_ERROR if out of memory,
+   XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+   to the XML_StartElementHandler that were specified in the start-tag
+   rather than defaulted. Each attribute/value pair counts as 2; thus
+   this correspondds to an index into the atts array passed to the
+   XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+   XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+   attribute/value pair counts as 2; thus this correspondds to an
+   index into the atts array passed to the XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+   detected.  The last call to XML_Parse must have isFinal true; len
+   may be zero for this call (or any other).
+
+   Though the return values for these functions has always been
+   described as a Boolean value, the implementation, at least for the
+   1.95.x series, has always returned exactly one of the XML_Status
+   values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
+   Must be called from within a call-back handler, except when aborting
+   (resumable = 0) an already suspended parser. Some call-backs may
+   still follow because they would otherwise get lost. Examples:
+   - endElementHandler() for empty elements when stopped in
+     startElementHandler(), 
+   - endNameSpaceDeclHandler() when stopped in endElementHandler(), 
+   and possibly others.
+
+   Can be called from most handlers, including DTD related call-backs,
+   except when parsing an external parameter entity and resumable != 0.
+   Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
+   Possible error codes: 
+   - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
+   - XML_ERROR_FINISHED: when the parser has already finished.
+   - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
+
+   When resumable != 0 (true) then parsing is suspended, that is, 
+   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. 
+   Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
+   return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
+
+   *Note*:
+   This will be applied to the current parser instance only, that is, if
+   there is a parent parser then it will continue parsing when the
+   externalEntityRefHandler() returns. It is up to the implementation of
+   the externalEntityRefHandler() to call XML_StopParser() on the parent
+   parser (recursively), if one wants to stop parsing altogether.
+
+   When suspended, parsing can be resumed by calling XML_ResumeParser(). 
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_StopParser(XML_Parser parser, XML_Bool resumable);
+
+/* Resumes parsing after it has been suspended with XML_StopParser().
+   Must not be called from within a handler call-back. Returns same
+   status codes as XML_Parse() or XML_ParseBuffer().
+   Additional error code XML_ERROR_NOT_SUSPENDED possible.   
+
+   *Note*:
+   This must be called on the most deeply nested child parser instance
+   first, and on its parent parser only after the child parser has finished,
+   to be applied recursively until the document entity's parser is restarted.
+   That is, the parent parser will not resume by itself and it is up to the
+   application to call XML_ResumeParser() on it at the appropriate moment.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_ResumeParser(XML_Parser parser);
+
+enum XML_Parsing {
+  XML_INITIALIZED,
+  XML_PARSING,
+  XML_FINISHED,
+  XML_SUSPENDED
+};
+
+typedef struct {
+  enum XML_Parsing parsing;
+  XML_Bool finalBuffer;
+} XML_ParsingStatus;
+
+/* Returns status of parser with respect to being initialized, parsing,
+   finished, or suspended and processing the final buffer.
+   XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
+   XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
+*/
+XMLPARSEAPI(void)
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
+
+/* Creates an XML_Parser object that can parse an external general
+   entity; context is a '\0'-terminated string specifying the parse
+   context; encoding is a '\0'-terminated string giving the name of
+   the externally specified encoding, or NULL if there is no
+   externally specified encoding.  The context string consists of a
+   sequence of tokens separated by formfeeds (\f); a token consisting
+   of a name specifies that the general entity of the name is open; a
+   token of the form prefix=uri specifies the namespace for a
+   particular prefix; a token of the form =uri specifies the default
+   namespace.  This can be called at any point after the first call to
+   an ExternalEntityRefHandler so longer as the parser has not yet
+   been freed.  The new parser is completely independent and may
+   safely be used in a separate thread.  The handlers and userData are
+   initialized from the parser argument.  Returns NULL if out of memory.
+   Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+                               const XML_Char *context,
+                               const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+   subset). If parsing of parameter entities is enabled, then
+   references to external parameter entities (including the external
+   DTD subset) will be passed to the handler set with
+   XML_SetExternalEntityRefHandler.  The context passed will be 0.
+
+   Unlike external general entities, external parameter entities can
+   only be parsed synchronously.  If the external parameter entity is
+   to be parsed, it must be parsed during the call to the external
+   entity ref handler: the complete sequence of
+   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+   XML_ParserFree calls must be made during this call.  After
+   XML_ExternalEntityParserCreate has been called to create the parser
+   for the external parameter entity (context must be 0 for this
+   call), it is illegal to make any calls on the old parser until
+   XML_ParserFree has been called on the newly created parser.
+   If the library has been compiled without support for parameter
+   entity parsing (ie without XML_DTD being defined), then
+   XML_SetParamEntityParsing will return 0 if parsing of parameter
+   entities is requested; otherwise it will return non-zero.
+   Note: If XML_SetParamEntityParsing is called after XML_Parse or
+      XML_ParseBuffer, then it has no effect and will always return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing parsing);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+   XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+   location.  They may be called from any callback called to report
+   some parse event; in this case the location is the location of the
+   first of the sequence of characters that generated the event.  When
+   called from callbacks generated by declarations in the document
+   prologue, the location identified isn't as neatly defined, but will
+   be within the relevant markup.  When called outside of the callback
+   functions, the position indicated will be just past the last parse
+   event (regardless of whether there was an associated callback).
+   
+   They may also be called after returning from a call to XML_Parse
+   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
+   the location is the location of the character at which the error
+   was detected; otherwise the location is the location of the last
+   parse event, as described above.
+*/
+XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+   Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+   the integer pointed to by offset to the offset within this buffer
+   of the current parse position, and sets the integer pointed to by size
+   to the size of this buffer (the number of input bytes). Otherwise
+   returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+   active.
+
+   NOTE: The character pointer returned should not be used outside
+   the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+                    int *offset,
+                    int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+  int major;
+  int minor;
+  int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+   number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+  XML_FEATURE_END = 0,
+  XML_FEATURE_UNICODE,
+  XML_FEATURE_UNICODE_WCHAR_T,
+  XML_FEATURE_DTD,
+  XML_FEATURE_CONTEXT_BYTES,
+  XML_FEATURE_MIN_SIZE,
+  XML_FEATURE_SIZEOF_XML_CHAR,
+  XML_FEATURE_SIZEOF_XML_LCHAR,
+  XML_FEATURE_NS,
+  XML_FEATURE_LARGE_SIZE
+  /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+  enum XML_FeatureEnum  feature;
+  const XML_LChar       *name;
+  long int              value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+
+/* Expat follows the GNU/Linux convention of odd number minor version for
+   beta/development releases and even number minor version for stable
+   releases. Micro is bumped with each release, and set to 0 with each
+   change to major or minor version.
+*/
+#define XML_MAJOR_VERSION 2
+#define XML_MINOR_VERSION 0
+#define XML_MICRO_VERSION 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_INCLUDED */

+ 115 - 0
TCL Copy Tool/Log4C/sd/expat_external.h

@@ -0,0 +1,115 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+   defined.  There are two macros defined to control this boundary;
+   each of these can be defined before including this header to
+   achieve some different behavior, but doing so it not recommended or
+   tested frequently.
+
+   XMLCALL    - The calling convention to use for all calls across the
+                "library boundary."  This will default to cdecl, and
+                try really hard to tell the compiler that's what we
+                want.
+
+   XMLIMPORT  - Whatever magic is needed to note that a function is
+                to be imported from a dynamically loaded library
+                (.dll, .so, or .sl, depending on your platform).
+
+   The XMLCALL macro was added in Expat 1.95.7.  The only one which is
+   expected to be directly useful in client code is XMLCALL.
+
+   Note that on at least some Unix versions, the Expat library must be
+   compiled with the cdecl calling convention as the default since
+   system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(_MSC_VER)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+   one calling convention, we need to extend this definition to
+   declare the convention used on that platform, if it's possible to
+   do so.
+
+   If this is the case for your platform, please file a bug report
+   with information on how to identify your platform via the C
+   pre-processor and how to specify the same calling convention as the
+   platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif  /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif  /* not defined XML_STATIC */
+
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else                  /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+typedef __int64 XML_Index; 
+typedef unsigned __int64 XML_Size;
+#else
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#endif
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */

+ 43 - 0
TCL Copy Tool/Log4C/sd/factory.h

@@ -0,0 +1,43 @@
+/* $Id$
+ *
+ * factory.h
+ * 
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_factory_h
+#define __sd_factory_h
+
+/**
+ * @file factory.h
+ */
+
+#include <stdio.h>
+#include <sd/defs.h>
+
+__SD_BEGIN_DECLS
+
+struct __sd_factory;
+typedef struct __sd_factory sd_factory_t;
+
+struct __sd_factory_ops
+{
+    void* (*fac_new)	(const char*);
+    void  (*fac_delete)	(void*);
+    void  (*fac_print)	(void*, FILE*);
+};
+typedef struct __sd_factory_ops sd_factory_ops_t;
+
+extern sd_factory_t* sd_factory_new(const char* a_name, 
+				    const sd_factory_ops_t* a_ops);
+extern void	sd_factory_delete(sd_factory_t* a_this);
+extern void*	sd_factory_get(sd_factory_t* a_this, const char* a_name);
+extern void	sd_factory_destroy(sd_factory_t* a_this, void* a_pr);
+extern void	sd_factory_print(const sd_factory_t* a_this, FILE* a_stream);
+extern int	sd_factory_list(const sd_factory_t* a_this, void** a_items,
+				int a_nitems);
+
+__SD_END_DECLS
+
+#endif

+ 166 - 0
TCL Copy Tool/Log4C/sd/hash.h

@@ -0,0 +1,166 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ * Author: Marc Vertes <mvertes@meiosys.com>
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_hash_h
+#define __sd_hash_h
+
+/**
+ * @file hash.h
+ *
+ * @brief Generic hash table. It is implemented as an array of doubly-linked
+ * lists of iterators. The index within the array is computed by a efficient
+ * hash function.
+ */
+
+#include <stddef.h>
+#include <sd/defs.h>
+
+__SD_BEGIN_DECLS
+
+struct __sd_hash_ops {
+    unsigned int	(*hash)		(const void*);
+    int			(*compare)	(const void*, const void*);
+    void*		(*key_dup)	(const void*);
+    void		(*key_free)	(void*);
+    void*		(*data_dup)	(const void*);
+    void		(*data_free)	(void*);
+};
+
+/**
+ * This structure holds hash table operations.
+ */
+typedef struct __sd_hash_ops sd_hash_ops_t;
+
+/**
+ * This is the hash table.
+ */
+typedef struct __sd_hash sd_hash_t;
+
+struct __sd_hash_iter {
+    void*			key;
+    void*			data;
+    struct __sd_hash*		hash;
+    unsigned int		__hkey;
+    struct __sd_hash_iter*	__next;
+    struct __sd_hash_iter*	__prev;
+    int				__foreach;
+};
+
+/**
+ * This is the elementary container for storing data into the hash table.
+ */
+typedef struct __sd_hash_iter sd_hash_iter_t;
+
+/**
+ * Signature of a "foreach" function.
+ */
+typedef unsigned int (*sd_hash_func_t)(void* a_key, void* a_data,
+				       void* a_userdata);
+
+/**
+ * Creates a new hash table. One can customize the memory (de)allocation
+ * policy for keys and data stored in the hash table.
+ * @param a_size the initial size of the array.
+ * @param a_ops the hash operations. If NULL, then string keys are assumed and
+ * no memory (de)allocation is performed for keys and data.
+ * @return a dynamicaly allocated hash table.
+ */
+extern sd_hash_t* sd_hash_new(size_t a_size, const sd_hash_ops_t* a_ops);
+
+/**
+ * Destroys the hash table.
+ */
+extern void sd_hash_delete(sd_hash_t* a_this);
+
+/**
+ * clears the hash table.
+ */
+extern void sd_hash_clear(sd_hash_t* a_this);
+
+/**
+ * Looks for the iterator associated to the given key in the hash table.
+ * @param a_key the key associated to the iterator.
+ * @return a pointer to the found iterator or NULL.
+ */
+extern sd_hash_iter_t* sd_hash_lookup(sd_hash_t* a_this, const void* a_key);
+
+/**
+ * Looks for the iterator associated to the given key in the hash table and
+ * creates it if doesn't exist.
+ * @param a_key the key associated to the iterator.
+ * @return a pointer to the found iterator or NULL.
+ */
+extern sd_hash_iter_t* sd_hash_lookadd(sd_hash_t* a_this, const void* a_key);
+
+/**
+ * Adds data associated with the given key into the hash table. If the
+ * key already exists, the old iterator is freed according to the memory
+ * management operations passed to sd_hash_new().
+ * @param a_key the key associated to the iterator.
+ * @return a pointer to the created or found iterator.
+ */
+extern sd_hash_iter_t* sd_hash_add(sd_hash_t* a_this, const void* a_key,
+				 void* a_data);
+
+/**
+ * Removes an iterator from the hash table.
+ * @param a_key the key associated to the iterator.
+ */
+extern void sd_hash_del(sd_hash_t* a_this, const void* a_key);
+
+/**
+ * Calls \a a_func for each element of the hash table, as long as \a a_func
+ * returns 0.
+ * @param a_func the "foreach" function.
+ * @param a_data the user data passed to \a a_func.
+ */
+extern void sd_hash_foreach(sd_hash_t* a_this, sd_hash_func_t a_func,
+			    void* a_data);
+
+/**
+ * Gets the number of iterators.
+ */
+extern unsigned int sd_hash_get_nelem(sd_hash_t* a_this);
+
+/**
+ * Gets the size of the array.
+ */
+extern unsigned int sd_hash_get_size(sd_hash_t* a_this);
+
+/**
+ * Gets the first iterator.
+ */
+extern sd_hash_iter_t* sd_hash_begin(sd_hash_t* a_this);
+
+/**
+ * Gets the last iterator.
+ */
+extern sd_hash_iter_t* sd_hash_end(sd_hash_t* a_this);
+
+/**
+ * Gets a pointer to the next iterator.
+ */
+extern sd_hash_iter_t* sd_hash_iter_next(sd_hash_iter_t* a_this);
+
+/**
+ * Gets a pointer to the previous iterator.
+ */
+extern sd_hash_iter_t* sd_hash_iter_prev(sd_hash_iter_t* a_this);
+
+/**
+ * Gets a pointer to the previous iterator.
+ */
+extern void sd_hash_iter_del(sd_hash_iter_t* a_this);
+
+/**
+ * Hashes strings.
+ */
+extern unsigned int sd_hash_hash_string(const char* a_string);
+
+__SD_END_DECLS
+
+#endif

+ 190 - 0
TCL Copy Tool/Log4C/sd/list.h

@@ -0,0 +1,190 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ * 
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_list_h
+#define __sd_list_h
+
+/**
+ * @file list.h @ingroup sd
+ *
+ * @brief Generic list object. It is implemented as an array of doubly-linked
+ * lists of iterators. The index within the array is computed by a efficient
+ * list function.
+ */
+
+#include <stddef.h>
+#include <sd/defs.h>
+
+__SD_BEGIN_DECLS
+
+/**
+ * This is the list object.
+ */
+typedef struct __sd_list sd_list_t;
+
+struct __sd_list_iter {
+    void*			data;
+    struct __sd_list*		list;
+    struct __sd_list_iter*	__next;
+    struct __sd_list_iter*	__prev;
+    int				__foreach;
+};
+
+/**
+ * This is the elementary container for storing data into the list object.
+ */
+typedef struct __sd_list_iter sd_list_iter_t;
+
+/**
+ * Signature of a "foreach" function.
+ */
+typedef unsigned int (*sd_list_func_t)(void* a_data, void* a_userdata);
+
+/**
+ * Creates a list.
+ * @param a_capacity initial number of preallocated iterators
+ * @return the list object.
+ */
+extern sd_list_t* sd_list_new(size_t a_capacity);
+
+/**
+ * Destroys the list object.
+ * @todo need a function parameter to destroy list elements.
+ */
+extern void sd_list_delete(sd_list_t* a_this);
+
+/**
+ * Adds the given_data at the head of the list.
+ */
+extern sd_list_iter_t* sd_list_prepend(sd_list_t* a_this, void* a_data);
+
+/**
+ * Adds the given data at the tail of the list.
+ */
+extern sd_list_iter_t* sd_list_append(sd_list_t* a_this, void* a_data);
+
+/**
+ * Looks for the iterator associated to the given data in the list object.
+ * @param a_data the data to find
+ * @return a pointer to the found iterator or NULL.
+ */
+extern sd_list_iter_t* sd_list_lookup(sd_list_t* a_this, void* a_data);
+
+/**
+ * Looks for the iterator associated to the given data in the list object and
+ * creates it if doesn't exist, using @c sd_list_add().
+ * @param a_data the data to find/add
+ * @return a pointer to the found iterator or NULL.
+ */
+extern sd_list_iter_t* sd_list_lookadd(sd_list_t* a_this, void* a_data);
+
+/**
+ * Adds the given data into the list object. If the data already exists,
+ * the associated iterator is returned.
+ * @warning the element is added at the begining of the list.
+ * @param a_data the data to add
+ * @return a pointer to the created or found iterator.
+ */
+extern sd_list_iter_t* sd_list_add(sd_list_t* a_this, void* a_data);
+
+/**
+ * Applies the given function to all list elements, starting from the
+ * first one. As soon as the function returns a non-null value, the
+ * given data is inserted in the list (before the element).
+ * @param a_func the "sort" function.
+ * @param a_data the data to add
+ * @return a pointer to the created iterator.
+ */
+extern sd_list_iter_t* sd_list_sortadd(sd_list_t* a_this,
+				       sd_list_func_t a_func,
+				       void* a_data);
+
+/**
+ * Removes an iterator from the list object.
+ * @param a_data the data associated to the iterator.
+ */
+extern int sd_list_del(sd_list_t* a_this, void* a_data);
+
+/**
+ * clears the list object.
+ */
+extern void sd_list_clear(sd_list_t* a_this);
+
+/**
+ * Calls \a a_func for each element of the list object, as long as \a a_func
+ * returns 0.
+ * @param a_func the "foreach" function.
+ * @param a_data the user data passed to \a a_func.
+ */
+extern void sd_list_foreach(sd_list_t* a_this, sd_list_func_t a_func,
+			    void* a_userdata);
+
+/**
+ * Calls \a a_func for each element of the list object, as long as \a a_func
+ * returns 0.
+ * Same as sd_list_foreach but from tail to head of list.
+ * @param a_func the "foreach" function.
+ * @param a_data the user data passed to \a a_func.
+ */
+extern void sd_list_rforeach(sd_list_t* a_this, sd_list_func_t a_func,
+			     void* a_userdata);
+
+/**
+ * Gets the number of iterators.
+ */
+extern size_t sd_list_get_nelem(sd_list_t* a_this);
+
+/**
+ * Gets the iterator pointing to the first element of the list.
+ */
+extern sd_list_iter_t* sd_list_begin(sd_list_t* a_this);
+
+/**
+ * Gets the past-the-last-element iterator of the list.
+ */
+extern sd_list_iter_t* sd_list_end(sd_list_t* a_this);
+
+/**
+ * Gets the iterator pointing to the last element of the list.
+ */
+extern sd_list_iter_t* sd_list_rbegin(sd_list_t* a_this);
+
+/**
+ * Gets the before-the-first-element iterator of the list.
+ */
+extern sd_list_iter_t* sd_list_rend(sd_list_t* a_this);
+
+/**
+ * Gets a pointer to the next iterator.
+ */
+extern sd_list_iter_t* sd_list_iter_next(sd_list_iter_t* a_this);
+
+/**
+ * Gets a pointer to the previous iterator.
+ */
+extern sd_list_iter_t* sd_list_iter_prev(sd_list_iter_t* a_this);
+
+/**
+ * Deletes the iterator from the list.
+ */
+extern void sd_list_iter_del(sd_list_iter_t* a_this);
+
+/**
+ * Deletes the iterator from the list.
+ */
+extern void sd_list_iter_del(sd_list_iter_t* a_this);
+
+/**
+ * Creates a new iterator and inserts it before @a a_this.
+ * @param a_data the data associated to the iterator.
+ */
+extern sd_list_iter_t* sd_list_iter_insert(sd_list_iter_t* a_this,
+					   void* a_data);
+
+__SD_END_DECLS
+
+#endif

+ 43 - 0
TCL Copy Tool/Log4C/sd/malloc.h

@@ -0,0 +1,43 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_malloc_h
+#define __sd_malloc_h
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sd/defs.h>
+
+/**
+ * @file malloc.h
+ */
+
+__SD_BEGIN_DECLS
+
+typedef void (*sd_malloc_handler_t)();
+
+extern sd_malloc_handler_t sd_malloc_set_handler(void (*a_handler)());
+
+#ifndef __SD_DEBUG__
+
+extern void *sd_malloc(size_t n);
+extern void *sd_calloc(size_t n, size_t s);
+extern void *sd_realloc(void *p, size_t n);
+extern char *sd_strdup (const char *__str);
+
+#else
+
+#define sd_malloc	malloc
+#define sd_calloc	calloc
+#define sd_realloc	realloc
+#define sd_strdup	strdup
+
+#endif
+
+__SD_END_DECLS
+
+#endif

+ 137 - 0
TCL Copy Tool/Log4C/sd/sd_xplatform.h

@@ -0,0 +1,137 @@
+/* $Id$
+ *
+ * sd_xplatform.h
+ * 
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_xplatform_h
+#define __sd_xplatform_h
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#else
+#include <time.h>
+#include <io.h> /* needed for _access  */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <winsock2.h>
+#include <process.h>
+#endif
+
+
+#ifdef HAVE_STDINT_H
+#       include <stdint.h>
+#define  XP_UINT64 uint64_t
+#define  XP_INT64 int64_t
+#else
+#ifndef _WIN32
+#define  XP_UINT64 unsigned long long
+#define  XP_INT64 long long
+#else
+#define  XP_UINT64 DWORD64
+#define  XP_INT64 __int64
+#endif
+#endif
+
+#include <log4c/defs.h>
+#include <sd/defs.h>
+
+
+/*extern int sd_optind; */
+LOG4C_DATA int sd_optind; 
+
+extern void getopt_reset(void); 
+
+extern int sd_getopt(int argc, char *const *argv, const char *opts);
+
+#ifdef _WIN32
+#define SD_GETOPT(a,b,c) sd_getopt(a,b,c)
+#define SD_OPTIND sd_optind
+#else
+#define SD_GETOPT(a,b,c) getopt(a,b,c)
+#define SD_OPTIND optind
+#endif
+
+
+#ifdef _WIN32
+#define SD_GETTIMEOFDAY(a,b) sd_gettimeofday(a,b)
+extern int sd_gettimeofday(LPFILETIME lpft, void* tzp);
+#else
+#define SD_GETTIMEOFDAY(a,b) gettimeofday(a,b)
+extern int sd_gettimeofday(struct timeval* tp, void* tzp);
+#endif
+
+#ifdef _WIN32
+#define FILE_SEP "\\"
+#else
+#define FILE_SEP "/"
+#endif
+
+#ifdef _WIN32
+#define SD_ACCESS_READ(a) _access(a,04)
+#else
+#define SD_ACCESS_READ(a) access(a,R_OK)
+#endif
+
+int sd_stat_ctime(const char* path, time_t* time);
+#define SD_STAT_CTIME(path, time) sd_stat_ctime(path, time)
+
+#ifndef _WIN32
+#define DIFF_CMD  "/usr/bin/diff -q"
+#else
+#define DIFF_CMD  "comp.exe"
+#endif
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define alloca _alloca
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#define YY_NO_UNISTD_H
+#define sleep(x) Sleep(x*1000)
+#endif
+
+
+/* Maybe should be using this for to mean
+* MS compiler #if defined(_MSC_VER) 
+*/
+#ifdef _WIN32
+#define pthread_t HANDLE
+#define pthread_mutex_t HANDLE
+#define pthread_attr_t DWORD
+#define THREAD_FUNCTION DWORD (WINAPI *)(void *)
+
+/*
+* This one not obvious: you would have naturally thought of mapping to
+* CreateThread()--turns out that to be safe using CRT functions
+* you need to use _begintheadex().  
+* cf. http://msdn2.microsoft.com/en-us/library/7t9ha0zh.aspx
+*  http://groups.google.com/group/comp.os.ms-windows.programmer.win32/browse_thread/thread/86d8624e7ee38c5d/f947ac76cd10f397?lnk=st&q=when+to+use+_beginthreadex&rnum=1#f947ac76cd10f397
+* 
+*/
+#define pthread_create(thhandle,attr,thfunc,tharg) \
+  (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(THREAD_FUNCTION)thfunc,tharg,0,NULL))==NULL)
+#define pthread_join(thread, result) \
+  ((WaitForSingleObject((thread),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread))
+#define pthread_exit() _endthreadex(0)
+#define pthread_cancel(thread) TerminateThread(thread,0)
+
+#define pthread_mutex_init(pobject,pattr) (*pobject=CreateMutex(NULL,FALSE,NULL))
+#define pthread_mutex_lock(pobject) WaitForSingleObject(*pobject,INFINITE)
+#define pthread_mutex_unlock(pobject) ReleaseMutex(*pobject)
+
+#define pthread_mutex_destroy(pobject) CloseHandle(*pobject)
+
+#endif
+
+
+#ifdef __HP_cc
+#define inline __inline
+#endif 
+
+#endif

+ 59 - 0
TCL Copy Tool/Log4C/sd/sprintf.h

@@ -0,0 +1,59 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_sprintf_h
+#define __sd_sprintf_h
+
+/**
+ * @file sprintf.h
+ *
+ * @brief Formatted output conversion
+ *
+ * These functions write the output under the control of a format
+ * string that specifies how subsequent arguments (or arguments
+ * accessed via the variable-length argument facilities of stdarg(2))
+ * are converted for output.
+ *
+ * They do not write more than \a size bytes, including the trailing
+ * \c '\0'.
+ *
+ * These functions return the number of characters printed (not
+ * including the trailing \c `\0' used to end output to strings). They
+ * return -1 if the output was truncated due to the @a size limit.
+ *
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <sd/defs.h>
+
+__SD_BEGIN_DECLS
+
+/**
+ * Same as fprintf(3) with auto-allocation of the resulting buffer,
+ * and output directly in a file, not a stream.
+ */
+extern int sd_fprintf(int fd, const char *fmt, ...);
+
+/**
+ * Same as sprintf(3) with auto-allocation of the resulting buffer.
+ */
+extern char* sd_sprintf(const char* a_fmt, ...);
+
+/**
+ * Same as vsprintf(3) with auto-allocation of the resulting buffer.
+ */
+extern char* sd_vsprintf(const char* a_fmt, va_list a_arg);
+
+#if defined(__osf__)
+extern int snprintf(char* str, size_t size, const char* fmt, ...);
+extern int vsnprintf(char* str, size_t size, const char* fmt, va_list arg);
+#endif
+
+__SD_END_DECLS
+
+#endif

+ 41 - 0
TCL Copy Tool/Log4C/sd/stack.h

@@ -0,0 +1,41 @@
+/* $Id$
+ *
+ * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef __sd_stack_h
+#define __sd_stack_h
+
+/**
+ * @file stack.h @ingroup sd
+ *
+ * @brief Generic stack object.
+ *
+ * @todo documentation
+ * @todo API homogeneity with sd_list and sd_hash
+ */
+
+#include <stddef.h>
+#include <sd/defs.h>
+
+__SD_BEGIN_DECLS
+
+typedef struct __sd_stack sd_stack_t;
+
+extern sd_stack_t* sd_stack_new(size_t max);
+extern void	sd_stack_delete(sd_stack_t* astack, void (*free_data_fn)(void *));
+extern size_t	sd_stack_get_nelem(const sd_stack_t* astack);
+
+extern void	sd_stack_clear(sd_stack_t* astack, void (*free_data_fn)(void *));
+extern int	sd_stack_push(sd_stack_t* astack, void *data);
+extern void*	sd_stack_pop(sd_stack_t* astack);
+extern void*	sd_stack_begin(sd_stack_t* astack);
+extern void*	sd_stack_next(sd_stack_t* astack);
+extern void*	sd_stack_end(sd_stack_t* astack);
+extern void*	sd_stack_peek(sd_stack_t* astack);
+
+__SD_END_DECLS
+
+#endif

+ 139 - 0
TCL Copy Tool/Setup.nsi

@@ -0,0 +1,139 @@
+; Script generated by the HM NIS Edit Script Wizard.
+
+; HM NIS Edit Wizard helper defines
+!define PRODUCT_NAME "scbc application"
+!define PRODUCT_VERSION "2.0.1.2"
+!define PRODUCT_PUBLISHER "tcl company, Inc."
+!define PRODUCT_WEB_SITE "http://www.tcl.com"
+!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\TCL Tools.exe"
+!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
+!define PRODUCT_UNINST_ROOT_KEY "HKLM"
+
+Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
+OutFile "Setup${PRODUCT_VERSION}.exe"
+LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf"
+LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf"
+InstallDir "$PROGRAMFILES\scbc application"
+Icon "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico"
+UninstallIcon "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico"
+InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+DirText "安装程序将安装 $(^Name) 在下列文件夹。$\r$\n$\r$\n要安装在不同文件夹,单击 [浏览] 并选择其他文件夹。"
+LicenseText "如果你接受所有协议条款,选择 [我愿意] 继续。你必须接受协议才能安装 $(^Name)。."
+LicenseData "Licence.txt"
+ShowInstDetails show
+ShowUnInstDetails show
+
+
+; 安装VC环境
+Function InstallVC
+   Push $R0
+   ClearErrors
+   ;FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4 Visual C++ 2008 runtime files VC 9.0 (x86)
+   ;9A25302D-30C0-39D9-BD6F-21E6EC160475 Visual C++ 2008 SP1 runtime files VC 9.0 SP1 (x86) 
+   ;f50edb7e-c25e-47b4-bc4f-7ec4a4d256b1 Visual C++ 2017 runtime files VC 9.0 SP1 (x86) 
+   ;ad831ec0-6a55-427f-b75b-341c827ce380 Visual C++ ??? runtime files VC 9.0 SP1 (x86)
+   ; vs2008
+   ;ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{9A25302D-30C0-39D9-BD6F-21E6EC160475}" "Version"
+   ; vs2017
+   ;ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{ad831ec0-6a55-427f-b75b-341c827ce380}" "Version"
+   ; vs2019
+   ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{5bfc1380-fd35-4b85-9715-7351535d077e}" "Version"
+
+   ; 检测含有vc的注册表信息是否存在
+   IfErrors 0 VSRedistInstalled
+   Exec "$INSTDIR\vcredist_x86.exe /q"   ;若不存在,执行静默安装
+   StrCpy $R0 "-1" 
+   ; MessageBox MB_OK  $R0 
+
+VSRedistInstalled:
+   ; MessageBox MB_OK  "已安装" 
+   Exch $R0
+ ; Delete "$INSTDIR\vcredist_x86." 
+FunctionEnd
+
+Function .onInit
+FunctionEnd
+
+Section "MainSection" SEC01
+  SetOutPath "$INSTDIR"
+  ;覆盖旧文件;
+  SetOverwrite ifnewer
+  File "..\..\..\..\bin\TCL Copy Tool\TCL Copy Tool.exe"
+  File "lib\Log4C.dll"
+  File "lib\libcurl.dll"
+  File "lib\libeay32.dll"
+  File "lib\ssleay32.dll"
+  File "lib\zlibwapi.dll"
+  File "log4crc.xml"
+  File "vcredist_x86.exe"
+  Delete "$INSTDIR\TCL Tools.exe"
+  CreateDirectory "$SMPROGRAMS\scbc application"
+  CreateShortCut "$SMPROGRAMS\scbc application\scbc application.lnk" "$INSTDIR\TCL Copy Tool.exe"
+  CreateShortCut "$DESKTOP\scbc application.lnk" "$INSTDIR\TCL Copy Tool.exe"
+  File "..\..\..\..\bin\rename\rename.exe"
+  ;不覆盖config.ini配置文件;
+  SetOverwrite off
+  File "TCL Copy Tool\config.json"
+  SetOutPath "$INSTDIR\log"
+  SetOutPath "$INSTDIR\DataDir"
+  SetOutPath "$INSTDIR\DataDir\WB"
+  SetOutPath "$INSTDIR\DataDir\CIKEY"
+  SetOutPath "$INSTDIR\DataDir\DeviceID"
+  SetOutPath "$INSTDIR\DataDir\ESN"
+  SetOutPath "$INSTDIR\DataDir\HDCPKEY"
+  SetOutPath "$INSTDIR\DataDir\HDCPKEY22"
+  SetOutPath "$INSTDIR\DataDir\MAC"
+  SetOutPath "$INSTDIR\DataDir\Widevine"
+  SetOutPath "$INSTDIR\DataDir\WiDi"
+  ;安装VC环境
+  Call InstallVC
+SectionEnd
+
+Section -AdditionalIcons
+  WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
+  CreateShortCut "$SMPROGRAMS\scbc application\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
+  CreateShortCut "$SMPROGRAMS\scbc application\Uninstall.lnk" "$INSTDIR\uninst.exe"
+SectionEnd
+
+Section -Post
+  WriteUninstaller "$INSTDIR\uninst.exe"
+  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\TCL Copy Tool.exe"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\TCL Tools.exe"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
+  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
+SectionEnd
+
+
+Function un.onUninstSuccess
+  HideWindow
+  MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从你的计算机移除。"
+FunctionEnd
+
+Function un.onInit
+  MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "你确实要完全移除 $(^Name) ,其及所有的组件?" IDYES +2
+  Abort
+FunctionEnd
+
+Section Uninstall
+  Delete "$INSTDIR\${PRODUCT_NAME}.url"
+  Delete "$INSTDIR\uninst.exe"
+  Delete "$INSTDIR\rename.exe"
+  Delete "$INSTDIR\TCL Copy Tool.exe"
+  Delete "$INSTDIR\config.json"
+  Delete "$INSTDIR\Log4C.dll"
+
+  Delete "$SMPROGRAMS\scbc application\Uninstall.lnk"
+  Delete "$SMPROGRAMS\scbc application\Website.lnk"
+  Delete "$DESKTOP\scbc application.lnk"
+  Delete "$SMPROGRAMS\scbc application\scbc application.lnk"
+
+  RMDir "$SMPROGRAMS\scbc application"
+  RMDir "$INSTDIR"
+
+  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
+  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+  SetAutoClose true
+SectionEnd

+ 43 - 0
TCL Copy Tool/TCL Copy Tool.sln

@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29123.88
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TCL Copy Tool", "TCL Copy Tool\TCL Copy Tool.vcxproj", "{652623E7-21D4-42F7-81EC-6FF166A63F05}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+		SDebug|x64 = SDebug|x64
+		SDebug|x86 = SDebug|x86
+		SRelease|x64 = SRelease|x64
+		SRelease|x86 = SRelease|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Debug|x64.ActiveCfg = Debug|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Debug|x64.Build.0 = Debug|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Debug|x86.ActiveCfg = Debug|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Debug|x86.Build.0 = Debug|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Release|x64.ActiveCfg = Release|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Release|x64.Build.0 = Release|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Release|x86.ActiveCfg = Release|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.Release|x86.Build.0 = Release|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SDebug|x64.ActiveCfg = SDebug|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SDebug|x64.Build.0 = SDebug|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SDebug|x86.ActiveCfg = SDebug|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SDebug|x86.Build.0 = SDebug|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SRelease|x64.ActiveCfg = SRelease|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SRelease|x64.Build.0 = SRelease|x64
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SRelease|x86.ActiveCfg = SRelease|Win32
+		{652623E7-21D4-42F7-81EC-6FF166A63F05}.SRelease|x86.Build.0 = SRelease|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {AF5A544F-8FDB-49A5-B1D2-32EC37406FFB}
+	EndGlobalSection
+EndGlobal

+ 130 - 0
TCL Copy Tool/TCL Copy Tool/Base64.cpp

@@ -0,0 +1,130 @@
+#include "pch.h"
+#include "Base64.h"
+
+CBase64::CBase64(void)
+{
+}
+
+CBase64::~CBase64(void)
+{
+}
+
+const char CBase64::sm_base64digits[65] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+const char CBase64::sm_base64val[128] = {
+	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
+	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
+	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
+	52, 53, 54, 55,  56, 57, 58, 59,  60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
+	BAD,  0,  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,BAD, BAD,BAD,BAD,BAD,
+	BAD, 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,BAD, BAD,BAD,BAD,BAD
+};
+
+/************************************************************************/
+/*  函数:[6/2/2016 IT];
+/*  描述:将字节转换为Base64字符;
+/*  参数:;
+/*  	[IN] pbinary:			要转换成Base64字符的二进制字节数组;
+/*  	[IN] nbinaryLen:		pbinary所指向的缓存大小;
+/*  	[OUT] pOutBase64:		返回转换后的Base64字符,以'\0'结束;
+/*  返回:返回转换成功后的Base64字符数;
+/*  注意:注意参数1是字节BYTE,返回的pOutBase64是人为加上'\0'结束符;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+void CBase64::binToBase64(IN const unsigned char *pbinary, IN size_t nbinaryLen, OUT char *pOutBase64)
+{
+	for ( ; nbinaryLen >= 3; nbinaryLen -= 3, pbinary += 3) 
+	{
+		*pOutBase64++ = sm_base64digits[pbinary[0] >> 2];
+		*pOutBase64++ = sm_base64digits[((pbinary[0] << 4) & 0x30) | (pbinary[1] >> 4)];
+		*pOutBase64++ = sm_base64digits[((pbinary[1] << 2) & 0x3c) | (pbinary[2] >> 6)];
+		*pOutBase64++ = sm_base64digits[pbinary[2] & 0x3f];
+	}
+
+	if (nbinaryLen > 0) 
+	{
+		unsigned char fragment;
+		*pOutBase64++ = sm_base64digits[pbinary[0] >> 2];
+		fragment = (pbinary[0] << 4) & 0x30;
+
+		if (nbinaryLen > 1)
+			fragment |= pbinary[1] >> 4;
+
+		*pOutBase64++ = sm_base64digits[fragment];
+		*pOutBase64++ = (nbinaryLen < 2) ? '=' : sm_base64digits[(pbinary[1] << 2) & 0x3c];
+		*pOutBase64++ = '=';
+	}
+	*pOutBase64 = '\0';
+}
+
+/************************************************************************/
+/*  函数:[6/2/2016 IT];
+/*  描述:将Base64字符串转为化二进制字节字符串;
+/*  参数:;
+/*  	[IN] pBase64:		要转化成二进制字节字符串的Base64字符;
+/*  	[OUT] pbinary:		返回转化成二进制字节的字符串;
+/*  	[IN] maxLen:		pbinary指向的缓存大小;
+/*  返回:返回转化成二进制字节字符数;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CBase64::base64ToBin(IN const char *pBase64, OUT unsigned char *pbinary, IN size_t maxLen)
+{
+	size_t len = 0;
+	unsigned char digit1, digit2, digit3, digit4;
+
+	if (pBase64[0] == '+' && pBase64[1] == ' ')
+		pBase64 += 2;
+	if (pBase64[0] == '\r')
+		return 0;
+
+	while (*pBase64 && *pBase64 != '\r' /*&& digit4 != '='*/) 
+	{
+		digit1 = pBase64[0];
+		if (decode64(digit1) == BAD)
+			return -1;
+		digit2 = pBase64[1];
+		if (decode64(digit2) == BAD)
+			return -1;
+		digit3 = pBase64[2];
+		if (digit3 != '=' && decode64(digit3) == BAD)
+			return -1; 
+		digit4 = pBase64[3];
+		if (digit4 != '=' && decode64(digit4) == BAD)
+			return -1;
+		pBase64 += 4;
+
+		++len;
+		if (maxLen && len > maxLen)
+			return -1;
+
+		*(pbinary++) = (decode64(digit1) << 2) | (decode64(digit2) >> 4);
+		if (digit3 != '=') 
+		{
+			++len;
+			if (maxLen && len > maxLen)
+				return -1;
+			*(pbinary++) = ((decode64(digit2) << 4) & 0xf0) | (decode64(digit3) >> 2);
+			if (digit4 != '=') 
+			{
+				++len;
+				if (maxLen && len > maxLen)
+					return -1;
+				*(pbinary++) = ((decode64(digit3) << 6) & 0xc0) | decode64(digit4);
+			} // if
+		} // if
+	} // while
+
+	return len;
+}

+ 70 - 0
TCL Copy Tool/TCL Copy Tool/Base64.h

@@ -0,0 +1,70 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [IT], 保留所有权利;
+/*  模 块 名:;
+/*  描    述:;
+/*
+/*  版    本:[V];	
+/*  作    者:[IT];
+/*  日    期:[5/24/2016];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[IT];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+#ifndef __BASE64_CODE__
+#define __BASE64_CODE__
+
+#pragma once
+
+class CBase64
+{
+public:
+	CBase64(void);
+	~CBase64(void);
+
+	/************************************************************************/
+	/*  函数:[5/24/2016 IT];
+	/*  描述:获取指定字符串长度对应的Base64字符长度;
+	/*  参数:;
+	/*  	[IN] len:要计算的字符长度;
+	/*  返回:返回指定长度len的字符串转换为编码Base64对应的长度,并多加一个'\0'结束符;
+	/*  注意:;
+	/************************************************************************/
+	static int CalcBase64Len(IN const size_t& len) {
+		return (len / 3 + (len % 3 ? 1 : 0)) * 4 + 1; // one more byte for '\0'
+	}
+
+	static void binToBase64(IN const unsigned char *pbinary, IN size_t nbinaryLen, OUT char *pOutBase64);
+
+	/************************************************************************/
+	/*  函数:[5/24/2016 IT];
+	/*  描述:获取指定Base64字符串长度对应的字节长度;
+	/*  参数:;
+	/*  	[IN] len:要计算的Base64字符长度;
+	/*  返回:返回指定长度len的Base64字符串转换为字节对应的长度;
+	/*  注意:;
+	/************************************************************************/
+	static int CalcBinLen(size_t len) {
+		return len / 4 * 3; 
+	}
+
+	static int base64ToBin(IN const char *pBase64, OUT unsigned char *pbinary, IN size_t maxLen);
+
+private:
+	static char decode64(unsigned char ch) {
+		return ch < 128 ? sm_base64val[ch] : BAD;
+	}
+
+private:
+	enum {BAD = -1};
+	// 必须是ASCII字符;
+	static const char sm_base64digits[65];
+	// 必须是ASCII字符;
+	static const char sm_base64val[128];
+};
+
+#endif // __BASE64_CODE__

+ 235 - 0
TCL Copy Tool/TCL Copy Tool/CharConvert.cpp

@@ -0,0 +1,235 @@
+#include "pch.h"
+#include "CharConvert.h"
+
+/* string to utf8 */
+std::string stringToUTF8(const std::string& str)
+{
+	int nwLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
+	wchar_t* pwBuf = new wchar_t[nwLen + 1];
+	ZeroMemory(pwBuf, nwLen * 2 + 2);
+
+	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
+
+	int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
+
+	char* pBuf = new char[nLen + 1];
+	ZeroMemory(pBuf, nLen + 1);
+
+	WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
+
+	std::string retStr(pBuf);
+
+	delete[] pwBuf;
+	delete[] pBuf;
+
+	pwBuf = NULL;
+	pBuf = NULL;
+
+	return(retStr);
+}
+
+/* utf8 to string */
+std::string UTF8Tostring(const std::string& str)
+{
+	int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
+
+	wchar_t* pwBuf = new wchar_t[nwLen + 1];
+	memset(pwBuf, 0, nwLen * 2 + 2);
+
+	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);
+
+	int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
+
+	char* pBuf = new char[nLen + 1];
+	memset(pBuf, 0, nLen + 1);
+
+	WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
+
+	std::string retStr = pBuf;
+
+	delete[] pwBuf;
+	delete[] pBuf;
+
+	pwBuf = NULL;
+	pBuf = NULL;
+
+	return(retStr);
+}
+
+/* UTF8 to URL String */
+std::string UTF8ToURLString(const std::string& str)
+{
+	std::string	strRes;
+	unsigned int iIndex = 0, iCount = str.length();
+
+	while(iIndex < iCount)
+	{
+		if((unsigned char)str.c_str()[iIndex] < 0x7F)
+		{
+			if ((unsigned char)str.c_str()[iIndex] == (unsigned char)(' '))
+			{
+				strRes.append(1, '+');
+			}
+			else
+			{
+				strRes.append(1, (unsigned char)str.c_str()[iIndex]);
+			}
+			++iIndex;
+		}
+		else
+		{
+			char chBuf[10];
+
+			sprintf_s(chBuf, "%%%02X%%%02X%%%02X", (unsigned char)str.c_str()[iIndex], (unsigned char)str.c_str()[iIndex + 1], (unsigned char)str.c_str()[iIndex + 3]);
+
+			std::string strTmp = chBuf;
+			strRes += strTmp;
+			iIndex += 3;
+		}
+	}
+
+	return strRes;
+}
+
+/* Hex string to char */
+char HexStrToChar(const std::string& str)
+{
+	char chRet = 0;
+
+	for (char i = 0; i < 2; i++)
+	{
+		char chTemp = str.at(i);
+		chRet *= 16;
+		
+		if(chTemp >= '0' && chTemp <= '9')
+			chRet += chTemp - '0';
+		else if(chTemp >= 'a' && chTemp <= 'f')
+			chRet += (chTemp - 'a') + 10;
+		else if(chTemp >= 'A' && chTemp <= 'F')
+			chRet += (chTemp - 'A') + 10;
+	}
+
+	return(chRet);
+}
+
+/* string to int */
+unsigned int StrToInt(const std::string& str)
+{
+	unsigned int uiRet = 0;
+
+	for(unsigned char ucIndex = 0; ucIndex < str.length(); ucIndex++)
+	{
+		char chTemp = str.at(ucIndex);
+		uiRet *= 10;
+		uiRet += chTemp - '0';
+	}
+
+	return(uiRet);
+}
+
+/************************************************************************/
+/*  函数:[4/2/2019 Wang];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/************************************************************************/
+unsigned char TwoHexCharToChar(char ch1,char ch2)  
+{
+	char Numb1;
+	char Numb2;
+
+	if (ch1 >= 'A')
+		Numb1 = (toupper(ch1)-'0'-7)*16;
+	else
+		Numb1 = (ch1 - '0')*16;
+
+	if (ch2 >= 'A')
+		Numb2 = (toupper(ch2) - '0' - 7);
+	else
+		Numb2 = (ch2 - '0');
+
+	return (Numb1 + Numb2);
+}
+
+
+/************************************************************************/
+/*  函数:[4/2/2019 Wang];
+/*  描述:16进制字符串转字节,16进制字符以空格间隔,如"AA BB CC 0A";
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/************************************************************************/
+std::string HexStr2Bytes(std::string strHex)
+{
+	byte value = 0;
+	std::string strBytes;
+	int nSize = strHex.size();
+	for (int i = 0; i < nSize; i+=3 )
+	{
+		strBytes.push_back(TwoHexCharToChar(strHex[i], strHex[i+1]));
+	}
+
+	return strBytes;
+}
+
+
+std::string Bytes2HexStr(const unsigned char *pbuffer, int nLen )
+{
+	std::string hex;
+	char szhex[5] = {0};
+	for ( int i = 0; i < nLen; i++ )
+	{
+		memset(szhex, 0, 5);
+		_stprintf_s(szhex, "%02X ", pbuffer[i]);
+		hex.append(szhex);
+	}
+
+	return hex;
+}
+
+//BYTE HexStrToChar(const string& szData)
+//{
+//	BYTE	byteRet = 0;
+//
+//	for (int i = 0; i < 2; ++i)
+//	{
+//		BYTE byteTmp = szData.at(i);
+//
+//		byteRet *= 16;
+//
+//		if (byteTmp >= '0' && byteTmp <= '9')
+//			byteRet += byteTmp - '0';
+//		else if (byteTmp >= 'a' && byteTmp <= 'f')
+//			byteRet += (byteTmp - 'a') + 10;
+//		else if (byteTmp >= 'A' && byteTmp <= 'F')
+//			byteRet += (byteTmp - 'A') + 10;
+//	}
+//
+//	return(byteRet);
+//}
+
+//std::string CString2string(CString csStrData)
+//{
+//	int iLen = csStrData.GetLength() + 1;
+//	char* pSrc = new char[iLen];
+//	if (pSrc == NULL)
+//	{
+//		return "";
+//	}
+//
+//	memset(pSrc, 0, iLen);
+//
+//	wchar_t* pwSrc = NULL;
+//	pwSrc = (wchar_t*)(csStrData.GetBuffer(iLen * sizeof(wchar_t)));
+//	WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pwSrc, -1, pSrc, iLen, NULL, NULL);
+//
+//	string strRet = string(pSrc);
+//	delete[] pSrc;
+//	csStrData.ReleaseBuffer(iLen);
+//	return strRet;
+//}

+ 22 - 0
TCL Copy Tool/TCL Copy Tool/CharConvert.h

@@ -0,0 +1,22 @@
+#ifndef __CHAR_CONVERT_H__
+#define __CHAR_CONVERT_H__
+
+#include <string>
+//using namespace std;
+
+/* Functions */
+std::string stringToUTF8(const std::string& str);
+std::string UTF8Tostring(const std::string& str);
+std::string UTF8ToURLString(const std::string& str);
+
+char HexStrToChar(const std::string& str);
+unsigned int StrToInt(const std::string& str);
+//unsigned int UnicodeToString(const CString strIn, string& szOut);
+//std::string CString2string(CString csStrData);
+//string CString2string(CString csStrData);
+//BYTE HexStrToChar(const string& szData);
+extern std::string HexStr2Bytes(std::string strHex);
+extern unsigned char TwoHexCharToChar(char ch1,char ch2) ;
+extern std::string Bytes2HexStr( const unsigned char *pbuffer, int nLen );
+
+#endif	/* __CHAR_CONVERT_H__ */

+ 739 - 0
TCL Copy Tool/TCL Copy Tool/CharEncoding.cpp

@@ -0,0 +1,739 @@
+#include "pch.h"
+#include "CharEncoding.h"
+
+WCHAR* CharEncoding::ASCII2UNICODE(IN LPCCH lpASCIIStr)
+{
+	if ( lpASCIIStr == NULL )
+		return NULL;
+
+	// 获取宽字符字节数;
+	int cchWideChar  = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
+	if ( cchWideChar == 0)
+		return NULL;
+
+	// 转换成宽字符串;
+	WCHAR *pWideChar = new WCHAR[cchWideChar + 1];
+	memset(pWideChar, 0 , sizeof(WCHAR)*(cchWideChar + 1));
+	int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pWideChar, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+	{ 
+		if (pWideChar) 
+			delete []pWideChar;
+		return NULL;
+	}
+
+	return pWideChar;
+}
+
+BOOL CharEncoding::ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen)
+{
+	if ( lpASCIIStr == NULL )
+		return FALSE;
+
+	// 获取宽字符字节数;
+	int cchWideChar  = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
+	if ( cchWideChar == 0 || cchWideChar >= nUNICODEStrLen)
+		return FALSE;
+
+	// 转换成宽字符串;
+	memset(pUNICODEStr, 0 , sizeof(WCHAR)*nUNICODEStrLen);
+	int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pUNICODEStr, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+		return FALSE;
+
+	return TRUE;
+}
+
+BOOL CharEncoding::ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT wstring &strResult)
+{
+	if ( lpASCIIStr == NULL )
+		return FALSE;
+
+	// 获取宽字符字节数;
+	int cchWideChar  = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
+	if ( cchWideChar == 0 )
+		return FALSE;
+
+	// 转换成宽字符串;
+	WCHAR *pResult = new WCHAR[cchWideChar];
+	memset(pResult, 0 , sizeof(WCHAR)*cchWideChar);
+	int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pResult, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+		return FALSE;
+
+	strResult = pResult;
+	if ( pResult )
+		delete[] pResult;
+
+	return TRUE;
+}
+
+CHAR* CharEncoding::UNICODE2ASCII(IN LPWCH lpUNICODEStr)
+{
+	if ( lpUNICODEStr == NULL )
+		return NULL;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 )
+		return NULL;
+
+	// 转换成多字节字符;
+	CHAR *pMultiByteStr = new CHAR[cbMultiByte+1];
+	memset(pMultiByteStr, 0, cbMultiByte + 1);
+	int nWriteNum = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, pMultiByteStr, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+	{
+		if (pMultiByteStr) 
+			delete []pMultiByteStr;
+		return NULL;
+	}
+
+	return pMultiByteStr;
+}
+
+BOOL CharEncoding::UNICODE2ASCII(IN LPWCH lpUNICODEStr, OUT LPCH pASCIIStr, IN CONST INT& nASCIIStrLen)
+{
+	if ( lpUNICODEStr == NULL )
+		return FALSE;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 || cbMultiByte >= nASCIIStrLen )
+		return FALSE;
+
+	// 转换成多字节字符;
+	memset((void*)pASCIIStr, 0, nASCIIStrLen);
+	int nWriteNum = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, pASCIIStr, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CharEncoding::UNICODE2ASCII(IN LPWCH lpUNICODEStr, OUT string &strResult)
+{
+	if ( lpUNICODEStr == NULL )
+		return FALSE;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 )
+		return FALSE;
+
+	// 转换成多字节字符;
+	CHAR* pResult = new CHAR[cbMultiByte];
+	memset(pResult, 0, cbMultiByte);
+	int nWriteNum = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, pResult, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+		return FALSE;
+
+	strResult = pResult;
+	if ( pResult )
+		delete[] pResult;
+
+	return TRUE;
+}
+
+CHAR* CharEncoding::UNICODE2UTF8(IN LPWCH lpUNICODEStr)
+{
+	if ( lpUNICODEStr == NULL )
+		return NULL;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 )
+		return NULL;
+
+	// 转换成多字节字符;
+	CHAR* pMultiByteStr = new CHAR[cbMultiByte+1];
+	memset(pMultiByteStr, 0, cbMultiByte + 1);
+	int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pMultiByteStr, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+	{
+		if (pMultiByteStr) 
+			delete []pMultiByteStr;
+		return NULL;
+	}
+
+	return pMultiByteStr;
+}
+
+BOOL CharEncoding::UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen)
+{
+	if ( lpUNICODEStr == NULL )
+		return FALSE;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 || cbMultiByte >= nUTF8StrLen )
+		return FALSE;
+
+	// 转换成多字节字符;
+	memset(pUTF8Str, 0, nUTF8StrLen);
+	int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pUTF8Str, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CharEncoding::UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT string &strResult)
+{
+	if ( lpUNICODEStr == NULL )
+		return FALSE;
+
+	// 获取多字节字符字节数;
+	int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+	if ( cbMultiByte == 0 )
+		return FALSE;
+
+	// 转换成多字节字符;
+	CHAR *pResult = new CHAR[cbMultiByte];
+	memset(pResult, 0, cbMultiByte);
+	int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pResult, cbMultiByte, NULL, NULL);
+	if (nWriteNum != cbMultiByte)
+		return FALSE;
+
+	strResult = pResult;
+	if ( pResult )
+		delete[] pResult;
+
+	return TRUE;
+}
+
+CHAR* CharEncoding::ASCII2UTF8(IN LPCCH lpASCIIStr)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
+	if ( pWideChar == NULL )
+		return NULL;
+
+	// 再将UICODE转成UTF8;
+	CHAR* pUTF8 = UNICODE2UTF8(pWideChar);
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return pUTF8;
+}
+
+BOOL CharEncoding::ASCII2UTF8(IN LPCCH lpASCIIStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
+	if ( pWideChar == NULL )
+		return FALSE;
+
+	// 再将UICODE转成UTF8;
+	BOOL bResult = UNICODE2UTF8(pWideChar, pUTF8Str, nUTF8StrLen);
+
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return bResult;
+}
+
+BOOL CharEncoding::ASCII2UTF8(IN LPCCH lpASCIIStr, OUT string &strResult)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
+	if ( pWideChar == NULL )
+		return FALSE;
+
+	// 再将UICODE转成UTF8;
+	BOOL bResult = UNICODE2UTF8(pWideChar, strResult);
+
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return bResult;
+}
+
+WCHAR* CharEncoding::UTF82UNICODE(IN LPCCH lpUTF8)
+{
+	if ( lpUTF8 == NULL )
+		return NULL;
+
+	// 获取unicode字符数;
+	int cchWideChar = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, NULL, 0);
+	if ( cchWideChar == 0)
+		return NULL;
+
+	// 转换成宽字符串;
+	WCHAR *pWideChar = new WCHAR[cchWideChar + 1];
+	memset(pWideChar, 0 , sizeof(WCHAR)*(cchWideChar + 1));
+	int nWriteNum = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, pWideChar, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+	{ 
+		if (pWideChar) 
+			delete []pWideChar;
+		return NULL;
+	}
+
+	return pWideChar;
+}
+
+BOOL CharEncoding::UTF82UNICODE(IN LPCCH lpUTF8, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen)
+{
+	if ( lpUTF8 == NULL )
+		return FALSE;
+
+	// 获取宽字符字节数;
+	int cchWideChar  = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, NULL, 0);
+	if ( cchWideChar == 0 || cchWideChar >= nUNICODEStrLen)
+		return FALSE;
+
+	// 转换成宽字符串;
+	memset(pUNICODEStr, 0 , sizeof(WCHAR)*nUNICODEStrLen);
+	int nWriteNum = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, pUNICODEStr, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+		return FALSE;
+
+	return TRUE;
+}
+
+BOOL CharEncoding::UTF82UNICODE(IN LPCCH lpUTF8, OUT wstring &strResult)
+{
+	if ( lpUTF8 == NULL )
+		return FALSE;
+
+	// 获取宽字符字节数;
+	int cchWideChar  = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, NULL, 0);
+	if ( cchWideChar == 0 )
+		return FALSE;
+
+	// 转换成宽字符串;
+	WCHAR* pResult = new WCHAR[cchWideChar];
+	memset(pResult, 0 , sizeof(WCHAR)*cchWideChar);
+	int nWriteNum = MultiByteToWideChar(CP_UTF8, 0, lpUTF8, -1, pResult, cchWideChar );
+	if ( nWriteNum != cchWideChar)
+		return FALSE;
+
+	strResult = pResult;
+	if ( pResult )
+		delete[] pResult;
+
+	return TRUE;
+}
+
+CHAR* CharEncoding::UTF82ASCII(IN LPCCH lpUTF8)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = UTF82UNICODE(lpUTF8);
+	if ( pWideChar == NULL )
+		return NULL;
+
+	// 再将UICODE转成UTF8;
+	CHAR* pUTF8 = UNICODE2ASCII(pWideChar);
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return pUTF8;
+}
+
+BOOL CharEncoding::UTF82ASCII(IN LPCCH lpUTF8, OUT LPCH pASCIIStr, IN CONST INT& nASCIIStrLen)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = UTF82UNICODE(lpUTF8);
+	if ( pWideChar == NULL )
+		return FALSE;
+
+	// 再将UICODE转成UTF8;
+	BOOL bResult = UNICODE2ASCII(pWideChar, pASCIIStr, nASCIIStrLen);
+
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return bResult;
+}
+
+BOOL CharEncoding::UTF82ASCII(IN LPCCH lpUTF8, OUT string &strResult)
+{
+	// 将ASCII字符串转成UNICODE字符串;
+	WCHAR* pWideChar = UTF82UNICODE(lpUTF8);
+	if ( pWideChar == NULL )
+		return FALSE;
+
+	// 再将UICODE转成UTF8;
+	BOOL bResult = UNICODE2ASCII(pWideChar, strResult);
+
+	if ( pWideChar )
+		delete []pWideChar;
+
+	return bResult;
+}
+
+//做为解Url使用
+char CharEncoding::CharToInt(char ch)
+{
+	if (ch >= '0' && ch <= '9')return (char)(ch - '0');
+	if (ch >= 'a' && ch <= 'f')return (char)(ch - 'a' + 10);
+	if (ch >= 'A' && ch <= 'F')return (char)(ch - 'A' + 10);
+	return -1;
+}
+
+char CharEncoding::StrToBin(IN char (&str)[2])
+{
+	char tempWord[2];
+	char chn;
+
+	tempWord[0] = CharToInt(str[0]);                         //make the B to 11 -- 00001011
+	tempWord[1] = CharToInt(str[1]);                         //make the 0 to 0  -- 00000000
+
+	chn = (tempWord[0] << 4) | tempWord[1];                //to change the BO to 10110000
+
+	return chn;
+}
+
+//GB2312 转为 UTF-8
+void CharEncoding::GB2312ToUTF_8(string& pOut, const char *pText, int pLen)
+{
+	char buf[4];
+	memset(buf, 0, 4);
+
+	pOut.clear();
+
+	int i = 0;
+	while (i < pLen)
+	{
+		//如果是英文直接复制就可以;
+		if (pText[i] >= 0)
+		{
+			char asciistr[2] = { 0 };
+			asciistr[0] = (pText[i++]);
+			pOut.append(asciistr);
+		}
+		else
+		{
+			WCHAR pbuffer[2] = {0};
+			MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pText + i, 2, pbuffer, 1);
+			UNICODE2UTF8(pbuffer, buf, 4);
+			pOut.append(buf);
+			i += 2;
+		}
+	}
+
+	return;
+}
+
+/************************************************************************/
+/*  函数:[7/26/2016 IT];
+/*  描述:将字符串编码成为GB2312格式的URL;;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+string CharEncoding::EnCode_GB2312URL(IN CHAR* pText)
+{
+	string dd;
+	size_t len = strlen(pText);
+	for (size_t i = 0; i < len; i++)
+	{
+		if (isalnum((BYTE)pText[i]))
+		{
+			char tempbuff[2];
+			sprintf_s(tempbuff, "%c", pText[i]);
+			dd.append(tempbuff);
+		}
+		else if (isspace((BYTE)pText[i]))
+		{
+			dd.append("+");
+		}
+		else
+		{
+			char tempbuff[4];
+			sprintf_s(tempbuff, "%%%X%X", ((BYTE*)pText)[i] >> 4, ((BYTE*)pText)[i] % 16);
+			dd.append(tempbuff);
+		}
+	}
+	return dd;
+}
+
+void CharEncoding::EnCode_GB2312URL(IN CHAR* pText, OUT string& strResult)
+{
+	size_t len = strlen(pText);
+	for (size_t i = 0; i < len; i++)
+	{
+		if (isalnum((BYTE)pText[i]))
+		{
+			char tempbuff[2];
+			sprintf_s(tempbuff, "%c", pText[i]);
+			strResult.append(tempbuff);
+		}
+		else if (isspace((BYTE)pText[i]))
+		{
+			strResult.append("+");
+		}
+		else
+		{
+			char tempbuff[4];
+			sprintf_s(tempbuff, "%%%X%X", ((BYTE*)pText)[i] >> 4, ((BYTE*)pText)[i] % 16);
+			strResult.append(tempbuff);
+		}
+	}
+}
+
+/************************************************************************/
+/*  函数:[7/26/2016 IT];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+string CharEncoding::EnCode_UTF8URL(IN const CHAR* pText)
+{
+	string tt = "";
+	string dd = "";
+	ASCII2UTF8(pText,tt);
+
+	size_t len = tt.length();
+	for (size_t i = 0; i < len; i++)
+	{
+		if (isalnum((BYTE)tt.at(i)))
+		{
+			char tempbuff[2] = { 0 };
+			sprintf_s(tempbuff, "%c", (BYTE)tt.at(i));
+			dd.append(tempbuff);
+		}
+		else if (isspace((BYTE)tt.at(i)))
+		{
+			dd.append("+");
+		}
+		else
+		{
+			char tempbuff[4];
+			sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16);
+			dd.append(tempbuff);
+		}
+	}
+	return dd;
+}
+
+void CharEncoding::EnCode_UTF8URL(IN const CHAR* pText, OUT string& strResult)
+{
+	string tt = "";
+	ASCII2UTF8(pText,tt);
+
+	size_t len = tt.length();
+	for (size_t i = 0; i < len; i++)
+	{
+		if (isalnum((BYTE)tt.at(i)))
+		{
+			char tempbuff[2] = { 0 };
+			sprintf_s(tempbuff, "%c", (BYTE)tt.at(i));
+			strResult.append(tempbuff);
+		}
+		else if (isspace((BYTE)tt.at(i)))
+		{
+			strResult.append("+");
+		}
+		else
+		{
+			char tempbuff[4];
+			sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16);
+			strResult.append(tempbuff);
+		}
+	}
+}
+
+string CharEncoding::EnCode_UNICODEURL(IN const CHAR* pText)
+{
+	return "";
+}
+
+/************************************************************************/
+/*  函数:[7/26/2016 IT];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+string CharEncoding::DeCode_URLGB2312(IN const CHAR* pURLText)
+{
+	string output = "";
+	char tmp[2];
+	int i = 0, idx = 0, len = strlen(pURLText);
+
+	while (i < len){
+		if (pURLText[i] == '%')
+		{
+			tmp[0] = pURLText[i + 1];
+			tmp[1] = pURLText[i + 2];
+			output += StrToBin(tmp);
+			i = i + 3;
+		}
+		else if (pURLText[i] == '+')
+		{
+			output += ' ';
+			i++;
+		}
+		else{
+			output += pURLText[i];
+			i++;
+		}
+	}
+
+	return output;
+}
+
+void CharEncoding::DeCode_URLGB2312(IN const CHAR* pURLText, OUT string& strResult)
+{
+	char tmp[2];
+	int i = 0, idx = 0, len = strlen(pURLText);
+
+	while (i < len){
+		if (pURLText[i] == '%')
+		{
+			tmp[0] = pURLText[i + 1];
+			tmp[1] = pURLText[i + 2];
+			strResult += StrToBin(tmp);
+			i = i + 3;
+		}
+		else if (pURLText[i] == '+')
+		{
+			strResult += ' ';
+			i++;
+		}
+		else{
+			strResult += pURLText[i];
+			i++;
+		}
+	}
+}
+
+/************************************************************************/
+/*  函数:[7/26/2016 IT];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+string CharEncoding::DeCode_URLUTF8(IN const CHAR* pURLText)
+{
+	string output = "";
+	string temp = DeCode_URLGB2312(pURLText);
+	UTF82ASCII(temp.c_str(), output);
+	return output;
+}
+
+void CharEncoding::DeCode_URLUTF8(IN const CHAR* pURLText, OUT string& strResult)
+{
+	string temp = DeCode_URLGB2312(pURLText);
+	UTF82ASCII(temp.c_str(), strResult);
+}
+
+/************************************************************************/
+/*  函数:[7/26/2016 IT];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+string CharEncoding::DeCode_URLUNICODE(IN const CHAR* pURLText)
+{
+	string str = pURLText;
+	string strResult = "";
+
+	INT nIndex = 0;
+	string strTemp = "";
+
+	while ( str.find_first_of("\\u") != string::npos )
+	{
+		nIndex = str.find_first_of("\\u");
+		strResult.append(str.substr(0, nIndex));
+		strTemp = str.substr(nIndex + 2, 4);
+		str = str.substr(nIndex + 2 +4);
+		CHAR szReturn[10] = {0};
+
+		union  __UNION_VAR_INT{
+			BYTE   ch[2];   
+			int	   value;   
+		}unionVarInt;
+
+		unionVarInt.ch[0] =  (CharToInt(strTemp.at(2)) << 4) | (CharToInt(strTemp.at(3))  & 0x00FF);
+		unionVarInt.ch[1] =  (CharToInt(strTemp.at(0)) << 4) | (CharToInt(strTemp.at(1))  & 0x00FF);
+
+		WCHAR szWide[2] = {0};
+		szWide[0] = unionVarInt.value;
+		UNICODE2ASCII(szWide,szReturn,10);
+		strResult.append(szReturn);
+	}
+	strResult.append(str);
+
+	return strResult;
+}
+
+void CharEncoding::DeCode_URLUNICODE(IN const CHAR* pURLText, OUT string& strResult)
+{
+	string str = pURLText;
+
+	INT nIndex = 0;
+	string strTemp = "";
+
+	while ( str.find_first_of("\\u") != string::npos )
+	{
+		nIndex = str.find_first_of("\\u");
+		strResult.append(str.substr(0, nIndex));
+		strTemp = str.substr(nIndex + 2, 4);
+		str = str.substr(nIndex + 2 +4);
+		CHAR szReturn[10] = {0};
+
+		union  __UNION_VAR_INT{
+			BYTE   ch[2];   
+			int	   value;   
+		}unionVarInt;
+
+		unionVarInt.ch[0] =  (CharToInt(strTemp.at(2)) << 4) | (CharToInt(strTemp.at(3))  & 0x00FF);
+		unionVarInt.ch[1] =  (CharToInt(strTemp.at(0)) << 4) | (CharToInt(strTemp.at(1))  & 0x00FF);
+
+		WCHAR szWide[2] = {0};
+		szWide[0] = unionVarInt.value;
+		UNICODE2ASCII(szWide,szReturn,10);
+		strResult.append(szReturn);
+	}
+	strResult.append(str);
+}

+ 97 - 0
TCL Copy Tool/TCL Copy Tool/CharEncoding.h

@@ -0,0 +1,97 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [IT], 保留所有权利;
+/*  模 块 名:公共模块,未做性能优化;
+/*  描    述:;
+/*
+/*  版    本:[V];	
+/*  作    者:[IT];
+/*  日    期:[7/26/2016];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[IT];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+#ifndef __CHAR_ENCODING__
+#define __CHAR_ENCODING__
+
+#include <string>
+#include <vector>
+using namespace std;
+
+#ifndef _UNICODE
+typedef string TString;
+#else
+typedef wstring TString;
+#endif
+
+#pragma once
+
+
+class  CharEncoding
+{
+public:
+	// 将字符转化为对应的ASCII十进制值;
+	static char CharToInt(char ch);
+	// 将两个字符串转化成十六进制值;
+	static char StrToBin(IN char (&str)[2]);
+	static void GB2312ToUTF_8(string& pOut, const char *pText, int pLen);
+	// 将ASCII字符串转成UNICODE字符串;
+	static WCHAR* ASCII2UNICODE(IN LPCCH lpASCIIStr);
+	static BOOL   ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen);
+	static BOOL   ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT wstring &strResult);
+
+	// 将UNICODE字符串转成ASCII字符串;
+	static CHAR* UNICODE2ASCII(IN LPWCH lpUNICODEStr);
+	static BOOL  UNICODE2ASCII(IN LPWCH lpUNICODEStr, OUT LPCH pASCIIStr, IN CONST INT& nASCIIStrLen);
+	static BOOL  UNICODE2ASCII(IN LPWCH lpUNICODEStr, OUT string &strResult);
+
+	// 将UNICODE字符串转成UFT8字符串;
+	static CHAR* UNICODE2UTF8(IN LPWCH lpUNICODEStr);
+	static BOOL  UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen);
+	static BOOL  UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT string &strResult);
+
+	// 将ASCII字符串转成UTF8字符串;
+	static CHAR* ASCII2UTF8(IN LPCCH lpASCIIStr);
+	static BOOL  ASCII2UTF8(IN LPCCH lpASCIIStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen);
+	static BOOL  ASCII2UTF8(IN LPCCH lpASCIIStr, OUT string &strResult);
+
+	// 将UTF-8字符串转成UNICODE字符串;
+	static WCHAR* UTF82UNICODE(IN LPCCH lpUTF8);
+	static BOOL   UTF82UNICODE(IN LPCCH lpUTF8, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen);
+	static BOOL   UTF82UNICODE(IN LPCCH lpUTF8, OUT wstring &strResult);
+
+	// 将UTF-8字符串转成ASCII字符串;
+	static CHAR*  UTF82ASCII(IN LPCCH lpUTF8);
+	static BOOL   UTF82ASCII(IN LPCCH lpUTF8, OUT LPCH pASCIIStr, IN CONST INT& nASCIIStrLen);
+	static BOOL   UTF82ASCII(IN LPCCH lpUTF8, OUT string &strResult);
+
+	// 将UTF-8编码成GB2312;
+	static string UTF8IntoGB2313(IN CHAR* pUTF8Text, IN const INT& nUTF8TextLen);
+	// 将GB2312编码成UTF-8;
+	static string GB2312IntoUTF8(IN CHAR* pGB2312Text, IN const INT& nGB2312TextLen);
+
+	// 将字符串编码成为GB2312编码格式的URL;
+	static string EnCode_GB2312URL(IN CHAR* pText);
+	static void EnCode_GB2312URL(IN CHAR* pText, OUT string& strResult);
+	// 将字符串编码成为UTF-8编码格式的URL;
+	static string EnCode_UTF8URL(IN const CHAR* pText);
+	static void EnCode_UTF8URL(IN const CHAR* pText, OUT string& strResult);
+	// 将字符串编码成为UNICODE编码格式的URL;
+	static string EnCode_UNICODEURL(IN const CHAR* pText);	// 未完成该函数;
+
+	// 解码UTF-8编码格式的URL;
+	static string DeCode_URLUTF8(IN const CHAR* pURLText);
+	static void DeCode_URLUTF8(IN const CHAR* pURLText, OUT string& strResult);
+	// 解码GB2312编码格式的URL;
+	static string DeCode_URLGB2312(IN const CHAR* pURLText);
+	static void DeCode_URLGB2312(IN const CHAR* pURLText, OUT string& strResult);
+	// 解码UNICODE编码格式的URL;
+	static string DeCode_URLUNICODE(IN const CHAR* pURLText);
+	static void DeCode_URLUNICODE(IN const CHAR* pURLText, OUT string& strResult);
+};
+
+#endif

+ 306 - 0
TCL Copy Tool/TCL Copy Tool/ChassisConfigDlg.cpp

@@ -0,0 +1,306 @@
+// ChassisConfigDlg.cpp: 实现文件
+//
+
+#include "pch.h"
+#include "TCL Copy Tool.h"
+#include "ChassisConfigDlg.h"
+#include "afxdialogex.h"
+
+// CChassisConfigDlg 对话框
+
+IMPLEMENT_DYNAMIC(CChassisConfigDlg, CDialogEx)
+
+CChassisConfigDlg::CChassisConfigDlg(CWnd *pParent /*=nullptr*/)
+	: CDialogEx(IDD_CONFIG_DIALOG, pParent)
+{
+}
+
+CChassisConfigDlg::~CChassisConfigDlg()
+{
+}
+
+void CChassisConfigDlg::DoDataExchange(CDataExchange *pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_COMBO_CHASSIS, m_cb_chassis);
+	DDX_Control(pDX, IDC_CHECK_MTK_INIT, m_check_mtk_init);
+	DDX_Control(pDX, IDC_CHECK_WB_INIT, m_check_wb_init);
+	DDX_Control(pDX, IDC_CHECK_WRITE_PID, m_check_pid);
+	DDX_Control(pDX, IDC_CHECK_COPY_DID, m_check_did);
+	DDX_Control(pDX, IDC_CHECK_COPY_MAC, m_check_mac);
+	DDX_Control(pDX, IDC_CHECK_COPY_HDCP, m_check_hdcp);
+	DDX_Control(pDX, IDC_CHECK_COPY_ESN, m_check_esn);
+	DDX_Control(pDX, IDC_CHECK_COPY_WIDI, m_check_widi);
+	DDX_Control(pDX, IDC_CHECK_COPY_WIDEVINE, m_check_widevine);
+	DDX_Control(pDX, IDC_CHECK_COPY_HDCP2, m_check_hdcp2);
+	DDX_Control(pDX, IDC_CHECK_COPY_CIKEY, m_check_cikey);
+	DDX_Control(pDX, IDC_CHECK_COPY_CHANNEL, m_check_channel);
+	DDX_Control(pDX, IDC_CHECK_COPY_OSDLANG, m_check_osd_lang);
+	DDX_Control(pDX, IDC_CHECK_COPY_SHOPLANG, m_check_shop_lang);
+	DDX_Control(pDX, IDC_CHECK_COPY_WB, m_check_wb);
+}
+
+BEGIN_MESSAGE_MAP(CChassisConfigDlg, CDialogEx)
+ON_CBN_SELCHANGE(IDC_COMBO_CHASSIS, &CChassisConfigDlg::OnCbnSelchangeComboChassis)
+ON_BN_CLICKED(BTN_ADD_CHASSIS, &CChassisConfigDlg::OnBnClickedAddChassis)
+END_MESSAGE_MAP()
+
+// CChassisConfigDlg 消息处理程序
+
+BOOL CChassisConfigDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	SetDlgItemInt(EDIT_WARN_COUNT, 200);
+	// TODO:  在此添加额外的初始化
+	CWnd *pWnd = GetDlgItem(EDIT_CHASSIS_NAME);
+	if (Global::g_tConfig.mode < 2)
+	{ // 显示下拉框;
+		CRect rcWnd;
+		pWnd->ShowWindow(SW_HIDE);
+		pWnd->GetWindowRect(rcWnd);
+		ScreenToClient(rcWnd);
+		m_cb_chassis.MoveWindow(rcWnd);
+		m_cb_chassis.ShowWindow(SW_SHOW);
+		GetDlgItem(BTN_ADD_CHASSIS)->ShowWindow(SW_SHOW);
+		for (auto it : Global::g_tConfig.chassislist)
+		{
+			m_cb_chassis.AddString(it.first.c_str());
+		}
+#if SAVE_AUTO_ONLINE
+		if (!IsChassisExsit(Global::g_AutoOnlineChassis.name))
+			m_cb_chassis.AddString(Global::g_AutoOnlineChassis.name.c_str());
+		m_cb_chassis.SelectString(0, Global::g_AutoOnlineChassis.name.c_str());
+#else
+		m_cb_chassis.SelectString(0, Global::g_tConfig.chassis.c_str());
+#endif
+	}
+	
+#if SAVE_AUTO_ONLINE
+	if ( Global::g_tConfig.mode < 2 )
+		FillData2Wnd(Global::g_AutoOnlineChassis);
+	else if (Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis.c_str()) != Global::g_tConfig.chassislist.end())
+		FillData2Wnd(Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis.c_str())->second);
+#else
+	if (Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis.c_str()) != Global::g_tConfig.chassislist.end())
+	{
+		FillData2Wnd(Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis.c_str())->second);
+	}
+#endif
+
+	return TRUE; // return TRUE unless you set the focus to a control
+				 // 异常: OCX 属性页应返回 FALSE
+}
+
+void CChassisConfigDlg::OnOK()
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	CString strChassis;
+	if (GetDlgItem(BTN_ADD_CHASSIS)->IsWindowVisible())
+	{
+		int nCurSel = m_cb_chassis.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			m_cb_chassis.GetLBText(nCurSel, strChassis);
+		}
+	}
+	else
+	{
+		GetDlgItemText(EDIT_CHASSIS_NAME, strChassis);
+	}
+
+	if ( strChassis.IsEmpty() )
+	{
+		MessageBox(_T("Chassis name can't empty!"), _T("Warnnig"), MB_OK | MB_ICONERROR);
+		return;
+	}
+
+	SaveChange2Config();
+	CDialogEx::OnOK();
+}
+
+void CChassisConfigDlg::FillData2Wnd(Global::TChassis &chassis)
+{
+#if SAVE_AUTO_ONLINE
+	if (Global::g_tConfig.mode < 2)
+	{
+		SetDlgItemText(EDIT_CHASSIS_NAME, Global::g_AutoOnlineChassis.name.c_str());
+		SetDlgItemText(EDIT_URL, Global::g_AutoOnlineChassis.url.c_str());
+	}
+	else
+	{
+		SetDlgItemText(EDIT_CHASSIS_NAME, Global::g_tConfig.chassis.c_str());
+		SetDlgItemText(EDIT_URL, Global::g_tConfig.serverurl.c_str());
+	}
+#else
+	SetDlgItemText(EDIT_CHASSIS_NAME, Global::g_tConfig.chassis.c_str());
+	SetDlgItemText(EDIT_URL, Global::g_tConfig.serverurl.c_str());
+#endif
+	SetDlgItemInt(EDIT_WARN_COUNT, Global::g_tConfig.warncount);
+	// check box
+	m_check_mtk_init.SetCheck(chassis.IsMTKInit);
+	m_check_wb_init.SetCheck(chassis.IsWBInit);
+	m_check_pid.SetCheck(chassis.IsWritePID);
+	m_check_did.SetCheck(chassis.IsCopyDID);
+	m_check_mac.SetCheck(chassis.IsCopyMAC);
+	m_check_hdcp.SetCheck(chassis.IsCopyKEY);
+	m_check_esn.SetCheck(chassis.IsCopyESN);
+	m_check_widi.SetCheck(chassis.IsCopyWiDi);
+	m_check_widevine.SetCheck(chassis.IsCopyWidevine);
+	m_check_hdcp2.SetCheck(chassis.IsCopyKEY2_2);
+	m_check_cikey.SetCheck(chassis.IsCopyCikey);
+	m_check_channel.SetCheck(chassis.IsCopyChannel);
+	m_check_osd_lang.SetCheck(chassis.IsOsdLanguage);
+	m_check_shop_lang.SetCheck(chassis.IsShopLanguage);
+	m_check_wb.SetCheck(chassis.IsCopyWB);
+
+	SetDlgItemText(IDC_EDIT_WBFILE, chassis.WBFile.c_str());
+	SetDlgItemText(IDC_EDIT_CHANNEL, chassis.Channel.c_str());
+	SetDlgItemText(IDC_EDIT_OSD_LANG, chassis.OsdLanguage.c_str());
+	SetDlgItemText(IDC_EDIT_SHOP_LANG, chassis.ShopLanguage.c_str());
+	SetDlgItemInt(IDC_EDIT_PID, chassis.ProjectID);
+	SetDlgItemText(IDC_EDIT_DID_TYPE, chassis.ClientType.c_str());
+	SetDlgItemText(IDC_EDIT_MAC_TYPE, chassis.MACType.c_str());
+	SetDlgItemText(IDC_EDIT_HDCP_TYPE, chassis.HDCPKeyType.c_str());
+	SetDlgItemText(IDC_EDIT_HDCP2_TYPE, chassis.HDCPKey22Type.c_str());
+	SetDlgItemText(IDC_EDIT_WIDI_TYPE, chassis.WiDiType.c_str());
+	SetDlgItemText(IDC_EDIT_WIDEVINE_TYPE, chassis.WidevineType.c_str());
+	SetDlgItemText(IDC_EDIT_ESN_TYPE, chassis.ESNType.c_str());
+	SetDlgItemText(IDC_EDIT_CIKEY_TYPE, chassis.CIKeyType.c_str());
+
+	SetDlgItemInt(EDIT_DELAY, chassis.Delay);
+	SetDlgItemText(EDIT_CHECKSTRING, chassis.CheckString.c_str());
+}
+
+void CChassisConfigDlg::SaveChange2Config()
+{
+	UpdateData();
+	CString strChassis = _T(""), strURL = _T("");
+	GetDlgItemText(EDIT_URL, strURL);
+	int WarnCount = GetDlgItemInt(EDIT_WARN_COUNT);
+	if (GetDlgItem(BTN_ADD_CHASSIS)->IsWindowVisible())
+	{
+		int nCurSel = m_cb_chassis.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			m_cb_chassis.GetLBText(nCurSel, strChassis);
+		}
+	}
+	else
+	{
+		GetDlgItemText(EDIT_CHASSIS_NAME, strChassis);
+	}
+	Global::g_tConfig.warncount = WarnCount;
+	Global::g_tConfig.serverurl = strURL.GetString();
+
+	Global::TChassis tchassis;
+	// check box
+	tchassis.IsWBInit = m_check_wb_init.GetCheck();
+	tchassis.IsWritePID = m_check_pid.GetCheck();
+	tchassis.IsCopyDID = m_check_did.GetCheck();
+	tchassis.IsCopyMAC = m_check_mac.GetCheck();
+	tchassis.IsCopyKEY = m_check_hdcp.GetCheck();
+	tchassis.IsCopyESN = m_check_esn.GetCheck();
+	tchassis.IsCopyWiDi = m_check_widi.GetCheck();
+	tchassis.IsCopyWidevine = m_check_widevine.GetCheck();
+	tchassis.IsCopyKEY2_2 = m_check_hdcp2.GetCheck();
+	tchassis.IsCopyCikey = m_check_cikey.GetCheck();
+	tchassis.IsCopyChannel = m_check_channel.GetCheck();
+	tchassis.IsOsdLanguage = m_check_osd_lang.GetCheck();
+	tchassis.IsShopLanguage = m_check_shop_lang.GetCheck();
+	tchassis.IsCopyWB = m_check_wb.GetCheck();
+	tchassis.IsMTKInit = m_check_mtk_init.GetCheck();
+
+	CString strData = _T("");
+	GetDlgItemText(IDC_EDIT_WBFILE, strData);
+	tchassis.WBFile = strData.GetString();
+	GetDlgItemText(IDC_EDIT_CHANNEL, strData);
+	tchassis.Channel = strData.GetString();
+	GetDlgItemText(IDC_EDIT_OSD_LANG, strData);
+	tchassis.OsdLanguage = strData.GetString();
+	GetDlgItemText(IDC_EDIT_SHOP_LANG, strData);
+	tchassis.ShopLanguage = strData.GetString();
+	tchassis.ProjectID = GetDlgItemInt(IDC_EDIT_PID);
+	GetDlgItemText(IDC_EDIT_DID_TYPE, strData);
+	tchassis.ClientType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_MAC_TYPE, strData);
+	tchassis.MACType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_HDCP_TYPE, strData);
+	tchassis.HDCPKeyType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_HDCP2_TYPE, strData);
+	tchassis.HDCPKey22Type = strData.GetString();
+	GetDlgItemText(IDC_EDIT_WIDI_TYPE, strData);
+	tchassis.WiDiType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_WIDEVINE_TYPE, strData);
+	tchassis.WidevineType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_ESN_TYPE, strData);
+	tchassis.ESNType = strData.GetString();
+	GetDlgItemText(IDC_EDIT_CIKEY_TYPE, strData);
+	tchassis.CIKeyType = strData.GetString();
+
+	tchassis.Delay = GetDlgItemInt(EDIT_DELAY);
+	GetDlgItemText(EDIT_CHECKSTRING, strData);
+	tchassis.CheckString = strData.GetString();
+
+	// 此Chassis是否存在于列表中;
+	std::map<std::string, Global::TChassis>::iterator it = Global::g_tConfig.chassislist.find(strChassis.GetString());
+	if (it != Global::g_tConfig.chassislist.end())
+	{
+		it->second = tchassis;
+	}
+	else
+	{
+		Global::g_tConfig.chassislist.insert(pair<std::string, Global::TChassis>(strChassis.GetString(), tchassis));
+	}
+
+	Global::SetConfig();
+}
+
+BOOL CChassisConfigDlg::IsChassisExsit(std::string chassis)
+{
+	BOOL bExsit = FALSE;
+	CString strChassis;
+	int nCount = m_cb_chassis.GetCount();
+	for ( int i= 0; i < nCount; i++ )
+	{
+		m_cb_chassis.GetLBText(i, strChassis);
+		if ( _tcsicmp(chassis.c_str(), strChassis.GetString() ) == 0 )
+		{
+			bExsit = TRUE;
+			break;
+		}
+	}
+
+	return bExsit;
+}
+
+void CChassisConfigDlg::OnCbnSelchangeComboChassis()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	int nCurSel = m_cb_chassis.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		CString strChassis;
+		m_cb_chassis.GetLBText(nCurSel, strChassis);
+		FillData2Wnd(Global::g_tConfig.chassislist.find(strChassis.GetString())->second);
+	}
+}
+
+void CChassisConfigDlg::OnBnClickedAddChassis()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	if (Global::g_tConfig.mode < 2)
+	{
+		// 隐藏combobox;
+		int nCurSel = m_cb_chassis.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			CString strChassis;
+			m_cb_chassis.GetLBText(nCurSel, strChassis);
+			SetDlgItemText(EDIT_CHASSIS_NAME, strChassis);
+		}
+		m_cb_chassis.ShowWindow(SW_HIDE);
+		GetDlgItem(EDIT_CHASSIS_NAME)->ShowWindow(SW_SHOW);
+		GetDlgItem(BTN_ADD_CHASSIS)->ShowWindow(SW_HIDE);
+	}
+}

+ 48 - 0
TCL Copy Tool/TCL Copy Tool/ChassisConfigDlg.h

@@ -0,0 +1,48 @@
+#pragma once
+#include "Global.h"
+
+
+// CChassisConfigDlg 对话框
+
+class CChassisConfigDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CChassisConfigDlg)
+
+public:
+	CChassisConfigDlg(CWnd* pParent = nullptr);   // 标准构造函数
+	virtual ~CChassisConfigDlg();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_CONFIG_DIALOG };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	virtual void OnOK();
+	CComboBox m_cb_chassis;
+	void FillData2Wnd(Global::TChassis &chassis);
+	void SaveChange2Config();
+	BOOL IsChassisExsit(std::string chassis);
+	afx_msg void OnCbnSelchangeComboChassis();
+	CButton m_check_mtk_init;
+	CButton m_check_wb_init;
+	CButton m_check_pid;
+	CButton m_check_did;
+	CButton m_check_mac;
+	CButton m_check_hdcp;
+	CButton m_check_esn;
+	CButton m_check_widi;
+	CButton m_check_widevine;
+	CButton m_check_hdcp2;
+	CButton m_check_cikey;
+	CButton m_check_channel;
+	CButton m_check_osd_lang;
+	CButton m_check_shop_lang;
+	CButton m_check_wb;
+	afx_msg void OnBnClickedAddChassis();
+};

+ 202 - 0
TCL Copy Tool/TCL Copy Tool/Config.json

@@ -0,0 +1,202 @@
+{
+	"COM":	"COM4",
+	"server-url":	"http://huizhou.idmanage.qhmoka.com/IDManage",
+	"Chassis":	"IDX141819B",
+	"Mode":	2,
+	"WarnCount":	200,
+	"Baudrate":	"115200",
+	"Channel":	[{
+			"Algeria":	"19"
+		}, {
+			"Araby":	"10"
+		}, {
+			"Benne":	"0F"
+		}, {
+			"CVT":	"1A"
+		}, {
+			"Condor":	"13"
+		}, {
+			"Egypt":	"0C"
+		}, {
+			"Eltholathia":	"11"
+		}, {
+			"HZ":	"01"
+		}, {
+			"Indonesia":	"0A"
+		}, {
+			"JAC":	"0D"
+		}, {
+			"LEXUAN":	"17"
+		}, {
+			"LIXIANG":	"16"
+		}, {
+			"Mexico":	"1D"
+		}, {
+			"NM":	"05"
+		}, {
+			"ODM":	"06"
+		}, {
+			"ORION":	"1C"
+		}, {
+			"PKV":	"15"
+		}, {
+			"Pakistan":	"0E"
+		}, {
+			"Philippines":	"09"
+		}, {
+			"Poland":	"02"
+		}, {
+			"RV":	"1E"
+		}, {
+			"Russia":	"0B"
+		}, {
+			"SEMP":	"1F"
+		}, {
+			"SouthAfrica":	"1B"
+		}, {
+			"TOSHIBA":	"18"
+		}, {
+			"TTET":	"03"
+		}, {
+			"Thailand":	"08"
+		}, {
+			"Tunisia":	"12"
+		}, {
+			"UPAC":	"14"
+		}, {
+			"Vietnam":	"07"
+		}, {
+			"WX":	"04"
+		}],
+	"Language":	[{
+			"阿拉伯4":	"61 72"
+		}, {
+			"阿拉伯6":	"61 72 61"
+		}, {
+			"俄语4":	"72 75"
+		}, {
+			"俄语6":	"72 75 73"
+		}, {
+			"法语4":	"66 72"
+		}, {
+			"法语6":	"66 72 65"
+		}, {
+			"韩语4":	"6B 6F"
+		}, {
+			"韩语6":	"6B 6F 72"
+		}, {
+			"葡萄牙4":	"70 74"
+		}, {
+			"葡萄牙6":	"70 6F 72"
+		}, {
+			"西语4":	"65 73"
+		}, {
+			"西语6":	"73 70 61"
+		}, {
+			"英语4":	"65 6E"
+		}, {
+			"英语6":	"65 6E 67"
+		}],
+	"KeyFolder":	[{
+			"CIKeyFolder":	"./DataDir/CIKEY"
+		}, {
+			"DIDFolder":	"./DataDir/DeviceID"
+		}, {
+			"ESNFolder":	"./DataDir/ESN"
+		}, {
+			"HDCPKEY22Folder":	"./DataDir/HDCPKEY22"
+		}, {
+			"HDCPKey2_3Folder":	"./DataDir/HDCPKey2_3"
+		}, {
+			"KEYFolder":	"./DataDir/HDCPKEY"
+		}, {
+			"MACFolder":	"./DataDir/MAC"
+		}, {
+			"MGKKeyFolder":	"./DataDir/MGKKEY"
+		}, {
+			"NovaTakHDCPFolder":	"./DataDir/NovaTakHDCP"
+		}, {
+			"WBFolder":	"./DataDir/WB"
+		}, {
+			"WiDiFolder":	"./DataDir/WiDi"
+		}, {
+			"WidevineFolder":	"./DataDir/Widevine"
+		}],
+	"Chassis-list":	[{
+			"name":	"IDX141819B",
+			"IsCopyDID":	false,
+			"IsCopyMAC":	true,
+			"IsCopyKEY":	false,
+			"IsCopyESN":	false,
+			"IsCopyWiDi":	false,
+			"IsCopyWidevine":	false,
+			"IsCopyKEY2_2":	false,
+			"IsCopyKEY2_3":	true,
+			"IsCopyCikey":	false,
+			"IsCopyChannel":	false,
+			"IsCopyWB":	false,
+			"IsDisplayClientType":	true,
+			"IsWritePID":	false,
+			"IsWBInit":	false,
+			"IsMTKInit":	false,
+			"IsOsdLanguage":	false,
+			"IsShopLanguage":	false,
+			"IsCopyClientType":	true,
+			"IsMGKKeyEnb":	true,
+			"IsNovaTakHDCPEnb":	true,
+			"ProjectID":	4,
+			"Delay":	500,
+			"Channel":	"",
+			"WBFile":	"",
+			"CheckString":	"",
+			"ClientType":	"tcl_unknown_model",
+			"MACType":	"TCL",
+			"HDCPKeyType":	"RealTek",
+			"HDCPKey22Type":	"",
+			"HDCPKey23Type":	"",
+			"ESNType":	"",
+			"WiDiType":	"",
+			"WidevineType":	"Global_RT41",
+			"CIKeyType":	"",
+			"MGKKeyType":	"",
+			"NovaTakHDCPType":	""
+		}, {
+			"name":	"other",
+			"IsCopyDID":	true,
+			"IsCopyMAC":	true,
+			"IsCopyKEY":	true,
+			"IsCopyESN":	false,
+			"IsCopyWiDi":	false,
+			"IsCopyWidevine":	false,
+			"IsCopyKEY2_2":	false,
+			"IsCopyKEY2_3":	true,
+			"IsCopyCikey":	false,
+			"IsCopyChannel":	true,
+			"IsCopyWB":	false,
+			"IsDisplayClientType":	true,
+			"IsWritePID":	false,
+			"IsWBInit":	true,
+			"IsMTKInit":	true,
+			"IsOsdLanguage":	false,
+			"IsShopLanguage":	false,
+			"IsCopyClientType":	true,
+			"IsMGKKeyEnb":	true,
+			"IsNovaTakHDCPEnb":	true,
+			"ProjectID":	0,
+			"Delay":	500,
+			"Channel":	"",
+			"WBFile":	"",
+			"CheckString":	"Factory auto test loop start",
+			"ClientType":	"",
+			"MACType":	"",
+			"HDCPKeyType":	"",
+			"HDCPKey22Type":	"",
+			"HDCPKey23Type":	"",
+			"ESNType":	"",
+			"WiDiType":	"",
+			"WidevineType":	"",
+			"CIKeyType":	"",
+			"MGKKeyType":	"",
+			"NovaTakHDCPType":	""
+		}]
+}

+ 84 - 0
TCL Copy Tool/TCL Copy Tool/CritSection.h

@@ -0,0 +1,84 @@
+#ifndef __CRITSECTION_20160221__
+#define __CRITSECTION_20160221__
+
+// ÁÙ½çÖµ;
+class ThreadSection
+{
+public:
+	ThreadSection(){
+		HRESULT hr = Init();
+		(hr);
+	}
+
+	~ThreadSection(){
+		DeleteCriticalSection(&_CriticalSection);
+	}
+
+	bool Lock()
+	{
+		bool result = false;
+		__try
+		{
+			EnterCriticalSection(&_CriticalSection);
+			result = true;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+		}
+		return result;
+	}
+
+	bool Unlock()
+	{
+		bool result = false;
+		__try
+		{
+			LeaveCriticalSection(&_CriticalSection);
+			result = true;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+		}
+		return result;
+	}
+
+private:
+	HRESULT Init() throw()
+	{
+		HRESULT hRes = E_FAIL;
+		__try
+		{
+			InitializeCriticalSection(&_CriticalSection);
+			hRes = S_OK;
+		}
+		__except (STATUS_NO_MEMORY == GetExceptionCode())
+		{
+			hRes = E_OUTOFMEMORY;
+		}
+		return hRes;
+	}
+
+	ThreadSection(const ThreadSection & tSection);
+	ThreadSection &operator=(const ThreadSection & tSection);
+	CRITICAL_SECTION _CriticalSection;
+};
+
+
+class AutoThreadSection
+{
+public:
+	AutoThreadSection(IN ThreadSection* pSection){
+		_pSection = pSection;
+		_pSection->Lock();
+	}
+
+	~AutoThreadSection(){
+		_pSection->Unlock();
+	}
+private:
+	AutoThreadSection(const AutoThreadSection & tSection);
+	AutoThreadSection &operator=(const AutoThreadSection & tSection);
+	ThreadSection * _pSection;
+};
+
+#endif //__CRITSECTION_20160221__

+ 555 - 0
TCL Copy Tool/TCL Copy Tool/CurlClient.cpp

@@ -0,0 +1,555 @@
+#include "pch.h"
+#include "CurlClient.h"
+#include "CharEncoding.h"
+
+
+CCurlClient::CCurlClient(void)
+{
+	m_bDebug = FALSE;
+	m_headers = NULL;
+}
+
+CCurlClient::~CCurlClient(void)
+{
+	// 释放curl的全局对象;
+	curl_global_cleanup(); 
+}
+
+INT CCurlClient::Initialize()
+{
+	// 初始化全局调用模式;
+	CURLcode res = ::curl_global_init( CURL_GLOBAL_ALL );
+	if( CURLE_OK != res ) 
+	{
+		fprintf( stderr, "curl_global_init failed: %d \n", res ); 
+		return -1;
+	}
+
+	return 0;
+}
+
+static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)   
+{   
+	if(itype == CURLINFO_TEXT)   
+	{   
+		//TRACE("[TEXT]%s\n", pData); 
+		LOG4C((LOG_WARN, "[TEXT]%s\n", pData));   
+	}   
+	else if(itype == CURLINFO_HEADER_IN)   
+	{   
+		//TRACE("[HEADER_IN]%s\n", pData); 
+		LOG4C((LOG_WARN, "[HEADER_IN]%s\n", pData));
+	}   
+	else if(itype == CURLINFO_HEADER_OUT)   
+	{   
+		//TRACE("[HEADER_OUT]%s\n", pData);   
+		LOG4C((LOG_WARN, "[HEADER_OUT]%s\n", pData));
+	}   
+	else if(itype == CURLINFO_DATA_IN)   
+	{   
+		//TRACE("[DATA_IN]%s\n", pData);   
+		LOG4C((LOG_WARN, "[DATA_IN]%s\n", pData));
+	}   
+	else if(itype == CURLINFO_DATA_OUT)   
+	{   
+		//TRACE("[DATA_OUT]%s\n", pData);   
+		LOG4C((LOG_WARN, "[DATA_OUT]%s\n", pData));
+	}   
+	return 0;   
+}   
+
+size_t CCurlClient::OnWriteData(const void *ptr, size_t size, size_t nmemb, std::string *stream)   
+{   
+	if( NULL == stream || NULL == ptr )
+		return -1;
+
+	stream->append((char*)ptr, size * nmemb);   
+	return nmemb;   
+}   
+
+int CCurlClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse, long time_out /*= 3*/)
+{   
+	CURLcode res;   
+	CURL* curl = curl_easy_init();   
+	if(NULL == curl)   
+	{   
+		return CURLE_FAILED_INIT;   
+	}   
+	if(m_bDebug)   
+	{// 是否开启调试日志输出;   
+		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);   
+		curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);   
+	}   
+	// 设置URL地址;
+	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());   
+	// 设置POST方式;
+	curl_easy_setopt(curl, CURLOPT_POST, 1);   
+	// 设置POST参数;
+	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
+    // 设置回调函数-读取;	
+	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);   
+	// 设置回调函数-写入;
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);   
+	// 设置回调函数-写入的缓存区;
+	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);   
+	// 设置(多线程下,只是尽量减少)无签名;
+	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);   
+	// 设置连接超时值(单位毫秒);
+	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30000); 
+	// 设置操作超时值(单位毫秒);
+	curl_easy_setopt(curl, CURLOPT_TIMEOUT, time_out);
+	// 设置头;
+	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers);
+
+	// 执行POST提交;
+	res = curl_easy_perform(curl);   
+	
+	// 释放资源;
+	curl_easy_cleanup(curl); 
+	//curl_global_cleanup();
+	ClearHeaders(); /* free the header list */
+
+	return res;   
+}  
+
+int CCurlClient::Post(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out /*= 3*/)
+{
+	if ( lpUrl == NULL || lpPost == NULL )
+		return CURLE_FAILED_INIT;
+
+	string strUrl;
+	string strPost;
+	string strResponse;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
+	CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost);
+
+	int res = Post(strUrl, strPost, strResponse) ;
+	if ( CURLE_OK == res )
+	{
+		CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
+		return CURLE_OK;
+	}
+
+	return res;
+#else
+	strUrl = lpUrl;
+	strPost = lpPost;
+	int res = Post(strUrl, strPost, strResponse, time_out) ;
+	if ( CURLE_OK == res )
+	{
+		sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Post(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, long time_out /*= 3*/)
+{
+	if ( strUrl.IsEmpty() || strPost.IsEmpty() )
+		return CURLE_FAILED_INIT;
+
+	string url;
+	string post;
+	string response;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
+	CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post);
+
+	int res = Post(url, post, response) ;
+	if ( CURLE_OK == res )
+	{
+		WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
+		if ( pResult )
+		{
+			strResponse = pResult;
+			delete []pResult;
+			pResult = NULL;
+			return CURLE_OK;
+		}
+	}
+
+	return res;
+#else
+	url = strUrl.GetString();
+	post = strPost.GetString();
+	int res = Post(url, post, response, time_out) ;
+	if ( CURLE_OK == res )
+	{
+		strResponse = response.c_str();
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Get(const std::string & strUrl, std::string & strResponse, long time_out /*= 3*/)
+{   
+	CURLcode res;   
+	CURL* curl = curl_easy_init();   
+	if(NULL == curl)   
+	{   
+		return CURLE_FAILED_INIT;   
+	}   
+	if(m_bDebug)   
+	{   
+		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);   
+		curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);   
+	}   
+
+	// 设置URL地址;
+	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());   
+	// 设置回调函数-读取;
+	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);   
+	// 设置回调函数-写入;
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);   
+	// 设置回调函数-写入的缓存区;
+	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);   
+	/**  
+	* 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。  
+	* 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。  
+	*/  
+	// 设置(多线程下,只是尽量减少)无签名;	
+	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);   
+	// 设置连接超时值;
+	curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000);
+	// 设置超时值;
+	curl_easy_setopt(curl,CURLOPT_TIMEOUT, time_out);
+	// 设置头;
+	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers);
+
+	res = curl_easy_perform(curl);   
+	curl_easy_cleanup(curl);
+	//curl_global_cleanup();
+	ClearHeaders(); /* free the header list */
+
+	return res;   
+}  
+
+int CCurlClient::Get(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out /*= 3*/)
+{
+	if ( lpUrl == NULL )
+		return CURLE_FAILED_INIT;
+
+	string strUrl;
+	string strResponse;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
+
+	int res = Get(strUrl, strResponse) ;
+	if ( CURLE_OK == res )
+	{
+		CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
+		return CURLE_OK;
+	}
+
+	return res;
+#else
+	strUrl = lpUrl;
+	int res = Get(strUrl, strResponse, time_out) ;
+	if ( CURLE_OK == res )
+	{
+		sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Get(IN CString& strUrl, OUT CString& strResponse, long time_out /*= 3*/)
+{
+	if ( strUrl.IsEmpty() )
+		return CURLE_FAILED_INIT;
+
+	string url;
+	string post;
+	string response;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
+
+	int res = Get(url, response) ;
+	if ( CURLE_OK == res )
+	{
+		WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
+		if ( pResult )
+		{
+			strResponse = pResult;
+			delete []pResult;
+			pResult = NULL;
+			return CURLE_OK;
+		}
+	}
+
+	return res;
+#else
+	url = strUrl.GetString();
+	int res = Get(url, response, time_out) ;
+	if ( CURLE_OK == res )
+	{
+		strResponse = response.c_str();
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath, long time_out /*= 3*/)
+{   
+	CURLcode res;   
+	CURL* curl = curl_easy_init();   
+	if(NULL == curl)   
+	{   
+		return CURLE_FAILED_INIT;   
+	}   
+	if(m_bDebug)   
+	{   
+		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);   
+		curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);   
+	}   
+	
+	// 设置URL地址;
+	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());   
+	// 设置POST提交方式;
+	curl_easy_setopt(curl, CURLOPT_POST, 1);   
+	// 设置POST参数;
+	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());   
+	// 设置回调函数-读取;
+	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);   
+	// 设置回调函数-写入;
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);   
+	// 设置回调函数-写入的缓存区;
+	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);   
+	// 设置;
+	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);   
+	if(NULL == pCaPath || pCaPath[0] == '\0')   
+	{   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);   
+	}   
+	else   
+	{   
+		//缺省情况就是PEM,所以无需设置,另外支持DER   
+		//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);   
+		curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);   
+	}   
+	// 设置连接超时值;
+	curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000);
+	// 设置超时值;
+	curl_easy_setopt(curl,CURLOPT_TIMEOUT, time_out);
+	// 设置头;
+	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers);
+	
+	// 执行POST提交;
+	res = curl_easy_perform(curl);   
+	
+	// 释放资源;
+	curl_easy_cleanup(curl); 
+	//curl_global_cleanup();
+	ClearHeaders(); /* free the header list */
+
+	return res;   
+}  
+
+int CCurlClient::Posts(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */, long time_out /*= 3*/)
+{
+	if ( lpUrl == NULL || lpPost == NULL )
+		return CURLE_FAILED_INIT;
+
+	string strUrl;
+	string strPost;
+	string strCapath;
+	string strResponse;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
+	CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost);
+	CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath);
+
+	int res = Posts(strUrl, strPost, strResponse, strCapath.c_str()) ;
+	if ( CURLE_OK == res )
+	{
+		CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
+		return CURLE_OK;
+	}
+
+	return res;
+#else
+	strUrl = lpUrl;
+	strPost = lpPost;
+	strCapath = lpCaPath;
+	int res = Posts(strUrl, strPost, strResponse, strCapath.c_str(), time_out ) ;
+	if ( CURLE_OK == res )
+	{
+		sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Posts(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */, long time_out /*= 3*/)
+{
+	if ( strUrl.IsEmpty() || strPost.IsEmpty() )
+		return CURLE_FAILED_INIT;
+
+	string url;
+	string post;
+	string capth;
+	string response;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
+	CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post);
+	CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth);
+
+	int res = Posts(url, post, response, capth.c_str()) ;
+	if ( CURLE_OK == res )
+	{
+		WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
+		if ( pResult )
+		{
+			strResponse = pResult;
+			delete []pResult;
+			pResult = NULL;
+			return CURLE_OK;
+		}
+	}
+
+	return res;
+#else
+	url = strUrl.GetString();
+	post = strPost.GetString();
+	capth = strCaPath.GetString();
+	int res = Posts(url, post, response, capth.c_str(), time_out) ;
+	if ( CURLE_OK == res )
+	{
+		strResponse = response.c_str();
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath, long time_out /*= 3*/)
+{   
+	CURLcode res;   
+	CURL* curl = curl_easy_init();   
+	if(NULL == curl)   
+	{   
+		return CURLE_FAILED_INIT;   
+	}   
+	if(m_bDebug)   
+	{   
+		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);   
+		curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);   
+	}   
+	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());   
+	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);   
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);   
+	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);   
+	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);   
+	if(NULL == pCaPath || pCaPath[0] == '\0')   
+	{   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);   
+	}   
+	else   
+	{   
+		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);   
+		curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);   
+	}   
+	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5000);   
+	curl_easy_setopt(curl, CURLOPT_TIMEOUT, time_out);
+	// 设置头;
+	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headers);
+
+	res = curl_easy_perform(curl);   
+	curl_easy_cleanup(curl); 
+	//curl_global_cleanup();
+	ClearHeaders(); /* free the header list */
+
+	return res;   
+} 
+
+int CCurlClient::Gets(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */, long time_out /*= 3*/)
+{
+	if ( lpUrl == NULL )
+		return CURLE_FAILED_INIT;
+
+	string strUrl;
+	string strCapath;
+	string strResponse;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
+	CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath);
+
+	int res = Gets(strUrl, strResponse, strCapath.c_str()) ;
+	if ( CURLE_OK == res )
+	{
+		CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
+		return CURLE_OK;
+	}
+
+	return res;
+#else
+	strUrl = lpUrl;
+	strCapath = lpCaPath;
+	int res = Gets(strUrl, strResponse, strCapath.c_str(), time_out) ;
+	if ( CURLE_OK == res )
+	{
+		sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+int CCurlClient::Gets(IN CString& strUrl, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */, long time_out /*= 3*/)
+{
+	if ( strUrl.IsEmpty() )
+		return CURLE_FAILED_INIT;
+
+	string url;
+	string post;
+	string capth;
+	string response;
+#ifdef UNICODE
+	CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
+	CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth);
+
+	int res = Gets(url, response, capth.c_str()) ;
+	if ( CURLE_OK == res )
+	{
+		WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
+		if ( pResult )
+		{
+			strResponse = pResult;
+			delete []pResult;
+			pResult = NULL;
+			return CURLE_OK;
+		}
+	}
+
+	return res;
+#else
+	url = strUrl.GetString();
+	capth = strCaPath.GetString();
+	int res = Gets(url, response, capth.c_str(), time_out) ;
+	if ( CURLE_OK == res )
+	{
+		strResponse = response.c_str();
+		return CURLE_OK;
+	}
+	return res;
+#endif
+}
+
+void CCurlClient::SetDebug(bool bDebug)   
+{   
+	m_bDebug = bDebug;   
+}   
+
+void CCurlClient::SetHeaders(const std::string headers)
+{
+	m_headers = curl_slist_append(m_headers, headers.c_str());
+}

+ 88 - 0
TCL Copy Tool/TCL Copy Tool/CurlClient.h

@@ -0,0 +1,88 @@
+#ifndef __CURLCLIENT__
+#define __CURLCLIENT__
+
+#include <string>
+#include <vector>
+using namespace std;
+#include "curl/curl.h"
+#include "curl/easy.h"
+#include "curl/curlver.h"
+
+#ifndef _UNICODE
+typedef string TString;
+#else
+typedef wstring TString;
+#endif
+
+#pragma once
+
+class  CCurlClient
+{
+public:
+	CCurlClient(void);
+	~CCurlClient(void);
+
+public:
+	INT Initialize();
+	/**  
+	* @brief HTTP POST请求  
+	* @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com  
+	* @param strPost 输入参数,使用如下格式para1=val1?2=val2&…  
+	* @param strResponse 输出参数,返回的内容  
+	* @return 返回是否Post成功  
+	*/   
+	int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse, long time_out = 3000);
+	int Post(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out = 3000);
+	int Post(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, long time_out = 3000);
+
+	/**  
+	* @brief HTTP GET请求  
+	* @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com  
+	* @param strResponse 输出参数,返回的内容  
+	* @return 返回是否Post成功  
+	*/   
+	int Get(const std::string & strUrl, std::string & strResponse, long time_out = 3000);
+	int Get(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, long time_out = 3000);
+	int Get(IN CString& strUrl, OUT CString& strResponse, long time_out = 3000);
+
+	/**  
+	* @brief HTTPS POST请求,无证书版本  
+	* @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com  
+	* @param strPost 输入参数,使用如下格式para1=val1?2=val2&…  
+	* @param strResponse 输出参数,返回的内容  
+	* @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.  
+	* @return 返回是否Post成功  
+	*/   
+	int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL, long time_out = 3000);
+	int Posts(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath = NULL, long time_out = 3000);
+	int Posts(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, IN const CString& strCaPath = _T(""), long time_out = 3000);
+
+	/**  
+	* @brief HTTPS GET请求,无证书版本  
+	* @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com  
+	* @param strResponse 输出参数,返回的内容  
+	* @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.  
+	* @return 返回是否Post成功  
+	*/   
+	int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL, long time_out = 3000);
+	int Gets(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath = NULL, long time_out = 3000);
+	int Gets(IN CString& strUrl, OUT CString& strResponse, IN const CString& strCaPath = _T(""), long time_out = 3000);
+
+public:   
+	void SetDebug(bool bDebug); 
+	void SetHeaders(const std::string headers);
+	void ClearHeaders()
+	{
+		curl_slist_free_all(m_headers);
+		m_headers = NULL;
+	}
+
+
+private:   
+	// 是否启用调试输出;
+	BOOL	m_bDebug;	
+	struct curl_slist *m_headers;
+	static size_t OnWriteData(const void *ptr, size_t size, size_t nmemb, std::string *stream);
+};
+
+#endif

+ 836 - 0
TCL Copy Tool/TCL Copy Tool/Global.cpp

@@ -0,0 +1,836 @@
+#include "pch.h"
+#include "Global.h"
+#include <SetupAPI.h>
+#include <InitGuid.h>
+#include <WinIoCtl.h>
+#pragma comment(lib, "SetupAPI.lib")
+
+namespace Global
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 全局变量;
+	BOOL g_bTestHost = FALSE;
+	TCHAR g_szCurModuleDir[MAX_PATH] = { 0 };
+	TCHAR g_szCurModulePath[MAX_PATH] = { 0 };
+	TCHAR g_szFna[MAX_PATH] = { 0 };
+	TCHAR g_szConfig[MAX_PATH] = { 0 };
+	std::string g_strMacs;
+	std::vector<MacAddress> g_vtMac;
+	TConfig g_tConfig;
+	Global::TChassis g_AutoOnlineChassis;
+
+	// usb;
+	static GUID UsbClassGuid = { 0xA5DCBF10L, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
+	// mac;
+	static GUID MacClassGuid = { 0xAD498944, 0x762F, 0x11D0, {0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C} };
+	// hdd;
+	static GUID HDDClassGuid = { 0x53F56307, 0xB6BF, 0x11D0, {0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B} };
+
+	//////////////////////////////////////////////////////////////////////////
+	// 全局函数;
+	/************************************************************************/
+	/*  函数:WriteTextLog[7/28/2009 Jeff];
+			/*  描述:写文本日志;
+			/*  参数:;
+			/*  	[IN] :;
+			/*  返回:void;
+			/*  注意:;
+			/*  示例:;
+			/*
+			/*  修改:;
+			/*  日期:;
+			/*  内容:;
+			/************************************************************************/
+	void WriteTextLog(const TCHAR* format, ...)
+	{
+		// 将日志内容输入到文件中;
+		// 获取今年年份;
+		__time64_t gmt = time(NULL); // 获取当前日历时间(1900-01-01开始的Unix时间戳);
+		struct tm gmtm = { 0 };
+		localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
+
+		// 解析出日志路径;
+		TCHAR szlogpath[MAX_PATH] = { 0 };
+		_stprintf_s(szlogpath, _T("%slog\\Serial Port Log %02d%02d.txt"), g_szCurModuleDir, gmtm.tm_mon + 1, gmtm.tm_mday);
+		// 打开或创建文件;
+		FILE* fp = NULL;
+		//if (_taccess(szlogpath, 0) != -1)
+#ifndef UNICODE
+		if (_access(szlogpath, 0) != -1)
+#else
+		if (_taccess(szlogpath, 0) != -1)
+#endif
+		{ // 存在;
+			if (0 == _tfopen_s(&fp, szlogpath, _T("a+")))
+				// 移动到末尾;
+				fseek(fp, 0, SEEK_END);
+		}
+		else
+		{ // 不存在;
+			_tfopen_s(&fp, szlogpath, _T("w+"));
+		}
+
+		if (fp == NULL)
+			return;
+
+		// 格式化前设置语言区域;
+		TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
+		_tsetlocale(LC_CTYPE, _T("chs")); //设定中文;
+
+		// 格式化日志内容;
+		va_list args = NULL;
+		int len = 0;
+		TCHAR* buffer = NULL;
+		va_start(args, format);
+		// _vscprintf doesn't count. terminating '\0'
+		len = _vsctprintf(format, args) + 1;
+		buffer = (TCHAR*)malloc(len * sizeof(TCHAR));
+		_vstprintf_s(buffer, len, format, args);
+		_ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year + 1990, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, buffer);
+
+		// 关闭文件,释放资源并设置回原语言区域;
+		free(buffer);
+		fclose(fp);
+		_tsetlocale(LC_CTYPE, old_locale);
+		free(old_locale); //还原区域设定;
+	}
+
+	// 读取配置文件-预留;
+	void GetConfig()
+	{
+		// 读取文件;
+		FILE* pf = NULL;
+		_tfopen_s(&pf, _T("./Config.json"), _T("rb"));
+		if (!pf)
+			return;
+		// 获取文件长度;
+		fseek(pf, 0, SEEK_END);
+		size_t file_size = ftell(pf);
+		fseek(pf, 0, SEEK_SET);
+		// 读取文件内容;
+		byte* pdata = (byte*)malloc(file_size);
+		fread(pdata, file_size, 1, pf);
+		fclose(pf);
+
+		// Json数据;
+		cJSON* pJson = cJSON_Parse((const char*)pdata);
+		if (pJson == NULL)
+		{
+			goto end;
+		}
+
+		// 获取数据;
+		g_tConfig.com = cJSON_GetObjectItem(pJson, _T("COM")) ? cJSON_GetObjectItem(pJson, _T("COM"))->valuestring : "";
+		g_tConfig.baudrate = cJSON_GetObjectItem(pJson, _T("Baudrate")) ? cJSON_GetObjectItem(pJson, _T("Baudrate"))->valuestring : "115200";
+		g_tConfig.mode = cJSON_GetObjectItem(pJson, _T("Mode")) ? cJSON_GetObjectItem(pJson, _T("Mode"))->valueint : 0;
+		g_tConfig.warncount = cJSON_GetObjectItem(pJson, _T("WarnCount")) ? cJSON_GetObjectItem(pJson, _T("WarnCount"))->valueint : 200;
+		g_tConfig.waitboot = cJSON_GetObjectItem(pJson, _T("WaitBoot")) ? cJSON_GetObjectItem(pJson, _T("WaitBoot"))->valueint : 5000;
+		g_tConfig.serverurl = cJSON_GetObjectItem(pJson, _T("server-url")) ? cJSON_GetObjectItem(pJson, _T("server-url"))->valuestring : "";
+		g_tConfig.chassis = cJSON_GetObjectItem(pJson, _T("Chassis")) ? cJSON_GetObjectItem(pJson, _T("Chassis"))->valuestring : "";
+
+		// 频道;
+		cJSON* pItem = NULL;
+		cJSON* pChannel = cJSON_GetObjectItem(pJson, "Channel");
+		if (pChannel)
+		{
+			int nCount = cJSON_GetArraySize(pChannel);
+			for (int i = 0; i < nCount; i++)
+			{
+				pItem = cJSON_GetArrayItem(pChannel, i);
+				if (pItem && pItem->child)
+				{
+					g_tConfig.channel.insert(pair<std::string, std::string>(pItem->child->string, pItem->child->valuestring));
+				}
+			}
+		}
+		// 语言;
+		cJSON* pLanguage = cJSON_GetObjectItem(pJson, "Language");
+		if (pLanguage)
+		{
+			int nCount = cJSON_GetArraySize(pLanguage);
+			for (int i = 0; i < nCount; i++)
+			{
+				pItem = cJSON_GetArrayItem(pLanguage, i);
+				if (pItem && pItem->child)
+				{
+					g_tConfig.language.insert(pair<std::string, std::string>(pItem->child->string, pItem->child->valuestring));
+				}
+			}
+		}
+		// 文件夹;
+		cJSON* pKeyFolder = cJSON_GetObjectItem(pJson, "KeyFolder");
+		if (pKeyFolder)
+		{
+			int nCount = cJSON_GetArraySize(pKeyFolder);
+			for (int i = 0; i < nCount; i++)
+			{
+				pItem = cJSON_GetArrayItem(pKeyFolder, i);
+				if (pItem && pItem->child)
+				{
+					g_tConfig.keyfolder.insert(pair<std::string, std::string>(pItem->child->string, pItem->child->valuestring));
+				}
+			}
+		}
+		// read check;
+		cJSON *pReadCheck = cJSON_GetObjectItem(pJson, "ReadCheck");
+		if ( pReadCheck )
+		{
+			g_tConfig.readcheck.IsPID = cJSON_GetObjectItem(pReadCheck, _T("PID")) ? cJSON_GetObjectItem(pReadCheck, _T("PID"))->valueint : 1;
+			g_tConfig.readcheck.IsCHANNEL = cJSON_GetObjectItem(pReadCheck, _T("CHANNEL")) ? cJSON_GetObjectItem(pReadCheck, _T("CHANNEL"))->valueint : 1;
+			g_tConfig.readcheck.IsOSD = cJSON_GetObjectItem(pReadCheck, _T("OSD")) ? cJSON_GetObjectItem(pReadCheck, _T("OSD"))->valueint : 1;
+			g_tConfig.readcheck.IsSHOP = cJSON_GetObjectItem(pReadCheck, _T("SHOP")) ? cJSON_GetObjectItem(pReadCheck, _T("SHOP"))->valueint : 1;
+			g_tConfig.readcheck.IsDID = cJSON_GetObjectItem(pReadCheck, _T("DID")) ? cJSON_GetObjectItem(pReadCheck, _T("DID"))->valueint : 1;
+			g_tConfig.readcheck.IsMAC = cJSON_GetObjectItem(pReadCheck, _T("MAC")) ? cJSON_GetObjectItem(pReadCheck, _T("MAC"))->valueint : 1;
+			g_tConfig.readcheck.IsHDCP = cJSON_GetObjectItem(pReadCheck, _T("HDCP")) ? cJSON_GetObjectItem(pReadCheck, _T("HDCP"))->valueint : 1;
+			g_tConfig.readcheck.IsHDCP22 = cJSON_GetObjectItem(pReadCheck, _T("HDCP22")) ? cJSON_GetObjectItem(pReadCheck, _T("HDCP22"))->valueint : 1;
+			g_tConfig.readcheck.IsWIDI = cJSON_GetObjectItem(pReadCheck, _T("WIDI")) ? cJSON_GetObjectItem(pReadCheck, _T("WIDI"))->valueint : 1;
+			g_tConfig.readcheck.IsWIDEVINE = cJSON_GetObjectItem(pReadCheck, _T("WIDEVINE")) ? cJSON_GetObjectItem(pReadCheck, _T("WIDEVINE"))->valueint : 1;
+			g_tConfig.readcheck.IsESN = cJSON_GetObjectItem(pReadCheck, _T("ESN")) ? cJSON_GetObjectItem(pReadCheck, _T("ESN"))->valueint : 1;
+			g_tConfig.readcheck.IsCI = cJSON_GetObjectItem(pReadCheck, _T("CI")) ? cJSON_GetObjectItem(pReadCheck, _T("CI"))->valueint : 1;
+		}
+
+#ifdef SUPER_VER
+		// write check;
+		cJSON* pWriteCheck = cJSON_GetObjectItem(pJson, "WriteCheck");
+		if (pWriteCheck)
+		{
+			//g_tConfig.writecheck.IsPID = cJSON_GetObjectItem(pWriteCheck, _T("PID")) ? cJSON_GetObjectItem(pWriteCheck, _T("PID"))->valueint : 1;
+			//g_tConfig.writecheck.IsCHANNEL = cJSON_GetObjectItem(pWriteCheck, _T("CHANNEL")) ? cJSON_GetObjectItem(pWriteCheck, _T("CHANNEL"))->valueint : 1;
+			//g_tConfig.writecheck.IsOSD = cJSON_GetObjectItem(pWriteCheck, _T("OSD")) ? cJSON_GetObjectItem(pWriteCheck, _T("OSD"))->valueint : 1;
+			//g_tConfig.writecheck.IsSHOP = cJSON_GetObjectItem(pWriteCheck, _T("SHOP")) ? cJSON_GetObjectItem(pWriteCheck, _T("SHOP"))->valueint : 1;
+			g_tConfig.writecheck.IsDID = cJSON_GetObjectItem(pWriteCheck, _T("DID")) ? cJSON_GetObjectItem(pWriteCheck, _T("DID"))->valueint : 1;
+			g_tConfig.writecheck.IsMAC = cJSON_GetObjectItem(pWriteCheck, _T("MAC")) ? cJSON_GetObjectItem(pWriteCheck, _T("MAC"))->valueint : 1;
+			g_tConfig.writecheck.IsHDCP = cJSON_GetObjectItem(pWriteCheck, _T("HDCP")) ? cJSON_GetObjectItem(pWriteCheck, _T("HDCP"))->valueint : 1;
+			g_tConfig.writecheck.IsHDCP22 = cJSON_GetObjectItem(pWriteCheck, _T("HDCP22")) ? cJSON_GetObjectItem(pWriteCheck, _T("HDCP22"))->valueint : 1;
+			g_tConfig.writecheck.IsWIDI = cJSON_GetObjectItem(pWriteCheck, _T("WIDI")) ? cJSON_GetObjectItem(pWriteCheck, _T("WIDI"))->valueint : 1;
+			g_tConfig.writecheck.IsWIDEVINE = cJSON_GetObjectItem(pWriteCheck, _T("WIDEVINE")) ? cJSON_GetObjectItem(pWriteCheck, _T("WIDEVINE"))->valueint : 1;
+			g_tConfig.writecheck.IsESN = cJSON_GetObjectItem(pWriteCheck, _T("ESN")) ? cJSON_GetObjectItem(pWriteCheck, _T("ESN"))->valueint : 1;
+			g_tConfig.writecheck.IsCI = cJSON_GetObjectItem(pWriteCheck, _T("CI")) ? cJSON_GetObjectItem(pWriteCheck, _T("CI"))->valueint : 1;
+		}
+
+		// write done;
+		cJSON* pWriteDone = cJSON_GetObjectItem(pJson, "WriteDone");
+		if (pWriteDone)
+		{
+			g_tConfig.writedone.IsPID = cJSON_GetObjectItem(pWriteDone, _T("PID")) ? cJSON_GetObjectItem(pWriteDone, _T("PID"))->valueint : 1;
+			g_tConfig.writedone.IsCHANNEL = cJSON_GetObjectItem(pWriteDone, _T("CHANNEL")) ? cJSON_GetObjectItem(pWriteDone, _T("CHANNEL"))->valueint : 1;
+			g_tConfig.writedone.IsOSD = cJSON_GetObjectItem(pWriteDone, _T("OSD")) ? cJSON_GetObjectItem(pWriteDone, _T("OSD"))->valueint : 1;
+			g_tConfig.writedone.IsSHOP = cJSON_GetObjectItem(pWriteDone, _T("SHOP")) ? cJSON_GetObjectItem(pWriteDone, _T("SHOP"))->valueint : 1;
+			g_tConfig.writedone.IsDID = cJSON_GetObjectItem(pWriteDone, _T("DID")) ? cJSON_GetObjectItem(pWriteDone, _T("DID"))->valueint : 1;
+			g_tConfig.writedone.IsMAC = cJSON_GetObjectItem(pWriteDone, _T("MAC")) ? cJSON_GetObjectItem(pWriteDone, _T("MAC"))->valueint : 1;
+			g_tConfig.writedone.IsHDCP = cJSON_GetObjectItem(pWriteDone, _T("HDCP")) ? cJSON_GetObjectItem(pWriteDone, _T("HDCP"))->valueint : 1;
+			g_tConfig.writedone.IsHDCP22 = cJSON_GetObjectItem(pWriteDone, _T("HDCP22")) ? cJSON_GetObjectItem(pWriteDone, _T("HDCP22"))->valueint : 1;
+			g_tConfig.writedone.IsWIDI = cJSON_GetObjectItem(pWriteDone, _T("WIDI")) ? cJSON_GetObjectItem(pWriteDone, _T("WIDI"))->valueint : 1;
+			g_tConfig.writedone.IsWIDEVINE = cJSON_GetObjectItem(pWriteDone, _T("WIDEVINE")) ? cJSON_GetObjectItem(pWriteDone, _T("WIDEVINE"))->valueint : 1;
+			g_tConfig.writedone.IsESN = cJSON_GetObjectItem(pWriteDone, _T("ESN")) ? cJSON_GetObjectItem(pWriteDone, _T("ESN"))->valueint : 1;
+			g_tConfig.writedone.IsCI = cJSON_GetObjectItem(pWriteDone, _T("CI")) ? cJSON_GetObjectItem(pWriteDone, _T("CI"))->valueint : 1;
+		}
+#endif
+		// 配置;
+		cJSON* pChassis = cJSON_GetObjectItem(pJson, "Chassis-list");
+		if (pChassis)
+		{
+			int nCount = cJSON_GetArraySize(pChassis);
+			for (int i = 0; i < nCount; i++)
+			{
+				pItem = cJSON_GetArrayItem(pChassis, i);
+				if (pItem && pItem->child)
+				{
+					std::string name;
+					TChassis tchassis;
+
+					name = cJSON_GetObjectItem(pItem, _T("name")) ? cJSON_GetObjectItem(pItem, _T("name"))->valuestring : "";
+					tchassis.IsCopyDID = cJSON_GetObjectItem(pItem, _T("IsCopyDID")) ? cJSON_GetObjectItem(pItem, _T("IsCopyDID"))->valueint : 0;
+					tchassis.IsCopyMAC = cJSON_GetObjectItem(pItem, _T("IsCopyMAC")) ? cJSON_GetObjectItem(pItem, _T("IsCopyMAC"))->valueint : 0;
+					tchassis.IsCopyKEY = cJSON_GetObjectItem(pItem, _T("IsCopyKEY")) ? cJSON_GetObjectItem(pItem, _T("IsCopyKEY"))->valueint : 0;
+					tchassis.IsCopyESN = cJSON_GetObjectItem(pItem, _T("IsCopyESN")) ? cJSON_GetObjectItem(pItem, _T("IsCopyESN"))->valueint : 0;
+					tchassis.IsCopyWiDi = cJSON_GetObjectItem(pItem, _T("IsCopyWiDi")) ? cJSON_GetObjectItem(pItem, _T("IsCopyWiDi"))->valueint : 0;
+					tchassis.IsCopyWidevine = cJSON_GetObjectItem(pItem, _T("IsCopyWidevine")) ? cJSON_GetObjectItem(pItem, _T("IsCopyWidevine"))->valueint : 0;
+					tchassis.IsCopyKEY2_2 = cJSON_GetObjectItem(pItem, _T("IsCopyKEY2_2")) ? cJSON_GetObjectItem(pItem, _T("IsCopyKEY2_2"))->valueint : 0;
+					tchassis.IsCopyKEY2_3 = cJSON_GetObjectItem(pItem, _T("IsCopyKEY2_3")) ? cJSON_GetObjectItem(pItem, _T("IsCopyKEY2_3"))->valueint : 0;
+					tchassis.IsCopyCikey = cJSON_GetObjectItem(pItem, _T("IsCopyCikey")) ? cJSON_GetObjectItem(pItem, _T("IsCopyCikey"))->valueint : 0;
+					tchassis.IsCopyChannel = cJSON_GetObjectItem(pItem, _T("IsCopyChannel")) ? cJSON_GetObjectItem(pItem, _T("IsCopyChannel"))->valueint : 0;
+					tchassis.IsCopyWB = cJSON_GetObjectItem(pItem, _T("IsCopyWB")) ? cJSON_GetObjectItem(pItem, _T("IsCopyWB"))->valueint : 0;
+					tchassis.IsDisplayClientType = cJSON_GetObjectItem(pItem, _T("IsDisplayClientType")) ? cJSON_GetObjectItem(pItem, _T("IsDisplayClientType"))->valueint : 0;
+					tchassis.IsWritePID = cJSON_GetObjectItem(pItem, _T("IsWritePID")) ? cJSON_GetObjectItem(pItem, _T("IsWritePID"))->valueint : 0;
+					tchassis.IsWBInit = cJSON_GetObjectItem(pItem, _T("IsWBInit")) ? cJSON_GetObjectItem(pItem, _T("IsWBInit"))->valueint : 0;
+					tchassis.IsMTKInit = cJSON_GetObjectItem(pItem, _T("IsMTKInit")) ? cJSON_GetObjectItem(pItem, _T("IsMTKInit"))->valueint : 0;
+					tchassis.IsOsdLanguage = cJSON_GetObjectItem(pItem, _T("IsOsdLanguage")) ? cJSON_GetObjectItem(pItem, _T("IsOsdLanguage"))->valueint : 0;
+					tchassis.IsShopLanguage = cJSON_GetObjectItem(pItem, _T("IsShopLanguage")) ? cJSON_GetObjectItem(pItem, _T("IsShopLanguage"))->valueint : 0;
+					tchassis.IsCopyClientType = cJSON_GetObjectItem(pItem, _T("IsCopyClientType")) ? cJSON_GetObjectItem(pItem, _T("IsCopyClientType"))->valueint : 0;
+					tchassis.IsMGKKeyEnb = cJSON_GetObjectItem(pItem, _T("IsMGKKeyEnb")) ? cJSON_GetObjectItem(pItem, _T("IsMGKKeyEnb"))->valueint : 0;
+					tchassis.IsNovaTakHDCPEnb = cJSON_GetObjectItem(pItem, _T("IsNovaTakHDCPEnb")) ? cJSON_GetObjectItem(pItem, _T("IsNovaTakHDCPEnb"))->valueint : 0;
+
+					tchassis.ProjectID = cJSON_GetObjectItem(pItem, _T("ProjectID")) ? cJSON_GetObjectItem(pItem, _T("ProjectID"))->valueint : 0;
+					tchassis.Channel = cJSON_GetObjectItem(pItem, _T("Channel")) ? cJSON_GetObjectItem(pItem, _T("Channel"))->valuestring : "";
+					tchassis.WBFile = cJSON_GetObjectItem(pItem, _T("WBFile")) ? cJSON_GetObjectItem(pItem, _T("WBFile"))->valuestring : "";
+					tchassis.Delay = cJSON_GetObjectItem(pItem, _T("Delay")) ? cJSON_GetObjectItem(pItem, _T("Delay"))->valueint : 50;
+					tchassis.CheckString = cJSON_GetObjectItem(pItem, _T("CheckString")) ? cJSON_GetObjectItem(pItem, _T("CheckString"))->valuestring : "";
+					tchassis.ClientType = cJSON_GetObjectItem(pItem, _T("ClientType")) ? cJSON_GetObjectItem(pItem, _T("ClientType"))->valuestring : "";
+					tchassis.MACType = cJSON_GetObjectItem(pItem, _T("MACType")) ? cJSON_GetObjectItem(pItem, _T("MACType"))->valuestring : "";
+					tchassis.HDCPKeyType = cJSON_GetObjectItem(pItem, _T("HDCPKeyType")) ? cJSON_GetObjectItem(pItem, _T("HDCPKeyType"))->valuestring : "";
+					tchassis.HDCPKey22Type = cJSON_GetObjectItem(pItem, _T("HDCPKey22Type")) ? cJSON_GetObjectItem(pItem, _T("HDCPKey22Type"))->valuestring : "";
+					tchassis.HDCPKey23Type = cJSON_GetObjectItem(pItem, _T("HDCPKey23Type")) ? cJSON_GetObjectItem(pItem, _T("HDCPKey23Type"))->valuestring : "";
+					tchassis.ESNType = cJSON_GetObjectItem(pItem, _T("ESNType")) ? cJSON_GetObjectItem(pItem, _T("ESNType"))->valuestring : "";
+					tchassis.WiDiType = cJSON_GetObjectItem(pItem, _T("WiDiType")) ? cJSON_GetObjectItem(pItem, _T("WiDiType"))->valuestring : "";
+					tchassis.WidevineType = cJSON_GetObjectItem(pItem, _T("WidevineType")) ? cJSON_GetObjectItem(pItem, _T("WidevineType"))->valuestring : "";
+					tchassis.CIKeyType = cJSON_GetObjectItem(pItem, _T("CIKeyType")) ? cJSON_GetObjectItem(pItem, _T("CIKeyType"))->valuestring : "";
+					tchassis.MGKKeyType = cJSON_GetObjectItem(pItem, _T("MGKKeyType")) ? cJSON_GetObjectItem(pItem, _T("MGKKeyType"))->valuestring : "";
+					tchassis.NovaTakHDCPType = cJSON_GetObjectItem(pItem, _T("NovaTakHDCPType")) ? cJSON_GetObjectItem(pItem, _T("NovaTakHDCPType"))->valuestring : "";
+
+					g_tConfig.chassislist.insert(pair<std::string, CHASSIS>(name, tchassis));
+				}
+			}
+		}
+
+	end:
+		if (pdata)
+			free(pdata);
+
+		if (pJson)
+			cJSON_Delete(pJson);
+	}
+
+	void SetConfig()
+	{
+		// Json数据;
+		cJSON* pJson = cJSON_CreateObject();
+		cJSON_AddStringToObject(pJson, "COM", g_tConfig.com.c_str());
+		cJSON_AddStringToObject(pJson, "server-url", g_tConfig.serverurl.c_str());
+		cJSON_AddStringToObject(pJson, "Chassis", g_tConfig.chassis.c_str());
+		cJSON_AddNumberToObject(pJson, "Mode", g_tConfig.mode);
+		cJSON_AddNumberToObject(pJson, "WarnCount", g_tConfig.warncount);
+		cJSON_AddNumberToObject(pJson, "WaitBoot", g_tConfig.waitboot);
+		cJSON_AddStringToObject(pJson, "Baudrate", g_tConfig.baudrate.c_str());
+
+		// 频道;
+		cJSON* pItem = NULL;
+		cJSON* pChannel = cJSON_AddArrayToObject(pJson, _T("Channel"));
+		if (pChannel)
+		{
+			std::map<std::string, std::string>::iterator it = g_tConfig.channel.begin();
+			for (; it != g_tConfig.channel.end(); it++)
+			{
+				pItem = cJSON_AddObjectToObject(pChannel, it->first.c_str());
+				cJSON_AddStringToObject(pItem, it->first.c_str(), it->second.c_str());
+			}
+		}
+
+		// 语言;
+		cJSON* pLanguage = cJSON_AddArrayToObject(pJson, _T("Language"));
+		if (pLanguage)
+		{
+			std::map<std::string, std::string>::iterator it = g_tConfig.language.begin();
+			for (; it != g_tConfig.language.end(); it++)
+			{
+				pItem = cJSON_AddObjectToObject(pLanguage, it->first.c_str());
+				cJSON_AddStringToObject(pItem, it->first.c_str(), it->second.c_str());
+			}
+		}
+
+		// 文件夹;
+		cJSON* pKeyFolder = cJSON_AddArrayToObject(pJson, _T("KeyFolder"));
+		if (pKeyFolder)
+		{
+			std::map<std::string, std::string>::iterator it = g_tConfig.keyfolder.begin();
+			for (; it != g_tConfig.keyfolder.end(); it++)
+			{
+				pItem = cJSON_AddObjectToObject(pKeyFolder, it->first.c_str());
+				cJSON_AddStringToObject(pItem, it->first.c_str(), it->second.c_str());
+			}
+		}
+
+		// read check;
+		cJSON* pReadCheck = cJSON_AddObjectToObject(pJson, "ReadCheck");
+		if (pReadCheck)
+		{
+			cJSON_AddBoolToObject(pReadCheck, _T("PID"), g_tConfig.readcheck.IsPID);
+			cJSON_AddBoolToObject(pReadCheck, _T("CHANNEL"), g_tConfig.readcheck.IsCHANNEL);
+			cJSON_AddBoolToObject(pReadCheck, _T("OSD"), g_tConfig.readcheck.IsOSD);
+			cJSON_AddBoolToObject(pReadCheck, _T("SHOP"), g_tConfig.readcheck.IsSHOP);
+			cJSON_AddBoolToObject(pReadCheck, _T("DID"), g_tConfig.readcheck.IsDID);
+			cJSON_AddBoolToObject(pReadCheck, _T("MAC"), g_tConfig.readcheck.IsMAC);
+			cJSON_AddBoolToObject(pReadCheck, _T("HDCP"), g_tConfig.readcheck.IsHDCP);
+			cJSON_AddBoolToObject(pReadCheck, _T("HDCP22"), g_tConfig.readcheck.IsHDCP22);
+			cJSON_AddBoolToObject(pReadCheck, _T("WIDI"), g_tConfig.readcheck.IsWIDI);
+			cJSON_AddBoolToObject(pReadCheck, _T("WIDEVINE"), g_tConfig.readcheck.IsWIDEVINE);
+			cJSON_AddBoolToObject(pReadCheck, _T("ESN"), g_tConfig.readcheck.IsESN);
+			cJSON_AddBoolToObject(pReadCheck, _T("CI"), g_tConfig.readcheck.IsCI);
+		}
+#ifdef SUPER_VER
+		// write check;
+		cJSON* pWriteCheck = cJSON_AddObjectToObject(pJson, "WriteCheck");
+		if (pWriteCheck)
+		{
+			//cJSON_AddBoolToObject(pWriteCheck, _T("PID"), g_tConfig.writecheck.IsPID);
+			//cJSON_AddBoolToObject(pWriteCheck, _T("CHANNEL"), g_tConfig.writecheck.IsCHANNEL);
+			//cJSON_AddBoolToObject(pWriteCheck, _T("OSD"), g_tConfig.writecheck.IsOSD);
+			//cJSON_AddBoolToObject(pWriteCheck, _T("SHOP"), g_tConfig.writecheck.IsSHOP);
+			cJSON_AddBoolToObject(pWriteCheck, _T("DID"), g_tConfig.writecheck.IsDID);
+			cJSON_AddBoolToObject(pWriteCheck, _T("MAC"), g_tConfig.writecheck.IsMAC);
+			cJSON_AddBoolToObject(pWriteCheck, _T("HDCP"), g_tConfig.writecheck.IsHDCP);
+			cJSON_AddBoolToObject(pWriteCheck, _T("HDCP22"), g_tConfig.writecheck.IsHDCP22);
+			cJSON_AddBoolToObject(pWriteCheck, _T("WIDI"), g_tConfig.writecheck.IsWIDI);
+			cJSON_AddBoolToObject(pWriteCheck, _T("WIDEVINE"), g_tConfig.writecheck.IsWIDEVINE);
+			cJSON_AddBoolToObject(pWriteCheck, _T("ESN"), g_tConfig.writecheck.IsESN);
+			cJSON_AddBoolToObject(pWriteCheck, _T("CI"), g_tConfig.writecheck.IsCI);
+		}
+
+		// write done;
+		cJSON* pWriteDone= cJSON_AddObjectToObject(pJson, "WriteDone");
+		if (pWriteDone)
+		{
+			cJSON_AddBoolToObject(pWriteDone, _T("PID"), g_tConfig.writedone.IsPID);
+			cJSON_AddBoolToObject(pWriteDone, _T("CHANNEL"), g_tConfig.writedone.IsCHANNEL);
+			cJSON_AddBoolToObject(pWriteDone, _T("OSD"), g_tConfig.writedone.IsOSD);
+			cJSON_AddBoolToObject(pWriteDone, _T("SHOP"), g_tConfig.writedone.IsSHOP);
+			cJSON_AddBoolToObject(pWriteDone, _T("DID"), g_tConfig.writedone.IsDID);
+			cJSON_AddBoolToObject(pWriteDone, _T("MAC"), g_tConfig.writedone.IsMAC);
+			cJSON_AddBoolToObject(pWriteDone, _T("HDCP"), g_tConfig.writedone.IsHDCP);
+			cJSON_AddBoolToObject(pWriteDone, _T("HDCP22"), g_tConfig.writedone.IsHDCP22);
+			cJSON_AddBoolToObject(pWriteDone, _T("WIDI"), g_tConfig.writedone.IsWIDI);
+			cJSON_AddBoolToObject(pWriteDone, _T("WIDEVINE"), g_tConfig.writedone.IsWIDEVINE);
+			cJSON_AddBoolToObject(pWriteDone, _T("ESN"), g_tConfig.writedone.IsESN);
+			cJSON_AddBoolToObject(pWriteDone, _T("CI"), g_tConfig.writedone.IsCI);
+		}
+#endif
+		// 配置;
+		cJSON* pChassis = cJSON_AddArrayToObject(pJson, _T("Chassis-list"));
+		if (pChassis)
+		{
+			std::map<std::string, TChassis>::iterator it = g_tConfig.chassislist.begin();
+			for (; it != g_tConfig.chassislist.end(); it++)
+			{
+				pItem = cJSON_AddObjectToObject(pChassis, it->first.c_str());
+				cJSON_AddStringToObject(pItem, _T("name"), it->first.c_str());
+				// bool
+				cJSON_AddBoolToObject(pItem, _T("IsCopyDID"), it->second.IsCopyDID);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyMAC"), it->second.IsCopyMAC);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyKEY"), it->second.IsCopyKEY);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyESN"), it->second.IsCopyESN);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyWiDi"), it->second.IsCopyWiDi);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyWidevine"), it->second.IsCopyWidevine);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyKEY2_2"), it->second.IsCopyKEY2_2);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyKEY2_3"), it->second.IsCopyKEY2_3);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyCikey"), it->second.IsCopyCikey);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyChannel"), it->second.IsCopyChannel);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyWB"), it->second.IsCopyWB);
+				cJSON_AddBoolToObject(pItem, _T("IsDisplayClientType"), it->second.IsDisplayClientType);
+				cJSON_AddBoolToObject(pItem, _T("IsWritePID"), it->second.IsWritePID);
+				cJSON_AddBoolToObject(pItem, _T("IsWBInit"), it->second.IsWBInit);
+				cJSON_AddBoolToObject(pItem, _T("IsMTKInit"), it->second.IsMTKInit);
+				cJSON_AddBoolToObject(pItem, _T("IsOsdLanguage"), it->second.IsOsdLanguage);
+				cJSON_AddBoolToObject(pItem, _T("IsShopLanguage"), it->second.IsShopLanguage);
+				cJSON_AddBoolToObject(pItem, _T("IsCopyClientType"), it->second.IsCopyClientType);
+				cJSON_AddBoolToObject(pItem, _T("IsMGKKeyEnb"), it->second.IsMGKKeyEnb);
+				cJSON_AddBoolToObject(pItem, _T("IsNovaTakHDCPEnb"), it->second.IsNovaTakHDCPEnb);
+				// ini
+				cJSON_AddNumberToObject(pItem, _T("ProjectID"), it->second.ProjectID);
+				cJSON_AddNumberToObject(pItem, _T("Delay"), it->second.Delay);
+				// string
+				cJSON_AddStringToObject(pItem, _T("Channel"), it->second.Channel.c_str());
+				cJSON_AddStringToObject(pItem, _T("WBFile"), it->second.WBFile.c_str());
+				cJSON_AddStringToObject(pItem, _T("CheckString"), it->second.CheckString.c_str());
+				cJSON_AddStringToObject(pItem, _T("ClientType"), it->second.ClientType.c_str());
+				cJSON_AddStringToObject(pItem, _T("MACType"), it->second.MACType.c_str());
+				cJSON_AddStringToObject(pItem, _T("HDCPKeyType"), it->second.HDCPKeyType.c_str());
+				cJSON_AddStringToObject(pItem, _T("HDCPKey22Type"), it->second.HDCPKey22Type.c_str());
+				cJSON_AddStringToObject(pItem, _T("HDCPKey23Type"), it->second.HDCPKey23Type.c_str());
+				cJSON_AddStringToObject(pItem, _T("ESNType"), it->second.ESNType.c_str());
+				cJSON_AddStringToObject(pItem, _T("WiDiType"), it->second.WiDiType.c_str());
+				cJSON_AddStringToObject(pItem, _T("WidevineType"), it->second.WidevineType.c_str());
+				cJSON_AddStringToObject(pItem, _T("CIKeyType"), it->second.CIKeyType.c_str());
+				cJSON_AddStringToObject(pItem, _T("MGKKeyType"), it->second.MGKKeyType.c_str());
+				cJSON_AddStringToObject(pItem, _T("NovaTakHDCPType"), it->second.NovaTakHDCPType.c_str());
+			}
+		}
+
+		char* pJsonText = cJSON_Print(pJson);
+
+		// 保存到文件中;
+		FILE* pf = NULL;
+		_tfopen_s(&pf, _T("./Config.json"), _T("wb"));
+		if (pf)
+		{
+			fwrite(pJsonText, _tcslen(pJsonText), 1, pf);
+			fclose(pf);
+		}
+
+		if (pJsonText)
+			delete[] pJsonText;
+		cJSON_Delete(pJson);
+	}
+
+	// 去除空格;
+	std::string& trim(std::string& str)
+	{
+		int nIndex = 0;
+		while ((nIndex = str.find_first_of(' ')) != std::string::npos)
+			str.erase(nIndex, 1);
+
+		return str;
+	}
+
+	// hModule 模块句柄 NULL表示当前模块;
+	bool GetVersion(IN const TCHAR* fname, OUT WORD* pdwFileVersion, OUT WORD* pdwProductVerion)
+	{
+		VS_FIXEDFILEINFO* pVi = NULL;
+		DWORD dwHandle = 0;
+		int size = GetFileVersionInfoSize(fname, &dwHandle);
+		if (size > 0)
+		{
+			BYTE* buffer = new BYTE[size];
+			memset(buffer, 0, size);
+
+			if (GetFileVersionInfo(fname, 0, size, buffer))
+			{
+				if (VerQueryValue(buffer, _T("\\"), (LPVOID*)& pVi, (PUINT)& size))
+				{
+					pdwFileVersion[0] = HIWORD(pVi->dwFileVersionMS);
+					pdwFileVersion[1] = LOWORD(pVi->dwFileVersionMS);
+					pdwFileVersion[2] = HIWORD(pVi->dwFileVersionLS);
+					pdwFileVersion[3] = LOWORD(pVi->dwFileVersionLS);
+
+					pdwProductVerion[0] = HIWORD(pVi->dwProductVersionMS);
+					pdwProductVerion[1] = LOWORD(pVi->dwProductVersionMS);
+					pdwProductVerion[2] = HIWORD(pVi->dwProductVersionLS);
+					pdwProductVerion[3] = LOWORD(pVi->dwProductVersionLS);
+
+					delete[] buffer;
+					return true;
+				}
+			}
+
+			delete[] buffer;
+		}
+
+		return false;
+	}
+
+	BOOL GetVersion(IN HMODULE hModule, OUT DWORD(&dwFVArray)[4], OUT DWORD(&dwPVArray)[4])
+	{
+		TCHAR fname[MAX_PATH];
+		VS_FIXEDFILEINFO* pVi;
+		DWORD dwHandle;
+
+		if (GetModuleFileName(hModule, fname, MAX_PATH))
+		{
+			INT nSize = GetFileVersionInfoSize(fname, &dwHandle);
+
+			if (nSize > 0)
+			{
+				BYTE* pBuffer = new BYTE[nSize];
+				memset(pBuffer, 0, nSize);
+
+				if (GetFileVersionInfo(fname, 0, nSize, pBuffer))
+				{
+					if (VerQueryValue(pBuffer, _T("\\"), (LPVOID*)& pVi, (PUINT)& nSize))
+					{
+						dwFVArray[0] = HIWORD(pVi->dwFileVersionMS);
+						dwFVArray[1] = LOWORD(pVi->dwFileVersionMS);
+						dwFVArray[2] = HIWORD(pVi->dwFileVersionLS);
+						dwFVArray[3] = LOWORD(pVi->dwFileVersionLS);
+
+						dwPVArray[0] = HIWORD(pVi->dwProductVersionMS);
+						dwPVArray[1] = LOWORD(pVi->dwProductVersionMS);
+						dwPVArray[2] = HIWORD(pVi->dwProductVersionLS);
+						dwPVArray[3] = LOWORD(pVi->dwProductVersionLS);
+
+						delete[]pBuffer;
+						return TRUE;
+					}
+				}
+
+				if (pBuffer)
+					delete[]pBuffer;
+			}
+		}
+
+		return FALSE;
+	}
+
+	WCHAR* ASCII2UNICODE(IN LPCCH lpASCIIStr)
+	{
+		if (lpASCIIStr == NULL)
+			return NULL;
+
+		// 获取宽字符字节数;
+		int cchWideChar = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
+		if (cchWideChar == 0)
+			return NULL;
+
+		// 转换成宽字符串;
+		WCHAR* pWideChar = new WCHAR[cchWideChar + 1];
+		memset(pWideChar, 0, sizeof(WCHAR) * (cchWideChar + 1));
+		int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pWideChar, cchWideChar);
+		if (nWriteNum != cchWideChar)
+		{
+			if (pWideChar)
+				delete[] pWideChar;
+			return NULL;
+		}
+
+		return pWideChar;
+	}
+
+	BOOL UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT string& strResult)
+	{
+		if (lpUNICODEStr == NULL)
+			return FALSE;
+
+		// 获取多字节字符字节数;
+		int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
+		if (cbMultiByte == 0)
+			return FALSE;
+
+		// 转换成多字节字符;
+		CHAR* pResult = new CHAR[cbMultiByte];
+		memset(pResult, 0, cbMultiByte);
+		int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pResult, cbMultiByte, NULL, NULL);
+		if (nWriteNum != cbMultiByte)
+			return FALSE;
+
+		strResult = pResult;
+		if (pResult)
+			delete[] pResult;
+
+		return TRUE;
+	}
+
+	BOOL ASCII2UTF8(IN LPCCH lpASCIIStr, OUT string& strResult)
+	{
+		// 将ASCII字符串转成UNICODE字符串;
+		WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
+		if (pWideChar == NULL)
+			return FALSE;
+
+		// 再将UICODE转成UTF8;
+		BOOL bResult = UNICODE2UTF8(pWideChar, strResult);
+
+		if (pWideChar)
+			delete[] pWideChar;
+
+		return bResult;
+	}
+
+	string EnCode_UTF8URL(IN const CHAR* pText)
+	{
+		string tt = "";
+		string dd = "";
+		ASCII2UTF8(pText, tt);
+
+		size_t len = tt.length();
+		for (size_t i = 0; i < len; i++)
+		{
+			if (isalnum((BYTE)tt.at(i)))
+			{
+				char tempbuff[2] = { 0 };
+				sprintf_s(tempbuff, "%c", (BYTE)tt.at(i));
+				dd.append(tempbuff);
+			}
+			else if (isspace((BYTE)tt.at(i)))
+			{
+				dd.append("+");
+			}
+			else
+			{
+				char tempbuff[4];
+				sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16);
+				dd.append(tempbuff);
+			}
+		}
+		return dd;
+	}
+
+	void EnCode_UTF8URL(IN const CHAR* pText, OUT string& strResult)
+	{
+		string tt = "";
+		ASCII2UTF8(pText, tt);
+
+		size_t len = tt.length();
+		for (size_t i = 0; i < len; i++)
+		{
+			if (isalnum((BYTE)tt.at(i)))
+			{
+				char tempbuff[2] = { 0 };
+				sprintf_s(tempbuff, "%c", (BYTE)tt.at(i));
+				strResult.append(tempbuff);
+			}
+			else if (isspace((BYTE)tt.at(i)))
+			{
+				strResult.append("+");
+			}
+			else
+			{
+				char tempbuff[4];
+				sprintf_s(tempbuff, "%%%X%X", ((BYTE)tt.at(i)) >> 4, ((BYTE)tt.at(i)) % 16);
+				strResult.append(tempbuff);
+			}
+		}
+	}
+
+	// 通过注册表查找系统当前串口信息;
+	BOOL GetSysSerialPort(std::vector<std::string>& vtports)
+	{
+		HKEY hKey;
+		LSTATUS lReg = 0;
+		DWORD dwMaxValLen = 0;
+		DWORD dwValNum = 0;
+		lReg = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey);
+		if (lReg != ERROR_SUCCESS)
+		{
+			LOG4C((LOG_WARN, "Open Registry Error"));
+			return FALSE;
+		}
+
+		lReg = RegQueryInfoKeyA(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValNum, &dwMaxValLen, NULL, NULL, NULL);
+		if (lReg != ERROR_SUCCESS)
+		{
+			LOG4C((LOG_WARN, "Getting Key Info Error"));
+			return FALSE;
+		}
+
+		if (vtports.size())
+		{
+			vtports.clear();
+		}
+
+		LPSTR lpValName, lpComNum;
+		DWORD dwValName, dwValSize = 6;
+		for (DWORD i = 0; i < dwValNum; i++)
+		{
+			dwValName = dwMaxValLen + 1;
+			dwValSize = 6;
+			lpValName = (LPSTR)VirtualAlloc(NULL, dwValName, MEM_COMMIT, PAGE_READWRITE);
+			lReg = RegEnumValueA(hKey, i, lpValName, &dwValName, NULL, NULL, NULL, NULL);
+			if ((lReg != ERROR_SUCCESS) && (lReg != ERROR_NO_MORE_ITEMS))
+			{
+				LOG4C((LOG_WARN, "Enum  Registry  Error or No More Items"));
+				continue;
+			}
+			lpComNum = (LPSTR)VirtualAlloc(NULL, 6, MEM_COMMIT, PAGE_READWRITE);
+			lReg = RegQueryValueExA(hKey, lpValName, NULL, NULL, (LPBYTE)lpComNum, &dwValSize);
+			if (lReg != ERROR_SUCCESS)
+			{
+				LOG4C((LOG_WARN, "Can not get the name of the port"));
+				continue;
+			}
+
+			vtports.push_back(lpComNum);
+			VirtualFree(lpValName, 0, MEM_RELEASE);
+			VirtualFree(lpComNum, 0, MEM_RELEASE);
+		}
+
+		return TRUE;
+	}
+
+	INT GetMacAddress()
+	{
+		HDEVINFO hDevInfo;
+		DWORD MemberIndex, RequiredSize;
+		SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
+		PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
+		INT nTotal = 0;
+		INT nNICKind = 0;
+
+		// 获取设备信息集;
+		hDevInfo = SetupDiGetClassDevs(&MacClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
+		if (hDevInfo == INVALID_HANDLE_VALUE)
+		{
+			return -1;
+		}
+
+		g_vtMac.clear();
+		// 枚举设备信息集中所有设备;
+		DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+		for (MemberIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &MacClassGuid, MemberIndex, &DeviceInterfaceData); MemberIndex++)
+		{
+			// 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER;
+			SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL);
+
+			// 申请接收缓冲区;
+			DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
+			DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+			// 获取设备细节信息;
+			if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL))
+			{
+				HANDLE hDeviceFile;
+				BOOL isOK = FALSE;
+				if (_tcsnicmp(DeviceInterfaceDetailData->DevicePath + 4, TEXT("pci"), 3) != 0)
+					continue;
+
+				MacAddress tagMacAddress;
+				tagMacAddress.nNICKind = NIC_PCI;
+				_stprintf_s(tagMacAddress.szNICKind, _T("%s"), _T("NIC_PCI"));
+
+				// 获取设备句柄;
+				hDeviceFile = CreateFile(DeviceInterfaceDetailData->DevicePath,
+					0,
+					FILE_SHARE_READ | FILE_SHARE_WRITE,
+					NULL,
+					OPEN_EXISTING,
+					0,
+					NULL);
+
+				if (hDeviceFile != INVALID_HANDLE_VALUE)
+				{
+					ULONG dwID;
+					BYTE ucData[8];
+					DWORD dwByteRet;
+
+					// 获取原生MAC地址;
+					dwID = OID_802_3_PERMANENT_ADDRESS;
+					isOK = DeviceIoControl(hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL);
+					if (isOK)
+					{
+						++nTotal;
+						_stprintf_s(tagMacAddress.szDevicePath, _T("%s"), DeviceInterfaceDetailData->DevicePath);
+						memset(tagMacAddress.szMacAddress, 0, sizeof(TCHAR) * MAX_PATH);
+						// 将字节数组转换成16进制字符串;
+						for (DWORD i = 0; i < dwByteRet; i++)
+						{
+							_stprintf_s(&tagMacAddress.szMacAddress[i * 3], MAX_PATH - (i * 3), (i != dwByteRet - 1) ? _T("%02X-") : _T("%02X"), ucData[i]);
+						}
+
+						g_vtMac.push_back(tagMacAddress);
+					}
+					CloseHandle(hDeviceFile);
+				}
+			}
+
+			free(DeviceInterfaceDetailData);
+		}
+
+		SetupDiDestroyDeviceInfoList(hDevInfo);
+
+#if 1
+		g_strMacs.clear();
+		std::vector<MacAddress>::iterator it = g_vtMac.begin();
+		for (; it != g_vtMac.end(); it++)
+		{
+			g_strMacs.append(it->szMacAddress);
+			g_strMacs.append("&");
+		}
+#endif
+
+		return nTotal;
+	}
+
+	BOOL IsValidString(LPCTSTR lpszString)
+	{
+		if (lpszString == NULL)
+			return FALSE;
+
+		do
+		{
+			// ASCII可显示的字符;
+			if (*lpszString < 32 || *lpszString > 126)
+			{
+				return FALSE;
+			}
+		} while (*++lpszString);
+
+		return TRUE;
+	}
+} // namespace Global

+ 300 - 0
TCL Copy Tool/TCL Copy Tool/Global.h

@@ -0,0 +1,300 @@
+
+#pragma once
+#include <stdio.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <time.h> //或者 #include <ctime>
+#include <io.h>
+#pragma comment(lib, "version.lib")
+#include "../cJson/cJSON.h"
+#include "tinyxml2.h"
+#include "Log4c.h"
+#include <vector>
+#include <string>
+
+namespace Global
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 升级包请求体;
+	typedef struct
+	{
+		std::string appid;
+		std::string devicemodel;
+		std::string dnum;
+		std::string ver;
+		std::string type;
+	} __update_post__;
+
+	// 升级包返回体;
+	typedef struct
+	{
+		std::string servertime;
+		std::string callid;
+		std::string status;
+		std::string note;
+		std::string language;
+		std::string apiversion;
+		typedef struct
+		{
+			std::string now;
+			std::string type;
+			std::string appid;
+			std::string apptype;
+			std::string version;
+			std::string verid;
+			std::string md5;
+			std::string size;
+			std::string minicon;
+			std::string midicon;
+			std::string fileurl;
+			std::string increment;
+			std::string appendver;
+			std::string updatetime;
+		} __upcontent__;
+		__upcontent__ upcontent;
+	} __update_result__;
+
+	// 烧录数据请求体;
+	typedef struct
+	{
+		std::string clienttype;
+		//std::string	projectid;
+		std::string version;
+		std::string bid; //批次号;
+		std::string mac; // mac地址;
+	} __burndata_post__;
+
+	typedef struct
+	{
+		std::string name;
+		std::string type;
+	} __burndata__;
+
+	typedef struct
+	{
+		std::string message;
+		std::string code;
+		std::string factoryname;
+		std::string factoryip;
+		std::string factoryNum;
+		std::string version;
+		std::string projectid;
+		std::string clienttype;
+		std::string host;
+		std::vector<__burndata__> obj;
+	} __burndata_result__;
+
+	typedef struct CHASSIS
+	{
+		bool IsCopyDID;
+		bool IsCopyMAC;
+		bool IsCopyKEY;
+		bool IsCopyESN;
+		bool IsCopyWiDi;
+		bool IsCopyWidevine;
+		bool IsCopyKEY2_2;
+		bool IsCopyKEY2_3;
+		bool IsCopyCikey;
+		bool IsCopyChannel;
+		bool IsCopyWB;
+		bool IsDisplayClientType;
+		bool IsWritePID;
+		bool IsWBInit;
+		bool IsMTKInit;
+		bool IsOsdLanguage;
+		bool IsShopLanguage;
+		bool IsCopyClientType;
+		bool IsMGKKeyEnb;
+		bool IsNovaTakHDCPEnb;
+
+		int Delay;
+		unsigned int ProjectID;
+		std::string Channel;
+		std::string WBFile;
+		std::string CheckString;
+		std::string ClientType;
+		std::string MACType;
+		std::string HDCPKeyType;
+		std::string HDCPKey22Type;
+		std::string HDCPKey23Type;
+		std::string ESNType;
+		std::string WiDiType;
+		std::string WidevineType;
+		std::string CIKeyType;
+		std::string OsdLanguage;
+		std::string ShopLanguage;
+		std::string MGKKeyType;
+		std::string NovaTakHDCPType;
+		std::string url;	// 在线服务器;
+		std::string name;	// chassis name;
+
+		CHASSIS& operator=(const CHASSIS& that)
+		{
+			if (this != &that)
+			{
+				url = that.url;
+				name = that.name;
+				IsCopyDID = that.IsCopyDID;
+				IsCopyMAC = that.IsCopyMAC;
+				IsCopyKEY = that.IsCopyKEY;
+				IsCopyESN = that.IsCopyESN;
+				IsCopyWiDi = that.IsCopyWiDi;
+				IsCopyWidevine = that.IsCopyWidevine;
+				IsCopyKEY2_2 = that.IsCopyKEY2_2;
+				IsCopyKEY2_3 = that.IsCopyKEY2_3;
+				IsCopyCikey = that.IsCopyCikey;
+				IsCopyChannel = that.IsCopyChannel;
+				IsCopyWB = that.IsCopyWB;
+				IsDisplayClientType = that.IsDisplayClientType;
+				IsWritePID = that.IsWritePID;
+				IsWBInit = that.IsWBInit;
+				IsMTKInit = that.IsMTKInit;
+				IsOsdLanguage = that.IsOsdLanguage;
+				IsShopLanguage = that.IsShopLanguage;
+				IsCopyClientType = that.IsCopyClientType;
+				IsMGKKeyEnb = that.IsMGKKeyEnb;
+				IsNovaTakHDCPEnb = that.IsNovaTakHDCPEnb;
+
+				Delay = that.Delay;
+				ProjectID = that.ProjectID;
+
+				Channel = that.Channel;
+				WBFile = that.WBFile;
+				CheckString = that.CheckString;
+				ClientType = that.ClientType;
+				MACType = that.MACType;
+				HDCPKeyType = that.HDCPKeyType;
+				HDCPKey22Type = that.HDCPKey22Type;
+				HDCPKey23Type = that.HDCPKey23Type;
+				ESNType = that.ESNType;
+				WiDiType = that.WiDiType;
+				WidevineType = that.WidevineType;
+				CIKeyType = that.CIKeyType;
+				OsdLanguage = that.OsdLanguage;
+				ShopLanguage = that.ShopLanguage;
+				MGKKeyType = that.MGKKeyType;
+				NovaTakHDCPType = that.NovaTakHDCPType;
+			}
+			return *this;
+		}
+	} TChassis, * pTChassis;
+
+	typedef struct __READCHECK__
+	{
+		bool IsPID = true;
+		bool IsCHANNEL = true;
+		bool IsOSD = true;
+		bool IsSHOP = true;
+		bool IsDID = true;
+		bool IsMAC = true;
+		bool IsHDCP = true;
+		bool IsHDCP22 = true;
+		bool IsWIDI = true;
+		bool IsWIDEVINE = true;
+		bool IsESN = true;
+		bool IsCI = true;
+	}TReadCheck, * pTReadCheck;
+
+	typedef struct __WRITECHECK__
+	{
+		//bool IsPID = true;
+		//bool IsCHANNEL = true;
+		//bool IsOSD = true;
+		//bool IsSHOP = true;
+		bool IsDID = true;
+		bool IsMAC = true;
+		bool IsHDCP = true;
+		bool IsHDCP22 = true;
+		bool IsWIDI = true;
+		bool IsWIDEVINE = true;
+		bool IsESN = true;
+		bool IsCI = true;
+	}TWriteCheck, * pWriteCheck;
+
+	typedef struct __WRITEDONE__
+	{
+		bool IsPID = true;
+		bool IsCHANNEL = true;
+		bool IsOSD = true;
+		bool IsSHOP = true;
+		bool IsDID = true;
+		bool IsMAC = true;
+		bool IsHDCP = true;
+		bool IsHDCP22 = true;
+		bool IsWIDI = true;
+		bool IsWIDEVINE = true;
+		bool IsESN = true;
+		bool IsCI = true;
+	}TWriteDone, * pTWriteDone;
+
+	extern Global::TChassis g_AutoOnlineChassis;
+	// 配置文件;
+	typedef struct TCONFIG
+	{
+		std::string com;
+		std::string baudrate;
+		std::string chassis;
+		int mode;
+		int warncount = 200;
+		int waitboot = 5000;
+		std::string siacpcmdfile;
+		std::string serverurl;
+		std::map<std::string, std::string> channel;
+		std::map<std::string, std::string> language;
+		std::map<std::string, std::string> keyfolder;
+		std::map<std::string, TChassis> chassislist;
+		TReadCheck readcheck;
+		TWriteCheck writecheck;
+		TWriteDone writedone;
+	} TConfig, * pTConfig;
+
+	// 网卡类型;
+	enum NICKIND
+	{
+		// pci网卡;
+		NIC_PCI,
+		// usb网卡;
+		NIC_USB,
+		// 虚拟网卡;
+		NIC_ROOT,
+		// 仿真网卡;
+		NIC_SWD,
+		// 未知类型;
+		NIC_UNK
+	};
+
+	typedef struct __MAC_ADDRESS__
+	{
+		INT nNICKind;
+		TCHAR szNICKind[16];
+		TCHAR szMacAddress[MAX_PATH];
+		TCHAR szDevicePath[MAX_PATH];
+	} MacAddress, * pMacAddress;
+	//////////////////////////////////////////////////////////////////////////
+	// 全局变量;
+	extern BOOL g_bTestHost;
+	extern TCHAR g_szCurModuleDir[MAX_PATH];
+	extern TCHAR g_szCurModulePath[MAX_PATH];
+	extern TCHAR g_szFna[MAX_PATH];
+	extern TCHAR g_szConfig[MAX_PATH];
+	extern std::string g_strMacs;
+	extern std::vector<MacAddress> g_vtMac;
+	extern TConfig g_tConfig;
+
+	//////////////////////////////////////////////////////////////////////////
+	// 全局函数;
+	void GetConfig();
+	void SetConfig();
+	bool GetVersion(IN const TCHAR* fname, OUT WORD* pdwFileVersion, OUT WORD* pdwProductVerion);
+	BOOL GetVersion(IN HMODULE hModule, OUT DWORD(&dwFVArray)[4], OUT DWORD(&dwPVArray)[4]);
+	void WriteTextLog(const TCHAR* format, ...);
+	std::string EnCode_UTF8URL(IN const CHAR* pText);
+	std::string& trim(std::string& str);
+	// 获取网卡地址;
+	INT GetMacAddress();
+	// 字符串是否由数字、字母、符号组成;
+	BOOL IsValidString(LPCTSTR lpszString);
+
+	// 获取系统当前串口数量;
+	BOOL GetSysSerialPort(std::vector<std::string>& vtports);
+}; // namespace Global

+ 1999 - 0
TCL Copy Tool/TCL Copy Tool/OTA.cpp

@@ -0,0 +1,1999 @@
+#include "pch.h"
+#include "OTA.h"
+#include "CharEncoding.h"
+#include "TCL Copy ToolDlg.h"
+
+std::vector<_SIACP_> g_vtSiacp = {
+	{"EnterFactory", "AA", "10", "01", false, 100},
+	{"LeaveFactory", "AA", "10", "00", false, 100},
+	{"WBInit", "AA", "16", "02", false, 100},//白平衡数据初始化(适用于所有信源)
+	{"GetProjectID", "AA", "84", "00", false, 100},
+	{"GetSoftVersion", "AA", "57", "00", false, 100},
+	{"GetDeviceId", "AA", "BE", "01", true, 100},
+	{"GetClientType", "AA", "8C", "00", false, 100},
+	{"GetMAC", "AA", "BE", "00", true, 100},
+	{"GetHDCPKey", "AA", "EE", "00", false, 100},
+	{"GetHDCPKey22", "AA", "E7", "00", false, 100},
+	{"GetWidi", "AA", "E7", "00", false, 100},
+	{"GetNetflixESN", "AA", "BE", "06", true, 100},
+	{"GetWidevine", "AA", "EC", "00", true, 100},
+	{"GetCiKey", "AA", "EC", "01", true, 100},
+	{"GetOSDLanguage", "AA", "97", "00", true, 100},
+	{"GetShopLanguage", "AA", "97", "01", true, 100},
+	{"GetChannel", "AA", "97", "13", true, 100},
+	// 设置;
+	{"SetProjectId", "AA", "70", "", false, 100},
+	{"SetDeviceID", "AA", "B2", "", false, 100},
+	{"SetMAC", "AA", "B3", "", false, 100},
+	{"SetHDCPKey", "AA FE", "86", "", false, 100},
+	{"SetHDCPKey22", "AA FE", "E4", "", false, 100},
+	{"SetNetflixESN", "AA", "99 00", "", false, 100},
+	{"SetWidi", "AA FE", "E4", "", false, 100}, //与hdcp22相同指令
+	{"SetWidevine", "AA FE", "E9 00", "", false, 100},
+	{"SetCiKey", "AA FE", "E9 01", "", false, 100},
+	{"SetOSDLanguage", "AA", "96 00", "", true, 100},
+	{"SetShopLanguage", "AA", "96 01", "", true, 100},
+	// 设置;
+	{"SetChannel", "AA", "15", "", false, 100},
+	{"SetWBNormal", "AA", "4D 04 01 01", "", false, 100},
+	{"SetWBCool", "AA", "4D 04 02 01", "", false, 100},
+	{"SetWBWarm", "AA", "4D 04 03 01", "", false, 100},
+	// 检测;
+	{"CheckMAC", "AA", "B4", "00", false, 100},
+	{"CheckDeviceId", "AA", "B4", "00", false, 100},
+	{"CheckHDCP", "AA", "87", "00", false, 100},
+	{"CheckNetflixESN", "AA", "9A", "00", true, 100},
+	{"CheckWidi", "AA", "E5", "00", false, 100},
+	{"CheckWidevine", "AA", "EA", "00", true, 100},
+
+	{"CheckCikey", "AA", "EA", "01", true, 100},
+	{"CheckHDCP22", "AA", "E5", "00", false, 100},
+	{"StarWarmUpMode", "AA", "13", "01", false, 100},
+	{"StopWarmUpMode", "AA", "13", "00", false, 100}
+};
+
+const unsigned short CRC16_TABLE[16] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF};
+
+unsigned short CRC16Calculate(byte *pBuffer, unsigned int wordLength)
+{
+	unsigned short wordCRC;
+	byte byteTemp;
+
+	wordCRC = 0xFFFF;
+	while (wordLength--)
+	{
+		byteTemp = (byte)(wordCRC >> 0x0C);
+		wordCRC <<= 4;
+		wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) >> 0x04)];
+		byteTemp = (byte)(wordCRC >> 0x0C);
+		wordCRC <<= 4;
+		wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) & 0x0F)];
+		pBuffer++;
+	}
+
+	return wordCRC;
+}
+
+unsigned char TwoHexChar2Char(char ch1, char ch2)
+{
+	char Numb1;
+	char Numb2;
+
+	if (ch1 >= 'A')
+		Numb1 = (toupper(ch1) - '0' - 7) * 16;
+	else
+		Numb1 = (ch1 - '0') * 16;
+
+	if (ch2 >= 'A')
+		Numb2 = (toupper(ch2) - '0' - 7);
+	else
+		Numb2 = (ch2 - '0');
+
+	return (Numb1 + Numb2);
+}
+
+std::string HexString2Bytes(std::string strHex, const int &len /* = 3 */)
+{
+	byte value = 0;
+	std::string strBytes;
+	int nSize = strHex.size();
+	for (int i = 0; i < nSize; i += len)
+	{
+		strBytes.push_back(TwoHexChar2Char(strHex[i], strHex[i + 1]));
+	}
+
+	return strBytes;
+}
+
+std::string Bytes2HexString(const unsigned char *pbuffer, int nLen, char chSpace)
+{
+	std::string hex;
+	char szhex[5] = {0};
+	for (int i = 0; i < nLen; i++)
+	{
+		memset(szhex, 0, 5);
+		_stprintf_s(szhex, "%02X%c", pbuffer[i], chSpace);
+		hex.append(szhex);
+	}
+
+	return hex.substr(0, hex.size() - 1);
+}
+
+std::string Bytes2HexString(const unsigned char *pbuffer, int nLen)
+{
+	std::string hex;
+	char szhex[5] = {0};
+	for (int i = 0; i < nLen; i++)
+	{
+		memset(szhex, 0, 5);
+		_stprintf_s(szhex, "%02X", pbuffer[i]);
+		hex.append(szhex);
+	}
+
+	return hex;
+}
+
+BOOL IsValidString(LPCTSTR lpszString)
+{
+	if (lpszString == NULL)
+		return FALSE;
+
+	do
+	{
+		// ASCII可显示的字符;
+		if (*lpszString < 32 || *lpszString > 126)
+		{
+			return FALSE;
+		}
+	} while (*++lpszString);
+
+	return TRUE;
+}
+
+// 去除空格;
+std::string &trim(std::string &str)
+{
+	int nIndex = 0;
+	while ((nIndex = str.find_first_of(' ')) != std::string::npos)
+		str.erase(nIndex, 1);
+
+	return str;
+}
+
+CSIACP::CSIACP(void) //:m_vtcommand(g_siacp, g_siacp+sizeof(g_siacp)/sizeof(_SIACP_))
+{
+	m_pMainDlg = nullptr;
+	m_pSerial = NULL;
+	LoadCommand();
+}
+
+CSIACP::~CSIACP(void)
+{
+	CloseComm();
+}
+
+void CSIACP::SetMainDlg(CDialogEx* p)
+{
+	m_pMainDlg = p;
+}
+
+void CSIACP::ShowMessage(LPCTSTR lpMsg, LOG_ENUM logtype)
+{
+	if (m_pMainDlg && lpMsg)
+	{
+		CTCLCopyToolDlg* pMainDlg = (CTCLCopyToolDlg*)m_pMainDlg;
+		pMainDlg->SetOptionLog(std::string(lpMsg), logtype);
+	}
+}
+
+void CSIACP::LoadCommand()
+{
+	// 解析xml;
+	tinyxml2::XMLDocument doc;
+	if (tinyxml2::XML_SUCCESS != doc.LoadFile(_T("Siacp.xml")))
+	{
+		SaveCommand(g_vtSiacp, _T("Siacp.xml"));
+		return;
+	}
+
+	std::string ver;
+	std::string desc;
+	g_vtSiacp.clear();
+	tinyxml2::XMLElement *pXmlRoot = NULL;
+	if ((pXmlRoot = doc.RootElement()) != NULL)
+	{
+		if (_tcsicmp(pXmlRoot->Value(), "CommandList") == 0)
+		{
+			// 属性;
+			const tinyxml2::XMLAttribute *pAttr = pXmlRoot->FirstAttribute();
+			while (pAttr)
+			{
+				if (_tcsicmp(pAttr->Name(), "ver") == 0)
+				{
+					ver = pAttr->Value();
+				}
+
+				if (_tcsicmp(pAttr->Name(), "desc") == 0)
+				{
+					desc = pAttr->Value();
+				}
+
+				pAttr = pAttr->Next();
+			}
+
+			// 子项;
+			tinyxml2::XMLElement *pXmlElent = pXmlRoot->FirstChildElement();
+			while (pXmlElent)
+			{
+				_SIACP_ siacp;
+				if (_tcsicmp(pXmlElent->Value(), _T("Item")) == 0)
+				{
+					tinyxml2::XMLElement *pItem = pXmlElent->FirstChildElement();
+					while (pItem)
+					{
+						if (_tcsicmp(pItem->Value(), _T("Name")) == 0)
+						{
+							siacp.name = pItem->GetText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("HeadCode")) == 0)
+						{
+							siacp.head = pItem->GetText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("ucCommand")) == 0)
+						{
+							siacp.code = pItem->GetText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("Mark")) == 0)
+						{
+							siacp.mark = pItem->GetText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("MultiParams")) == 0)
+						{
+							siacp.bMulticode = pItem->BoolText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("ReadWaitTime")) == 0)
+						{
+							siacp.read_wait_time = pItem->IntText();
+						}
+						else if (_tcsicmp(pItem->Value(), _T("CmdWaitTime")) == 0)
+						{
+							siacp.cmd_wait_time = pItem->IntText();
+						}
+
+						pItem = pItem->NextSiblingElement();
+					}
+				}
+				g_vtSiacp.push_back(siacp);
+				pXmlElent = pXmlElent->NextSiblingElement();
+			}
+		}
+	}
+
+	Global::WriteTextLog("Load Comman xml");
+}
+
+void CSIACP::SaveCommand(std::vector<_SIACP_> &vtSiacp, std::string path)
+{
+	tinyxml2::XMLDocument doc;
+	//添加申明可以使用如下两行
+	tinyxml2::XMLDeclaration *declaration = doc.NewDeclaration();
+	doc.InsertFirstChild(declaration);
+
+	tinyxml2::XMLElement *root = doc.NewElement("CommandList");
+	root->SetAttribute("ver", "9.5");
+	root->SetAttribute("desc", "command info");
+	doc.InsertEndChild(root);
+
+	std::vector<_SIACP_>::iterator it = vtSiacp.begin();
+	for (; it != vtSiacp.end(); it++)
+	{
+		tinyxml2::XMLElement *pItem = doc.NewElement("Item");
+
+		tinyxml2::XMLElement *pName = doc.NewElement("Name");
+		pName->SetText(it->name.c_str());
+		pItem->InsertEndChild(pName);
+
+		tinyxml2::XMLElement *pHeadCode = doc.NewElement("HeadCode");
+		pHeadCode->SetText(it->head.c_str());
+		pItem->InsertEndChild(pHeadCode);
+
+		tinyxml2::XMLElement *pucCommand = doc.NewElement("ucCommand");
+		pucCommand->SetText(it->code.c_str());
+		pItem->InsertEndChild(pucCommand);
+
+		tinyxml2::XMLElement *pMark = doc.NewElement("Mark");
+		pMark->SetText(it->mark.c_str());
+		pItem->InsertEndChild(pMark);
+
+		tinyxml2::XMLElement *pMultiParams = doc.NewElement("MultiParams");
+		pMultiParams->SetText(it->bMulticode);
+		pItem->InsertEndChild(pMultiParams);
+
+		tinyxml2::XMLElement *pReadWaitTime = doc.NewElement("ReadWaitTime");
+		pReadWaitTime->SetText(it->read_wait_time);
+		pItem->InsertEndChild(pReadWaitTime);
+
+		tinyxml2::XMLElement* pCmdWaitTime = doc.NewElement("CmdWaitTime");
+		pCmdWaitTime->SetText(it->cmd_wait_time);
+		pItem->InsertEndChild(pCmdWaitTime);
+
+		root->InsertEndChild(pItem);
+	}
+
+	doc.SaveFile(path.c_str());
+}
+
+BOOL CSIACP::OpenComm(LPCTSTR lpszCom, DWORD dwBaudrate)
+{
+	if (lpszCom == NULL || lpszCom[0] == '\0')
+	{
+		LOG4C((LOG_WARN, "(lpszCom) Invalid parameter!"));
+		return FALSE;
+	}
+
+	// 释放打开的;
+	if (m_pSerial)
+		delete m_pSerial;
+	m_pSerial = NULL;
+
+	m_pSerial = new CSerialPort();
+	if (m_pSerial == NULL)
+	{
+		LOG4C((LOG_WARN, "(m_pSerial) Fail to create object!"));
+		return FALSE;
+	}
+
+	m_pSerial->Open(lpszCom, dwBaudrate);
+	if (m_pSerial->IsOpen() == FALSE)
+	{
+		delete m_pSerial;
+		m_pSerial = NULL;
+		LOG4C((LOG_WARN, "Open Serial Port Fail !"));
+		return FALSE;
+	}
+
+	// 超时值设置;
+	COMMTIMEOUTS comTimeOut;
+	comTimeOut.ReadIntervalTimeout = 50;
+	comTimeOut.ReadTotalTimeoutConstant = 8000;   // 读取所有字节总超时值;
+	comTimeOut.ReadTotalTimeoutMultiplier = 100;  // 读取1个字节超时值;
+	comTimeOut.WriteTotalTimeoutConstant = 5000;  // 写所有字节的总超时值;
+	comTimeOut.WriteTotalTimeoutMultiplier = 100; // 写1个字节的超时值;
+	m_pSerial->SetTimeouts(comTimeOut);
+
+	return TRUE;
+}
+
+void CSIACP::CloseComm()
+{
+	if (m_pSerial)
+		delete m_pSerial;
+	m_pSerial = NULL;
+}
+
+BOOL CSIACP::ExecSerialCommand(const _SIACP_ &siacp, std::string command)
+{
+	if (m_pSerial == NULL || !m_pSerial->IsOpen())
+	{
+		LOG4C((LOG_ERROR, "Serial Port un't Open!"));
+		return FALSE;
+	}
+
+	byte szRecive[BUFFER_LEN] = {0};
+	DWORD dwWritten = m_pSerial->Write(command.c_str(), command.size());
+	Global::WriteTextLog(_T("COM Write:%s"), Bytes2HexString((const byte *)command.c_str(), command.size(), ' ').c_str());
+	if (dwWritten != command.size())
+	{
+		Global::WriteTextLog("COM Written Error!");
+		return FALSE;
+	}
+
+	// 暂停时间;// 等待设备响应完成;
+	Sleep(siacp.read_wait_time);
+	DWORD dwBytesRead = m_pSerial->Read(szRecive, BUFFER_LEN);
+	if (dwBytesRead == 0)
+	{
+		Global::WriteTextLog("COM Read Error!");
+		return FALSE;
+	}
+
+	Global::WriteTextLog(_T("COM Read:%s\r"), Bytes2HexString(szRecive, dwBytesRead, ' ').c_str());
+
+	// 下一条命令等待时间;
+	Sleep(siacp.cmd_wait_time);
+	// 解析数据;
+	return ParserSerialData(m_vtdata, siacp, szRecive, dwBytesRead);
+}
+
+BOOL CSIACP::ParserSerialData(std::vector<RTN> &vtdata, const _SIACP_ &siacp, byte *pbuffer, DWORD dwlen)
+{
+	vtdata.clear();
+	if (pbuffer == NULL || dwlen < 5)
+		return FALSE;
+
+	// 返回码;
+	byte byReturn = TV_Return;
+	byte byHead = (byte)HexString2Bytes(siacp.head)[0];
+	byte byCode = (byte)HexString2Bytes(siacp.code)[0];
+
+	if (byHead == TV_Debug)
+	{
+		byReturn = TV_Return;
+	}
+	else if (byHead == TV_Panel_Debug)
+	{
+		byReturn = TV_Panel_Return;
+	}
+	else if (byHead == TV_Debug_Other)
+	{
+		byReturn = TV_Other_Return;
+	}
+	else
+	{
+		Global::WriteTextLog("COM Read Parser: Invalid return code!");
+		return FALSE;
+	}
+
+	std::string data;
+	data.append((const char *)pbuffer, dwlen);
+
+	int nABFE = 0;
+	std::string package;
+	int package_len = 0;
+	// 已取出的长度;
+	int nTookenLen = 0;
+	unsigned short usCRCValue;
+	while (true)
+	{
+		// 是否已取完所有数据;
+		if (nTookenLen >= dwlen)
+			break;
+
+		// 取出长度;
+		if ((byte)data.at(nTookenLen + 1) == 0xFE)
+		{
+			nABFE = 2; //FE占1字节,长度多占1字节;共多占2字节;
+			package_len = ((unsigned int)data[nTookenLen + 2] << 8) | (byte)data[nTookenLen + 3];
+		}
+		else
+		{
+			nABFE = 0;
+			package_len = data[nTookenLen + 1];
+		}
+
+		// 包长度是否在有效长度内;
+		if (package_len > (dwlen - nTookenLen))
+		{
+			Global::WriteTextLog("COM Read Parser: Incorrect length of returned data!");
+			return FALSE;
+		}
+
+		// 取出数据包;
+		package = data.substr(nTookenLen, nTookenLen + package_len);
+
+		// 校验包头是否正确;
+		if (byte(package[0]) != byReturn)
+		{
+			Global::WriteTextLog("COM Read Parser: Data Header Check Error!");
+			return FALSE;
+		}
+
+		// 校验crc;
+		usCRCValue = CRC16Calculate((unsigned char *)package.data(), package_len - 2);
+		if (((usCRCValue >> 8) & 0xFF) != (unsigned char)package[package_len - 2] || (usCRCValue & 0xFF) != (unsigned char)package[package_len - 1])
+		{
+			Global::WriteTextLog("COM Read Parser: Data CRC validation failure!");
+			return FALSE;
+		}
+
+		// 第一组返回,检测结果码
+		if (nTookenLen == 0)
+		{
+			if (package[2] != RC_OK)
+			{
+				Global::WriteTextLog("COM Read Parser: The return code of the response data is invalid!");
+				return FALSE;
+			}
+		}
+		else
+		{
+			// 响应数据的命令码 = 发送数据的命令码 - 1;
+			if (byte(package[2 + nABFE] - 1) != byCode)
+			{
+				Global::WriteTextLog("COM Read Parser: The command code of response data does not match the command code of sending data!");
+				return FALSE;
+			}
+
+			RTN rtn;
+			// 获取结果值;
+			if (siacp.bMulticode)
+			{
+				rtn.len = package_len - 6 - nABFE;
+				rtn.data = package.substr(4 + nABFE, package_len - 6 - nABFE);
+			}
+			else
+			{
+				rtn.len = package_len - 5 - nABFE;
+				rtn.data = package.substr(3 + nABFE, package_len - 5 - nABFE);
+			}
+			vtdata.push_back(rtn);
+		}
+
+		nTookenLen += package_len;
+	}
+
+	return TRUE;
+}
+
+const _SIACP_ *CSIACP::GetSiacp(std::string name)
+{
+	std::vector<_SIACP_>::iterator it = g_vtSiacp.begin();
+	for (; it != g_vtSiacp.end(); it++)
+	{
+		if (_tcsicmp(it->name.c_str(), name.c_str()) == 0)
+		{
+			return &*it;
+		}
+	}
+
+	return NULL;
+}
+
+std::string CSIACP::GetSiacpCommand(const _SIACP_ &siacp, std::string others, int othersLen)
+{
+	std::string command;
+	command.append(HexString2Bytes(siacp.head).c_str(), (siacp.head.size() + 1) / 3);
+	command.append(HexString2Bytes(siacp.code).c_str(), (siacp.code.size() + 1) / 3);
+	command.append(HexString2Bytes(siacp.mark).c_str(), (siacp.mark.size() + 1) / 3);
+	command.append(others.c_str(), othersLen);
+
+	// 长度;
+	byte szlen[2] = {0};
+	int len = command.size() + 3; // 3=长度本身占1位+2位crc;
+	if ((byte)command[1] == 0xFE)
+	{
+		szlen[0] = ((len + 1) >> 8) & 0xFF;
+		szlen[1] = (len + 1) & 0xFF;
+		command.insert(2, (char *)szlen, 2);
+	}
+	else
+	{
+		szlen[0] = len & 0xFF;
+		command.insert(1, (char *)szlen, 1);
+	}
+
+	// crc校验;
+	byte szcrc[2] = {0};
+	WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), command.size());
+	szcrc[0] = (usCRCValue >> 8) & 0xFF;
+	szcrc[1] = usCRCValue & 0xFF;
+	command.append((char *)szcrc, 2);
+
+	return command;
+}
+
+std::string CSIACP::GetSiacpCommand(std::string name, std::string others, int othersLen)
+{
+	std::string command;
+	std::vector<_SIACP_>::iterator it = g_vtSiacp.begin();
+	for (; it != g_vtSiacp.end(); it++)
+	{
+		if (_tcsicmp(name.c_str(), it->name.c_str()) == 0)
+		{
+			command.append(HexString2Bytes(it->head).c_str(), (it->head.size() + 1) / 3);
+			command.append(HexString2Bytes(it->code).c_str(), (it->code.size() + 1) / 3);
+			command.append(HexString2Bytes(it->mark).c_str(), (it->mark.size() + 1) / 3);
+			command.append(others.c_str(), othersLen);
+
+			// 长度;
+			byte szlen[2] = {0};
+			int len = command.size() + 3; // 长度本身占1位;
+			if ((byte)command[1] == 0xFE)
+			{
+				szlen[0] = ((len + 1) >> 8) & 0xFF;
+				szlen[1] = (len + 1) & 0xFF;
+				command.insert(2, (char *)szlen, 2);
+			}
+			else
+			{
+				szlen[0] = len & 0xFF;
+				command.insert(1, (char *)szlen, 1);
+			}
+
+			// crc校验;
+			byte szcrc[2] = {0};
+			int usCRCValue = CRC16Calculate((byte *)command.c_str(), command.size());
+			szcrc[0] = (usCRCValue >> 8) & 0xFF;
+			szcrc[1] = usCRCValue & 0xFF;
+			command.append((char *)szcrc, 2);
+
+			break;
+		}
+	}
+
+	return command;
+}
+
+BOOL CSIACP::SendCommand(std::string cmd_name, const byte *pszOthers, DWORD dwOthersLen)
+{
+	std::string others;
+	if (pszOthers && dwOthersLen > 0)
+	{
+		others.append((char *)pszOthers, dwOthersLen);
+	}
+
+	// 获取命令协议;
+	const _SIACP_ *pSiacp = GetSiacp(cmd_name);
+	if (pSiacp == NULL)
+	{
+		LOG4C((LOG_ERROR, "This command is not supported!"));
+		return FALSE;
+	}
+
+	std::string command = GetSiacpCommand(*pSiacp, others, dwOthersLen);
+	if (command.size() == 0)
+	{
+		LOG4C((LOG_ERROR, "Generation command failed!"));
+		return FALSE;
+	}
+
+	return ExecSerialCommand(*pSiacp, command);
+}
+
+BOOL CSIACP::SendCommand2(std::string cmd_name, std::string data /* = "" */, size_t nlen /* = 0 */)
+{
+	// 获取命令协议;
+	const _SIACP_ *pSiacp = GetSiacp(cmd_name);
+	if (pSiacp == NULL)
+	{
+		LOG4C((LOG_ERROR, "This command is not supported!"));
+		return FALSE;
+	}
+
+	std::string command = GetSiacpCommand(*pSiacp, data, nlen);
+	if (command.size() == 0)
+	{
+		LOG4C((LOG_ERROR, "Generation command failed!"));
+		return FALSE;
+	}
+
+	return ExecSerialCommand(*pSiacp, command);
+}
+
+BOOL CSIACP::SCBC_WaitTVBoot()
+{
+	byte szRecive[BUFFER_LEN] = { 0 };
+	DWORD dwBytesRead = m_pSerial->Read(szRecive, BUFFER_LEN);
+	if (dwBytesRead == 0)
+	{
+		if ( SCBC_EnterFactory() )
+		{
+			SCBC_LeaveFactory();
+			Global::WriteTextLog("TV Boot OK!");
+			return TRUE;
+		}		
+	}
+
+	return FALSE;
+}
+
+BOOL CSIACP::SCBC_MTKInit()
+{
+	if (m_pSerial == NULL)
+	{
+		LOG4C((LOG_ERROR, "CSerialPort对象未初始化"));
+		return FALSE;
+	}
+
+	if (!m_pSerial->IsOpen())
+	{
+		LOG4C((LOG_ERROR, "CSerialPort对象未打开串口"));
+		return FALSE;
+	}
+
+	unsigned char ucBufInitMTK8223[16] = {0x54, 0x8A, 0x51, 0x37, 0x56, 0x92, 0x1C, 0xB2, 0x50, 0x80, 0x50, 0x02, 0x50, 0x01, 0x50, 0xE2};
+	m_pSerial->Write(ucBufInitMTK8223, 16);
+	Sleep(50);
+
+	return TRUE;
+}
+
+// 对外接口;
+BOOL CSIACP::SCBC_EnterFactory()
+{
+	return SendCommand("EnterFactory");
+}
+
+BOOL CSIACP::SCBC_LeaveFactory()
+{
+	return SendCommand("LeaveFactory");
+}
+
+BOOL CSIACP::SCBC_WBInit()
+{
+	return SendCommand("WBInit");
+}
+
+BOOL CSIACP::SCBC_GetProjectId(int &pid)
+{
+	BOOL bRet = SendCommand("GetProjectId");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.len == 2)
+		{
+			pid = (byte)rtn.data[0] << 8;
+			pid += (byte)rtn.data[1];
+		}
+		else
+		{
+			pid = (byte)rtn.data[0];
+		}
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetSoftVersion(std::string &strVer)
+{
+	BOOL bRet = SendCommand("GetSoftVersion");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (!IsValidString(rtn.data.c_str()))
+		{
+			LOG4C((LOG_WARN, "tv version string is invalid!"));
+			return FALSE;
+		}
+
+		strVer.append(rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetDeviceId(std::string &strDid)
+{
+	BOOL bRet = SendCommand("GetDeviceId");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		strDid.append(rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetClientType(std::string &strClt)
+{
+	BOOL bRet = SendCommand("GetClientType");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (!IsValidString(rtn.data.c_str()))
+		{
+			LOG4C((LOG_WARN, "tv client type string is invalid!"));
+			return FALSE;
+		}
+		strClt.append(rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetMAC(std::string &strMac)
+{
+	BOOL bRet = SendCommand("GetMAC");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		strMac = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len, '-');
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetHDCPKey(std::string &strHDCP)
+{
+	BOOL bRet = SendCommand("GetHDCPKey");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		//strHDCP.append(rtn.data.c_str(), rtn.len);
+		strHDCP = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetHDCPKey22(std::string &strHDCP22)
+{
+	BOOL bRet = SendCommand("GetHDCPKey22");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		//strHDCP22.append(rtn.data.c_str(), rtn.len);
+		strHDCP22 = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetWidi(std::string &strWidi)
+{
+	BOOL bRet = SendCommand("GetWidi");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		//strWidi.append(rtn.data.c_str(), rtn.len);
+		strWidi = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetNetflixESN(std::string &strESN)
+{
+	BOOL bRet = SendCommand("GetNetflixESN");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		strESN.append(rtn.data.c_str(), rtn.len);
+		//strESN = Bytes2HexString((const byte*)rtn.data.c_str(), rtn.len, ' ');
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetWidevine(std::string &strWidevine)
+{
+	BOOL bRet = SendCommand("GetWidevine");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		//strWidevine.append(rtn.data.c_str(), rtn.len);
+		strWidevine = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetCiKey(std::string &strCikey)
+{
+	BOOL bRet = SendCommand("GetCiKey");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		//strCikey.append(rtn.data.c_str(), rtn.len);
+		strCikey = Bytes2HexString((const byte *)rtn.data.c_str(), rtn.len);
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetOSDLanguage(std::string &strOSDLan)
+{
+	BOOL bRet = SendCommand("GetOSDLanguage");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		strOSDLan.append(rtn.data.c_str(), rtn.len);
+		strOSDLan = Bytes2HexString((const byte*)rtn.data.c_str(), rtn.len, ' ');
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetShopLanguage(std::string &strShopLan)
+{
+	BOOL bRet = SendCommand("GetShopLanguage");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		strShopLan.append(rtn.data.c_str(), rtn.len);
+		strShopLan = Bytes2HexString((const byte*)rtn.data.c_str(), rtn.len, ' ');
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_GetChannel(std::string& channel)
+{
+	BOOL bRet = SendCommand("GetChannel");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		channel.append(rtn.data.c_str(), rtn.len);
+		channel = Bytes2HexString((const byte*)rtn.data.c_str(), rtn.len, ' ');
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_SetProjectId(const int &pid)
+{
+	std::string data;
+	if (pid > 0xFF)
+	{
+		data.append(1, (pid >> 8) & 0xFF);
+		data.append(1, pid & 0xFF);
+	}
+	else
+	{
+		data.append(1, pid & 0xFF);
+	}
+
+	return SendCommand2("SetProjectId", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetProjectId(std::string pid)
+{
+	return SCBC_SetProjectId(atoi(pid.c_str()));
+}
+
+BOOL CSIACP::SCBC_SetProjectId(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetProjectId", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetDeviceId(std::string strDeviceId)
+{
+	if (strDeviceId.size() < 40)
+	{
+		return FALSE;
+	}
+
+	return SendCommand2("SetDeviceId", strDeviceId, strDeviceId.size());
+}
+
+BOOL CSIACP::SCBC_SetDeviceId(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetDeviceId", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetMAC(std::string strMac)
+{
+	if (strMac.size() < 16)
+		return FALSE;
+
+	std::string data = HexString2Bytes(strMac);
+	return SendCommand2("SetMAC", data, (strMac.size() + 1) / 3);
+}
+
+BOOL CSIACP::SCBC_SetMAC(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetMAC", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetHDCPKey(std::string strHDCP, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strHDCP, bHasSpace ? 3 : 2);
+	return SendCommand2("SetHDCPKey", data, (strHDCP.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetHDCPKey(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetHDCPKey", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetHDCPKey22(std::string strHDCP22, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strHDCP22, bHasSpace ? 3 : 2);
+	return SendCommand2("SetHDCPKey22", data, (strHDCP22.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetHDCPKey22(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetHDCPKey22", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetNetflixESN(std::string strESN, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strESN, bHasSpace ? 3 : 2);
+	return SendCommand2("SetNetflixESN", data, (strESN.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetNetflixESN(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetNetflixESN", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetWidi(std::string strWidi, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strWidi, bHasSpace ? 3 : 2);
+	return SendCommand2("SetWidi", data, (strWidi.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetWidi(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetWidi", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetWidevine(std::string strWidevine, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strWidevine, bHasSpace ? 3 : 2);
+	return SendCommand2("SetWidevine", data, (strWidevine.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetWidevine(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetWidevine", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetCiKey(std::string strCiKey, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(strCiKey, bHasSpace ? 3 : 2);
+	return SendCommand2("SetCiKey", data, (strCiKey.size() + 1) / (bHasSpace ? 3 : 2));
+}
+
+BOOL CSIACP::SCBC_SetCiKey(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetCiKey", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetOSDLanguage(std::string lan, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(lan, bHasSpace ? 3 : 2);
+	return SendCommand2("SetOSDLanguage", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetOSDLanguage(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetOSDLanguage", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetShopLanguage(std::string lan, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(lan, bHasSpace ? 3 : 2);
+	return SendCommand2("SetShopLanguage", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetShopLanguage(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetShopLanguage", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetChannel(std::string channel, BOOL bHasSpace /* = TRUE */)
+{
+	std::string data = HexString2Bytes(channel, bHasSpace ? 3 : 2);
+	return SendCommand2("SetChannel", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetChannel(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetChannel", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetWBNormal(std::string data)
+{
+	return SendCommand2("SetWBNormal", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetWBNormal(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetWBNormal", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetWBCool(std::string data)
+{
+	return SendCommand2("SetWBCool", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetWBCool(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetWBCool", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_SetWBWarm(std::string data)
+{
+	return SendCommand2("SetWBWarm", data, data.size());
+}
+
+BOOL CSIACP::SCBC_SetWBWarm(const byte *pBuffer, const int &nLen)
+{
+	return SendCommand("SetWBWarm", pBuffer, nLen);
+}
+
+BOOL CSIACP::SCBC_CheckDeviceId()
+{
+	BOOL bRet = SendCommand("CheckDeviceId");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x03 || bydata == 0x02)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckMAC()
+{
+	BOOL bRet = SendCommand("CheckMAC");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x03 || bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckHDCP()
+{
+	BOOL bRet = SendCommand("CheckHDCP");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckHDCP22()
+{
+	BOOL bRet = SendCommand("CheckHDCP22");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckNetflixESN()
+{
+	BOOL bRet = SendCommand("CheckNetflixESN");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckWidi()
+{
+	BOOL bRet = SendCommand("CheckWidi");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckWidevine()
+{
+	BOOL bRet = SendCommand("CheckWidevine");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_CheckCikey()
+{
+	BOOL bRet = SendCommand("CheckCikey");
+	if (bRet)
+	{
+		if (m_vtdata.size() == 0)
+		{
+			LOG4C((LOG_WARN, "No data return!"));
+			return FALSE;
+		}
+
+		RTN rtn = m_vtdata.at(0);
+		if (rtn.data.size() == 0)
+		{
+			return FALSE;
+		}
+
+		byte bydata = (byte)rtn.data.at(0);
+		if (bydata == 0x01)
+			return TRUE;
+		else
+			return FALSE;
+	}
+
+	return bRet;
+}
+
+BOOL CSIACP::SCBC_StarWarmUpMode()
+{
+	return SendCommand("StarWarmUpMode");
+}
+
+BOOL CSIACP::SCBC_StopWarmUpMode()
+{
+	return SendCommand("StopWarmUpMode");
+}
+
+//////////////////////////////////////////////////////////////////////////
+COTA::COTA()
+{
+	m_pMainDlg = nullptr;
+	m_curl.Initialize();
+}
+
+COTA::~COTA()
+{
+}
+
+void COTA::SetMainDlg(CDialogEx* p)
+{
+	m_pMainDlg = p;
+}
+
+void COTA::ShowMessage(LPCTSTR lpMsg, LOG_ENUM logtype)
+{
+	if (m_pMainDlg && lpMsg)
+	{
+		CTCLCopyToolDlg* pMainDlg = (CTCLCopyToolDlg*)m_pMainDlg;
+		pMainDlg->SetOptionLog(std::string(lpMsg), logtype);
+	}
+}
+
+BOOL COTA::HttpGet(std::string host, std::string context, std::string &result, DATATYPE dt)
+{
+	//host = CharEncoding::EnCode_UTF8URL(host.c_str());
+	//context = CharEncoding::EnCode_UTF8URL(context.c_str());
+	context = CharEncoding::ASCII2UTF8(context.c_str());
+	m_curl.SetHeaders("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*");
+	m_curl.SetHeaders("Accept-Language: zh-cn");
+	if (dt == DATA_JSON)
+		m_curl.SetHeaders("Content-Type: application/json;charset=utf-8");
+
+	int nRecCode = CURLE_OK;
+	if (_tcsstr(host.c_str(), "https://"))
+		nRecCode = m_curl.Gets(host + context, result);
+	else
+		nRecCode = m_curl.Get(host + context, result);
+
+	if (CURLE_OK != nRecCode)
+		LOG4C((LOG_NOTICE, "请求失败:%s, 错误码=%ld", context.c_str(), nRecCode));
+
+	return CURLE_OK == nRecCode;
+}
+
+BOOL COTA::HttpPost(std::string host, std::string context, std::string &result, DATATYPE dt)
+{
+	context = CharEncoding::ASCII2UTF8(context.c_str());
+	m_curl.SetHeaders("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*");
+	m_curl.SetHeaders("Accept-Language: zh-cn");
+	if (dt == DATA_JSON)
+		m_curl.SetHeaders("Content-Type: application/json;charset=utf-8");
+
+	int nRecCode = CURLE_OK;
+	if (_tcsstr(host.c_str(), "https://"))
+		nRecCode = m_curl.Posts(host, context, result);
+	else
+		nRecCode = m_curl.Posts(host, context, result);
+
+	result = CharEncoding::DeCode_URLUTF8(result.c_str());
+
+	if (CURLE_OK != nRecCode)
+	{
+		TCHAR szMsg[250] = {0};
+		_stprintf_s(szMsg, _T("http request failed, curl error code = %d\r"), nRecCode);
+		ShowMessage(szMsg);
+		LOG4C((LOG_NOTICE, "请求失败:%s, 错误码=%ld\n", context.c_str(), nRecCode));
+	}
+
+	std::string api = host.substr(host.find_last_of('/') + 1);
+#ifdef _DEBUG
+	LOG4C((LOG_NOTSET, "\n地址:%s\n报文:%s\n结果:%s\n", host.c_str(), context.c_str(), result.c_str()));
+#else
+	LOG4C((LOG_NOTSET, "\n地址:%s\n报文:%s\n结果:%s\n", api.c_str(), context.c_str(), result.c_str()));
+#endif
+	return CURLE_OK == nRecCode;
+}
+
+BOOL COTA::GetMIDInfo(MIDInfo &mid, std::string bid, std::string strMacs, std::string iptvid, std::string version)
+{
+	// Json数据;
+	cJSON *pJson = cJSON_CreateObject();
+	cJSON_AddStringToObject(pJson, "clientType", iptvid.c_str());
+	cJSON_AddStringToObject(pJson, "version", version.c_str());
+	cJSON_AddStringToObject(pJson, "mac", strMacs.c_str());
+	cJSON_AddStringToObject(pJson, "bid", trim(bid).c_str());
+	char *pJsonText = cJSON_Print(pJson);
+
+	// post请求;
+	std::string name, type;
+	std::string host, result, context;
+	context = pJsonText;
+
+	host = Global::g_bTestHost ? _T("http://test.admin.uc.qhmoka.com/scbc-server/clientType/getMessage.do") : _T("https://cn.uc.qhmoka.com/scbc-server/clientType/getMessage.do");
+	BOOL bRet = HttpPost(host, context, result, DATA_JSON);
+	if (!bRet)
+	{
+		LOG4C((LOG_WARN, "Post request failed!"));
+		goto end;
+	}
+
+	// 解析返回值;
+	pJson = cJSON_Parse(result.c_str());
+	if (pJson == NULL)
+	{
+		bRet = FALSE;
+		LOG4C((LOG_WARN, "JSON parsing failure:post=%s;return=%s\n", context.c_str(), result.c_str()));
+		goto end;
+	}
+
+	mid.message = cJSON_GetObjectItem(pJson, "message") ? cJSON_GetObjectItem(pJson, "message")->valuestring : "";
+	mid.code = cJSON_GetObjectItem(pJson, "code") ? cJSON_GetObjectItem(pJson, "code")->valuestring : "";
+	mid.factoryname = cJSON_GetObjectItem(pJson, "factoryName") ? (cJSON_GetObjectItem(pJson, "factoryName")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "factoryName")->valuestring : "") : "";
+	mid.factoryNum = cJSON_GetObjectItem(pJson, "factoryNum") ? (cJSON_GetObjectItem(pJson, "factoryNum")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "factoryNum")->valuestring : "") : "";
+	mid.version = cJSON_GetObjectItem(pJson, "version") ? (cJSON_GetObjectItem(pJson, "version")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "version")->valuestring : "") : "";
+	mid.projectid = cJSON_GetObjectItem(pJson, "projectId") ? (cJSON_GetObjectItem(pJson, "projectId")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "projectId")->valuestring : "") : "";
+	mid.clienttype = cJSON_GetObjectItem(pJson, "clientType") ? (cJSON_GetObjectItem(pJson, "clientType")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "clientType")->valuestring : "") : "";
+	mid.host = cJSON_GetObjectItem(pJson, "host") ? (cJSON_GetObjectItem(pJson, "host")->valuestring != NULL ? cJSON_GetObjectItem(pJson, "host")->valuestring : "") : "";
+	cJSON *pObj = cJSON_GetObjectItem(pJson, "obj");
+	if (pObj == NULL)
+	{
+		bRet = FALSE;
+		LOG4C((LOG_WARN, "JSON parsing failure:post=%s;return=%s\n", context.c_str(), result.c_str()));
+		goto end;
+	}
+
+	if (_tcsicmp(mid.code.c_str(), "1000") != 0)
+	{
+		bRet = FALSE;
+		LOG4C((LOG_WARN, "return invalid data:post=%s;return=%s\n", context.c_str(), result.c_str()));
+		goto end;
+	}
+
+	if (mid.host.size() == 0)
+	{
+		bRet = FALSE;
+		LOG4C((LOG_WARN, "return invalid data:post=%s;return=%s\n", context.c_str(), result.c_str()));
+		goto end;
+	}
+
+	// 清空
+	Global::g_AutoOnlineChassis = Global::CHASSIS();
+	Global::g_AutoOnlineChassis.ProjectID = _ttoi(mid.projectid.c_str());
+	Global::g_AutoOnlineChassis.url = mid.host;
+	Global::g_AutoOnlineChassis.name = bid;
+
+	mid.obj.clear();
+	cJSON *pItem = NULL;
+	int nSize = cJSON_GetArraySize(pObj);
+	for (int i = 0; i < nSize; i++)
+	{
+		pItem = cJSON_GetArrayItem(pObj, i);
+		if (pItem)
+		{
+			name = cJSON_GetObjectItem(pItem, "name") ? cJSON_GetObjectItem(pItem, "name")->valuestring : "";
+			type = cJSON_GetObjectItem(pItem, "type") ? cJSON_GetObjectItem(pItem, "type")->valuestring : "";
+			mid.obj.insert(pair<std::string, std::string>(name,type));
+
+			if ( _tcsicmp(name.c_str(), _T("DeviceID")) == 0 )
+			{
+				Global::g_AutoOnlineChassis.IsCopyDID = true;
+				Global::g_AutoOnlineChassis.ClientType = type;
+				if (_tcsicmp(type.c_str(), _T("SCBC")) == 0 || _tcsicmp(type.c_str(), _T("新用户系统")) == 0)
+					Global::g_AutoOnlineChassis.ClientType = "tcl_unknown_model";;
+			}
+			else if (_tcsicmp(name.c_str(), _T("MAC")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyMAC = true;
+				Global::g_AutoOnlineChassis.MACType = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("HDCP_KEY")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyKEY = true;
+				Global::g_AutoOnlineChassis.HDCPKeyType = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("CI_PLUS_KEY")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyCikey = true;
+				Global::g_AutoOnlineChassis.CIKeyType = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("WiDi")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyWiDi = true;
+				Global::g_AutoOnlineChassis.WiDiType = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("Widevine_KEY")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyWidevine = true;
+				Global::g_AutoOnlineChassis.WidevineType = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("HDCP2.2_KEY")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyKEY2_2 = true;
+				Global::g_AutoOnlineChassis.HDCPKey22Type = type;
+			}
+			else if (_tcsicmp(name.c_str(), _T("NETFILX_ESN")) == 0)
+			{
+				Global::g_AutoOnlineChassis.IsCopyESN = true;
+				Global::g_AutoOnlineChassis.ESNType = type;
+			}
+		}
+	}
+
+	if ( mid.projectid.size() != 0 )
+	{
+		Global::g_AutoOnlineChassis.IsWritePID = true;
+	}
+
+	LOG4C((LOG_NOTSET, "post success:post=%s;return=%s\n", context.c_str(), result.c_str()));
+
+end:
+	// 释放Json;
+	if (pJsonText)
+		delete pJsonText;
+	pJsonText = NULL;
+	cJSON_Delete(pJson);
+
+	if ( mid.factoryname.size() )
+		UpgradeCheck(mid.factoryNum);
+
+	return bRet;
+}
+
+BOOL COTA::GetKeyInfo(std::string host, std::string context, std::string keyname, std::string valuename, std::string &value)
+{
+	std::string result;
+	if (!HttpPost(host, context, result))
+	{
+		return FALSE;
+	}
+
+	// 无数据;
+	if (result.size() == 0)
+	{
+		LOG4C((LOG_ERROR, "(http=%s) No data return!", context.c_str()));
+		ShowMessage(_T("http No data return!\r"));
+		return FALSE;
+	}
+
+	// 解析xml;
+	tinyxml2::XMLDocument doc;
+	if (tinyxml2::XML_SUCCESS != doc.Parse(result.c_str()))
+	{
+		LOG4C((LOG_ERROR, "(http=%s) this post return xml invalid!", context.c_str()));
+		ShowMessage(_T("http return invalid xml data!\r"));
+		return FALSE;
+	}
+
+	std::string code;
+	std::string desc;
+	tinyxml2::XMLElement *pXmlRoot = NULL;
+	if ((pXmlRoot = doc.RootElement()) != NULL)
+	{
+		if (_tcsicmp(pXmlRoot->Value(), "response") == 0)
+		{
+			// 属性;
+			const tinyxml2::XMLAttribute *pAttr = pXmlRoot->FirstAttribute();
+			while (pAttr)
+			{
+				if (_tcsicmp(pAttr->Name(), "code") == 0)
+				{
+					code = pAttr->Value();
+				}
+
+				if (_tcsicmp(pAttr->Name(), "desc") == 0)
+				{
+					desc = pAttr->Value();
+				}
+
+				pAttr = pAttr->Next();
+			}
+
+			if (_tcsicmp(code.c_str(), "200") != 0)
+			{
+				LOG4C((LOG_ERROR, "(http=%s) Code is not equal to 200, desc=%s!", context.c_str(), desc.c_str()));
+				TCHAR szMsg[250] = { 0 };
+				_stprintf_s(szMsg, _T("http Code is not equal to 200, desc=%s\r"), desc.c_str());
+				ShowMessage(szMsg);
+				return FALSE;
+			}
+
+			if (keyname.size() == 0 || valuename.size() == 0)
+				return TRUE;
+
+			// 子项;
+			std::string name; // std::string value;
+			tinyxml2::XMLElement *pXmlElent = pXmlRoot->FirstChildElement();
+			while (pXmlElent)
+			{
+				// 中文;
+				name = CharEncoding::UTF82ASCII(pXmlElent->Value());
+				if (_tcsicmp(name.c_str(), keyname.c_str()) == 0)
+				{
+					pAttr = pXmlElent->FirstAttribute();
+					while (pAttr)
+					{
+						if (_tcsicmp(pAttr->Name(), valuename.c_str()) == 0)
+						{
+							value = pAttr->Value();
+							break;
+						}
+						pAttr = pAttr->Next();
+					}
+
+					break;
+				}
+				pXmlElent = pXmlElent->NextSiblingElement();
+			}
+
+			if (value.size() == 0)
+			{
+				LOG4C((LOG_ERROR, "(http=%s)xml value is empty!", context.c_str()));
+				ShowMessage(_T("http xml value is empty!\r"));
+				return FALSE;
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+void COTA::UpgradeCheck(std::string factoryNum)
+{
+	// 当前文件版本号、产品版本号;
+	WORD sFileVersion[4] = {0};
+	WORD sProductVerion[4] = {0};
+	Global::GetVersion(Global::g_szCurModulePath, sFileVersion, sProductVerion);
+	TCHAR szVersion[128] = {0};
+	_stprintf_s(szVersion, _T("%d.%d.%d.%d"), sFileVersion[0], sFileVersion[1], sFileVersion[2], sFileVersion[3]);
+
+	// Json数据;
+	cJSON *pJson = cJSON_CreateObject();
+	cJSON_AddStringToObject(pJson, "appid", "SCBC_Factory_Tools");
+	cJSON_AddStringToObject(pJson, "devicemodel", "SCBC_Factory_Tools");
+	cJSON_AddStringToObject(pJson, "dnum", factoryNum.c_str()); //工厂名;
+	cJSON_AddStringToObject(pJson, "ver", szVersion);
+	cJSON_AddStringToObject(pJson, "type", "pc");
+	char *pJsonText = cJSON_Print(pJson);
+
+	// post请求;
+	std::string strHttpUrl, strResHttp, strContext, strErrCode, strErrValue, strCount;
+	strContext = pJsonText;
+	// 正式上线地址;
+	strHttpUrl = _T("https://cn.ota.qhmoka.com/ota-services/upmp/upgradeInterfaceForPC");
+	HttpPost(strHttpUrl.c_str(), pJsonText, strResHttp, DATA_JSON);
+
+	// 释放Json;
+	if (pJsonText)
+		delete pJsonText;
+	pJsonText = NULL;
+	cJSON_Delete(pJson);
+	pJson = NULL;
+
+	if (strResHttp.size() == 0)
+	{
+		LOG4C((LOG_WARN, "返回结果空:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		ReportUpgrade(FALSE, szVersion, factoryNum);
+		return;
+	}
+
+	// 将json结果转换成结构体;
+	Global::__update_result__ upresult;
+	pJson = cJSON_Parse(strResHttp.c_str());
+	if (pJson == NULL)
+	{
+		cJSON_Delete(pJson);
+		LOG4C((LOG_WARN, "cJSON解析时出错:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		ReportUpgrade(FALSE, szVersion, factoryNum);
+		return;
+	}
+	upresult.servertime = cJSON_GetObjectItem(pJson, "servertime") ? cJSON_GetObjectItem(pJson, "servertime")->valuestring : "";
+	upresult.callid = cJSON_GetObjectItem(pJson, "callid") ? cJSON_GetObjectItem(pJson, "callid")->valuestring : "";
+	upresult.note = cJSON_GetObjectItem(pJson, "note") ? cJSON_GetObjectItem(pJson, "note")->valuestring : "";
+	upresult.status = cJSON_GetObjectItem(pJson, "state") ? cJSON_GetObjectItem(pJson, "state")->valuestring : "";
+	upresult.language = cJSON_GetObjectItem(pJson, "language") ? cJSON_GetObjectItem(pJson, "language")->valuestring : "";
+	upresult.apiversion = cJSON_GetObjectItem(pJson, "apiversion") ? cJSON_GetObjectItem(pJson, "apiversion")->valuestring : "";
+	cJSON *pUpdate = cJSON_GetObjectItem(pJson, "upgrade");
+	if (pUpdate == NULL)
+	{
+		cJSON_Delete(pJson);
+		LOG4C((LOG_WARN, "升级接口没有升级内容:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		//ReportUpdateResult(FALSE, strVer);
+		return;
+	}
+	upresult.upcontent.now = cJSON_GetObjectItem(pUpdate, "now") ? cJSON_GetObjectItem(pUpdate, "now")->valuestring : "";
+	upresult.upcontent.type = cJSON_GetObjectItem(pUpdate, "type") ? cJSON_GetObjectItem(pUpdate, "type")->valuestring : "";
+	upresult.upcontent.appid = cJSON_GetObjectItem(pUpdate, "appid") ? cJSON_GetObjectItem(pUpdate, "appid")->valuestring : "";
+	upresult.upcontent.apptype = cJSON_GetObjectItem(pUpdate, "apptype") ? cJSON_GetObjectItem(pUpdate, "apptype")->valuestring : "";
+	upresult.upcontent.version = cJSON_GetObjectItem(pUpdate, "version") ? cJSON_GetObjectItem(pUpdate, "version")->valuestring : "";
+	upresult.upcontent.verid = cJSON_GetObjectItem(pUpdate, "verid") ? cJSON_GetObjectItem(pUpdate, "verid")->valuestring : "";
+	upresult.upcontent.md5 = cJSON_GetObjectItem(pUpdate, "md5") ? cJSON_GetObjectItem(pUpdate, "md5")->valuestring : "";
+	upresult.upcontent.size = cJSON_GetObjectItem(pUpdate, "size") ? cJSON_GetObjectItem(pUpdate, "size")->valuestring : "";
+	upresult.upcontent.minicon = cJSON_GetObjectItem(pUpdate, "minicon") ? cJSON_GetObjectItem(pUpdate, "minicon")->valuestring : "";
+	upresult.upcontent.midicon = cJSON_GetObjectItem(pUpdate, "midicon") ? cJSON_GetObjectItem(pUpdate, "midicon")->valuestring : "";
+	upresult.upcontent.fileurl = cJSON_GetObjectItem(pUpdate, "fileurl") ? cJSON_GetObjectItem(pUpdate, "fileurl")->valuestring : "";
+	upresult.upcontent.increment = cJSON_GetObjectItem(pUpdate, "increment") ? cJSON_GetObjectItem(pUpdate, "increment")->valuestring : "";
+	upresult.upcontent.appendver = cJSON_GetObjectItem(pUpdate, "appendver") ? cJSON_GetObjectItem(pUpdate, "appendver")->valuestring : "";
+	upresult.upcontent.updatetime = cJSON_GetObjectItem(pUpdate, "updatetime") ? cJSON_GetObjectItem(pUpdate, "updatetime")->valuestring : "";
+	// 释放cJSON资源;
+	cJSON_Delete(pJson);
+	pJson = NULL;
+
+	if (upresult.note.compare("成功") != 0)
+	{
+		LOG4C((LOG_WARN, "升级接口http返回出错:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		ReportUpgrade(FALSE, szVersion, factoryNum);
+		return;
+	}
+
+	// 下载文件;
+	TCHAR szNewPath[MAX_PATH] = {0};
+	_stprintf_s(szNewPath, _T("%s%s.exe"), Global::g_szCurModuleDir, upresult.upcontent.version.c_str());
+	if (_tcsicmp(szVersion , upresult.upcontent.version.c_str()) > 0 )
+	{
+		LOG4C((LOG_NOTICE, "当前版本(%s)比服务器版本(%s)新", szVersion, upresult.upcontent.version.c_str()));
+		return;
+	}
+
+	// 保存成文件;
+	if (!DownloadFile(upresult.upcontent.fileurl, szNewPath))
+	{
+		LOG4C((LOG_NOTICE, "下载升级文件失败"));
+		ReportUpgrade(FALSE, szVersion, factoryNum);
+	}
+	else
+	{
+		ReportUpgrade(TRUE, szVersion, factoryNum);
+	}
+
+	Sleep(500);
+
+	MessageBox(NULL, _T("found out lastest software version, you need restart apps."), _T("Tips"), MB_OK | MB_TOPMOST | MB_ICONINFORMATION);
+
+	// 启动程序;
+	::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); //某些情况下要初始化COM才能使用ShellExecuteEx;
+	SHELLEXECUTEINFO stuExecInfo = {0};
+	CString strParamters;
+	strParamters.Format(_T("--pid %ld --oldpath \"%s\" --newpath \"%s\" --killproc 1"), GetCurrentProcessId(), Global::g_szCurModulePath, szNewPath);
+	//strParamters.Format(_T("--pid %ld --oldpath \"%s\" --newpath \"%s\" --killproc 0"), GetCurrentProcessId(), g_szCurModulePath, szNewPath);
+	stuExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
+	stuExecInfo.lpFile = _T("rename.exe");
+	stuExecInfo.nShow = SW_HIDE;
+	stuExecInfo.lpParameters = strParamters;
+	stuExecInfo.lpVerb = _T("open");
+	stuExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
+
+	if (!ShellExecuteEx(&stuExecInfo))
+	{
+		DWORD dwError = GetLastError();
+		LOG4C((LOG_ERROR, "执行rename程序失败,错误码=%d", dwError))
+		return;
+	}
+
+	HANDLE hProcess = stuExecInfo.hProcess;
+	if (hProcess != NULL)
+		CloseHandle(hProcess);
+	else
+		LOG4C((LOG_WARN, "执行rename程序失败,进程句柄空"));
+
+	// 提示升级程序执行;
+	LOG4C((LOG_NOTICE, "后台升级程序执行成功,程序退出后自动覆盖文件"));
+}
+
+void COTA::ReportUpgrade(BOOL bUpgrade, std::string ver, std::string num)
+{
+	// Json数据;
+	cJSON *pJson = cJSON_CreateObject();
+	cJSON_AddStringToObject(pJson, "appid", "SCBC_Factory_Tools");
+	cJSON_AddStringToObject(pJson, "devmodel", "SCBC_Factory_Tools");
+	cJSON_AddStringToObject(pJson, "dnum", num.c_str());
+	cJSON_AddStringToObject(pJson, "ver", ver.c_str());
+	cJSON_AddStringToObject(pJson, "result", bUpgrade ? "Success" : "FAILURE");
+	cJSON_AddStringToObject(pJson, "type", "pc");
+	char *pJsonText = cJSON_Print(pJson);
+
+	// post请求;
+	std::string strHttpUrl, strResHttp, strContext, strErrCode, strErrValue, strCount;
+	strContext = pJsonText;
+	strHttpUrl = _T("https://cn.ota.qhmoka.com/ota-services/upmp/operateInterfaceForPC");
+	HttpPost(strHttpUrl.c_str(), strContext.c_str(), strResHttp, DATA_JSON);
+
+	// 释放Json;
+	if (pJsonText)
+		delete pJsonText;
+	pJsonText = NULL;
+	cJSON_Delete(pJson);
+	pJson = NULL;
+
+	pJson = cJSON_Parse(strResHttp.c_str());
+	if (pJson == NULL)
+	{
+		LOG4C((LOG_WARN, "解析JSON失败:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		return;
+	}
+
+	std::string result = cJSON_GetObjectItem(pJson, "state") ? cJSON_GetObjectItem(pJson, "state")->valuestring : "";
+	cJSON_Delete(pJson);
+	pJson = NULL;
+}
+
+BOOL COTA::DownloadFile(std::string url, std::string savePath)
+{
+	std::string result;
+	if (HttpGet(url, "", result))
+	{
+		FILE* pf = nullptr;
+		if (fopen_s(&pf, savePath.c_str(), "wb") == 0 )
+		{
+			if ( pf )
+			{
+				fwrite(result.data(), result.size(), 1, pf);
+				fclose(pf);
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+BOOL COTA::ReportLog(TReportData& repdata)
+{
+	// Json数据;
+	cJSON* pJson = cJSON_CreateObject();
+	cJSON_AddStringToObject(pJson, "reportType", repdata.report_type.c_str());
+
+	cJSON *pObj = cJSON_AddObjectToObject(pJson, _T("reportData"));
+	for ( auto it : repdata.report_data)
+	{
+		cJSON_AddStringToObject(pObj, it.first.c_str(), it.second.c_str());
+	}
+	
+	char* pJsonText = cJSON_Print(pJson);
+
+	// post请求;
+	std::string strHttpUrl, strResHttp, strContext;
+	strContext = pJsonText;
+	strHttpUrl = _T("https://cn.ota.qhmoka.com/ota-services/upmp/reportToolsLog.do");
+	HttpPost(strHttpUrl.c_str(), strContext.c_str(), strResHttp, DATA_JSON);
+
+	// 释放Json;
+	if (pJsonText)
+		delete pJsonText;
+	pJsonText = NULL;
+	cJSON_Delete(pJson);
+	pJson = NULL;
+
+	pJson = cJSON_Parse(strResHttp.c_str());
+	if (pJson == NULL)
+	{
+		LOG4C((LOG_WARN, "解析JSON失败:post=%s;return=%s", strContext.c_str(), strResHttp.c_str()));
+		return FALSE;
+	}
+
+	std::string result = cJSON_GetObjectItem(pJson, "code") ? cJSON_GetObjectItem(pJson, "code")->valuestring : "";
+	cJSON_Delete(pJson);
+	pJson = NULL;
+	if ( _tcsicmp(result.c_str(), _T("200")) == 0 )
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL COTA::GetVCode(std::string mac, std::string& vcode)
+{
+	std::string result;
+	std::string host = _T("http://test.admin.ota.qhmoka.com/IDManage/export/getvcode.do?");
+	std::string context = _T("macAddress=");
+	context.append(mac);
+	if (!HttpPost(host, context, result))
+		return FALSE;
+
+	// 无数据;
+	if (result.size() == 0)
+	{
+		LOG4C((LOG_ERROR, "(http=%s) No data return!", context.c_str()));
+		return FALSE;
+	}
+
+	// 解析xml;
+	tinyxml2::XMLDocument doc;
+	if (tinyxml2::XML_SUCCESS != doc.Parse(result.c_str()))
+	{
+		LOG4C((LOG_ERROR, "(http=%s) this post return xml invalid!", context.c_str()));
+		return FALSE;
+	}
+}

+ 244 - 0
TCL Copy Tool/TCL Copy Tool/OTA.h

@@ -0,0 +1,244 @@
+#ifndef __OTA_20190702__
+#define __OTA_20190702__
+
+#include "SerialPort.h"
+#include "CurlClient.h"
+#include "../cJson/cJSON.h"
+
+#define BUFFER_LEN 10240
+#pragma once
+
+typedef struct __SIACP__
+{
+	std::string name; // 命令描述;
+	std::string head; // 命令头;
+	std::string code; // 命令码;
+	std::string mark; // 特殊标记;
+	bool bMulticode = false;	// 命令码是否多参数;
+	int cmd_wait_time = 100;	// 两条串口指令间隔时间;
+	int read_wait_time = 100;	// 写完串口后,等待多久读;
+} _SIACP_;
+
+
+// 包头码(包引导码)
+enum PHeader {
+	TV_Debug = 0xAA,
+	TV_Return = 0xAB,
+	TV_Panel_Debug = 0xAC,
+	TV_Panel_Return = 0xAD,
+	TV_Debug_Other = 0xAE,
+	TV_Other_Return = 0xAF,
+};
+
+// 命令结果码;
+enum RCode {
+	RC_OK = 0x0A,      // 命令执行通过;
+	RC_ERR = 0x0E,     // 命令错误或无法执行;
+	RC_LOSE = 0x0F,    // 命令丢失(链路层出错);
+};
+
+//////////////////////////////////////////////////////////////////////////
+enum LOG_ENUM
+{
+	NORMAL_LOG = 0,
+	ERROR_LOG,
+	OK_LOG,
+	INFO_LOG
+};
+
+extern std::string HexString2Bytes(std::string strHex, const int& len /* = 3 */);
+extern std::string Bytes2HexString(const unsigned char* pbuffer, int nLen);
+extern std::string Bytes2HexString(const unsigned char* pbuffer, int nLen, char chSpace);
+
+class CSIACP
+{
+public:
+	CSIACP(void);
+	~CSIACP(void);
+
+	void SetMainDlg(CDialogEx* p);
+	void ShowMessage(LPCTSTR lpMsg, LOG_ENUM logtype = NORMAL_LOG);
+protected:
+	CSerialPort* m_pSerial;
+	CDialogEx* m_pMainDlg;
+	typedef struct __RTN__
+	{
+		int len = 0;		// 返回的数据长度;
+		std::string data;	// 返回的数据内容;		
+	}RTN, * pRTN;
+
+	std::vector<RTN> m_vtdata;
+	std::vector<_SIACP_> m_vtcommand;
+	BOOL ExecSerialCommand(const _SIACP_& siacp, std::string command);
+	BOOL ParserSerialData(std::vector<RTN>& vtdata, const _SIACP_& siacp, byte* pbuffer, DWORD dwlen);
+
+	const _SIACP_* GetSiacp(std::string name);
+	std::string GetSiacpCommand(const _SIACP_& siacp, std::string others, int othersLen);
+	std::string GetSiacpCommand(std::string name, std::string others, int othersLen);
+
+public:
+	void LoadCommand();
+	void SaveCommand(std::vector<_SIACP_> &vtSiacp, std::string path);
+	BOOL OpenComm(LPCTSTR lpszCom, DWORD dwBaudrate);
+	void CloseComm();
+	BOOL IsOpen() {
+		return m_pSerial && m_pSerial->IsOpen();
+	}
+	BOOL SendCommand(std::string cmd_name, const byte* pszOthers = NULL, DWORD dwOthersLen = 0);
+	BOOL SendCommand2(std::string cmd_name, std::string data = "", size_t nlen = 0);
+public:
+	// 等待tv启动成功;
+	BOOL SCBC_WaitTVBoot();
+	BOOL SCBC_MTKInit();
+	// 进入工厂模式;
+	BOOL SCBC_EnterFactory();
+	// 离开工厂模式;
+	BOOL SCBC_LeaveFactory();
+	// 初始化Wb;
+	BOOL SCBC_WBInit();
+	// 获取pid;
+	BOOL SCBC_GetProjectId(int& pid);
+	// 软件版本号;
+	BOOL SCBC_GetSoftVersion(std::string& strVer);
+	// 设备ID
+	BOOL SCBC_GetDeviceId(std::string& strDid);
+	// ClientType;
+	BOOL SCBC_GetClientType(std::string& strClt);
+	// MAC地址;
+	BOOL SCBC_GetMAC(std::string& strMac);
+	// HDCP Key;
+	BOOL SCBC_GetHDCPKey(std::string& strHDCP);
+	// HDCP Key2.2;
+	BOOL SCBC_GetHDCPKey22(std::string& strHDCP22);
+	// Widi;
+	BOOL SCBC_GetWidi(std::string& strWidi);
+	// Netflix ESN;
+	BOOL SCBC_GetNetflixESN(std::string& strESN);
+	// Widevine;
+	BOOL SCBC_GetWidevine(std::string& strWidevine);
+	// ci plus key;
+	BOOL SCBC_GetCiKey(std::string& strCikey);
+	// OSD Language;
+	BOOL SCBC_GetOSDLanguage(std::string& strOSDLan);
+	// Shop Language;
+	BOOL SCBC_GetShopLanguage(std::string& strShopLan);
+	BOOL SCBC_GetChannel(std::string& channel);
+
+	BOOL SCBC_SetProjectId(const int& pid);
+	BOOL SCBC_SetProjectId(std::string pid);
+	BOOL SCBC_SetProjectId(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetDeviceId(std::string strDeviceId);
+	BOOL SCBC_SetDeviceId(const byte* pBuffer, const int &nLen);
+	BOOL SCBC_SetMAC(std::string strMac);
+	BOOL SCBC_SetMAC(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetHDCPKey(std::string strHDCP, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetHDCPKey(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetHDCPKey22(std::string strHDCP22, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetHDCPKey22(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetNetflixESN(std::string strESN, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetNetflixESN(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetWidi(std::string strWidi, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetWidi(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetWidevine(std::string strWidevine, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetWidevine(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetCiKey(std::string strCiKey, BOOL bHasSpace = FALSE);
+	BOOL SCBC_SetCiKey(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetOSDLanguage(std::string lan, BOOL bHasSpace = TRUE);
+	BOOL SCBC_SetOSDLanguage(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetShopLanguage(std::string lan, BOOL bHasSpace = TRUE);
+	BOOL SCBC_SetShopLanguage(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetChannel(std::string channel, BOOL bHasSpace = TRUE);
+	BOOL SCBC_SetChannel(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetWBNormal(std::string data);
+	BOOL SCBC_SetWBNormal(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetWBCool(std::string data);
+	BOOL SCBC_SetWBCool(const byte* pBuffer, const int& nLen);
+	BOOL SCBC_SetWBWarm(std::string data);
+	BOOL SCBC_SetWBWarm(const byte* pBuffer, const int& nLen);
+
+	BOOL SCBC_CheckDeviceId();
+	BOOL SCBC_CheckMAC();
+	BOOL SCBC_CheckHDCP();
+	BOOL SCBC_CheckHDCP22();
+	BOOL SCBC_CheckNetflixESN();
+	BOOL SCBC_CheckWidi();
+	BOOL SCBC_CheckWidevine();
+	BOOL SCBC_CheckCikey();
+
+	BOOL SCBC_StarWarmUpMode();
+	BOOL SCBC_StopWarmUpMode();
+};
+
+// 数据类型;
+enum DATATYPE
+{
+	DATA_JSON = 0,		// json数据;
+	DATA_FORM = 1		// 表单类型;
+};
+
+typedef struct __MIDKEY__ {
+	std::string name;
+	std::string type;
+}MidKeyInfo;
+
+typedef struct __MID__ {
+	std::string message;
+	std::string code;
+	std::string factoryname;
+	std::string factoryip;
+	std::string factoryNum;
+	std::string version;
+	std::string projectid;
+	std::string clienttype;
+	std::string host;
+	std::map<std::string, std::string> obj;
+}MIDInfo;
+
+
+typedef struct TREPORTDATA {
+	std::string report_type;
+	std::map<std::string, std::string> report_data;
+}TReportData, * pTReportData;
+
+class COTA
+{
+	CCurlClient m_curl;
+public:
+	COTA();
+	~COTA();
+
+	void SetMainDlg(CDialogEx* p);
+	void ShowMessage(LPCTSTR lpMsg, LOG_ENUM logtype = NORMAL_LOG);
+private:
+	CDialogEx* m_pMainDlg;
+	BOOL HttpGet(std::string host, std::string context, std::string& result, DATATYPE dt = DATA_FORM);
+	BOOL HttpPost(std::string host, std::string context, std::string& result, DATATYPE dt = DATA_FORM);
+
+public:
+	MIDInfo m_midInfo;
+	BOOL GetMIDInfo(MIDInfo& mid, std::string bid, std::string strMacs, std::string iptvid = "", std::string version = "");
+	BOOL GetKeyInfo(std::string host, std::string context, std::string keyname, std::string valuename, std::string& value);
+	std::string GetMidKey(const MIDInfo& mid, std::string name)
+	{
+		std::string key;
+		std::map<std::string, std::string>::const_iterator it = mid.obj.find(name);
+		if (it != mid.obj.end())
+			key = it->second;
+
+		if (_tcsicmp(name.c_str(), "DeviceID") == 0)
+		{
+			if ( _tcsicmp(it->first.c_str(), _T("SCBC")) == 0 || _tcsicmp(it->first.c_str(), _T("新用户系统")) == 0)
+				key = "tcl_unknown_model";
+		}
+
+		return key;
+	}
+	void UpgradeCheck(std::string factoryNum);
+	void ReportUpgrade(BOOL bUpgrade, std::string ver, std::string num);
+	BOOL DownloadFile(std::string url, std::string savePath);
+	BOOL ReportLog(TReportData &repdata);
+	BOOL GetVCode(std::string mac, std::string &vcode);
+};
+
+extern std::string HexString2Bytes(std::string strHex, const int& len = 3);
+#endif

+ 990 - 0
TCL Copy Tool/TCL Copy Tool/SerialPort.cpp

@@ -0,0 +1,990 @@
+///////////////////////////////// Includes ////////////////////////////////////
+#include "pch.h"
+#include "serialport.h"
+#ifndef _WINERROR
+#pragma message("To avoid this message, please put WinError.h in your pre compiled header")
+#include <WinError.h>
+#endif
+
+///////////////////////////////// Defines /////////////////////////////////////
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////// Implementation ///////////////////////////////
+CSerialException::CSerialException(DWORD dwError) : m_dwError(dwError)
+{
+}
+
+BOOL CSerialException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
+	
+	if(pnHelpContext != NULL)
+		*pnHelpContext = 0;
+
+	// What will be the return value from this function(assume the worst)
+	BOOL bSuccess = FALSE;
+	
+	LPTSTR lpBuffer;
+	DWORD dwReturn = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+									NULL, 
+									m_dwError, 
+									MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
+									reinterpret_cast<LPTSTR>(&lpBuffer), 
+									0, 
+									NULL
+									);
+	if(dwReturn == 0)
+	{
+		*lpszError = _T('\0');
+	}
+	else
+	{
+		bSuccess = TRUE;
+		Checked::tcsncpy_s(lpszError, nMaxError, lpBuffer, _TRUNCATE);
+		LocalFree(lpBuffer);
+	}
+	
+	return bSuccess;
+}
+
+CString CSerialException::GetErrorMessage()
+{
+	CString strVal;
+	LPTSTR pstrError = strVal.GetBuffer(ERR_BUFFER);
+
+	GetErrorMessage(pstrError, ERR_BUFFER, NULL);
+	strVal.ReleaseBuffer();
+
+	return strVal;
+}
+
+IMPLEMENT_DYNAMIC(CSerialException, CException)
+
+#ifdef _DEBUG
+void CSerialException::Dump(CDumpContext &dc) const
+{
+	CObject::Dump(dc);
+	dc << _T("m_dwError = ") << m_dwError << _T("\n");
+}
+#endif
+
+CSerialPort::CSerialPort() : m_hComm(INVALID_HANDLE_VALUE), m_hEvent(NULL)
+{
+	m_hKernel32 = GetModuleHandle(_T("KERNEL32.DLL"));
+	if(m_hKernel32)
+		m_lpfnCancelIO = reinterpret_cast<LPCANCELIO>(GetProcAddress(m_hKernel32, "CancelIo"));
+	else
+		m_lpfnCancelIO = NULL;
+}
+
+CSerialPort::~CSerialPort()
+{
+	Close();
+}
+
+void CSerialPort::ThrowSerialException(DWORD dwError	/* = 0 */)
+{
+	if(dwError == 0)
+		dwError = GetLastError();
+
+	CSerialException* pException = new CSerialException(dwError);
+
+	TRACE(_T("Warning: throwing CSerialException for error %d\n"), dwError);
+	THROW(pException);
+}
+
+#ifdef _DEBUG
+void CSerialPort::Dump(CDumpContext &dc) const
+{
+	dc << _T("m_hComm = ") << m_hComm << _T("\n");
+}
+#endif
+
+void CSerialPort::Open(LPCTSTR pszPort,					/* COM1   */
+					   DWORD dwBaud						/* = 9600 */, 
+					   CSerialPort::Parity parity		/* = NoParity */, 
+					   BYTE dataBits					/* = 8 */, 
+					   CSerialPort::StopBits stopBits	/* = OneStopBit */, 
+					   CSerialPort::FlowControl flowCtl	/* = NoFlowControl */, 
+					   BOOL bOverlapped					/* = 0 */)
+{
+	Close();	// In case we are already open
+
+	// Call CreateFile to open the comms port
+	TCHAR szPort[10] = {0};
+	_stprintf_s(szPort, _T("\\\\.\\%s"), pszPort);
+	m_hComm = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
+	if(m_hComm == INVALID_HANDLE_VALUE)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Open, Failed to open the comms port, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"%s打开失败,GetLastError=%ld", szPort, dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	// Create the event we need for later synchronisation use
+	m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if(m_hEvent == NULL)
+	{
+		DWORD dwLastError = GetLastError();
+		Close();
+		//TRACE(_T("CSerialPort::Open, Failed in call to CreateEvent in Open, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", szPort, dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	if ( !SetupComm(m_hComm,10240,2048) )
+	{
+		CloseHandle(m_hComm);
+		CloseHandle(m_hEvent);
+		return ;
+	}
+	// Get the current state prior to changing it
+	DCB dcb;
+	dcb.DCBlength = sizeof(DCB);
+	GetState(dcb);
+
+	// Setup the baud rate
+	dcb.BaudRate = dwBaud;
+
+	// Setup the Parity
+	switch(parity)
+	{
+	case NoParity:
+		dcb.Parity = NOPARITY;
+		break;
+	case OddParity:
+		dcb.Parity = ODDPARITY;
+		break;
+	case EvenParity:
+		dcb.Parity = EVENPARITY;
+		break;
+	case MarkParity:
+		dcb.Parity = MARKPARITY;
+		break;
+	case SpaceParity:
+		dcb.Parity = SPACEPARITY;
+		break;
+	default:
+		ASSERT(FALSE);
+		break;
+	}
+
+	// Setup the data bits
+	dcb.ByteSize = dataBits;
+
+	// Setup the stop bits
+	switch(stopBits)
+	{
+	case OneStopBit:
+		dcb.StopBits = ONESTOPBIT;
+		break;
+	case OnePointFiveStopBits:
+		dcb.StopBits = ONE5STOPBITS;
+		break;
+	case TwoStopBits:
+		dcb.StopBits = TWOSTOPBITS;
+		break;
+	default:
+		ASSERT(FALSE);
+		break;
+	}
+
+	// Setup the flow control
+	dcb.fDsrSensitivity = FALSE;
+	switch(flowCtl)
+	{
+	case NoFlowControl:
+		dcb.fOutxCtsFlow = FALSE;
+		dcb.fOutxDsrFlow = FALSE;
+		dcb.fOutX = FALSE;
+		dcb.fInX = FALSE;
+		break;
+	case CtsRtsFlowControl:
+		dcb.fOutxCtsFlow = TRUE;
+		dcb.fOutxDsrFlow = FALSE;
+		dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+		dcb.fOutX = FALSE;
+		dcb.fInX = FALSE;
+		break;
+	case CtsDtrFlowControl:
+		dcb.fOutxCtsFlow = TRUE;
+		dcb.fOutxDsrFlow = FALSE;
+		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+		dcb.fOutX = FALSE;
+		dcb.fInX = FALSE;
+		break;
+	case DsrRtsFlowControl:
+		dcb.fOutxCtsFlow = FALSE;
+		dcb.fOutxDsrFlow = TRUE;
+		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+		dcb.fOutX = FALSE;
+		dcb.fInX = FALSE;
+		break;
+	case DsrDtrFlowControl:
+		dcb.fOutxCtsFlow = FALSE;
+		dcb.fOutxDsrFlow = TRUE;
+		dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+		dcb.fOutX = FALSE;
+		dcb.fInX = FALSE;
+		break;
+	case XonXoffFlowControl:
+		dcb.fOutxCtsFlow = FALSE;
+		dcb.fOutxDsrFlow = FALSE;
+		dcb.fOutX = TRUE;
+		dcb.fInX = TRUE;
+		dcb.XonChar = 0x11;
+		dcb.XoffChar = 0x13;
+		dcb.XoffLim = 100;
+		dcb.XonLim = 100;
+		break;
+	default:
+		ASSERT(FALSE);
+		break;
+	}
+
+	//Now that we have all the settings in place, make the changes
+	SetState(dcb);
+}
+
+void CSerialPort::Open(int nPort, 
+					   DWORD dwBaud						/* = 9600 */, 
+					   CSerialPort::Parity parity		/* = NoParity */, 
+					   BYTE dataBits					/* = 8 */, 
+					   CSerialPort::StopBits stopBits	/* = OneStopBit */, 
+					   CSerialPort::FlowControl flowCtl	/* = NoFlowControl */, 
+					   BOOL bOverlapped					/* = 0 */)
+{
+	//Form the string version of the port number
+	CString strPort;
+	strPort.Format(_T("\\\\.\\COM%d"), nPort);
+
+	//Then delegate the work to the other version of Open
+	Open(strPort, dwBaud, parity, dataBits, stopBits, flowCtl, bOverlapped);
+}
+
+void CSerialPort::Close()
+{
+	if(IsOpen())
+	{
+		// Close down the comms port
+		BOOL bSuccess = CloseHandle(m_hComm);
+		m_hComm = INVALID_HANDLE_VALUE;
+		if(!bSuccess)
+			//TRACE(_T("CSerialPort::Close, Failed to close up the comms port, Error:%d\n"), GetLastError());
+			LOG4C((LOG_WARN,"关闭串口失败,GetLastError=%ld", GetLastError()));
+
+		// Free the event object we are using
+		if(m_hEvent)
+		{
+			CloseHandle(m_hEvent);
+			m_hEvent = NULL;
+		}
+	}
+}
+
+void CSerialPort::Attach(HANDLE hComm)
+{
+	Close();
+
+	//Validate our parameters, now that the port has been closed
+	ASSERT(m_hComm == INVALID_HANDLE_VALUE);
+	ASSERT(m_hEvent == NULL);
+
+	m_hComm = hComm;
+
+	//Create the event we need for later synchronisation use
+	m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if (m_hEvent == NULL)
+	{
+		DWORD dwLastError = GetLastError();
+		Close();
+		//TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", GetLastError()));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+HANDLE CSerialPort::Detach()
+{
+	// What will be the return value from this function
+	HANDLE hVal = m_hComm;
+
+	m_hComm = INVALID_HANDLE_VALUE;
+
+	if(m_hEvent)
+	{
+		CloseHandle(m_hEvent);
+		m_hEvent = NULL;
+	}
+	
+	return hVal;
+}
+
+DWORD CSerialPort::Read(void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if (lpBuf == NULL || !::AfxIsValidAddress(lpBuf, dwCount, FALSE))
+	{
+		LOG4C((LOG_WARN, "Read的缓存地址无效!"))
+		return 0;
+	}
+
+	DWORD dwErrorFlags = 0;
+	COMSTAT ComStat;
+	ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+
+#if 1
+	// 使用ClearCommError来读取缓存区接受到的字节时, 
+	// 可能受系统线程调试或硬件延时, cbInQue为空, 
+	// 这里要用while延时获取;
+	DWORD dwTick = GetTickCount();
+	DWORD dwLastLen = 0;
+	//while (ComStat.cbInQue == 0)
+	while(1)
+	{// cbInQue表示输入缓冲区的字节数; 
+		Sleep(150);
+		if (GetTickCount() - dwTick > 5000)
+			break;
+		ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+		if ( ComStat.cbInQue != 0 && dwLastLen == ComStat.cbInQue )
+			break;
+		dwLastLen = ComStat.cbInQue;
+	}
+
+	if (ComStat.cbInQue == 0)
+	{
+		// 串口无数据返回;
+		LOG4C((LOG_ERROR, "1.5秒超时已过,读串口失败,缓存区无数据"));
+		return 0;
+	}
+#endif
+
+	DWORD dwBytesRead = 0;
+	if(!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return dwBytesRead;
+}
+
+void CSerialPort::Read(void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesRead /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesRead = 0;
+	BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
+	if(!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+	else
+	{
+		if(pBytesRead)
+			*pBytesRead = dwBytesRead;
+	}
+}
+
+DWORD CSerialPort::Write(const void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesWritten = 0;
+	// 写前,清空缓存区;
+	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+	if(!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return dwBytesWritten;
+}
+
+void CSerialPort::Write(const void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesWritten /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesWritten = 0;
+	// 写前,清空缓存区;
+	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+	BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
+	if(!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+	else
+	{
+		if(pBytesWritten)
+			*pBytesWritten = dwBytesWritten;
+	}
+}
+
+void CSerialPort::GetOverlappedResult(OVERLAPPED &overlapped, DWORD &dwBytesTransferred, BOOL bWait)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetOverlappedResult失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
+{
+	// Validate our parameters
+	AFXASSUME(lpOverlapped);
+
+	// Convert back to the C++ world
+	CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
+	AFXASSUME(pSerialPort);
+
+	// Call the C++ function
+	pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
+}
+
+void CSerialPort::OnCompletion(DWORD /* dwErrorCode */, DWORD /* dwCount */, LPOVERLAPPED lpOverlapped)
+{
+	// Just free the memory which was previously allocated for the OVERLAPPED structure
+	delete lpOverlapped;
+
+	// Your derived classes can do something useful in OnCompletion, but don't forget to 
+	// call CSerialPort::OnCompletion to ensure the memory is freed
+}
+
+void CSerialPort::CancelIO()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(m_lpfnCancelIO == NULL)
+	{
+		//TRACE(_T("CSerialPort::CancelIO, CancelIO function is not supported on this OS, You need to be running at least NT 4 or Win 98 to use this function\n"));
+		LOG4C((LOG_WARN,"CancelIO失败,m_lpfnCancelIO函数指针空"));
+		//ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
+	}
+
+	if(!m_lpfnCancelIO(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("Failed in call to CancelIO, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"CancelIO失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+DWORD CSerialPort::BytesWaiting()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	// Check to see how many characters are unread
+	COMSTAT stat;
+	GetStatus(stat);
+	return stat.cbInQue;
+}
+
+BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	// Setup to wait fo incoming data
+	DWORD dwOldMask;
+	GetMask(dwOldMask);
+	SetMask(EV_RXCHAR);
+
+	// Setup the overlapped structure
+	OVERLAPPED overlapped;
+	overlapped.hEvent = m_hEvent;
+
+	// Assume the worst
+	BOOL bSuccess = FALSE;
+
+	DWORD dwEvent;
+	bSuccess = WaitEvent(dwEvent, overlapped);
+	if(!bSuccess)
+	{
+		if(WaitForSingleObject(overlapped.hEvent, dwTimeout) == WAIT_OBJECT_0)
+		{
+			DWORD dwBytesTransferred;
+			GetOverlappedResult(overlapped, dwBytesTransferred, FALSE);
+			bSuccess = TRUE;
+		}
+	}
+
+	// Reset the event mask
+	SetMask(dwOldMask);
+
+	return bSuccess;
+}
+
+void CSerialPort::WriteEx(const void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	OVERLAPPED* pOverlapped = new OVERLAPPED;
+	memset(pOverlapped, 0, sizeof(OVERLAPPED));
+	pOverlapped->hEvent = static_cast<HANDLE>(this);
+	if(!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
+	{
+		DWORD dwLastError = GetLastError();
+		delete pOverlapped;
+		//TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"WriteEx失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ReadEx(void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	OVERLAPPED* pOverlapped = new OVERLAPPED;
+	memset(pOverlapped, 0, sizeof(OVERLAPPED));
+	pOverlapped->hEvent = static_cast<HANDLE>(this);
+	if(!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
+	{
+		DWORD dwLastError = GetLastError();
+		delete pOverlapped;
+		//TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ReadEx失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::TransmitChar(char cChar)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!TransmitCommChar(m_hComm, cChar))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"TransmitCommChar失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetConfig(COMMCONFIG &config)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!GetCommConfig(m_hComm, &config, &dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetConfig(COMMCONFIG &config)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!SetCommConfig(m_hComm, &config, dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetBreak()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!SetCommBreak(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetBreak, Failed in call to SetCommBreak, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetCommBreak失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ClearBreak()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!ClearCommBreak(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::ClearBreak, Failed in call to ClearCommBreak, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ClearCommBreak失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ClearError(DWORD &dwErrors)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!ClearCommError(m_hComm, &dwErrors, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::ClearError, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG &config)
+{
+	// Create the device name as a string
+	CString strPort;
+	strPort.Format(_T("COM%d"), nPort);
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!GetDefaultCommConfig(strPort, &config, &dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetDefaultConfig, Failed in call to GetDefaultCommConfig, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetDefaultCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG &config)
+{
+	// Create the device name as a string
+	CString strPort;
+	strPort.Format(_T("COM%d"), nPort);
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!SetDefaultCommConfig(strPort, &config, dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetDefaultConfig, Failed in call to SetDefaultCommConfig, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetDefaultConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetStatus(COMSTAT &stat)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwErrors;
+	if (!ClearCommError(m_hComm, &dwErrors, &stat))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetStatus, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetState(DCB &dcb)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommState(m_hComm, &dcb))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetState, Failed in call to GetCommState, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetCommState失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetState(DCB &dcb)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommState(m_hComm, &dcb))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetState, Failed in call to SetCommState, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetState失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Escape(DWORD dwFunc)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!EscapeCommFunction(m_hComm, dwFunc))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Escape, Failed in call to EscapeCommFunction, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"Escape失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ClearDTR()
+{
+  Escape(CLRDTR);
+}
+
+void CSerialPort::ClearRTS()
+{
+	Escape(CLRRTS);
+}
+
+void CSerialPort::SetDTR()
+{
+	Escape(SETDTR);
+}
+
+void CSerialPort::SetRTS()
+{
+	Escape(SETRTS);
+}
+
+void CSerialPort::SetXOFF()
+{
+	Escape(SETXOFF);
+}
+
+void CSerialPort::SetXON()
+{
+	Escape(SETXON);
+}
+
+void CSerialPort::GetProperties(COMMPROP& properties)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommProperties(m_hComm, &properties))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetProperties, Failed in call to GetCommProperties, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetProperties失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommModemStatus(m_hComm, &dwModemStatus))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetModemStatus, Failed in call to GetCommModemStatus, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetModemStatus失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetMask(DWORD dwMask)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommMask(m_hComm, dwMask))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetMask, Failed in call to SetCommMask, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetMask失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetMask(DWORD& dwMask)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommMask(m_hComm, &dwMask))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetMask, Failed in call to GetCommMask, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetMask失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Flush()
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!FlushFileBuffers(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Flush, Failed in call to FlushFileBuffers, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"Flush失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Purge(DWORD dwFlags)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!PurgeComm(m_hComm, dwFlags))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Purge, Failed in call to PurgeComm, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"Purge失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::TerminateOutstandingWrites()
+{
+	Purge(PURGE_TXABORT);
+}
+
+void CSerialPort::TerminateOutstandingReads()
+{
+	Purge(PURGE_RXABORT);
+}
+
+void CSerialPort::ClearWriteBuffer()
+{
+	Purge(PURGE_TXCLEAR);
+}
+
+void CSerialPort::ClearReadBuffer()
+{
+	Purge(PURGE_RXCLEAR);
+}
+
+void CSerialPort::Setup(DWORD dwInQueue, DWORD dwOutQueue)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Setup, Failed in call to SetupComm, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"Setup失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommTimeouts(m_hComm, &timeouts))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetTimeouts, Failed in call to SetCommTimeouts, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"SetTimeouts失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommTimeouts(m_hComm, &timeouts))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetTimeouts, Failed in call to GetCommTimeouts, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"GetTimeouts失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Set0Timeout()
+{
+	COMMTIMEOUTS Timeouts;
+	memset(&Timeouts, 0, sizeof(Timeouts));
+	Timeouts.ReadIntervalTimeout = MAXDWORD;
+	SetTimeouts(Timeouts);
+}
+
+void CSerialPort::Set0WriteTimeout()
+{
+	COMMTIMEOUTS Timeouts;
+	GetTimeouts(Timeouts);
+	Timeouts.WriteTotalTimeoutMultiplier = 0;
+	Timeouts.WriteTotalTimeoutConstant = 0;
+	SetTimeouts(Timeouts);
+}
+
+void CSerialPort::Set0ReadTimeout()
+{
+	COMMTIMEOUTS Timeouts;
+	GetTimeouts(Timeouts);
+	Timeouts.ReadIntervalTimeout = MAXDWORD;
+	Timeouts.ReadTotalTimeoutMultiplier = 0;
+	Timeouts.ReadTotalTimeoutConstant = 0;
+	SetTimeouts(Timeouts);
+}
+
+void CSerialPort::WaitEvent(DWORD& dwMask)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!WaitCommEvent(m_hComm, &dwMask, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+	ASSERT(overlapped.hEvent);
+
+	BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
+	if (!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
+		LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return bSuccess;
+}

+ 168 - 0
TCL Copy Tool/TCL Copy Tool/SerialPort.h

@@ -0,0 +1,168 @@
+#ifndef __SERIAL_PORT_H__
+#define __SERIAL_PORT_H__
+
+//#include "stdafx.h"
+
+#ifndef CSERIALPORT_EXT_CLASS
+#define CSERIALPORT_EXT_CLASS
+#endif
+
+#define ERR_BUFFER	4096
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	/////////////////////////////////////////// Classes ///////////////////////////////////////////
+	class CSERIALPORT_EXT_CLASS CSerialException : public CException
+	{
+	public:
+		// Constructors / Destructors
+		CSerialException(DWORD dwError);
+
+		// Methods
+#ifdef _DEBUG
+		virtual void Dump(CDumpContext& dc) const;
+#endif
+		virtual BOOL GetErrorMessage(__out_ecount_z(nMaxError) LPTSTR lpszError, __in UINT nMaxError, __out_opt PUINT pnHelpContext = NULL);
+		CString GetErrorMessage();
+
+		// Data members
+		DWORD m_dwError;
+
+	protected:
+		DECLARE_DYNAMIC(CSerialException)
+	};
+
+	class CSerialPort
+	{
+	public:
+		//Enums
+		enum FlowControl
+		{
+			NoFlowControl,
+			CtsRtsFlowControl,
+			CtsDtrFlowControl,
+			DsrRtsFlowControl,
+			DsrDtrFlowControl,
+			XonXoffFlowControl
+		};
+
+		enum Parity
+		{
+			NoParity = 0,
+			OddParity = 1,
+			EvenParity = 2,
+			MarkParity = 3,
+			SpaceParity = 4
+		};
+
+		enum StopBits
+		{
+			OneStopBit,
+			OnePointFiveStopBits,
+			TwoStopBits
+		};
+
+		//Constructors / Destructors
+		CSerialPort();
+		virtual ~CSerialPort();
+
+		//General Methods
+		void	Open(int nPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
+			StopBits stopBits = OneStopBit, FlowControl flowCtl = NoFlowControl, BOOL bOverlapped = FALSE);
+		void	Open(LPCTSTR pszPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
+			StopBits stopBits = OneStopBit, FlowControl flowCtl = NoFlowControl, BOOL bOverlapped = FALSE);
+		void	Close();
+		void	Attach(HANDLE hComm);
+		HANDLE	Detach();
+		operator HANDLE() const { return m_hComm; };
+		BOOL IsOpen() const { return m_hComm != INVALID_HANDLE_VALUE; };
+#ifdef _DEBUG
+		void Dump(CDumpContext& dc) const;
+#endif
+
+		// Reading / Writting Methods
+		DWORD Read(void* lpBuf, DWORD dwCount);
+		void Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead = NULL);
+		void ReadEx(void* lpBuf, DWORD dwCount);
+		DWORD Write(const void* lpBuf, DWORD dwCount);
+		void Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten = NULL);
+		void WriteEx(const void* lpBuf, DWORD dwCount);
+		void TransmitChar(char cChar);
+		void GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait);
+		void CancelIO();
+		DWORD BytesWaiting();
+		BOOL DataWaiting(DWORD dwTimeout);
+
+		// Configuration Methods
+		void GetConfig(COMMCONFIG& config);
+		static void GetDefaultConfig(int nPort, COMMCONFIG& config);
+		void SetConfig(COMMCONFIG& config);
+		static void SetDefaultConfig(int nPort, COMMCONFIG& config);
+
+		// Misc RS232 Methods
+		void ClearBreak();
+		void SetBreak();
+		void ClearError(DWORD& dwErrors);
+		void GetStatus(COMSTAT& stat);
+		void GetState(DCB& dcb);
+		void SetState(DCB& dcb);
+		void Escape(DWORD dwFunc);
+		void ClearDTR();
+		void ClearRTS();
+		void SetDTR();
+		void SetRTS();
+		void SetXOFF();
+		void SetXON();
+		void GetProperties(COMMPROP& porperties);
+		void GetModemStatus(DWORD& dwModemStatus);
+
+		// Timeouts
+		void SetTimeouts(COMMTIMEOUTS& timeouts);
+		void GetTimeouts(COMMTIMEOUTS& timeouts);
+		void Set0Timeout();
+		void Set0WriteTimeout();
+		void Set0ReadTimeout();
+
+		// Event Methods
+		void SetMask(DWORD dwMask);
+		void GetMask(DWORD& dwMask);
+		void WaitEvent(DWORD& dwMask);
+		BOOL WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped);
+
+		// Queue Methods
+		void Flush();
+		void Purge(DWORD dwFlags);
+		void TerminateOutstandingWrites();
+		void TerminateOutstandingReads();
+		void ClearWriteBuffer();
+		void ClearReadBuffer();
+		void Setup(DWORD dwInQueue, DWORD dwOutQueue);
+
+		// Overridables
+		virtual void OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);
+
+		// Static methods
+		static void ThrowSerialException(DWORD dwError = 0);
+
+	protected:
+		// Typedefs
+		typedef BOOL(WINAPI CANCELIO)(HANDLE);
+		typedef CANCELIO* LPCANCELIO;
+
+		// Static methods
+		static void WINAPI _OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);
+
+		// Member variables
+		HANDLE		m_hComm;		// Handle to the comms port
+		HANDLE		m_hEvent;		// A event handle we need for internal synchronisation
+		HINSTANCE	m_hKernel32;	// Kernel32 handle
+		LPCANCELIO	m_lpfnCancelIO;	// CancelIO function pointer
+	};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	// __SERIAL_PORT_H__

+ 156 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.cpp

@@ -0,0 +1,156 @@
+
+// TCL Tools.cpp: 定义应用程序的类行为。
+//
+
+#include "pch.h"
+#include "framework.h"
+#include "TCL Copy Tool.h"
+#include "TCL Copy ToolDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTCLToolsApp
+
+BEGIN_MESSAGE_MAP(CTCLToolsApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CTCLToolsApp 构造
+
+CTCLToolsApp::CTCLToolsApp()
+{
+	// 支持重新启动管理器
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的 CTCLToolsApp 对象
+
+CTCLToolsApp theApp;
+
+
+// CTCLToolsApp 初始化
+
+BOOL CTCLToolsApp::InitInstance()
+{
+// TODO: 调用 AfxInitRichEdit2() 以初始化 richedit2 库。\n"	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	AfxInitRichEdit2();
+	CWinApp::InitInstance();
+
+#if 1
+	// 获取模块的目录;
+	TCHAR szDrive[MAX_PATH] = { 0 };
+	TCHAR szDir[MAX_PATH] = { 0 };
+	TCHAR szExt[MAX_PATH] = { 0 };
+	::GetModuleFileName(NULL, Global::g_szCurModulePath, sizeof(Global::g_szCurModulePath) / sizeof(TCHAR));
+	_tsplitpath_s(Global::g_szCurModulePath, szDrive, szDir, Global::g_szFna, szExt);
+	_tcscpy_s(Global::g_szCurModuleDir, szDrive);
+	_tcscat_s(Global::g_szCurModuleDir, szDir);
+	// config文件路径;
+	_stprintf_s(Global::g_szConfig, _T("%sconfig.ini"), Global::g_szCurModuleDir);
+
+	// 日志模板;
+	char szFileName[MAX_PATH];
+	sprintf_s(szFileName, "%s\\log4crc.xml", Global::g_szCurModuleDir);
+	///设置日志配置文件名
+	LOG4C_PARAM_CFG_FILE_NAME(szFileName);
+	///设置日志级别
+	LOG4C_PARAM_LOG_LEVEL("unknown");
+	///设置日志文件大小
+	LOG4C_PARAM_LOG_FILE_SIZE(102400);
+	///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志
+	LOG4C_PARAM_LOG_FILE_NUM(3);
+	///设置每次记录日志都重新读取日志配置文件
+	LOG4C_PARAM_REREAD_LOG_CFG_FILE(1);
+	///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值
+	LOG4C_INIT_WITH_PARAM();
+
+#if 0 // 等级示例;
+	LOG4C((LOG_FATAL, "LOG_FATAL!"));
+	LOG4C((LOG_ALERT, "LOG_ALERT!"));
+	LOG4C((LOG_CRIT, "LOG_CRIT!"));
+	LOG4C((LOG_ERROR, "LOG_ERROR!"));
+	LOG4C((LOG_WARN, "LOG_WARN!"));
+	LOG4C((LOG_NOTICE, "LOG_NOTICE!"));
+	LOG4C((LOG_INFO, "LOG_INFO!"));
+	LOG4C((LOG_DEBUG, "LOG_DEBUG!"));
+	LOG4C((LOG_TRACE, "LOG_TRACE!"));
+	LOG4C((LOG_NOTSET, "LOG_NOTSET!"));
+	LOG4C((LOG_UNKNOWN, "LOG_UNKNOWN!"));
+#endif
+
+	LOG4C((LOG_NOTICE, "程序开始运行!"));
+#endif
+
+	Global::GetConfig();
+	Global::GetMacAddress();
+	AfxEnableControlContainer();
+
+	//std::string vcode;
+	//g_ota.GetVCode("CC-A1-2B-03-09-13", vcode);
+	// 创建 shell 管理器,以防对话框包含
+	// 任何 shell 树视图控件或 shell 列表视图控件。
+	CShellManager *pShellManager = new CShellManager;
+
+	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+	CTCLCopyToolDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+	}
+
+	// 删除上面创建的 shell 管理器。
+	if (pShellManager != nullptr)
+	{
+		delete pShellManager;
+	}
+
+#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
+	ControlBarCleanUp();
+#endif
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}
+

+ 32 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.h

@@ -0,0 +1,32 @@
+
+// TCL Tools.h: PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CTCLToolsApp:
+// 有关此类的实现,请参阅 TCL Tools.cpp
+//
+
+class CTCLToolsApp : public CWinApp
+{
+public:
+	CTCLToolsApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CTCLToolsApp theApp;

+ 478 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.vcxproj

@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="SDebug|Win32">
+      <Configuration>SDebug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="SDebug|x64">
+      <Configuration>SDebug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="SRelease|Win32">
+      <Configuration>SRelease</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="SRelease|x64">
+      <Configuration>SRelease</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <ProjectGuid>{652623E7-21D4-42F7-81EC-6FF166A63F05}</ProjectGuid>
+    <Keyword>MFCProj</Keyword>
+    <RootNamespace>TCLCopyTool</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\..\..\..\bin\$(ProjectName)\</OutDir>
+    <IntDir>$(OutDir)$(Configuration)\</IntDir>
+    <TargetName>$(ProjectName)D</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\..\..\..\bin\$(ProjectName)\</OutDir>
+    <IntDir>$(OutDir)$(Configuration)\</IntDir>
+    <TargetName>S$(ProjectName)D</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>..\..\..\..\..\bin\$(ProjectName)\</OutDir>
+    <IntDir>$(OutDir)$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>..\..\..\..\..\bin\$(ProjectName)\</OutDir>
+    <IntDir>$(OutDir)$(Configuration)\</IntDir>
+    <TargetName>S$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;LOG4C_ENABLE;HTTP_ONLY;CURL_STATICLIB;USE_CURL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalIncludeDirectories>..\cJson;..\Log4C;..\Include;..\UI;..\filehelper</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;wldap32.lib;log4C.lib;libcurl.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\lib</AdditionalLibraryDirectories>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;LOG4C_ENABLE;HTTP_ONLY;CURL_STATICLIB;USE_CURL;SUPER_VER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalIncludeDirectories>..\cJson;..\Log4C;..\Include;..\UI;..\filehelper</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;wldap32.lib;log4C.lib;libcurl.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\lib</AdditionalLibraryDirectories>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SDebug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;LOG4C_ENABLE;HTTP_ONLY;CURL_STATICLIB;USE_CURL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalIncludeDirectories>..\cJson;..\Log4C;..\Include;..\UI;..\filehelper</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;wldap32.lib;log4C.lib;libcurl.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\lib</AdditionalLibraryDirectories>
+      <UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;LOG4C_ENABLE;HTTP_ONLY;CURL_STATICLIB;USE_CURL;SUPER_VER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalIncludeDirectories>..\cJson;..\Log4C;..\Include;..\UI;..\filehelper</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;wldap32.lib;log4C.lib;libcurl.lib</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\lib</AdditionalLibraryDirectories>
+      <UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SRelease|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\cJson\cJSON.h" />
+    <ClInclude Include="..\filehelper\filehelper.h" />
+    <ClInclude Include="..\filehelper\findfile.h" />
+    <ClInclude Include="..\UI\BCMenu.h" />
+    <ClInclude Include="..\UI\BtnST.h" />
+    <ClInclude Include="..\UI\ComboTreeCtrl.h" />
+    <ClInclude Include="..\UI\FontSize.h" />
+    <ClInclude Include="..\UI\PictureEx.h" />
+    <ClInclude Include="..\UI\SubLabel.h" />
+    <ClInclude Include="..\UI\TreeComboBox.h" />
+    <ClInclude Include="..\UI\XColorStatic.h" />
+    <ClInclude Include="Base64.h" />
+    <ClInclude Include="CharConvert.h" />
+    <ClInclude Include="CharEncoding.h" />
+    <ClInclude Include="ChassisConfigDlg.h" />
+    <ClInclude Include="CritSection.h" />
+    <ClInclude Include="CurlClient.h" />
+    <ClInclude Include="framework.h" />
+    <ClInclude Include="Global.h" />
+    <ClInclude Include="log4c.h" />
+    <ClInclude Include="OTA.h" />
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="SerialPort.h" />
+    <ClInclude Include="stdint.h" />
+    <ClInclude Include="targetver.h" />
+    <ClInclude Include="TCL Copy Tool.h" />
+    <ClInclude Include="TCL Copy ToolDlg.h" />
+    <ClInclude Include="tinyxml2.h" />
+    <ClInclude Include="VerificationCodeDlg.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\cJson\cJSON.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\filehelper\filehelper.cpp" />
+    <ClCompile Include="..\filehelper\findfile.cpp" />
+    <ClCompile Include="..\UI\BCMenu.cpp" />
+    <ClCompile Include="..\UI\BtnST.cpp" />
+    <ClCompile Include="..\UI\ComboTreeCtrl.cpp" />
+    <ClCompile Include="..\UI\FontSize.cpp" />
+    <ClCompile Include="..\UI\PictureEx.cpp" />
+    <ClCompile Include="..\UI\SubLabel.cpp" />
+    <ClCompile Include="..\UI\TreeComboBox.cpp" />
+    <ClCompile Include="..\UI\XColorStatic.cpp" />
+    <ClCompile Include="Base64.cpp" />
+    <ClCompile Include="CharConvert.cpp" />
+    <ClCompile Include="CharEncoding.cpp" />
+    <ClCompile Include="ChassisConfigDlg.cpp" />
+    <ClCompile Include="CurlClient.cpp" />
+    <ClCompile Include="Global.cpp" />
+    <ClCompile Include="OTA.cpp" />
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SDebug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SRelease|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="SerialPort.cpp" />
+    <ClCompile Include="TCL Copy Tool.cpp" />
+    <ClCompile Include="TCL Copy ToolDlg.cpp" />
+    <ClCompile Include="tinyxml2.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SDebug|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SRelease|Win32'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="VerificationCodeDlg.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="TCLCopyTool.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="cpp.hint" />
+    <None Include="res\TCLCopyTool.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\TCL Copy Tool.ico" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 217 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy Tool.vcxproj.filters

@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="cJson">
+      <UniqueIdentifier>{594e4670-445c-4c41-8dc0-e9ca5d1559fb}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="tinyxml2">
+      <UniqueIdentifier>{373c18b1-1e97-479b-a638-2fbfad1ebb63}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="curl">
+      <UniqueIdentifier>{a3fa2f14-9946-4250-bb3a-391a35a67f20}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="ota">
+      <UniqueIdentifier>{eb765745-d098-4a13-bce9-c10757b665a1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="ui">
+      <UniqueIdentifier>{af98cc01-14e5-4cd0-aac2-e8f7e4121ebb}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="filehelper">
+      <UniqueIdentifier>{b7d5fb38-3a86-4d06-ba69-0055fb1229c5}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="TCL Copy Tool.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="TCL Copy ToolDlg.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="framework.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="pch.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="..\cJson\cJSON.h">
+      <Filter>cJson</Filter>
+    </ClInclude>
+    <ClInclude Include="Global.h">
+      <Filter>ota</Filter>
+    </ClInclude>
+    <ClInclude Include="log4c.h">
+      <Filter>ota</Filter>
+    </ClInclude>
+    <ClInclude Include="OTA.h">
+      <Filter>ota</Filter>
+    </ClInclude>
+    <ClInclude Include="SerialPort.h">
+      <Filter>ota</Filter>
+    </ClInclude>
+    <ClInclude Include="Base64.h">
+      <Filter>curl</Filter>
+    </ClInclude>
+    <ClInclude Include="CharConvert.h">
+      <Filter>curl</Filter>
+    </ClInclude>
+    <ClInclude Include="CharEncoding.h">
+      <Filter>curl</Filter>
+    </ClInclude>
+    <ClInclude Include="CritSection.h">
+      <Filter>curl</Filter>
+    </ClInclude>
+    <ClInclude Include="CurlClient.h">
+      <Filter>curl</Filter>
+    </ClInclude>
+    <ClInclude Include="tinyxml2.h">
+      <Filter>tinyxml2</Filter>
+    </ClInclude>
+    <ClInclude Include="stdint.h">
+      <Filter>tinyxml2</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\BtnST.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\ComboTreeCtrl.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\FontSize.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\PictureEx.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\SubLabel.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\TreeComboBox.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\XColorStatic.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\UI\BCMenu.h">
+      <Filter>ui</Filter>
+    </ClInclude>
+    <ClInclude Include="ChassisConfigDlg.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="VerificationCodeDlg.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="..\filehelper\findfile.h">
+      <Filter>filehelper</Filter>
+    </ClInclude>
+    <ClInclude Include="..\filehelper\filehelper.h">
+      <Filter>filehelper</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="TCL Copy Tool.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="TCL Copy ToolDlg.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="pch.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="..\cJson\cJSON.c">
+      <Filter>cJson</Filter>
+    </ClCompile>
+    <ClCompile Include="Global.cpp">
+      <Filter>ota</Filter>
+    </ClCompile>
+    <ClCompile Include="OTA.cpp">
+      <Filter>ota</Filter>
+    </ClCompile>
+    <ClCompile Include="SerialPort.cpp">
+      <Filter>ota</Filter>
+    </ClCompile>
+    <ClCompile Include="Base64.cpp">
+      <Filter>curl</Filter>
+    </ClCompile>
+    <ClCompile Include="CharConvert.cpp">
+      <Filter>curl</Filter>
+    </ClCompile>
+    <ClCompile Include="CharEncoding.cpp">
+      <Filter>curl</Filter>
+    </ClCompile>
+    <ClCompile Include="CurlClient.cpp">
+      <Filter>curl</Filter>
+    </ClCompile>
+    <ClCompile Include="tinyxml2.cpp">
+      <Filter>tinyxml2</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\BtnST.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\ComboTreeCtrl.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\FontSize.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\PictureEx.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\SubLabel.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\TreeComboBox.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\XColorStatic.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\UI\BCMenu.cpp">
+      <Filter>ui</Filter>
+    </ClCompile>
+    <ClCompile Include="ChassisConfigDlg.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="VerificationCodeDlg.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="..\filehelper\findfile.cpp">
+      <Filter>filehelper</Filter>
+    </ClCompile>
+    <ClCompile Include="..\filehelper\filehelper.cpp">
+      <Filter>filehelper</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="TCLCopyTool.rc">
+      <Filter>资源文件</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\TCLCopyTool.rc2">
+      <Filter>资源文件</Filter>
+    </None>
+    <None Include="cpp.hint" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\TCL Copy Tool.ico">
+      <Filter>资源文件</Filter>
+    </Image>
+  </ItemGroup>
+</Project>

+ 3611 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy ToolDlg.cpp

@@ -0,0 +1,3611 @@
+
+// TCL ToolsDlg.cpp: 实现文件
+//
+
+#include "pch.h"
+#include "framework.h"
+#include "TCL Copy Tool.h"
+#include "TCL Copy ToolDlg.h"
+#include "afxdialogex.h"
+#include "ChassisConfigDlg.h"
+#include "filehelper.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+HHOOK CTCLCopyToolDlg::m_hHook;
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialogEx
+{
+public:
+	CAboutDlg();
+
+	// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_ABOUTBOX };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CTCLCopyToolDlg 对话框
+
+
+
+CTCLCopyToolDlg::CTCLCopyToolDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_TCLCOPYTOOL_DIALOG, pParent)
+	, m_str_pid(_T(""))
+	, m_str_sn(_T(""))
+	, m_str_bid(_T(""))
+{
+	m_pCurChassis = nullptr;
+	m_bRunning = FALSE;
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CTCLCopyToolDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, COMBO_COM, m_cb_com);
+	DDX_Control(pDX, COMBO_BD, m_cb_baudrate);
+	DDX_Control(pDX, COMBO_MODE, m_cb_mode);
+	DDX_Control(pDX, COMBO_CHASSIS, m_cb_chassis);
+	// 是否抄写控件;
+	DDX_Control(pDX, CHECK_PID, m_check_pid);
+	DDX_Control(pDX, CHECK_CHANNEL, m_check_channel);
+	DDX_Control(pDX, CHECK_OSD_LANG, m_check_osd_lang);
+	DDX_Control(pDX, CHECK_SHOP_LANG, m_check_shop_lang);
+	DDX_Control(pDX, CHECK_DID, m_check_did);
+	DDX_Control(pDX, CHECK_MAC, m_check_mac);
+	DDX_Control(pDX, CHECK_HDCP, m_check_hdcp);
+	DDX_Control(pDX, CHECK_HDCP22, m_check_hdcp22);
+	DDX_Control(pDX, CHECK_WIDI, m_check_widi);
+	DDX_Control(pDX, CHECK_WIDEVINE, m_check_widevine);
+	DDX_Control(pDX, CHECK_ESN, m_check_esn);
+	DDX_Control(pDX, CHECK_CIKEY, m_check_cikey);
+	DDX_Control(pDX, CHECK_MTK_INIT, m_check_mtk_init);
+	DDX_Control(pDX, CHECK_WB_INIT, m_check_wb_init);
+	// 下拉框;
+	DDX_Control(pDX, COMBO_CHANNEL, m_cb_channel);
+	DDX_Control(pDX, COMBO_OSD_LANG, m_cb_osd_lang);
+	DDX_Control(pDX, COMBO_SHOP_LANG, m_cb_shop_lang);
+	// 余量显示控件;
+	DDX_Control(pDX, STATIC_DID_COUNT, m_lb_did_count);
+	DDX_Control(pDX, STATIC_MAC_COUNT, m_lb_mac_count);
+	DDX_Control(pDX, STATIC_HDCP_COUNT, m_lb_hdcp_count);
+	DDX_Control(pDX, STATIC_HDCP22_COUNT, m_lb_hdcp22_count);
+	DDX_Control(pDX, STATIC_WIDI_COUNT, m_lb_widi_count);
+	DDX_Control(pDX, STATIC_WIDEVINE_COUNT, m_lb_widevine_count);
+	DDX_Control(pDX, STATIC_ESN_COUNT, m_lb_esn_count);
+	DDX_Control(pDX, STATIC_CI_COUNT, m_lb_cikey_count);
+	// 写状态显示控件;
+	DDX_Control(pDX, STATIC_PID_WRITE, m_lb_pid_write);
+	DDX_Control(pDX, STATIC_CHANNEL_WRITE, m_lb_channel_write);
+	DDX_Control(pDX, STATIC_OSD_LANG_WRITE, m_lb_osd_lang_write);
+	DDX_Control(pDX, STATIC_SHOP_LANG_WRITE, m_lb_shop_lang_write);
+
+	DDX_Control(pDX, STATIC_DID_WRITE, m_lb_did_write);
+	DDX_Control(pDX, STATIC_MAC_WRITE, m_lb_mac_write);
+	DDX_Control(pDX, STATIC_HDCP_WRITE, m_lb_hdcp_write);
+	DDX_Control(pDX, STATIC_HDCP22_WRITE, m_lb_hdcp22_write);
+	DDX_Control(pDX, STATIC_WIDI_WRITE, m_lb_widi_write);
+	DDX_Control(pDX, STATIC_WIDEVINE_WRITE, m_lb_widevine_write);
+	DDX_Control(pDX, STATIC_ESN_WRITE, m_lb_esn_write);
+	DDX_Control(pDX, STATIC_CI_WRITE, m_lb_cikey_write);
+	// 检测状态显示控件;
+	DDX_Control(pDX, STATIC_PID_CHECK, m_lb_pid_check);
+	DDX_Control(pDX, STATIC_CHANNEL_CHECK, m_lb_channel_check);
+	DDX_Control(pDX, STATIC_OSD_LANG_CHECK, m_lb_osd_lang_check);
+	DDX_Control(pDX, STATIC_SHOP_LANG_CHECK, m_lb_shop_lang_check);
+
+	DDX_Control(pDX, STATIC_DID_CHECK, m_lb_did_check);
+	DDX_Control(pDX, STATIC_MAC_CHECK, m_lb_mac_check);
+	DDX_Control(pDX, STATIC_HDCP_CHECK, m_lb_hdcp_check);
+	DDX_Control(pDX, STATIC_HDCP22_CHECK, m_lb_hdcp22_check);
+	DDX_Control(pDX, STATIC_WIDI_CHECK, m_lb_widi_check);
+	DDX_Control(pDX, STATIC_WIDEVINE_CHECK, m_lb_widevine_check);
+	DDX_Control(pDX, STATIC_ESN_CHECK, m_lb_esn_check);
+	DDX_Control(pDX, STATIC_CI_CHECK, m_lb_cikey_check);
+	// 读验证状态显示控件;
+	DDX_Control(pDX, STATIC_PID_READ, m_lb_pid_read);
+	DDX_Control(pDX, STATIC_CHANNEL_READ, m_lb_channel_read);
+	DDX_Control(pDX, STATIC_OSD_LANG_READ, m_lb_osd_lang_read);
+	DDX_Control(pDX, STATIC_SHOP_LANG_READ, m_lb_shop_lang_read);
+
+	DDX_Control(pDX, STATIC_DID_READ, m_lb_did_read);
+	DDX_Control(pDX, STATIC_MAC_READ, m_lb_mac_read);
+	DDX_Control(pDX, STATIC_HDCP_READ, m_lb_hdcp_read);
+	DDX_Control(pDX, STATIC_HDCP22_READ, m_lb_hdcp22_read);
+	DDX_Control(pDX, STATIC_WIDI_READ, m_lb_widi_read);
+	DDX_Control(pDX, STATIC_WIDEVINE_READ, m_lb_widevine_read);
+	DDX_Control(pDX, STATIC_ESN_READ, m_lb_esn_read);
+	DDX_Control(pDX, STATIC_CI_READ, m_lb_cikey_read);
+	DDX_Text(pDX, EDIT_PID, m_str_pid);
+	DDX_Control(pDX, STATIC_FACTORY_MODE, m_lb_enter_factory_mode);
+	DDX_Control(pDX, STATIC_ENTER_FACTORY_MODE, m_lb_enter_factory_mode_status);
+	DDX_Control(pDX, STATIC_COLUMN_A1, m_lb_column_a1);
+	DDX_Control(pDX, STATIC_COLUMN_A2, m_lb_column_a2);
+	DDX_Control(pDX, STATIC_COLUMN_A3, m_lb_column_a3);
+	DDX_Control(pDX, STATIC_COLUMN_A4, m_lb_column_a4);
+	DDX_Control(pDX, STATIC_COLUMN_A5, m_lb_column_a5);
+
+	DDX_Control(pDX, STATIC_COLUMN_B1, m_lb_column_b1);
+	DDX_Control(pDX, STATIC_COLUMN_B2, m_lb_column_b2);
+	DDX_Control(pDX, STATIC_COLUMN_B3, m_lb_column_b3);
+	DDX_Control(pDX, STATIC_COLUMN_B4, m_lb_column_b4);
+	DDX_Control(pDX, STATIC_COLUMN_B5, m_lb_column_b5);
+	DDX_Control(pDX, STATIC_RESULT, m_lb_result);
+	DDX_Control(pDX, BTN_HIDE, m_btn_hide);
+	DDX_Control(pDX, STATIC_WB_INIT, m_lb_wb_init);
+	DDX_Text(pDX, EDIT_ORDER, m_str_bid);
+	DDX_Control(pDX, CHECK_WB_WRITE, m_check_wb_write);
+	DDX_Control(pDX, STATIC_WB_WRITE, m_lb_wb_write);
+	DDX_Control(pDX, RICHEDIT2_LOG, m_edit_log);
+	DDX_Control(pDX, CHECK_VERIFY_PID, m_check_verify_pid);
+	DDX_Control(pDX, CHECK_VERIFY_CLIENT_TYPE, m_check_verify_client_type);
+	DDX_Control(pDX, CHECK_VERIFY_SOFT_VERSION, m_check_verify_soft_version);
+	DDX_Control(pDX, CHECK_SET, m_check_set);
+	DDX_Control(pDX, IDCANCEL, m_btn_cancel);
+	DDX_Control(pDX, BTN_START, m_btn_manual_start);
+	DDX_Control(pDX, CHECK_FOCUS, m_check_focus);
+	DDX_Control(pDX, CHECK_LOCK, m_check_lock);
+	DDX_Control(pDX, IDC_STATIC_TEST_MODE, m_lb_test_mode);
+}
+
+BEGIN_MESSAGE_MAP(CTCLCopyToolDlg, CDialogEx)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_WM_TIMER()
+	ON_WM_DEVICECHANGE()
+	ON_BN_CLICKED(BTN_HIDE, &CTCLCopyToolDlg::OnBnClickedHide)
+	ON_CBN_SELCHANGE(COMBO_MODE, &CTCLCopyToolDlg::OnCbnSelchangeMode)
+	ON_CBN_SELCHANGE(COMBO_CHASSIS, &CTCLCopyToolDlg::OnCbnSelchangeChassis)
+	ON_BN_CLICKED(BTN_START, &CTCLCopyToolDlg::OnBnClickedStart)
+	//	ON_WM_CTLCOLOR()
+	ON_WM_CTLCOLOR()
+	//ON_WM_ERASEBKGND()
+	ON_EN_CHANGE(EDIT_SN, &CTCLCopyToolDlg::OnEnChangeSn)
+	ON_BN_CLICKED(BTN_WB_FILE, &CTCLCopyToolDlg::OnBnClickedWbFile)
+	ON_BN_CLICKED(CHECK_LOCK, &CTCLCopyToolDlg::OnBnClickedLock)
+	ON_BN_CLICKED(CHECK_FOCUS, &CTCLCopyToolDlg::OnBnClickedFocus)
+	ON_EN_CHANGE(EDIT_ORDER, &CTCLCopyToolDlg::OnEnChangeOrder)
+	ON_COMMAND_RANGE(CHECK_DID, CHECK_CIKEY, OnGetKeyCountClicked)
+
+	ON_BN_CLICKED(BTN_CONFIG, &CTCLCopyToolDlg::OnBnClickedConfig)
+	ON_CBN_SELCHANGE(COMBO_COM, &CTCLCopyToolDlg::OnCbnSelchangeCom)
+	ON_CBN_SELCHANGE(COMBO_BD, &CTCLCopyToolDlg::OnCbnSelchangeBd)
+END_MESSAGE_MAP()
+
+
+// CTCLCopyToolDlg 消息处理程序
+
+BOOL CTCLCopyToolDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != nullptr)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	SetWindowTitle("");
+
+	ShowWindow(SW_NORMAL);
+	CenterWindow();
+
+	// 定时器,一直设置焦点控件;
+	SetTimer(0, 500, NULL);
+	g_siacp.SetMainDlg(this);
+	g_ota.SetMainDlg(this);
+	// TODO: 在此添加额外的初始化代码
+	Global::GetSysSerialPort(m_vtCOM);
+	InitCombobox_port();
+	InitCombobox_baudrate();
+	InitCtrl();
+	UpdateKeyCount();
+#if ENABLE_CHASSIS_CONFIG
+	GetDlgItem(BTN_CONFIG)->ShowWindow(SW_SHOW);
+#endif
+
+#if TEST
+	SetTimer(1, 5000, NULL);
+#endif
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CTCLCopyToolDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialogEx::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CTCLCopyToolDlg::OnPaint()
+{
+	if (IsIconic())
+	{
+		CPaintDC dc(this); // 用于绘制的设备上下文
+
+		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+		// 使图标在工作区矩形中居中
+		int cxIcon = GetSystemMetrics(SM_CXICON);
+		int cyIcon = GetSystemMetrics(SM_CYICON);
+		CRect rect;
+		GetClientRect(&rect);
+		int x = (rect.Width() - cxIcon + 1) / 2;
+		int y = (rect.Height() - cyIcon + 1) / 2;
+
+		// 绘制图标
+		dc.DrawIcon(x, y, m_hIcon);
+	}
+	else
+	{
+#if 0
+		CRect rect;
+		CPaintDC dc(this);
+		GetClientRect(rect);
+		dc.FillSolidRect(rect, DEFAULT_DLG_COLOR); //设置为绿色背景
+#endif
+		CDialogEx::OnPaint();
+	}
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CTCLCopyToolDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+
+void CTCLCopyToolDlg::InitCtrl()
+{
+	// 测试模式提醒;
+	m_lb_test_mode.SetText(_T("Test Mode"));
+	m_lb_test_mode.SetBkColor(RGB(255, 255, 0));
+	m_lb_test_mode.SetTextColor(WARN_TEXT_COLOR);
+	m_lb_test_mode.SetFontSize(8);
+
+	// 按钮;
+	m_btn_hide.SetFlat();
+	m_btn_hide.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
+	m_btn_hide.OffsetColor(CButtonST::BTNST_COLOR_FG_IN, 30);
+	m_btn_hide.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(255, 255, 0));//背景颜色;
+	m_btn_hide.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(255, 255, 0));//背景颜色;
+	m_btn_hide.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(255, 250, 11));//背景颜色;
+
+	m_btn_cancel.SetFlat(FALSE);
+	m_btn_cancel.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
+	m_btn_cancel.OffsetColor(CButtonST::BTNST_COLOR_FG_IN, 30);
+	m_btn_cancel.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(255, 255, 0));//背景颜色;
+	m_btn_cancel.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(255, 255, 0));//背景颜色;
+	m_btn_cancel.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(255, 250, 11));//背景颜色;
+
+	m_btn_manual_start.SetFlat(FALSE);
+	m_btn_manual_start.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
+	m_btn_manual_start.OffsetColor(CButtonST::BTNST_COLOR_FG_IN, 30);
+	m_btn_manual_start.SetColor(CButtonST::BTNST_COLOR_BK_IN, RGB(128, 255, 128));//背景颜色;
+	m_btn_manual_start.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(128, 255, 128));//背景颜色;
+	m_btn_manual_start.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(128, 250, 11));//背景颜色;
+
+	// combobox
+	m_cb_com.SelectString(0, Global::g_tConfig.com.c_str());
+	m_cb_baudrate.SelectString(0, Global::g_tConfig.baudrate.c_str());
+	g_siacp.OpenComm(Global::g_tConfig.com.c_str(), _ttol(Global::g_tConfig.baudrate.c_str()));
+	m_cb_mode.SetCurSel(Global::g_tConfig.mode);
+	EnableChassisCheckbox();
+
+	GetDlgItem(EDIT_ORDER)->EnableWindow(Global::g_tConfig.mode < 2);
+	GetDlgItem(EDIT_SN)->EnableWindow(Global::g_tConfig.mode < 3);
+	GetDlgItem(CHECK_LOCK)->EnableWindow(Global::g_tConfig.mode < 2);
+	GetDlgItem(CHECK_FOCUS)->EnableWindow(Global::g_tConfig.mode < 3);
+
+	// 设置wb file;
+	if (Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis) != Global::g_tConfig.chassislist.end())
+	{
+		SetDlgItemText(STATIC_WB_FILE, Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis)->second.WBFile.c_str());
+		if (Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis)->second.WBFile.size())
+		{// 加载wb file;
+			std::string wbfile = Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis)->second.WBFile;
+			m_chWBNormalBuffer[R] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white R:"), NULL, wbfile.c_str());
+			m_chWBNormalBuffer[G] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white G:"), NULL, wbfile.c_str());
+			m_chWBNormalBuffer[B] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white B:"), NULL, wbfile.c_str());
+			m_chWBWarmBuffer[R] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white R:"), NULL, wbfile.c_str());
+			m_chWBWarmBuffer[G] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white G:"), NULL, wbfile.c_str());
+			m_chWBWarmBuffer[B] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white B:"), NULL, wbfile.c_str());
+			m_chWBCoolBuffer[R] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white R:"), NULL, wbfile.c_str());
+			m_chWBCoolBuffer[G] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white G:"), NULL, wbfile.c_str());
+			m_chWBCoolBuffer[B] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white B:"), NULL, wbfile.c_str());
+		}
+	}
+
+	// 填充combobox;
+	std::map<std::string, Global::TChassis>::iterator it = Global::g_tConfig.chassislist.begin();
+	for (; it != Global::g_tConfig.chassislist.end(); it++)
+	{
+		m_cb_chassis.AddString(it->first.c_str());
+	}
+
+	m_cb_chassis.EnableWindow(Global::g_tConfig.mode > 1);
+	if (Global::g_tConfig.mode > 1)
+	{
+		m_cb_chassis.SelectString(0, Global::g_tConfig.chassis.c_str());
+	}
+	else
+	{
+		m_cb_chassis.SetCurSel(-1);
+	}
+
+	EnableChassisCheckbox();
+
+	if (Global::g_tConfig.mode > 1)
+	{// chassis
+		it = Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis);
+		if (it != Global::g_tConfig.chassislist.end())
+		{
+			// check box;
+			if (it->second.ProjectID != 0)
+			{
+				SetDlgItemInt(EDIT_PID, it->second.ProjectID);
+				m_check_pid.SetCheck(it->second.IsWritePID);
+			}
+			else
+			{
+				m_check_pid.SetCheck(FALSE);
+			}
+			m_check_channel.SetCheck(it->second.IsCopyChannel);
+			m_check_osd_lang.SetCheck(it->second.IsOsdLanguage);
+			m_check_shop_lang.SetCheck(it->second.IsShopLanguage);
+			m_check_did.SetCheck(it->second.IsCopyDID);
+			m_check_mac.SetCheck(it->second.IsCopyMAC);
+			m_check_hdcp.SetCheck(it->second.IsCopyKEY);
+			m_check_hdcp22.SetCheck(it->second.IsCopyKEY2_2);
+			m_check_widi.SetCheck(it->second.IsCopyWiDi);
+			m_check_widevine.SetCheck(it->second.IsCopyWidevine);
+			m_check_esn.SetCheck(it->second.IsCopyESN);
+			m_check_cikey.SetCheck(it->second.IsCopyCikey);
+			m_check_mtk_init.SetCheck(it->second.IsMTKInit);
+			m_check_wb_init.SetCheck(it->second.IsWBInit);
+			m_check_wb_write.SetCheck(it->second.IsCopyWB);
+
+			// combobox;
+			for (auto it : Global::g_tConfig.channel)
+			{
+				m_cb_channel.AddString(it.first.c_str());
+			}
+
+			for (auto it : Global::g_tConfig.language)
+			{
+				m_cb_osd_lang.AddString(it.first.c_str());
+			}
+
+			for (auto it : Global::g_tConfig.language)
+			{
+				m_cb_shop_lang.AddString(it.first.c_str());
+			}
+		}
+	}
+
+	// 其他单独初始化;
+	m_lb_enter_factory_mode.SetBorder();
+	m_lb_enter_factory_mode.SetFontBold();
+	m_lb_enter_factory_mode.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_enter_factory_mode.SetTextColor(NORMAL_TEXT_COLOR);
+	m_lb_enter_factory_mode.SetFontSize(10);
+	m_lb_enter_factory_mode.SetFontName(_T("微软雅黑"));
+
+	m_lb_enter_factory_mode_status.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_enter_factory_mode_status.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_enter_factory_mode_status.SetFontSize(10);
+	m_lb_enter_factory_mode_status.SetFontName(_T("微软雅黑"));
+
+	// 结果显示 ;
+	m_lb_result.SetBorder();
+	m_lb_result.SetFontBold();
+	m_lb_result.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_result.SetTextColor(NORMAL_TEXT_COLOR);
+	m_lb_result.SetFontSize(10);
+	m_lb_result.SetFontName(_T("微软雅黑"));
+
+	// 其他控件初始化;
+	InitColumn();
+	InitKeyCountLabel();
+	InitWriteStatusLabel();
+	InitReadStatusLabel();
+	InitCheckStatusLabel();
+	InitLogCharFormat();
+
+#if 1
+	m_hThread = CreateThread(NULL, 0, ThreadGetMessage, this, 0, &m_dwThreadId);
+	if (m_hThread)
+	{
+		CloseHandle(m_hThread);
+	}
+#endif
+}
+
+void CTCLCopyToolDlg::InitColumn()
+{
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetFontItalic();
+	m_lb_column_a2.SetFontItalic();
+	m_lb_column_a3.SetFontItalic();
+	m_lb_column_a4.SetFontItalic();
+	m_lb_column_a5.SetFontItalic();
+	m_lb_column_b1.SetFontItalic();
+	m_lb_column_b2.SetFontItalic();
+	m_lb_column_b3.SetFontItalic();
+	m_lb_column_b4.SetFontItalic();
+	m_lb_column_b5.SetFontItalic();
+	//////////////////////////////////////////////////////////////////////////
+// 	m_lb_column_a1.SetFontBold();
+// 	m_lb_column_a2.SetFontBold();
+// 	m_lb_column_a3.SetFontBold();
+// 	m_lb_column_a4.SetFontBold();
+// 	m_lb_column_a5.SetFontBold();
+// 	m_lb_column_b1.SetFontBold();
+// 	m_lb_column_b2.SetFontBold();
+// 	m_lb_column_b3.SetFontBold();
+// 	m_lb_column_b4.SetFontBold();
+// 	m_lb_column_b5.SetFontBold();
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetBorder();
+	m_lb_column_a2.SetBorder();
+	m_lb_column_a3.SetBorder();
+	m_lb_column_a4.SetBorder();
+	m_lb_column_a5.SetBorder();
+	m_lb_column_b1.SetBorder();
+	m_lb_column_b2.SetBorder();
+	m_lb_column_b3.SetBorder();
+	m_lb_column_b4.SetBorder();
+	m_lb_column_b5.SetBorder();
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetFontSize(10);
+	m_lb_column_a2.SetFontSize(10);
+	m_lb_column_a3.SetFontSize(10);
+	m_lb_column_a4.SetFontSize(10);
+	m_lb_column_a5.SetFontSize(10);
+	m_lb_column_b1.SetFontSize(10);
+	m_lb_column_b2.SetFontSize(10);
+	m_lb_column_b3.SetFontSize(10);
+	m_lb_column_b4.SetFontSize(10);
+	m_lb_column_b5.SetFontSize(10);
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetFontName(_T("微软雅黑"));
+	m_lb_column_a2.SetFontName(_T("微软雅黑"));
+	m_lb_column_a3.SetFontName(_T("微软雅黑"));
+	m_lb_column_a4.SetFontName(_T("微软雅黑"));
+	m_lb_column_a5.SetFontName(_T("微软雅黑"));
+	m_lb_column_b1.SetFontName(_T("微软雅黑"));
+	m_lb_column_b2.SetFontName(_T("微软雅黑"));
+	m_lb_column_b3.SetFontName(_T("微软雅黑"));
+	m_lb_column_b4.SetFontName(_T("微软雅黑"));
+	m_lb_column_b5.SetFontName(_T("微软雅黑"));
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_a2.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_a3.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_a4.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_a5.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_b1.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_b2.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_b3.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_b4.SetTextColor(RGB(26, 72, 204));
+	m_lb_column_b5.SetTextColor(RGB(26, 72, 204));
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_column_a1.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_a2.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_a3.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_a4.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_a5.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_b1.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_b2.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_b3.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_b4.SetBkColor(RGB(153, 217, 234));
+	m_lb_column_b5.SetBkColor(RGB(153, 217, 234));
+}
+
+void CTCLCopyToolDlg::InitCombobox_port()
+{
+	CComboBox* pCommbox = ((CComboBox*)GetDlgItem(COMBO_COM));
+	for (std::vector<std::string>::iterator it = m_vtCOM.begin(); it != m_vtCOM.end(); it++)
+	{
+		if (!IsPortInserted(it->c_str()))
+			pCommbox->AddString(it->c_str());
+	}
+}
+
+void CTCLCopyToolDlg::InitCombobox_baudrate()
+{
+	CComboBox* pCommbox = ((CComboBox*)GetDlgItem(COMBO_BD));
+	pCommbox = ((CComboBox*)GetDlgItem(COMBO_BD));
+	pCommbox->AddString(_T("4800"));
+	pCommbox->AddString(_T("9600"));
+	pCommbox->AddString(_T("19200"));
+	pCommbox->AddString(_T("38400"));
+	pCommbox->AddString(_T("115200"));
+}
+
+void CTCLCopyToolDlg::InitCombobox_Chassis()
+{
+	int nCount = m_cb_chassis.GetCount();
+	if (nCount == 0 || nCount != Global::g_tConfig.chassislist.size())
+	{
+		CString strChassis = _T("");
+		int nCurSel = m_cb_chassis.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			m_cb_chassis.GetLBText(nCurSel, strChassis);
+		}
+
+		m_cb_chassis.ResetContent();
+		std::map<std::string, Global::TChassis>::iterator it = Global::g_tConfig.chassislist.begin();
+		for (; it != Global::g_tConfig.chassislist.end(); it++)
+		{
+			m_cb_chassis.AddString(it->first.c_str());
+		}
+
+		if (strChassis.IsEmpty() && Global::g_tConfig.mode > 1)
+		{
+			m_cb_chassis.SetCurSel(0);
+			m_cb_chassis.GetLBText(0, strChassis);
+		}
+		else
+			m_cb_chassis.SelectString(0, strChassis.GetString());
+
+		if (Global::g_tConfig.mode > 1)
+		{
+			m_pCurChassis = &Global::g_tConfig.chassislist.find(strChassis.GetString())->second;
+			UpdateChassisCheckBoxStatus();
+		}
+	}
+}
+
+void CTCLCopyToolDlg::InitKeyCountLabel()
+{
+	// did 余量控件;
+	m_lb_did_count.SetText(_T("-----"));
+	m_lb_did_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_did_count.SetFontSize(12);
+	m_lb_did_count.SetFontName(_T("Arial"));
+
+	m_lb_mac_count.SetText(_T("-----"));
+	m_lb_mac_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_mac_count.SetFontSize(12);
+	m_lb_mac_count.SetFontName(_T("Arial"));
+
+	m_lb_hdcp_count.SetText(_T("-----"));
+	m_lb_hdcp_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp_count.SetFontSize(12);
+	m_lb_hdcp_count.SetFontName(_T("Arial"));
+
+	m_lb_hdcp22_count.SetText(_T("-----"));
+	m_lb_hdcp22_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp22_count.SetFontSize(12);
+	m_lb_hdcp22_count.SetFontName(_T("Arial"));
+
+	m_lb_widi_count.SetText(_T("-----"));
+	m_lb_widi_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widi_count.SetFontSize(12);
+	m_lb_widi_count.SetFontName(_T("Arial"));
+
+	m_lb_widevine_count.SetText(_T("-----"));
+	m_lb_widevine_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widevine_count.SetFontSize(12);
+	m_lb_widevine_count.SetFontName(_T("Arial"));
+
+	m_lb_esn_count.SetText(_T("-----"));
+	m_lb_esn_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_esn_count.SetFontSize(12);
+	m_lb_esn_count.SetFontName(_T("Arial"));
+
+	m_lb_cikey_count.SetText(_T("-----"));
+	m_lb_cikey_count.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_cikey_count.SetFontSize(12);
+	m_lb_cikey_count.SetFontName(_T("Arial"));
+}
+
+void CTCLCopyToolDlg::InitWriteStatusLabel()
+{
+	m_lb_wb_init.SetText(_T("NT"));
+	m_lb_wb_init.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_wb_init.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_wb_init.SetFontSize(10);
+	m_lb_wb_init.SetFontName(_T("微软雅黑"));
+
+	m_lb_pid_write.SetText(_T("NT"));
+	m_lb_pid_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_pid_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_pid_write.SetFontSize(10);
+	m_lb_pid_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_channel_write.SetText(_T("NT"));
+	m_lb_channel_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_channel_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_channel_write.SetFontSize(10);
+	m_lb_channel_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_osd_lang_write.SetText(_T("NT"));
+	m_lb_osd_lang_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_osd_lang_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_osd_lang_write.SetFontSize(10);
+	m_lb_osd_lang_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_shop_lang_write.SetText(_T("NT"));
+	m_lb_shop_lang_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_shop_lang_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_shop_lang_write.SetFontSize(10);
+	m_lb_shop_lang_write.SetFontName(_T("微软雅黑"));
+
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_did_write.SetText(_T("NT"));
+	m_lb_did_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_did_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_did_write.SetFontSize(10);
+	m_lb_did_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_mac_write.SetText(_T("NT"));
+	m_lb_mac_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_mac_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_mac_write.SetFontSize(10);
+	m_lb_mac_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp_write.SetText(_T("NT"));
+	m_lb_hdcp_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp_write.SetFontSize(10);
+	m_lb_hdcp_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp22_write.SetText(_T("NT"));
+	m_lb_hdcp22_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp22_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp22_write.SetFontSize(10);
+	m_lb_hdcp22_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_widi_write.SetText(_T("NT"));
+	m_lb_widi_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widi_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widi_write.SetFontSize(10);
+	m_lb_widi_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_widevine_write.SetText(_T("NT"));
+	m_lb_widevine_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widevine_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widevine_write.SetFontSize(10);
+	m_lb_widevine_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_esn_write.SetText(_T("NT"));
+	m_lb_esn_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_esn_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_esn_write.SetFontSize(10);
+	m_lb_esn_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_cikey_write.SetText(_T("NT"));
+	m_lb_cikey_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_cikey_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_cikey_write.SetFontSize(10);
+	m_lb_cikey_write.SetFontName(_T("微软雅黑"));
+
+	m_lb_wb_write.SetText(_T("NT"));
+	m_lb_wb_write.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_wb_write.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_wb_write.SetFontSize(10);
+	m_lb_wb_write.SetFontName(_T("微软雅黑"));
+}
+
+void CTCLCopyToolDlg::InitReadStatusLabel()
+{
+	m_lb_pid_read.SetText(_T("NT"));
+	m_lb_pid_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_pid_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_pid_read.SetFontSize(10);
+	m_lb_pid_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_channel_read.SetText(_T("NT"));
+	m_lb_channel_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_channel_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_channel_read.SetFontSize(10);
+	m_lb_channel_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_osd_lang_read.SetText(_T("NT"));
+	m_lb_osd_lang_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_osd_lang_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_osd_lang_read.SetFontSize(10);
+	m_lb_osd_lang_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_shop_lang_read.SetText(_T("NT"));
+	m_lb_shop_lang_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_shop_lang_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_shop_lang_read.SetFontSize(10);
+	m_lb_shop_lang_read.SetFontName(_T("微软雅黑"));
+
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_did_read.SetText(_T("NT"));
+	m_lb_did_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_did_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_did_read.SetFontSize(10);
+	m_lb_did_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_mac_read.SetText(_T("NT"));
+	m_lb_mac_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_mac_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_mac_read.SetFontSize(10);
+	m_lb_mac_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp_read.SetText(_T("NT"));
+	m_lb_hdcp_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp_read.SetFontSize(10);
+	m_lb_hdcp_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp22_read.SetText(_T("NT"));
+	m_lb_hdcp22_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp22_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp22_read.SetFontSize(10);
+	m_lb_hdcp22_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_widi_read.SetText(_T("NT"));
+	m_lb_widi_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widi_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widi_read.SetFontSize(10);
+	m_lb_widi_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_widevine_read.SetText(_T("NT"));
+	m_lb_widevine_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widevine_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widevine_read.SetFontSize(10);
+	m_lb_widevine_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_esn_read.SetText(_T("NT"));
+	m_lb_esn_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_esn_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_esn_read.SetFontSize(10);
+	m_lb_esn_read.SetFontName(_T("微软雅黑"));
+
+	m_lb_cikey_read.SetText(_T("NT"));
+	m_lb_cikey_read.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_cikey_read.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_cikey_read.SetFontSize(10);
+	m_lb_cikey_read.SetFontName(_T("微软雅黑"));
+}
+
+void CTCLCopyToolDlg::InitCheckStatusLabel()
+{
+	m_lb_pid_check.SetText(_T("NT"));
+	m_lb_pid_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_pid_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_pid_check.SetFontSize(10);
+	m_lb_pid_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_channel_check.SetText(_T("NT"));
+	m_lb_channel_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_channel_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_channel_check.SetFontSize(10);
+	m_lb_channel_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_osd_lang_check.SetText(_T("NT"));
+	m_lb_osd_lang_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_osd_lang_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_osd_lang_check.SetFontSize(10);
+	m_lb_osd_lang_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_shop_lang_check.SetText(_T("NT"));
+	m_lb_shop_lang_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_shop_lang_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_shop_lang_check.SetFontSize(10);
+	m_lb_shop_lang_check.SetFontName(_T("微软雅黑"));
+	//////////////////////////////////////////////////////////////////////////
+	m_lb_did_check.SetText(_T("NT"));
+	m_lb_did_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_did_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_did_check.SetFontSize(10);
+	m_lb_did_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_mac_check.SetText(_T("NT"));
+	m_lb_mac_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_mac_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_mac_check.SetFontSize(10);
+	m_lb_mac_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp_check.SetText(_T("NT"));
+	m_lb_hdcp_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp_check.SetFontSize(10);
+	m_lb_hdcp_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_hdcp22_check.SetText(_T("NT"));
+	m_lb_hdcp22_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_hdcp22_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_hdcp22_check.SetFontSize(10);
+	m_lb_hdcp22_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_widi_check.SetText(_T("NT"));
+	m_lb_widi_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widi_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widi_check.SetFontSize(10);
+	m_lb_widi_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_widevine_check.SetText(_T("NT"));
+	m_lb_widevine_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_widevine_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_widevine_check.SetFontSize(10);
+	m_lb_widevine_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_esn_check.SetText(_T("NT"));
+	m_lb_esn_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_esn_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_esn_check.SetFontSize(10);
+	m_lb_esn_check.SetFontName(_T("微软雅黑"));
+
+	m_lb_cikey_check.SetText(_T("NT"));
+	m_lb_cikey_check.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_cikey_check.SetTextColor(DEFAULT_TEXT_COLOR);
+	m_lb_cikey_check.SetFontSize(10);
+	m_lb_cikey_check.SetFontName(_T("微软雅黑"));
+}
+
+void CTCLCopyToolDlg::RetSetSiacpStatus()
+{
+	m_edit_log.SetWindowText(_T(""));
+	m_lb_enter_factory_mode_status.SetText(_T("NT"));
+	m_lb_enter_factory_mode_status.SetBkColor(DEFAULT_BG_COLOR);
+	m_lb_enter_factory_mode_status.SetTextColor(NORMAL_TEXT_COLOR);
+
+	//InitKeyCountLabel();
+	InitCheckStatusLabel();
+	InitReadStatusLabel();
+	InitWriteStatusLabel();
+}
+
+// 串口是否已插入commbobox中;
+BOOL CTCLCopyToolDlg::IsPortInserted(LPCTSTR lpPort)
+{
+	CComboBox* pCommbox = ((CComboBox*)GetDlgItem(COMBO_COM));
+
+	BOOL bInserted = FALSE;
+	CString strCommPort = _T("");
+	int nCount = pCommbox->GetCount();
+	for (int i = 0; i < nCount; i++)
+	{
+		pCommbox->GetLBText(i, strCommPort);
+		if (strCommPort.CompareNoCase(lpPort) == 0)
+		{
+			bInserted = TRUE;
+			break;
+		}
+	}
+
+	return bInserted;
+}
+
+void CTCLCopyToolDlg::EnableChassisCheckbox()
+{
+	BOOL bStatus = FALSE;
+	if (Global::g_tConfig.mode == 0)
+	{
+		bStatus = FALSE;
+	}
+	else if (Global::g_tConfig.mode == 1)
+	{
+		bStatus = TRUE;
+	}
+	else
+	{
+		bStatus = _tcsicmp(Global::g_tConfig.chassis.c_str(), _T("other")) == 0;
+	}
+
+	m_check_did.EnableWindow(bStatus);
+	m_check_mac.EnableWindow(bStatus);
+	m_check_hdcp.EnableWindow(bStatus);
+	m_check_hdcp22.EnableWindow(bStatus);
+	m_check_widi.EnableWindow(bStatus);
+	m_check_widevine.EnableWindow(bStatus);
+	m_check_esn.EnableWindow(bStatus);
+	m_check_cikey.EnableWindow(bStatus);
+	// 校验;
+	m_check_verify_pid.EnableWindow(Global::g_tConfig.mode < 2);
+	m_check_verify_client_type.EnableWindow(Global::g_tConfig.mode < 2);
+	m_check_verify_soft_version.EnableWindow(Global::g_tConfig.mode < 2);
+
+	if (m_pCurChassis == nullptr && Global::g_tConfig.mode != 0)
+	{
+		//m_check_wb_write.EnableWindow(bStatus);
+		//m_check_mtk_init.EnableWindow(bStatus);
+		//m_check_wb_init.EnableWindow(bStatus);
+		//m_check_pid.EnableWindow(bStatus);
+		//m_check_channel.EnableWindow(bStatus);
+		//m_check_osd_lang.EnableWindow(bStatus);
+		//m_check_shop_lang.EnableWindow(bStatus);
+		//下拉框;
+		//m_cb_channel.EnableWindow(bStatus);
+		//m_cb_osd_lang.EnableWindow(bStatus);
+		//m_cb_shop_lang.EnableWindow(bStatus);
+	}
+
+	if (Global::g_tConfig.mode == 0)
+	{
+		GetDlgItem(EDIT_PID)->EnableWindow(bStatus);
+		m_check_pid.EnableWindow(bStatus);
+	}
+	else
+	{
+		GetDlgItem(EDIT_PID)->EnableWindow(TRUE);
+		m_check_pid.EnableWindow(TRUE);
+	}
+}
+
+void CTCLCopyToolDlg::UpdateKeyCount(BOOL bUseThread /*= TRUE*/)
+{
+	static auto _update_key_count = [&]()
+	{
+		SetOptionLog(CString(_T("Update Key Count now, Please wait...\r")), OK_LOG);
+		// 如果是自动在线的,需要获取批次号;
+		if (Global::g_tConfig.mode < 2) // 自动在线+人工在线;
+		{
+			UpdateAutoOnlineMode();
+		}
+		else // 离线模式+本地模式;
+		{
+			m_cb_chassis.EnableWindow(FALSE);
+			m_cb_mode.EnableWindow(FALSE);
+			if (Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis) == Global::g_tConfig.chassislist.end())
+			{
+				m_cb_chassis.EnableWindow();
+				m_cb_mode.EnableWindow();
+				return;
+			}
+
+			m_pCurChassis = &Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis)->second;
+			// 清空余量显示;
+			InitKeyCountLabel();
+			// 更新Chassis控件状态;
+			UpdateChassisCheckBoxStatus();
+			// 更新了Chassis后再获取余量;
+			SetLabelKeyCount(_T("DeviceID"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("MAC"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("HDCP_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("HDCP2.2_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("WiDi"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("Widevine_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("NETFILX_ESN"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("CI_PLUS_KEY"), Global::g_tConfig.mode);
+			m_cb_chassis.EnableWindow();
+			m_cb_mode.EnableWindow();
+		}
+
+		SetOptionLog(CString(_T("Update Key Count Ok...\r")), OK_LOG);
+	};
+
+	if (bUseThread)
+	{
+		std::thread t([&](CTCLCopyToolDlg* p) {
+			p->GetDlgItem(BTN_START)->EnableWindow(FALSE);
+			p->GetDlgItem(IDOK)->EnableWindow(FALSE);
+			_update_key_count();
+			p->GetDlgItem(BTN_START)->EnableWindow(TRUE);
+			p->GetDlgItem(IDOK)->EnableWindow(TRUE);
+			}, this);
+		t.detach();
+	}
+	else
+	{
+		_update_key_count();
+	}
+	Sleep(500);
+}
+
+void CTCLCopyToolDlg::SetLabelKeyCount(std::string count, CLabel* pLabel)
+{
+	// 如果空,设置醒目颜色表示获取余量失败;
+	if (count.size() == 0)
+	{
+		pLabel->SetText(_T("-----"));
+		pLabel->SetTextColor(WARN_TEXT_COLOR);
+	}
+	else
+	{
+		// 去掉逗号;
+		while (count.find_first_of(',') != std::string::npos)
+			count.erase(count.find_first_of(','), 1);
+
+		pLabel->SetText(count.c_str());
+		pLabel->SetTextColor(_ttoi(count.c_str()) > Global::g_tConfig.warncount ? OK_TEXT_COLOR : WARN_TEXT_COLOR);
+	}
+}
+
+void CTCLCopyToolDlg::SetLabelKeyCount(std::string key_type, int mode /* =0 */)
+{
+	std::string count;
+	std::string key_value;
+	if (m_pCurChassis == nullptr)
+	{
+		InitKeyCountLabel();
+		return;
+	}
+
+	if (_tcsicmp(key_type.c_str(), _T("DeviceID")) == 0 && m_check_did.GetCheck())
+	{
+		//m_check_did.SetCheck(m_pCurChassis->IsCopyDID);
+		key_value = m_pCurChassis->ClientType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("DeviceID"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statdeviceid.do?",
+				"devicetype=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_did_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("MAC")) == 0 && m_check_mac.GetCheck())
+	{
+		//m_check_mac.SetCheck(m_pCurChassis->IsCopyMAC);
+		key_value = m_pCurChassis->MACType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("MAC"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statmac.do?", "typeString=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_mac_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("HDCP_KEY")) == 0 && m_check_hdcp.GetCheck())
+	{
+		//m_check_hdcp.SetCheck(m_pCurChassis->IsCopyKEY);
+		key_value = m_pCurChassis->HDCPKeyType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("HDCPKEY"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/stathdcpkey.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_hdcp_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("CI_PLUS_KEY")) == 0 && m_check_cikey.GetCheck())
+	{
+		//m_check_cikey.SetCheck(m_pCurChassis->IsCopyCikey);
+		key_value = m_pCurChassis->CIKeyType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("CIKEY"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statcikey.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_cikey_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("WiDi")) == 0 && m_check_widi.GetCheck())
+	{
+		//m_check_widi.SetCheck(m_pCurChassis->IsCopyWiDi);
+		key_value = m_pCurChassis->WiDiType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("WiDi"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statwidi.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_widi_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("Widevine_KEY")) == 0 && m_check_widevine.GetCheck())
+	{
+		//m_check_widevine.SetCheck(m_pCurChassis->IsCopyWidevine);
+		key_value = m_pCurChassis->WidevineType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("Widevine"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statwidevine.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_widevine_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("HDCP2.2_KEY")) == 0 && m_check_hdcp22.GetCheck())
+	{
+		//m_check_hdcp22.SetCheck(m_pCurChassis->IsCopyKEY2_2);
+		key_value = m_pCurChassis->HDCPKey22Type;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("HDCPKEY22"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/stathdcpkey2.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_hdcp22_count);
+	}
+	else if (_tcsicmp(key_type.c_str(), _T("NETFILX_ESN")) == 0 && m_check_esn.GetCheck())
+	{
+		//m_check_esn.SetCheck(m_pCurChassis->IsCopyESN);
+		key_value = m_pCurChassis->ESNType;
+		if (mode == 3) // 本地模式;
+		{
+			count = GetFileCount(_T("ESN"));
+		}
+		else
+		{
+			g_ota.GetKeyInfo((mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/statnetfilxesn.do?", "type=" + key_value, "count", "value", count);
+		}
+		SetLabelKeyCount(count, &m_lb_esn_count);
+	}
+}
+
+void CTCLCopyToolDlg::UpdateChassisCheckBoxStatus()
+{
+	if (m_pCurChassis != nullptr)
+	{
+		// check box;
+		if (m_pCurChassis->ProjectID != 0)
+		{
+			SetDlgItemInt(EDIT_PID, m_pCurChassis->ProjectID);
+			m_check_pid.SetCheck(m_pCurChassis->IsWritePID);
+		}
+		else
+		{
+			m_check_pid.SetCheck(FALSE);
+			SetDlgItemInt(EDIT_PID, 0);
+		}
+
+		m_check_channel.SetCheck(m_pCurChassis->IsCopyChannel);
+		m_check_osd_lang.SetCheck(m_pCurChassis->IsOsdLanguage);
+		m_check_shop_lang.SetCheck(m_pCurChassis->IsShopLanguage);
+		m_check_did.SetCheck(m_pCurChassis->IsCopyDID);
+		m_check_mac.SetCheck(m_pCurChassis->IsCopyMAC);
+		m_check_hdcp.SetCheck(m_pCurChassis->IsCopyKEY);
+		m_check_hdcp22.SetCheck(m_pCurChassis->IsCopyKEY2_2);
+		m_check_widi.SetCheck(m_pCurChassis->IsCopyWiDi);
+		m_check_widevine.SetCheck(m_pCurChassis->IsCopyWidevine);
+		m_check_esn.SetCheck(m_pCurChassis->IsCopyESN);
+		m_check_cikey.SetCheck(m_pCurChassis->IsCopyCikey);
+		m_check_mtk_init.SetCheck(m_pCurChassis->IsMTKInit);
+		m_check_wb_init.SetCheck(m_pCurChassis->IsWBInit);
+		m_check_wb_write.SetCheck(m_pCurChassis->IsCopyWB);
+	}
+	else
+	{
+		EnableChassisCheckbox();
+	}
+}
+
+void CTCLCopyToolDlg::SaveChange2Config()
+{
+	if (Global::g_tConfig.mode < 2)
+		return;
+	std::map<std::string, Global::TChassis>::iterator it;
+	it = Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis);
+	if (it != Global::g_tConfig.chassislist.end())
+	{
+		it->second.IsWritePID = m_check_pid.GetCheck();
+		UpdateData(TRUE);
+		it->second.ProjectID = _ttoi(m_str_pid.GetString());
+		it->second.IsCopyChannel = m_check_channel.GetCheck();
+		it->second.IsOsdLanguage = m_check_osd_lang.GetCheck();
+		it->second.IsShopLanguage = m_check_shop_lang.GetCheck();
+		it->second.IsCopyDID = m_check_did.GetCheck();
+		it->second.IsCopyMAC = m_check_mac.GetCheck();
+		it->second.IsCopyKEY = m_check_hdcp.GetCheck();
+		it->second.IsCopyKEY2_2 = m_check_hdcp22.GetCheck();
+		it->second.IsCopyWiDi = m_check_widi.GetCheck();
+		it->second.IsCopyWidevine = m_check_widevine.GetCheck();
+		it->second.IsCopyESN = m_check_esn.GetCheck();
+		it->second.IsCopyCikey = m_check_cikey.GetCheck();
+		it->second.IsMTKInit = m_check_mtk_init.GetCheck();
+		it->second.IsWBInit = m_check_wb_init.GetCheck();
+		it->second.IsCopyWB = m_check_wb_write.GetCheck();
+	}
+
+	int nCurSel = 0;
+	CString strCOM = _T(""), strBuadrate = _T("");
+	nCurSel = m_cb_com.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		m_cb_com.GetLBText(nCurSel, strCOM);
+	}
+
+	nCurSel = m_cb_baudrate.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		m_cb_baudrate.GetLBText(nCurSel, strBuadrate);
+	}
+
+	Global::g_tConfig.com = strCOM.GetString();
+	Global::g_tConfig.baudrate = strBuadrate.GetString();
+
+	Global::SetConfig();
+}
+
+void CTCLCopyToolDlg::UpdateAutoOnlineMode()
+{
+	CString strBid = _T("");
+	GetDlgItemText(EDIT_ORDER, strBid);
+	if (strBid.IsEmpty())
+	{
+		RetSetChassisCheckBox();
+		InitKeyCountLabel();
+		m_strLastBid.Empty();
+		m_pCurChassis = nullptr;
+	}
+	else
+	{
+		if (m_strLastBid.CompareNoCase(strBid) != 0)
+		{
+			if (strBid.GetLength() < 5)
+			{
+				//SetOptionLog(CString(_T("The length of the order is not enough!\r")), ERROR_LOG);
+				return;
+			}
+
+			m_strLastBid = strBid;
+			// 变更订单号,重置;
+			m_check_verify_pid.SetCheck(TRUE);
+			m_check_verify_client_type.SetCheck(TRUE);
+			m_check_verify_soft_version.SetCheck(TRUE);
+
+			if (g_ota.GetMIDInfo(g_midInfo, strBid.GetString(), Global::g_strMacs))
+			{
+				m_pCurChassis = &Global::g_AutoOnlineChassis;
+				// 更新check box状态;
+				UpdateChassisCheckBoxStatus();
+				// 更新Chassis状态后再获取余量;
+				SetLabelKeyCount(_T("DeviceID"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("MAC"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("HDCP_KEY"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("HDCP2.2_KEY"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("WiDi"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("Widevine_KEY"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("NETFILX_ESN"), Global::g_tConfig.mode);
+				SetLabelKeyCount(_T("CI_PLUS_KEY"), Global::g_tConfig.mode);
+
+				m_edit_log.SetWindowText(_T(""));
+				SetOptionLog(CString(_T("Get Mid Info Successful!\r")), OK_LOG);
+			}
+			else
+			{
+				m_pCurChassis = nullptr;
+				RetSetChassisCheckBox();
+				InitKeyCountLabel();
+				m_strLastBid.Empty();
+				SetOptionLog(CString(_T("Get Mid Info Failed!\r")), ERROR_LOG);
+				SetOptionLog(_T("Current PC MAC:") + Global::g_strMacs + _T("\r"), ERROR_LOG);
+			}
+		}
+		else
+		{
+			SetOptionLog(CString(_T("No change in order number, Use last Mid Info!\r")), OK_LOG);
+
+			SetLabelKeyCount(_T("DeviceID"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("MAC"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("HDCP_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("HDCP2.2_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("WiDi"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("Widevine_KEY"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("NETFILX_ESN"), Global::g_tConfig.mode);
+			SetLabelKeyCount(_T("CI_PLUS_KEY"), Global::g_tConfig.mode);
+		}
+	}
+}
+
+void CTCLCopyToolDlg::RetSetChassisCheckBox()
+{
+	m_check_channel.SetCheck(FALSE);
+	m_check_osd_lang.SetCheck(FALSE);
+	m_check_shop_lang.SetCheck(FALSE);
+	m_check_did.SetCheck(FALSE);
+	m_check_mac.SetCheck(FALSE);
+	m_check_hdcp.SetCheck(FALSE);
+	m_check_hdcp22.SetCheck(FALSE);
+	m_check_widi.SetCheck(FALSE);
+	m_check_widevine.SetCheck(FALSE);
+	m_check_esn.SetCheck(FALSE);
+	m_check_cikey.SetCheck(FALSE);
+	m_check_mtk_init.SetCheck(FALSE);
+	m_check_wb_init.SetCheck(FALSE);
+	m_check_wb_write.SetCheck(FALSE);
+	m_check_pid.SetCheck(FALSE);
+
+	// 清除pid;
+	SetDlgItemText(EDIT_PID, _T(""));
+}
+
+void CTCLCopyToolDlg::SetLabelResult(int nStatus /* = 0 */, BOOL bWriteLog /*= FALSE*/)
+{
+	if (nStatus == -1)
+	{
+		m_lb_result.SetText(_T("NT"));
+		m_lb_result.SetFontBold();
+		m_lb_result.SetTextColor(NORMAL_TEXT_COLOR);
+		m_lb_result.SetBkColor(DEFAULT_BG_COLOR);
+	}
+	else if (nStatus == 1)
+	{
+		m_lb_result.SetText(_T("OK"));
+		m_lb_result.SetFontBold();
+		m_lb_result.SetBkColor(STATUS_OK_COLOR);
+		m_lb_result.SetTextColor(RGB(255, 243, 0));
+		if (bWriteLog)
+			SetOptionLog(CString(_T("\rTest OK!\r")), OK_LOG);
+	}
+	else if (nStatus == 0)
+	{
+		m_lb_result.SetText(_T("NG"));
+		m_lb_result.SetFontBold();
+		m_lb_result.SetBkColor(STATUS_ERROR_COLOR);
+		m_lb_result.SetTextColor(RGB(255, 243, 0));
+		if (bWriteLog)
+			SetOptionLog(CString(_T("\rTest Error!\r")), ERROR_LOG);
+	}
+}
+
+void CTCLCopyToolDlg::SetSiacpStatus(CLabel& label, BOOL bOK)
+{
+	label.SetText(bOK ? _T("OK") : _T("NG"));
+	label.SetFontBold();
+	label.SetBkColor(bOK ? STATUS_OK_COLOR : STATUS_ERROR_COLOR);
+	label.SetTextColor(RGB(255, 243, 0));
+}
+
+void CTCLCopyToolDlg::SetWindowTitle(std::string client_type)
+{
+	DWORD sFileVersion[4] = { 0 };
+	DWORD sProductVerion[4] = { 0 };
+	Global::GetVersion(NULL, sFileVersion, sProductVerion);
+	TCHAR szVersion[128] = { 0 };
+	_stprintf_s(szVersion, _T("%d.%d.%d.%d"), sFileVersion[0], sFileVersion[1], sFileVersion[2], sFileVersion[3]);
+
+	CString strVer;
+
+	if (client_type.size() == 0)
+	{
+		strVer.Format(_T("TCL Copy Tool                  Version: %d.%d.%d.%d"),
+			sFileVersion[0], sFileVersion[1], sFileVersion[2], sFileVersion[3]);
+	}
+	else
+	{
+		if (client_type.find_first_of(_T("SCBC")) != std::string::npos)
+			strVer.Format(_T("SCBC User Center Copy Tool                  Version: %d.%d.%d.%d"),
+				sFileVersion[0], sFileVersion[1], sFileVersion[2], sFileVersion[3]);
+		else
+			strVer.Format(_T("Huan User Center Copy Tool                 Version: %d.%d.%d.%d"),
+				sFileVersion[0], sFileVersion[1], sFileVersion[2], sFileVersion[3]);
+	}
+
+	SetWindowText(strVer);
+}
+
+std::string CTCLCopyToolDlg::GetFileCount(std::string key_type)
+{
+	filehelper fh;
+	STR_VEC vtfiles;
+	fh.getfolderfiles((_T(".\\DataDir\\") + key_type).c_str(), NULL, &vtfiles);
+
+	TCHAR szKeyCount[10] = { 0 };
+	_itoa_s(vtfiles.size(), szKeyCount, 10);
+
+	return std::string(szKeyCount);
+}
+
+BOOL CTCLCopyToolDlg::ReadKeyFile(std::string dir, std::string& data)
+{
+	filehelper fh;
+	std::string file;
+	fh.find1st(dir, file);
+
+	FILE* pf = NULL;
+	if (fopen_s(&pf, file.c_str(), _T("rb")) == 0)
+	{
+		if (pf)
+		{
+			fseek(pf, 0, SEEK_END);
+			size_t fs = ftell(pf);
+			fseek(pf, 0, SEEK_SET);
+
+			byte* pdata = (byte*)malloc(fs);
+			if (pdata)
+			{
+				fread(pdata, fs, 1, pf);
+				fclose(pf);
+
+				data.append((char*)pdata, fs);
+				free(pdata);
+
+				m_vt_key_files.push_back(file);
+
+				return TRUE;
+			}
+			fclose(pf);
+		}
+	}
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::ReadKeyFile(std::string dir, std::string& data, std::string& file)
+{
+	filehelper fh;
+	fh.find1st(dir, file);
+
+	FILE* pf = NULL;
+	if (fopen_s(&pf, file.c_str(), _T("rb")) == 0)
+	{
+		if (pf)
+		{
+			fseek(pf, 0, SEEK_END);
+			size_t fs = ftell(pf);
+			fseek(pf, 0, SEEK_SET);
+
+			byte* pdata = (byte*)malloc(fs);
+			if (pdata)
+			{
+				fread(pdata, fs, 1, pf);
+				fclose(pf);
+
+				data.append((char*)pdata, fs);
+				free(pdata);
+
+				m_vt_key_files.push_back(file);
+
+				return TRUE;
+			}
+			fclose(pf);
+		}
+	}
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_MTKInit()
+{
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_MTKInit()) == TRUE)
+	{
+		SetOptionLog(CString(_T("MTK Init Successful!\r")));
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, TRUE);
+	}
+	else
+	{
+		SetOptionLog(CString(_T("MTK Init Failed!\r")), ERROR_LOG);
+		// 输出日志到界面中;
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, FALSE);
+		SetLabelResult(FALSE);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_EnterFactoryMode()
+{
+	BOOL bRet = FALSE;
+	// 进入工厂模式;
+	if ((bRet = g_siacp.SCBC_EnterFactory()) == TRUE)
+	{
+		SetOptionLog(CString(_T("Enter Factory Mode Successful!\r")));
+		SetSiacpStatus(m_lb_enter_factory_mode_status, TRUE);
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetOptionLog(CString(_T("Enter Factory Mode Failed!\r")), ERROR_LOG);
+		SetSiacpStatus(m_lb_enter_factory_mode_status, FALSE);
+		SetLabelResult(FALSE);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetClientType(std::string& client_type)
+{
+	BOOL bRet = FALSE;
+	// 获取Client Type;
+	if ((bRet = g_siacp.SCBC_GetClientType(client_type)) == TRUE)
+	{
+		SetOptionLog(CString(_T("Get Client Type Successful:\r")));
+		SetOptionLog(client_type + _T("\r"), INFO_LOG);
+		SetWindowTitle(client_type);
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, TRUE);
+	}
+	else
+	{
+#if DEL_CLIENT_TYPE_ERROR_LOG
+		SetOptionLog(CString(_T("Get Client Type Failed!\r")), NORMAL_LOG);
+#else
+		// 输出日志到界面中;
+		SetOptionLog(CString(_T("Get Client Type Failed!\r")), ERROR_LOG);
+#endif
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, FALSE);
+		SetLabelResult(FALSE);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetSofteVersion(std::string& soft_version)
+{
+	BOOL bRet = FALSE;
+	// 时入工厂模式;
+	if ((bRet = g_siacp.SCBC_GetSoftVersion(soft_version)) == TRUE)
+	{
+		SetOptionLog(CString(_T("Get Soft Version Successful:\r")));
+		SetOptionLog(soft_version + _T("\r"), INFO_LOG);
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, TRUE);
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetOptionLog(CString(_T("Get Soft Version Failed!\r")), ERROR_LOG);
+		//SetSiacpStatus(m_lb_enter_factory_mode_status, FALSE);
+		SetLabelResult(FALSE);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetProjectId()
+{
+	if (!m_check_pid.GetCheck() || m_str_pid.IsEmpty())
+		return FALSE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_SetProjectId(_ttoi(m_str_pid.GetString()))) == TRUE)
+	{
+		SetSiacpStatus(m_lb_pid_write);
+		SetOptionLog(CString(_T("Write project Successful!\r")));
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_pid_write, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Write project id Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetProjectId()
+{
+	int pid = 0;
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_GetProjectId(pid)) == TRUE)
+	{
+		if (_ttoi(m_str_pid.GetString()) == pid)
+		{
+			SetSiacpStatus(m_lb_pid_read);
+			SetOptionLog(CString(_T("Get project Successful:")));
+			SetOptionLog(m_str_pid + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_pid_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get project id Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetWB()
+{
+	BOOL bRet1 = g_siacp.SCBC_SetWBNormal(m_chWBNormalBuffer, WB_MAX);
+
+	// 冷模式色温赋值
+	BOOL bRet2 = g_siacp.SCBC_SetWBCool(m_chWBCoolBuffer, WB_MAX);
+
+	// 暖模式色温赋值
+	BOOL bRet3 = g_siacp.SCBC_SetWBWarm(m_chWBWarmBuffer, WB_MAX);
+
+	BOOL bRet = bRet1 & bRet2 & bRet3;
+	if (bRet)
+	{
+		SetSiacpStatus(m_lb_wb_write);
+		SetOptionLog(CString(_T("Write WB Successful!\r")));
+	}
+	else
+	{
+		SetSiacpStatus(m_lb_wb_write, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Write WB Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetChannel(std::string& channel)
+{
+	int nCurSel = 0;
+	if (!m_check_channel.GetCheck() || (nCurSel = m_cb_channel.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	CString strChannel = _T("");
+	m_cb_channel.GetLBText(nCurSel, strChannel);
+	channel = Global::g_tConfig.channel.find(strChannel.GetString())->second;
+	if ((bRet = g_siacp.SCBC_SetChannel(channel)) == TRUE)
+	{
+		SetSiacpStatus(m_lb_channel_write);
+		SetOptionLog(CString(_T("Set Channel Successful!\r")));
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_channel_write, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Set Channel Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetChannel(std::string channel)
+{
+	int nCurSel = 0;
+	if (!m_check_channel.GetCheck() || (nCurSel = m_cb_channel.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	CString strChannel = _T("");
+	m_cb_channel.GetLBText(nCurSel, strChannel);
+	if ((bRet = g_siacp.SCBC_GetChannel(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsCHANNEL || _tcsicmp(data.c_str(), channel.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_channel_read);
+			SetOptionLog(CString(_T("Get Channel Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_channel_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get Channel Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetOSDLanguage(std::string& language)
+{
+	int nCurSel = 0;
+	if (!m_check_osd_lang.GetCheck() || (nCurSel = m_cb_osd_lang.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	CString strLanguage = _T("");
+	m_cb_channel.GetLBText(nCurSel, strLanguage);
+	language = Global::g_tConfig.language.find(strLanguage.GetString())->second;
+	if ((bRet = g_siacp.SCBC_SetOSDLanguage(language)) == TRUE)
+	{
+		SetSiacpStatus(m_lb_osd_lang_write);
+		SetOptionLog(CString(_T("Set OSD Language Successful!\r")));
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_osd_lang_write, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Set OSD Language Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetOSDLanguage(std::string language)
+{
+	int nCurSel = 0;
+	if (!m_check_osd_lang.GetCheck() || (nCurSel = m_cb_osd_lang.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	CString strLanguage = _T("");
+	m_cb_channel.GetLBText(nCurSel, strLanguage);
+	if ((bRet = g_siacp.SCBC_GetOSDLanguage(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsOSD || _tcsicmp(data.c_str(), language.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_shop_lang_read);
+			SetOptionLog(CString(_T("Get OSD Language Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_shop_lang_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get OSD Language Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetShopLanguage(std::string& language)
+{
+	int nCurSel = 0;
+	if (!m_check_shop_lang.GetCheck() || (nCurSel = m_cb_shop_lang.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	CString strLanguage = _T("");
+	m_cb_shop_lang.GetLBText(nCurSel, strLanguage);
+	language = Global::g_tConfig.language.find(strLanguage.GetString())->second;
+	if ((bRet = g_siacp.SCBC_SetShopLanguage(language)) == TRUE)
+	{
+		SetSiacpStatus(m_lb_shop_lang_write);
+		SetOptionLog(CString(_T("Set Shop Language Successful!\r")));
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_shop_lang_write, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Set Shop Language Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetShopLanguage(std::string language)
+{
+	int nCurSel = 0;
+	if (!m_check_shop_lang.GetCheck() || (nCurSel = m_cb_shop_lang.GetCurSel()) == CB_ERR)
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	CString strLanguage = _T("");
+	m_cb_channel.GetLBText(nCurSel, strLanguage);
+	if ((bRet = g_siacp.SCBC_GetShopLanguage(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsSHOP || _tcsicmp(data.c_str(), language.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_shop_lang_read);
+			SetOptionLog(CString(_T("Get Shop Language Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_shop_lang_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get Shop Language Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetDeviceId(std::string& deviceid)
+{
+	if (!m_check_did.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("DIDFolder")->second, deviceid/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetDeviceId(deviceid)) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				SetSiacpStatus(m_lb_did_write);
+				SetOptionLog(CString(_T("Set Device id Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getid.do?",
+		"devicetype=" + m_pCurChassis->ClientType + "&sn=" + m_str_sn.GetString(), "id", "deviceid", deviceid))
+	{
+		if ((bRet = g_siacp.SCBC_SetDeviceId(deviceid)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_did_write);
+			SetOptionLog(CString(_T("Set Device id Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_did_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set Device id Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckDeviceId()
+{
+	if (!m_check_did.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckDeviceId()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_did_check);
+		SetOptionLog(CString(_T("Check Device id Successful!\r")));
+	}
+	else
+	{
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_did_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check Device id Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetDeviceId(std::string deviceid)
+{
+	if (!m_check_did.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetDeviceId(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsDID || _tcsicmp(deviceid.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_did_read);
+			SetOptionLog(CString(_T("Get Device id Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_did_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get Device id Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetMac(std::string& mac)
+{
+	if (!m_check_mac.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("MACFolder")->second, mac/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetMAC((byte*)mac.data(), mac.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				mac = Bytes2HexString((const byte*)mac.c_str(), mac.size(), '-');
+				SetSiacpStatus(m_lb_mac_write);
+				SetOptionLog(CString(_T("Set MAC Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getmac.do?",
+		"typeString=" + m_pCurChassis->MACType + "&sn=" + m_str_sn.GetString(), "mac", "value", mac))
+	{
+		if ((bRet = g_siacp.SCBC_SetMAC(mac)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_mac_write);
+			SetOptionLog(CString(_T("Set MAC Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_mac_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set MAC Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckMac()
+{
+	if (!m_check_mac.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckMAC()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_mac_check);
+		SetOptionLog(CString(_T("Check MAC Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_mac_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check MAC Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetMac(std::string mac)
+{
+	if (!m_check_mac.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetMAC(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsMAC || _tcsicmp(mac.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_mac_read);
+			SetOptionLog(CString(_T("Get MAC Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_mac_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get MAC Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetHDCP(std::string& hdcp)
+{
+	if (!m_check_hdcp.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("KEYFolder")->second, hdcp/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetHDCPKey((byte*)hdcp.data(), hdcp.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				hdcp = Bytes2HexString((const byte*)hdcp.c_str(), hdcp.size());
+				SetSiacpStatus(m_lb_hdcp_write);
+				SetOptionLog(CString(_T("Set HDCP Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/gethdcpkey.do?",
+		"type=" + m_pCurChassis->HDCPKeyType + "&sn=" + m_str_sn.GetString(), "key", "value", hdcp))
+	{
+		if ((bRet = g_siacp.SCBC_SetHDCPKey(hdcp)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_hdcp_write);
+			SetOptionLog(CString(_T("Set HDCP Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_hdcp_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set HDCP Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckHDCP()
+{
+	if (!m_check_hdcp.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckHDCP()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_hdcp_check);
+		SetOptionLog(CString(_T("Check HDCP Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_hdcp_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check HDCP Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetHDCP(std::string hdcp)
+{
+	if (!m_check_hdcp.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetHDCPKey(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsHDCP || _tcsicmp(hdcp.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_hdcp_read);
+			SetOptionLog(CString(_T("Get HDCP Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_hdcp_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get HDCP Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetHDCP22(std::string& hdcp22)
+{
+	if (!m_check_hdcp22.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("HDCPKEY22Folder")->second, hdcp22/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetHDCPKey22((byte*)hdcp22.data(), hdcp22.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				hdcp22 = Bytes2HexString((const byte*)hdcp22.c_str(), hdcp22.size());
+				SetSiacpStatus(m_lb_hdcp22_write);
+				SetOptionLog(CString(_T("Set HDCP2 Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/gethdcpkey2.do?",
+		"type=" + m_pCurChassis->HDCPKey22Type + "&sn=" + m_str_sn.GetString(), "key", "value", hdcp22))
+	{
+		if ((bRet = g_siacp.SCBC_SetHDCPKey22(hdcp22)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_hdcp22_write);
+			SetOptionLog(CString(_T("Set HDCP2 Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_hdcp22_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set HDCP2 Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckHDCP22()
+{
+	if (!m_check_hdcp22.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckHDCP22()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_hdcp22_check);
+		SetOptionLog(CString(_T("Check HDCP2 Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_hdcp22_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check HDCP2 Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetHDCP22(std::string hdcp22)
+{
+	if (!m_check_hdcp22.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetHDCPKey22(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsHDCP22 || _tcsicmp(hdcp22.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_hdcp22_read);
+			SetOptionLog(CString(_T("Get HDCP2 Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_hdcp22_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get HDCP2 Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+
+BOOL CTCLCopyToolDlg::Siacp_SetWidi(std::string& widi)
+{
+	if (!m_check_widi.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("WiDiFolder")->second, widi/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetWidi((byte*)widi.data(), widi.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				widi = Bytes2HexString((const byte*)widi.c_str(), widi.size());
+				SetSiacpStatus(m_lb_widi_write);
+				SetOptionLog(CString(_T("Set Widi Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getwidi.do?",
+		"type=" + m_pCurChassis->WiDiType + "&sn=" + m_str_sn.GetString(), "key", "value", widi))
+	{
+		if ((bRet = g_siacp.SCBC_SetWidi(widi)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_widi_write);
+			SetOptionLog(CString(_T("Set Widi Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_widi_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set Widi Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckWidi()
+{
+	if (!m_check_widi.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckWidi()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_widi_check);
+		SetOptionLog(CString(_T("Check Widi Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_widi_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check Widi Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetWidi(std::string widi)
+{
+	if (!m_check_widi.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetWidi(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsWIDI || _tcsicmp(widi.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_widi_read);
+			SetOptionLog(CString(_T("Get Widi Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_widi_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get Widi Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetWidevine(std::string& widevine)
+{
+	if (!m_check_widevine.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("WidevineFolder")->second, widevine/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetWidevine((byte*)widevine.data(), widevine.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				widevine = Bytes2HexString((const byte*)widevine.c_str(), widevine.size());
+				SetSiacpStatus(m_lb_widevine_write);
+				SetOptionLog(CString(_T("Set widevine Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getwidevine.do?",
+		"type=" + m_pCurChassis->WidevineType + "&sn=" + m_str_sn.GetString(), "widevine", "value", widevine))
+	{
+		if ((bRet = g_siacp.SCBC_SetWidevine(widevine)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_widevine_write);
+			SetOptionLog(CString(_T("Set widevine Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_widevine_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set widevine Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckWidevine()
+{
+	if (!m_check_widevine.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckWidevine()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_widevine_check);
+		SetOptionLog(CString(_T("Check widevine Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_widevine_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check widevine Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetWidevine(std::string widevine)
+{
+	if (!m_check_widevine.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetWidevine(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsWIDEVINE || _tcsicmp(widevine.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_widevine_read);
+			SetOptionLog(CString(_T("Get widevine Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_widevine_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get widevine Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetESN(std::string& esn)
+{
+	if (!m_check_esn.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("ESNFolder")->second, esn/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetNetflixESN((byte*)esn.data(), esn.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				esn = Bytes2HexString((const byte*)esn.c_str(), esn.size());
+				SetSiacpStatus(m_lb_esn_write);
+				SetOptionLog(CString(_T("Set Netflix ESN Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getnetfilxesn.do?",
+		"type=" + m_pCurChassis->ESNType + "&sn=" + m_str_sn.GetString(), "esn", "value", esn))
+	{
+		if ((bRet = g_siacp.SCBC_SetNetflixESN(esn)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_esn_write);
+			SetOptionLog(CString(_T("Set Netflix ESN Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_esn_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set Netflix ESN Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckESN()
+{
+	if (!m_check_esn.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckNetflixESN()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_esn_check);
+		SetOptionLog(CString(_T("Check Netflix ESN Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_esn_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check Netflix ESN Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetESN(std::string esn)
+{
+	if (!m_check_esn.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetNetflixESN(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsESN || _tcsicmp(esn.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_esn_read);
+			SetOptionLog(CString(_T("Check Netflix ESN Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_esn_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get Netflix ESN Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_SetCikey(std::string& cikey)
+{
+	if (!m_check_cikey.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if (Global::g_tConfig.mode == 3)
+	{
+		std::string file;
+		if (ReadKeyFile(Global::g_tConfig.keyfolder.find("CIKeyFolder")->second, cikey/*, file*/))
+		{
+			if ((bRet = g_siacp.SCBC_SetCiKey((byte*)cikey.data(), cikey.size())) == TRUE)
+			{
+				//DeleteFile(file.c_str());
+				cikey = Bytes2HexString((const byte*)cikey.c_str(), cikey.size());
+				SetSiacpStatus(m_lb_cikey_write);
+				SetOptionLog(CString(_T("Set cikey Successful!\r")));
+				return TRUE;
+			}
+		}
+	}
+	else if (g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/getcikey.do?",
+		"type=" + m_pCurChassis->CIKeyType + "&sn=" + m_str_sn.GetString(), "key", "value", cikey))
+	{
+		if ((bRet = g_siacp.SCBC_SetCiKey(cikey)) == TRUE)
+		{
+			SetSiacpStatus(m_lb_cikey_write);
+			SetOptionLog(CString(_T("Set cikey Successful!\r")));
+			return TRUE;
+		}
+	}
+
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_cikey_write, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Set cikey Failed!\r")), ERROR_LOG);
+
+	return FALSE;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_CheckCikey()
+{
+	if (!m_check_cikey.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	if ((bRet = g_siacp.SCBC_CheckCikey()) == TRUE)
+	{
+		SetSiacpStatus(m_lb_cikey_check);
+		SetOptionLog(CString(_T("Check cikey Successful!\r")));
+	}
+	else {
+		// 输出日志到界面中;
+		SetSiacpStatus(m_lb_cikey_check, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Check cikey Failed!\r")), ERROR_LOG);
+	}
+
+	return bRet;
+}
+
+BOOL CTCLCopyToolDlg::Siacp_GetCikey(std::string cikey)
+{
+	if (!m_check_cikey.GetCheck())
+		return TRUE;
+
+	BOOL bRet = FALSE;
+	std::string data;
+	if ((bRet = g_siacp.SCBC_GetCiKey(data)) == TRUE)
+	{
+		if (!Global::g_tConfig.writedone.IsCI || _tcsicmp(cikey.c_str(), data.c_str()) == 0)
+		{
+			SetSiacpStatus(m_lb_cikey_read);
+			SetOptionLog(CString(_T("Get cikey Successful:\r")));
+			SetOptionLog(data + _T("\r"), INFO_LOG);
+			return TRUE;
+		}
+	}
+#if TEST
+	else
+	{
+		SetSiacpStatus(m_lb_cikey_read, FALSE);
+		SetLabelResult(FALSE);
+		SetOptionLog(CString(_T("Get cikey Failed!, Try again\r")), ERROR_LOG);
+
+		if ((bRet = g_siacp.SCBC_GetCiKey(data)) == TRUE)
+		{
+			if (_tcsicmp(cikey.c_str(), data.c_str()) == 0)
+			{
+				//SetSiacpStatus(m_lb_cikey_read);
+				SetOptionLog(CString(_T("Get cikey Successful:\r")));
+				SetOptionLog(data + _T("\r"), INFO_LOG);
+				//return TRUE;
+			}
+		}
+	}
+#else
+	// 输出日志到界面中;
+	SetSiacpStatus(m_lb_cikey_read, FALSE);
+	SetLabelResult(FALSE);
+	SetOptionLog(CString(_T("Get cikey Failed!\r")), ERROR_LOG);
+#endif
+	return FALSE;
+}
+
+void CTCLCopyToolDlg::InitLogCharFormat()
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 字体初始化;
+	m_cf_normal.cbSize = sizeof(CHARFORMAT);
+	m_cf_normal.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
+	m_cf_normal.dwEffects = (unsigned long)~(CFE_UNDERLINE | CFE_BOLD | CFE_AUTOCOLOR);
+	//cf.dwEffects ^= CFE_AUTOCOLOR;
+	m_cf_normal.crTextColor = BLACK_TEXT_COLOR;
+	m_cf_normal.yHeight = 180;
+	memset(m_cf_normal.szFaceName, 0, LF_FACESIZE);
+	memcpy(m_cf_normal.szFaceName, _T("宋体"), sizeof(_T("宋体")));
+
+	// 错误;
+	m_cf_error.cbSize = sizeof(CHARFORMAT);
+	m_cf_error.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
+	m_cf_error.dwEffects = (unsigned long)~(CFE_UNDERLINE | CFE_AUTOCOLOR);
+	//cf.dwEffects ^= CFE_AUTOCOLOR;
+	m_cf_error.crTextColor = WARN_TEXT_COLOR;
+	m_cf_error.yHeight = 220;
+	memset(m_cf_error.szFaceName, 0, LF_FACESIZE);
+	memcpy(m_cf_error.szFaceName, _T("宋体"), sizeof(_T("宋体")));
+
+	// 成功;
+	m_cf_ok.cbSize = sizeof(CHARFORMAT);
+	m_cf_ok.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
+	m_cf_ok.dwEffects = (unsigned long)~(CFE_UNDERLINE | CFE_AUTOCOLOR);
+	//cf.dwEffects ^= CFE_AUTOCOLOR;
+	m_cf_ok.crTextColor = OK_TEXT_COLOR;
+	m_cf_ok.yHeight = 220;
+	memset(m_cf_ok.szFaceName, 0, LF_FACESIZE);
+	memcpy(m_cf_ok.szFaceName, _T("宋体"), sizeof(_T("宋体")));
+
+	// 信息;
+	m_cf_info.cbSize = sizeof(CHARFORMAT);
+	m_cf_info.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
+	m_cf_info.dwEffects = (unsigned long)~(CFE_UNDERLINE | CFE_BOLD | CFE_AUTOCOLOR);
+	//cf.dwEffects ^= CFE_AUTOCOLOR;
+	m_cf_info.crTextColor = NORMAL_TEXT_COLOR;
+	m_cf_info.yHeight = 200;
+	memset(m_cf_info.szFaceName, 0, LF_FACESIZE);
+	memcpy(m_cf_info.szFaceName, _T("宋体"), sizeof(_T("宋体")));
+	//////////////////////////////////////////////////////////////////////////
+}
+
+DWORD __stdcall CTCLCopyToolDlg::ThreadGetMessage(LPVOID lpParam)
+{
+	MSG msg;
+	CTCLCopyToolDlg* pDlg = (CTCLCopyToolDlg*)lpParam;
+	while (::GetMessage(&msg, NULL, 0, 0))
+	{
+		switch (msg.message)
+		{
+		case WM_GET_BARCODE:
+		{
+			Sleep(300); // 等待条码输入完成;
+			CString strSN = _T("");
+			pDlg->GetDlgItemTextA(EDIT_SN, strSN);
+			if (strSN.GetLength() >= 12)
+			{
+				pDlg->GetDlgItemText(EDIT_SN, pDlg->m_str_sn);
+				//pDlg->OnBnClickedStart();//线程中不能使用UpdateData();
+				pDlg->PostMessage(WM_COMMAND, MAKEWPARAM(BTN_START, BN_CLICKED), NULL);
+			}
+			else
+			{
+				pDlg->SetOptionLog(CString("Sn length less than 12:") + strSN + CString(_T("\r")), INFO_LOG);
+			}
+			// 完成后清空编辑框;
+			pDlg->SetDlgItemText(EDIT_SN, _T(""));
+			pDlg->m_bGetBarCode = FALSE;
+		}
+		break;
+		case WM_GET_ORDERNUM:
+		{
+			//Sleep(2500); // 等待订单号输入完成;
+			pDlg->GetDlgItem(BTN_START)->EnableWindow(FALSE);
+			pDlg->GetDlgItem(IDOK)->EnableWindow(FALSE);
+			pDlg->UpdateAutoOnlineMode();
+			pDlg->m_bGetOrderNum = FALSE;
+			pDlg->GetDlgItem(BTN_START)->EnableWindow(TRUE);
+			pDlg->GetDlgItem(IDOK)->EnableWindow(TRUE);
+		}
+		break;
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+LRESULT __stdcall CTCLCopyToolDlg::CBTHookProc(long nCode, WPARAM wparam, LPARAM lparam)
+{
+	if (nCode == HCBT_ACTIVATE)
+	{
+		::SetDlgItemText((HWND)wparam, IDYES, "&Continue");
+		::SetDlgItemText((HWND)wparam, IDNO, "&Cancel");
+		::SetDlgItemText((HWND)wparam, IDOK, "&OK");
+		::SetDlgItemText((HWND)wparam, IDCANCEL, "&Cancel");
+		UnhookWindowsHookEx(m_hHook);
+	}
+
+	return LRESULT(0);
+}
+
+//实现串口热插拔  
+BOOL CTCLCopyToolDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
+{
+	switch (nEventType)
+	{
+		// 串口拨掉;
+	case DBT_DEVICEREMOVECOMPLETE:
+		break;
+		// 串口插入;
+	case DBT_DEVICEARRIVAL:
+		Global::GetSysSerialPort(m_vtCOM);
+		InitCombobox_port();
+		break;
+	default:
+		break;
+	}
+	return TRUE;
+}
+
+void CTCLCopyToolDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	if (nIDEvent == 0)
+	{
+		if (Global::g_tConfig.mode < 3)
+		{
+			if (m_bAutofocus)
+			{
+				if (GetDlgItem(EDIT_SN) != GetFocus())
+					GetDlgItem(EDIT_SN)->SetFocus();
+			}
+
+			CWnd* pWnd = GetFocus();
+			if (pWnd == GetDlgItem(EDIT_SN))
+			{
+				// 关闭输入法;
+				HWND hWnd = ::GetForegroundWindow();
+				HIMC hImc = ImmGetContext(hWnd);
+				if (ImmGetOpenStatus(hImc))
+					ImmSetOpenStatus(hImc, FALSE);
+			}
+		}
+	}
+#if TEST
+	else if (nIDEvent == 1)
+	{
+		if (m_str_sn.IsEmpty() && Global::g_tConfig.mode == 2 && GetDlgItem(EDIT_SN)->IsWindowEnabled())
+			SetDlgItemText(EDIT_SN, _T("6aca86586a84851744c"));
+	}
+#endif
+
+	CDialogEx::OnTimer(nIDEvent);
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedHide()  // 隐藏界面;
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CRect rcHide;
+	static BOOL bHide = FALSE;
+	if (!bHide)
+	{// 隐藏;
+		GetWindowRect(m_rcWind);
+		GetDlgItem(IDC_GROUP_HIDE)->GetWindowRect(rcHide);
+		m_rcWind.right = rcHide.left + 8;
+		MoveWindow(m_rcWind);
+		SetDlgItemText(BTN_HIDE, _T(">"));
+
+		if (Global::g_bTestHost)
+		{
+			m_lb_test_mode.GetWindowRect(m_rcWind);
+			m_rcWind.right = rcHide.left;
+			ScreenToClient(m_rcWind);
+			m_lb_test_mode.MoveWindow(m_rcWind);
+			m_lb_test_mode.SetText("Test Mode");
+		}
+	}
+	else
+	{// 伸展;
+		GetWindowRect(m_rcWind);
+		GetDlgItem(IDC_GROUP_HIDE)->GetWindowRect(rcHide);
+		m_rcWind.right += rcHide.Width() + 15;
+		MoveWindow(m_rcWind);
+		SetDlgItemText(BTN_HIDE, _T("<"));
+
+		if (Global::g_bTestHost)
+		{
+			m_lb_test_mode.GetWindowRect(m_rcWind);
+			m_rcWind.right += rcHide.Width() + 15;
+			ScreenToClient(m_rcWind);
+			m_lb_test_mode.MoveWindow(m_rcWind);
+			m_lb_test_mode.SetText("Test Mode");
+		}
+		}
+
+	bHide = !bHide;
+	}
+
+void CTCLCopyToolDlg::OnCbnSelchangeMode() // 模式;
+{
+	// TODO: 在此添加控件通知处理程序代码
+	SaveChange2Config();
+	SetLabelResult(-1);
+	RetSetSiacpStatus();
+	SetDlgItemText(RICHEDIT2_LOG, _T(""));
+
+#if ENABLE_VCODE
+	if (m_cb_mode.GetCurSel() != 0)
+	{
+
+	}
+#else
+	Global::g_tConfig.mode = m_cb_mode.GetCurSel();
+#endif
+	m_cb_chassis.EnableWindow(Global::g_tConfig.mode > 1);
+	GetDlgItem(CHECK_LOCK)->EnableWindow(Global::g_tConfig.mode < 2);
+	GetDlgItem(CHECK_FOCUS)->EnableWindow(Global::g_tConfig.mode < 3);
+	EnableChassisCheckbox();
+
+	if (Global::g_tConfig.mode < 2) // 自动+手动;
+	{
+		m_cb_chassis.SetCurSel(-1);
+		GetDlgItem(EDIT_ORDER)->EnableWindow(!m_check_lock.GetCheck());
+		GetDlgItem(EDIT_SN)->EnableWindow(TRUE);
+	}
+	else // 离线+本地;
+	{
+		int nCurSel = 0;
+		CString strChassis = _T("");
+		if (CB_ERR != (nCurSel = m_cb_chassis.GetCurSel()))
+		{
+			m_cb_chassis.GetLBText(nCurSel, strChassis);
+			Global::g_tConfig.chassis = strChassis.GetString();
+		}
+		else
+		{
+			m_cb_chassis.SelectString(0, Global::g_tConfig.chassis.c_str());
+		}
+
+		if (m_check_lock.GetCheck())
+		{
+			m_check_lock.SetCheck(FALSE);
+			PostMessage(WM_COMMAND, MAKEWPARAM(CHECK_LOCK, BN_CLICKED), NULL);
+		}
+
+		if (Global::g_tConfig.mode == 2) // 离线;
+		{
+			GetDlgItem(EDIT_ORDER)->EnableWindow(FALSE);
+			GetDlgItem(EDIT_SN)->EnableWindow(TRUE);
+		}
+		else  // 本地;
+		{
+			GetDlgItem(EDIT_ORDER)->EnableWindow(FALSE);
+			GetDlgItem(EDIT_SN)->EnableWindow(FALSE);
+		}
+	}
+
+	if (Global::g_tConfig.mode > 1) // 离线+本地,清空;
+	{
+		//m_str_sn.Empty();
+		SetDlgItemText(EDIT_SN, _T(""));
+		m_str_bid.Empty();
+		UpdateData(FALSE);
+	}
+
+	UpdateKeyCount();
+	UpdateChassisCheckBoxStatus();
+}
+
+
+void CTCLCopyToolDlg::OnCbnSelchangeChassis() // Chassis
+{
+	SetDlgItemText(RICHEDIT2_LOG, _T(""));
+	// TODO: 在此添加控件通知处理程序代码
+	int nCurSel = m_cb_chassis.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		CString strChassis;
+		m_cb_chassis.GetLBText(nCurSel, strChassis);
+		SaveChange2Config();
+		Global::g_tConfig.chassis = strChassis.GetString();
+
+		UpdateKeyCount();
+		//UpdateChassisCheckBoxStatus();
+		EnableChassisCheckbox();
+	}
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedStart()  // 开始;
+{
+	static ThreadSection _critSection;
+	AutoThreadSection aSection(&_critSection);
+
+	m_dwTickCount = GetTickCount64();
+	if (m_bRunning)
+		return;
+
+	m_bRunning = TRUE;
+	UpdateData();
+	SaveChange2Config();
+	SetLabelResult(-1);
+	RetSetSiacpStatus();
+	m_vt_key_files.clear();
+
+	if (!m_str_sn.IsEmpty())
+	{
+		GetDlgItem(EDIT_SN)->EnableWindow(FALSE);
+		SetOptionLog(CString(_T("Current SN:")) + m_str_sn + CString(_T("\r")), INFO_LOG);
+	}
+
+	// 打开串口;
+	if (!g_siacp.IsOpen())
+	{
+		int nIndex = -1;
+		CString strCom = _T("");
+		if (CB_ERR != (nIndex = m_cb_com.GetCurSel()))
+		{
+			m_cb_com.GetLBText(nIndex, strCom);
+			if (CB_ERR != (nIndex = m_cb_baudrate.GetCurSel()))
+			{
+				CString strBaudrate = _T("");
+				m_cb_baudrate.GetLBText(nIndex, strBaudrate);
+				if (!g_siacp.OpenComm(strCom.GetString(), _ttoi(strBaudrate.GetString())))
+				{
+					m_bRunning = FALSE;
+					m_str_sn.Empty();
+					GetDlgItem(EDIT_SN)->EnableWindow();
+					MessageBox(_T("Open Serial Port Fail, Please Check!"), _T("Error"), MB_OK | MB_ICONERROR);
+					return;
+				}
+			}
+			else
+			{
+				m_bRunning = FALSE;
+				m_str_sn.Empty();
+				GetDlgItem(EDIT_SN)->EnableWindow();
+				MessageBox(_T("No selection of baud rate!"), _T("Error"), MB_OK | MB_ICONERROR);
+				return;
+			}
+		}
+		else
+		{
+			m_bRunning = FALSE;
+			m_str_sn.Empty();
+			GetDlgItem(EDIT_SN)->EnableWindow();
+			MessageBox(_T("No Serial Port Selection!"), _T("Error"), MB_OK | MB_ICONERROR);
+			return;
+		}
+	}
+
+	if (Global::g_tConfig.mode < 2)
+	{
+		if (m_str_bid.IsEmpty())
+		{
+			m_bRunning = FALSE;
+			m_str_sn.Empty();
+			GetDlgItem(EDIT_SN)->EnableWindow();
+			MessageBox(_T("Order number cannot be empty"), _T("error"), MB_OK | MB_TOPMOST | MB_ICONERROR);
+			GetDlgItem(EDIT_ORDER)->SetFocus();
+			return;
+		}
+
+		UpdateAutoOnlineMode();
+	}
+
+	// TODO: 在此添加控件通知处理程序代码
+	std::thread t([](CTCLCopyToolDlg* p) {
+		p->GetDlgItem(BTN_START)->EnableWindow(FALSE);
+		p->GetDlgItem(IDOK)->EnableWindow(FALSE);
+
+		// 开机盲抄等待;
+		BOOL bTVBoot = FALSE;
+		//Sleep(Global::g_tConfig.waitboot);
+		int nWatiCount = Global::g_tConfig.waitboot / 1000;
+		p->SetOptionLog(CString(_T("Waiting TV Boot...\r")));
+		for (int i = 0; i < nWatiCount; i++)
+		{
+			if (g_siacp.SCBC_WaitTVBoot())
+			{
+				p->SetOptionLog(CString(_T("TV Boot Ok\r")), OK_LOG);
+				bTVBoot = TRUE;
+				Sleep(500);
+				break;
+			}
+			Sleep(1000);
+		}
+
+		if (!bTVBoot)
+		{
+			p->SetOptionLog(CString(_T("TV Boot Failed\r")), ERROR_LOG);
+			p->SetLabelResult(0);
+			goto over;
+		}
+
+		if (p->m_check_mtk_init.GetCheck())
+		{
+			if (!p->Siacp_MTKInit())
+			{
+				p->SetLabelResult(0);
+				goto over;
+			}
+		}
+
+		if (p->Siacp_EnterFactoryMode())
+		{
+			bool result = true;
+			CString strLog = _T("");
+			std::string context;// post结果;
+			std::string client_type, softe_version, deviceid, mac;
+			std::string hdcp, hdcp22, widi, widevine, esn, cikey, channel, language;
+
+			// 读取client type;
+			p->Siacp_GetClientType(client_type);
+			// 校验client type是否与服务器一致;
+			if (Global::g_tConfig.mode < 2 && p->m_check_verify_client_type.GetCheck())
+			{
+				if (_tcsicmp(client_type.c_str(), g_midInfo.clienttype.c_str()))
+				{
+					p->m_hHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTHookProc, AfxGetInstanceHandle(), GetCurrentThreadId());
+
+					CString strMsg;
+					strMsg.Format(_T("Current core client type: %s \r\nis inconsistent with RDM mass-produced client type:%s!\r\nplease check and confirm!"),
+						client_type.c_str(), g_midInfo.clienttype.c_str());
+					if (p->MessageBox(strMsg, _T("Warnning"), MB_YESNO | MB_TOPMOST | MB_ICONERROR) == IDYES)
+					{
+						p->m_check_verify_client_type.SetCheck(FALSE);
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+			}
+
+			// 读取版本号;
+			p->Siacp_GetSofteVersion(softe_version);
+			if (Global::g_tConfig.mode < 2 && p->m_check_verify_soft_version.GetCheck())
+			{
+				if (_tcsicmp(softe_version.c_str(), g_midInfo.version.c_str()))
+				{
+					p->m_hHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTHookProc, AfxGetInstanceHandle(), GetCurrentThreadId());
+					CString strMsg;
+					strMsg.Format(_T("Current core software version: %s\r\nis inconsistent with RDM mass-produced software version:%s!\r\nplease check and confirm!"),
+						softe_version.c_str(), g_midInfo.version.c_str());
+					if (p->MessageBox(strMsg, _T("Warnning"), MB_YESNO | MB_TOPMOST | MB_ICONERROR) == IDYES)
+					{
+						p->m_check_verify_soft_version.SetCheck(FALSE);
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+			}
+
+			if (p->m_check_did.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsDID ? p->Siacp_SetDeviceId(deviceid) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsDID ? p->Siacp_CheckDeviceId() : true) &&
+						(Global::g_tConfig.readcheck.IsDID ? p->Siacp_GetDeviceId(deviceid) : true))
+					{
+						context.append("deviceid=" + deviceid + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_mac.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsMAC ? p->Siacp_SetMac(mac) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsMAC ? p->Siacp_CheckMac() : true) &&
+						(Global::g_tConfig.readcheck.IsMAC ? p->Siacp_GetMac(mac) : true))
+					{
+						context.append("mac=" + mac + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_hdcp.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsHDCP ? p->Siacp_SetHDCP(hdcp) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsHDCP ? p->Siacp_CheckHDCP() : true) &&
+						(Global::g_tConfig.readcheck.IsHDCP ? p->Siacp_GetHDCP(hdcp) : true))
+					{
+						context.append("hdcpkey=" + hdcp + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_hdcp22.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsHDCP22 ? p->Siacp_SetHDCP22(hdcp22) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsHDCP22 ? p->Siacp_CheckHDCP22() : true) &&
+						(Global::g_tConfig.readcheck.IsHDCP22 ? p->Siacp_GetHDCP22(hdcp22) : true))
+					{
+						context.append("hdcpkey2=" + hdcp22 + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_widi.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsWIDI ? p->Siacp_SetWidi(widi) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsWIDI ? p->Siacp_CheckWidi() : true) &&
+						(Global::g_tConfig.readcheck.IsWIDI ? p->Siacp_GetWidi(widi) : true))
+					{
+						context.append("widi=" + widi + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_widevine.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsWIDEVINE ? p->Siacp_SetWidevine(widevine) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsWIDEVINE ? p->Siacp_CheckWidevine() : true) &&
+						(Global::g_tConfig.readcheck.IsWIDEVINE ? p->Siacp_GetWidevine(widevine) : true))
+					{
+						context.append("widevine=" + widevine + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_esn.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsESN ? p->Siacp_SetESN(esn) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsESN ? p->Siacp_CheckESN() : true) &&
+						(Global::g_tConfig.readcheck.IsESN ? p->Siacp_GetESN(esn) : true))
+					{
+						context.append("netfilxesn=" + esn + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_cikey.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsCI ? p->Siacp_SetCikey(cikey) : true))
+				{
+					if ((Global::g_tConfig.writecheck.IsCI ? p->Siacp_CheckCikey() : true) &&
+						(Global::g_tConfig.readcheck.IsCI ? p->Siacp_GetCikey(cikey) : true))
+					{
+						context.append("cikey=" + cikey + "&");
+					}
+					else
+					{
+						result = false;
+						goto end;
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_wb_init.GetCheck())
+			{
+				if (!g_siacp.SCBC_WBInit())
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_wb_write.GetCheck())
+			{
+				if (p->Siacp_SetWB())
+				{
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_channel.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsCHANNEL ? p->Siacp_SetChannel(channel) : true) &&
+					(Global::g_tConfig.readcheck.IsCHANNEL ? p->Siacp_GetChannel(channel) : true))
+				{
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_osd_lang.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsOSD ? p->Siacp_SetOSDLanguage(language) : true) &&
+					(Global::g_tConfig.readcheck.IsOSD ? p->Siacp_GetOSDLanguage(language) : true))
+				{
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			if (p->m_check_shop_lang.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsSHOP ? p->Siacp_SetShopLanguage(language) : true) &&
+					(Global::g_tConfig.readcheck.IsSHOP ? p->Siacp_GetShopLanguage(language) : true))
+				{
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			// 注意:切换pid一般放在最后处理;
+			if (p->m_check_pid.GetCheck())
+			{
+				if ((Global::g_tConfig.writedone.IsPID ? p->Siacp_SetProjectId() : true) && (Global::g_tConfig.readcheck.IsPID ? p->Siacp_GetProjectId() : true))
+				{
+					// 写入的pid再次读取出来校验;
+					if (Global::g_tConfig.mode < 3 /*&& p->m_check_verify_pid.GetCheck()*/)
+					{
+						context.append("projectid=" + std::string(p->m_str_pid.GetString()) + "&");
+					}
+				}
+				else
+				{
+					result = false;
+					goto end;
+				}
+			}
+
+			DWORD dwCount = GetTickCount64() - p->m_dwTickCount;
+			strLog.Format(_T("\rAll key Copy Sucessfull,It took %d milliseconds!\r\r"), dwCount);
+			p->SetOptionLog(strLog, INFO_LOG);
+			p->DeleteKeyFiles();
+
+			// 成功后,上报结果;
+			if (Global::g_tConfig.mode < 3 && p->m_check_did.GetCheck())
+			{
+				if (softe_version.size())
+					context.append("sversionid=" + softe_version + "&");
+				else
+					context.append("sversionid=" + g_midInfo.version + "&");
+
+				if (client_type.size())
+					context.append("clienttype=" + client_type + "&");
+				else
+					context.append("clienttype=" + g_midInfo.clienttype + "&");
+
+				if (Global::g_tConfig.mode < 2)
+				{
+					context.append("ordernum=" + std::string(p->m_str_bid.GetString()) + "&");
+				}
+				if (!p->m_str_sn.IsEmpty())
+				{
+					context.append("sn=" + std::string(p->m_str_sn.GetString()) + "&");
+				}
+
+				std::string xml;
+				if (!g_ota.GetKeyInfo((Global::g_tConfig.mode < 2 ? g_midInfo.host : Global::g_tConfig.serverurl) + "/report.do?", context, "", "", xml))
+				{
+					// 上报失败;
+					p->SetOptionLog(CString(_T("Upload result Failed!\r")), ERROR_LOG);
+				}
+				else
+				{
+					p->SetOptionLog(CString(_T("Upload result Successful!\r")), OK_LOG);
+				}
+			}
+		end:
+			p->m_str_sn.Empty();
+			// 更新余量;
+			p->UpdateKeyCount(FALSE);
+			p->SetLabelResult(result, TRUE);
+#if TEST
+			if (!result)
+				p->KillTimer(1);
+#endif
+			}
+
+	over:
+		p->m_str_sn.Empty();
+		p->GetDlgItem(EDIT_SN)->EnableWindow();
+		p->GetDlgItem(BTN_START)->EnableWindow(TRUE);
+		p->GetDlgItem(IDOK)->EnableWindow(TRUE);
+		p->m_bRunning = FALSE;
+		}, this);
+	t.detach();
+	}
+
+
+HBRUSH CTCLCopyToolDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+	// TODO:  在此更改 DC 的任何特性
+// 	if (nCtlColor == CTLCOLOR_STATIC)
+// 	{
+// 		//pDC->SetBkColor(RGB(239, 228, 176)); //字体背景色 
+// 		pDC->SetBkMode(TRANSPARENT);
+// 		return (HBRUSH)::GetStockObject(NULL_BRUSH);
+// 	}
+	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
+	return hbr;
+}
+
+
+void CTCLCopyToolDlg::OnEnChangeOrder() // 订单;
+{
+	// TODO:  如果该控件是 RICHEDIT 控件,它将不
+	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
+	// 函数并调用 CRichEditCtrl().SetEventMask(),
+	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
+#if 0 // 由lock锁定订单号时,触发获取key信息;
+	if (!m_bGetOrderNum)
+	{
+		m_bGetOrderNum = TRUE;
+		SetLabelResult(-1);
+		RetSetSiacpStatus();
+		InitKeyCountLabel();
+		PostThreadMessage(m_dwThreadId, WM_GET_ORDERNUM, 0, 0);
+	}
+#endif
+	// TODO:  在此添加控件通知处理程序代码
+}
+
+
+void CTCLCopyToolDlg::OnEnChangeSn() // 条码;
+{
+	// TODO:  如果该控件是 RICHEDIT 控件,它将不
+	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
+	// 函数并调用 CRichEditCtrl().SetEventMask(),
+	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
+	if (!m_bGetBarCode && m_str_sn.IsEmpty())
+	{
+		m_bGetBarCode = TRUE;
+		PostThreadMessage(m_dwThreadId, WM_GET_BARCODE, 0, 0);
+	}
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedWbFile()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CString filePath, fileName;
+
+	CFileDialog fileDialog(
+		TRUE,									// 创建打开文件对话框, FALSE是保存文件对话框
+		".wba",									// 默认打开文件类型
+		NULL,									// 默认打开文件名
+		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, // 打开只读文件
+		"WB config file(*.wba)|*.wba");			// 所有可以打开的文件类型
+
+	if (fileDialog.DoModal() == IDOK)
+	{
+		filePath = fileDialog.GetPathName(); // 取出文件路径
+		CString strWBFile = fileDialog.GetFileName();
+		fileName.Format(_T(".//DataDir//%s"), strWBFile);
+
+		if (CopyFile(filePath, fileName, FALSE))
+		{
+			Global::g_tConfig.chassislist.find(Global::g_tConfig.chassis)->second.WBFile = strWBFile.GetString();
+
+			m_chWBNormalBuffer[R] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white R:"), NULL, fileName);
+			m_chWBNormalBuffer[G] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white G:"), NULL, fileName);
+			m_chWBNormalBuffer[B] = GetPrivateProfileInt(_T("WBA value:"), _T("HDMI white B:"), NULL, fileName);
+			m_chWBWarmBuffer[R] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white R:"), NULL, fileName);
+			m_chWBWarmBuffer[G] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white G:"), NULL, fileName);
+			m_chWBWarmBuffer[B] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Warm white B:"), NULL, fileName);
+			m_chWBCoolBuffer[R] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white R:"), NULL, fileName);
+			m_chWBCoolBuffer[G] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white G:"), NULL, fileName);
+			m_chWBCoolBuffer[B] = WB_OFFSET + GetPrivateProfileInt(_T("WBA value:"), _T("Cool white B:"), NULL, fileName);
+
+			GetDlgItem(STATIC_WB_FILE)->SetWindowText(strWBFile);
+		}
+	}
+}
+
+
+void CTCLCopyToolDlg::OnCancel()
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	SaveChange2Config();
+	CDialogEx::OnCancel();
+}
+
+
+void CTCLCopyToolDlg::OnOK()
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	if (GetDlgItem(BTN_START)->IsWindowEnabled() && !m_bGetBarCode) // m_bGetBarCode不使用条码回车功能;
+		PostMessage(WM_COMMAND, MAKEWPARAM(BTN_START, BN_CLICKED), NULL);
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedLock()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	BOOL bCheck = ((CButton*)GetDlgItem(CHECK_LOCK))->GetCheck();
+	GetDlgItem(EDIT_ORDER)->EnableWindow(!bCheck && Global::g_tConfig.mode < 2);
+	m_check_pid.EnableWindow(!bCheck && Global::g_tConfig.mode != 0);
+	GetDlgItem(EDIT_PID)->EnableWindow(!bCheck && Global::g_tConfig.mode != 0);
+	m_check_channel.EnableWindow(!bCheck);
+	m_check_osd_lang.EnableWindow(!bCheck);
+	m_check_shop_lang.EnableWindow(!bCheck);
+
+	m_cb_osd_lang.EnableWindow(!bCheck);
+	m_cb_shop_lang.EnableWindow(!bCheck);
+	m_cb_channel.EnableWindow(!bCheck);
+
+	// auto+manual模式,check;
+	if ( Global::g_tConfig.mode < 2 && bCheck )
+	{
+		if (!m_bGetOrderNum)
+		{
+			m_bGetOrderNum = TRUE;
+			SetLabelResult(-1);
+			RetSetSiacpStatus();
+			InitKeyCountLabel();
+			PostThreadMessage(m_dwThreadId, WM_GET_ORDERNUM, 0, 0);
+		}
+	}
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedFocus()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	m_bAutofocus = ((CButton*)GetDlgItem(CHECK_FOCUS))->GetCheck();
+}
+
+
+void CTCLCopyToolDlg::OnGetKeyCountClicked(UINT id)
+{
+	switch (id)
+	{
+	case CHECK_DID:
+		SetLabelKeyCount(_T("DeviceID"), Global::g_tConfig.mode);
+		break;
+	case CHECK_MAC:
+		SetLabelKeyCount(_T("MAC"), Global::g_tConfig.mode);
+		break;
+	case CHECK_HDCP:
+		SetLabelKeyCount(_T("HDCP_KEY"), Global::g_tConfig.mode);
+		break;
+	case CHECK_HDCP22:
+		SetLabelKeyCount(_T("HDCP2.2_KEY"), Global::g_tConfig.mode);
+		break;
+	case CHECK_WIDI:
+		SetLabelKeyCount(_T("WiDi"), Global::g_tConfig.mode);
+		break;
+	case CHECK_WIDEVINE:
+		SetLabelKeyCount(_T("Widevine_KEY"), Global::g_tConfig.mode);
+		break;
+	case CHECK_ESN:
+		SetLabelKeyCount(_T("NETFILX_ESN"), Global::g_tConfig.mode);
+		break;
+	case CHECK_CIKEY:
+		SetLabelKeyCount(_T("CI_PLUS_KEY"), Global::g_tConfig.mode);
+		break;
+	default:
+		break;
+	}
+}
+
+
+void CTCLCopyToolDlg::OnBnClickedConfig() // 配置Chassis;
+{
+	UpdateData();
+	// 先保存;
+	SaveChange2Config();
+	// 清空状态;
+	SetLabelResult(-1);
+	RetSetSiacpStatus();
+	CChassisConfigDlg dlg;
+	if (dlg.DoModal() == IDOK)
+	{
+		InitCombobox_Chassis();
+		if (Global::g_tConfig.mode > 1)
+		{
+			UpdateKeyCount();
+			//UpdateChassisCheckBoxStatus();
+		}
+	}
+}
+
+
+BOOL CTCLCopyToolDlg::PreTranslateMessage(MSG* pMsg)
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	static BOOL bTopWnd = FALSE;
+	if (pMsg->message == WM_KEYDOWN)
+	{
+		switch (pMsg->wParam)
+		{
+			// F2开启或关闭测试服务器地址;
+		case VK_F2:
+		{
+			Global::g_bTestHost = !Global::g_bTestHost;
+			m_lb_test_mode.ShowWindow(Global::g_bTestHost);
+		}
+		break;
+		// 前置窗口;
+		case VK_F3:
+		{
+			CString strText;
+			GetWindowText(strText);
+
+			if (bTopWnd == FALSE)
+			{
+				SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//窗口置顶
+				strText.Format(_T("%s  Front window (Press F3 to Cancel Or Open)"), strText.GetString());
+			}
+			else
+			{
+				SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//取消窗口置顶	
+				strText.Replace(_T("Front window (Press F3 to Cancel Or Open)"), _T(""));
+			}
+			bTopWnd = !bTopWnd;
+			SetWindowText(strText);
+		}
+		break;
+		case VK_F5:
+		{// 先保存;
+			PostMessage(WM_COMMAND, MAKEWPARAM(BTN_CONFIG, BN_CLICKED), NULL);
+		}
+		break;
+		default:
+			break;
+		}
+	}
+	return CDialogEx::PreTranslateMessage(pMsg);
+}
+
+
+void CTCLCopyToolDlg::OnCbnSelchangeCom()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CString strData;
+	int nCurSel = m_cb_com.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		m_cb_com.GetLBText(nCurSel, strData);
+		Global::g_tConfig.com = strData.GetString();
+
+		nCurSel = m_cb_baudrate.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			m_cb_baudrate.GetLBText(nCurSel, strData);
+			Global::g_tConfig.baudrate = strData.GetString();
+		}
+	}
+
+	// 重新打开串口;
+	g_siacp.OpenComm(Global::g_tConfig.com.c_str(), _ttol(Global::g_tConfig.baudrate.c_str()));
+}
+
+
+void CTCLCopyToolDlg::OnCbnSelchangeBd()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CString strData;
+	int nCurSel = m_cb_com.GetCurSel();
+	if (nCurSel != CB_ERR)
+	{
+		m_cb_com.GetLBText(nCurSel, strData);
+		Global::g_tConfig.com = strData.GetString();
+
+		nCurSel = m_cb_baudrate.GetCurSel();
+		if (nCurSel != CB_ERR)
+		{
+			m_cb_baudrate.GetLBText(nCurSel, strData);
+			Global::g_tConfig.baudrate = strData.GetString();
+		}
+	}
+
+	// 重新打开串口;
+	g_siacp.OpenComm(Global::g_tConfig.com.c_str(), _ttol(Global::g_tConfig.baudrate.c_str()));
+}

+ 344 - 0
TCL Copy Tool/TCL Copy Tool/TCL Copy ToolDlg.h

@@ -0,0 +1,344 @@
+
+// TCL ToolsDlg.h: 头文件
+//
+
+#pragma once
+#include "SubLabel.h"
+#include "BtnST.h"
+#include "CritSection.h"
+
+#define STATUS_DEFAULT_COLOR	RGB(128, 64, 64)
+#define STATUS_WARN_COLOR		RGB(255, 64, 64)
+#define STATUS_ERROR_COLOR		RGB(255, 0, 0)
+#define STATUS_OK_COLOR			RGB(34, 177, 76)
+// 默认文本色;
+#define BLACK_TEXT_COLOR		RGB(0, 0, 0)
+#define DEFAULT_TEXT_COLOR		RGB(0, 0, 0)
+#define NORMAL_TEXT_COLOR		RGB(0, 0, 255)
+#define OK_TEXT_COLOR			RGB(0, 255, 0)
+#define WARN_TEXT_COLOR			RGB(255, 64, 64)
+// 默认背景色;
+#define DEFAULT_BG_COLOR		RGB(155, 194, 230)
+// 对话框颜色 ;
+#define DEFAULT_DLG_COLOR		RGB(239,228,176)
+
+// 消息;
+#define WM_GET_ORDERNUM			(WM_USER + 1)
+#define WM_GET_BARCODE			(WM_USER + 3)
+
+// 白平衡数据定义
+#define WB_OFFSET				0x100		// 冷暖色温偏移量计算
+enum { R = 0, G, B, WB_MAX };				// R/G/B通道定义
+////////////////////////////////////////////////////////////////////////
+//enum LOG_ENUM
+//{
+//	NORMAL_LOG = 0,
+//	ERROR_LOG,
+//	OK_LOG,
+//	INFO_LOG
+//};
+// CTCLCopyToolDlg 对话框
+class CTCLCopyToolDlg : public CDialogEx
+{
+// 构造
+public:
+	CTCLCopyToolDlg(CWnd* pParent = nullptr);	// 标准构造函数
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_TCLCOPYTOOL_DIALOG };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+public:
+	BOOL m_bRunning;
+	CRect m_rcWind;
+	DWORD m_dwTickCount;
+	Global::TChassis* m_pCurChassis;
+	std::vector<std::string> m_vtCOM;
+	void InitCtrl();
+	void InitColumn();
+	void InitCombobox_port();
+	void InitCombobox_baudrate();
+	void InitCombobox_Chassis();
+	void InitKeyCountLabel();
+	void InitWriteStatusLabel();
+	void InitReadStatusLabel();
+	void InitCheckStatusLabel();
+	void RetSetSiacpStatus();
+	BOOL IsPortInserted(LPCTSTR lpPort);
+	void EnableChassisCheckbox();
+	void UpdateKeyCount(BOOL bUseThread = TRUE);
+	void SetLabelKeyCount(std::string count, CLabel *pLabel);
+	void SetLabelKeyCount(std::string key_type, int mode = 0);
+	void UpdateChassisCheckBoxStatus();
+	void SaveChange2Config();
+	void UpdateAutoOnlineMode();
+	void RetSetChassisCheckBox();
+	void SetLabelResult(int nStatus = -1, BOOL bWriteLog = FALSE);
+	void SetSiacpStatus(CLabel& label, BOOL bOK = TRUE);
+	void SetWindowTitle(std::string client_type);
+	std::string GetFileCount(std::string key_type);
+	BOOL ReadKeyFile(std::string dir, std::string& data);
+	BOOL ReadKeyFile(std::string dir, std::string& data, std::string &file);
+	// 串口操作;
+	BOOL Siacp_MTKInit();
+	BOOL Siacp_EnterFactoryMode();
+	BOOL Siacp_GetClientType(std::string &client_type);
+	BOOL Siacp_GetSofteVersion(std::string &soft_version);
+	BOOL Siacp_SetProjectId();
+	BOOL Siacp_GetProjectId();
+	BOOL Siacp_SetWB();
+
+	BOOL Siacp_SetChannel(std::string &channel);
+	BOOL Siacp_GetChannel(std::string channel);
+	
+	BOOL Siacp_SetOSDLanguage(std::string& language);
+	BOOL Siacp_GetOSDLanguage(std::string language);
+	
+	BOOL Siacp_SetShopLanguage(std::string& language);
+	BOOL Siacp_GetShopLanguage(std::string language);
+
+	BOOL Siacp_SetDeviceId(std::string &deviceid);
+	BOOL Siacp_CheckDeviceId();
+	BOOL Siacp_GetDeviceId(std::string deviceid);
+
+	BOOL Siacp_SetMac(std::string &mac);
+	BOOL Siacp_CheckMac();
+	BOOL Siacp_GetMac(std::string mac);
+
+	BOOL Siacp_SetHDCP(std::string& hdcp);
+	BOOL Siacp_CheckHDCP();
+	BOOL Siacp_GetHDCP(std::string hdcp);
+
+	BOOL Siacp_SetHDCP22(std::string& hdcp22);
+	BOOL Siacp_CheckHDCP22();
+	BOOL Siacp_GetHDCP22(std::string hdcp22);
+
+	BOOL Siacp_SetWidi(std::string& widi);
+	BOOL Siacp_CheckWidi();
+	BOOL Siacp_GetWidi(std::string widi);
+
+	BOOL Siacp_SetWidevine(std::string& widevine);
+	BOOL Siacp_CheckWidevine();
+	BOOL Siacp_GetWidevine(std::string widevine);
+
+	BOOL Siacp_SetESN(std::string& esn);
+	BOOL Siacp_CheckESN();
+	BOOL Siacp_GetESN(std::string esn);
+
+	BOOL Siacp_SetCikey(std::string& cikey);
+	BOOL Siacp_CheckCikey();
+	BOOL Siacp_GetCikey(std::string cikey);
+
+	std::vector<std::string> m_vt_key_files;
+	inline void DeleteKeyFiles()
+	{
+		for ( auto file:m_vt_key_files)
+		{
+			DeleteFile(file.c_str());
+		}
+		m_vt_key_files.clear();
+	}
+
+	CHARFORMAT m_cf_normal;
+	CHARFORMAT m_cf_error;
+	CHARFORMAT m_cf_ok;
+	CHARFORMAT m_cf_info;
+	void InitLogCharFormat();
+	inline void SetOptionLog(CString strLogs, LOG_ENUM logtype = NORMAL_LOG)
+	{
+		m_edit_log.SetSel(-1, -1);
+		if ( logtype == NORMAL_LOG )
+			m_edit_log.SetSelectionCharFormat(m_cf_normal);
+		else if ( logtype == ERROR_LOG )
+			m_edit_log.SetSelectionCharFormat(m_cf_error);
+		else if (logtype == OK_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_ok);
+		else if (logtype == INFO_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_info);
+				
+		if (strLogs.GetLength() > 59)
+			strLogs = strLogs.Left(59) + _T("...\r");
+		m_edit_log.ReplaceSel(strLogs);
+		m_edit_log.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
+	}
+
+	inline void SetOptionLog(std::string strLogs, LOG_ENUM logtype = NORMAL_LOG)
+	{
+		m_edit_log.SetSel(-1, -1);
+		if (logtype == NORMAL_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_normal);
+		else if (logtype == ERROR_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_error);
+		else if (logtype == OK_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_ok);
+		else if (logtype == INFO_LOG)
+			m_edit_log.SetSelectionCharFormat(m_cf_info);
+		
+		if (strLogs.size() > 59)
+			strLogs = strLogs.substr(0, 59) + _T("...\r");
+		m_edit_log.ReplaceSel(strLogs.c_str());
+		m_edit_log.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
+	}
+	//////////////////////////////////////////////////////////////////////////
+#if 1
+	BOOL m_bAutofocus;
+	BOOL m_bGetBarCode;
+	BOOL m_bGetOrderNum;
+	HANDLE m_hThread;
+	DWORD m_dwThreadId;
+	static DWORD WINAPI ThreadGetMessage(LPVOID lpParam);
+#endif
+
+	static HHOOK   m_hHook;
+	static LRESULT WINAPI CBTHookProc(long nCode, WPARAM wparam, LPARAM lparam);
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData);
+	DECLARE_MESSAGE_MAP()
+public:
+	CString m_strLastBid;
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	CComboBox m_cb_com;
+	CComboBox m_cb_baudrate;
+	CComboBox m_cb_mode;
+	CComboBox m_cb_chassis;
+	afx_msg void OnBnClickedHide();
+	afx_msg void OnCbnSelchangeMode();
+	// check box控件;
+	CButton m_check_mtk_init;
+	CButton m_check_wb_init;
+	CButton m_check_pid;
+	CButton m_check_channel;
+	CButton m_check_osd_lang;
+	CButton m_check_shop_lang;
+	CButton m_check_did;
+	CButton m_check_mac;
+	CButton m_check_hdcp;
+	CButton m_check_hdcp22;
+	CButton m_check_widi;
+	CButton m_check_widevine;
+	CButton m_check_esn;
+	CButton m_check_cikey;
+	CButton m_check_wb_write;
+	// combobox;
+	CComboBox m_cb_channel;
+	CComboBox m_cb_osd_lang;
+	CComboBox m_cb_shop_lang;
+	// 余量显示控件;
+	CLabel m_lb_did_count;
+	CLabel m_lb_mac_count;
+	CLabel m_lb_hdcp_count;
+	CLabel m_lb_hdcp22_count;
+	CLabel m_lb_widi_count;
+	CLabel m_lb_widevine_count;
+	CLabel m_lb_esn_count;
+	CLabel m_lb_cikey_count;
+	// wb init;
+	CLabel m_lb_wb_init;
+	// 写状态控件;
+	CLabel m_lb_wb_write;
+	CLabel m_lb_pid_write;
+	CLabel m_lb_channel_write;
+	CLabel m_lb_osd_lang_write;
+	CLabel m_lb_shop_lang_write;
+	
+	CLabel m_lb_did_write;
+	CLabel m_lb_mac_write;
+	CLabel m_lb_hdcp_write;
+	CLabel m_lb_hdcp22_write;
+	CLabel m_lb_widi_write;
+	CLabel m_lb_widevine_write;
+	CLabel m_lb_esn_write;
+	CLabel m_lb_cikey_write;
+	// check状态控件;
+	CLabel m_lb_pid_check;
+	CLabel m_lb_channel_check;
+	CLabel m_lb_osd_lang_check;
+	CLabel m_lb_shop_lang_check;
+
+	CLabel m_lb_did_check;
+	CLabel m_lb_mac_check;
+	CLabel m_lb_hdcp_check;
+	CLabel m_lb_hdcp22_check;
+	CLabel m_lb_widi_check;
+	CLabel m_lb_widevine_check;
+	CLabel m_lb_esn_check;
+	CLabel m_lb_cikey_check;
+	// 读状态控件;
+	CLabel m_lb_pid_read;
+	CLabel m_lb_channel_read;
+	CLabel m_lb_osd_lang_read;
+	CLabel m_lb_shop_lang_read;
+
+	CLabel m_lb_did_read;
+	CLabel m_lb_mac_read;
+	CLabel m_lb_hdcp_read;
+	CLabel m_lb_hdcp22_read;
+	CLabel m_lb_widi_read;
+	CLabel m_lb_widevine_read;
+	CLabel m_lb_esn_read;
+	CLabel m_lb_cikey_read;
+	afx_msg void OnCbnSelchangeChassis();
+	CString m_str_pid;		// 控件关联的pid值;
+	afx_msg void OnBnClickedStart();
+	CLabel m_lb_enter_factory_mode;
+	CLabel m_lb_enter_factory_mode_status;
+	// 列标题;
+	CLabel m_lb_column_a1;
+	CLabel m_lb_column_a2;
+	CLabel m_lb_column_a3;
+	CLabel m_lb_column_a4;
+	CLabel m_lb_column_a5;
+	
+	CLabel m_lb_column_b1;
+	CLabel m_lb_column_b2;
+	CLabel m_lb_column_b3;
+	CLabel m_lb_column_b4;
+	CLabel m_lb_column_b5;
+	CLabel m_lb_result;// 结果;
+	// 隐藏界面按钮;
+	CButtonST m_btn_hide;
+	// 条码;
+	CString m_str_sn;
+	// 批次号;
+	CString m_str_bid;
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnEnChangeSn();	
+	// wb内容;
+	byte	m_chWBNormalBuffer[WB_MAX];
+	byte	m_chWBWarmBuffer[WB_MAX];
+	byte	m_chWBCoolBuffer[WB_MAX];
+	afx_msg void OnBnClickedWbFile();
+	virtual void OnCancel();
+	virtual void OnOK();
+	afx_msg void OnBnClickedLock();
+	afx_msg void OnBnClickedFocus();
+	afx_msg void OnEnChangeOrder();
+	afx_msg void OnGetKeyCountClicked(UINT id);
+	CRichEditCtrl m_edit_log;
+	CButton m_check_verify_pid;
+	CButton m_check_verify_client_type;
+	CButton m_check_verify_soft_version;
+	afx_msg void OnBnClickedConfig();
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	afx_msg void OnCbnSelchangeCom();
+	afx_msg void OnCbnSelchangeBd();
+	CButton m_check_set;
+	CButtonST m_btn_cancel;
+	CButtonST m_btn_manual_start;
+	CButton m_check_focus;
+	CButton m_check_lock;
+	CLabel m_lb_test_mode;
+};

BIN
TCL Copy Tool/TCL Copy Tool/TCLCopyTool.rc


+ 34 - 0
TCL Copy Tool/TCL Copy Tool/VerificationCodeDlg.cpp

@@ -0,0 +1,34 @@
+// VerificationCodeDlg.cpp: 实现文件
+//
+
+#include "pch.h"
+#include "TCL Copy Tool.h"
+#include "VerificationCodeDlg.h"
+#include "afxdialogex.h"
+
+
+// CVerificationCodeDlg 对话框
+
+IMPLEMENT_DYNAMIC(CVerificationCodeDlg, CDialogEx)
+
+CVerificationCodeDlg::CVerificationCodeDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_VERIFICATION_CODE_DIALOG, pParent)
+{
+
+}
+
+CVerificationCodeDlg::~CVerificationCodeDlg()
+{
+}
+
+void CVerificationCodeDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CVerificationCodeDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CVerificationCodeDlg 消息处理程序

+ 23 - 0
TCL Copy Tool/TCL Copy Tool/VerificationCodeDlg.h

@@ -0,0 +1,23 @@
+#pragma once
+
+
+// CVerificationCodeDlg 对话框
+
+class CVerificationCodeDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CVerificationCodeDlg)
+
+public:
+	CVerificationCodeDlg(CWnd* pParent = nullptr);   // 标准构造函数
+	virtual ~CVerificationCodeDlg();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_VERIFICATION_CODE_DIALOG };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+};

+ 49 - 0
TCL Copy Tool/TCL Copy Tool/framework.h

@@ -0,0 +1,49 @@
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+// 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+
+#include <afxdisp.h>        // MFC 自动化类
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // MFC 支持功能区和控制条
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+

+ 27 - 0
TCL Copy Tool/TCL Copy Tool/log4c.h

@@ -0,0 +1,27 @@
+/* $Id$
+ *
+ * log4c.h
+ *
+ * Copyright 2001-2002, Meiosys (www.meiosys.com). All rights reserved.
+ *
+ * See the COPYING file for the terms of usage and distribution.
+ */
+
+#ifndef log4c_log4c_h
+#define log4c_log4c_h
+
+#define IMPLEMENT_LOG4C
+
+#include <log4c/version.h>
+#include <log4c/init.h>
+#include <log4c/rc.h>
+#include <log4c/appender.h>
+#include <log4c/rollingpolicy.h>
+#include <log4c/category.h>
+#include <log4c/layout.h>
+#include <log4c/logging_event.h>
+#include <log4c/priority.h>
+#include <log4c/log.h>
+
+#endif
+

+ 8 - 0
TCL Copy Tool/TCL Copy Tool/pch.cpp

@@ -0,0 +1,8 @@
+// pch.cpp: 与预编译标头对应的源文件
+
+#include "pch.h"
+
+// 当使用预编译的头时,需要使用此源文件,编译才能成功。
+COTA g_ota;
+CSIACP g_siacp;
+MIDInfo g_midInfo;

+ 44 - 0
TCL Copy Tool/TCL Copy Tool/pch.h

@@ -0,0 +1,44 @@
+// pch.h: 这是预编译标头文件。
+// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
+// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
+// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
+// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
+
+#ifndef PCH_H
+#define PCH_H
+
+// 添加要在此处预编译的标头
+#include "framework.h"
+
+#include <string>
+#include <vector>
+#include <thread>
+#include <Dbt.h>	// 设备头文件;
+#include <queue>
+#include <map>
+#include "Global.h"
+
+using namespace std;
+
+#include <imm.h>
+#pragma comment(lib,"Imm32.lib")
+
+#include "OTA.h"
+#include <afxcontrolbars.h>
+
+extern COTA g_ota;
+extern CSIACP g_siacp;
+extern MIDInfo g_midInfo;
+
+
+// 某机芯要求处理;
+#define DEL_CLIENT_TYPE_ERROR_LOG 1		// 去除Client type读取失败后,打印红色的出错日志;改为正常颜色日志输出,防止厂线员工有疑问;
+#define ENABLE_CHASSIS_CONFIG 0
+#define ENABLE_VCODE 0
+#define SAVE_AUTO_ONLINE 1
+// 2019.08.12
+#define YAHUI 1
+#define ZHANGYI 0
+#define TEST 0
+
+#endif //PCH_H

BIN
TCL Copy Tool/TCL Copy Tool/res/TCL Copy Tool.ico


BIN
TCL Copy Tool/TCL Copy Tool/res/TCL Copy Tool2.ico


BIN
TCL Copy Tool/TCL Copy Tool/res/TCLCopyTool.rc2


+ 158 - 0
TCL Copy Tool/TCL Copy Tool/resource.h

@@ -0,0 +1,158 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ 生成的包含文件。
+// 供 TCLCopyTool.rc 使用
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDR_MAINFRAME                   128
+#define IDD_TCLCOPYTOOL_DIALOG          130
+#define IDD_CONFIG_DIALOG               131
+#define IDD_DIALOG1                     133
+#define IDD_VERIFICATION_CODE_DIALOG    133
+#define COMBO_COM                       1000
+#define COMBO_BD                        1001
+#define COMBO_CHASSIS                   1002
+#define COMBO_MODE                      1003
+#define CHECK_VERIFY_PID                1004
+#define CHECK_VERIFY_CLIENT_TYPE        1005
+#define EDIT_ORDER                      1006
+#define CHECK_VERIFY_SOFT_VERSION       1007
+#define EDIT_SN                         1008
+#define CHECK_LOCK                      1009
+#define CHECK_FOCUS                     1010
+#define CHECK_MTK_INIT                  1011
+#define CHECK_WB_WRITE                  1012
+#define CHECK_PID                       1013
+#define CHECK_CHANNEL                   1014
+#define CHECK_OSD_LANG                  1015
+#define CHECK_SHOP_LANG                 1016
+#define CHECK_DID                       1017
+#define CHECK_MAC                       1018
+#define CHECK_HDCP                      1019
+#define CHECK_HDCP22                    1020
+#define CHECK_WIDI                      1021
+#define CHECK_WIDEVINE                  1022
+#define CHECK_ESN                       1023
+#define CHECK_CIKEY                     1024
+#define EDIT_PID                        1025
+#define COMBO_OSD_LANG                  1026
+#define COMBO_SHOP_LANG                 1027
+#define COMBO_CHANNEL                   1028
+#define CHECK_WB_INIT                   1029
+#define BTN_WB_FILE                     1030
+#define BTN_START                       1031
+#define BTN_HIDE                        1032
+#define IDC_GROUP_HIDE                  1033
+#define STATIC_DID_COUNT                1034
+#define STATIC_MAC_COUNT                1035
+#define STATIC_HDCP_COUNT               1036
+#define STATIC_HDCP22_COUNT             1037
+#define STATIC_WIDI_COUNT               1038
+#define STATIC_WIDEVINE_COUNT           1039
+#define STATIC_ESN_COUNT                1040
+#define STATIC_CI_COUNT                 1041
+#define STATIC_COLUMN_A1                1042
+#define STATIC_RESULT                   1043
+#define STATIC_COLUMN_A2                1044
+#define STATIC_DID_WRITE                1045
+#define STATIC_MAC_WRITE                1046
+#define STATIC_HDCP_WRITE               1047
+#define STATIC_HDCP22_WRITE             1048
+#define STATIC_WIDI_WRITE               1049
+#define STATIC_WIDEVINE_WRITE           1050
+#define STATIC_ESN_WRITE                1051
+#define STATIC_CI_WRITE                 1052
+#define STATIC_DID_CHECK                1053
+#define STATIC_MAC_CHECK                1054
+#define STATIC_HDCP_CHECK               1055
+#define STATIC_HDCP22_CHECK             1056
+#define STATIC_WIDI_CHECK               1057
+#define STATIC_WIDEVINE_CHECK           1058
+#define STATIC_ESN_CHECK                1059
+#define STATIC_CI_CHECK                 1060
+#define STATIC_DID_READ                 1061
+#define STATIC_MAC_READ                 1062
+#define STATIC_HDCP_READ                1063
+#define STATIC_HDCP22_READ              1064
+#define STATIC_WIDI_READ                1065
+#define STATIC_WIDEVINE_READ            1066
+#define STATIC_ESN_READ                 1067
+#define STATIC_CI_READ                  1068
+#define STATIC_PID_WRITE                1069
+#define STATIC_CHANNEL_WRITE            1070
+#define STATIC_OSD_LANG_WRITE           1071
+#define STATIC_SHOP_LANG_WRITE          1072
+#define STATIC_ENTER_FACTORY_MODE       1073
+#define STATIC_FACTORY_MODE             1074
+#define STATIC_COLUMN_A3                1075
+#define STATIC_COLUMN_A4                1076
+#define STATIC_COLUMN_A5                1077
+#define STATIC_WB_INIT                  1078
+#define STATIC_WB_FILE                  1079
+#define RICHEDIT2_LOG                   1080
+#define STATIC_PID_CHECK                1081
+#define STATIC_CHANNEL_CHECK            1082
+#define STATIC_OSD_LANG_CHECK           1083
+#define STATIC_SHOP_LANG_CHECK          1084
+#define STATIC_PID_READ                 1085
+#define STATIC_CHANNEL_READ             1086
+#define STATIC_OSD_LANG_READ            1087
+#define STATIC_SHOP_LANG_READ           1088
+#define STATIC_WB_WRITE                 1089
+#define STATIC_COLUMN_B1                1090
+#define STATIC_COLUMN_B2                1091
+#define STATIC_COLUMN_B3                1092
+#define STATIC_COLUMN_B4                1093
+#define STATIC_COLUMN_B5                1094
+#define BTN_CONFIG                      1095
+#define EDIT_CHASSIS_NAME               1096
+#define CHECK_LOCK2                     1096
+#define CHECK_SET                       1096
+#define EDIT_URL                        1097
+#define IDC_CHECK_WRITE_PID             1098
+#define IDC_EDIT_PID                    1099
+#define EDIT_DELAY                      1100
+#define EDIT_CHECKSTRING                1101
+#define IDC_CHECK_COPY_DID              1102
+#define IDC_EDIT_DID_TYPE               1103
+#define IDC_CHECK_COPY_MAC              1104
+#define IDC_EDIT_MAC_TYPE               1105
+#define IDC_CHECK_COPY_HDCP             1106
+#define IDC_EDIT_HDCP_TYPE              1107
+#define IDC_CHECK_COPY_ESN              1108
+#define IDC_EDIT_ESN_TYPE               1109
+#define IDC_CHECK_COPY_WIDI             1110
+#define IDC_EDIT_WIDI_TYPE              1111
+#define IDC_CHECK_COPY_WIDEVINE         1112
+#define IDC_EDIT_WIDEVINE_TYPE          1113
+#define IDC_CHECK_MTK_INIT              1114
+#define IDC_CHECK_WB_INIT               1115
+#define IDC_CHECK_COPY_HDCP2            1116
+#define IDC_EDIT_HDCP2_TYPE             1117
+#define IDC_CHECK_COPY_CIKEY            1118
+#define IDC_EDIT_CIKEY_TYPE             1119
+#define IDC_CHECK_COPY_CHANNEL          1120
+#define IDC_EDIT_CHANNEL                1121
+#define IDC_CHECK_COPY_OSDLANG          1122
+#define IDC_EDIT_OSD_LANG               1123
+#define IDC_CHECK_COPY_SHOPLANG         1124
+#define IDC_EDIT_SHOP_LANG              1125
+#define IDC_COMBO_CHASSIS               1126
+#define BTN_ADD_CHASSIS                 1127
+#define IDC_CHECK_COPY_WB               1128
+#define IDC_EDIT1                       1128
+#define IDC_EDIT_WBFILE                 1129
+#define IDC_STATIC_TEST_MODE            1129
+#define EDIT_WARN_COUNT                 1130
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        135
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1130
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 259 - 0
TCL Copy Tool/TCL Copy Tool/stdint.h

@@ -0,0 +1,259 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2013 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. Neither the name of the product nor the names of its contributors may
+//      be used to endorse or promote products derived from this software
+//      without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#if _MSC_VER >= 2000 // [
+#include <stdint.h>
+#else // ] _MSC_VER >= 1600 [
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
+// Check out Issue 9 for the details.
+#ifndef INTMAX_C //   [
+#  define INTMAX_C   INT64_C
+#endif // INTMAX_C    ]
+#ifndef UINTMAX_C //  [
+#  define UINTMAX_C  UINT64_C
+#endif // UINTMAX_C   ]
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+#endif // _MSC_VER >= 1600 ]
+
+#endif // _MSC_STDINT_H_ ]

+ 8 - 0
TCL Copy Tool/TCL Copy Tool/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>

Неке датотеке нису приказане због велике количине промена