BIND 10 trac2117, updated. b2c95709d92f76df94d5faf9cbfeb0524d37d7dc DLL first try

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jul 4 10:14:25 UTC 2012


The branch, trac2117 has been updated
       via  b2c95709d92f76df94d5faf9cbfeb0524d37d7dc (commit)
      from  d5ec81ad8f86f860c2b8e5c9980268da2efdd94e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b2c95709d92f76df94d5faf9cbfeb0524d37d7dc
Author: Francis Dupont <fdupont at isc.org>
Date:   Wed Jul 4 12:14:15 2012 +0200

    DLL first try

-----------------------------------------------------------------------

Summary of changes:
 WIN32-NOTES                                        |  163 ++++
 src/lib/cryptolink/crypto_hmac.cc                  |   11 +
 src/lib/cryptolink/crypto_hmac.h                   |    9 +-
 src/lib/cryptolink/cryptolink.cc                   |   10 +
 src/lib/cryptolink/cryptolink.h                    |   18 +-
 .../resolver/common.h => lib/cryptolink/lib.h}     |   23 +-
 src/lib/exceptions/exceptions.cc                   |    2 +
 src/lib/exceptions/exceptions.h                    |   86 +-
 src/lib/util/buffer.h                              |    8 +-
 src/lib/util/encode/base16_from_binary.h           |    6 +-
 src/lib/util/encode/base32hex.h                    |    4 +
 src/lib/util/encode/base32hex_from_binary.h        |    6 +-
 src/lib/util/encode/base64.h                       |    4 +
 src/lib/util/encode/base_n.cc                      |    4 +
 src/lib/util/encode/binary_from_base16.h           |    6 +-
 src/lib/util/encode/binary_from_base32hex.h        |    6 +-
 src/lib/util/encode/hex.h                          |    4 +
 src/lib/util/filename.cc                           |    2 +
 src/lib/util/filename.h                            |    3 +-
 src/lib/util/hash/sha1.cc                          |    3 +
 src/lib/util/hash/sha1.h                           |   17 +-
 src/lib/util/interprocess_sync.h                   |    8 +-
 src/lib/util/interprocess_sync_file.cc             |   54 +-
 src/lib/util/interprocess_sync_file.h              |   13 +-
 src/lib/util/interprocess_sync_null.cc             |    2 +
 src/lib/util/interprocess_sync_null.h              |    3 +-
 src/lib/util/io/fd.cc                              |   78 ++
 src/lib/util/io/fd.h                               |   26 +-
 src/lib/util/io/fd_share.cc                        |   92 ++-
 src/lib/util/io/fd_share.h                         |   16 +-
 src/lib/util/io/fdshare_python.cc                  |   11 +-
 src/{bin/resolver/common.h => lib/util/io/lib.h}   |   23 +-
 src/lib/util/io/pktinfo_utilities.h                |    4 +
 src/lib/util/io/sockaddr_util.h                    |   17 +-
 src/lib/util/io/socketsession.cc                   |  347 ++++++++
 src/lib/util/io/socketsession.h                    |   54 +-
 src/lib/util/io_utilities.h                        |    2 +
 src/{bin/resolver/common.h => lib/util/lib.h}      |   23 +-
 src/lib/util/locks.h                               |   12 +-
 src/lib/util/lru_list.h                            |    3 +-
 .../{gen_wiredata.py.in => gen_wiredata.py.win32}  |    2 +-
 .../{mkpywrapper.py.in => mkpywrapper.py.win32}    |    2 +-
 src/lib/util/pyunittests/pyunittests_util.py.win32 |    6 +
 src/lib/util/random/qid_gen.cc                     |   15 +
 src/lib/util/random/qid_gen.h                      |    4 +-
 src/lib/util/random/random_number_generator.h      |   12 +-
 src/lib/util/range_utilities.h                     |    2 +
 src/lib/util/strutil.cc                            |    2 +
 src/lib/util/strutil.h                             |    9 +-
 src/lib/util/tests/buffer_unittest.cc              |    4 +-
 src/lib/util/tests/fd_tests.cc                     |    4 +
 src/lib/util/tests/io_utilities_unittest.cc        |    4 +
 src/lib/util/tests/qid_gen_unittest.cc             |    2 +
 .../util/tests/random_number_generator_unittest.cc |    9 +
 src/lib/util/tests/range_utilities_unittest.cc     |    3 +
 src/lib/util/tests/run_unittests.cc                |    7 +
 src/lib/util/tests/socketsession_unittest.cc       |   62 +-
 src/lib/util/time_utilities.cc                     |   21 +
 src/lib/util/time_utilities.h                      |   14 +-
 src/lib/util/unittests/fork.cc                     |  172 ++++
 src/lib/util/unittests/fork.h                      |   12 +-
 .../resolver/common.h => lib/util/unittests/lib.h} |   23 +-
 src/lib/util/unittests/mock_socketsession.h        |   20 +-
 src/lib/util/unittests/newhook.cc                  |    2 +
 src/lib/util/unittests/newhook.h                   |    6 +-
 src/lib/util/unittests/resolver.h                  |    5 +-
 src/lib/util/unittests/resource.cc                 |    8 +
 src/lib/util/unittests/resource.h                  |    4 +-
 src/lib/util/unittests/run_all.cc                  |    2 +
 src/lib/util/unittests/run_all.h                   |    4 +-
 src/lib/util/unittests/testdata.cc                 |    2 +
 src/lib/util/unittests/testdata.h                  |    5 +-
 src/lib/util/unittests/textdata.h                  |   10 +-
 win32build/BINDInstall/BINDInstall.cpp             |   11 +
 win32build/BINDInstall/stdafx.cpp                  |    8 +
 win32build/BINDInstall/stdafx.h                    |   15 +
 win32build/BINDInstall/targetver.h                 |    8 +
 win32build/VS2012/bind10-2010.sln                  |  845 ++++++++++++++++++++
 win32build/config.h                                |   72 ++
 win32build/dllmain.cc                              |   18 +
 win32build/getopt.cc                               |   79 ++
 win32build/getopt.h                                |    4 +
 win32build/getopt_long.cc                          |  523 ++++++++++++
 win32build/getopt_long.h                           |  104 +++
 win32build/strptime.cc                             |  181 +++++
 win32build/strptime.h                              |   31 +
 86 files changed, 3406 insertions(+), 135 deletions(-)
 create mode 100644 WIN32-NOTES
 copy src/{bin/resolver/common.h => lib/cryptolink/lib.h} (68%)
 copy src/{bin/resolver/common.h => lib/util/io/lib.h} (70%)
 copy src/{bin/resolver/common.h => lib/util/lib.h} (71%)
 copy src/lib/util/python/{gen_wiredata.py.in => gen_wiredata.py.win32} (99%)
 copy src/lib/util/python/{mkpywrapper.py.in => mkpywrapper.py.win32} (99%)
 create mode 100644 src/lib/util/pyunittests/pyunittests_util.py.win32
 copy src/{bin/resolver/common.h => lib/util/unittests/lib.h} (67%)
 create mode 100644 win32build/BINDInstall/BINDInstall.cpp
 create mode 100644 win32build/BINDInstall/stdafx.cpp
 create mode 100644 win32build/BINDInstall/stdafx.h
 create mode 100644 win32build/BINDInstall/targetver.h
 create mode 100755 win32build/VS2012/bind10-2010.sln
 create mode 100644 win32build/config.h
 create mode 100644 win32build/dllmain.cc
 create mode 100644 win32build/getopt.cc
 create mode 100644 win32build/getopt.h
 create mode 100644 win32build/getopt_long.cc
 create mode 100644 win32build/getopt_long.h
 create mode 100644 win32build/strptime.cc
 create mode 100644 win32build/strptime.h

-----------------------------------------------------------------------
diff --git a/WIN32-NOTES b/WIN32-NOTES
new file mode 100644
index 0000000..dc2db24
--- /dev/null
+++ b/WIN32-NOTES
@@ -0,0 +1,163 @@
+What is needed:
+
+ - full IPv6 support (so at least Vista or Server 2008,
+  tested on Server 2008 x86 and Windows 7 x86_64)
+
+ - POSIX (aka Unix) environment for tar/git/etc (I use cygwin)
+
+ - Visual Studio C++ (versions 2008 and 2010 were tested,
+  (note older versions could fail to correctly compile,
+  cf. C4373 warning), 2010 express and 64 bit support
+  from the 7.1 SDK work too)
+
+ - python >= 3.1 (I got Cpython 3.2 MSI from python.org,
+  note the pre-built python can give C++ runtime issue with
+  an incompatible Visual Studio, and botan wants a version 2
+  for configuration. Current python has no socket.inet_ntop /
+  socket.inet_pton or _d.lib, so I recommend to recompile it)
+
+ - perl (the Windows native one)
+
+ - sqlite3 >= 3.3.9 (got the 3.7.6 prebuilds but the distrib
+  is needed to get/build the .h and .lib file) (note for the second
+  'lib /def:C:\path\to\sqlite3.def /out:C:\path\to\sqlite3.lib /machine:x86')
+
+ - splite3 python DSO (included in the Python MSI)
+
+ - cmakefile (got the 2.8.4 .exe, can be used but see below)
+
+ - google test (aka gtest, got the 1.[56].0 sources but some recent
+  tests require >= 1.6.0)
+
+ - boost >= 1.35 (got the 1.44/1.47 setup from Boostpro, installed
+  Multithread and Multithread Debug)
+
+ - setproctitle python module (in theory)
+
+ - botan 1.8.x (compiled from sources to control things, i.e.,
+  tried to factorize the (in)convenience with gtest. Note its
+  config phase requires a python2. Tested with a 1.10.x too)
+
+ - log4cplus (compiled from sources in the same style...
+  Note WIN32 disables syslog support. In VS2010 solution/project
+  files are required, the subversion URL is
+  https://log4cplus.svn.sourceforge.net/svnroot/log4cplus
+  and the PRODUCTION_1_0_x branch includes a msvc10 directory)
+
+Environment variables (with examples):
+
+ - BOOST -> C:\Program Files\boost\boost_1_44
+
+ - BIND10HOME -> c:/cygwin/home/dupont/bind10
+
+How to compile google test:
+
+ - remove the /MD -> /MT line in the CMakeLists.txt, use cmake
+
+ - *or* open the solution gtest-md in msvc (please note the rights
+  of files in this directory must be fixed before)
+
+ - please remember the same Visual Studio version must be used
+  for gtest and bind10
+
+ - msvc gives the gtestd.lib (in place of gtest.lib) for the debug version
+
+How to recompile python:
+
+ - solution file is in PCbuild/pcbuild.sln
+
+ - patch socketmodule.h with (can replace WIN7 by WS08, etc):
+
+#else /* MS_WINDOWS */
+# define NTDDI_VERSION NTDDI_WIN7
+# define WINVER _WIN32_WINNT_WIN7
+# define _WIN32_WINNT _WIN32_WINNT_WIN7
+# include <ws2tcpip.h>
+/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
+ * Separate SDKs have all the functions we want, but older ones don't have
+ * any version information.
+ * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
+ */
+# ifdef SIO_GET_MULTICAST_FILTER
+#  include <MSTcpIP.h> /* for SIO_RCVALL */
+#  define HAVE_ADDRINFO
+#  define HAVE_SOCKADDR_STORAGE
+#  define HAVE_GETADDRINFO
+#  define HAVE_GETNAMEINFO
+#  define HAVE_INET_NTOP
+#  define HAVE_INET_PTON
+#  define ENABLE_IPV6
+# else
+
+Where I put things (hardwired paths):
+
+ - <home>\bind10 for bind10 (BIND10HOME environment variable)
+
+ - <home>\gtest\include
+
+ - <home>\gtest\md10\{Debug,Release} gtest{d,}.lib and vc100.[ip]db, or,
+   <home>\gtest\md9\{Debug,Release} gtest{d,}.lib and vc90.[ip]db
+
+ - <home>\botan\include and <home>\botan\md{9,10}\{Debug,Release}
+   (--disable-shared to get static libs, no DLL)
+
+ - <home>\log4cplus\include and <home>\log4cplus\md{9,10}\{Debug,Release}
+
+ - "C:\Program Files\boost\boost_1_44" (the include and
+  sometimes the libraries (in lib, called by the auto_link) too,
+  BOOST environment variable)
+
+ - C:\Python32 (update your PATH, same for perl)
+
+ - C:\sqlite3 (don't forget to copy the DLL in a place in the PATH,
+  on Window7 I can't get the permissions right but it works by putting
+  the DLL directory in the PATH)
+
+How to compile:
+
+ - open win32build\VS2010\bind10.sln file with Visual Studio 2010, or,
+   open win32build\VS2008\bind10.sln file with Visual Studio 2008
+
+ - fix the paths (\ becomes \\\ in grep/ed/etc)
+
+ - build
+
+ - partial or todo directory ports are marked
+
+Random notes (for porting new code):
+ - getopt() is *not* standard (got working getopt.{h,cc})
+ - inet_pton() requires >= Vista/2008
+ - forget lcov/pycoverage
+ - cmake?
+
+ - ifdefs: _WIN32 and _MSC_VER
+ - for(int i; ... -very-often-> for(unsigned int i; ...
+ - *no* <unistd.h> (or network includes)
+ - <sys/time.h> -> <time.h>
+ - missing general defines -> include <config.h> in front
+ - missing less general defines -> conditionally include <winsock2.h>
+ - missing TCP/IP defines -> conditionally include <ws2tcpip.h>
+  and perhaps <mswsock> too *before* asio
+ - integer posix types -> include <stdint.h> (or <cstdint>)
+ - "this" used too soon -> move to body
+ - "=" with contants: standard private C4512 declaration
+ - reuse_address is different in Windows
+ - missing namespace:
+  * error_code -> asio::error_code (both type and function)
+  * shared_ptr -> boost::shared_ptr
+ - *no* PF_UNIX (aka asio::local) sockets
+ - *no* fork() (but can use threads)
+ - unused variable in catch: simply remove it
+ - sleep() or nanosleep() -> Sleep()
+ - gettimeofday() -> GetSystemTimeAsFileTime() - SystemTimeToFileTime(epoch)
+ - underscored function names: _getid, _read, _write (caution: convert
+  the handle before), 
+ - defined misc names: min, max, IN, ERROR, NOERROR
+ - different names: close -> closesocket (and error is INVALID_SOCKET
+  not < 0), errno -> WSAGetLastError()
+ - different declarations: send, recv, 
+ - WSAStartup/WSACleanup in main()
+
+Test status: (unittests failures)
+ b10-dhcp6: can't work as Windows has no loopback interface...
+
diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc
index c1bbfa8..b8f58cb 100644
--- a/src/lib/cryptolink/crypto_hmac.cc
+++ b/src/lib/cryptolink/crypto_hmac.cc
@@ -12,6 +12,13 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBCRYPTOLINK_EXPORT
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4290 4512)
+#endif
+
 #include <cryptolink.h>
 #include <cryptolink/crypto_hmac.h>
 
@@ -281,3 +288,7 @@ deleteHMAC(HMAC* hmac) {
 
 } // namespace cryptolink
 } // namespace isc
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/src/lib/cryptolink/crypto_hmac.h b/src/lib/cryptolink/crypto_hmac.h
index 2eb0d0e..48b4c93 100644
--- a/src/lib/cryptolink/crypto_hmac.h
+++ b/src/lib/cryptolink/crypto_hmac.h
@@ -16,6 +16,7 @@
 
 #include <boost/noncopyable.hpp>
 
+#include <cryptolink/lib.h>
 #include <cryptolink/cryptolink.h>
 
 #ifndef _ISC_CRYPTO_HMAC_H
@@ -25,14 +26,14 @@ namespace isc {
 namespace cryptolink {
 
 /// Forward declaration, pimpl style
-class HMACImpl;
+class ISC_LIBCRYPTOLINK_API HMACImpl;
 
 /// \brief HMAC support
 ///
 /// This class is used to create and verify HMAC signatures. Instances
 /// can be created with CryptoLink::createHMAC()
 ///
-class HMAC : private boost::noncopyable {
+class ISC_LIBCRYPTOLINK_API HMAC : private boost::noncopyable {
 private:
     /// \brief Constructor from a secret and a hash algorithm
     ///
@@ -157,6 +158,7 @@ private:
 /// \param result The signature will be appended to this buffer
 /// \param len If this is non-zero and less than the output size,
 ///            the result will be truncated to len bytes
+ISC_LIBCRYPTOLINK_API
 void signHMAC(const void* data,
               const size_t data_len,
               const void* secret,
@@ -191,6 +193,7 @@ void signHMAC(const void* data,
 /// \param sig The signature to verify
 /// \param sig_len The length of the signature
 /// \return True if the signature verifies, false if not
+ISC_LIBCRYPTOLINK_API
 bool verifyHMAC(const void* data,
                 const size_t data_len,
                 const void* secret,
@@ -200,7 +203,7 @@ bool verifyHMAC(const void* data,
                 const size_t sig_len);
 
 /// \brief Delete an HMAC object
-void deleteHMAC(HMAC* hmac);
+ISC_LIBCRYPTOLINK_API void deleteHMAC(HMAC* hmac);
 
 } // namespace cryptolink
 } // namespace isc
diff --git a/src/lib/cryptolink/cryptolink.cc b/src/lib/cryptolink/cryptolink.cc
index d1c375d..51771d5 100644
--- a/src/lib/cryptolink/cryptolink.cc
+++ b/src/lib/cryptolink/cryptolink.cc
@@ -12,6 +12,13 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBCRYPTOLINK_EXPORT
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4290 4512)
+#endif
+
 #include <cryptolink/cryptolink.h>
 #include <cryptolink/crypto_hmac.h>
 
@@ -67,3 +74,6 @@ CryptoLink::createHMAC(const void* secret, size_t secret_len,
 } // namespace cryptolink
 } // namespace isc
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/src/lib/cryptolink/cryptolink.h b/src/lib/cryptolink/cryptolink.h
index d0f7d38..c0899ff 100644
--- a/src/lib/cryptolink/cryptolink.h
+++ b/src/lib/cryptolink/cryptolink.h
@@ -24,6 +24,8 @@
 
 #include <memory>
 
+#include <cryptolink/lib.h>
+
 namespace isc {
 namespace cryptolink {
 
@@ -45,11 +47,11 @@ enum HashAlgorithm {
 };
 
 // Forward declaration for createHMAC()
-class HMAC;
+class ISC_LIBCRYPTOLINK_API HMAC;
 
 /// General exception class that is the base for all crypto-related
 /// exceptions
-class CryptoLinkError : public Exception {
+class ISC_LIBCRYPTOLINK_API CryptoLinkError : public Exception {
 public:
     CryptoLinkError(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -57,7 +59,7 @@ public:
 
 /// This exception is thrown if there was a problem initializing the
 /// crypto library
-class InitializationError : public CryptoLinkError {
+class ISC_LIBCRYPTOLINK_API InitializationError : public CryptoLinkError {
 public:
     InitializationError(const char* file, size_t line, const char* what) :
         CryptoLinkError(file, line, what) {}
@@ -65,7 +67,7 @@ public:
 
 /// This exception is thrown when a cryptographic action is requested
 /// for an algorithm that is not supported by the underlying library.
-class UnsupportedAlgorithm : public CryptoLinkError {
+class ISC_LIBCRYPTOLINK_API UnsupportedAlgorithm : public CryptoLinkError {
 public:
     UnsupportedAlgorithm(const char* file, size_t line, const char* what) :
         CryptoLinkError(file, line, what) {}
@@ -73,7 +75,7 @@ public:
 
 /// This exception is thrown when the underlying library could not
 /// handle the key data.
-class BadKey : public CryptoLinkError {
+class ISC_LIBCRYPTOLINK_API BadKey : public CryptoLinkError {
 public:
     BadKey(const char* file, size_t line, const char* what) :
         CryptoLinkError(file, line, what) {}
@@ -83,14 +85,14 @@ public:
 /// specifically caught is thrown by the underlying library. It
 /// is replaced by this one so as not have 'external' exceptions
 /// bubbling up
-class LibraryError : public CryptoLinkError {
+class ISC_LIBCRYPTOLINK_API LibraryError : public CryptoLinkError {
 public:
     LibraryError(const char* file, size_t line, const char* what) :
         CryptoLinkError(file, line, what) {}
 };
 
 /// Forward declaration for pimpl
-class CryptoLinkImpl;
+class ISC_LIBCRYPTOLINK_API CryptoLinkImpl;
 
 /// \brief Singleton entry point and factory class
 ///
@@ -130,7 +132,7 @@ class CryptoLinkImpl;
 ///
 // Internal note: we can use this class later to initialize and manage
 // dynamic (PKCS#11) libs
-class CryptoLink : private boost::noncopyable {
+class ISC_LIBCRYPTOLINK_API CryptoLink : private boost::noncopyable {
 public:
     /// \brief Returns a reference to the singleton instance
     ///
diff --git a/src/lib/cryptolink/lib.h b/src/lib/cryptolink/lib.h
new file mode 100644
index 0000000..5a9561a
--- /dev/null
+++ b/src/lib/cryptolink/lib.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LIBCRYPTOLINK_H
+#define __LIBCRYPTOLINK_H 1
+
+#if !defined(_WIN32) || defined(USE_STATIC_LINK)
+#define ISC_LIBCRYPTOLINK_API
+#else
+#ifdef ISC_LIBCRYPTOLINK_EXPORT
+#define ISC_LIBCRYPTOLINK_API __declspec(dllexport)
+#else
+#defineISC_LIBCRYPTOLINK_API __declspec(dllimport)
+#endif
+#endif
+
+#endif // __LIBCRYPTOLINK_H
+
+// Local Variables: 
+// mode: c++
+// End: 
diff --git a/src/lib/exceptions/exceptions.cc b/src/lib/exceptions/exceptions.cc
index 2a374da..df3e269 100644
--- a/src/lib/exceptions/exceptions.cc
+++ b/src/lib/exceptions/exceptions.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_EXCEPTIONS_EXPORT
+
 #include <string>
 
 #include <exceptions/exceptions.h>
diff --git a/src/lib/exceptions/exceptions.h b/src/lib/exceptions/exceptions.h
index 010fd39..44c42da 100644
--- a/src/lib/exceptions/exceptions.h
+++ b/src/lib/exceptions/exceptions.h
@@ -19,6 +19,16 @@
 #include <string>
 #include <sstream>
 
+#if !defined(_WIN32) || defined(USE_STATIC_LINK)
+#define ISC_EXCEPTIONS_API
+#else
+#ifdef ISC_EXCEPTIONS_EXPORT
+#define ISC_EXCEPTIONS_API __declspec(dllexport)
+#else
+#defineISC_EXCEPTIONS_API __declspec(dllimport)
+#endif
+#endif
+
 namespace isc {
 
 ///
@@ -28,7 +38,7 @@ namespace isc {
 /// exception such as the file name and line number where the exception is
 /// triggered.
 ///
-class Exception : public std::exception {
+class ISC_EXCEPTIONS_API Exception : public std::exception {
 public:
     ///
     /// \name Constructors and Destructor
@@ -103,7 +113,7 @@ private:
 
 /// \brief A generic exception that is thrown if a parameter given
 /// to a method would refer to or modify out-of-range data.
-class OutOfRange : public Exception {
+class ISC_EXCEPTIONS_API OutOfRange : public Exception {
 public:
     OutOfRange(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -112,7 +122,7 @@ public:
 /// \brief A generic exception that is thrown if a parameter given
 /// to a method or function is considered invalid and no other specific
 /// exceptions are suitable to describe the error.
-class InvalidParameter : public Exception {
+class ISC_EXCEPTIONS_API InvalidParameter : public Exception {
 public:
     InvalidParameter(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -120,7 +130,7 @@ public:
 
 /// \brief A generic exception that is thrown if a parameter given
 /// to a method is considered invalid in that context.
-class BadValue : public Exception {
+class ISC_EXCEPTIONS_API BadValue : public Exception {
 public:
     BadValue(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -131,7 +141,7 @@ public:
 ///
 /// For example, this can happen if a class method is called when the object's
 /// state does not allow that particular method.
-class InvalidOperation : public Exception {
+class ISC_EXCEPTIONS_API InvalidOperation : public Exception {
 public:
     InvalidOperation(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -141,7 +151,7 @@ public:
 /// \brief A generic exception that is thrown when an unexpected
 /// error condition occurs.
 ///
-class Unexpected : public Exception {
+class ISC_EXCEPTIONS_API Unexpected : public Exception {
 public:
     Unexpected(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -153,7 +163,7 @@ public:
 ///
 /// This may be due to unfinished implementation or in case the
 /// function isn't even planned to be provided for that situation.
-class NotImplemented : public Exception {
+class ISC_EXCEPTIONS_API NotImplemented : public Exception {
 public:
     NotImplemented(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -180,36 +190,84 @@ public:
 /// this is defined as a macro.  The convenience for the ostream is a secondary
 /// purpose (if that were the only possible reason we should rather avoid
 /// using a macro).
+#ifdef _MSC_VER
+#define isc_throw(type, stream) \
+    __pragma(warning(push)) \
+    __pragma(warning(disable: 4127)) \
+    do { \
+        std::ostringstream oss__; \
+        oss__ << stream; \
+        throw type(__FILE__, __LINE__, oss__.str().c_str()); \
+    } while (1) \
+    __pragma(warning(pop))
+#else
 #define isc_throw(type, stream) \
     do { \
         std::ostringstream oss__; \
         oss__ << stream; \
         throw type(__FILE__, __LINE__, oss__.str().c_str()); \
     } while (1)
+#endif
 
 ///
 /// Similar as isc_throw, but allows the exception to have one additional
 /// parameter (the stream/text goes first)
+#ifdef _MSC_VER
+#define isc_throw_1(type, stream, param1) \
+    __pragma(warning(push)) \
+    __pragma(warning(disable: 4127)) \
+    do { \
+        std::ostringstream oss__; \
+        oss__ << stream; \
+        throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \
+    } while (1) \
+    __pragma(warning(pop))
+#else
 #define isc_throw_1(type, stream, param1) \
     do { \
         std::ostringstream oss__; \
         oss__ << stream; \
         throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \
     } while (1)
+#endif
 
 ///
 /// Similar as isc_throw, but allows the exception to have two additional
 /// parameters (the stream/text goes first)
+#ifdef _MSC_VER
+#define isc_throw_2(type, stream, param1, param2) \
+    __pragma(warning(push)) \
+    __pragma(warning(disable: 4127)) \
+    do { \
+        std::ostringstream oss__; \
+        oss__ << stream; \
+        throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2); \
+    } while (1) \
+    __pragma(warning(pop))
+#else
 #define isc_throw_2(type, stream, param1, param2) \
     do { \
         std::ostringstream oss__; \
         oss__ << stream; \
         throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2); \
     } while (1)
+#endif
 
 ///
 /// Similar as isc_throw, but allows the exception to have three additional
 /// parameters (the stream/text goes first)
+#ifdef _MSC_VER
+#define isc_throw_3(type, stream, param1, param2, param3) \
+    __pragma(warning(push)) \
+    __pragma(warning(disable: 4127)) \
+    do { \
+        std::ostringstream oss__; \
+        oss__ << stream; \
+        throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\
+                   param3); \
+    } while (1) \
+    __pragma(warning(pop))
+#else
 #define isc_throw_3(type, stream, param1, param2, param3) \
     do { \
         std::ostringstream oss__; \
@@ -217,10 +275,23 @@ public:
         throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\
                    param3); \
     } while (1)
+#endif
 
 ///
 /// Similar as isc_throw, but allows the exception to have four additional
 /// parameters (the stream/text goes first)
+#ifdef _MSC_VER
+#define isc_throw_4(type, stream, param1, param2, param3, param4) \
+    __pragma(warning(push)) \
+    __pragma(warning(disable: 4127)) \
+    do { \
+        std::ostringstream oss__; \
+        oss__ << stream; \
+        throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\
+                   param3, param4); \
+    } while (1) \
+    __pragma(warning(pop))
+#else
 #define isc_throw_4(type, stream, param1, param2, param3, param4) \
     do { \
         std::ostringstream oss__; \
@@ -228,6 +299,7 @@ public:
         throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2,\
                    param3, param4); \
     } while (1)
+#endif
 
 }
 #endif // __EXCEPTIONS_H
diff --git a/src/lib/util/buffer.h b/src/lib/util/buffer.h
index 7e88108..4138016 100644
--- a/src/lib/util/buffer.h
+++ b/src/lib/util/buffer.h
@@ -25,6 +25,8 @@
 
 #include <boost/shared_ptr.hpp>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 
@@ -32,7 +34,7 @@ namespace util {
 /// \brief A standard DNS module exception that is thrown if an out-of-range
 /// buffer operation is being performed.
 ///
-class InvalidBufferPosition : public Exception {
+class ISC_LIBUTIL_API InvalidBufferPosition : public Exception {
 public:
     InvalidBufferPosition(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -86,7 +88,7 @@ public:
 /// head of the unread data.  An object of this class internally holds (a
 /// notion of) where the next read operation should start.  We call it the
 /// <em>read position</em> in this document.
-class InputBuffer {
+class ISC_LIBUTIL_API InputBuffer {
 public:
     ///
     /// \name Constructors and Destructor
@@ -299,7 +301,7 @@ protected:
 /// if we really want that flexibility.  We may revisit the class design as
 /// we see more applications of the class.  The same considerations apply to
 /// the \c InputBuffer and \c MessageRenderer classes.
-class OutputBuffer {
+class ISC_LIBUTIL_API OutputBuffer {
 public:
     ///
     /// \name Constructors and Destructor
diff --git a/src/lib/util/encode/base16_from_binary.h b/src/lib/util/encode/base16_from_binary.h
index 8606c61..0e56be0 100644
--- a/src/lib/util/encode/base16_from_binary.h
+++ b/src/lib/util/encode/base16_from_binary.h
@@ -29,6 +29,8 @@ namespace std{
 // See base32hex_from_binary.h for why we need base64_from...hpp here.
 #include <boost/archive/iterators/base64_from_binary.hpp>
 
+#include <util/lib.h>
+
 namespace boost { 
 namespace archive {
 namespace iterators {
@@ -39,7 +41,7 @@ namespace iterators {
 namespace detail {
 
 template<class CharType>
-struct from_4_bit {
+struct ISC_LIBUTIL_API from_4_bit {
     typedef CharType result_type;
     CharType operator()(CharType t) const{
         const char * lookup_table = 
@@ -70,7 +72,7 @@ template<
     class Base, 
     class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
 >
-class base16_from_binary : 
+class ISC_LIBUTIL_API base16_from_binary : 
     public transform_iterator<
         detail::from_4_bit<CharType>,
         Base
diff --git a/src/lib/util/encode/base32hex.h b/src/lib/util/encode/base32hex.h
index d7129d7..f1c7307 100644
--- a/src/lib/util/encode/base32hex.h
+++ b/src/lib/util/encode/base32hex.h
@@ -19,6 +19,8 @@
 #include <string>
 #include <vector>
 
+#include <util/lib.h>
+
 //
 // Note: this helper module isn't specific to the DNS protocol per se.
 // We should probably move this to somewhere else, possibly in some common
@@ -39,6 +41,7 @@ namespace encode {
 /// \param binary A vector object storing the data to be encoded. 
 /// \return A newly created string that stores base32hex encoded value for
 /// binary.
+ISC_LIBUTIL_API
 std::string encodeBase32Hex(const std::vector<uint8_t>& binary);
 
 /// \brief Decode a text encoded in the base32hex format into the
@@ -51,6 +54,7 @@ std::string encodeBase32Hex(const std::vector<uint8_t>& binary);
 ///
 /// \param input A text encoded in the base32hex format.
 /// \param result A vector in which the decoded %data is to be stored.
+ISC_LIBUTIL_API
 void decodeBase32Hex(const std::string& input, std::vector<uint8_t>& result);
 
 } // namespace encode 
diff --git a/src/lib/util/encode/base32hex_from_binary.h b/src/lib/util/encode/base32hex_from_binary.h
index 5d16d04..2aabc38 100644
--- a/src/lib/util/encode/base32hex_from_binary.h
+++ b/src/lib/util/encode/base32hex_from_binary.h
@@ -31,6 +31,8 @@ namespace std{
 // simply include the base64 header here.
 #include <boost/archive/iterators/base64_from_binary.hpp>
 
+#include <util/lib.h>
+
 namespace boost { 
 namespace archive {
 namespace iterators {
@@ -41,7 +43,7 @@ namespace iterators {
 namespace detail {
 
 template<class CharType>
-struct from_5_bit {
+struct ISC_LIBUTIL_API from_5_bit {
     typedef CharType result_type;
     CharType operator()(CharType t) const{
         const char * lookup_table = 
@@ -72,7 +74,7 @@ template<
     class Base, 
     class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
 >
-class base32hex_from_binary : 
+class ISC_LIBUTIL_API base32hex_from_binary : 
     public transform_iterator<
         detail::from_5_bit<CharType>,
         Base
diff --git a/src/lib/util/encode/base64.h b/src/lib/util/encode/base64.h
index 6b1b346..11c6523 100644
--- a/src/lib/util/encode/base64.h
+++ b/src/lib/util/encode/base64.h
@@ -19,6 +19,8 @@
 #include <string>
 #include <vector>
 
+#include <util/lib.h>
+
 //
 // Note: this helper module isn't specific to the DNS protocol per se.
 // We should probably move this to somewhere else, possibly in some common
@@ -42,6 +44,7 @@ namespace encode {
 ///
 /// \param binary A vector object storing the data to be encoded. 
 /// \return A newly created string that stores base64 encoded value for binary.
+ISC_LIBUTIL_API
 std::string encodeBase64(const std::vector<uint8_t>& binary);
 
 /// \brief Decode a text encoded in the base64 format into the original %data.
@@ -66,6 +69,7 @@ std::string encodeBase64(const std::vector<uint8_t>& binary);
 ///
 /// \param input A text encoded in the base64 format.
 /// \param result A vector in which the decoded %data is to be stored.
+ISC_LIBUTIL_API
 void decodeBase64(const std::string& input, std::vector<uint8_t>& result);
 
 } // namespace encode
diff --git a/src/lib/util/encode/base_n.cc b/src/lib/util/encode/base_n.cc
index 0026a0b..180dcec 100644
--- a/src/lib/util/encode/base_n.cc
+++ b/src/lib/util/encode/base_n.cc
@@ -12,6 +12,10 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
+#include <config.h>
+
 #include <stdint.h>
 #include <cassert>
 #include <iterator>
diff --git a/src/lib/util/encode/binary_from_base16.h b/src/lib/util/encode/binary_from_base16.h
index 50342f1..588b235 100644
--- a/src/lib/util/encode/binary_from_base16.h
+++ b/src/lib/util/encode/binary_from_base16.h
@@ -23,6 +23,8 @@
 
 #include <exceptions/exceptions.h>
 
+#include <util/lib.h>
+
 namespace boost { 
 namespace archive {
 namespace iterators {
@@ -33,7 +35,7 @@ namespace iterators {
 namespace detail {
 
 template<class CharType>
-struct to_4_bit {
+struct ISC_LIBUTIL_API to_4_bit {
     typedef CharType result_type;
     CharType operator()(CharType t) const{
         const char lookup_table[] = {
@@ -79,7 +81,7 @@ template<
     class Base, 
     class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
 >
-class binary_from_base16 : public
+class ISC_LIBUTIL_API binary_from_base16 : public
     transform_iterator<
         detail::to_4_bit<CharType>,
         Base
diff --git a/src/lib/util/encode/binary_from_base32hex.h b/src/lib/util/encode/binary_from_base32hex.h
index 1d83f54..aab39ce 100644
--- a/src/lib/util/encode/binary_from_base32hex.h
+++ b/src/lib/util/encode/binary_from_base32hex.h
@@ -25,6 +25,8 @@
 
 #include <exceptions/exceptions.h>
 
+#include <util/lib.h>
+
 namespace boost { 
 namespace archive {
 namespace iterators {
@@ -35,7 +37,7 @@ namespace iterators {
 namespace detail {
 
 template<class CharType>
-struct to_5_bit {
+struct ISC_LIBUTIL_API to_5_bit {
     typedef CharType result_type;
     CharType operator()(CharType t) const{
         const char lookup_table[] = {
@@ -82,7 +84,7 @@ template<
     class Base, 
     class CharType = BOOST_DEDUCED_TYPENAME boost::iterator_value<Base>::type
 >
-class binary_from_base32hex : public
+class ISC_LIBUTIL_API binary_from_base32hex : public
     transform_iterator<
         detail::to_5_bit<CharType>,
         Base
diff --git a/src/lib/util/encode/hex.h b/src/lib/util/encode/hex.h
index 5c806fc..f8b2e28 100644
--- a/src/lib/util/encode/hex.h
+++ b/src/lib/util/encode/hex.h
@@ -19,6 +19,8 @@
 #include <string>
 #include <vector>
 
+#include <util/lib.h>
+
 //
 // Note: this helper module isn't specific to the DNS protocol per se.
 // We should probably move this to somewhere else, possibly in some common
@@ -39,6 +41,7 @@ namespace encode {
 /// \param binary A vector object storing the data to be encoded. 
 /// \return A newly created string that stores base16 encoded value for
 /// binary.
+ISC_LIBUTIL_API
 std::string encodeHex(const std::vector<uint8_t>& binary);
 
 /// \brief Decode a text encoded in the base16 ('hex') format into the
@@ -52,6 +55,7 @@ std::string encodeHex(const std::vector<uint8_t>& binary);
 ///
 /// \param input A text encoded in the base16 format.
 /// \param result A vector in which the decoded %data is to be stored.
+ISC_LIBUTIL_API
 void decodeHex(const std::string& input, std::vector<uint8_t>& result);
 
 } // namespace encode
diff --git a/src/lib/util/filename.cc b/src/lib/util/filename.cc
index d7da9c8..f9bcb05 100644
--- a/src/lib/util/filename.cc
+++ b/src/lib/util/filename.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
 #include <iostream>
 #include <algorithm>
 #include <string>
diff --git a/src/lib/util/filename.h b/src/lib/util/filename.h
index f625938..c2637c9 100644
--- a/src/lib/util/filename.h
+++ b/src/lib/util/filename.h
@@ -17,6 +17,7 @@
 
 #include <string>
 
+#include <util/lib.h>
 #include <util/strutil.h>
 
 namespace isc {
@@ -55,7 +56,7 @@ namespace util {
 /// substituting components.
 
 
-class Filename {
+class ISC_LIBUTIL_API Filename {
 public:
 
     /// \brief Constructor
diff --git a/src/lib/util/hash/sha1.cc b/src/lib/util/hash/sha1.cc
index 091e293..dd3c3d9 100644
--- a/src/lib/util/hash/sha1.cc
+++ b/src/lib/util/hash/sha1.cc
@@ -50,6 +50,9 @@
  *      without express or implied warranty of any kind.
  *      
  */
+
+#define ISC_LIBUTIL_EXPORT
+
 #include <util/hash/sha1.h>
 
 namespace isc {
diff --git a/src/lib/util/hash/sha1.h b/src/lib/util/hash/sha1.h
index 6089ca8..30428e2 100644
--- a/src/lib/util/hash/sha1.h
+++ b/src/lib/util/hash/sha1.h
@@ -35,6 +35,8 @@
 
 #include <stdint.h>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 namespace hash {
@@ -64,7 +66,7 @@ enum {
  *  This structure will hold context information for the SHA-1
  *  hashing operation
  */
-typedef struct SHA1Context
+typedef struct ISC_LIBUTIL_API SHA1Context
 {
     uint32_t Intermediate_Hash[SHA1_HASHSIZE/4]; /* Message Digest */
     uint32_t Length_Low;                /* Message length in bits */
@@ -78,12 +80,13 @@ typedef struct SHA1Context
 /*
  *  Function Prototypes
  */
-extern int SHA1Reset(SHA1Context *);
-extern int SHA1Input(SHA1Context *, const uint8_t *bytes,
-                     unsigned int bytecount);
-extern int SHA1FinalBits(SHA1Context *, const uint8_t bits,
-                         unsigned int bitcount);
-extern int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1_HASHSIZE]);
+extern ISC_LIBUTIL_API int SHA1Reset(SHA1Context *);
+extern ISC_LIBUTIL_APIint SHA1Input(SHA1Context *, const uint8_t *bytes,
+                                    unsigned int bytecount);
+extern ISC_LIBUTIL_API int SHA1FinalBits(SHA1Context *, const uint8_t bits,
+                                         unsigned int bitcount);
+extern ISC_LIBUTIL_API int SHA1Result(SHA1Context *,
+                                      uint8_t Message_Digest[SHA1_HASHSIZE]);
 
 } // namespace hash
 } // namespace util
diff --git a/src/lib/util/interprocess_sync.h b/src/lib/util/interprocess_sync.h
index e4fa7af..784cbf8 100644
--- a/src/lib/util/interprocess_sync.h
+++ b/src/lib/util/interprocess_sync.h
@@ -17,10 +17,12 @@
 
 #include <string>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 
-class InterprocessSyncLocker; // forward declaration
+class ISC_LIBUTIL_API InterprocessSyncLocker; // forward declaration
 
 /// \brief Interprocess Sync Class
 ///
@@ -42,7 +44,7 @@ class InterprocessSyncLocker; // forward declaration
 /// NOTE: All implementations of InterprocessSync should keep the
 /// is_locked_ member variable updated whenever their
 /// lock()/tryLock()/unlock() implementations are called.
-class InterprocessSync {
+class ISC_LIBUTIL_API InterprocessSync {
   // InterprocessSyncLocker is the only code outside this class that
   // should be allowed to call the lock(), tryLock() and unlock()
   // methods.
@@ -90,7 +92,7 @@ protected:
 /// locks that are released automatically when the block is exited
 /// (RAII). It is meant to be used along with InterprocessSync objects. See
 /// the description of InterprocessSync.
-class InterprocessSyncLocker {
+class ISC_LIBUTIL_API InterprocessSyncLocker {
 public:
     /// \brief Constructor
     ///
diff --git a/src/lib/util/interprocess_sync_file.cc b/src/lib/util/interprocess_sync_file.cc
index d045449..5e820b3 100644
--- a/src/lib/util/interprocess_sync_file.cc
+++ b/src/lib/util/interprocess_sync_file.cc
@@ -12,27 +12,42 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
+#include <config.h>
+
 #include "interprocess_sync_file.h"
 
 #include <string>
 
 #include <stdlib.h>
 #include <string.h>
+#ifndef _WIN32
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#endif
 
 namespace isc {
 namespace util {
 
 InterprocessSyncFile::~InterprocessSyncFile() {
+#ifdef _WIN32
+    if (fd_ != INVALID_HANDLE_VALUE) {
+        // This will also release any applied locks.
+        CloseHandle(fd_);
+        // The lockfile will continue to exist, and we must not delete
+        // it.
+    }
+#else
     if (fd_ != -1) {
         // This will also release any applied locks.
         close(fd_);
         // The lockfile will continue to exist, and we must not delete
         // it.
     }
+#endif
 }
 
 bool
@@ -40,7 +55,13 @@ InterprocessSyncFile::do_lock(int cmd, short l_type) {
     // Open lock file only when necessary (i.e., here). This is so that
     // if a default InterprocessSync object is replaced with another
     // implementation, it doesn't attempt any opens.
-    if (fd_ == -1) {
+    if
+#ifdef _WIN32
+       (fd_ == INVALID_HANDLE_VALUE)
+#else
+       (fd_ == -1)
+#endif
+    {
         std::string lockfile_path = LOCKFILE_DIR;
 
         const char* const env = getenv("B10_FROM_BUILD");
@@ -62,6 +83,20 @@ InterprocessSyncFile::do_lock(int cmd, short l_type) {
 
         // Open the lockfile in the constructor so it doesn't do the access
         // checks every time a message is logged.
+#ifdef _WIN32
+        fd_ = CreateFileA(lockfile_path.c_str(),
+                          GENERIC_READ | GENERIC_WRITE,
+                          FILE_SHARE_READ | FILE_SHARE_WRITE,
+                          NULL,
+                          OPEN_ALWAYS,
+                          FILE_ATTRIBUTE_NORMAL,
+                          NULL);
+        if (fd_ == INVALID_HANDLE_VALUE) {
+            isc_throw(InterprocessSyncFileError,
+                      "Unable to use interprocess sync lockfile: " +
+                      lockfile_path);
+        }
+#else
         const mode_t mode = umask(0111);
         fd_ = open(lockfile_path.c_str(), O_CREAT | O_RDWR, 0660);
         umask(mode);
@@ -71,8 +106,24 @@ InterprocessSyncFile::do_lock(int cmd, short l_type) {
                       "Unable to use interprocess sync lockfile: " +
                       lockfile_path);
         }
+#endif
     }
 
+#ifdef _WIN32
+#define F_SETLK 0
+#define F_SETLKW 1
+#define F_UNLCK 0
+#define F_WRLCK 1
+
+    if (l_type == F_UNLCK)
+        return (UnlockFile(fd_, 0, 0, 1, 0) != 0);
+    OVERLAPPED o;
+    memset(&o, 0, sizeof (o));
+    if (cmd == F_SETLK)
+        return (LockFileEx(fd_, LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &o) != 0);
+    else
+        return (LockFileEx(fd_, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &o) != 0);
+#else
     struct flock lock;
 
     memset(&lock, 0, sizeof (lock));
@@ -82,6 +133,7 @@ InterprocessSyncFile::do_lock(int cmd, short l_type) {
     lock.l_len = 1;
 
     return (fcntl(fd_, cmd, &lock) == 0);
+#endif
 }
 
 bool
diff --git a/src/lib/util/interprocess_sync_file.h b/src/lib/util/interprocess_sync_file.h
index fd8da1b..554f6af 100644
--- a/src/lib/util/interprocess_sync_file.h
+++ b/src/lib/util/interprocess_sync_file.h
@@ -15,6 +15,7 @@
 #ifndef __INTERPROCESS_SYNC_FILE_H__
 #define __INTERPROCESS_SYNC_FILE_H__
 
+#include <util/lib.h>
 #include <util/interprocess_sync.h>
 #include <exceptions/exceptions.h>
 
@@ -25,7 +26,7 @@ namespace util {
 ///
 /// Exception that is thrown if it's not possible to open the
 /// lock file.
-class InterprocessSyncFileError : public Exception {
+class ISC_LIBUTIL_API InterprocessSyncFileError : public Exception {
 public:
     InterprocessSyncFileError(const char* file, size_t line,
                               const char* what) :
@@ -46,7 +47,7 @@ public:
 /// This implementation opens lock files lazily (only when
 /// necessary). It also leaves the lock files lying around as multiple
 /// processes may have locks on them.
-class InterprocessSyncFile : public InterprocessSync {
+class ISC_LIBUTIL_API InterprocessSyncFile : public InterprocessSync {
 public:
     /// \brief Constructor
     ///
@@ -56,7 +57,11 @@ public:
     /// identical among the various processes that need to be
     /// synchronized for the same task.
     InterprocessSyncFile(const std::string& task_name) :
+#ifdef _WIN32
+        InterprocessSync(task_name), fd_(INVALID_HANDLE_VALUE)
+#else
         InterprocessSync(task_name), fd_(-1)
+#endif
     {}
 
     /// \brief Destructor
@@ -82,7 +87,11 @@ protected:
 private:
     bool do_lock(int cmd, short l_type);
 
+#ifdef _WIN32
+    HANDLE fd_; ///< The handle for the open file
+#else
     int fd_; ///< The descriptor for the open file
+#endif
 };
 
 } // namespace util
diff --git a/src/lib/util/interprocess_sync_null.cc b/src/lib/util/interprocess_sync_null.cc
index 5355d57..7f12ed7 100644
--- a/src/lib/util/interprocess_sync_null.cc
+++ b/src/lib/util/interprocess_sync_null.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
 #include "interprocess_sync_null.h"
 
 namespace isc {
diff --git a/src/lib/util/interprocess_sync_null.h b/src/lib/util/interprocess_sync_null.h
index 6ac0322..542a294 100644
--- a/src/lib/util/interprocess_sync_null.h
+++ b/src/lib/util/interprocess_sync_null.h
@@ -15,6 +15,7 @@
 #ifndef __INTERPROCESS_SYNC_NULL_H__
 #define __INTERPROCESS_SYNC_NULL_H__
 
+#include <util/lib.h>
 #include <util/interprocess_sync.h>
 
 namespace isc {
@@ -25,7 +26,7 @@ namespace util {
 /// This class specifies a concrete implementation for a null (no effect)
 /// interprocess synchronization mechanism. Please see the
 /// InterprocessSync class documentation for usage.
-class InterprocessSyncNull : public InterprocessSync {
+class ISC_LIBUTIL_API InterprocessSyncNull : public InterprocessSync {
 public:
     /// \brief Constructor
     ///
diff --git a/src/lib/util/io/fd.cc b/src/lib/util/io/fd.cc
index 49aac39..c8ca485 100644
--- a/src/lib/util/io/fd.cc
+++ b/src/lib/util/io/fd.cc
@@ -12,9 +12,17 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_IO_EXPORT
+
 #include "fd.h"
 
+#ifdef _WIN32
+#include <io.h>
+#define write _write
+#define read _read
+#else
 #include <unistd.h>
+#endif
 #include <cerrno>
 
 namespace isc {
@@ -79,6 +87,76 @@ read_data(const int fd, void *buffer_v, const size_t length) {
     return (static_cast<ssize_t>(length - remaining));
 }
 
+bool
+send_data(
+#ifdef _WIN32
+          const SOCKET fd,
+#else
+          const int fd,
+#endif
+          const void *buffer_v, const size_t length) {
+    const char* buffer(static_cast<const char*>(buffer_v));
+    size_t remaining = length;  // Amount remaining to be written
+
+    // Just keep writing until all is written
+    while (remaining > 0) {
+      const int written = send(fd, buffer, remaining, 0);
+        if (written == -1) {
+            if (errno == EINTR) { // Just keep going
+                continue;
+            } else {
+                return (false);
+            }
+
+        } else if (written > 0) {
+            // Wrote "written" bytes from the buffer
+            remaining -= written;
+            buffer += written;
+
+        } else {
+            // Wrote zero bytes from the buffer. We should not get here as any
+            // error that causes zero bytes to be written should have returned
+            // -1.  However, write(2) can return 0, and in this case we
+            // interpret it as an error.
+            return (false);
+        }
+    }
+    return (true);
+}
+
+ssize_t
+recv_data(
+#ifdef _WIN32
+          const SOCKET fd,
+#else
+          const int fd,
+#endif
+          void *buffer_v, const size_t length) {
+    char* buffer(static_cast<char*>(buffer_v));
+    size_t remaining = length;   // Amount remaining to be read
+
+    while (remaining > 0) {
+        const int amount = recv(fd, buffer, remaining, 0);
+        if (amount == -1) {
+            if (errno == EINTR) { // Continue on interrupted call
+                continue;
+            } else {
+                return (-1);
+            }
+        } else if (amount > 0) {
+            // Read "amount" bytes into the buffer
+            remaining -= amount;
+            buffer += amount;
+        } else {
+            // EOF - end the read
+            break;
+        }
+    }
+
+    // Return total number of bytes read
+    return (static_cast<ssize_t>(length - remaining));
+}
+
 }
 }
 }
diff --git a/src/lib/util/io/fd.h b/src/lib/util/io/fd.h
index bdd2d41..e8c49c9 100644
--- a/src/lib/util/io/fd.h
+++ b/src/lib/util/io/fd.h
@@ -15,7 +15,15 @@
 #ifndef __UTIL_IO_FD_H
 #define __UTIL_IO_FD_H 1
 
+#include <config.h>
+
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <unistd.h>
+#endif
+
+#include <util/io/lib.h>
 
 /**
  * @file fd.h
@@ -38,8 +46,15 @@ namespace io {
  * \param data The buffer to write.
  * \param length How much data is there to write.
  */
-bool
+ISC_LIBUTIL_IO_API bool
 write_data(const int fd, const void *data, const size_t length);
+#ifdef _WIN32
+ISC_LIBUTIL_IO_API bool
+send_data(const SOCKET fd, const void *data, const size_t length);
+#else
+ISC_LIBUTIL_IO_API bool
+send_data(const int fd, const void *data, const size_t length);
+#endif
 
 /*
  * \short read() that reads everything.
@@ -51,8 +66,15 @@ write_data(const int fd, const void *data, const size_t length);
  * \param data Where to put the data.
  * \param length How many of them.
  */
-ssize_t
+ISC_LIBUTIL_IO_API ssize_t
 read_data(const int fd, void *buffer, const size_t length);
+#ifdef _WIN32
+ISC_LIBUTIL_IO_API ssize_t
+recv_data(const SOCKET fd, void *buffer, const size_t length);
+#else
+ISC_LIBUTIL_IO_API ssize_t
+recv_data(const int fd, void *buffer, const size_t length);
+#endif
 
 }
 }
diff --git a/src/lib/util/io/fd_share.cc b/src/lib/util/io/fd_share.cc
index 7adbbbe..aad60f1 100644
--- a/src/lib/util/io/fd_share.cc
+++ b/src/lib/util/io/fd_share.cc
@@ -12,17 +12,30 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_IO_EXPORT
+
+#include <config.h>
+
 #include <cstring>
 #include <cstdlib>
 
+#ifdef _WIN32
+#include <process.h>
+#include <winsock2.h>
+#else
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
+#include <unistd.h>
+#endif
 #include <errno.h>
 #include <stdlib.h>             // for malloc and free
-#include <unistd.h>
 #include "fd_share.h"
 
+#ifndef _WIN32
+
+/* Unix version */
+
 namespace isc {
 namespace util {
 namespace io {
@@ -157,3 +170,80 @@ send_fd(const int sock, const int fd) {
 } // End for namespace io
 } // End for namespace util
 } // End for namespace isc
+
+
+#else
+
+/* Windows version */
+
+namespace isc {
+namespace util {
+namespace io {
+
+namespace {
+// Need the peer PID
+
+int
+send_pid(const SOCKET sock) {
+    pid_t pid(_getpid());
+    if (send(sock, (const char *)&pid, sizeof(pid), 0) != sizeof(pid)) {
+        return (FD_SYSTEM_ERROR);
+    }
+    return (0);
+}
+
+pid_t
+recv_pid(const SOCKET sock) {
+    pid_t pid;
+    if (recv(sock, (char *)&pid , sizeof(pid), 0) != sizeof(pid)) {
+        return (FD_SYSTEM_ERROR);
+    }
+    return (pid);
+}
+}
+
+SOCKET
+recv_fd(const SOCKET sock) {
+    int ret(send_pid(sock));
+    if (ret != 0) {
+        return ((SOCKET) ret);
+    }
+    WSAPROTOCOL_INFO pi;
+    if (recv(sock, (char *)&pi, sizeof(pi), 0) != sizeof(pi)) {
+        return ((SOCKET) FD_SYSTEM_ERROR);
+    }
+    SOCKET nsock = WSASocket(pi.iAddressFamily,
+                             pi.iSocketType,
+                             pi.iProtocol,
+                             &pi, 0, 0);
+    if (nsock == INVALID_SOCKET) {
+        return ((SOCKET) FD_OTHER_ERROR);
+    }
+    return (nsock);
+}
+
+int
+send_fd(const SOCKET sock, const SOCKET fd) {
+    pid_t peerpid(recv_pid(sock));
+    if (peerpid == FD_SYSTEM_ERROR) {
+        return (FD_SYSTEM_ERROR);
+    }
+
+    WSAPROTOCOL_INFO pi;
+    // this will fail with WSAENOTSOCK when fd is not a socket
+    if (WSADuplicateSocket(fd, peerpid, &pi) != 0) {
+        return (FD_OTHER_ERROR);
+    }
+
+    if (send(sock, (const char *)&pi, sizeof(pi), 0) != sizeof(pi)) {
+        return (FD_SYSTEM_ERROR);
+    }
+    return (0);
+
+}
+
+} // End for namespace io
+} // End for namespace util
+} // End for namespace isc
+
+#endif
diff --git a/src/lib/util/io/fd_share.h b/src/lib/util/io/fd_share.h
index 2b30abd..76bc379 100644
--- a/src/lib/util/io/fd_share.h
+++ b/src/lib/util/io/fd_share.h
@@ -21,12 +21,14 @@
  * \todo This interface is very C-ish. Should we have some kind of exceptions?
  */
 
+#include <util/io/lib.h>
+
 namespace isc {
 namespace util {
 namespace io {
 
-const int FD_SYSTEM_ERROR = -2;
-const int FD_OTHER_ERROR = -1;
+ISC_LIBUTIL_IO_API const int FD_SYSTEM_ERROR = -2;
+ISC_LIBUTIL_IO_API const int FD_OTHER_ERROR = -1;
 
 /**
  * \short Receives a file descriptor.
@@ -41,7 +43,12 @@ const int FD_OTHER_ERROR = -1;
  * \param sock The unix domain socket to read from. Tested and it does
  *     not work with a pipe.
  */
+ISC_LIBUTIL_IO_API
+#ifdef _WIN32
+SOCKET recv_fd(const SOCKET sock);
+#else
 int recv_fd(const int sock);
+#endif
 
 /**
  * \short Sends a file descriptor.
@@ -56,7 +63,12 @@ int recv_fd(const int sock);
  * \param fd The file descriptor to send. It should work with any valid
  *     file descriptor.
  */
+ISC_LIBUTIL_IO_API
+#ifdef _WIN32
+int send_fd(const SOCKET sock, const SOCKET fd);
+#else
 int send_fd(const int sock, const int fd);
+#endif
 
 } // End for namespace io
 } // End for namespace util
diff --git a/src/lib/util/io/fdshare_python.cc b/src/lib/util/io/fdshare_python.cc
index 249f8b0..4bcd460 100644
--- a/src/lib/util/io/fdshare_python.cc
+++ b/src/lib/util/io/fdshare_python.cc
@@ -18,6 +18,10 @@
 
 #include <config.h>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#endif
+
 #include "fd_share.h"
 
 
@@ -27,7 +31,7 @@ fdshare_recv_fd(PyObject*, PyObject* args) {
     if (!PyArg_ParseTuple(args, "i", &sock)) {
         return (NULL);
     }
-    fd = isc::util::io::recv_fd(sock);
+    fd = (int) isc::util::io::recv_fd((SOCKET) sock);
     return (Py_BuildValue("i", fd));
 }
 
@@ -37,7 +41,7 @@ fdshare_send_fd(PyObject*, PyObject* args) {
     if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
         return (NULL);
     }
-    result = isc::util::io::send_fd(sock, fd);
+    result = isc::util::io::send_fd((SOCKET) sock, (SOCKET) fd);
     return (Py_BuildValue("i", result));
 }
 
@@ -60,6 +64,9 @@ static PyModuleDef bind10_fdshare_python = {
     NULL
 };
 
+#if defined(_WIN32) && !defined(USE_STATIC_LINK)
+__declspec(dllexport)
+#endif
 PyMODINIT_FUNC
 PyInit_libutil_io_python(void) {
     PyObject *mod = PyModule_Create(&bind10_fdshare_python);
diff --git a/src/lib/util/io/lib.h b/src/lib/util/io/lib.h
new file mode 100644
index 0000000..85fd463
--- /dev/null
+++ b/src/lib/util/io/lib.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LIBUTIL_IO_H
+#define __LIBUTIL_IO_H 1
+
+#if !defined(_WIN32) || defined(USE_STATIC_LINK)
+#define ISC_LIBUTIL_IO_API
+#else
+#ifdef ISC_LIBUTIL_IO_EXPORT
+#define ISC_LIBUTIL_IO_API __declspec(dllexport)
+#else
+#defineISC_LIBUTIL_IO_API __declspec(dllimport)
+#endif
+#endif
+
+#endif // __LIBUTIL_IO_H
+
+// Local Variables: 
+// mode: c++
+// End: 
diff --git a/src/lib/util/io/pktinfo_utilities.h b/src/lib/util/io/pktinfo_utilities.h
index 9883c30..59da31d 100644
--- a/src/lib/util/io/pktinfo_utilities.h
+++ b/src/lib/util/io/pktinfo_utilities.h
@@ -15,8 +15,12 @@
 #ifndef __PKTINFO_UTIL_H_
 #define __PKTINFO_UTIL_H_ 1
 
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netinet/in.h>
+#endif
+
+#include <util/io/lib.h>
 
 // These definitions in this file are for the convenience of internal
 // implementation and test code, and are not intended to be used publicly.
diff --git a/src/lib/util/io/sockaddr_util.h b/src/lib/util/io/sockaddr_util.h
index 0cd7c7b..06981fd 100644
--- a/src/lib/util/io/sockaddr_util.h
+++ b/src/lib/util/io/sockaddr_util.h
@@ -15,12 +15,18 @@
 #ifndef __SOCKADDR_UTIL_H_
 #define __SOCKADDR_UTIL_H_ 1
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#endif
 
 #include <cassert>
 
+#include <util/io/lib.h>
+
 // These definitions in this file are for the convenience of internal
 // implementation and test code, and are not intended to be used publicly.
 // The namespace "internal" indicates the intent.
@@ -43,34 +49,35 @@ getSALength(const struct sockaddr& sa) {
 // Lower level C-APIs require conversion between various variants of
 // sockaddr's, which is not friendly with C++.  The following templates
 // are a shortcut of common workaround conversion in such cases.
-
+#ifndef _MSC_VER
 template <typename SAType>
-const struct sockaddr*
+ISC_LIBUTIL_IO_API const struct sockaddr*
 convertSockAddr(const SAType* sa) {
     const void* p = sa;
     return (static_cast<const struct sockaddr*>(p));
 }
 
 template <typename SAType>
-const SAType*
+ISC_LIBUTIL_IO_API const SAType*
 convertSockAddr(const struct sockaddr* sa) {
     const void* p = sa;
     return (static_cast<const SAType*>(p));
 }
 
 template <typename SAType>
-struct sockaddr*
+ISC_LIBUTIL_IO_API struct sockaddr*
 convertSockAddr(SAType* sa) {
     void* p = sa;
     return (static_cast<struct sockaddr*>(p));
 }
 
 template <typename SAType>
-SAType*
+ISC_LIBUTIL_IO_API SAType*
 convertSockAddr(struct sockaddr* sa) {
     void* p = sa;
     return (static_cast<SAType*>(p));
 }
+#endif
 
 }
 }
diff --git a/src/lib/util/io/socketsession.cc b/src/lib/util/io/socketsession.cc
index 4c50949..9b712b4 100644
--- a/src/lib/util/io/socketsession.cc
+++ b/src/lib/util/io/socketsession.cc
@@ -12,14 +12,21 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_IO_EXPORT
+
 #include <config.h>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#include <process.h>
+#else
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include <sys/un.h>
 
 #include <netinet/in.h>
+#endif
 
 #include <fcntl.h>
 #include <stdint.h>
@@ -81,6 +88,8 @@ const size_t INITIAL_BUFSIZE = 512;
 // may want to customize this value in future.
 const int SOCKSESSION_BUFSIZE = (DEFAULT_HEADER_BUFLEN + MAX_DATASIZE) * 2;
 
+#ifndef _WIN32
+
 struct SocketSessionForwarder::ForwarderImpl {
     ForwarderImpl() : buf_(DEFAULT_HEADER_BUFLEN) {}
     struct sockaddr_un sock_un_;
@@ -94,6 +103,7 @@ SocketSessionForwarder::SocketSessionForwarder(const std::string& unix_file) :
 {
     // We need to filter SIGPIPE for subsequent push().  See the class
     // description.
+
     if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
         isc_throw(Unexpected, "Failed to filter SIGPIPE: " << strerror(errno));
     }
@@ -429,6 +439,343 @@ SocketSessionReceiver::pop() {
     }
 }
 
+#else
+
+/* Windows version */
+
+struct SocketSessionForwarder::ForwarderImpl {
+    ForwarderImpl() : buf_(DEFAULT_HEADER_BUFLEN) {}
+    struct sockaddr_in sock_in_;
+    socklen_t sock_in_len_;
+    SOCKET fd_;
+    OutputBuffer buf_;
+};
+
+SocketSessionForwarder::SocketSessionForwarder(const std::string& unix_file) :
+    impl_(NULL)
+{
+    ForwarderImpl impl;
+    if (atoi(unix_file.c_str()) <= 0) {
+        isc_throw(SocketSessionError, "Port name is not valid: " << unix_file);
+    }
+    impl.sock_in_.sin_family = AF_INET;
+    impl.sock_in_.sin_addr.s_addr = inet_addr("127.0.0.1");
+    impl.sock_in_.sin_port = htons(atoi(unix_file.c_str()));
+    impl.sock_in_len_ = sizeof(struct sockaddr_in);
+    impl.fd_ = INVALID_SOCKET;
+
+    impl_ = new ForwarderImpl;
+    *impl_ = impl;
+}
+
+SocketSessionForwarder::~SocketSessionForwarder() {
+    if (impl_->fd_ != INVALID_SOCKET) {
+        close();
+    }
+    delete impl_;
+}
+
+void
+SocketSessionForwarder::connectToReceiver() {
+    if (impl_->fd_ != INVALID_SOCKET) {
+        isc_throw(BadValue, "Duplicate connect to IP domain "
+                  "endpoint " << ntohs(impl_->sock_in_.sin_port));
+    }
+
+    impl_->fd_ = socket(AF_INET, SOCK_STREAM, 0);
+    if (impl_->fd_ == INVALID_SOCKET) {
+        isc_throw(SocketSessionError, "Failed to create a socket: "
+                  << strerror(WSAGetLastError()));
+    }
+    // Make the socket non blocking
+    u_long nbio_flags = 1;
+    if (ioctlsocket(impl_->fd_, FIONBIO, &nbio_flags) != 0) {
+        close();   // note: this is the internal method, not ::close()
+        isc_throw(SocketSessionError,
+                  "Failed to make socket non blocking: " <<
+                  strerror(WSAGetLastError()));
+    }
+    // Ensure the socket send buffer is large enough.  If we can't get the
+    // current size, simply set the sufficient size.
+    int sndbuf_size;
+    socklen_t sndbuf_size_len = sizeof(sndbuf_size);
+    if (getsockopt(impl_->fd_, SOL_SOCKET, SO_SNDBUF,
+                   (char *)&sndbuf_size, &sndbuf_size_len) == -1 ||
+        sndbuf_size < SOCKSESSION_BUFSIZE) {
+        if (setsockopt(impl_->fd_, SOL_SOCKET, SO_SNDBUF,
+                       (char *)&SOCKSESSION_BUFSIZE,
+                       sizeof(SOCKSESSION_BUFSIZE)) == -1) {
+            close();
+            isc_throw(SocketSessionError, "Failed to set send buffer size");
+        }
+    }
+    if (connect(impl_->fd_, (struct sockaddr *) &impl_->sock_in_,
+                impl_->sock_in_len_) == -1) {
+        close();
+        isc_throw(SocketSessionError, "Failed to connect to endpoint "
+                  << ntohs(impl_->sock_in_.sin_port) << ": " <<
+                  strerror(WSAGetLastError()));
+    }
+}
+
+void
+SocketSessionForwarder::close() {
+    if (impl_->fd_ == INVALID_SOCKET) {
+        isc_throw(BadValue, "Attempt of close before connect");
+    }
+    closesocket(impl_->fd_);
+    impl_->fd_ = INVALID_SOCKET;
+}
+
+void
+SocketSessionForwarder::push(SOCKET sock,
+                             int family, int type, int protocol,
+                             const struct sockaddr& local_end,
+                             const struct sockaddr& remote_end,
+                             const void* data, size_t data_len)
+{
+    if (impl_->fd_ == INVALID_SOCKET) {
+        isc_throw(BadValue, "Attempt of push before connect");
+    }
+    if ((local_end.sa_family != AF_INET && local_end.sa_family != AF_INET6) ||
+        (remote_end.sa_family != AF_INET && remote_end.sa_family != AF_INET6))
+    {
+        isc_throw(BadValue, "Invalid address family: must be "
+                  "AF_INET or AF_INET6; " <<
+                  static_cast<int>(local_end.sa_family) << ", " <<
+                  static_cast<int>(remote_end.sa_family) << " given");
+    }
+    if (family != local_end.sa_family || family != remote_end.sa_family) {
+        isc_throw(BadValue, "Inconsistent address family: must be "
+                  << static_cast<int>(family) << "; "
+                  << static_cast<int>(local_end.sa_family) << ", "
+                  << static_cast<int>(remote_end.sa_family) << " given");
+    }
+    if (data_len == 0 || data == NULL) {
+        isc_throw(BadValue, "Data for a socket session must not be empty");
+    }
+    if (data_len > MAX_DATASIZE) {
+        isc_throw(BadValue, "Invalid socket session data size: " <<
+                  data_len << ", must not exceed " << MAX_DATASIZE);
+    }
+
+    if (send_fd(impl_->fd_, sock) != 0) {
+        isc_throw(SocketSessionError, "FD passing failed: " <<
+                  strerror(errno));
+    }
+
+    impl_->buf_.clear();
+    // Leave the space for the header length
+    impl_->buf_.skip(sizeof(uint16_t));
+    // Socket properties: family, type, protocol
+    impl_->buf_.writeUint32(static_cast<uint32_t>(family));
+    impl_->buf_.writeUint32(static_cast<uint32_t>(type));
+    impl_->buf_.writeUint32(static_cast<uint32_t>(protocol));
+    // Local endpoint
+    impl_->buf_.writeUint32(static_cast<uint32_t>(getSALength(local_end)));
+    impl_->buf_.writeData(&local_end, getSALength(local_end));
+    // Remote endpoint
+    impl_->buf_.writeUint32(static_cast<uint32_t>(getSALength(remote_end)));
+    impl_->buf_.writeData(&remote_end, getSALength(remote_end));
+    // Data length.  Must be fit uint32 due to the range check above.
+    const uint32_t data_len32 = static_cast<uint32_t>(data_len);
+    assert(data_len == data_len32); // shouldn't cause overflow.
+    impl_->buf_.writeUint32(data_len32);
+    // Write the resulting header length at the beginning of the buffer
+    impl_->buf_.writeUint16At(impl_->buf_.getLength() - sizeof(uint16_t), 0);
+
+    WSABUF iov[2] = {
+        { impl_->buf_.getLength(), (char *) impl_->buf_.getData() },
+        { data_len, (char *) data }
+    };
+    DWORD cc;
+    if (WSASend(impl_->fd_, iov, 2, &cc, 0, NULL, NULL) == SOCKET_ERROR) {
+        isc_throw(SocketSessionError,
+                  "Write failed in forwarding a socket session: " <<
+                  strerror(WSAGetLastError()));
+    }
+    if (cc != impl_->buf_.getLength() + data_len) {
+        isc_throw(SocketSessionError,
+                  "Incomplete write in forwarding a socket session: " << cc <<
+                  "/" << (impl_->buf_.getLength() + data_len));
+    }
+}
+
+SocketSession::SocketSession(SOCKET sock,
+                             int family, int type, int protocol,
+                             const sockaddr* local_end,
+                             const sockaddr* remote_end,
+                             const void* data, size_t data_len) :
+    sock_(sock), family_(family), type_(type), protocol_(protocol),
+    local_end_(local_end), remote_end_(remote_end),
+    data_(data), data_len_(data_len)
+{
+    if (local_end == NULL || remote_end == NULL) {
+        isc_throw(BadValue, "sockaddr must be non NULL for SocketSession");
+    }
+    if (data_len == 0) {
+        isc_throw(BadValue, "data_len must be non 0 for SocketSession");
+    }
+    if (data == NULL) {
+        isc_throw(BadValue, "data must be non NULL for SocketSession");
+    }
+}
+
+struct SocketSessionReceiver::ReceiverImpl {
+    ReceiverImpl(SOCKET fd) : fd_(fd),
+                              sa_local_((struct sockaddr *) &ss_local_),
+                              sa_remote_((struct sockaddr *) &ss_remote_),
+                              header_buf_(DEFAULT_HEADER_BUFLEN),
+                              data_buf_(INITIAL_BUFSIZE)
+    {
+        if (setsockopt(fd_, SOL_SOCKET, SO_RCVBUF,
+                       (char *) &SOCKSESSION_BUFSIZE,
+                       sizeof(SOCKSESSION_BUFSIZE)) == -1) {
+            isc_throw(SocketSessionError,
+                      "Failed to set receive buffer size");
+        }
+    }
+
+    const SOCKET fd_;
+    struct sockaddr_storage ss_local_; // placeholder for local endpoint
+    struct sockaddr* const sa_local_;
+    struct sockaddr_storage ss_remote_; // placeholder for remote endpoint
+    struct sockaddr* const sa_remote_;
+
+    // placeholder for session header and data
+    vector<uint8_t> header_buf_;
+    vector<uint8_t> data_buf_;
+};
+
+SocketSessionReceiver::SocketSessionReceiver(SOCKET fd) :
+    impl_(new ReceiverImpl(fd))
+{
+}
+
+SocketSessionReceiver::~SocketSessionReceiver() {
+    delete impl_;
+}
+
+namespace {
+// A shortcut to throw common exception on failure of recv(2)
+void
+readFail(int actual_len, int expected_len) {
+    if (expected_len < 0) {
+        isc_throw(SocketSessionError, "Failed to receive data from "
+                  "SocketSessionForwarder: " << strerror(WSAGetLastError()));
+    }
+    isc_throw(SocketSessionError, "Incomplete data from "
+              "SocketSessionForwarder: " << actual_len << "/" <<
+              expected_len);
+}
+
+// A helper container for a (socket) file descriptor used in
+// SocketSessionReceiver::pop that ensures the socket is closed unless it
+// can be safely passed to the caller via release().
+struct ScopedSocket : boost::noncopyable {
+    ScopedSocket(SOCKET fd) : fd_(fd) {}
+    ~ScopedSocket() {
+        if (fd_ != INVALID_SOCKET) {
+            closesocket(fd_);
+        }
+    }
+    SOCKET release() {
+        const SOCKET fd = fd_;
+        fd_ = INVALID_SOCKET;
+        return (fd);
+    }
+    SOCKET fd_;
+};
+}
+
+SocketSession
+SocketSessionReceiver::pop() {
+    ScopedSocket passed_sock(recv_fd(impl_->fd_));
+    if (passed_sock.fd_ == FD_SYSTEM_ERROR) {
+        isc_throw(SocketSessionError, "Receiving a forwarded FD failed: " <<
+                  strerror(WSAGetLastError()));
+    } else if (passed_sock.fd_ == FD_OTHER_ERROR) {
+        isc_throw(SocketSessionError, "No FD forwarded");
+    }
+
+    uint16_t header_len;
+    const int cc_hlen = recv(impl_->fd_, (char *) &header_len,
+                             sizeof(header_len), MSG_WAITALL);
+    if (cc_hlen < sizeof(header_len)) {
+        readFail(cc_hlen, sizeof(header_len));
+    }
+    header_len = InputBuffer(&header_len, sizeof(header_len)).readUint16();
+    if (header_len > DEFAULT_HEADER_BUFLEN) {
+        isc_throw(SocketSessionError, "Too large header length: " <<
+                  header_len);
+    }
+    impl_->header_buf_.clear();
+    impl_->header_buf_.resize(header_len);
+    const int cc_hdr = recv(impl_->fd_, (char *) &impl_->header_buf_[0],
+                            header_len, MSG_WAITALL);
+    if (cc_hdr < header_len) {
+        readFail(cc_hdr, header_len);
+    }
+
+    InputBuffer ibuffer(&impl_->header_buf_[0], header_len);
+    try {
+        const int family = static_cast<int>(ibuffer.readUint32());
+        if (family != AF_INET && family != AF_INET6) {
+            isc_throw(SocketSessionError,
+                      "Unsupported address family is passed: " << family);
+        }
+        const int type = static_cast<int>(ibuffer.readUint32());
+        const int protocol = static_cast<int>(ibuffer.readUint32());
+        const socklen_t local_end_len = ibuffer.readUint32();
+        const socklen_t endpoint_minlen = (family == AF_INET) ?
+            sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
+        if (local_end_len < endpoint_minlen ||
+            local_end_len > sizeof(impl_->ss_local_)) {
+            isc_throw(SocketSessionError, "Invalid local SA length: " <<
+                      local_end_len);
+        }
+        ibuffer.readData(&impl_->ss_local_, local_end_len);
+        const socklen_t remote_end_len = ibuffer.readUint32();
+        if (remote_end_len < endpoint_minlen ||
+            remote_end_len > sizeof(impl_->ss_remote_)) {
+            isc_throw(SocketSessionError, "Invalid remote SA length: " <<
+                      remote_end_len);
+        }
+        ibuffer.readData(&impl_->ss_remote_, remote_end_len);
+        if (family != impl_->sa_local_->sa_family ||
+            family != impl_->sa_remote_->sa_family) {
+            isc_throw(SocketSessionError, "SA family inconsistent: " <<
+                      static_cast<int>(impl_->sa_local_->sa_family) << ", " <<
+                      static_cast<int>(impl_->sa_remote_->sa_family) <<
+                      " given, must be " << family);
+        }
+        const size_t data_len = ibuffer.readUint32();
+        if (data_len == 0 || data_len > MAX_DATASIZE) {
+            isc_throw(SocketSessionError,
+                      "Invalid socket session data size: " << data_len <<
+                      ", must be > 0 and <= " << MAX_DATASIZE);
+        }
+
+        impl_->data_buf_.clear();
+        impl_->data_buf_.resize(data_len);
+        const int cc_data = recv(impl_->fd_, (char *) &impl_->data_buf_[0],
+                                 data_len, MSG_WAITALL);
+        if (cc_data < (int) data_len) {
+            readFail(cc_data, data_len);
+        }
+
+        return (SocketSession(passed_sock.release(), family, type, protocol,
+                              impl_->sa_local_, impl_->sa_remote_,
+                              &impl_->data_buf_[0], data_len));
+    } catch (const InvalidBufferPosition& ex) {
+        // We catch the case where the given header is too short and convert
+        // the exception to SocketSessionError.
+        isc_throw(SocketSessionError, "bogus socket session header: " <<
+                  ex.what());
+    }
+}
+#endif
+
 }
 }
 }
diff --git a/src/lib/util/io/socketsession.h b/src/lib/util/io/socketsession.h
index 48b7f19..edbbd80 100644
--- a/src/lib/util/io/socketsession.h
+++ b/src/lib/util/io/socketsession.h
@@ -21,7 +21,13 @@
 
 #include <string>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <sys/socket.h>
+#endif
+
+#include <util/io/lib.h>
 
 namespace isc {
 namespace util {
@@ -152,7 +158,7 @@ namespace io {
 /// In general the errors are unusual but possible failures such as unexpected
 /// connection reset, and suggest the application to close the connection and
 /// (if necessary) reestablish it.
-class SocketSessionError: public Exception {
+class ISC_LIBUTIL_IO_API SocketSessionError: public Exception {
 public:
     SocketSessionError(const char *file, size_t line, const char *what):
         isc::Exception(file, line, what) {}
@@ -173,7 +179,7 @@ public:
 /// version of this base class, while it's not prohibited at the API level.
 ///
 /// See description of \c SocketSessionForwarder for the expected interface.
-class BaseSocketSessionForwarder  {
+class ISC_LIBUTIL_IO_API BaseSocketSessionForwarder  {
 protected:
     BaseSocketSessionForwarder() {}
 
@@ -181,7 +187,13 @@ public:
     virtual ~BaseSocketSessionForwarder() {}
     virtual void connectToReceiver() = 0;
     virtual void close() = 0;
-    virtual void push(int sock, int family, int type, int protocol,
+    virtual void push(
+#ifdef _WIN32
+                      SOCKET sock,
+#else
+                      int sock,
+#endif
+                      int family, int type, int protocol,
                       const struct sockaddr& local_end,
                       const struct sockaddr& remote_end,
                       const void* data, size_t data_len) = 0;
@@ -195,8 +207,8 @@ public:
 ///
 /// See the description of \ref SocketSessionUtility for other details of how
 /// the session forwarding works.
-class SocketSessionForwarder : boost::noncopyable,
-                               public BaseSocketSessionForwarder
+class ISC_LIBUTIL_IO_API SocketSessionForwarder :
+ boost::noncopyable, public BaseSocketSessionForwarder
 {
 public:
     /// The constructor.
@@ -309,7 +321,13 @@ public:
     /// \param data A pointer to the beginning of the memory region for the
     ///             session data
     /// \param data_len The size of the session data in bytes.
-    virtual void push(int sock, int family, int type, int protocol,
+    virtual void push(
+#ifdef _WIN32
+                      SOCKET sock,
+#else
+                      int sock,
+#endif
+                      int family, int type, int protocol,
                       const struct sockaddr& local_end,
                       const struct sockaddr& remote_end,
                       const void* data, size_t data_len);
@@ -334,7 +352,7 @@ private:
 /// (e.g. a class or a function that constructs it) is responsible for validity
 /// of the data passed to the object.  See the description of
 /// \c SocketSessionReceiver::pop() for the specific case of that usage.
-class SocketSession {
+class ISC_LIBUTIL_IO_API SocketSession {
 public:
     /// The constructor.
     ///
@@ -359,12 +377,22 @@ public:
     /// session data.  Must not be NULL, and the subsequent \c data_len bytes
     /// must be valid.
     /// \param data_len The size of the session data in bytes.  Must not be 0.
-    SocketSession(int sock, int family, int type, int protocol,
+    SocketSession(
+#ifdef _WIN32
+                  SOCKET sock,
+#else
+                  int sock,
+#endif
+                  int family, int type, int protocol,
                   const sockaddr* local_end, const sockaddr* remote_end,
                   const void* data, size_t data_len);
 
     /// Return the socket file descriptor.
+#ifdef _WIN32
+    SOCKET getSocket() const { return (sock_); }
+#else
     int getSocket() const { return (sock_); }
+#endif
 
     /// Return the address family (such as AF_INET6) of the socket.
     int getFamily() const { return (family_); }
@@ -394,7 +422,11 @@ public:
     size_t getDataLength() const { return (data_len_); }
 
 private:
+#ifdef _WIN32
+    const SOCKET sock_;
+#else
     const int sock_;
+#endif
     const int family_;
     const int type_;
     const int protocol_;
@@ -423,7 +455,7 @@ private:
 ///
 /// See the description of \ref SocketSessionUtility for other details of how
 /// the session forwarding works.
-class SocketSessionReceiver : boost::noncopyable {
+class ISC_LIBUTIL_IO_API SocketSessionReceiver : boost::noncopyable {
 public:
     /// The constructor.
     ///
@@ -433,7 +465,11 @@ public:
     ///
     /// \param fd A UNIX domain socket for an established connection with
     /// a forwarder.
+#ifdef _WIN32
+    explicit SocketSessionReceiver(SOCKET fd);
+#else
     explicit SocketSessionReceiver(int fd);
+#endif
 
     /// The destructor.
     ///
diff --git a/src/lib/util/io_utilities.h b/src/lib/util/io_utilities.h
index 61d4c9c..a6b7bc4 100644
--- a/src/lib/util/io_utilities.h
+++ b/src/lib/util/io_utilities.h
@@ -17,6 +17,8 @@
 
 #include <cstddef>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 
diff --git a/src/lib/util/lib.h b/src/lib/util/lib.h
new file mode 100644
index 0000000..d45932c
--- /dev/null
+++ b/src/lib/util/lib.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LIBUTIL_H
+#define __LIBUTIL_H 1
+
+#if !defined(_WIN32) || defined(USE_STATIC_LINK)
+#define ISC_LIBUTIL_API
+#else
+#ifdef ISC_LIBUTIL_EXPORT
+#define ISC_LIBUTIL_API __declspec(dllexport)
+#else
+#defineISC_LIBUTIL_API __declspec(dllimport)
+#endif
+#endif
+
+#endif // __LIBUTIL_H
+
+// Local Variables: 
+// mode: c++
+// End: 
diff --git a/src/lib/util/locks.h b/src/lib/util/locks.h
index da9e9cd..35a77cf 100644
--- a/src/lib/util/locks.h
+++ b/src/lib/util/locks.h
@@ -26,27 +26,29 @@
 #ifndef __LOCKS_
 #define __LOCKS_
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 namespace locks {
 
-class mutex {
+class ISC_LIBUTIL_API mutex {
 };
 
-class recursive_mutex {
+class ISC_LIBUTIL_API recursive_mutex {
 };
 
-class upgradable_mutex {
+class ISC_LIBUTIL_API upgradable_mutex {
 };
 
 template <typename T>
-class sharable_lock {
+class ISC_LIBUTIL_API sharable_lock {
 public:
     sharable_lock(T) { }
 };
 
 template <typename T>
-class scoped_lock {
+class ISC_LIBUTIL_API scoped_lock {
 public:
     scoped_lock(T) { }
 
diff --git a/src/lib/util/lru_list.h b/src/lib/util/lru_list.h
index 797c3c9..bb86b70 100644
--- a/src/lib/util/lru_list.h
+++ b/src/lib/util/lru_list.h
@@ -21,6 +21,7 @@
 #include <boost/noncopyable.hpp>
 #include <boost/shared_ptr.hpp>
 
+#include <util/lib.h>
 #include <util/locks.h>
 
 namespace isc {
@@ -37,7 +38,7 @@ namespace util {
 /// It is not intended that the class be copied, and the derivation from
 /// boost::noncopyable enforces this.
 template <typename T>
-class LruList : boost::noncopyable {
+class ISC_LIBUTIL_API LruList : boost::noncopyable {
 public:
     typedef typename std::list<boost::shared_ptr<T> > lru_list;
     typedef typename lru_list::iterator               iterator;
diff --git a/src/lib/util/python/gen_wiredata.py.win32 b/src/lib/util/python/gen_wiredata.py.win32
new file mode 100755
index 0000000..4e6b609
--- /dev/null
+++ b/src/lib/util/python/gen_wiredata.py.win32
@@ -0,0 +1,1277 @@
+#!/usr/bin/python
+
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Generator of various types of DNS data in the hex format.
+
+This script reads a human readable specification file (called "spec
+file" hereafter) that defines some type of DNS data (an RDATA, an RR,
+or a complete message) and dumps the defined data to a separate file
+as a "wire format" sequence parsable by the
+UnitTestUtil::readWireData() function (currently defined as part of
+libdns++ tests).  Many DNS related tests involve wire format test
+data, so it will be convenient if we can define the data in a more
+intuitive way than writing the entire hex sequence by hand.
+
+Here is a simple example.  Consider the following spec file:
+
+  [custom]
+  sections: a
+  [a]
+  as_rr: True
+
+When the script reads this file, it detects the file specifies a single
+component (called "section" here) that consists of a single A RDATA,
+which must be dumped as an RR (not only the part of RDATA).  It then
+dumps the following content:
+
+  # A RR (QNAME=example.com Class=IN(1) TTL=86400 RDLEN=4)
+  076578616d706c6503636f6d00 0001 0001 00015180 0004
+  # Address=192.0.2.1
+  c0000201
+
+As can be seen, the script automatically completes all variable
+parameters of RRs: owner name, class, TTL, RDATA length and data.  For
+testing purposes many of these will be the same common one (like
+"example.com" or 192.0.2.1), so it would be convenient if we only have
+to specify non default parameters.  To change the RDATA (i.e., the
+IPv4 address), we should add the following line at the end of the spec
+file:
+
+  address: 192.0.2.2
+
+Then the last two lines of the output file will be as follows:
+
+  # Address=192.0.2.2
+  c0000202
+
+In some cases we would rather specify malformed data for tests.  This
+script has the ability to specify broken parameters for many types of
+data.  For example, we can generate data that would look like an A RR
+but the RDLEN is 3 by adding the following line to the spec file:
+
+  rdlen: 3
+
+Then the first two lines of the output file will be as follows:
+
+  # A RR (QNAME=example.com Class=IN(1) TTL=86400 RDLEN=3)
+  076578616d706c6503636f6d00 0001 0001 00015180 0003
+
+** USAGE **
+
+  gen_wiredata.py [-o output_file] spec_file
+
+If the -o option is missing, and if the spec_file has a suffix (such as
+in the form of "data.spec"), the output file name will be the prefix
+part of it (as in "data"); if -o is missing and the spec_file does not
+have a suffix, the script will fail.
+
+** SPEC FILE SYNTAX **
+
+A spec file accepted in this script should be in the form of a
+configuration file that is parsable by the Python's standard
+configparser module.  In short, it consists of sections; each section
+is identified in the form of [section_name] followed by "name: value"
+entries.  Lines beginning with # or ; will be treated as comments.
+Refer to the configparser module documentation for further details of
+the general syntax.
+
+This script has two major modes: the custom mode and the DNS query
+mode.  The former generates an arbitrary combination of DNS message
+header, question section, RDATAs or RRs.  It is mainly intended to
+generate a test data for a single type of RDATA or RR, or for
+complicated complete DNS messages.  The DNS query mode is actually a
+special case of the custom mode, which is a shortcut to generate a
+simple DNS query message (with or without EDNS).
+
+* Custom mode syntax *
+
+By default this script assumes the DNS query mode.  To specify the
+custom mode, there must be a special "custom" section in the spec
+file, which should contain 'sections' entry.  This value of this
+entryis colon-separated string fields, each of which is either
+"header", "question", "edns", "name", or a string specifying an RR
+type.  For RR types the string is lower-cased string mnemonic that
+identifies the type: 'a' for type A, 'ns' for type NS, and so on
+(note: in the current implementation it's case sensitive, and must be
+lower cased).
+
+Each of these fields is interpreted as a section name of the spec
+(configuration), and in that section parameters specific to the
+semantics of the field can be configured.
+
+A "header" section specifies the content of a DNS message header.
+See the documentation of the DNSHeader class of this module for
+configurable parameters.
+
+A "question" section specifies the content of a single question that
+is normally to be placed in the Question section of a DNS message.
+See the documentation of the DNSQuestion class of this module for
+configurable parameters.
+
+An "edns" section specifies the content of an EDNS OPT RR.  See the
+documentation of the EDNS class of this module for configurable
+parameters.
+
+A "name" section specifies a domain name with or without compression.
+This is specifically intended to be used for testing name related
+functionalities and would rarely be used with other sections.  See the
+documentation of the Name class of this module for configurable
+parameters.
+
+In a specific section for an RR or RDATA, possible entries depend on
+the type.  But there are some common configurable entries.  See the
+description of the RR class.  The most important one would be "as_rr".
+It controls whether the entry should be treated as an RR (with name,
+type, class and TTL) or only as an RDATA.  By default as_rr is
+"False", so if an entry is to be intepreted as an RR, an as_rr entry
+must be explicitly specified with a value of "True".
+
+Another common entry is "rdlen".  It specifies the RDLEN field value
+of the RR (note: this is included when the entry is interpreted as
+RDATA, too).  By default this value is automatically determined by the
+RR type and (it has a variable length) from other fields of RDATA, but
+as shown in the above example, it can be explicitly set, possibly to a
+bogus value for testing against invalid data.
+
+For type specific entries (and their defaults when provided), see the
+documentation of the corresponding Python class defined in this
+module.  In general, there should be a class named the same mnemonic
+of the corresponding RR type for each supported type, and they are a
+subclass of the RR class.  For example, the "NS" class is defined for
+RR type NS.
+
+Look again at the A RR example shown at the beginning of this
+description.  There's a "custom" section, which consists of a
+"sections" entry whose value is a single "a", which means the data to
+be generated is an A RR or RDATA.  There's a corresponding "a"
+section, which only specifies that it should be interpreted as an RR
+(all field values of the RR are derived from the default).
+
+If you want to generate a data sequence for two ore more RRs or
+RDATAs, you can specify them in the form of colon-separated fields for
+the "sections" entry.  For example, to generate a sequence of A and NS
+RRs in that order, the "custom" section would be something like this:
+
+  [custom]
+  sections: a:ns
+
+and there must be an "ns" section in addtion to "a".
+
+If a sequence of two or more RRs/RDATAs of the same RR type should be
+generated, these should be uniquely indexed with the "/" separator.
+For example, to generate two A RRs, the "custom" section would be as
+follows:
+
+  [custom]
+  sections: a/1:a/2
+
+and there must be "a/1" and "a/2" sections.
+
+Another practical example that would be used for many tests is to
+generate data for a complete DNS ressponse message.  The spec file of
+such an example configuration would look like as follows:
+
+  [custom]
+  sections: header:question:a
+  [header]
+  qr: 1
+  ancount: 1
+  [question]
+  [a]
+  as_rr: True
+
+With this configuration, this script will generate test data for a DNS
+response to a query for example.com/IN/A containing one corresponding
+A RR in the answer section.
+
+* DNS query mode syntax *
+
+If the spec file does not contain a "custom" section (that has a
+"sections" entry), this script assumes the DNS query mode.  This mode
+is actually a special case of custom mode; it implicitly assumes the
+"sections" entry whose value is "header:question:edns".
+
+In this mode it is expected that the spec file also contains at least
+a "header" and "question" sections, and optionally an "edns" section.
+But the script does not warn or fail even if the expected sections are
+missing.
+
+* Entry value types *
+
+As described above, a section of the spec file accepts entries
+specific to the semantics of the section.  They generally correspond
+to DNS message or RR fields.
+
+Many of them are expected to be integral values, for which either decimal or
+hexadecimal representation is accepted, for example:
+
+  rr_ttl: 3600
+  tag: 0x1234
+
+Some others are expected to be string.  A string value does not have
+to be quated:
+
+  address: 192.0.2.2
+
+but can also be quoated with single quotes:
+
+  address: '192.0.2.2'
+
+Note 1: a string that can be interpreted as an integer must be quated.
+For example, if you want to set a "string" entry to "3600", it should
+be:
+
+  string: '3600'
+
+instead of
+
+  string: 3600
+
+Note 2: a string enclosed with double quotes is not accepted:
+
+  # This doesn't work:
+  address: "192.0.2.2"
+
+In general, string values are converted to hexadecimal sequences
+according to the semantics of the entry.  For instance, a textual IPv4
+address in the above example will be converted to a hexadecimal
+sequence corresponding to a 4-byte integer.  So, in many cases, the
+acceptable syntax for a particular string entry value should be
+obvious from the context.  There are still some exceptional cases
+especially for complicated RR field values, for which the
+corresponding class documentation should be referenced.
+
+One special string syntax that would be worth noting is domain names,
+which would natually be used in many kinds of entries.  The simplest
+form of acceptable syntax is a textual representation of domain names
+such as "example.com" (note: names are always assumed to be
+"absolute", so the trailing dot can be omitted).  But a domain name in
+the wire format can also contain a compression pointer.  This script
+provides a simple support for name compression with a special notation
+of "ptr=nn" where nn is the numeric pointer value (decimal).  For example,
+if the NSDNAME field of an NS RDATA is specified as follows:
+
+  nsname: ns.ptr=12
+
+this script will generate the following output:
+
+  # NS name=ns.ptr=12
+  026e73c00c
+
+** EXTEND THE SCRIPT **
+
+This script is expected to be extended as we add more support for
+various types of RR.  It is encouraged to add support for a new type
+of RR to this script as we see the need for testing that type.  Here
+is a simple instruction of how to do that.
+
+Assume you are adding support for "FOO" RR.  Also assume that the FOO
+RDATA contains a single field named "value".
+
+What you are expected to do is as follows:
+
+- Define a new class named "FOO" inherited from the RR class.  Also
+  define a class variable named "value" for the FOO RDATA field (the
+  variable name can be different from the field name, but it's
+  convenient if it can be easily identifiable.) with an appropriate
+  default value (if possible):
+
+    class FOO(RR):
+        value = 10
+
+  The name of the variable will be (automatically) used as the
+  corresponding entry name in the spec file.  So, a spec file that
+  sets this field to 20 would look like this:
+
+    [foo]
+    value: 20
+
+- Define the "dump()" method for class FOO.  It must call
+  self.dump_header() (which is derived from class RR) at the
+  beginning.  It then prints the RDATA field values in an appropriate
+  way.  Assuming the value is a 16-bit integer field, a complete
+  dump() method would look like this:
+
+    def dump(self, f):
+        if self.rdlen is None:
+            self.rdlen = 2
+        self.dump_header(f, self.rdlen)
+        f.write('# Value=%d\\n' % (self.value))
+        f.write('%04x\\n' % (self.value))
+
+  The first f.write() call is not mandatory, but is encouraged to
+  be provided so that the generated files will be more human readable.
+  Depending on the complexity of the RDATA fields, the dump()
+  implementation would be more complicated.  In particular, if the
+  RDATA length is variable and the RDLEN field value is not specified
+  in the spec file, the dump() method is normally expected to
+  calculate the correct length and pass it to dump_header().  See the
+  implementation of various derived classes of class RR for actual
+  examples.
+"""
+
+import configparser, re, time, socket, sys
+from datetime import datetime
+from optparse import OptionParser
+
+re_hex = re.compile(r'^0x[0-9a-fA-F]+')
+re_decimal = re.compile(r'^\d+$')
+re_string = re.compile(r"\'(.*)\'$")
+
+dnssec_timefmt = '%Y%m%d%H%M%S'
+
+dict_qr = { 'query' : 0, 'response' : 1 }
+dict_opcode = { 'query' : 0, 'iquery' : 1, 'status' : 2, 'notify' : 4,
+                'update' : 5 }
+rdict_opcode = dict([(dict_opcode[k], k.upper()) for k in dict_opcode.keys()])
+dict_rcode = { 'noerror' : 0, 'formerr' : 1, 'servfail' : 2, 'nxdomain' : 3,
+               'notimp' : 4, 'refused' : 5, 'yxdomain' : 6, 'yxrrset' : 7,
+               'nxrrset' : 8, 'notauth' : 9, 'notzone' : 10 }
+rdict_rcode = dict([(dict_rcode[k], k.upper()) for k in dict_rcode.keys()])
+dict_rrtype = { 'none' : 0, 'a' : 1, 'ns' : 2, 'md' : 3, 'mf' : 4, 'cname' : 5,
+                'soa' : 6, 'mb' : 7, 'mg' : 8, 'mr' : 9, 'null' : 10,
+                'wks' : 11, 'ptr' : 12, 'hinfo' : 13, 'minfo' : 14, 'mx' : 15,
+                'txt' : 16, 'rp' : 17, 'afsdb' : 18, 'x25' : 19, 'isdn' : 20,
+                'rt' : 21, 'nsap' : 22, 'nsap_tr' : 23, 'sig' : 24, 'key' : 25,
+                'px' : 26, 'gpos' : 27, 'aaaa' : 28, 'loc' : 29, 'nxt' : 30,
+                'srv' : 33, 'naptr' : 35, 'kx' : 36, 'cert' : 37, 'a6' : 38,
+                'dname' : 39, 'opt' : 41, 'apl' : 42, 'ds' : 43, 'sshfp' : 44,
+                'ipseckey' : 45, 'rrsig' : 46, 'nsec' : 47, 'dnskey' : 48,
+                'dhcid' : 49, 'nsec3' : 50, 'nsec3param' : 51, 'hip' : 55,
+                'spf' : 99, 'unspec' : 103, 'tkey' : 249, 'tsig' : 250,
+                'dlv' : 32769, 'ixfr' : 251, 'axfr' : 252, 'mailb' : 253,
+                'maila' : 254, 'any' : 255 }
+rdict_rrtype = dict([(dict_rrtype[k], k.upper()) for k in dict_rrtype.keys()])
+dict_rrclass = { 'in' : 1, 'ch' : 3, 'hs' : 4, 'any' : 255 }
+rdict_rrclass = dict([(dict_rrclass[k], k.upper()) for k in \
+                          dict_rrclass.keys()])
+dict_algorithm = { 'rsamd5' : 1, 'dh' : 2, 'dsa' : 3, 'ecc' : 4,
+                   'rsasha1' : 5 }
+dict_nsec3_algorithm = { 'reserved' : 0, 'sha1' : 1 }
+rdict_algorithm = dict([(dict_algorithm[k], k.upper()) for k in \
+                            dict_algorithm.keys()])
+rdict_nsec3_algorithm = dict([(dict_nsec3_algorithm[k], k.upper()) for k in \
+                                  dict_nsec3_algorithm.keys()])
+
+header_xtables = { 'qr' : dict_qr, 'opcode' : dict_opcode,
+                   'rcode' : dict_rcode }
+question_xtables = { 'rrtype' : dict_rrtype, 'rrclass' : dict_rrclass }
+
+def parse_value(value, xtable = {}):
+    if re.search(re_hex, value):
+        return int(value, 16)
+    if re.search(re_decimal, value):
+        return int(value)
+    m = re.match(re_string, value)
+    if m:
+        return m.group(1)
+    lovalue = value.lower()
+    if lovalue in xtable:
+        return xtable[lovalue]
+    return value
+
+def code_totext(code, dict):
+    if code in dict.keys():
+        return dict[code] + '(' + str(code) + ')'
+    return str(code)
+
+def encode_name(name, absolute=True):
+    # make sure the name is dot-terminated.  duplicate dots will be ignored
+    # below.
+    name += '.'
+    labels = name.split('.')
+    wire = ''
+    for l in labels:
+        if len(l) > 4 and l[0:4] == 'ptr=':
+            # special meta-syntax for compression pointer
+            wire += '%04x' % (0xc000 | int(l[4:]))
+            break
+        if absolute or len(l) > 0:
+            wire += '%02x' % len(l)
+            wire += ''.join(['%02x' % ord(ch) for ch in l])
+        if len(l) == 0:
+            break
+    return wire
+
+def encode_string(name, len=None):
+    if type(name) is int and len is not None:
+        return '%0.*x' % (len * 2, name)
+    return ''.join(['%02x' % ord(ch) for ch in name])
+
+def count_namelabels(name):
+    if name == '.':             # special case
+        return 0
+    m = re.match('^(.*)\.$', name)
+    if m:
+        name = m.group(1)
+    return len(name.split('.'))
+
+def get_config(config, section, configobj, xtables = {}):
+    try:
+        for field in config.options(section):
+            value = config.get(section, field)
+            if field in xtables.keys():
+                xtable = xtables[field]
+            else:
+                xtable = {}
+            configobj.__dict__[field] = parse_value(value, xtable)
+    except configparser.NoSectionError:
+        return False
+    return True
+
+def print_header(f, input_file):
+    f.write('''###
+### This data file was auto-generated from ''' + input_file + '''
+###
+''')
+
+class Name:
+    '''Implements rendering a single domain name in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - name (string): A textual representation of the name, such as
+      'example.com'.
+    - pointer (int): If specified, compression pointer will be
+      prepended to the generated data with the offset being the value
+      of this parameter.
+    '''
+
+    name = 'example.com'
+    pointer = None                # no compression by default
+    def dump(self, f):
+        name = self.name
+        if self.pointer is not None:
+            if len(name) > 0 and name[-1] != '.':
+                name += '.'
+            name += 'ptr=%d' % self.pointer
+        name_wire = encode_name(name)
+        f.write('\n# DNS Name: %s' % self.name)
+        if self.pointer is not None:
+            f.write(' + compression pointer: %d' % self.pointer)
+        f.write('\n')
+        f.write('%s' % name_wire)
+        f.write('\n')
+
+class DNSHeader:
+    '''Implements rendering a DNS Header section in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - id (16-bit int):
+    - qr, aa, tc, rd, ra, ad, cd (0 or 1): Standard header bits as
+      defined in RFC1035 and RFC4035.  If set to 1, the corresponding
+      bit will be set; if set to 0, it will be cleared.
+    - mbz (0-3): The reserved field of the 3rd and 4th octets of the
+      header.
+    - rcode (4-bit int or string): The RCODE field.  If specified as a
+      string, it must be the commonly used textual mnemonic of the RCODEs
+      (NOERROR, FORMERR, etc, case insensitive).
+    - opcode (4-bit int or string): The OPCODE field.  If specified as
+      a string, it must be the commonly used textual mnemonic of the
+      OPCODEs (QUERY, NOTIFY, etc, case insensitive).
+    - qdcount, ancount, nscount, arcount (16-bit int): The QD/AN/NS/AR
+      COUNT fields, respectively.
+    '''
+
+    id = 0x1035
+    (qr, aa, tc, rd, ra, ad, cd) = 0, 0, 0, 0, 0, 0, 0
+    mbz = 0
+    rcode = 0                   # noerror
+    opcode = 0                  # query
+    (qdcount, ancount, nscount, arcount) = 1, 0, 0, 0
+
+    def dump(self, f):
+        f.write('\n# Header Section\n')
+        f.write('# ID=' + str(self.id))
+        f.write(' QR=' + ('Response' if self.qr else 'Query'))
+        f.write(' Opcode=' + code_totext(self.opcode, rdict_opcode))
+        f.write(' Rcode=' + code_totext(self.rcode, rdict_rcode))
+        f.write('%s' % (' AA' if self.aa else ''))
+        f.write('%s' % (' TC' if self.tc else ''))
+        f.write('%s' % (' RD' if self.rd else ''))
+        f.write('%s' % (' AD' if self.ad else ''))
+        f.write('%s' % (' CD' if self.cd else ''))
+        f.write('\n')
+        f.write('%04x ' % self.id)
+        flag_and_code = 0
+        flag_and_code |= (self.qr << 15 | self.opcode << 14 | self.aa << 10 |
+                          self.tc << 9 | self.rd << 8 | self.ra << 7 |
+                          self.mbz << 6 | self.ad << 5 | self.cd << 4 |
+                          self.rcode)
+        f.write('%04x\n' % flag_and_code)
+        f.write('# QDCNT=%d, ANCNT=%d, NSCNT=%d, ARCNT=%d\n' %
+                (self.qdcount, self.ancount, self.nscount, self.arcount))
+        f.write('%04x %04x %04x %04x\n' % (self.qdcount, self.ancount,
+                                           self.nscount, self.arcount))
+
+class DNSQuestion:
+    '''Implements rendering a DNS question in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - name (string): The QNAME.  The string must be interpreted as a
+      valid domain name.
+    - rrtype (int or string): The question type.  If specified
+      as an integer, it must be the 16-bit RR type value of the
+      covered type.  If specifed as a string, it must be the textual
+      mnemonic of the type.
+    - rrclass (int or string): The question class.  If specified as an
+      integer, it must be the 16-bit RR class value of the covered
+      type.  If specifed as a string, it must be the textual mnemonic
+      of the class.
+    '''
+    name = 'example.com.'
+    rrtype = parse_value('A', dict_rrtype)
+    rrclass = parse_value('IN', dict_rrclass)
+
+    def dump(self, f):
+        f.write('\n# Question Section\n')
+        f.write('# QNAME=%s QTYPE=%s QCLASS=%s\n' %
+                (self.name,
+                 code_totext(self.rrtype, rdict_rrtype),
+                 code_totext(self.rrclass, rdict_rrclass)))
+        f.write(encode_name(self.name))
+        f.write(' %04x %04x\n' % (self.rrtype, self.rrclass))
+
+class EDNS:
+    '''Implements rendering EDNS OPT RR in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - name (string): The owner name of the OPT RR.  The string must be
+      interpreted as a valid domain name.
+    - udpsize (16-bit int): The UDP payload size (set as the RR class)
+    - extrcode (8-bit int): The upper 8 bits of the extended RCODE.
+    - version (8-bit int): The EDNS version.
+    - do (int): The DNSSEC DO bit.  The bit will be set if this value
+      is 1; otherwise the bit will be unset.
+    - mbz (15-bit int): The rest of the flags field.
+    - rdlen (16-bit int): The RDLEN field.  Note: right now specifying
+      a non 0 value (except for making bogus data) doesn't make sense
+      because there is no way to configure RDATA.
+    '''
+    name = '.'
+    udpsize = 4096
+    extrcode = 0
+    version = 0
+    do = 0
+    mbz = 0
+    rdlen = 0
+    def dump(self, f):
+        f.write('\n# EDNS OPT RR\n')
+        f.write('# NAME=%s TYPE=%s UDPSize=%d ExtRcode=%s Version=%s DO=%d\n' %
+                (self.name, code_totext(dict_rrtype['opt'], rdict_rrtype),
+                 self.udpsize, self.extrcode, self.version,
+                 1 if self.do else 0))
+        
+        code_vers = (self.extrcode << 8) | (self.version & 0x00ff)
+        extflags = (self.do << 15) | (self.mbz & ~0x8000)
+        f.write('%s %04x %04x %04x %04x\n' %
+                (encode_name(self.name), dict_rrtype['opt'], self.udpsize,
+                 code_vers, extflags))
+        f.write('# RDLEN=%d\n' % self.rdlen)
+        f.write('%04x\n' % self.rdlen)
+
+class RR:
+    '''This is a base class for various types of RR test data.
+    For each RR type (A, AAAA, NS, etc), we define a derived class of RR
+    to dump type specific RDATA parameters.  This class defines parameters
+    common to all types of RDATA, namely the owner name, RR class and TTL.
+    The dump() method of derived classes are expected to call dump_header(),
+    whose default implementation is provided in this class.  This method
+    decides whether to dump the test data as an RR (with name, type, class)
+    or only as RDATA (with its length), and dumps the corresponding data
+    via the specified file object.
+
+    By convention we assume derived classes are named after the common
+    standard mnemonic of the corresponding RR types.  For example, the
+    derived class for the RR type SOA should be named "SOA".
+
+    Configurable parameters are as follows:
+    - as_rr (bool): Whether or not the data is to be dumped as an RR.
+      False by default.
+    - rr_name (string): The owner name of the RR.  The string must be
+      interpreted as a valid domain name (compression pointer can be
+      contained).  Default is 'example.com.'
+    - rr_class (string): The RR class of the data.  Only meaningful
+      when the data is dumped as an RR.  Default is 'IN'.
+    - rr_ttl (int): The TTL value of the RR.  Only meaningful when
+      the data is dumped as an RR.  Default is 86400 (1 day).
+    - rdlen (int): 16-bit RDATA length.  It can be None (i.e. omitted
+      in the spec file), in which case the actual length of the
+      generated RDATA is automatically determined and used; if
+      negative, the RDLEN field will be omitted from the output data.
+      (Note that omitting RDLEN with as_rr being True is mostly
+      meaningless, although the script doesn't complain about it).
+      Default is None.
+    '''
+
+    def __init__(self):
+        self.as_rr = False
+        # only when as_rr is True, same for class/TTL:
+        self.rr_name = 'example.com'
+        self.rr_class = 'IN'
+        self.rr_ttl = 86400
+        self.rdlen = None
+
+    def dump_header(self, f, rdlen):
+        type_txt = self.__class__.__name__
+        type_code = parse_value(type_txt, dict_rrtype)
+        rdlen_spec = ''
+        rdlen_data = ''
+        if rdlen >= 0:
+            rdlen_spec = ', RDLEN=%d' % rdlen
+            rdlen_data = '%04x' % rdlen
+        if self.as_rr:
+            rrclass = parse_value(self.rr_class, dict_rrclass)
+            f.write('\n# %s RR (QNAME=%s Class=%s TTL=%d%s)\n' %
+                    (type_txt, self.rr_name,
+                     code_totext(rrclass, rdict_rrclass), self.rr_ttl,
+                     rdlen_spec))
+            f.write('%s %04x %04x %08x %s\n' %
+                    (encode_name(self.rr_name), type_code, rrclass,
+                     self.rr_ttl, rdlen_data))
+        else:
+            f.write('\n# %s RDATA%s\n' % (type_txt, rdlen_spec))
+            f.write('%s\n' % rdlen_data)
+
+class A(RR):
+    '''Implements rendering A RDATA (of class IN) in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - address (string): The address field.  This must be a valid textual
+      IPv4 address.
+    '''
+    RDLEN_DEFAULT = 4           # fixed by default
+    address = '192.0.2.1'
+
+    def dump(self, f):
+        if self.rdlen is None:
+            self.rdlen = self.RDLEN_DEFAULT
+        self.dump_header(f, self.rdlen)
+        f.write('# Address=%s\n' % (self.address))
+        bin_address = socket.inet_aton(self.address)
+        f.write('%02x%02x%02x%02x\n' % (bin_address[0], bin_address[1],
+                                        bin_address[2], bin_address[3]))
+
+class AAAA(RR):
+    '''Implements rendering AAAA RDATA (of class IN) in the test data
+    format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - address (string): The address field.  This must be a valid textual
+      IPv6 address.
+    '''
+    RDLEN_DEFAULT = 16          # fixed by default
+    address = '2001:db8::1'
+
+    def dump(self, f):
+        if self.rdlen is None:
+            self.rdlen = self.RDLEN_DEFAULT
+        self.dump_header(f, self.rdlen)
+        f.write('# Address=%s\n' % (self.address))
+        bin_address = socket.inet_pton(socket.AF_INET6, self.address)
+        [f.write('%02x' % x) for x in bin_address]
+        f.write('\n')
+
+class NS(RR):
+    '''Implements rendering NS RDATA in the test data format.
+
+    Configurable parameter is as follows (see the description of the
+    same name of attribute for the default value):
+    - nsname (string): The NSDNAME field.  The string must be
+      interpreted as a valid domain name.
+    '''
+
+    nsname = 'ns.example.com'
+
+    def dump(self, f):
+        nsname_wire = encode_name(self.nsname)
+        if self.rdlen is None:
+            self.rdlen = len(nsname_wire) / 2
+        self.dump_header(f, self.rdlen)
+        f.write('# NS name=%s\n' % (self.nsname))
+        f.write('%s\n' % nsname_wire)
+
+class SOA(RR):
+    '''Implements rendering SOA RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - mname/rname (string): The MNAME/RNAME fields, respectively.  The
+      string must be interpreted as a valid domain name.
+    - serial (32-bit int): The SERIAL field
+    - refresh (32-bit int): The REFRESH field
+    - retry (32-bit int): The RETRY field
+    - expire (32-bit int): The EXPIRE field
+    - minimum (32-bit int): The MINIMUM field
+    '''
+
+    mname = 'ns.example.com'
+    rname = 'root.example.com'
+    serial = 2010012601
+    refresh = 3600
+    retry = 300
+    expire = 3600000
+    minimum = 1200
+    def dump(self, f):
+        mname_wire = encode_name(self.mname)
+        rname_wire = encode_name(self.rname)
+        if self.rdlen is None:
+            self.rdlen = int(20 + len(mname_wire) / 2 + len(str(rname_wire)) / 2)
+        self.dump_header(f, self.rdlen)
+        f.write('# NNAME=%s RNAME=%s\n' % (self.mname, self.rname))
+        f.write('%s %s\n' % (mname_wire, rname_wire))
+        f.write('# SERIAL(%d) REFRESH(%d) RETRY(%d) EXPIRE(%d) MINIMUM(%d)\n' %
+                (self.serial, self.refresh, self.retry, self.expire,
+                 self.minimum))
+        f.write('%08x %08x %08x %08x %08x\n' % (self.serial, self.refresh,
+                                                self.retry, self.expire,
+                                                self.minimum))
+
+class TXT(RR):
+    '''Implements rendering TXT RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - nstring (int): number of character-strings
+    - stringlenN (int) (int, N = 0, ..., nstring-1): the length of the
+      N-th character-string.
+    - stringN (string, N = 0, ..., nstring-1): the N-th
+      character-string.
+    - stringlen (int): the default string.  If nstring >= 1 and the
+      corresponding stringlenN isn't specified in the spec file, this
+      value will be used.  If this parameter isn't specified either,
+      the length of the string will be used.  Note that it means
+      this parameter (or any stringlenN) doesn't have to be specified
+      unless you want to intentially build a broken character string.
+    - string (string): the default string.  If nstring >= 1 and the
+      corresponding stringN isn't specified in the spec file, this
+      string will be used.
+    '''
+
+    nstring = 1
+    stringlen = None
+    string = 'Test String'
+
+    def dump(self, f):
+        stringlen_list = []
+        string_list = []
+        wirestring_list = []
+        for i in range(0, self.nstring):
+            key_string = 'string' + str(i)
+            if key_string in self.__dict__:
+                string_list.append(self.__dict__[key_string])
+            else:
+                string_list.append(self.string)
+            wirestring_list.append(encode_string(string_list[-1]))
+            key_stringlen = 'stringlen' + str(i)
+            if key_stringlen in self.__dict__:
+                stringlen_list.append(self.__dict__[key_stringlen])
+            else:
+                stringlen_list.append(self.stringlen)
+            if stringlen_list[-1] is None:
+                stringlen_list[-1] = int(len(wirestring_list[-1]) / 2)
+        if self.rdlen is None:
+            self.rdlen = int(len(''.join(wirestring_list)) / 2) + self.nstring
+        self.dump_header(f, self.rdlen)
+        for i in range(0, self.nstring):
+            f.write('# String Len=%d, String=\"%s\"\n' %
+                    (stringlen_list[i], string_list[i]))
+            f.write('%02x%s%s\n' % (stringlen_list[i],
+                                    ' ' if len(wirestring_list[i]) > 0 else '',
+                                    wirestring_list[i]))
+
+class RP(RR):
+    '''Implements rendering RP RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - mailbox (string): The mailbox field.
+    - text (string): The text field.
+    These strings must be interpreted as a valid domain name.
+    '''
+    mailbox = 'root.example.com'
+    text = 'rp-text.example.com'
+    def dump(self, f):
+        mailbox_wire = encode_name(self.mailbox)
+        text_wire = encode_name(self.text)
+        if self.rdlen is None:
+            self.rdlen = (len(mailbox_wire) + len(text_wire)) / 2
+        else:
+            self.rdlen = int(self.rdlen)
+        self.dump_header(f, self.rdlen)
+        f.write('# MAILBOX=%s TEXT=%s\n' % (self.mailbox, self.text))
+        f.write('%s %s\n' % (mailbox_wire, text_wire))
+
+class SSHFP(RR):
+    '''Implements rendering SSHFP RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - algorithm (int): The algorithm number.
+    - fingerprint_type (int): The fingerprint type.
+    - fingerprint (string): The fingerprint.
+    '''
+    algorithm = 2
+    fingerprint_type = 1
+    fingerprint = '123456789abcdef67890123456789abcdef67890'
+    def dump(self, f):
+        if self.rdlen is None:
+            self.rdlen = 2 + (len(self.fingerprint) / 2)
+        else:
+            self.rdlen = int(self.rdlen)
+        self.dump_header(f, self.rdlen)
+        f.write('# ALGORITHM=%d FINGERPRINT_TYPE=%d FINGERPRINT=%s\n' % (self.algorithm,
+                                                                         self.fingerprint_type,
+                                                                         self.fingerprint))
+        f.write('%02x %02x %s\n' % (self.algorithm, self.fingerprint_type, self.fingerprint))
+
+class MINFO(RR):
+    '''Implements rendering MINFO RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - rmailbox (string): The rmailbox field.
+    - emailbox (string): The emailbox field.
+    These strings must be interpreted as a valid domain name.
+    '''
+    rmailbox = 'rmailbox.example.com'
+    emailbox = 'emailbox.example.com'
+    def dump(self, f):
+        rmailbox_wire = encode_name(self.rmailbox)
+        emailbox_wire = encode_name(self.emailbox)
+        if self.rdlen is None:
+            self.rdlen = (len(rmailbox_wire) + len(emailbox_wire)) / 2
+        else:
+            self.rdlen = int(self.rdlen)
+        self.dump_header(f, self.rdlen)
+        f.write('# RMAILBOX=%s EMAILBOX=%s\n' % (self.rmailbox, self.emailbox))
+        f.write('%s %s\n' % (rmailbox_wire, emailbox_wire))
+
+class AFSDB(RR):
+    '''Implements rendering AFSDB RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - subtype (16 bit int): The subtype field.
+    - server (string): The server field.
+    The string must be interpreted as a valid domain name.
+    '''
+    subtype = 1
+    server = 'afsdb.example.com'
+    def dump(self, f):
+        server_wire = encode_name(self.server)
+        if self.rdlen is None:
+            self.rdlen = 2 + len(server_wire) / 2
+        else:
+            self.rdlen = int(self.rdlen)
+        self.dump_header(f, self.rdlen)
+        f.write('# SUBTYPE=%d SERVER=%s\n' % (self.subtype, self.server))
+        f.write('%04x %s\n' % (self.subtype, server_wire))
+
+class NSECBASE(RR):
+    '''Implements rendering NSEC/NSEC3 type bitmaps commonly used for
+    these RRs.  The NSEC and NSEC3 classes will be inherited from this
+    class.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - nbitmap (int): The number of type bitmaps.
+    The following three define the bitmaps.  If suffixed with "N"
+    (0 <= N < nbitmaps), it means the definition for the N-th bitmap.
+    If there is no suffix (e.g., just "block", it means the default
+    for any unspecified values)
+    - block[N] (8-bit int): The Window Block.
+    - maplen[N] (8-bit int): The Bitmap Length.  The default "maplen"
+      can also be unspecified (with being set to None), in which case
+      the corresponding length will be calculated from the bitmap.
+    - bitmap[N] (string): The Bitmap.  This must be the hexadecimal
+      representation of the bitmap field.  For example, for a bitmap
+      where the 7th and 15th bits (and only these bits) are set, it
+      must be '0101'.  Note also that the value must be quated with
+      single quatations because it could also be interpreted as an
+      integer.
+    '''
+    nbitmap = 1                 # number of bitmaps
+    block = 0
+    maplen = None              # default bitmap length, auto-calculate
+    bitmap = '040000000003'     # an arbtrarily chosen bitmap sample
+    def dump(self, f):
+        # first, construct the bitmpa data
+        block_list = []
+        maplen_list = []
+        bitmap_list = []
+        for i in range(0, self.nbitmap):
+            key_bitmap = 'bitmap' + str(i)
+            if key_bitmap in self.__dict__:
+                bitmap_list.append(self.__dict__[key_bitmap])
+            else:
+                bitmap_list.append(self.bitmap)
+            key_maplen = 'maplen' + str(i)
+            if key_maplen in self.__dict__:
+                maplen_list.append(self.__dict__[key_maplen])
+            else:
+                maplen_list.append(self.maplen)
+            if maplen_list[-1] is None: # calculate it if not specified
+                maplen_list[-1] = int(len(bitmap_list[-1]) / 2)
+            key_block = 'block' + str(i)
+            if key_block in self.__dict__:
+               block_list.append(self.__dict__[key_block])
+            else:
+                block_list.append(self.block)
+
+        # dump RR-type specific part (NSEC or NSEC3)
+        self.dump_fixedpart(f, 2 * self.nbitmap + \
+                                int(len(''.join(bitmap_list)) / 2))
+
+        # dump the bitmap
+        for i in range(0, self.nbitmap):
+            f.write('# Bitmap: Block=%d, Length=%d\n' %
+                    (block_list[i], maplen_list[i]))
+            f.write('%02x %02x %s\n' %
+                    (block_list[i], maplen_list[i], bitmap_list[i]))
+
+class NSEC(NSECBASE):
+    '''Implements rendering NSEC RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - Type bitmap related parameters: see class NSECBASE
+    - nextname (string): The Next Domain Name field.  The string must be
+      interpreted as a valid domain name.
+    '''
+
+    nextname = 'next.example.com'
+    def dump_fixedpart(self, f, bitmap_totallen):
+        name_wire = encode_name(self.nextname)
+        if self.rdlen is None:
+            # if rdlen needs to be calculated, it must be based on the bitmap
+            # length, because the configured maplen can be fake.
+            self.rdlen = int(len(name_wire) / 2) + bitmap_totallen
+        self.dump_header(f, self.rdlen)
+        f.write('# Next Name=%s (%d bytes)\n' % (self.nextname,
+                                                 int(len(name_wire) / 2)))
+        f.write('%s\n' % name_wire)
+
+class NSEC3PARAM(RR):
+    '''Implements rendering NSEC3PARAM RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - hashalg (8-bit int): The Hash Algorithm field.  Note that
+      currently the only defined algorithm is SHA-1, for which a value
+      of 1 will be used, and it's the default.  So this implementation
+      does not support any string representation right now.
+    - optout (bool): The Opt-Out flag of the Flags field.
+    - mbz (7-bit int): The rest of the Flags field.  This value will
+      be left shifted for 1 bit and then OR-ed with optout to
+      construct the complete Flags field.
+    - iterations (16-bit int): The Iterations field.
+    - saltlen (int): The Salt Length field.
+    - salt (string): The Salt field.  It is converted to a sequence of
+      ascii codes and its hexadecimal representation will be used.
+    '''
+
+    hashalg = 1                 # SHA-1
+    optout = False              # opt-out flag
+    mbz = 0                     # other flag fields (none defined yet)
+    iterations = 1
+    saltlen = 5
+    salt = 's' * saltlen
+
+    def dump(self, f):
+        if self.rdlen is None:
+            self.rdlen = 4 + 1 + len(self.salt)
+        self.dump_header(f, self.rdlen)
+        self._dump_params(f)
+
+    def _dump_params(self, f):
+        '''This method is intended to be shared with NSEC3 class.
+
+        '''
+
+        optout_val = 1 if self.optout else 0
+        f.write('# Hash Alg=%s, Opt-Out=%d, Other Flags=%0x, Iterations=%d\n' %
+                (code_totext(self.hashalg, rdict_nsec3_algorithm),
+                 optout_val, self.mbz, self.iterations))
+        f.write('%02x %02x %04x\n' %
+                (self.hashalg, (self.mbz << 1) | optout_val, self.iterations))
+        f.write("# Salt Len=%d, Salt='%s'\n" % (self.saltlen, self.salt))
+        f.write('%02x%s%s\n' % (self.saltlen,
+                                ' ' if len(self.salt) > 0 else '',
+                                encode_string(self.salt)))
+
+class NSEC3(NSECBASE, NSEC3PARAM):
+    '''Implements rendering NSEC3 RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - Type bitmap related parameters: see class NSECBASE
+    - Hash parameter related parameters: see class NSEC3PARAM
+    - hashlen (int): The Hash Length field.
+    - hash (string): The Next Hashed Owner Name field.  This parameter
+      is interpreted as "salt".
+    '''
+
+    hashlen = 20
+    hash = 'h' * hashlen
+    def dump_fixedpart(self, f, bitmap_totallen):
+        if self.rdlen is None:
+            # if rdlen needs to be calculated, it must be based on the bitmap
+            # length, because the configured maplen can be fake.
+            self.rdlen = 4 + 1 + len(self.salt) + 1 + len(self.hash) \
+                + bitmap_totallen
+        self.dump_header(f, self.rdlen)
+        self._dump_params(f)
+        f.write("# Hash Len=%d, Hash='%s'\n" % (self.hashlen, self.hash))
+        f.write('%02x%s%s\n' % (self.hashlen,
+                                ' ' if len(self.hash) > 0 else '',
+                                encode_string(self.hash)))
+
+class RRSIG(RR):
+    '''Implements rendering RRSIG RDATA in the test data format.
+
+    Configurable parameters are as follows (see the description of the
+    same name of attribute for the default value):
+    - covered (int or string): The Type Covered field.  If specified
+      as an integer, it must be the 16-bit RR type value of the
+      covered type.  If specifed as a string, it must be the textual
+      mnemonic of the type.
+    - algorithm (int or string): The Algorithm field.   If specified
+      as an integer, it must be the 8-bit algorithm number as defined
+      in RFC4034.  If specifed as a string, it must be one of the keys
+      of dict_algorithm (case insensitive).
+    - labels (int): The Labels field.  If omitted (the corresponding
+      variable being set to None), the number of labels of "signer"
+      (excluding the trailing null label as specified in RFC4034) will
+      be used.
+    - originalttl (32-bit int): The Original TTL field.
+    - expiration (32-bit int): The Expiration TTL field.
+    - inception (32-bit int): The Inception TTL field.
+    - tag (16-bit int): The Key Tag field.
+    - signer (string): The Signer's Name field.  The string must be
+      interpreted as a valid domain name.
+    - signature (int): The Signature field.  Right now only a simple
+      integer form is supported.  A prefix of "0" will be prepended if
+      the resulting hexadecimal representation consists of an odd
+      number of characters.
+    '''
+
+    covered = 'A'
+    algorithm = 'RSASHA1'
+    labels = None                 # auto-calculate (#labels of signer)
+    originalttl = 3600
+    expiration = int(time.mktime(datetime.strptime('20100131120000',
+                                                   dnssec_timefmt).timetuple()))
+    inception = int(time.mktime(datetime.strptime('20100101120000',
+                                                  dnssec_timefmt).timetuple()))
+    tag = 0x1035
+    signer = 'example.com'
+    signature = 0x123456789abcdef123456789abcdef
+
+    def dump(self, f):
+        name_wire = encode_name(self.signer)
+        sig_wire = '%x' % self.signature
+        if len(sig_wire) % 2 != 0:
+            sig_wire = '0' + sig_wire
+        if self.rdlen is None:
+            self.rdlen = int(18 + len(name_wire) / 2 + len(str(sig_wire)) / 2)
+        self.dump_header(f, self.rdlen)
+
+        if type(self.covered) is str:
+            self.covered = dict_rrtype[self.covered.lower()]
+        if type(self.algorithm) is str:
+            self.algorithm = dict_algorithm[self.algorithm.lower()]
+        if self.labels is None:
+            self.labels = count_namelabels(self.signer)
+        f.write('# Covered=%s Algorithm=%s Labels=%d OrigTTL=%d\n' %
+                (code_totext(self.covered, rdict_rrtype),
+                 code_totext(self.algorithm, rdict_algorithm), self.labels,
+                 self.originalttl))
+        f.write('%04x %02x %02x %08x\n' % (self.covered, self.algorithm,
+                                           self.labels, self.originalttl))
+        f.write('# Expiration=%s, Inception=%s\n' %
+                (str(self.expiration), str(self.inception)))
+        f.write('%08x %08x\n' % (self.expiration, self.inception))
+        f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
+        f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
+
+class TSIG(RR):
+    '''Implements rendering TSIG RDATA in the test data format.
+
+    As a meta RR type TSIG uses some non common parameters.  This
+    class overrides some of the default attributes of the RR class
+    accordingly:
+    - rr_class is set to 'ANY'
+    - rr_ttl is set to 0
+    Like other derived classes these can be overridden via the spec
+    file.
+
+    Other configurable parameters are as follows (see the description
+    of the same name of attribute for the default value):
+    - algorithm (string): The Algorithm Name field.  The value is
+      generally interpreted as a domain name string, and will
+      typically be one of the standard algorithm names defined in
+      RFC4635.  For convenience, however, a shortcut value "hmac-md5"
+      is allowed instead of the standard "hmac-md5.sig-alg.reg.int".
+    - time_signed (48-bit int): The Time Signed field.
+    - fudge (16-bit int): The Fudge field.
+    - mac_size (int): The MAC Size field.  If omitted, the common value
+      determined by the algorithm will be used.
+    - mac (int or string): The MAC field.  If specified as an integer,
+      the integer value is used as the MAC, possibly with prepended
+      0's so that the total length will be mac_size.  If specifed as a
+      string, it is converted to a sequence of ascii codes and its
+      hexadecimal representation will be used.  So, for example, if
+      "mac" is set to 'abc', it will be converted to '616263'.  Note
+      that in this case the length of "mac" may not be equal to
+      mac_size.  If unspecified, the mac_size number of '78' (ascii
+      code of 'x') will be used.
+    - original_id (16-bit int): The Original ID field.
+    - error (16-bit int): The Error field.
+    - other_len (int): The Other Len field.
+    - other_data (int or string): The Other Data field.  This is
+      interpreted just like "mac" except that other_len is used
+      instead of mac_size.  If unspecified this will be empty unless
+      the "error" is set to 18 (which means the "BADTIME" error), in
+      which case a hexadecimal representation of "time_signed + fudge
+      + 1" will be used.
+    '''
+
+    algorithm = 'hmac-sha256'
+    time_signed = 1286978795    # arbitrarily chosen default
+    fudge = 300
+    mac_size = None             # use a common value for the algorithm
+    mac = None                  # use 'x' * mac_size
+    original_id = 2845          # arbitrarily chosen default
+    error = 0
+    other_len = None         # 6 if error is BADTIME; otherwise 0
+    other_data = None        # use time_signed + fudge + 1 for BADTIME
+    dict_macsize = { 'hmac-md5' : 16, 'hmac-sha1' : 20, 'hmac-sha256' : 32 }
+
+    # TSIG has some special defaults
+    def __init__(self):
+        super().__init__()
+        self.rr_class = 'ANY'
+        self.rr_ttl = 0
+
+    def dump(self, f):
+        if str(self.algorithm) == 'hmac-md5':
+            name_wire = encode_name('hmac-md5.sig-alg.reg.int')
+        else:
+            name_wire = encode_name(self.algorithm)
+        mac_size = self.mac_size
+        if mac_size is None:
+            if self.algorithm in self.dict_macsize.keys():
+                mac_size = self.dict_macsize[self.algorithm]
+            else:
+                raise RuntimeError('TSIG Mac Size cannot be determined')
+        mac = encode_string('x' * mac_size) if self.mac is None else \
+            encode_string(self.mac, mac_size)
+        other_len = self.other_len
+        if other_len is None:
+            # 18 = BADTIME
+            other_len = 6 if self.error == 18 else 0
+        other_data = self.other_data
+        if other_data is None:
+            other_data = '%012x' % (self.time_signed + self.fudge + 1) \
+                if self.error == 18 else ''
+        else:
+            other_data = encode_string(self.other_data, other_len)
+        if self.rdlen is None:
+            self.rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \
+                                 len(other_data) / 2)
+        self.dump_header(f, self.rdlen)
+        f.write('# Algorithm=%s Time-Signed=%d Fudge=%d\n' %
+                (self.algorithm, self.time_signed, self.fudge))
+        f.write('%s %012x %04x\n' % (name_wire, self.time_signed, self.fudge))
+        f.write('# MAC Size=%d MAC=(see hex)\n' % mac_size)
+        f.write('%04x%s\n' % (mac_size, ' ' + mac if len(mac) > 0 else ''))
+        f.write('# Original-ID=%d Error=%d\n' % (self.original_id, self.error))
+        f.write('%04x %04x\n' %  (self.original_id, self.error))
+        f.write('# Other-Len=%d Other-Data=(see hex)\n' % other_len)
+        f.write('%04x%s\n' % (other_len,
+                              ' ' + other_data if len(other_data) > 0 else ''))
+
+# Build section-class mapping
+config_param = { 'name' : (Name, {}),
+                 'header' : (DNSHeader, header_xtables),
+                 'question' : (DNSQuestion, question_xtables),
+                 'edns' : (EDNS, {}) }
+for rrtype in dict_rrtype.keys():
+    # For any supported RR types add the tuple of (RR_CLASS, {}).
+    # We expect KeyError as not all the types are supported, and simply
+    # ignore them.
+    try:
+        cur_mod = sys.modules[__name__]
+        config_param[rrtype] = (cur_mod.__dict__[rrtype.upper()], {})
+    except KeyError:
+        pass
+
+def get_config_param(section):
+    s = section
+    m = re.match('^([^:]+)/\d+$', section)
+    if m:
+        s = m.group(1)
+    return config_param[s]
+
+usage = '''usage: %prog [options] input_file'''
+
+if __name__ == "__main__":
+    parser = OptionParser(usage=usage)
+    parser.add_option('-o', '--output', action='store', dest='output',
+                      default=None, metavar='FILE',
+                      help='output file name [default: prefix of input_file]')
+    (options, args) = parser.parse_args()
+
+    if len(args) == 0:
+        parser.error('input file is missing')
+    configfile = args[0]
+
+    outputfile = options.output
+    if not outputfile:
+        m = re.match('(.*)\.[^.]+$', configfile)
+        if m:
+            outputfile = m.group(1)
+        else:
+            raise ValueError('output file is not specified and input file is not in the form of "output_file.suffix"')
+
+    config = configparser.SafeConfigParser()
+    config.read(configfile)
+
+    output = open(outputfile, 'w')
+
+    print_header(output, configfile)
+
+    # First try the 'custom' mode; if it fails assume the query mode.
+    try:
+        sections = config.get('custom', 'sections').split(':')
+    except configparser.NoSectionError:
+        sections = ['header', 'question', 'edns']
+
+    for s in sections:
+        section_param = get_config_param(s)
+        (obj, xtables) = (section_param[0](), section_param[1])
+        if get_config(config, s, obj, xtables):
+            obj.dump(output)
+
+    output.close()
diff --git a/src/lib/util/python/mkpywrapper.py.win32 b/src/lib/util/python/mkpywrapper.py.win32
new file mode 100755
index 0000000..8761ad5
--- /dev/null
+++ b/src/lib/util/python/mkpywrapper.py.win32
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+
+# Copyright (C) 2011  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""This utility program generates a C++ header and implementation files
+that can be used as a template of C++ python binding for a C++ class.
+
+Usage: ./mkpywrapper.py ClassName
+(the script should be run on this directory)
+
+It will generate two files: classname_python.h and classname_python.cc,
+many of whose definitions are in the namespace isc::MODULE_NAME::python.
+By default MODULE_NAME will be 'dns' (because this tool is originally
+intended to be used for the C++ python binding of the DNS library), but
+can be changed via the -m command line option.
+
+The generated files contain code fragments that are commonly used in
+C++ python binding implementations.  It will define a class named
+s_ClassName which is a derived class of PyModule and can meet the
+requirement of the CPPPyObjectContainer template class (see
+pycppwrapper_util.h).  It also defines (and declares in the header file)
+"classname_type", which is of PyTypeObject and is intended to be used
+to define details of the python bindings for the ClassName class.
+
+In many cases the header file can be used as a startpoint of the
+binding development without modification.  But you may want to make
+ClassName::cppobj a constant variable (and you should if you can).
+Many definitions of classname_python.cc should also be able to be used
+just as defined, but some will need to be changed or removed.  In
+particular, you should at least adjust ClassName_init().  You'll
+probably also need to add more definitions to that file to provide
+complete features of the C++ class.
+"""
+
+import datetime, string, sys
+from optparse import OptionParser
+
+# Remember the current year to produce the copyright boilerplate
+YEAR = datetime.date.today().timetuple()[0]
+
+def dump_file(out_file, temp_file, class_name, module):
+    for line in temp_file.readlines():
+        line = line.replace("@YEAR@", str(YEAR))
+        line = line.replace("@CPPCLASS at _H", class_name.upper() + "_H")
+        line = line.replace("@CPPCLASS@", class_name)
+        line = line.replace("@cppclass@", class_name.lower())
+        line = line.replace("@MODULE@", module)
+        out_file.write(line)
+
+def dump_wrappers(class_name, output, module):
+    try:
+        if output == "-":
+            header_file = sys.stdout
+        else:
+            header_file = open(output + "_python.h", "w")
+        header_template_file = open("wrapper_template.h", "r")
+        if output == "-":
+            impl_file = sys.stdout
+        else:
+            impl_file = open(output + "_python.cc", "w")
+        impl_template_file = open("wrapper_template.cc", "r")
+    except:
+        sys.stderr.write('Failed to open C++ file(s)\n')
+        sys.exit(1)
+    dump_file(header_file, header_template_file, class_name, module)
+    dump_file(impl_file, impl_template_file, class_name, module)
+
+usage = '''usage: %prog [options] class_name'''
+
+if __name__ == "__main__":
+    parser = OptionParser(usage=usage)
+    parser.add_option('-o', '--output', action='store', dest='output',
+                      default=None, metavar='FILE',
+                      help='prefix of output file names [default: derived from the class name]')
+    parser.add_option('-m', '--module', action='store', dest='module',
+                      default='dns',
+                      help='C++ module name of the wrapper (for namespaces) [default: dns]')
+    (options, args) = parser.parse_args()
+
+    if len(args) == 0:
+        parser.error('input file is missing')
+
+    class_name = args[0]
+    if not options.output:
+        options.output = class_name.lower()
+
+    dump_wrappers(class_name, options.output, options.module)
diff --git a/src/lib/util/pyunittests/pyunittests_util.py.win32 b/src/lib/util/pyunittests/pyunittests_util.py.win32
new file mode 100644
index 0000000..d5113bf
--- /dev/null
+++ b/src/lib/util/pyunittests/pyunittests_util.py.win32
@@ -0,0 +1,6 @@
+"""fake pyunittests_util module"""
+
+import pydnspp
+
+fix_current_time = pydnspp.fix_current_time
+
diff --git a/src/lib/util/random/qid_gen.cc b/src/lib/util/random/qid_gen.cc
index 43041ad..88c4f1d 100644
--- a/src/lib/util/random/qid_gen.cc
+++ b/src/lib/util/random/qid_gen.cc
@@ -18,9 +18,18 @@
 // (and other parts where we need randomness, perhaps another thing
 // for a general libutil?)
 
+#define ISC_LIBUTIL_EXPORT
+
+#include <config.h>
+#include <stdint.h>
+
 #include <util/random/qid_gen.h>
 
+#ifdef _WIN32
+#include <time.h>
+#else
 #include <sys/time.h>
+#endif
 
 namespace isc {
 namespace util {
@@ -41,9 +50,15 @@ QidGenerator::QidGenerator() : dist_(0, 65535),
 
 void
 QidGenerator::seed() {
+#ifdef _WIN32
+    FILETIME now;
+    GetSystemTimeAsFileTime(&now);
+    generator_.seed(now.dwLowDateTime + now.dwHighDateTime);
+#else
     struct timeval tv;
     gettimeofday(&tv, 0);
     generator_.seed((tv.tv_sec * 1000000) + tv.tv_usec);
+#endif
 }
 
 uint16_t
diff --git a/src/lib/util/random/qid_gen.h b/src/lib/util/random/qid_gen.h
index 1af43c1..b4dd2ff 100644
--- a/src/lib/util/random/qid_gen.h
+++ b/src/lib/util/random/qid_gen.h
@@ -25,6 +25,8 @@
 #include <boost/random/uniform_int.hpp>
 #include <boost/random/variate_generator.hpp>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 namespace random {
@@ -36,7 +38,7 @@ namespace random {
 ///
 /// It automatically seeds it with the current time when it is first
 /// used.
-class QidGenerator {
+class ISC_LIBUTIL_API QidGenerator {
 public:
     /// \brief Returns the singleton instance of the QidGenerator
     ///
diff --git a/src/lib/util/random/random_number_generator.h b/src/lib/util/random/random_number_generator.h
index 485ea7a..c2a57e8 100644
--- a/src/lib/util/random/random_number_generator.h
+++ b/src/lib/util/random/random_number_generator.h
@@ -26,23 +26,25 @@
 #include <boost/random/uniform_real.hpp>
 #include <boost/random/variate_generator.hpp>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 namespace random {
 
-class InvalidLimits : public isc::BadValue {
+class ISC_LIBUTIL_API InvalidLimits : public isc::BadValue {
 public:
     InvalidLimits(const char* file, size_t line, const char* what) :
         isc::BadValue(file, line, what) {}
 };
 
-class SumNotOne : public isc::BadValue {
+class ISC_LIBUTIL_API SumNotOne : public isc::BadValue {
 public:
     SumNotOne(const char* file, size_t line, const char* what) :
         isc::BadValue(file, line, what) {}
 };
 
-class InvalidProbValue : public isc::BadValue {
+class ISC_LIBUTIL_API InvalidProbValue : public isc::BadValue {
 public:
     InvalidProbValue(const char* file, size_t line, const char* what) :
         isc::BadValue(file, line, what) {}
@@ -53,7 +55,7 @@ public:
 /// \brief Uniform random integer generator
 ///
 /// Generate uniformly distributed integers in range of [min, max]
-class UniformRandomIntegerGenerator{
+class ISC_LIBUTIL_API UniformRandomIntegerGenerator{
 public:
     /// \brief Constructor
     ///
@@ -92,7 +94,7 @@ private:
 /// \brief Weighted random integer generator
 ///
 /// Generate random integers according different probabilities
-class WeightedRandomIntegerGenerator {
+class ISC_LIBUTIL_API WeightedRandomIntegerGenerator {
 public:
     /// \brief Constructor
     ///
diff --git a/src/lib/util/range_utilities.h b/src/lib/util/range_utilities.h
index 3f8b971..d4a1e9b 100644
--- a/src/lib/util/range_utilities.h
+++ b/src/lib/util/range_utilities.h
@@ -18,6 +18,8 @@
 #include <stdlib.h>
 #include <algorithm>
 
+#include <util/lib.h>
+
 // This header contains useful methods for conduction operations on
 // a range of container elements. Currently the collection is limited,
 // but it is expected to grow.
diff --git a/src/lib/util/strutil.cc b/src/lib/util/strutil.cc
index 89edcc9..350fea6 100644
--- a/src/lib/util/strutil.cc
+++ b/src/lib/util/strutil.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
 #include <numeric>
 
 #include <string.h>
diff --git a/src/lib/util/strutil.h b/src/lib/util/strutil.h
index 0dbbe96..b180cc2 100644
--- a/src/lib/util/strutil.h
+++ b/src/lib/util/strutil.h
@@ -23,6 +23,8 @@
 #include <exceptions/exceptions.h>
 #include <boost/lexical_cast.hpp>
 
+#include <util/lib.h>
+
 namespace isc {
 namespace util {
 namespace str {
@@ -33,7 +35,7 @@ namespace str {
 /// \brief A standard string util exception that is thrown if getToken or
 /// numToToken are called with bad input data
 ///
-class StringTokenError : public Exception {
+class ISC_LIBUTIL_API StringTokenError : public Exception {
 public:
     StringTokenError(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -47,7 +49,7 @@ public:
 /// if not the command line).
 ///
 /// \param name Name to be substituted
-void normalizeSlash(std::string& name);
+ISC_LIBUTIL_API void normalizeSlash(std::string& name);
 
 
 /// \brief Trim Leading and Trailing Spaces
@@ -85,6 +87,7 @@ std::string trim(const std::string& instring);
 /// \param delim Delimiter characters
 ///
 /// \return Vector of tokens.
+ISC_LIBUTIL_API
 std::vector<std::string> tokens(const std::string& text,
         const std::string& delim = std::string(" \t\n"));
 
@@ -162,7 +165,7 @@ std::string format(const std::string& format,
 /// \param iss stringstream to read one token from
 ///
 /// \return the first token read from the stringstream
-std::string getToken(std::istringstream& iss);
+ISC_LIBUTIL_API std::string getToken(std::istringstream& iss);
 
 /// \brief Converts a string token to an *unsigned* integer.
 ///
diff --git a/src/lib/util/tests/buffer_unittest.cc b/src/lib/util/tests/buffer_unittest.cc
index 9af3d57..2d5a2b7 100644
--- a/src/lib/util/tests/buffer_unittest.cc
+++ b/src/lib/util/tests/buffer_unittest.cc
@@ -16,7 +16,7 @@
 
 #include <exceptions/exceptions.h>
 
-#ifdef EXPECT_DEATH
+#if defined(EXPECT_DEATH) && !defined(NO_EXPECT_DEATH)
 #include <util/unittests/resource.h>
 #endif /* EXPECT_DEATH */
 
@@ -186,7 +186,7 @@ TEST_F(BufferTest, outputBufferReadat) {
     for (int i = 0; i < sizeof(testdata); i ++) {
         EXPECT_EQ(testdata[i], obuffer[i]);
     }
-#ifdef EXPECT_DEATH
+#if defined(EXPECT_DEATH) && !defined(NO_EXPECT_DEATH)
     // We use assert now, so we check it dies
     EXPECT_DEATH({
         isc::util::unittests::dontCreateCoreDumps();
diff --git a/src/lib/util/tests/fd_tests.cc b/src/lib/util/tests/fd_tests.cc
index 6ba2766..42a61f5 100644
--- a/src/lib/util/tests/fd_tests.cc
+++ b/src/lib/util/tests/fd_tests.cc
@@ -18,6 +18,10 @@
 
 #include <gtest/gtest.h>
 
+#ifdef _WIN32
+#define close(x) _close(x)
+#endif
+
 using namespace isc::util::io;
 using namespace isc::util::unittests;
 
diff --git a/src/lib/util/tests/io_utilities_unittest.cc b/src/lib/util/tests/io_utilities_unittest.cc
index 4293c7e..c509e2c 100644
--- a/src/lib/util/tests/io_utilities_unittest.cc
+++ b/src/lib/util/tests/io_utilities_unittest.cc
@@ -19,7 +19,11 @@
 
 #include <cstddef>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <arpa/inet.h>
+#endif
 #include <gtest/gtest.h>
 
 #include <util/buffer.h>
diff --git a/src/lib/util/tests/qid_gen_unittest.cc b/src/lib/util/tests/qid_gen_unittest.cc
index 60c81ae..e4ccfaf 100644
--- a/src/lib/util/tests/qid_gen_unittest.cc
+++ b/src/lib/util/tests/qid_gen_unittest.cc
@@ -30,6 +30,8 @@
 /// \brief Test of QidGenerator
 ///
 
+#include <stdint.h>
+
 #include <gtest/gtest.h>
 
 #include <util/random/qid_gen.h>
diff --git a/src/lib/util/tests/random_number_generator_unittest.cc b/src/lib/util/tests/random_number_generator_unittest.cc
index 23d5b88..fa0a6fc 100644
--- a/src/lib/util/tests/random_number_generator_unittest.cc
+++ b/src/lib/util/tests/random_number_generator_unittest.cc
@@ -14,6 +14,8 @@
 
 #include <config.h>
 
+#include <time.h>
+
 #include <gtest/gtest.h>
 #include <boost/shared_ptr.hpp>
 
@@ -23,6 +25,13 @@
 
 #include <util/random/random_number_generator.h>
 
+#if defined(_WIN32) && defined(min)
+#undef min
+#endif
+#if defined(_WIN32) && defined(max)
+#undef max
+#endif
+
 namespace isc {
 namespace util {
 namespace random {
diff --git a/src/lib/util/tests/range_utilities_unittest.cc b/src/lib/util/tests/range_utilities_unittest.cc
index 6fa1c64..9ae2d65 100644
--- a/src/lib/util/tests/range_utilities_unittest.cc
+++ b/src/lib/util/tests/range_utilities_unittest.cc
@@ -15,6 +15,9 @@
 #include <config.h>
 #include <stdint.h>
 #include <stdlib.h>
+#ifdef _WIN32
+#include <time.h>
+#endif
 
 #include <gtest/gtest.h>
 #include <vector>
diff --git a/src/lib/util/tests/run_unittests.cc b/src/lib/util/tests/run_unittests.cc
index 8789a9c..38a680a 100644
--- a/src/lib/util/tests/run_unittests.cc
+++ b/src/lib/util/tests/run_unittests.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <gtest/gtest.h>
 #include <util/unittests/run_all.h>
 #include <stdlib.h>
@@ -20,6 +22,11 @@ int
 main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
 
+#ifdef _WIN32
+    std::string vv("B10_LOCKFILE_DIR_FROM_BUILD=" TEST_DATA_TOPBUILDDIR);
+    _putenv(vv.c_str());
+#else
     setenv("B10_LOCKFILE_DIR_FROM_BUILD", TEST_DATA_TOPBUILDDIR, 1);
+#endif
     return (isc::util::unittests::run_all());
 }
diff --git a/src/lib/util/tests/socketsession_unittest.cc b/src/lib/util/tests/socketsession_unittest.cc
index e83c140..342279b 100644
--- a/src/lib/util/tests/socketsession_unittest.cc
+++ b/src/lib/util/tests/socketsession_unittest.cc
@@ -14,6 +14,9 @@
 
 #include <config.h>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -22,6 +25,7 @@
 #include <fcntl.h>
 #include <netdb.h>
 #include <unistd.h>
+#endif
 
 #include <cerrno>
 #include <cstring>
@@ -51,7 +55,11 @@ using namespace isc::util::io::internal;
 
 namespace {
 
+#ifdef _WIN32
+const char* const TEST_UNIX_FILE = "12345";
+#else
 const char* const TEST_UNIX_FILE = TEST_DATA_TOPBUILDDIR "/test.unix";
+#endif
 const char* const TEST_PORT = "53535";
 const char* const TEST_PORT2 = "53536"; // use this in case we need 2 ports
 const char TEST_DATA[] = "BIND10 test";
@@ -59,6 +67,24 @@ const char TEST_DATA[] = "BIND10 test";
 // A simple helper structure to automatically close test sockets on return
 // or exception in a RAII manner.  non copyable to prevent duplicate close.
 struct ScopedSocket : boost::noncopyable {
+#ifdef _WIN32
+    ScopedSocket() : fd(INVALID_SOCKET) {}
+    ScopedSocket(SOCKET sock) : fd(sock) {}
+    ~ScopedSocket() {
+        closeSocket();
+    }
+    void reset(SOCKET sock) {
+        closeSocket();
+        fd = sock;
+    }
+    SOCKET fd;
+private:
+    void closeSocket() {
+        if (fd != INVALID_SOCKET) {
+            closesocket(fd);
+        }
+    }
+#else
     ScopedSocket() : fd(-1) {}
     ScopedSocket(int sock) : fd(sock) {}
     ~ScopedSocket() {
@@ -75,10 +101,21 @@ private:
             close(fd);
         }
     }
+#endif
 };
 
 // A helper function that makes a test socket non block so that a certain
 // kind of test failure (such as missing send) won't cause hangup.
+#ifdef _WIN32
+void
+setNonBlock(SOCKET s, bool on) {
+    u_long nbio_flags = on ? 1 : 0;
+    if (ioctlsocket(s, FIONBIO, &nbio_flags) == SOCKET_ERROR) {
+        isc_throw(isc::Unexpected, "ioctl(FIONBIO) failed: " <<
+                  strerror(WSAGetLastError()));
+    }
+}
+#else
 void
 setNonBlock(int s, bool on) {
     int fcntl_flags = fcntl(s, F_GETFL, 0);
@@ -92,20 +129,39 @@ setNonBlock(int s, bool on) {
                   strerror(errno));
     }
 }
+#endif
 
 // A helper to impose some reasonable amount of wait on recv(from)
 // if possible.  It returns an option flag to be set for the system call
 // (when necessary).
 int
-setRecvDelay(int s) {
+#ifdef _WIN32
+setRecvDelay(SOCKET s)
+#else
+setRecvDelay(int s)
+#endif
+{
     const struct timeval timeo = { 10, 0 };
-    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)) == -1) {
+    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+                   (char *) &timeo, sizeof(timeo)) == -1) {
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 123
+#endif
         if (errno == ENOPROTOOPT) {
             // Workaround for Solaris: see recursive_query_unittest
+#ifdef _WIN32
+            return (/* MSG_DONTWAIT */ 0);
+#else
             return (MSG_DONTWAIT);
+#endif
         } else {
+#ifdef _WIN32
+            isc_throw(isc::Unexpected, "set RCVTIMEO failed: " <<
+                      strerror(WSAGetLastError()));
+#else
             isc_throw(isc::Unexpected, "set RCVTIMEO failed: " <<
                       strerror(errno));
+#endif
         }
     }
     return (0);
@@ -120,6 +176,7 @@ typedef pair<const struct sockaddr*, socklen_t> SockAddrInfo;
 // pair).  Its get method uses getaddrinfo(3) for the conversion and stores
 // the result in the addrinfo_list_ vector until the object is destructed.
 // The allocated resources will be automatically freed in an RAII manner.
+#ifndef _WIN32
 class SockAddrCreator {
 public:
     ~SockAddrCreator() {
@@ -849,4 +906,5 @@ TEST(SocketSessionTest, badValue) {
                                addr_creator.get("192.0.2.2", "5300").first,
                                NULL, sizeof(TEST_DATA)), BadValue);
 }
+#endif
 }
diff --git a/src/lib/util/time_utilities.cc b/src/lib/util/time_utilities.cc
index c756382..8b782f8 100644
--- a/src/lib/util/time_utilities.cc
+++ b/src/lib/util/time_utilities.cc
@@ -12,9 +12,15 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_EXPORT
+
+#include <config.h>
+
 #include <stdint.h>
 
+#ifndef _WIN32
 #include <sys/time.h>
+#endif
 
 #include <string>
 #include <iomanip>
@@ -117,10 +123,25 @@ gettimeWrapper() {
         return (gettimeFunction());
     }
 
+#ifdef _WIN32
+    SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
+    FILETIME temp;
+    SystemTimeToFileTime(&epoch, &temp);
+    ULARGE_INTEGER t;
+    t.LowPart = temp.dwLowDateTime;
+    t.HighPart = temp.dwHighDateTime;
+    FILETIME now;
+    GetSystemTimeAsFileTime(&now);
+    ULARGE_INTEGER n;
+    n.LowPart = now.dwLowDateTime;
+    n.HighPart = now.dwHighDateTime;
+    return (static_cast<int64_t>((n.QuadPart - t.QuadPart) / 10000000));
+#else
     struct timeval now;
     gettimeofday(&now, NULL);
 
     return (static_cast<int64_t>(now.tv_sec));
+#endif
 }
 }
 
diff --git a/src/lib/util/time_utilities.h b/src/lib/util/time_utilities.h
index a53089d..f8f6359 100644
--- a/src/lib/util/time_utilities.h
+++ b/src/lib/util/time_utilities.h
@@ -22,6 +22,8 @@
 
 #include <exceptions/exceptions.h>
 
+#include <util/lib.h>
+
 //
 // Note: this helper module isn't specific to the DNS protocol per se.
 // We should probably move this to somewhere else, possibly in some common
@@ -35,7 +37,7 @@ namespace util {
 /// \brief A standard DNS (or ISC) module exception that is thrown if 
 /// a time conversion function encounters bad input
 ///
-class InvalidTime : public Exception {
+class ISC_LIBUTIL_API InvalidTime : public Exception {
 public:
     InvalidTime(const char* file, size_t line, const char* what) :
         isc::Exception(file, line, what) {}
@@ -64,7 +66,7 @@ namespace detail {
 /// If the implementation doesn't need to be tested with faked current time,
 /// it should simply use the system supplied library function instead of
 /// this one.
-int64_t gettimeWrapper();
+ISC_LIBUTIL_API int64_t gettimeWrapper();
 }
 
 ///
@@ -112,7 +114,7 @@ int64_t gettimeWrapper();
 ///
 /// \param time_txt Textual time in the form of YYYYMMDDHHmmSS
 /// \return Seconds since epoch corresponding to \c time_txt
-uint64_t
+ISC_LIBUTIL_API uint64_t
 timeFromText64(const std::string& time_txt);
 
 /// Convert textual DNSSEC time to integer, 32-bit version.
@@ -120,7 +122,7 @@ timeFromText64(const std::string& time_txt);
 /// This version is the same as \c timeFromText64() except that the return
 /// value is wrapped around to an unsigned 32-bit integer, simply dropping
 /// the upper 32 bits.
-uint32_t
+ISC_LIBUTIL_API uint32_t
 timeFromText32(const std::string& time_txt);
 
 /// Convert integral DNSSEC time to textual form, 64-bit version.
@@ -137,7 +139,7 @@ timeFromText32(const std::string& time_txt);
 ///
 /// \param value Seconds since epoch to be converted.
 /// \return Textual representation of \c value in the form of YYYYMMDDHHmmSS.
-std::string
+ISC_LIBUTIL_API std::string
 timeToText64(uint64_t value);
 
 /// Convert integral DNSSEC time to textual form, 32-bit version.
@@ -159,7 +161,7 @@ timeToText64(uint64_t value);
 /// half of the 32-bit values are treated as a future time.  For example,
 /// 2^32-1 (the highest value in 32-bit unsigned integers) will be converted
 /// to "21060207062815", instead of "19691231235959".
-std::string
+ISC_LIBUTIL_API std::string
 timeToText32(const uint32_t value);
 
 //@}
diff --git a/src/lib/util/unittests/fork.cc b/src/lib/util/unittests/fork.cc
index 3414a3c..2c9e2db 100644
--- a/src/lib/util/unittests/fork.cc
+++ b/src/lib/util/unittests/fork.cc
@@ -12,10 +12,16 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_UNITTESTS_EXPORT
+
 #include "fork.h"
 
 #include <util/io/fd.h>
 
+#ifndef _WIN32
+
+/* Unix version */
+
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -143,3 +149,169 @@ check_output(int *write_pipe, const void *output, const size_t length)
 }
 }
 }
+
+#else
+
+/* WIN32 version (using thread: no fork()!) */
+
+#include <io.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <cerrno>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace isc::util::io;
+
+namespace isc {
+namespace util {
+namespace unittests {
+
+bool
+process_ok(pid_t process) {
+    HANDLE handle;
+
+    handle = OpenThread(PROCESS_ALL_ACCESS, FALSE, process);
+    if (handle == NULL)
+        return false;
+    // It is long, but if everything is OK, it'll not happen
+    DWORD result(WaitForSingleObject(handle, 10000));
+    if (result != 0) {
+        if (result == WAIT_FAILED)
+            TerminateThread(handle, SIGTERM);
+        CloseHandle(handle);
+        return false;
+    }
+    // Check what we found out
+    DWORD status;
+    result = GetExitCodeThread(handle, &status);
+    CloseHandle(handle);
+    return (result != 0) && (status == 0);
+}
+
+struct pichildargs {
+    HANDLE pipe;
+    const void *input;
+    const size_t length;
+    pichildargs(HANDLE pipe, const void *input, const size_t length) :
+    pipe(pipe), input(input), length(length)
+    {}
+private:
+    pichildargs& operator=(pichildargs const&);
+};
+
+DWORD WINAPI PIChildProc(void *childparam) {
+    pichildargs *args;
+
+    args = static_cast<pichildargs *>(childparam);
+    if (!write_data(_open_osfhandle((intptr_t)args->pipe, 0),
+                    args->input, args->length)) {
+        delete args;
+        return 1;
+    } else {
+        CloseHandle(args->pipe);
+        delete args;
+        return 0;
+    }
+}
+
+/*
+ * This creates a pipe, forks and feeds the pipe with given data.
+ * Used to provide the input in non-blocking/asynchronous way.
+ */
+pid_t
+provide_input(int *read_pipe, const void *input, const size_t length)
+{
+    HANDLE hReadPipe, hWritePipe;
+    if (CreatePipe(&hReadPipe, &hWritePipe, NULL, 0) == 0) {
+        return -1;
+    }
+    *read_pipe = _open_osfhandle((intptr_t)hReadPipe, _O_RDONLY);
+
+    pichildargs *args = new pichildargs(hWritePipe, input, length);
+    DWORD pid;
+    if (CreateThread(NULL, 0, PIChildProc, args, 0, &pid) == NULL) {
+        CloseHandle(hReadPipe);
+        CloseHandle(hWritePipe);
+        return -1;
+    }
+    return (pid_t) pid;
+}
+
+struct cochildargs {
+    HANDLE pipe;
+    const void *output;
+    const size_t length;
+    cochildargs(HANDLE pipe, const void *output, const size_t length) :
+    pipe(pipe), output(output), length(length)
+    {}
+private:
+    cochildargs& operator=(cochildargs const&);
+};
+
+DWORD WINAPI COChildProc(void *childparam) {
+    cochildargs *args;
+
+    args = static_cast<cochildargs *>(childparam);
+    // We don't return the memory, but we're in tests and end this process
+    // right away.
+    unsigned char *buffer = new unsigned char[args->length + 1];
+    // Try to read one byte more to see if the output ends here
+    size_t got_length(read_data(_open_osfhandle((intptr_t)args->pipe,
+                                                _O_RDONLY),
+                                buffer, args->length + 1));
+    bool ok(true);
+    if (got_length != args->length) {
+        fprintf(stderr, "Different length (expected %u, got %u)\n",
+                static_cast<unsigned>(args->length),
+                static_cast<unsigned>(got_length));
+        ok = false;
+    }
+    if(!ok || memcmp(buffer, args->output, args->length)) {
+        const unsigned char *output_c(static_cast<const unsigned char *>(
+                args->output));
+        // If they differ, print what we have
+        for(size_t i(0); i != got_length; ++ i) {
+            fprintf(stderr, "%02hhx", buffer[i]);
+        }
+        fprintf(stderr, "\n");
+        for(size_t i(0); i != args->length; ++ i) {
+            fprintf(stderr, "%02hhx", output_c[i]);
+        }
+        fprintf(stderr, "\n");
+        delete args;
+        return 1;
+    } else
+        delete args;
+        return 0;
+}
+
+/*
+ * This creates a pipe, forks and reads the pipe and compares it
+ * with given data. Used to check output of run in asynchronous way.
+ */
+pid_t
+check_output(int *write_pipe, const void *output, const size_t length)
+{
+    HANDLE hReadPipe, hWritePipe;
+    if (CreatePipe(&hReadPipe, &hWritePipe, NULL, 0) == 0) {
+        return -1;
+    }
+    *write_pipe = _open_osfhandle((intptr_t)hWritePipe, 0);
+
+    cochildargs *args = new cochildargs(hReadPipe, output, length);
+    DWORD pid;
+    if (CreateThread(NULL, 0, COChildProc, args, 0, &pid) == NULL) {
+        CloseHandle(hReadPipe);
+        CloseHandle(hWritePipe);
+        return -1;
+    }
+    return (pid_t) pid;
+}
+
+}
+}
+}
+
+#endif
diff --git a/src/lib/util/unittests/fork.h b/src/lib/util/unittests/fork.h
index 3331cfa..164c308 100644
--- a/src/lib/util/unittests/fork.h
+++ b/src/lib/util/unittests/fork.h
@@ -15,7 +15,13 @@
 #ifndef __UTIL_UNITTESTS_FORK_H
 #define __UTIL_UNITTESTS_FORK_H 1
 
+#include <config.h>
+
+#ifndef _WIN32
 #include <unistd.h>
+#endif
+
+#include <util/unittests/lib.h>
 
 /**
  * @file fork.h
@@ -36,13 +42,13 @@ namespace unittests {
  * @return True if the process terminates with 0, false otherwise.
  * @param process The ID of process to wait for.
  */
-bool
+ISC_LIBUTIL_UNITTESTS_API bool
 process_ok(pid_t process);
 
-pid_t
+ISC_LIBUTIL_UNITTESTS_API pid_t
 provide_input(int *read_pipe, const void *input, const size_t length);
 
-pid_t
+ISC_LIBUTIL_UNITTESTS_API pid_t
 check_output(int *write_pipe, const void *output, const size_t length);
 
 } // End of the namespace
diff --git a/src/lib/util/unittests/lib.h b/src/lib/util/unittests/lib.h
new file mode 100644
index 0000000..afc2303
--- /dev/null
+++ b/src/lib/util/unittests/lib.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __LIBUTIL_UNITTESTS_H
+#define __LIBUTIL_UNITTESTS_H 1
+
+#if !defined(_WIN32) || defined(USE_STATIC_LINK)
+#define ISC_LIBUTIL_UNITTESTS_API
+#else
+#ifdef ISC_LIBUTIL_UNITTESTS_EXPORT
+#define ISC_LIBUTIL_UNITTESTS_API __declspec(dllexport)
+#else
+#defineISC_LIBUTIL_UNITTESTS_API __declspec(dllimport)
+#endif
+#endif
+
+#endif // __LIBUTIL_UNITTESTS_H
+
+// Local Variables: 
+// mode: c++
+// End: 
diff --git a/src/lib/util/unittests/mock_socketsession.h b/src/lib/util/unittests/mock_socketsession.h
index 8078265..5a56de0 100644
--- a/src/lib/util/unittests/mock_socketsession.h
+++ b/src/lib/util/unittests/mock_socketsession.h
@@ -27,6 +27,8 @@
 #include <sys/socket.h>
 #include <stdint.h>
 
+#include <util/unittests/lib.h>
+
 namespace isc {
 namespace util {
 namespace unittests {
@@ -36,7 +38,7 @@ namespace unittests {
 /// It emulates the behavior of SocketSessionForwarder without involving
 /// network communication, and allowing the tester to customize the behavior
 /// and to examine forwarded data afterwards.
-class MockSocketSessionForwarder :
+class ISC_LIBUTIL_UNITTESTS_API MockSocketSessionForwarder :
     public isc::util::io::BaseSocketSessionForwarder
 {
 public:
@@ -66,7 +68,13 @@ public:
     // so that the test code can check the values later via the getter
     // methods.  Complete deep copy will be created, so the caller doesn't
     // have to keep the parameters valid after the call to this method.
-    virtual void push(int sock, int family, int type, int protocol,
+    virtual void push(
+#ifdef _WIN32
+                      SOCKET sock,
+#else
+                      int sock,
+#endif
+                      int family, int type, int protocol,
                       const struct sockaddr& local_end,
                       const struct sockaddr& remote_end,
                       const void* data, size_t data_len)
@@ -116,7 +124,11 @@ public:
     // sense; it was originally filled with the binary image of another
     // sockaddr structure, and we are going to return the image opaquely
     // as a sockaddr structure without touching the data.
+#ifdef _WIN32
+    SOCKET getPushedSock() const { return (pushed_sock_); }
+#else
     int getPushedSock() const { return (pushed_sock_); }
+#endif
     int getPushedFamily() const { return (pushed_family_); }
     int getPushedType() const { return (pushed_type_); }
     int getPushedProtocol() const { return (pushed_protocol_); }
@@ -135,7 +147,11 @@ private:
     bool connect_ok_;
     bool push_ok_;
     bool close_ok_;
+#ifdef _WIN32
+    SOCKET pushed_sock_;
+#else
     int pushed_sock_;
+#endif
     int pushed_family_;
     int pushed_type_;
     int pushed_protocol_;
diff --git a/src/lib/util/unittests/newhook.cc b/src/lib/util/unittests/newhook.cc
index 9e545a5..7f12d8f 100644
--- a/src/lib/util/unittests/newhook.cc
+++ b/src/lib/util/unittests/newhook.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_UNITTESTS_EXPORT
+
 #include <stdlib.h>
 
 #include <new>
diff --git a/src/lib/util/unittests/newhook.h b/src/lib/util/unittests/newhook.h
index 7eb8ade..182d206 100644
--- a/src/lib/util/unittests/newhook.h
+++ b/src/lib/util/unittests/newhook.h
@@ -15,6 +15,8 @@
 #ifndef __UTIL_UNITTESTS_NEWHOOK_H
 #define __UTIL_UNITTESTS_NEWHOOK_H 1
 
+#include <util/unittests/lib.h>
+
 /**
  * @file newhook.h
  * @short Enable the use of special operator new that throws for testing.
@@ -57,7 +59,7 @@ namespace unittests {
 /// Switch to enable the use of special operator new
 ///
 /// This is set to \c false by default.
-extern bool force_throw_on_new;
+extern ISC_LIBUTIL_UNITTESTS_API bool force_throw_on_new;
 
 /// The allocation size that triggers an exception in the special operator new
 ///
@@ -70,7 +72,7 @@ extern bool force_throw_on_new;
 /// The default value is 0.  The value of this variable has no meaning
 /// unless the use of the special operator is enabled at build time and
 /// via \c force_throw_on_new.
-extern size_t throw_size_on_new;
+extern ISC_LIBUTIL_UNITTESTS_API size_t throw_size_on_new;
 }
 }
 }
diff --git a/src/lib/util/unittests/resolver.h b/src/lib/util/unittests/resolver.h
index 560a892..4b401d0 100644
--- a/src/lib/util/unittests/resolver.h
+++ b/src/lib/util/unittests/resolver.h
@@ -28,6 +28,8 @@
 #include <resolve/resolver_interface.h>
 #include <gtest/gtest.h>
 
+#include <util/unittests/lib.h>
+
 namespace isc {
 namespace util {
 namespace unittests {
@@ -49,7 +51,8 @@ createResponseMessage(isc::dns::RRsetPtr answer_rrset)
 /// This class pretends to be a resolver. However, it only stores the
 /// requests and can answer them right away by prepared answers. It doesn't
 /// do any real work and is intended for testing purposes.
-class TestResolver : public isc::resolve::ResolverInterface {
+class ISC_LIBUTIL_UNITTESTS_API TestResolver :
+ public isc::resolve::ResolverInterface {
     private:
         bool checkIndex(size_t index) {
             return (requests.size() > index);
diff --git a/src/lib/util/unittests/resource.cc b/src/lib/util/unittests/resource.cc
index 3e77e0d..15f0462 100644
--- a/src/lib/util/unittests/resource.cc
+++ b/src/lib/util/unittests/resource.cc
@@ -12,12 +12,18 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_UNITTESTS_EXPORT
+
+#include <config.h>
+
 #include "resource.h"
 
 #include <gtest/gtest.h>
 
+#ifndef _WIN32
 #include <sys/time.h>
 #include <sys/resource.h>
+#endif
 
 namespace isc {
 namespace util {
@@ -25,9 +31,11 @@ namespace unittests {
 
 void
 dontCreateCoreDumps() {
+#ifndef _WIN32
     const rlimit core_limit = {0, 0};
 
     EXPECT_EQ(setrlimit(RLIMIT_CORE, &core_limit), 0);
+#endif
 }
 
 } // end of namespace unittests
diff --git a/src/lib/util/unittests/resource.h b/src/lib/util/unittests/resource.h
index 6430ab2..9456fa7 100644
--- a/src/lib/util/unittests/resource.h
+++ b/src/lib/util/unittests/resource.h
@@ -15,6 +15,8 @@
 #ifndef __UTIL_UNITTESTS_RESOURCE_H
 #define __UTIL_UNITTESTS_RESOURCE_H 1
 
+#include <util/unittests/lib.h>
+
 namespace isc {
 namespace util {
 namespace unittests {
@@ -26,7 +28,7 @@ namespace unittests {
 /// is used, where processes abort (and create cores in the process).
 /// As a new process is forked to run EXPECT_DEATH tests, the rlimits of
 /// the parent process that runs the other tests should be unaffected.
-void dontCreateCoreDumps();
+ISC_LIBUTIL_UNITTESTS_API void dontCreateCoreDumps();
 
 } // end of namespace unittests
 } // end of namespace util
diff --git a/src/lib/util/unittests/run_all.cc b/src/lib/util/unittests/run_all.cc
index 5f50f77..5d57e68 100644
--- a/src/lib/util/unittests/run_all.cc
+++ b/src/lib/util/unittests/run_all.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_UNITTESTS_EXPORT
+
 #include <stdlib.h>
 
 #include <iostream>
diff --git a/src/lib/util/unittests/run_all.h b/src/lib/util/unittests/run_all.h
index 94c7cb0..2488088 100644
--- a/src/lib/util/unittests/run_all.h
+++ b/src/lib/util/unittests/run_all.h
@@ -21,6 +21,8 @@
 
 #include <gtest/gtest.h>
 
+#include <util/unittests/lib.h>
+
 namespace isc {
 namespace util {
 namespace unittests {
@@ -41,7 +43,7 @@ namespace unittests {
 ///
 /// \return Return value from RUN_ALL_TESTS().
 
-int run_all();
+ISC_LIBUTIL_UNITTESTS_API int run_all();
 
 } // namespace unittests
 } // namespace util
diff --git a/src/lib/util/unittests/testdata.cc b/src/lib/util/unittests/testdata.cc
index 2148d31..6efc1d7 100644
--- a/src/lib/util/unittests/testdata.cc
+++ b/src/lib/util/unittests/testdata.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#define ISC_LIBUTIL_UNITTESTS_EXPORT
+
 #include <string>
 #include <stdexcept>
 #include <fstream>
diff --git a/src/lib/util/unittests/testdata.h b/src/lib/util/unittests/testdata.h
index 03bd83a..1ec7a7a 100644
--- a/src/lib/util/unittests/testdata.h
+++ b/src/lib/util/unittests/testdata.h
@@ -15,6 +15,8 @@
 #ifndef __UTIL_UNITTESTS_TESTDATA_H
 #define __UTIL_UNITTESTS_TESTDATA_H 1
 
+#include <util/unittests/lib.h>
+
 /**
  * @file testdata.h
  * @short Manipulating test data files.
@@ -28,7 +30,7 @@ namespace util {
 namespace unittests {
 /// Add a path (directory) that \c openTestData() will search for test data
 /// files.
-void addTestDataPath(const std::string& path);
+ISC_LIBUTIL_UNITTESTS_API void addTestDataPath(const std::string& path);
 
 /// Open a file specified by 'datafile' using the data paths registered via
 /// addTestDataPath().  On success, ifs will be ready for reading the data
@@ -42,6 +44,7 @@ void addTestDataPath(const std::string& path);
 /// is to use a different \c ifstream object for a new call to this function;
 /// alternatively make sure you explicitly clear the error bit by calling
 /// \c ifstream::clear() on \c ifs.
+ISC_LIBUTIL_UNITTESTS_API
 void openTestData(const char* const datafile, std::ifstream& ifs);
 }
 }
diff --git a/src/lib/util/unittests/textdata.h b/src/lib/util/unittests/textdata.h
index 3e9b1aa..ec22d1a 100644
--- a/src/lib/util/unittests/textdata.h
+++ b/src/lib/util/unittests/textdata.h
@@ -18,6 +18,8 @@
 
 #include <gtest/gtest.h>
 
+#include <util/unittests/lib.h>
+
 #ifndef __UTIL_UNITTESTS_TEXTDATA_H
 #define __UTIL_UNITTESTS_TEXTDATA_H 1
 
@@ -38,7 +40,7 @@ namespace unittests {
 /// This templated function takes two standard input streams, extracts
 /// strings from them, and compares the two sets of strings line by line.
 template <typename EXPECTED_STREAM, typename ACTUAL_STREAM>
-void
+ISC_LIBUTIL_UNITTESTS_API void
 matchTextData(EXPECTED_STREAM& expected, ACTUAL_STREAM& actual) {
     std::string actual_line;
     std::string expected_line;
@@ -67,7 +69,7 @@ matchTextData(EXPECTED_STREAM& expected, ACTUAL_STREAM& actual) {
 /// so that the test code doesn't have to create a string stream with the
 /// string data just for testing.
 template <typename EXPECTED_STREAM>
-void
+ISC_LIBUTIL_UNITTESTS_API void
 matchTextData(EXPECTED_STREAM& expected, const std::string& actual_text) {
     std::istringstream iss(actual_text);
     matchTextData(expected, iss);
@@ -75,7 +77,7 @@ matchTextData(EXPECTED_STREAM& expected, const std::string& actual_text) {
 
 /// Same for the previous version, but the first argument is string.
 template <typename ACTUAL_STREAM>
-void
+ISC_LIBUTIL_UNITTESTS_API void
 matchTextData(const std::string& expected_text, ACTUAL_STREAM& actual) {
     std::istringstream iss(expected_text);
     matchTextData(iss, actual);
@@ -83,7 +85,7 @@ matchTextData(const std::string& expected_text, ACTUAL_STREAM& actual) {
 
 /// Same for the previous two, but takes strings for both expected and
 /// actual data.
-void
+ISC_LIBUTIL_UNITTESTS_API void
 matchTextData(const std::string& expected_text,
               const std::string& actual_text)
 {
diff --git a/win32build/BINDInstall/BINDInstall.cpp b/win32build/BINDInstall/BINDInstall.cpp
new file mode 100644
index 0000000..cbb562b
--- /dev/null
+++ b/win32build/BINDInstall/BINDInstall.cpp
@@ -0,0 +1,11 @@
+// BINDInstall.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+	return 0;
+}
+
diff --git a/win32build/BINDInstall/stdafx.cpp b/win32build/BINDInstall/stdafx.cpp
new file mode 100644
index 0000000..4acff63
--- /dev/null
+++ b/win32build/BINDInstall/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// BINDInstall.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/win32build/BINDInstall/stdafx.h b/win32build/BINDInstall/stdafx.h
new file mode 100644
index 0000000..47a0d02
--- /dev/null
+++ b/win32build/BINDInstall/stdafx.h
@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/win32build/BINDInstall/targetver.h b/win32build/BINDInstall/targetver.h
new file mode 100644
index 0000000..90e767b
--- /dev/null
+++ b/win32build/BINDInstall/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>
diff --git a/win32build/VS2012/bind10-2010.sln b/win32build/VS2012/bind10-2010.sln
new file mode 100755
index 0000000..81bd21b
--- /dev/null
+++ b/win32build/VS2012/bind10-2010.sln
@@ -0,0 +1,845 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BINDInstall", "BINDInstall\BINDInstall.vcxproj", "{41B1A417-2276-422A-A054-2691F6E40A54}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B} = {9F69DE07-D285-4B5C-8528-DF975C59ED3B}
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F} = {3FFD260A-C606-49D1-A34F-74B78D8DC76F}
+		{1AB80214-A605-4453-8960-F618C72C4CF3} = {1AB80214-A605-4453-8960-F618C72C4CF3}
+		{4D551D14-3C0F-4554-B20C-4B600249E42A} = {4D551D14-3C0F-4554-B20C-4B600249E42A}
+		{5D857B14-7763-466C-9D4E-D7C2E57C0E7F} = {5D857B14-7763-466C-9D4E-D7C2E57C0E7F}
+		{32624520-5341-471B-B88D-2599DBCDABF5} = {32624520-5341-471B-B88D-2599DBCDABF5}
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6} = {831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD} = {33927325-C9B5-4FE6-B69F-318433AFF4BD}
+		{D781E925-FE57-4C75-9E26-BBC102B6A24A} = {D781E925-FE57-4C75-9E26-BBC102B6A24A}
+		{1ADF152B-0153-424D-B195-5821B30128D6} = {1ADF152B-0153-424D-B195-5821B30128D6}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2} = {DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}
+		{D728B037-F63F-4CB5-B840-9AC54BDFBED5} = {D728B037-F63F-4CB5-B840-9AC54BDFBED5}
+		{6D55503E-0B43-4273-B6A5-4CEB39E114AC} = {6D55503E-0B43-4273-B6A5-4CEB39E114AC}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286} = {48B8644A-79FB-4D03-A981-1CA21FEE3286}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8} = {55BCB364-62B0-4F93-8B88-38F3349B22C8}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{47052F67-D9A0-433E-A074-5E50247B5F48} = {47052F67-D9A0-433E-A074-5E50247B5F48}
+		{8412D26C-6C2B-4FCC-ABB4-E9509E833951} = {8412D26C-6C2B-4FCC-ABB4-E9509E833951}
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2} = {DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}
+		{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7} = {2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}
+		{E5640378-81D0-4769-B108-4DF4E2B0AD0C} = {E5640378-81D0-4769-B108-4DF4E2B0AD0C}
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5} = {761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}
+		{D9178188-26B3-466B-A85A-C3C3344438BE} = {D9178188-26B3-466B-A85A-C3C3344438BE}
+		{6280D58A-5E05-45D1-8B79-DF677C114CD4} = {6280D58A-5E05-45D1-8B79-DF677C114CD4}
+		{D09B618B-D0E4-468D-A4BD-E204B4344C18} = {D09B618B-D0E4-468D-A4BD-E204B4344C18}
+		{FAF93094-D5F8-45AC-8C6C-29BCC522204B} = {FAF93094-D5F8-45AC-8C6C-29BCC522204B}
+		{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5} = {3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}
+		{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3} = {6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}
+		{D85833AC-23A9-4710-9911-8AAEC4BF6E8F} = {D85833AC-23A9-4710-9911-8AAEC4BF6E8F}
+		{B5D971AD-D95B-4A15-9E31-38AEF4F69627} = {B5D971AD-D95B-4A15-9E31-38AEF4F69627}
+		{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3} = {B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+		{13D541BC-8365-42F7-840F-A117CA0413DD} = {13D541BC-8365-42F7-840F-A117CA0413DD}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D} = {FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4} = {2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524} = {F27BC0D0-A334-4DC0-9DC9-880D5DA74524}
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2} = {AC4806D1-C2CC-444B-8F0D-209851A969D2}
+		{7BA6A1D1-3C42-40B9-9336-342982DD408B} = {7BA6A1D1-3C42-40B9-9336-342982DD408B}
+		{65B0B6D2-94CE-4A21-85E7-A047C79044F9} = {65B0B6D2-94CE-4A21-85E7-A047C79044F9}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423} = {564B0ADE-76A4-4833-9610-8DEEA6A15423}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{C90961EC-3DDF-432F-8E3D-BDA06E4859D9} = {C90961EC-3DDF-432F-8E3D-BDA06E4859D9}
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF} = {66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}
+		{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE} = {C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}
+		{9C5774EF-E833-4150-8B7A-B6082D879775} = {9C5774EF-E833-4150-8B7A-B6082D879775}
+		{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA} = {7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}
+		{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E} = {F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{165C00FA-A384-450C-95D4-7069FBAEE072} = {165C00FA-A384-450C-95D4-7069FBAEE072}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexceptions", "libexceptions\libexceptions.vcxproj", "{7D04222B-643C-446C-A2B8-93AF74A86246}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libutil", "libutil\libutil.vcxproj", "{8F120666-1A69-4506-8546-0F665E80FFB7}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcryptolink", "libcryptolink\libcryptolink.vcxproj", "{13215E3E-E75D-463D-A0EF-93A1C9A20896}"
+	ProjectSection(ProjectDependencies) = postProject
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4} = {2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns++", "libdns++\libdns++.vcxproj", "{F6E728D3-A0B2-40F6-9B91-7D4474D778F3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libexceptions_tests", "libexceptions_tests\libexceptions_tests.vcxproj", "{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libutil_tests", "libutil_tests\libutil_tests.vcxproj", "{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2} = {AC4806D1-C2CC-444B-8F0D-209851A969D2}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libutil_unittests", "libutil_unittests\libutil_unittests.vcxproj", "{2844FDFB-A0A1-4FA4-A654-15D69CC717DD}"
+	ProjectSection(ProjectDependencies) = postProject
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423} = {564B0ADE-76A4-4833-9610-8DEEA6A15423}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcryptolink_tests", "libcryptolink_tests\libcryptolink_tests.vcxproj", "{8412D26C-6C2B-4FCC-ABB4-E9509E833951}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns++_tests", "libdns++_tests\libdns++_tests.vcxproj", "{65B0B6D2-94CE-4A21-85E7-A047C79044F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyddns++", "pyddns++\pyddns++.vcxproj", "{13D541BC-8365-42F7-840F-A117CA0413DD}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1AB80214-A605-4453-8960-F618C72C4CF3} = {1AB80214-A605-4453-8960-F618C72C4CF3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcc", "libcc\libcc.vcxproj", "{CC29C1F9-A77B-476C-803E-8830F8312571}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1AB80214-A605-4453-8960-F618C72C4CF3} = {1AB80214-A605-4453-8960-F618C72C4CF3}
+		{13D541BC-8365-42F7-840F-A117CA0413DD} = {13D541BC-8365-42F7-840F-A117CA0413DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcc_tests", "libcc_tests\libcc_tests.vcxproj", "{D781E925-FE57-4C75-9E26-BBC102B6A24A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcfgclient", "libcfgclient\libcfgclient.vcxproj", "{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcfgclient_tests", "libcfgclient_tests\libcfgclient_tests.vcxproj", "{5D857B14-7763-466C-9D4E-D7C2E57C0E7F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD} = {33927325-C9B5-4FE6-B69F-318433AFF4BD}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog", "liblog\liblog.vcxproj", "{AEF3DFFE-B566-4E6A-B299-B59B81022C06}"
+	ProjectSection(ProjectDependencies) = postProject
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_tests", "liblog_tests\liblog_tests.vcxproj", "{9F69DE07-D285-4B5C-8528-DF975C59ED3B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4} = {2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_compiler", "liblog_compiler\liblog_compiler.vcxproj", "{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libasiolink", "libasiolink\libasiolink.vcxproj", "{69048307-9655-4AAA-B07E-B67345C1DEF9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2} = {DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libasiolink_tests", "libasiolink_tests\libasiolink_tests.vcxproj", "{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libasiodns", "libasiodns\libasiodns.vcxproj", "{7EB244E7-D381-4CF4-A2D4-739B81F77588}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libasiodns_tests", "libasiodns_tests\libasiodns_tests.vcxproj", "{6D55503E-0B43-4273-B6A5-4CEB39E114AC}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnsas", "libnsas\libnsas.vcxproj", "{67046450-CCEA-4CAC-A05B-17516F3FB540}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnsas_tests", "libnsas_tests\libnsas_tests.vcxproj", "{B5D971AD-D95B-4A15-9E31-38AEF4F69627}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcache", "libcache\libcache.vcxproj", "{F8616086-9CE9-4F32-BC97-8494EADAEC6F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcache_tests", "libcache_tests\libcache_tests.vcxproj", "{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libresolve", "libresolve\libresolve.vcxproj", "{3FFD260A-C606-49D1-A34F-74B78D8DC76F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libresolve_tests", "libresolve_tests\libresolve_tests.vcxproj", "{9C5774EF-E833-4150-8B7A-B6082D879775}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F} = {3FFD260A-C606-49D1-A34F-74B78D8DC76F}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtestutils", "libtestutils\libtestutils.vcxproj", "{55BCB364-62B0-4F93-8B88-38F3349B22C8}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F} = {3FFD260A-C606-49D1-A34F-74B78D8DC76F}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdatasrc", "libdatasrc\libdatasrc.vcxproj", "{32624520-5341-471B-B88D-2599DBCDABF5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8} = {55BCB364-62B0-4F93-8B88-38F3349B22C8}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdatasrc_tests", "libdatasrc_tests\libdatasrc_tests.vcxproj", "{4D551D14-3C0F-4554-B20C-4B600249E42A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{32624520-5341-471B-B88D-2599DBCDABF5} = {32624520-5341-471B-B88D-2599DBCDABF5}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8} = {55BCB364-62B0-4F93-8B88-38F3349B22C8}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserver_common", "libserver_common\libserver_common.vcxproj", "{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}"
+	ProjectSection(ProjectDependencies) = postProject
+		{32624520-5341-471B-B88D-2599DBCDABF5} = {32624520-5341-471B-B88D-2599DBCDABF5}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserver_common_tests", "libserver_common_tests\libserver_common_tests.vcxproj", "{D09B618B-D0E4-468D-A4BD-E204B4344C18}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD} = {33927325-C9B5-4FE6-B69F-318433AFF4BD}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF} = {66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbench", "libbench\libbench.vcxproj", "{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5} = {761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbench_tests", "libbench_tests\libbench_tests.vcxproj", "{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2} = {DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbench_example", "libbench_example\libbench_example.vcxproj", "{6280D58A-5E05-45D1-8B79-DF677C114CD4}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns++_rbench", "libdns++_rbench\libdns++_rbench.vcxproj", "{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libutil_io", "libutil_io\libutil_io.vcxproj", "{AC4806D1-C2CC-444B-8F0D-209851A969D2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pydutil_io", "pydutil_io\pydutil_io.vcxproj", "{564B0ADE-76A4-4833-9610-8DEEA6A15423}"
+	ProjectSection(ProjectDependencies) = postProject
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2} = {AC4806D1-C2CC-444B-8F0D-209851A969D2}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxfr", "libxfr\libxfr.vcxproj", "{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdhcp", "libdhcp\libdhcp.vcxproj", "{F27BC0D0-A334-4DC0-9DC9-880D5DA74524}"
+	ProjectSection(ProjectDependencies) = postProject
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF} = {66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdhcp_tests", "libdhcp_tests\libdhcp_tests.vcxproj", "{D9178188-26B3-466B-A85A-C3C3344438BE}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524} = {F27BC0D0-A334-4DC0-9DC9-880D5DA74524}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b10-dhcp6", "b10-dhcp6\b10-dhcp6.vcxproj", "{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524} = {F27BC0D0-A334-4DC0-9DC9-880D5DA74524}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b10-dhcp6_tests", "b10-dhcp6_tests\b10-dhcp6_tests.vcxproj", "{E5640378-81D0-4769-B108-4DF4E2B0AD0C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6} = {831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libacl", "libacl\libacl.vcxproj", "{635B804D-1B52-433E-9ECD-84F507FDB1F1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD} = {33927325-C9B5-4FE6-B69F-318433AFF4BD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdnsacl", "libdnsacl\libdnsacl.vcxproj", "{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libacl_tests", "libacl_tests\libacl_tests.vcxproj", "{D728B037-F63F-4CB5-B840-9AC54BDFBED5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_example", "liblog_example\liblog_example.vcxproj", "{C90961EC-3DDF-432F-8E3D-BDA06E4859D9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_iltest", "liblog_iltest\liblog_iltest.vcxproj", "{D85833AC-23A9-4710-9911-8AAEC4BF6E8F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfake_session", "libfake_session\libfake_session.vcxproj", "{33927325-C9B5-4FE6-B69F-318433AFF4BD}"
+	ProjectSection(ProjectDependencies) = postProject
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyddatasrc", "pyddatasrc\pyddatasrc.vcxproj", "{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1AB80214-A605-4453-8960-F618C72C4CF3} = {1AB80214-A605-4453-8960-F618C72C4CF3}
+		{32624520-5341-471B-B88D-2599DBCDABF5} = {32624520-5341-471B-B88D-2599DBCDABF5}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{13D541BC-8365-42F7-840F-A117CA0413DD} = {13D541BC-8365-42F7-840F-A117CA0413DD}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns++_python", "libdns++_python\libdns++_python.vcxproj", "{1AB80214-A605-4453-8960-F618C72C4CF3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pydlog", "pydlog\pydlog.vcxproj", "{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pydacl", "pydacl\pydacl.vcxproj", "{FAF93094-D5F8-45AC-8C6C-29BCC522204B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyddnsacl", "pyddnsacl\pyddnsacl.vcxproj", "{47052F67-D9A0-433E-A074-5E50247B5F48}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b10-host", "b10-host\b10-host.vcxproj", "{7BA6A1D1-3C42-40B9-9336-342982DD408B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b10-resolver", "b10-resolver\b10-resolver.vcxproj", "{48B8644A-79FB-4D03-A981-1CA21FEE3286}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F} = {3FFD260A-C606-49D1-A34F-74B78D8DC76F}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4} = {2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF} = {66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "b10-resolver_tests", "b10-resolver_tests\b10-resolver_tests.vcxproj", "{1ADF152B-0153-424D-B195-5821B30128D6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F} = {3FFD260A-C606-49D1-A34F-74B78D8DC76F}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896} = {13215E3E-E75D-463D-A0EF-93A1C9A20896}
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286} = {48B8644A-79FB-4D03-A981-1CA21FEE3286}
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1} = {635B804D-1B52-433E-9ECD-84F507FDB1F1}
+		{67046450-CCEA-4CAC-A05B-17516F3FB540} = {67046450-CCEA-4CAC-A05B-17516F3FB540}
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8} = {55BCB364-62B0-4F93-8B88-38F3349B22C8}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F} = {F8616086-9CE9-4F32-BC97-8494EADAEC6F}
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1} = {EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6} = {813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF} = {66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}
+		{CC29C1F9-A77B-476C-803E-8830F8312571} = {CC29C1F9-A77B-476C-803E-8830F8312571}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tt-badpacket", "tt-badpacket\tt-badpacket.vcxproj", "{165C00FA-A384-450C-95D4-7069FBAEE072}"
+	ProjectSection(ProjectDependencies) = postProject
+		{69048307-9655-4AAA-B07E-B67345C1DEF9} = {69048307-9655-4AAA-B07E-B67345C1DEF9}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588} = {7EB244E7-D381-4CF4-A2D4-739B81F77588}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tt-badpacket_tests", "tt-badpacket_tests\tt-badpacket_tests.vcxproj", "{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_lltest", "liblog_lltest\liblog_lltest.vcxproj", "{6A29BC58-CA6E-4196-8E88-C675FE944BBF}"
+	ProjectSection(ProjectDependencies) = postProject
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B} = {9F69DE07-D285-4B5C-8528-DF975C59ED3B}
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_i1utests", "liblog_i1utests\liblog_i1utests.vcxproj", "{1CCFABAC-5A0B-499F-914E-AAD0371EEC4F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblog_i2utests", "liblog_i2utests\liblog_i2utests.vcxproj", "{9FBAAE48-1543-41C9-80EA-A65E7C1D1A98}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns++_mbench", "libdns++_mbench\libdns++_mbench.vcxproj", "{E7E6EC32-E109-4334-9BCD-BC8190489070}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{8F120666-1A69-4506-8546-0F665E80FFB7} = {8F120666-1A69-4506-8546-0F665E80FFB7}
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3} = {F6E728D3-A0B2-40F6-9B91-7D4474D778F3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libstatistics", "libstatistics\libstatistics.vcxproj", "{FF298091-A570-41CF-BB91-841ECB7F4E5F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524} = {F27BC0D0-A334-4DC0-9DC9-880D5DA74524}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libstatistics_tests", "libstatistics_tests\libstatistics_tests.vcxproj", "{2D4553C4-1AA7-4524-ABC0-6FDF4EEE6F2E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7D04222B-643C-446C-A2B8-93AF74A86246} = {7D04222B-643C-446C-A2B8-93AF74A86246}
+		{FF298091-A570-41CF-BB91-841ECB7F4E5F} = {FF298091-A570-41CF-BB91-841ECB7F4E5F}
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD} = {2844FDFB-A0A1-4FA4-A654-15D69CC717DD}
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06} = {AEF3DFFE-B566-4E6A-B299-B59B81022C06}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{41B1A417-2276-422A-A054-2691F6E40A54}.Debug|Win32.ActiveCfg = Debug|Win32
+		{41B1A417-2276-422A-A054-2691F6E40A54}.Debug|Win32.Build.0 = Debug|Win32
+		{41B1A417-2276-422A-A054-2691F6E40A54}.Release|Win32.ActiveCfg = Release|Win32
+		{41B1A417-2276-422A-A054-2691F6E40A54}.Release|Win32.Build.0 = Release|Win32
+		{7D04222B-643C-446C-A2B8-93AF74A86246}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7D04222B-643C-446C-A2B8-93AF74A86246}.Debug|Win32.Build.0 = Debug|Win32
+		{7D04222B-643C-446C-A2B8-93AF74A86246}.Release|Win32.ActiveCfg = Release|Win32
+		{7D04222B-643C-446C-A2B8-93AF74A86246}.Release|Win32.Build.0 = Release|Win32
+		{8F120666-1A69-4506-8546-0F665E80FFB7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8F120666-1A69-4506-8546-0F665E80FFB7}.Debug|Win32.Build.0 = Debug|Win32
+		{8F120666-1A69-4506-8546-0F665E80FFB7}.Release|Win32.ActiveCfg = Release|Win32
+		{8F120666-1A69-4506-8546-0F665E80FFB7}.Release|Win32.Build.0 = Release|Win32
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896}.Debug|Win32.ActiveCfg = Debug|Win32
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896}.Debug|Win32.Build.0 = Debug|Win32
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896}.Release|Win32.ActiveCfg = Release|Win32
+		{13215E3E-E75D-463D-A0EF-93A1C9A20896}.Release|Win32.Build.0 = Release|Win32
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3}.Debug|Win32.Build.0 = Debug|Win32
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3}.Release|Win32.ActiveCfg = Release|Win32
+		{F6E728D3-A0B2-40F6-9B91-7D4474D778F3}.Release|Win32.Build.0 = Release|Win32
+		{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}.Debug|Win32.Build.0 = Debug|Win32
+		{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}.Release|Win32.ActiveCfg = Release|Win32
+		{DCF4ED2E-FFD1-4432-AFEF-8D6EC96B79A2}.Release|Win32.Build.0 = Release|Win32
+		{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}.Debug|Win32.Build.0 = Debug|Win32
+		{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}.Release|Win32.ActiveCfg = Release|Win32
+		{2C518972-FF5F-4D33-9D3E-5BCC6357EDD7}.Release|Win32.Build.0 = Release|Win32
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD}.Debug|Win32.Build.0 = Debug|Win32
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD}.Release|Win32.ActiveCfg = Release|Win32
+		{2844FDFB-A0A1-4FA4-A654-15D69CC717DD}.Release|Win32.Build.0 = Release|Win32
+		{8412D26C-6C2B-4FCC-ABB4-E9509E833951}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8412D26C-6C2B-4FCC-ABB4-E9509E833951}.Debug|Win32.Build.0 = Debug|Win32
+		{8412D26C-6C2B-4FCC-ABB4-E9509E833951}.Release|Win32.ActiveCfg = Release|Win32
+		{8412D26C-6C2B-4FCC-ABB4-E9509E833951}.Release|Win32.Build.0 = Release|Win32
+		{65B0B6D2-94CE-4A21-85E7-A047C79044F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{65B0B6D2-94CE-4A21-85E7-A047C79044F9}.Debug|Win32.Build.0 = Debug|Win32
+		{65B0B6D2-94CE-4A21-85E7-A047C79044F9}.Release|Win32.ActiveCfg = Release|Win32
+		{65B0B6D2-94CE-4A21-85E7-A047C79044F9}.Release|Win32.Build.0 = Release|Win32
+		{13D541BC-8365-42F7-840F-A117CA0413DD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{13D541BC-8365-42F7-840F-A117CA0413DD}.Debug|Win32.Build.0 = Debug|Win32
+		{13D541BC-8365-42F7-840F-A117CA0413DD}.Release|Win32.ActiveCfg = Release|Win32
+		{13D541BC-8365-42F7-840F-A117CA0413DD}.Release|Win32.Build.0 = Release|Win32
+		{CC29C1F9-A77B-476C-803E-8830F8312571}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CC29C1F9-A77B-476C-803E-8830F8312571}.Debug|Win32.Build.0 = Debug|Win32
+		{CC29C1F9-A77B-476C-803E-8830F8312571}.Release|Win32.ActiveCfg = Release|Win32
+		{CC29C1F9-A77B-476C-803E-8830F8312571}.Release|Win32.Build.0 = Release|Win32
+		{D781E925-FE57-4C75-9E26-BBC102B6A24A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D781E925-FE57-4C75-9E26-BBC102B6A24A}.Debug|Win32.Build.0 = Debug|Win32
+		{D781E925-FE57-4C75-9E26-BBC102B6A24A}.Release|Win32.ActiveCfg = Release|Win32
+		{D781E925-FE57-4C75-9E26-BBC102B6A24A}.Release|Win32.Build.0 = Release|Win32
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}.Debug|Win32.Build.0 = Debug|Win32
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}.Release|Win32.ActiveCfg = Release|Win32
+		{813BA1C9-8CD8-4B06-B1C0-FDAB576AC4B6}.Release|Win32.Build.0 = Release|Win32
+		{5D857B14-7763-466C-9D4E-D7C2E57C0E7F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5D857B14-7763-466C-9D4E-D7C2E57C0E7F}.Debug|Win32.Build.0 = Debug|Win32
+		{5D857B14-7763-466C-9D4E-D7C2E57C0E7F}.Release|Win32.ActiveCfg = Release|Win32
+		{5D857B14-7763-466C-9D4E-D7C2E57C0E7F}.Release|Win32.Build.0 = Release|Win32
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06}.Debug|Win32.Build.0 = Debug|Win32
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06}.Release|Win32.ActiveCfg = Release|Win32
+		{AEF3DFFE-B566-4E6A-B299-B59B81022C06}.Release|Win32.Build.0 = Release|Win32
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B}.Debug|Win32.Build.0 = Debug|Win32
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B}.Release|Win32.ActiveCfg = Release|Win32
+		{9F69DE07-D285-4B5C-8528-DF975C59ED3B}.Release|Win32.Build.0 = Release|Win32
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}.Debug|Win32.Build.0 = Debug|Win32
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}.Release|Win32.ActiveCfg = Release|Win32
+		{2E64F6CC-3AD9-4DA7-8E05-ABBB83F9AFC4}.Release|Win32.Build.0 = Release|Win32
+		{69048307-9655-4AAA-B07E-B67345C1DEF9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{69048307-9655-4AAA-B07E-B67345C1DEF9}.Debug|Win32.Build.0 = Debug|Win32
+		{69048307-9655-4AAA-B07E-B67345C1DEF9}.Release|Win32.ActiveCfg = Release|Win32
+		{69048307-9655-4AAA-B07E-B67345C1DEF9}.Release|Win32.Build.0 = Release|Win32
+		{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}.Debug|Win32.Build.0 = Debug|Win32
+		{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}.Release|Win32.ActiveCfg = Release|Win32
+		{6AC4F7A4-9BDC-415F-81DB-6332CACA38B3}.Release|Win32.Build.0 = Release|Win32
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588}.Debug|Win32.Build.0 = Debug|Win32
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588}.Release|Win32.ActiveCfg = Release|Win32
+		{7EB244E7-D381-4CF4-A2D4-739B81F77588}.Release|Win32.Build.0 = Release|Win32
+		{6D55503E-0B43-4273-B6A5-4CEB39E114AC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6D55503E-0B43-4273-B6A5-4CEB39E114AC}.Debug|Win32.Build.0 = Debug|Win32
+		{6D55503E-0B43-4273-B6A5-4CEB39E114AC}.Release|Win32.ActiveCfg = Release|Win32
+		{6D55503E-0B43-4273-B6A5-4CEB39E114AC}.Release|Win32.Build.0 = Release|Win32
+		{67046450-CCEA-4CAC-A05B-17516F3FB540}.Debug|Win32.ActiveCfg = Debug|Win32
+		{67046450-CCEA-4CAC-A05B-17516F3FB540}.Debug|Win32.Build.0 = Debug|Win32
+		{67046450-CCEA-4CAC-A05B-17516F3FB540}.Release|Win32.ActiveCfg = Release|Win32
+		{67046450-CCEA-4CAC-A05B-17516F3FB540}.Release|Win32.Build.0 = Release|Win32
+		{B5D971AD-D95B-4A15-9E31-38AEF4F69627}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B5D971AD-D95B-4A15-9E31-38AEF4F69627}.Debug|Win32.Build.0 = Debug|Win32
+		{B5D971AD-D95B-4A15-9E31-38AEF4F69627}.Release|Win32.ActiveCfg = Release|Win32
+		{B5D971AD-D95B-4A15-9E31-38AEF4F69627}.Release|Win32.Build.0 = Release|Win32
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F}.Debug|Win32.Build.0 = Debug|Win32
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F}.Release|Win32.ActiveCfg = Release|Win32
+		{F8616086-9CE9-4F32-BC97-8494EADAEC6F}.Release|Win32.Build.0 = Release|Win32
+		{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}.Debug|Win32.Build.0 = Debug|Win32
+		{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}.Release|Win32.ActiveCfg = Release|Win32
+		{7B80F6F0-E0CD-40D3-87B7-95C2EA2581BA}.Release|Win32.Build.0 = Release|Win32
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F}.Debug|Win32.Build.0 = Debug|Win32
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F}.Release|Win32.ActiveCfg = Release|Win32
+		{3FFD260A-C606-49D1-A34F-74B78D8DC76F}.Release|Win32.Build.0 = Release|Win32
+		{9C5774EF-E833-4150-8B7A-B6082D879775}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9C5774EF-E833-4150-8B7A-B6082D879775}.Debug|Win32.Build.0 = Debug|Win32
+		{9C5774EF-E833-4150-8B7A-B6082D879775}.Release|Win32.ActiveCfg = Release|Win32
+		{9C5774EF-E833-4150-8B7A-B6082D879775}.Release|Win32.Build.0 = Release|Win32
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8}.Debug|Win32.Build.0 = Debug|Win32
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8}.Release|Win32.ActiveCfg = Release|Win32
+		{55BCB364-62B0-4F93-8B88-38F3349B22C8}.Release|Win32.Build.0 = Release|Win32
+		{32624520-5341-471B-B88D-2599DBCDABF5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{32624520-5341-471B-B88D-2599DBCDABF5}.Debug|Win32.Build.0 = Debug|Win32
+		{32624520-5341-471B-B88D-2599DBCDABF5}.Release|Win32.ActiveCfg = Release|Win32
+		{32624520-5341-471B-B88D-2599DBCDABF5}.Release|Win32.Build.0 = Release|Win32
+		{4D551D14-3C0F-4554-B20C-4B600249E42A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4D551D14-3C0F-4554-B20C-4B600249E42A}.Debug|Win32.Build.0 = Debug|Win32
+		{4D551D14-3C0F-4554-B20C-4B600249E42A}.Release|Win32.ActiveCfg = Release|Win32
+		{4D551D14-3C0F-4554-B20C-4B600249E42A}.Release|Win32.Build.0 = Release|Win32
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}.Debug|Win32.Build.0 = Debug|Win32
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}.Release|Win32.ActiveCfg = Release|Win32
+		{66C9A5EC-514B-4BDC-AC74-ED4CB465CAAF}.Release|Win32.Build.0 = Release|Win32
+		{D09B618B-D0E4-468D-A4BD-E204B4344C18}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D09B618B-D0E4-468D-A4BD-E204B4344C18}.Debug|Win32.Build.0 = Debug|Win32
+		{D09B618B-D0E4-468D-A4BD-E204B4344C18}.Release|Win32.ActiveCfg = Release|Win32
+		{D09B618B-D0E4-468D-A4BD-E204B4344C18}.Release|Win32.Build.0 = Release|Win32
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}.Debug|Win32.Build.0 = Debug|Win32
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}.Release|Win32.ActiveCfg = Release|Win32
+		{DC86E86E-BB80-4C93-8A1F-E409C1FA38D2}.Release|Win32.Build.0 = Release|Win32
+		{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}.Debug|Win32.Build.0 = Debug|Win32
+		{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}.Release|Win32.ActiveCfg = Release|Win32
+		{FEFFE0CB-CD6B-4E61-854C-39506D6DCD5D}.Release|Win32.Build.0 = Release|Win32
+		{6280D58A-5E05-45D1-8B79-DF677C114CD4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6280D58A-5E05-45D1-8B79-DF677C114CD4}.Debug|Win32.Build.0 = Debug|Win32
+		{6280D58A-5E05-45D1-8B79-DF677C114CD4}.Release|Win32.ActiveCfg = Release|Win32
+		{6280D58A-5E05-45D1-8B79-DF677C114CD4}.Release|Win32.Build.0 = Release|Win32
+		{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}.Debug|Win32.Build.0 = Debug|Win32
+		{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}.Release|Win32.ActiveCfg = Release|Win32
+		{C7DEAFEC-423B-486D-BBD8-896B0DE69DDE}.Release|Win32.Build.0 = Release|Win32
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2}.Debug|Win32.Build.0 = Debug|Win32
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2}.Release|Win32.ActiveCfg = Release|Win32
+		{AC4806D1-C2CC-444B-8F0D-209851A969D2}.Release|Win32.Build.0 = Release|Win32
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423}.Debug|Win32.ActiveCfg = Debug|Win32
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423}.Debug|Win32.Build.0 = Debug|Win32
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423}.Release|Win32.ActiveCfg = Release|Win32
+		{564B0ADE-76A4-4833-9610-8DEEA6A15423}.Release|Win32.Build.0 = Release|Win32
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}.Debug|Win32.Build.0 = Debug|Win32
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}.Release|Win32.ActiveCfg = Release|Win32
+		{761E7D88-6CCB-4E41-9F1E-6C1FBBD062F5}.Release|Win32.Build.0 = Release|Win32
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524}.Debug|Win32.Build.0 = Debug|Win32
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524}.Release|Win32.ActiveCfg = Release|Win32
+		{F27BC0D0-A334-4DC0-9DC9-880D5DA74524}.Release|Win32.Build.0 = Release|Win32
+		{D9178188-26B3-466B-A85A-C3C3344438BE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D9178188-26B3-466B-A85A-C3C3344438BE}.Debug|Win32.Build.0 = Debug|Win32
+		{D9178188-26B3-466B-A85A-C3C3344438BE}.Release|Win32.ActiveCfg = Release|Win32
+		{D9178188-26B3-466B-A85A-C3C3344438BE}.Release|Win32.Build.0 = Release|Win32
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}.Debug|Win32.Build.0 = Debug|Win32
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}.Release|Win32.ActiveCfg = Release|Win32
+		{831EDB24-3B0A-44AE-A192-6F3DEA1A9BA6}.Release|Win32.Build.0 = Release|Win32
+		{E5640378-81D0-4769-B108-4DF4E2B0AD0C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E5640378-81D0-4769-B108-4DF4E2B0AD0C}.Debug|Win32.Build.0 = Debug|Win32
+		{E5640378-81D0-4769-B108-4DF4E2B0AD0C}.Release|Win32.ActiveCfg = Release|Win32
+		{E5640378-81D0-4769-B108-4DF4E2B0AD0C}.Release|Win32.Build.0 = Release|Win32
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1}.Debug|Win32.Build.0 = Debug|Win32
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1}.Release|Win32.ActiveCfg = Release|Win32
+		{635B804D-1B52-433E-9ECD-84F507FDB1F1}.Release|Win32.Build.0 = Release|Win32
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}.Debug|Win32.Build.0 = Debug|Win32
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}.Release|Win32.ActiveCfg = Release|Win32
+		{EB54F7B8-FAEF-4348-989C-D4E6B42CEFB1}.Release|Win32.Build.0 = Release|Win32
+		{D728B037-F63F-4CB5-B840-9AC54BDFBED5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D728B037-F63F-4CB5-B840-9AC54BDFBED5}.Debug|Win32.Build.0 = Debug|Win32
+		{D728B037-F63F-4CB5-B840-9AC54BDFBED5}.Release|Win32.ActiveCfg = Release|Win32
+		{D728B037-F63F-4CB5-B840-9AC54BDFBED5}.Release|Win32.Build.0 = Release|Win32
+		{C90961EC-3DDF-432F-8E3D-BDA06E4859D9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C90961EC-3DDF-432F-8E3D-BDA06E4859D9}.Debug|Win32.Build.0 = Debug|Win32
+		{C90961EC-3DDF-432F-8E3D-BDA06E4859D9}.Release|Win32.ActiveCfg = Release|Win32
+		{C90961EC-3DDF-432F-8E3D-BDA06E4859D9}.Release|Win32.Build.0 = Release|Win32
+		{D85833AC-23A9-4710-9911-8AAEC4BF6E8F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D85833AC-23A9-4710-9911-8AAEC4BF6E8F}.Debug|Win32.Build.0 = Debug|Win32
+		{D85833AC-23A9-4710-9911-8AAEC4BF6E8F}.Release|Win32.ActiveCfg = Release|Win32
+		{D85833AC-23A9-4710-9911-8AAEC4BF6E8F}.Release|Win32.Build.0 = Release|Win32
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD}.Debug|Win32.Build.0 = Debug|Win32
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD}.Release|Win32.ActiveCfg = Release|Win32
+		{33927325-C9B5-4FE6-B69F-318433AFF4BD}.Release|Win32.Build.0 = Release|Win32
+		{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}.Debug|Win32.Build.0 = Debug|Win32
+		{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}.Release|Win32.ActiveCfg = Release|Win32
+		{B681A9B5-8BA0-4553-B3EC-F94DC4986CA3}.Release|Win32.Build.0 = Release|Win32
+		{1AB80214-A605-4453-8960-F618C72C4CF3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1AB80214-A605-4453-8960-F618C72C4CF3}.Debug|Win32.Build.0 = Debug|Win32
+		{1AB80214-A605-4453-8960-F618C72C4CF3}.Release|Win32.ActiveCfg = Release|Win32
+		{1AB80214-A605-4453-8960-F618C72C4CF3}.Release|Win32.Build.0 = Release|Win32
+		{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}.Debug|Win32.Build.0 = Debug|Win32
+		{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}.Release|Win32.ActiveCfg = Release|Win32
+		{F1C335F5-32B3-4401-8CEF-CB0990D4FE7E}.Release|Win32.Build.0 = Release|Win32
+		{FAF93094-D5F8-45AC-8C6C-29BCC522204B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FAF93094-D5F8-45AC-8C6C-29BCC522204B}.Debug|Win32.Build.0 = Debug|Win32
+		{FAF93094-D5F8-45AC-8C6C-29BCC522204B}.Release|Win32.ActiveCfg = Release|Win32
+		{FAF93094-D5F8-45AC-8C6C-29BCC522204B}.Release|Win32.Build.0 = Release|Win32
+		{47052F67-D9A0-433E-A074-5E50247B5F48}.Debug|Win32.ActiveCfg = Debug|Win32
+		{47052F67-D9A0-433E-A074-5E50247B5F48}.Debug|Win32.Build.0 = Debug|Win32
+		{47052F67-D9A0-433E-A074-5E50247B5F48}.Release|Win32.ActiveCfg = Release|Win32
+		{47052F67-D9A0-433E-A074-5E50247B5F48}.Release|Win32.Build.0 = Release|Win32
+		{7BA6A1D1-3C42-40B9-9336-342982DD408B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7BA6A1D1-3C42-40B9-9336-342982DD408B}.Debug|Win32.Build.0 = Debug|Win32
+		{7BA6A1D1-3C42-40B9-9336-342982DD408B}.Release|Win32.ActiveCfg = Release|Win32
+		{7BA6A1D1-3C42-40B9-9336-342982DD408B}.Release|Win32.Build.0 = Release|Win32
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286}.Debug|Win32.ActiveCfg = Debug|Win32
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286}.Debug|Win32.Build.0 = Debug|Win32
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286}.Release|Win32.ActiveCfg = Release|Win32
+		{48B8644A-79FB-4D03-A981-1CA21FEE3286}.Release|Win32.Build.0 = Release|Win32
+		{1ADF152B-0153-424D-B195-5821B30128D6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1ADF152B-0153-424D-B195-5821B30128D6}.Debug|Win32.Build.0 = Debug|Win32
+		{1ADF152B-0153-424D-B195-5821B30128D6}.Release|Win32.ActiveCfg = Release|Win32
+		{1ADF152B-0153-424D-B195-5821B30128D6}.Release|Win32.Build.0 = Release|Win32
+		{165C00FA-A384-450C-95D4-7069FBAEE072}.Debug|Win32.ActiveCfg = Debug|Win32
+		{165C00FA-A384-450C-95D4-7069FBAEE072}.Debug|Win32.Build.0 = Debug|Win32
+		{165C00FA-A384-450C-95D4-7069FBAEE072}.Release|Win32.ActiveCfg = Release|Win32
+		{165C00FA-A384-450C-95D4-7069FBAEE072}.Release|Win32.Build.0 = Release|Win32
+		{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}.Debug|Win32.Build.0 = Debug|Win32
+		{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}.Release|Win32.ActiveCfg = Release|Win32
+		{3D451C9D-2AE7-4E8D-93B8-4E5470064FF5}.Release|Win32.Build.0 = Release|Win32
+		{6A29BC58-CA6E-4196-8E88-C675FE944BBF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6A29BC58-CA6E-4196-8E88-C675FE944BBF}.Debug|Win32.Build.0 = Debug|Win32
+		{6A29BC58-CA6E-4196-8E88-C675FE944BBF}.Release|Win32.ActiveCfg = Release|Win32
+		{6A29BC58-CA6E-4196-8E88-C675FE944BBF}.Release|Win32.Build.0 = Release|Win32
+		{1CCFABAC-5A0B-499F-914E-AAD0371EEC4F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1CCFABAC-5A0B-499F-914E-AAD0371EEC4F}.Debug|Win32.Build.0 = Debug|Win32
+		{1CCFABAC-5A0B-499F-914E-AAD0371EEC4F}.Release|Win32.ActiveCfg = Release|Win32
+		{1CCFABAC-5A0B-499F-914E-AAD0371EEC4F}.Release|Win32.Build.0 = Release|Win32
+		{9FBAAE48-1543-41C9-80EA-A65E7C1D1A98}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9FBAAE48-1543-41C9-80EA-A65E7C1D1A98}.Debug|Win32.Build.0 = Debug|Win32
+		{9FBAAE48-1543-41C9-80EA-A65E7C1D1A98}.Release|Win32.ActiveCfg = Release|Win32
+		{9FBAAE48-1543-41C9-80EA-A65E7C1D1A98}.Release|Win32.Build.0 = Release|Win32
+		{E7E6EC32-E109-4334-9BCD-BC8190489070}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E7E6EC32-E109-4334-9BCD-BC8190489070}.Debug|Win32.Build.0 = Debug|Win32
+		{E7E6EC32-E109-4334-9BCD-BC8190489070}.Release|Win32.ActiveCfg = Release|Win32
+		{E7E6EC32-E109-4334-9BCD-BC8190489070}.Release|Win32.Build.0 = Release|Win32
+		{FF298091-A570-41CF-BB91-841ECB7F4E5F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FF298091-A570-41CF-BB91-841ECB7F4E5F}.Debug|Win32.Build.0 = Debug|Win32
+		{FF298091-A570-41CF-BB91-841ECB7F4E5F}.Release|Win32.ActiveCfg = Release|Win32
+		{FF298091-A570-41CF-BB91-841ECB7F4E5F}.Release|Win32.Build.0 = Release|Win32
+		{2D4553C4-1AA7-4524-ABC0-6FDF4EEE6F2E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2D4553C4-1AA7-4524-ABC0-6FDF4EEE6F2E}.Debug|Win32.Build.0 = Debug|Win32
+		{2D4553C4-1AA7-4524-ABC0-6FDF4EEE6F2E}.Release|Win32.ActiveCfg = Release|Win32
+		{2D4553C4-1AA7-4524-ABC0-6FDF4EEE6F2E}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/win32build/config.h b/win32build/config.h
new file mode 100644
index 0000000..2bd91f4
--- /dev/null
+++ b/win32build/config.h
@@ -0,0 +1,72 @@
+/* config.h for WIN32 */
+
+/* Define to 1 if sockaddr has a sa_len member, and corresponding sin_len and
+   sun_len */
+/* #undef HAVE_SA_LEN */
+
+/* Need boost sunstudio workaround */
+/* #undef NEED_SUNPRO_WORKAROUND */
+
+/* Name of package */
+#define PACKAGE "bind10-devel"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bind10-dev at isc.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "bind10-devel"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "bind10-devel 20110322"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "bind10-devel"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "20110322"
+
+/* Use boost threads */
+/* #undef USE_BOOST_THREADS */
+
+/* Version number of package */
+#define VERSION "20110322"
+
+/* Additional things */
+
+/* At least Vista */
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+
+/* WIN32 specials */
+
+#define srandom srand
+#define random() rand()
+typedef int pid_t;
+typedef unsigned int uid_t;
+#ifdef _WIN64
+typedef __int64 ssize_t;
+#else
+typedef int ssize_t;
+#endif
+
+/* Prevent the definition of min() and max() macros */
+#define NOMINMAX 1
+
+/* Prevent inclusion of winsock.h in windows.h */
+#define WIN32_LEAN_AND_MEAN 1
+/*
+ * Make the number of available sockets large
+ * The number of sockets needed can get large and memory's cheap
+ * This must be defined before winsock2.h gets included as the
+ * macro is used there.
+ */
+
+#define FD_SETSIZE 16384
+#include <windows.h>
+
+/* #pragma warning(disable: 4512) */
diff --git a/win32build/dllmain.cc b/win32build/dllmain.cc
new file mode 100644
index 0000000..359227d
--- /dev/null
+++ b/win32build/dllmain.cc
@@ -0,0 +1,18 @@
+#include <windows.h>
+
+__declspec(dllexport) BOOL WINAPI
+DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpvReserved)
+{
+    hModule = hModule;
+    lpvReserved = lpvReserved;
+    
+    switch (ul_reason_for_call) { 
+    case DLL_PROCESS_ATTACH:
+    case DLL_THREAD_ATTACH: 
+    case DLL_THREAD_DETACH: 
+    case DLL_PROCESS_DETACH: 
+    default:
+        break;
+    }
+    return (TRUE);
+}
diff --git a/win32build/getopt.cc b/win32build/getopt.cc
new file mode 100644
index 0000000..fa46d4d
--- /dev/null
+++ b/win32build/getopt.cc
@@ -0,0 +1,79 @@
+/* ::[[ @(#) getopt.c 1.5 89/03/11 05:40:23 ]]:: */
+#ifndef LINT
+static const char Id[] = "$Id: getopt.c,v 1.2 2002/11/22 22:06:46 tom Exp $";
+#endif
+
+/*
+ * Here's something you've all been waiting for:  the AT&T public domain
+ * source for getopt(3).  It is the code which was given out at the 1985
+ * UNIFORUM conference in Dallas.  I obtained it by electronic mail
+ * directly from AT&T.  The people there assure me that it is indeed
+ * in the public domain.
+ *
+ * There is no manual page.  That is because the one they gave out at
+ * UNIFORUM was slightly different from the current System V Release 2
+ * manual page.  The difference apparently involved a note about the
+ * famous rules 5 and 6, recommending using white space between an option
+ * and its first argument, and not grouping options that have arguments.
+ * Getopt itself is currently lenient about both of these things White
+ * space is allowed, but not mandatory, and the last option in a group can
+ * have an argument.  That particular version of the man page evidently
+ * has no official existence, and my source at AT&T did not send a copy.
+ * The current SVR2 man page reflects the actual behavor of this getopt.
+ * However, I am not about to post a copy of anything licensed by AT&T.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define ERR(szz,czz) if(opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);}
+
+int opterr = 1;
+int optind = 1;
+int optopt;
+char *optarg;
+
+int
+getopt(int argc, char * const argv[], const char *opts)
+{
+    static int sp = 1;
+    register int c;
+    register const char *cp;
+
+    if (sp == 1) {
+	if (optind >= argc ||
+	    argv[optind][0] != '-' || argv[optind][1] == '\0')
+	    return (EOF);
+	else if (strcmp(argv[optind], "--") == 0) {
+	    optind++;
+	    return (EOF);
+	}
+    }
+    optopt = c = argv[optind][sp];
+    if (c == ':' || (cp = strchr(opts, c)) == NULL) {
+	ERR(": illegal option -- ", c);
+	if (argv[optind][++sp] == '\0') {
+	    optind++;
+	    sp = 1;
+	}
+	return ('?');
+    }
+    if (*++cp == ':') {
+	if (argv[optind][sp + 1] != '\0')
+	    optarg = &argv[optind++][sp + 1];
+	else if (++optind >= argc) {
+	    ERR(": option requires an argument -- ", c);
+	    sp = 1;
+	    return ('?');
+	} else
+	    optarg = argv[optind++];
+	sp = 1;
+    } else {
+	if (argv[optind][++sp] == '\0') {
+	    sp = 1;
+	    optind++;
+	}
+	optarg = NULL;
+    }
+    return (c);
+}
diff --git a/win32build/getopt.h b/win32build/getopt.h
new file mode 100644
index 0000000..e70e5a7
--- /dev/null
+++ b/win32build/getopt.h
@@ -0,0 +1,4 @@
+extern char *optarg;
+extern int optind, opterr;
+
+int getopt (int argc, char * const argv[], const char *options);
diff --git a/win32build/getopt_long.cc b/win32build/getopt_long.cc
new file mode 100644
index 0000000..face900
--- /dev/null
+++ b/win32build/getopt_long.cc
@@ -0,0 +1,523 @@
+/*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*/
+/*	$FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.2 2002/10/16 22:18:42 alfred Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+
+#include <getopt_long.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+
+/* Windows needs warnx().  We change the definition though:
+ *  1. (another) global is defined, opterrmsg, which holds the error message
+ *  2. errors are always printed out on stderr w/o the program name
+ * Note that opterrmsg always gets set no matter what opterr is set to.  The
+ * error message will not be printed if opterr is 0 as usual.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+extern char opterrmsg[128];
+char opterrmsg[128]; /* last error message is stored here */
+
+static void warnx(int print_error, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (fmt != NULL)
+		_vsnprintf(opterrmsg, 128, fmt, ap);
+	else
+		opterrmsg[0]='\0';
+	va_end(ap);
+	if (print_error) {
+		fprintf(stderr, opterrmsg);
+		fprintf(stderr, "\n");
+	}
+}
+
+#endif /*_WIN32*/
+
+/* not part of the original file */
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(X)
+#endif
+
+#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND
+#define REPLACE_GETOPT
+#endif
+
+int	opterr = 1;		/* if error message should be printed */
+int	optind = 1;		/* index into parent argv vector */
+int	optopt = '?';		/* character checked for validity */
+int	optreset;		/* reset getopt */
+char    *optarg;		/* argument associated with option */
+
+#if !HAVE_GETOPT_LONG
+#define IGNORE_FIRST	(*options == '-' || *options == '+')
+#define PRINT_ERROR	((opterr) && ((*options != ':') \
+				      || (IGNORE_FIRST && options[1] != ':')))
+#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
+#define PERMUTE         (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+/* XXX: GNU ignores PC if *options == '-' */
+#define IN_ORDER        (!IS_POSIXLY_CORRECT && *options == '-')
+
+/* return values */
+#define	BADCH	(int)'?'
+#define	BADARG		((IGNORE_FIRST && options[1] == ':') \
+			 || (*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define	EMSG	""
+
+static int getopt_internal(int, char * const *, const char *);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+	int c;
+
+	c = a % b;
+	while (c != 0) {
+		a = b;
+		b = c;
+		c = a % b;
+	}
+	   
+	return b;
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end,
+	     int opt_end, char * const *nargv)
+{
+	int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+	char *swap;
+
+	_DIAGASSERT(nargv != NULL);
+
+	/*
+	 * compute lengths of blocks and number and size of cycles
+	 */
+	nnonopts = panonopt_end - panonopt_start;
+	nopts = opt_end - panonopt_end;
+	ncycle = gcd(nnonopts, nopts);
+	cyclelen = (opt_end - panonopt_start) / ncycle;
+
+	for (i = 0; i < ncycle; i++) {
+		cstart = panonopt_end+i;
+		pos = cstart;
+		for (j = 0; j < cyclelen; j++) {
+			if (pos >= panonopt_end)
+				pos -= nnonopts;
+			else
+				pos += nopts;
+			swap = nargv[pos];
+			/* LINTED const cast */
+			((char **) nargv)[pos] = nargv[cstart];
+			/* LINTED const cast */
+			((char **)nargv)[cstart] = swap;
+		}
+	}
+}
+
+/*
+ * getopt_internal --
+ *	Parse argc/argv argument vector.  Called by user level routines.
+ *  Returns -2 if -- is found (can be long option or end of options marker).
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options)
+{
+	char *oli;				/* option letter list index */
+	int optchar;
+
+	_DIAGASSERT(nargv != NULL);
+	_DIAGASSERT(options != NULL);
+
+	optarg = NULL;
+
+	/*
+	 * XXX Some programs (like rsyncd) expect to be able to
+	 * XXX re-initialize optind to 0 and have getopt_long(3)
+	 * XXX properly function again.  Work around this braindamage.
+	 */
+	if (optind == 0)
+		optind = 1;
+
+	if (optreset)
+		nonopt_start = nonopt_end = -1;
+start:
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc) {          /* end of argument vector */
+			place = EMSG;
+			if (nonopt_end != -1) {
+				/* do permutation, if we have to */
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			else if (nonopt_start != -1) {
+				/*
+				 * If we skipped non-options, set optind
+				 * to the first of them.
+				 */
+				optind = nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return -1;
+		}
+		if ((*(place = nargv[optind]) != '-')
+		    || (place[1] == '\0')) {    /* found non-option */
+			place = EMSG;
+			if (IN_ORDER) {
+				/*
+				 * GNU extension: 
+				 * return non-option as argument to option 1
+				 */
+				optarg = nargv[optind++];
+				return INORDER;
+			}
+			if (!PERMUTE) {
+				/*
+				 * if no permutation wanted, stop parsing
+				 * at first non-option
+				 */
+				return -1;
+			}
+			/* do permutation */
+			if (nonopt_start == -1)
+				nonopt_start = optind;
+			else if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				nonopt_start = optind -
+				    (nonopt_end - nonopt_start);
+				nonopt_end = -1;
+			}
+			optind++;
+			/* process next argument */
+			goto start;
+		}
+		if (nonopt_start != -1 && nonopt_end == -1)
+			nonopt_end = optind;
+		if (place[1] && *++place == '-') {	/* found "--" */
+			place++;
+			return -2;
+		}
+	}
+	if ((optchar = (int)*place++) == (int)':' ||
+	    (oli = (char *) strchr(options + (IGNORE_FIRST ? 1 : 0),
+				   optchar)) == NULL) {
+		/* option letter unknown or ':' */
+		if (!*place)
+			++optind;
+#ifndef _WIN32
+		if (PRINT_ERROR)
+			warnx(illoptchar, optchar);
+#else
+			warnx(PRINT_ERROR, illoptchar, optchar);
+#endif
+		optopt = optchar;
+		return BADCH;
+	}
+	if (optchar == 'W' && oli[1] == ';') {		/* -W long-option */
+		/* XXX: what if no long options provided (called by getopt)? */
+		if (*place) 
+			return -2;
+
+		if (++optind >= nargc) {	/* no arg */
+			place = EMSG;
+#ifndef _WIN32
+			if (PRINT_ERROR)
+				warnx(recargchar, optchar);
+#else
+				warnx(PRINT_ERROR, recargchar, optchar);
+#endif
+			optopt = optchar;
+			return BADARG;
+		} else				/* white space */
+			place = nargv[optind];
+		/*
+		 * Handle -W arg the same as --arg (which causes getopt to
+		 * stop parsing).
+		 */
+		return -2;
+	}
+	if (*++oli != ':') {			/* doesn't take argument */
+		if (!*place)
+			++optind;
+	} else {				/* takes (optional) argument */
+		optarg = NULL;
+		if (*place)			/* no white space */
+			optarg = place;
+		/* XXX: disable test for :: if PC? (GNU doesn't) */
+		else if (oli[1] != ':') {	/* arg not optional */
+			if (++optind >= nargc) {	/* no arg */
+				place = EMSG;
+#ifndef _WIN32
+				if (PRINT_ERROR)
+					warnx(recargchar, optchar);
+#else
+					warnx(PRINT_ERROR, recargchar, optchar);
+#endif
+				optopt = optchar;
+				return BADARG;
+			} else
+				optarg = nargv[optind];
+		}
+		place = EMSG;
+		++optind;
+	}
+	/* dump back option letter */
+	return optchar;
+}
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the real getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+	int retval;
+
+	_DIAGASSERT(nargv != NULL);
+	_DIAGASSERT(options != NULL);
+
+	if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
+		++optind;
+		/*
+		 * We found an option (--), so if we skipped non-options,
+		 * we have to permute.
+		 */
+		if (nonopt_end != -1) {
+			permute_args(nonopt_start, nonopt_end, optind,
+				       nargv);
+			optind -= nonopt_end - nonopt_start;
+		}
+		nonopt_start = nonopt_end = -1;
+		retval = -1;
+	}
+	return retval;
+}
+
+/*
+ * getopt_long --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc,
+	    char * const *nargv,
+	    const char *options,
+	    const struct option *long_options,
+	    int *idx)
+{
+	int retval;
+
+	_DIAGASSERT(nargv != NULL);
+	_DIAGASSERT(options != NULL);
+	_DIAGASSERT(long_options != NULL);
+	/* idx may be NULL */
+
+	if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
+		char *current_argv, *has_equal;
+		size_t current_argv_len;
+		int i, match;
+
+		current_argv = place;
+		match = -1;
+
+		optind++;
+		place = EMSG;
+
+		if (*current_argv == '\0') {		/* found "--" */
+			/*
+			 * We found an option (--), so if we skipped
+			 * non-options, we have to permute.
+			 */
+			if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return -1;
+		}
+		if ((has_equal = strchr(current_argv, '=')) != NULL) {
+			/* argument found (--option=arg) */
+			current_argv_len = has_equal - current_argv;
+			has_equal++;
+		} else
+			current_argv_len = strlen(current_argv);
+	    
+		for (i = 0; long_options[i].name; i++) {
+			/* find matching long option */
+			if (strncmp(current_argv, long_options[i].name,
+			    current_argv_len))
+				continue;
+
+			if (strlen(long_options[i].name) ==
+			    (unsigned)current_argv_len) {
+				/* exact match */
+				match = i;
+				break;
+			}
+			if (match == -1)		/* partial match */
+				match = i;
+			else {
+				/* ambiguous abbreviation */
+#ifndef _WIN32
+				if (PRINT_ERROR)
+					warnx(ambig, (int)current_argv_len,
+					     current_argv);
+#else
+					warnx(PRINT_ERROR, ambig, (int)current_argv_len,
+					     current_argv);
+#endif
+				optopt = 0;
+				return BADCH;
+			}
+		}
+		if (match != -1) {			/* option found */
+		        if (long_options[match].has_arg == no_argument
+			    && has_equal) {
+#ifndef _WIN32
+				if (PRINT_ERROR)
+					warnx(noarg, (int)current_argv_len,
+					     current_argv);
+#else
+					warnx(PRINT_ERROR, noarg, (int)current_argv_len,
+					     current_argv);
+#endif
+				/*
+				 * XXX: GNU sets optopt to val regardless of
+				 * flag
+				 */
+				if (long_options[match].flag == NULL)
+					optopt = long_options[match].val;
+				else
+					optopt = 0;
+				return BADARG;
+			}
+			if (long_options[match].has_arg == required_argument ||
+			    long_options[match].has_arg == optional_argument) {
+				if (has_equal)
+					optarg = has_equal;
+				else if (long_options[match].has_arg ==
+				    required_argument) {
+					/*
+					 * optional argument doesn't use
+					 * next nargv
+					 */
+					optarg = nargv[optind++];
+				}
+			}
+			if ((long_options[match].has_arg == required_argument)
+			    && (optarg == NULL)) {
+				/*
+				 * Missing argument; leading ':'
+				 * indicates no error should be generated
+				 */
+#ifndef _WIN32
+				if (PRINT_ERROR)
+					warnx(recargstring, current_argv);
+#else
+					warnx(PRINT_ERROR, recargstring, current_argv);
+#endif
+				/*
+				 * XXX: GNU sets optopt to val regardless
+				 * of flag
+				 */
+				if (long_options[match].flag == NULL)
+					optopt = long_options[match].val;
+				else
+					optopt = 0;
+				--optind;
+				return BADARG;
+			}
+		} else {			/* unknown option */
+#ifndef _WIN32
+			if (PRINT_ERROR)
+				warnx(illoptstring, current_argv);
+#else
+				warnx(PRINT_ERROR, illoptstring, current_argv);
+#endif
+			optopt = 0;
+			return BADCH;
+		}
+		if (long_options[match].flag) {
+			*long_options[match].flag = long_options[match].val;
+			retval = 0;
+		} else 
+			retval = long_options[match].val;
+		if (idx)
+			*idx = match;
+	}
+	return retval;
+}
+#endif /* !GETOPT_LONG */
diff --git a/win32build/getopt_long.h b/win32build/getopt_long.h
new file mode 100644
index 0000000..5b9210f
--- /dev/null
+++ b/win32build/getopt_long.h
@@ -0,0 +1,104 @@
+/*      $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $    */
+/*      $FreeBSD: src/include/getopt.h,v 1.1 2002/09/29 04:14:30 eric Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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 _GETOPT_H_
+#define _GETOPT_H_
+
+#ifdef _WIN32
+/* from <sys/cdefs.h> */
+# ifdef  __cplusplus
+#  define __BEGIN_DECLS  extern "C" {
+#  define __END_DECLS    }
+# else
+#  define __BEGIN_DECLS
+#  define __END_DECLS
+# endif
+# define __P(args)      args
+#endif
+
+/*#ifndef _WIN32
+#include <sys/cdefs.h>
+#include <unistd.h>
+#endif*/
+
+/*
+ * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions
+ */
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+struct option {
+        /* name of long option */
+        const char *name;
+        /*
+         * one of no_argument, required_argument, and optional_argument:
+         * whether option takes an argument
+         */
+        int has_arg;
+        /* if not NULL, set *flag to val when option found */
+        int *flag;
+        /* if flag not NULL, value to set *flag to; else return value */
+        int val;
+};
+
+__BEGIN_DECLS
+int getopt_long __P((int, char * const *, const char *,
+    const struct option *, int *));
+__END_DECLS
+#endif
+
+#ifdef _WIN32
+/* These are global getopt variables */
+__BEGIN_DECLS
+
+extern int   opterr,   /* if error message should be printed */
+             optind,   /* index into parent argv vector */
+             optopt,   /* character checked for validity */
+             optreset; /* reset getopt */
+extern char* optarg;   /* argument associated with option */
+
+/* Original getopt */
+int getopt __P((int, char * const *, const char *));
+
+__END_DECLS
+#endif
+ 
+#endif /* !_GETOPT_H_ */
diff --git a/win32build/strptime.cc b/win32build/strptime.cc
new file mode 100644
index 0000000..84113a8
--- /dev/null
+++ b/win32build/strptime.cc
@@ -0,0 +1,181 @@
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "strptime.h"
+
+#include <time.h>
+#include <ctype.h>
+#include <string.h>
+
+// Implement strptime under windows
+static const char* kWeekFull[] = {
+  "Sunday", "Monday", "Tuesday", "Wednesday",
+  "Thursday", "Friday", "Saturday"
+};
+
+static const char* kWeekAbbr[] = {
+  "Sun", "Mon", "Tue", "Wed",
+  "Thu", "Fri", "Sat"
+};
+
+static const char* kMonthFull[] = {
+  "January", "February", "March", "April", "May", "June",
+  "July", "August", "September", "October", "November", "December"
+};
+
+static const char* kMonthAbbr[] = {
+  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const char* _parse_num(const char* s, int low, int high, int* value) {
+  const char* p = s;
+  for (*value = 0; *p != NULL && isdigit(*p); ++p) {
+    *value = (*value) * 10 + static_cast<int>(*p) - static_cast<int>('0');
+  }
+
+  if (p == s || *value < low || *value > high) return NULL;
+  return p;
+}
+
+char* strptime(const char *s, const char *format, struct tm *tm) {
+  while (*format != NULL && *s != NULL) {
+    if (*format != '%') {
+      if (*s != *format) return NULL;
+
+      ++format;
+      ++s;
+      continue;
+    }
+
+    ++format;
+    int len = 0;
+    switch (*format) {
+      // weekday name.
+      case 'a':
+      case 'A':
+        tm->tm_wday = -1;
+        for (int i = 0; i < 7; ++i) {
+          len = static_cast<int>(strlen(kWeekAbbr[i]));
+          if (_strnicmp(kWeekAbbr[i], s, len) == 0) {
+            tm->tm_wday = i;
+            break;
+          }
+
+          len = static_cast<int>(strlen(kWeekFull[i]));
+          if (_strnicmp(kWeekFull[i], s, len) == 0) {
+            tm->tm_wday = i;
+            break;
+          }
+        }
+        if (tm->tm_wday == -1) return NULL;
+        s += len;
+        break;
+
+      // month name.
+      case 'b':
+      case 'B':
+      case 'h':
+        tm->tm_mon = -1;
+        for (int i = 0; i < 12; ++i) {
+          len = static_cast<int>(strlen(kMonthAbbr[i]));
+          if (_strnicmp(kMonthAbbr[i], s, len) == 0) {
+            tm->tm_mon = i;
+            break;
+          }
+
+          len = static_cast<int>(strlen(kMonthFull[i]));
+          if (_strnicmp(kMonthFull[i], s, len) == 0) {
+            tm->tm_mon = i;
+            break;
+          }
+        }
+        if (tm->tm_mon == -1) return NULL;
+        s += len;
+        break;
+
+      // month [1, 12].
+      case 'm':
+        s = _parse_num(s, 1, 12, &tm->tm_mon);
+        if (s == NULL) return NULL;
+        --tm->tm_mon;
+        break;
+
+      // day [1, 31].
+      case 'd':
+      case 'e':
+        s = _parse_num(s, 1, 31, &tm->tm_mday);
+        if (s == NULL) return NULL;
+        break;
+
+      // hour [0, 23].
+      case 'H':
+        s = _parse_num(s, 0, 23, &tm->tm_hour);
+        if (s == NULL) return NULL;
+        break;
+
+      // minute [0, 59]
+      case 'M':
+        s = _parse_num(s, 0, 59, &tm->tm_min);
+        if (s == NULL) return NULL;
+        break;
+
+      // seconds [0, 60]. 60 is for leap year.
+      case 'S':
+        s = _parse_num(s, 0, 60, &tm->tm_sec);
+        if (s == NULL) return NULL;
+        break;
+
+      // year [1900, 9999].
+      case 'Y':
+        s = _parse_num(s, 1900, 9999, &tm->tm_year);
+        if (s == NULL) return NULL;
+        tm->tm_year -= 1900;
+        break;
+
+      // year [0, 99].
+      case 'y':
+        s = _parse_num(s, 0, 99, &tm->tm_year);
+        if (s == NULL) return NULL;
+        if (tm->tm_year <= 68) {
+          tm->tm_year += 100;
+        }
+        break;
+
+      // arbitray whitespace.
+      case 't':
+      case 'n':
+        while (isspace(*s)) ++s;
+        break;
+
+      // '%'.
+      case '%':
+        if (*s != '%') return NULL;
+        ++s;
+        break;
+
+      // All the other format are not supported.
+      default:
+        return NULL;
+    }
+    ++format;
+  }
+
+  if (*format != NULL) {
+    return NULL;
+  } else {
+    return const_cast<char*>(s);
+  }
+}
diff --git a/win32build/strptime.h b/win32build/strptime.h
new file mode 100644
index 0000000..bc9193c
--- /dev/null
+++ b/win32build/strptime.h
@@ -0,0 +1,31 @@
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// This files includes functions to support time related operations.
+// It defines common functions, which are only available on platforms.
+// It also provides functions to parse RFC times.
+
+#ifndef _TIMESUPPORT_H__
+#define _TIMESUPPORT_H__
+
+#include <time.h>
+#include <string>
+
+// Convert a string representation time to a time tm structure.
+// It is the conversion function of strftime().
+// Linux provides this function.
+char *strptime(const char *buf, const char *fmt, struct tm *tm);
+
+#endif  // _TIMESUPPORT_H__



More information about the bind10-changes mailing list